Implement fizzle

This commit is contained in:
James Lambert 2022-06-14 13:01:26 -06:00
parent f6718c5ea7
commit 4411a99bdc
10 changed files with 213 additions and 3 deletions

View file

@ -57,6 +57,9 @@ where `/home/james/Blender/blender-2.93.1-linux-x64` is the folder where blender
## Current TODO list ## Current TODO list
Allow player to press button -- kinda done implement elevator
mesh collider type
implement emancipation grid
Change the way player standing logic works
cube dispenser cube dispenser
nan in overlap nan in overlap

View file

@ -310,4 +310,14 @@ materials:
set: [G_LIGHTING, G_SHADE] set: [G_LIGHTING, G_SHADE]
gDPSetCombineMode: gDPSetCombineMode:
color: ["SHADE", "0", "TEXEL0", "0"] color: ["SHADE", "0", "TEXEL0", "0"]
portal_cleanser:
gDPSetTile:
filename: ../../portal_pak_modified/materials/effects/portal_cleanser.png
fmt: G_IM_FMT_RGBA
siz: G_IM_SIZ_16b
gDPSetCombineMode: G_CC_DECALRGB
gSPGeometryMode:
clear: [G_CULL_BACK, G_CULL_FRONT]

View file

@ -23,4 +23,6 @@ Gfx* door_01_gfx = &props_door_01_model_gfx[0];
short door_01_material_index = DOOR_01_INDEX; short door_01_material_index = DOOR_01_INDEX;
Gfx* cylinder_gfx = &props_cylinder_test_model_gfx[0]; Gfx* cylinder_gfx = &props_cylinder_test_model_gfx[0];
short cylinder_material_index = PLASTIC_PLASTICWALL001A_INDEX; short cylinder_material_index = PLASTIC_PLASTICWALL001A_INDEX;
short fizzler_material_index = PORTAL_CLEANSER_INDEX;

View file

@ -21,4 +21,6 @@ extern short door_01_material_index;
extern Gfx* cylinder_gfx; extern Gfx* cylinder_gfx;
extern short cylinder_material_index; extern short cylinder_material_index;
extern short fizzler_material_index;
#endif #endif

146
src/scene/fizzler.c Normal file
View file

