From 3ca2e4d77a37a9fbe190a6195bdccc5404e9ffc7 Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Tue, 14 Apr 2026 19:40:57 +0200 Subject: [PATCH] Bad Apple!! --- apple.py | 19 +++++ include/d/actor/d_a_obj_smtile.h | 6 +- src/d/actor/d_a_obj_smtile.cpp | 128 ++++++++++++++++++++++++++++++- 3 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 apple.py diff --git a/apple.py b/apple.py new file mode 100644 index 0000000000..8787bcdf4a --- /dev/null +++ b/apple.py @@ -0,0 +1,19 @@ +from PIL import Image +FRAME_COUNT = 6572 +WIDTH = 48 +HEIGHT = 36 + +out = open("apple.dat", "wb") +for frame in range(1, 6572+1): + print(frame) + img = Image.open(f"apples/{frame}.png") + pixels = img.load() + assert img.width == WIDTH + assert img.height == HEIGHT + for y in range(HEIGHT): + for x in range(WIDTH): + (r, g, b) = pixels[x, y] + if r > 128: + out.write(b"\x01") + else: + out.write(b"\x00") diff --git a/include/d/actor/d_a_obj_smtile.h b/include/d/actor/d_a_obj_smtile.h index 1832a7c4b8..1933b9eb14 100644 --- a/include/d/actor/d_a_obj_smtile.h +++ b/include/d/actor/d_a_obj_smtile.h @@ -41,7 +41,7 @@ public: * */ class daObj_SMTile_c : public fopAc_ac_c { -private: +public: /* 0x568 */ mDoExt_brkAnm mBrk; /* 0x580 */ OBJ_SMTILE_HIO_CLASS* mpHIO; /* 0x584 */ request_of_phase_process_class mPhase; @@ -59,6 +59,10 @@ private: /* 0xB29 */ u8 field_0xb29; /* 0xB2A */ u8 field_0xb2a; /* 0xB2B */ u8 field_0xb2b; + + bool bad_apple; + u32 bad_apple_frame; + JAISoundHandle apple_sound; public: virtual ~daObj_SMTile_c(); int create(); diff --git a/src/d/actor/d_a_obj_smtile.cpp b/src/d/actor/d_a_obj_smtile.cpp index 0cdd9f0077..374f9c2e96 100644 --- a/src/d/actor/d_a_obj_smtile.cpp +++ b/src/d/actor/d_a_obj_smtile.cpp @@ -6,8 +6,13 @@ #include "d/dolzel_rel.h" // IWYU pragma: keep #include "d/actor/d_a_obj_smtile.h" -#include "d/d_com_inf_game.h" + +#include + +#include "JSystem/J3DGraphBase/J3DDrawBuffer.h" +#include "JSystem/JParticle/JPAResourceManager.h" #include "SSystem/SComponent/c_counter.h" +#include "d/d_com_inf_game.h" static u32 l_bmdData[1][2] = { 4, 1, @@ -117,7 +122,117 @@ int daObj_SMTile_c::Delete() { return 1; } +constexpr u32 APPLE_FRAMES = 6572; +constexpr u32 APPLE_WIDTH = 48; +constexpr u32 APPLE_HEIGHT = 36; + +static constexpr f32 APPLE_TILE_SEPARATION = 100; +static constexpr f32 APPLE_TILE_SIZE = 90; +static const cXyz APPLE_TILE_OFFSET = cXyz(APPLE_TILE_SEPARATION, APPLE_TILE_SEPARATION, 0); +static const cXyz APPLE_OFFSET = cXyz(-(f32)APPLE_WIDTH/2 * APPLE_TILE_SEPARATION, 0, -(f32)APPLE_HEIGHT/2 * APPLE_TILE_SEPARATION - 400); + +static cXyz applePositions[APPLE_HEIGHT * APPLE_WIDTH]; +static u8 appleData[APPLE_HEIGHT * APPLE_WIDTH]; + +class guhPacket : public J3DPacket { + void draw() override { + u8 rmId = dPa_control_c::getRM_ID(0x86EC); + JPAResourceManager* rm = dPa_control_c::mEmitterMng->getResourceManager(rmId); + auto resource = rm->getResource(0x86EC); + rm->load(resource->getTexIdx(0), GX_TEXMAP0); + + GXSetTevColor(GX_TEVREG0, GXColor{0xFF,0xFF,0xFF,0xFF}); + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE); + GXSetNumTexGens(1); + GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); + GXSetNumTevStages(1); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_C0, GX_CC_TEXC, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_DISABLE); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); + GXSetNumIndStages(0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + GXSetCullMode(GX_CULL_NONE); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + + GXLoadPosMtxImm(j3dSys.getViewMtx(), GX_PNMTX0); + GXSetCurrentMtx(GX_PNMTX0); + + for (u32 y = 0; y < APPLE_HEIGHT; y++) { + for (u32 x = 0; x < APPLE_WIDTH; x++) { + u32 idx = y * APPLE_WIDTH + x; + if (!appleData[idx]) { + continue; + } + + cXyz pos = applePositions[idx]; + + GXBegin(GX_TRIANGLES, GX_VTXFMT0, 6); + + GXPosition3f32(pos.x, pos.y, pos.z); + GXTexCoord2f32(0, 0); + GXPosition3f32(pos.x+APPLE_TILE_SIZE, pos.y, pos.z); + GXTexCoord2f32(1, 0); + GXPosition3f32(pos.x+APPLE_TILE_SIZE, pos.y, pos.z+APPLE_TILE_SIZE); + GXTexCoord2f32(1, 1); + + GXPosition3f32(pos.x, pos.y, pos.z); + GXTexCoord2f32(0, 0); + GXPosition3f32(pos.x+APPLE_TILE_SIZE, pos.y, pos.z+APPLE_TILE_SIZE); + GXTexCoord2f32(1, 1); + GXPosition3f32(pos.x, pos.y, pos.z+APPLE_TILE_SIZE); + GXTexCoord2f32(0, 1); + + GXEnd(); + } + } + } +}; + +static guhPacket guh; + +static std::ifstream AppleData(R"(E:\Projects\dusk\apple.dat)", std::ios_base::binary | std::ios_base::in); + +static void AppleExecute(daObj_SMTile_c* tile) { + if (tile->bad_apple_frame == APPLE_FRAMES) { + tile->field_0xb2a = true; + tile->bad_apple = false; + return; + } + + AppleData.read((char*)appleData, sizeof(appleData)); + + tile->bad_apple_frame += 1; +} + +static void AppleInit(daObj_SMTile_c* tile) { + tile->bad_apple = true; + JAISoundStarter::getInstance()->startSound(0x0200007d, &tile->apple_sound, nullptr); + + for (u32 y = 0; y < APPLE_HEIGHT; y++) { + for (u32 x = 0; x < APPLE_WIDTH; x++) { + u32 idx = y * APPLE_WIDTH + x; + cXyz pos = tile->current.pos + cXyz(x, 0, y) * APPLE_TILE_SEPARATION + APPLE_OFFSET; + applePositions[idx] = pos; + // mDoMtx_stack_c::multVec(&pos, &); + // appleEmitters[idx] = dComIfGp_particle_set(0x86EC, &applePositions[idx], nullptr, &appleScale); + } + } +} + int daObj_SMTile_c::Execute() { + if (bad_apple) { + AppleExecute(this); + return 0; + } + if (home.roomNo == dComIfGp_roomControl_getStayNo()) { if (field_0xb2b != 0) { for (int i = 0; i < 21; i++) { @@ -174,10 +289,11 @@ int daObj_SMTile_c::Execute() { if (field_0xa7c > 240) { field_0xb29 = 0; + AppleInit(this); } else { - if (field_0xa7c > 220) { - field_0xb2a = 1; - } + // if (field_0xa7c > 220) { + // field_0xb2a = 1; + // } f32 fVar1 = (240 - field_0xa7c) / 40.0f; if (1.0f < fVar1) { fVar1 = 1.0f; @@ -196,6 +312,10 @@ int daObj_SMTile_c::Execute() { } int daObj_SMTile_c::Draw() { + if (bad_apple) { + j3dSys.getDrawBuffer(J3DSysDrawBuf_Xlu)->entryImm(&guh, 0); + } + J3DModelData* modelData = mModel->getModelData(); g_env_light.settingTevStruct(0, ¤t.pos, &tevStr); g_env_light.setLightTevColorType_MAJI(mModel, &tevStr);