perfect_dark/src/game/camera.c

645 lines
18 KiB
C

#include <ultra64.h>
#include "constants.h"
#include "game/atan2f.h"
#include "game/camera.h"
#include "game/tex.h"
#include "game/playermgr.h"
#include "game/bg.h"
#include "game/texdecompress.h"
#include "bss.h"
#include "lib/mtx.h"
#include "data.h"
#include "types.h"
struct coord var8009dd20;
f32 var8009dd2c;
struct coord var8009dd30;
f32 var8009dd3c;
struct coord var8009dd40;
f32 var8009dd4c;
struct coord var8009dd50;
f32 var8009dd5c;
struct coord var8009dd60;
f32 var8009dd6c;
void cam0f0b4950(void)
{
// empty
}
void camSetScreenSize(f32 width, f32 height)
{
struct player *player = g_Vars.currentplayer;
player->c_screenwidth = width;
player->c_screenheight = height;
player->c_halfwidth = width * 0.5f;
player->c_halfheight = height * 0.5f;
}
void camSetScreenPosition(f32 left, f32 top)
{
struct player *player = g_Vars.currentplayer;
player->c_screenleft = left;
player->c_screentop = top;
}
void camSetPerspective(f32 near, f32 fovy, f32 aspect)
{
struct player *player = g_Vars.currentplayer;
player->c_perspnear = near;
player->c_perspfovy = fovy;
player->c_perspaspect = aspect;
}
f32 cam0f0b49b8(f32 arg0)
{
f32 result = atan2f(g_Vars.currentplayer->c_scalelod60 * arg0 * g_Vars.currentplayer->c_halfheight, 1.0f);
result *= 114.591552f;
if (result < 0) {
result = -result;
}
return result;
}
void camSetScale(void)
{
struct player *player = g_Vars.currentplayer;
f32 fVar4;
f32 tmp;
f32 fVar5;
f32 fVar2;
player->c_scaley = sinf(player->c_perspfovy * (M_PI / 360.0f)) / (cosf(player->c_perspfovy * (M_PI / 360.0f)) * player->c_halfheight);
player->c_scalelod = player->c_scaley;
player->c_scalex = (player->c_scaley * player->c_perspaspect * player->c_halfheight) / player->c_halfwidth;
player->c_recipscalex = 1.0f / player->c_scalex;
player->c_recipscaley = 1.0f / player->c_scaley;
fVar4 = sinf(0.52359879016876f) / (cosf(0.52359879016876f) * 120.0f);
player->c_scalelod60 = fVar4;
player->c_lodscalez = player->c_scalelod / fVar4;
tmp = player->c_lodscalez * 65536.0f;
if (tmp > 4294967296.0f) {
player->c_lodscalezu32 = 0xffffffff;
} else {
player->c_lodscalezu32 = tmp;
}
fVar2 = player->c_halfheight * player->c_scaley;
fVar4 = 1.0f / sqrtf(fVar2 * fVar2 + 1.0f);
player->c_cameratopnorm.x = 0;
player->c_cameratopnorm.y = fVar4;
player->c_cameratopnorm.z = fVar2 * fVar4;
fVar5 = -player->c_halfwidth * player->c_scalex;
fVar4 = 1.0f / sqrtf(fVar5 * fVar5 + 1.0f);
player->c_cameraleftnorm.x = -fVar4;
player->c_cameraleftnorm.y = 0;
player->c_cameraleftnorm.z = -fVar5 * fVar4;
}
void cam0f0b4c3c(f32 *crosspos, struct coord *dst, f32 arg2)
{
struct player *player = g_Vars.currentplayer;
f32 sp20;
f32 sp1c;
f32 sp18 = -1.0f;
f32 f2;
sp1c = (player->c_halfheight - (crosspos[1] - player->c_screentop)) * player->c_scaley;
sp20 = (crosspos[0] - player->c_screenleft - player->c_halfwidth) * player->c_scalex;
f2 = arg2 / sqrtf(sp20 * sp20 + sp1c * sp1c + sp18 * sp18);
dst->x = sp20 * f2;
dst->y = sp1c * f2;
dst->z = sp18 * f2;
}
void cam0f0b4d04(struct coord *in, f32 *out)
{
struct player *player = g_Vars.currentplayer;
f32 value = 1.0f / in->z;
out[1] = in->y * value * player->c_recipscaley
+ (player->c_screentop + player->c_halfheight);
out[0] = (player->c_screenleft + player->c_halfwidth)
- in->x * value * player->c_recipscalex;
}
void cam0f0b4d68(struct coord *in, f32 out[2])
{
struct player *player = g_Vars.currentplayer;
f32 value;
if (in->z == 0.0f) {
value = -100000000000000000000.0f;
} else {
value = 1.0f / in->z;
}
out[1] = in->y * value * player->c_recipscaley + (player->c_screentop + player->c_halfheight);
out[0] = (player->c_screenleft + player->c_halfwidth) - in->x * value * player->c_recipscalex;
}
void cam0f0b4dec(struct coord *in, f32 out[2])
{
struct player *player = g_Vars.currentplayer;
f32 value = 1.0f / in->z;
if (value < 0) {
value = -value;
}
out[1] = in->y * value * player->c_recipscaley + (player->c_screentop + player->c_halfheight);
out[0] = (player->c_screenleft + player->c_halfwidth) - in->x * value * player->c_recipscalex;
}
void cam0f0b4e68(f32 in[2], f32 divisor, f32 out[2])
{
out[1] = in[1] * (1.0f / divisor) * g_Vars.currentplayer->c_recipscaley;
out[0] = in[0] * (1.0f / divisor) * g_Vars.currentplayer->c_recipscalex;
}
void cam0f0b4eb8(struct coord *arg0, f32 arg1[2], f32 zoom, f32 aspect)
{
f32 f12;
f32 f14;
struct player *player = g_Vars.currentplayer;
f12 = cosf(zoom * 0.008726646f) * player->c_halfheight / (sinf(zoom * 0.008726646f) * arg0->f[2]);
f14 = f12 * player->c_halfwidth / (aspect * player->c_halfheight);
arg1[1] = f12 * arg0->f[1] + (player->c_screentop + player->c_halfheight);
arg1[0] = player->c_screenleft + player->c_halfwidth - f14 * arg0->f[0];
}
void camSetMtxL1738(Mtx *mtx)
{
g_Vars.currentplayer->mtxl1738 = mtx;
}
Mtx *camGetMtxL1738(void)
{
return g_Vars.currentplayer->mtxl1738;
}
void camSetMtxL173c(Mtx *mtx)
{
g_Vars.currentplayer->mtxl173c = mtx;
}
Mtx *camGetMtxL173c(void)
{
return g_Vars.currentplayer->mtxl173c;
}
void camSetMtxF006c(Mtxf *mtx)
{
g_Vars.currentplayer->mtxf006c = mtx;
}
Mtxf *camGetMtxF006c(void)
{
return g_Vars.currentplayer->mtxf006c;
}
void camSetPerspectiveMtxL(Mtx *mtx)
{
g_Vars.currentplayer->perspmtxl = mtx;
}
Mtx *camGetPerspectiveMtxL(void)
{
return g_Vars.currentplayer->perspmtxl;
}
void camSetOrthogonalMtxL(Mtx *mtx)
{
g_Vars.currentplayer->orthomtxl = mtx;
}
Mtx *camGetOrthogonalMtxL(void)
{
return g_Vars.currentplayer->orthomtxl;
}
void camSetWorldToScreenMtxf(Mtxf *mtx)
{
struct player *player = g_Vars.currentplayer;
player->prevworldtoscreenmtx = player->worldtoscreenmtx;
player->worldtoscreenmtx = mtx;
player->c_viewfmdynticknum = g_GfxNumSwaps;
player->unk0488 = player->unk0484;
player->unk0484 = g_GfxMemPos;
}
Mtxf *cam0f0b5050(u8 *arg0)
{
Mtxf *result = NULL;
s32 i;
if (arg0 >= g_VtxBuffers[g_GfxActiveBufferIndex] && arg0 < g_VtxBuffers[g_GfxActiveBufferIndex + 1]) {
for (i = 0; i < PLAYERCOUNT(); i++) {
if (g_Vars.currentplayerindex >= playermgrGetOrderOfPlayer(i)) {
if (g_GfxNumSwaps == g_Vars.players[i]->c_viewfmdynticknum) {
if (arg0 >= g_Vars.players[i]->unk0484 && (u8 *)result < g_Vars.players[i]->unk0484) {
result = g_Vars.players[i]->worldtoscreenmtx;
}
}
}
}
} else {
for (i = 0; i < PLAYERCOUNT(); i++) {
if (g_Vars.currentplayerindex >= playermgrGetOrderOfPlayer(i)) {
if (g_GfxNumSwaps == g_Vars.players[i]->c_prevviewfmdynticknum + 1) {
if (arg0 >= g_Vars.players[i]->unk0488 && (u8 *)result < g_Vars.players[i]->unk0488) {
result = g_Vars.players[i]->prevworldtoscreenmtx;
}
}
} else {
if (g_GfxNumSwaps == g_Vars.players[i]->c_viewfmdynticknum + 1) {
if (arg0 >= g_Vars.players[i]->unk0484 && (u8 *)result < g_Vars.players[i]->unk0484) {
result = g_Vars.players[i]->worldtoscreenmtx;
}
}
}
}
}
return result;
}
Mtxf *cam0f0b53a4(u8 *arg0)
{
Mtxf *result = NULL;
s32 i;
if (arg0 >= g_VtxBuffers[g_GfxActiveBufferIndex] && arg0 < g_VtxBuffers[g_GfxActiveBufferIndex + 1]) {
for (i = 0; i < PLAYERCOUNT(); i++) {
if (g_Vars.currentplayerindex >= playermgrGetOrderOfPlayer(i)) {
if (g_GfxNumSwaps == g_Vars.players[i]->c_viewfmdynticknum) {
if (arg0 >= g_Vars.players[i]->unk0484 && (u8 *)result < g_Vars.players[i]->unk0484) {
result = g_Vars.players[i]->projectionmtx;
}
}
}
}
} else {
for (i = 0; i < PLAYERCOUNT(); i++) {
if (g_Vars.currentplayerindex >= playermgrGetOrderOfPlayer(i)) {
if (g_GfxNumSwaps == g_Vars.players[i]->c_prevviewfmdynticknum + 1) {
if (arg0 >= g_Vars.players[i]->unk0488 && (u8 *)result < g_Vars.players[i]->unk0488) {
result = g_Vars.players[i]->prevprojectionmtx;
}
}
} else {
if (g_GfxNumSwaps == g_Vars.players[i]->c_viewfmdynticknum + 1) {
if (arg0 >= g_Vars.players[i]->unk0484 && (u8 *)result < g_Vars.players[i]->unk0484) {
result = g_Vars.players[i]->projectionmtx;
}
}
}
}
}
return result;
}
Mtxf *camGetWorldToScreenMtxf(void)
{
return g_Vars.currentplayer->worldtoscreenmtx;
}
void camSetMtxF1754(Mtxf *mtx)
{
g_Vars.currentplayer->mtxf1754 = mtx;
}
Mtxf *camGetMtxF1754(void)
{
return g_Vars.currentplayer->mtxf1754;
}
Mtxf *camGetPrevWorldToScreenMtxf(void)
{
return g_Vars.currentplayer->prevworldtoscreenmtx;
}
void camSetMtxF1748(Mtxf *mtx)
{
g_Vars.currentplayer->mtxf1748 = mtx;
}
Mtxf *camGetMtxF1748(void)
{
return g_Vars.currentplayer->mtxf1748;
}
void camSetProjectionMtxF(Mtxf *mtx)
{
struct player *player = g_Vars.currentplayer;
player->c_prevviewfmdynticknum = player->c_viewfmdynticknum;
player->prevprojectionmtx = player->projectionmtx;
player->projectionmtx = mtx;
}
Mtxf *camGetProjectionMtxF(void)
{
return g_Vars.currentplayer->projectionmtx;
}
Mtxf *camGetPrevProjectionMtxF(void)
{
return g_Vars.currentplayer->prevprojectionmtx;
}
void camSetLookAt(LookAt *lookat)
{
g_Vars.currentplayer->lookat = lookat;
}
LookAt *camGetLookAt(void)
{
return g_Vars.currentplayer->lookat;
}
f32 camGetLodScaleZ(void)
{
return g_Vars.currentplayer->c_lodscalez;
}
u32 camGetLodScaleZU32(void)
{
return g_Vars.currentplayer->c_lodscalezu32;
}
f32 camGetScreenWidth(void)
{
return g_Vars.currentplayer->c_screenwidth;
}
f32 camGetScreenHeight(void)
{
return g_Vars.currentplayer->c_screenheight;
}
f32 camGetScreenLeft(void)
{
return g_Vars.currentplayer->c_screenleft;
}
f32 camGetScreenTop(void)
{
return g_Vars.currentplayer->c_screentop;
}
f32 camGetPerspFovY(void)
{
return g_Vars.currentplayer->c_perspfovy;
}
f32 camGetPerspAspect(void)
{
return g_Vars.currentplayer->c_perspaspect;
}
void cam0f0b5838(void)
{
f32 sp2c;
f32 sp28;
f32 sp24;
f32 sp20;
struct player *player;
Mtxf *mtx;
f32 sp14;
f32 sp10;
player = g_Vars.currentplayer;
sp24 = player->c_halfheight * player->c_scaley;
mtx = player->projectionmtx;
sp2c = 1.0f / sqrtf(sp24 * sp24 + 1.0f);
sp24 *= sp2c;
sp20 = -sp2c;
var8009dd20.f[0] = -sp20 * mtx->m[1][0] + (sp24) * mtx->m[2][0];
var8009dd20.f[1] = -sp20 * mtx->m[1][1] + (sp24) * mtx->m[2][1];
var8009dd20.f[2] = -sp20 * mtx->m[1][2] + (sp24) * mtx->m[2][2];
var8009dd2c = var8009dd20.f[0] * mtx->m[3][0] + var8009dd20.f[1] * mtx->m[3][1] + var8009dd20.f[2] * mtx->m[3][2];
var8009dd30.f[0] = sp20 * mtx->m[1][0] + (sp24) * mtx->m[2][0];
var8009dd30.f[1] = sp20 * mtx->m[1][1] + (sp24) * mtx->m[2][1];
var8009dd30.f[2] = sp20 * mtx->m[1][2] + (sp24) * mtx->m[2][2];
var8009dd3c = var8009dd30.f[0] * mtx->m[3][0] + var8009dd30.f[1] * mtx->m[3][1] + var8009dd30.f[2] * mtx->m[3][2];
sp28 = -player->c_halfwidth * player->c_scalex;
sp10 = 1.0f / sqrtf(sp28 * sp28 + 1.0f);
sp28 *= sp10;
sp14 = -sp10;
var8009dd40.f[0] = sp14 * mtx->m[0][0] - sp28 * mtx->m[2][0];
var8009dd40.f[1] = sp14 * mtx->m[0][1] - sp28 * mtx->m[2][1];
var8009dd40.f[2] = sp14 * mtx->m[0][2] - sp28 * mtx->m[2][2];
var8009dd4c = var8009dd40.f[0] * mtx->m[3][0] + var8009dd40.f[1] * mtx->m[3][1] + var8009dd40.f[2] * mtx->m[3][2];
var8009dd50.f[0] = -sp14 * mtx->m[0][0] - sp28 * mtx->m[2][0];
var8009dd50.f[1] = -sp14 * mtx->m[0][1] - sp28 * mtx->m[2][1];
var8009dd50.f[2] = -sp14 * mtx->m[0][2] - sp28 * mtx->m[2][2];
var8009dd5c = var8009dd50.f[0] * mtx->m[3][0] + var8009dd50.f[1] * mtx->m[3][1] + var8009dd50.f[2] * mtx->m[3][2];
var8009dd60.f[0] = -mtx->m[3][0];
var8009dd60.f[1] = -mtx->m[3][1];
var8009dd60.f[2] = -mtx->m[3][2];
var8009dd6c = mtx->m[2][0] * mtx->m[3][0] + mtx->m[2][1] * mtx->m[3][1] + mtx->m[2][2] * mtx->m[3][2];
}
bool cam0f0b5b9c(struct coord *arg0, f32 arg1)
{
Mtxf *mtx = g_Vars.currentplayer->projectionmtx;
if (var8009dd6c + arg1 < mtx->m[2][0] * arg0->f[0] + mtx->m[2][1] * arg0->f[1] + mtx->m[2][2] * arg0->f[2]) {
return false;
}
if (var8009dd4c + arg1 < var8009dd40.f[0] * arg0->f[0] + var8009dd40.f[1] * arg0->f[1] + var8009dd40.f[2] * arg0->f[2]) {
return false;
}
if (var8009dd5c + arg1 < var8009dd50.f[0] * arg0->f[0] + var8009dd50.f[1] * arg0->f[1] + var8009dd50.f[2] * arg0->f[2]) {
return false;
}
if (var8009dd2c + arg1 < var8009dd20.f[0] * arg0->f[0] + var8009dd20.f[1] * arg0->f[1] + var8009dd20.f[2] * arg0->f[2]) {
return false;
}
if (var8009dd3c + arg1 < var8009dd30.f[0] * arg0->f[0] + var8009dd30.f[1] * arg0->f[1] + var8009dd30.f[2] * arg0->f[2]) {
return false;
}
return true;
}
bool camIsPosInScreenBox(struct coord *pos, f32 arg1, struct drawslot *drawslot)
{
struct coord sp74;
f32 sp70;
struct coord sp64;
f32 sp60;
struct coord sp54;
f32 sp50;
struct coord sp44;
f32 sp40;
f32 sp3c;
f32 sp38;
f32 sp34;
f32 sp30;
f32 sp2c;
f32 sp28;
f32 sp24;
f32 sp20;
f32 sp1c;
f32 sp18;
if (var8009dd6c + arg1 < g_Vars.currentplayer->projectionmtx->m[2][0] * pos->f[0] + g_Vars.currentplayer->projectionmtx->m[2][1] * pos->f[1] + g_Vars.currentplayer->projectionmtx->m[2][2] * pos->f[2]) {
return false;
}
sp38 = (drawslot->box.xmin - g_Vars.currentplayer->c_screenleft - g_Vars.currentplayer->c_halfwidth) * g_Vars.currentplayer->c_scalex;
sp3c = 1.0f / sqrtf(sp38 * sp38 + 1.0f);
sp38 *= sp3c;
sp24 = -sp3c;
sp54.f[0] = sp24 * g_Vars.currentplayer->projectionmtx->m[0][0] - sp38 * g_Vars.currentplayer->projectionmtx->m[2][0];
sp54.f[1] = sp24 * g_Vars.currentplayer->projectionmtx->m[0][1] - sp38 * g_Vars.currentplayer->projectionmtx->m[2][1];
sp54.f[2] = sp24 * g_Vars.currentplayer->projectionmtx->m[0][2] - sp38 * g_Vars.currentplayer->projectionmtx->m[2][2];
sp50 = sp54.f[0] * g_Vars.currentplayer->projectionmtx->m[3][0] + sp54.f[1] * g_Vars.currentplayer->projectionmtx->m[3][1] + sp54.f[2] * g_Vars.currentplayer->projectionmtx->m[3][2];
if (sp50 + arg1 < sp54.f[0] * pos->f[0] + sp54.f[1] * pos->f[1] + sp54.f[2] * pos->f[2]) {
return false;
}
sp38 = -(drawslot->box.xmax - g_Vars.currentplayer->c_screenleft - g_Vars.currentplayer->c_halfwidth) * g_Vars.currentplayer->c_scalex;
sp30 = 1.0f / sqrtf(sp38 * sp38 + 1.0f);
sp38 *= sp30;
sp20 = -sp30;
sp44.f[0] = -sp20 * g_Vars.currentplayer->projectionmtx->m[0][0] - sp38 * g_Vars.currentplayer->projectionmtx->m[2][0];
sp44.f[1] = -sp20 * g_Vars.currentplayer->projectionmtx->m[0][1] - sp38 * g_Vars.currentplayer->projectionmtx->m[2][1];
sp44.f[2] = -sp20 * g_Vars.currentplayer->projectionmtx->m[0][2] - sp38 * g_Vars.currentplayer->projectionmtx->m[2][2];
sp40 = sp44.f[0] * g_Vars.currentplayer->projectionmtx->m[3][0] + sp44.f[1] * g_Vars.currentplayer->projectionmtx->m[3][1] + sp44.f[2] * g_Vars.currentplayer->projectionmtx->m[3][2];
if (sp40 + arg1 < sp44.f[0] * pos->f[0] + sp44.f[1] * pos->f[1] + sp44.f[2] * pos->f[2]) {
return false;
}
sp34 = (g_Vars.currentplayer->c_halfheight - (drawslot->box.ymin - g_Vars.currentplayer->c_screentop)) * g_Vars.currentplayer->c_scaley;
sp2c = 1.0f / sqrtf(sp34 * sp34 + 1.0f);
sp34 *= sp2c;
sp1c = -sp2c;
sp74.f[0] = -sp1c * g_Vars.currentplayer->projectionmtx->m[1][0] + sp34 * g_Vars.currentplayer->projectionmtx->m[2][0];
sp74.f[1] = -sp1c * g_Vars.currentplayer->projectionmtx->m[1][1] + sp34 * g_Vars.currentplayer->projectionmtx->m[2][1];
sp74.f[2] = -sp1c * g_Vars.currentplayer->projectionmtx->m[1][2] + sp34 * g_Vars.currentplayer->projectionmtx->m[2][2];
sp70 = sp74.f[0] * g_Vars.currentplayer->projectionmtx->m[3][0] + sp74.f[1] * g_Vars.currentplayer->projectionmtx->m[3][1] + sp74.f[2] * g_Vars.currentplayer->projectionmtx->m[3][2];
if (sp70 + arg1 < sp74.f[0] * pos->f[0] + sp74.f[1] * pos->f[1] + sp74.f[2] * pos->f[2]) {
return false;
}
sp34 = -(g_Vars.currentplayer->c_halfheight - (drawslot->box.ymax - g_Vars.currentplayer->c_screentop)) * g_Vars.currentplayer->c_scaley;
sp28 = 1.0f / sqrtf(sp34 * sp34 + 1.0f);
sp34 *= sp28;
sp18 = -sp28;
sp64.f[0] = sp18 * g_Vars.currentplayer->projectionmtx->m[1][0] + sp34 * g_Vars.currentplayer->projectionmtx->m[2][0];
sp64.f[1] = sp18 * g_Vars.currentplayer->projectionmtx->m[1][1] + sp34 * g_Vars.currentplayer->projectionmtx->m[2][1];
sp64.f[2] = sp18 * g_Vars.currentplayer->projectionmtx->m[1][2] + sp34 * g_Vars.currentplayer->projectionmtx->m[2][2];
sp60 = sp64.f[0] * g_Vars.currentplayer->projectionmtx->m[3][0] + sp64.f[1] * g_Vars.currentplayer->projectionmtx->m[3][1] + sp64.f[2] * g_Vars.currentplayer->projectionmtx->m[3][2];
if (sp60 + arg1 < sp64.f[0] * pos->f[0] + sp64.f[1] * pos->f[1] + sp64.f[2] * pos->f[2]) {
return false;
}
return true;
}
/**
* This function is building a drawslot on the stack so it can pass it to
* camIsPosInScreenBox, however if we allocate this struct then it uses too much
* stack and creates a mismatch.
*
* We resolve this by allocating a screenbox instead, which is a substruct of
* drawslot and is all we need in this function. screenbox isn't at the
* start of drawslot though, so we use a negative array index to pass the
* correct address to camIsPosInScreenBox so it can interpret the pointer as a
* drawslot.
*/
bool camIsPosInFovAndVisibleRoom(RoomNum *rooms, struct coord *pos, f32 arg2)
{
s32 i;
RoomNum room;
bool hasdata = false;
struct drawslot *thisthing;
struct screenbox box;
for (i = 0, room = rooms[i]; room != -1; i++, room = rooms[i]) {
if (g_Rooms[room].flags & ROOMFLAG_ONSCREEN) {
thisthing = bgGetRoomDrawSlot(room);
if (hasdata == false) {
box.xmin = thisthing->box.xmin;
box.ymin = thisthing->box.ymin;
box.xmax = thisthing->box.xmax;
box.ymax = thisthing->box.ymax;
} else {
if (thisthing->box.xmin < box.xmin) {
box.xmin = thisthing->box.xmin;
}
if (thisthing->box.ymin < box.ymin) {
box.ymin = thisthing->box.ymin;
}
if (thisthing->box.xmax > box.xmax) {
box.xmax = thisthing->box.xmax;
}
if (thisthing->box.ymax > box.ymax) {
box.ymax = thisthing->box.ymax;
}
}
hasdata = true;
}
}
if (!hasdata) {
return false;
}
return camIsPosInScreenBox(pos, arg2, (struct drawslot *) &(((u8 *) &box)[-((uintptr_t) &(((struct drawslot *)0)->box))]));
}