@ -0,0 +1,146 @@
#include "fizzler.h"
#include "../util/memory.h"
#include "../graphics/render_scene.h"
#include "../scene/dynamic_scene.h"
#include "../models/models.h"
#define GFX_PER_PARTICLE(particleCount) ((particleCount) + (((particleCount) + 7) >> 3) + 1)
void fizzlerRender(void* data, struct RenderScene* renderScene) {
struct Fizzler* fizzler = (struct Fizzler*)data;
Mtx* matrix = renderStateRequestMatrices(renderScene->renderState, 1);
transformToMatrixL(&fizzler->transform, matrix, SCENE_SCALE);
renderSceneAdd(renderScene, fizzler->modelGraphics, matrix, fizzler_material_index, &fizzler->transform.position, NULL);
}
void fizzlerSpawnParticle(struct Fizzler* fizzler, int particleIndex) {
int x = (particleIndex & 0x1) ? -fizzler->maxExtent : fizzler->maxExtent;
int y = guRandom() % (fizzler->maxVerticalExtent * 2) - fizzler->maxVerticalExtent;
int xSize = (particleIndex & 0x1) ? (FIZZLER_PARTICLE_LENGTH_FIXED / 2) : -(FIZZLER_PARTICLE_LENGTH_FIXED / 2);
Vtx* currentVertex = &fizzler->modelVertices[particleIndex << 2];
currentVertex->v.ob[0] = x - xSize;
currentVertex->v.ob[1] = y - (FIZZLER_PARTICLE_HEIGHT_FIXED / 2);
currentVertex->v.ob[2] = 0;
currentVertex->v.flag = 0;
currentVertex->v.tc[0] = 0;
currentVertex->v.tc[1] = 0;
currentVertex->v.cn[0] = 255; currentVertex->v.cn[1] = 255; currentVertex->v.cn[2] = 255; currentVertex->v.cn[3] = 255;
++currentVertex;
currentVertex->v.ob[0] = x - xSize;
currentVertex->v.ob[1] = y + (FIZZLER_PARTICLE_HEIGHT_FIXED / 2);
currentVertex->v.ob[2] = 0;
currentVertex->v.flag = 0;
currentVertex->v.tc[0] = 32 << 5;
currentVertex->v.tc[1] = 0;
currentVertex->v.cn[0] = 255; currentVertex->v.cn[1] = 255; currentVertex->v.cn[2] = 255; currentVertex->v.cn[3] = 255;
++currentVertex;
currentVertex->v.ob[0] = x + xSize;
currentVertex->v.ob[1] = y + (FIZZLER_PARTICLE_HEIGHT_FIXED / 2);
currentVertex->v.ob[2] = 0;
currentVertex->v.flag = 0;
currentVertex->v.tc[0] = 32 << 5;
currentVertex->v.tc[1] = 64 << 5;
currentVertex->v.cn[0] = 255; currentVertex->v.cn[1] = 255; currentVertex->v.cn[2] = 255; currentVertex->v.cn[3] = 255;
++currentVertex;
currentVertex->v.ob[0] = x + xSize;
currentVertex->v.ob[1] = y - (FIZZLER_PARTICLE_HEIGHT_FIXED / 2);
currentVertex->v.ob[2] = 0;
currentVertex->v.flag = 0;
currentVertex->v.tc[0] = 0;
currentVertex->v.tc[1] = 64 << 5;
currentVertex->v.cn[0] = 255; currentVertex->v.cn[1] = 255; currentVertex->v.cn[2] = 255; currentVertex->v.cn[3] = 255;
}
void fizzlerInit(struct Fizzler* fizzler, struct Transform* transform, float width, float height) {
fizzler->transform = *transform;
fizzler->maxExtent = (int)(width * SCENE_SCALE * 0.5f);
fizzler->maxVerticalExtent = (int)(height * SCENE_SCALE * 0.5f);
fizzler->particleCount = (int)(width * height * FIZZLER_PARTICLES_PER_1x1);
fizzler->modelVertices = malloc(fizzler->particleCount * 4 * sizeof(Vtx));
fizzler->modelGraphics = malloc(GFX_PER_PARTICLE(fizzler->particleCount) * sizeof(Gfx));
Gfx* curr = fizzler->modelGraphics;
for (int currentParticle = 0; currentParticle < fizzler->particleCount; currentParticle += 8) {
int endParticle = currentParticle + 8;
if (endParticle > fizzler->particleCount) {
endParticle = fizzler->particleCount;
}
int vertexCount = (endParticle - currentParticle) << 2;
gSPVertex(curr++, &fizzler->modelVertices[currentParticle << 2], vertexCount, 0);
for (int currentIndex = 0; currentIndex < vertexCount; currentIndex += 4) {
gSP2Triangles(curr++,
currentIndex + 0, currentIndex + 1, currentIndex + 2, 0,
currentIndex + 0, currentIndex + 2, currentIndex + 3, 0
);
}
}
gSPEndDisplayList(curr++);
for (int i = 0; i < fizzler->particleCount; ++i) {
fizzlerSpawnParticle(fizzler, i);
int offset = fizzler->maxExtent * 2 * (fizzler->particleCount - i) / fizzler->particleCount;
if (!(i & 0x1)) {
offset = -offset;
}
int maxVertex = (i + 1) << 2;
for (int currVertex = (i << 2); currVertex < maxVertex; ++currVertex) {
fizzler->modelVertices[currVertex].v.ob[0] += offset;
}
}
fizzler->dynamicId = dynamicSceneAdd(fizzler, fizzlerRender, &fizzler->transform, sqrtf(width * width + height * height) * 0.5f);
}
void fizzlerUpdate(struct Fizzler* fizzler) {
Vtx* currentVertex = fizzler->modelVertices;
int maxVertex = fizzler->particleCount << 2;
for (int vertexIndex = 0; vertexIndex < maxVertex; ++vertexIndex) {
int delta = (vertexIndex & 0x4) ? FIZZLER_UNITS_PER_UPDATE : -FIZZLER_UNITS_PER_UPDATE;
currentVertex->v.ob[0] += delta;
++currentVertex;
}
if ((fizzler->oldestParticleIndex & 0x1) ? fizzler->modelVertices[fizzler->oldestParticleIndex << 2].v.ob[0] > fizzler->maxExtent : fizzler->modelVertices[fizzler->oldestParticleIndex << 2].v.ob[0] < -fizzler->maxExtent) {
fizzlerSpawnParticle(fizzler, fizzler->oldestParticleIndex);
++fizzler->oldestParticleIndex;
if (fizzler->oldestParticleIndex == fizzler->particleCount) {
fizzler->oldestParticleIndex = 0;
}
}
}

30
src/scene/fizzler.h Normal file
View file

@ -0,0 +1,30 @@
#ifndef __FIZZLER_H__
#define __FIZZLER_H__
#include <ultra64.h>
#include "../math/transform.h"
#include "defs.h"
#include "../util/time.h"
#define FIZZLER_PARTICLES_PER_1x1 2.5f
#define FIZZLER_PARTICLE_VELOCITY 1.0f
#define FIZZLER_UNITS_PER_UPDATE (int)(SCENE_SCALE * FIZZLER_PARTICLE_VELOCITY * FIXED_DELTA_TIME)
#define FIZZLER_PARTICLE_LENGTH 0.4f
#define FIZZLER_PARTICLE_LENGTH_FIXED (int)(FIZZLER_PARTICLE_LENGTH * SCENE_SCALE)
#define FIZZLER_PARTICLE_HEIGHT_FIXED (int)(FIZZLER_PARTICLE_LENGTH * SCENE_SCALE * 0.5f)
struct Fizzler {
struct Transform transform;
Vtx* modelVertices;
Gfx* modelGraphics;
short particleCount;
short maxExtent;
short maxVerticalExtent;
short oldestParticleIndex;
short dynamicId;
};
void fizzlerInit(struct Fizzler* fizzler, struct Transform* transform, float width, float height);
void fizzlerUpdate(struct Fizzler* fizzler);
#endif

View file

@ -83,6 +83,16 @@ void sceneInit(struct Scene* scene) {
for (int i = 0; i < scene->doorCount; ++i) { for (int i = 0; i < scene->doorCount; ++i) {
doorInit(&scene->doors[i], &gCurrentLevel->doors[i], &gCurrentLevel->world); doorInit(&scene->doors[i], &gCurrentLevel->doors[i], &gCurrentLevel->world);
} }
scene->fizzlerCount = 1;
scene->fizzlers = malloc(sizeof(struct Fizzler) * scene->fizzlerCount);
for (int i = 0; i < scene->fizzlerCount; ++i) {
struct Transform fizzlerTransform;
transformInitIdentity(&fizzlerTransform);
fizzlerTransform.position = scene->buttons[0].rigidBody.transform.position;
fizzlerTransform.position.y += 1.0f;
fizzlerInit(&scene->fizzlers[i], &fizzlerTransform, 2.0f, 2.0f);
}
} }
void sceneRenderWithProperties(void* data, struct RenderProps* properties, struct RenderState* renderState) { void sceneRenderWithProperties(void* data, struct RenderProps* properties, struct RenderState* renderState) {
@ -244,6 +254,10 @@ void sceneUpdate(struct Scene* scene) {
for (int i = 0; i < scene->decorCount; ++i) { for (int i = 0; i < scene->decorCount; ++i) {
decorObjectUpdate(scene->decor[i]); decorObjectUpdate(scene->decor[i]);
} }
for (int i = 0; i < scene->fizzlerCount; ++i) {
fizzlerUpdate(&scene->fizzlers[i]);
}
collisionSceneUpdateDynamics(); collisionSceneUpdateDynamics();

View file

@ -12,6 +12,7 @@
#include "button.h" #include "button.h"
#include "../decor/decor_object.h" #include "../decor/decor_object.h"
#include "./door.h" #include "./door.h"
#include "./fizzler.h"
#define MAX_CUBES 1 #define MAX_CUBES 1
@ -23,12 +24,14 @@ struct Scene {
struct Button* buttons; struct Button* buttons;
struct DecorObject** decor; struct DecorObject** decor;
struct Door* doors; struct Door* doors;
struct Fizzler* fizzlers;
OSTime cpuTime; OSTime cpuTime;
OSTime lastFrameStart; OSTime lastFrameStart;
OSTime lastFrameTime; OSTime lastFrameTime;
u8 buttonCount; u8 buttonCount;
u8 decorCount; u8 decorCount;
u8 doorCount; u8 doorCount;
u8 fizzlerCount;
}; };
extern struct Scene gScene; extern struct Scene gScene;