Most texure work
This commit is contained in:
14
tiles/belt.c
14
tiles/belt.c
@@ -9,10 +9,15 @@
|
||||
#include "../player/player.h"
|
||||
#include "../items/item.h"
|
||||
#include "../util/atlas.h"
|
||||
#include "../util/font.h"
|
||||
|
||||
void generateBeltFrames(SDL_Renderer *renderer) {
|
||||
SDL_Texture *baseTexture = TileRegistry[TYPE_BELT].animation.textures[ORIENT_LEFT][0]; // Base belt tile
|
||||
SDL_Texture *baseTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET,
|
||||
TILE_SIZE,
|
||||
TILE_SIZE);
|
||||
SDL_Texture *oldTarget = SDL_GetRenderTarget(renderer);
|
||||
SDL_SetRenderTarget(renderer, baseTexture);
|
||||
SDL_RenderCopy(renderer, atlasTexture, &TileRegistry[TYPE_BELT].animation.atlasRects[ORIENT_LEFT][0], NULL);
|
||||
const int frameCount = TILE_SIZE; // 32 frames, 1px per frame = full seamless loop
|
||||
|
||||
for (OrientDirection dir = ORIENT_LEFT_DOWN; dir < ORIENT_DIRECTION_COUNT; dir++) {
|
||||
@@ -79,7 +84,6 @@ void generateBeltFrames(SDL_Renderer *renderer) {
|
||||
SDL_RenderCopy(renderer, rotated, NULL, &dst1);
|
||||
SDL_RenderCopy(renderer, rotated, NULL, &dst2);
|
||||
|
||||
TileRegistry[TYPE_BELT].animation.textures[dir][f] = frame;
|
||||
TileRegistry[TYPE_BELT].animation.atlasRects[dir][f] = allocate_32x32(frame, renderer);
|
||||
}
|
||||
|
||||
@@ -88,6 +92,7 @@ void generateBeltFrames(SDL_Renderer *renderer) {
|
||||
TileRegistry[TYPE_BELT].animation.divisor = 1;
|
||||
}
|
||||
|
||||
SDL_DestroyTexture(baseTexture);
|
||||
SDL_SetRenderTarget(renderer, oldTarget);
|
||||
}
|
||||
|
||||
@@ -103,4 +108,9 @@ void renderBelt(int x, int y, int w, int h, OrientDirection dir, SDL_Rect player
|
||||
(animationStep / TileRegistry[TYPE_BELT].animation.divisor) %
|
||||
TileRegistry[TYPE_BELT].animation.frameCount],
|
||||
&dst);
|
||||
if (tileMap[y][x].health < TileRegistry[TYPE_BELT].maxHealth) {
|
||||
char healthStr[12];
|
||||
snprintf(healthStr, 12, "%d/%d", tileMap[y][x].health, TileRegistry[tileMap[y][x].type].maxHealth);
|
||||
renderText(renderer, fonts[3], healthStr, dst.x, dst.y);
|
||||
}
|
||||
}
|
@@ -6,58 +6,20 @@
|
||||
#include "tile.h"
|
||||
#include "../util/audio.h"
|
||||
|
||||
const ItemType FurnaceRecipes[ITEMREGISTRY_SIZE] = {
|
||||
[IRON_ORE] = IRON_INGOT,
|
||||
[SILVER_ORE] = SILVER_INGOT,
|
||||
[GOLD_ORE] = GOLD_INGOT,
|
||||
[PLATINUM_ORE] = PLATINUM_INGOT
|
||||
|
||||
const MachineRecipe FurnaceRecipes[] = {
|
||||
{IRON_ORE, TYPE_AIR, IRON_INGOT, 60},
|
||||
{SILVER_ORE, TYPE_AIR, SILVER_INGOT, 70},
|
||||
{GOLD_ORE, TYPE_AIR, GOLD_INGOT, 80},
|
||||
{PLATINUM_ORE, TYPE_AIR, PLATINUM_INGOT, 90}
|
||||
};
|
||||
|
||||
void initFurnaceTile() {
|
||||
initMachineTile(TYPE_FURNACE, FurnaceRecipes, sizeof(FurnaceRecipes) / sizeof(FurnaceRecipes[0]),
|
||||
1, /* start frame */
|
||||
8 /* frame divisor */);
|
||||
}
|
||||
|
||||
void updateFurnace(Tile *tile) {
|
||||
ItemOnBelt *inItem = &tile->items[FURNACE_INPUT_SLOT];
|
||||
ItemOnBelt *outItem = &tile->items[FURNACE_OUTPUT_SLOT];
|
||||
Item inItemType = ItemRegistry[inItem->type];
|
||||
|
||||
ItemType targetOutItemType = FurnaceRecipes[inItem->type];
|
||||
|
||||
Item targetOutItem = ItemRegistry[targetOutItemType];
|
||||
|
||||
if (targetOutItemType != TYPE_AIR) {
|
||||
if (tile->miscVal == 0) {
|
||||
if (outItem->type != TYPE_AIR) {
|
||||
if (tile->audioCh < NUM_SYNTH_VOICES) {
|
||||
audioData.synthVoices[tile->audioCh].volume = 0;
|
||||
}
|
||||
tile->fixedFrame = 1;
|
||||
return;
|
||||
}
|
||||
tile->audioCh = getAvailableChannel();
|
||||
if (tile->audioCh < NUM_SYNTH_VOICES) {
|
||||
audioData.synthVoices[tile->audioCh].volume = 255;
|
||||
audioData.synthVoices[tile->audioCh].phase = 0;
|
||||
audioData.synthVoices[tile->audioCh].sourceRect.x = TILE_SIZE * tile->rect.x;
|
||||
audioData.synthVoices[tile->audioCh].sourceRect.y = TILE_SIZE * tile->rect.y;
|
||||
audioData.synthVoices[tile->audioCh].waveform = WAVE_SINE;
|
||||
audioData.synthVoices[tile->audioCh].frequency = 200;
|
||||
}
|
||||
tile->fixedFrame = 0;
|
||||
}
|
||||
++audioData.synthVoices[tile->audioCh].frequency;
|
||||
if (audioData.synthVoices[tile->audioCh].volume < 255) {
|
||||
audioData.synthVoices[tile->audioCh].volume++;
|
||||
}
|
||||
if (outItem->type == 0 && ++tile->miscVal >= targetOutItem.miscVal) {
|
||||
if (tile->audioCh < NUM_SYNTH_VOICES) {
|
||||
audioData.synthVoices[tile->audioCh].volume = 0;
|
||||
}
|
||||
tile->fixedFrame = 1;
|
||||
tile->miscVal = 0;
|
||||
inItem->type = 0;
|
||||
outItem->type = targetOutItemType;
|
||||
outItem->offset = -0.5f;
|
||||
}
|
||||
} else {
|
||||
tile->fixedFrame = 1;
|
||||
}
|
||||
updateMachine(tile, FurnaceRecipes, sizeof(FurnaceRecipes) / sizeof(FurnaceRecipes[0]), WAVE_SINE, 200, 1);
|
||||
}
|
@@ -7,8 +7,15 @@
|
||||
|
||||
#include "../items/item.h"
|
||||
#include "stdint.h"
|
||||
#include "../util/crafter.h"
|
||||
|
||||
extern const ItemType FurnaceRecipes[];
|
||||
// Suppose this is defined somewhere
|
||||
extern const MachineRecipe FurnaceRecipes[];
|
||||
extern const size_t FurnaceRecipeCount;
|
||||
|
||||
void updateFurnace(Tile *tile);
|
||||
|
||||
void initFurnaceTile();
|
||||
|
||||
#define FURNACE_INPUT_SLOT 0
|
||||
#define FURNACE_OUTPUT_SLOT 1
|
||||
|
@@ -8,8 +8,6 @@
|
||||
#include "../items/item.h"
|
||||
#include "stdint.h"
|
||||
|
||||
extern const ItemType FurnaceRecipes[];
|
||||
|
||||
#define MINER_OUTPUT_SLOT 0
|
||||
|
||||
void updateMiner(Tile * tile);
|
||||
|
61
tiles/tile.c
61
tiles/tile.c
@@ -113,7 +113,6 @@ void registerTile(char fname[20], SDL_Renderer *renderer) {
|
||||
};
|
||||
|
||||
// printf("Bound %s to %d orient %s\n", fname, indexTile, OrientStrings[o]);
|
||||
TileRegistry[indexTile].animation.textures[o][frame] = textures[o];
|
||||
SDL_SetTextureBlendMode(textures[o], SDL_BLENDMODE_BLEND);
|
||||
TileRegistry[indexTile].animation.atlasRects[o][frame] = allocate_32x32(textures[o], renderer);
|
||||
}
|
||||
@@ -126,6 +125,10 @@ void registerTile(char fname[20], SDL_Renderer *renderer) {
|
||||
|
||||
TileRegistry[indexTile].type = tileTypeIndex;
|
||||
TileRegistry[indexTile].breakTime = 15;
|
||||
TileRegistry[indexTile].itemMoves = false;
|
||||
TileRegistry[indexTile].walkable = false;
|
||||
TileRegistry[indexTile].needsTicks = false;
|
||||
TileRegistry[indexTile].updateTileCallback = NULL;
|
||||
|
||||
if (indexTile + 1 > tileTypeIndex) {
|
||||
tileTypeIndex = indexTile + 1;
|
||||
@@ -159,7 +162,6 @@ void registerBackgroundTile(char fname[20], SDL_Renderer *renderer) {
|
||||
|
||||
//printf("Bound %s to %d\n", fname, indexBgTile);
|
||||
|
||||
BackgroundTileRegistry[indexBgTile].animation.textures[frame] = texture;
|
||||
BackgroundTileRegistry[indexBgTile].animation.atlasRects[frame] = allocate_32x32(texture, renderer);
|
||||
|
||||
BackgroundTileRegistry[indexBgTile].type = indexBgTile;
|
||||
@@ -257,6 +259,17 @@ void loadBackgroundTiles(SDL_Renderer *renderer) {
|
||||
}
|
||||
}
|
||||
|
||||
void preSetupTiles() {
|
||||
TileRegistry[TYPE_MINER].animation.startFrame = 1;
|
||||
TileRegistry[TYPE_FURNACE].animation.divisor = 8;
|
||||
TileRegistry[TYPE_CORE].animation.divisor = 8;
|
||||
BackgroundTileRegistry[BGType_WATER_DEEP].animation.divisor = 16;
|
||||
BackgroundTileRegistry[BGType_WATER_SHALLOW].animation.divisor = 12;
|
||||
BackgroundTileRegistry[BGType_GRASS_FLOWER0].animation.divisor = 16;
|
||||
BackgroundTileRegistry[BGType_GRASS_FLOWER1].animation.divisor = 16;
|
||||
BackgroundTileRegistry[BGType_GRASS_FLOWER2].animation.divisor = 16;
|
||||
}
|
||||
|
||||
void setupTiles() {
|
||||
TileRegistry[TYPE_AIR].breakTime = 0;
|
||||
TileRegistry[TYPE_BELT].itemMoves = true;
|
||||
@@ -268,33 +281,34 @@ void setupTiles() {
|
||||
TileRegistry[TYPE_BELT].allowedInItems[l][i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (ItemType i = 0; i < itemRegistryIndex; i++) {
|
||||
if (FurnaceRecipes[i] != 0) {
|
||||
TileRegistry[TYPE_FURNACE].allowedInItems[FURNACE_INPUT_SLOT][i] = true;
|
||||
}
|
||||
TileRegistry[TYPE_SPLITTER].allowedInItems[0][i] = true;
|
||||
}
|
||||
; TileRegistry[TYPE_FURNACE].outputLane[FURNACE_OUTPUT_SLOT] = 1;
|
||||
TileRegistry[TYPE_FURNACE].startFrame = 1;
|
||||
TileRegistry[TYPE_SPLITTER].outputLane[0] = true;
|
||||
TileRegistry[TYPE_SPLITTER].needsTicks = true;
|
||||
TileRegistry[TYPE_SPLITTER].walkable = true;
|
||||
TileRegistry[TYPE_SPLITTER].allDir = true;
|
||||
|
||||
TileRegistry[TYPE_FURNACE].outputLane[FURNACE_OUTPUT_SLOT] = 1;
|
||||
TileRegistry[TYPE_FURNACE].animation.startFrame = 1;
|
||||
TileRegistry[TYPE_FURNACE].needsTicks = true;
|
||||
TileRegistry[TYPE_FURNACE].animation.divisor = 8;
|
||||
TileRegistry[TYPE_BELT].needsTicks = true;
|
||||
TileRegistry[TYPE_BELT].walkable = true;
|
||||
TileRegistry[TYPE_MINER].needsTicks = true;
|
||||
TileRegistry[TYPE_MINER].outputLane[MINER_OUTPUT_SLOT] = 1;
|
||||
TileRegistry[TYPE_MINER].startFrame = 1;
|
||||
TileRegistry[TYPE_AIR].walkable = true;
|
||||
|
||||
TileRegistry[TYPE_TURRET].needsTicks = true;
|
||||
TileRegistry[TYPE_TURRET].allowedInItems[TURRET_AMMO_INPUT_SLOT][IRON_INGOT] = true;
|
||||
for (ItemType i = 0; i < ITEMREGISTRY_SIZE; i++) {
|
||||
if (AmmoDamages[i] > 0)
|
||||
TileRegistry[TYPE_TURRET].allowedInItems[TURRET_AMMO_INPUT_SLOT][i] = true;
|
||||
}
|
||||
|
||||
|
||||
BackgroundTileRegistry[BGType_WATER_DEEP].animation.divisor = 16;
|
||||
BackgroundTileRegistry[BGType_WATER_SHALLOW].animation.divisor = 12;
|
||||
BackgroundTileRegistry[BGType_GRASS_FLOWER0].animation.divisor = 16;
|
||||
BackgroundTileRegistry[BGType_GRASS_FLOWER1].animation.divisor = 16;
|
||||
BackgroundTileRegistry[BGType_GRASS_FLOWER2].animation.divisor = 16;
|
||||
BackgroundTileRegistry[BGType_WATER_SHALLOW].walkable = false;
|
||||
BackgroundTileRegistry[BGType_WATER_DEEP].walkable = false;
|
||||
|
||||
initFurnaceTile();
|
||||
}
|
||||
|
||||
uint16_t getBreakTime(int type) {
|
||||
@@ -358,8 +372,6 @@ void renderAllTiles(SDL_Renderer *renderer, SDL_Rect playerRect) {
|
||||
printf("Error on tile %d, %d\n", x, y);
|
||||
backgroundMap[y][x].type = BGType_PLATINUM_ORE;
|
||||
} else {
|
||||
SDL_Texture *tex = BackgroundTileRegistry[bt.type].animation.textures[animationStep %
|
||||
BackgroundTileRegistry[bt.type].animation.frameCount];
|
||||
SDL_Rect atlRect = BackgroundTileRegistry[bt.type].animation.atlasRects[
|
||||
(animationStep / BackgroundTileRegistry[bt.type].animation.divisor) %
|
||||
BackgroundTileRegistry[bt.type].animation.frameCount];
|
||||
@@ -396,20 +408,23 @@ void renderAllTiles(SDL_Renderer *renderer, SDL_Rect playerRect) {
|
||||
default: {
|
||||
char animationFrame = ((animationStep / TileRegistry[t.type].animation.divisor) %
|
||||
(TileRegistry[t.type].animation.frameCount -
|
||||
TileRegistry[t.type].startFrame)) + TileRegistry[t.type].startFrame;
|
||||
TileRegistry[t.type].animation.startFrame)) +
|
||||
TileRegistry[t.type].animation.startFrame;
|
||||
if (t.fixedFrame > 0) {
|
||||
animationFrame = t.fixedFrame - 1;
|
||||
}
|
||||
SDL_Rect atlRect = TileRegistry[t.type].animation.atlasRects[t.direction][animationFrame];
|
||||
SDL_Texture *tex = TileRegistry[t.type].animation.textures[t.direction][animationFrame];
|
||||
if (atlRect.w == 0 || atlRect.h == 0) {
|
||||
tex = TileRegistry[t.type].animation.textures[ORIENT_LEFT][animationFrame];
|
||||
atlRect = TileRegistry[t.type].animation.atlasRects[ORIENT_LEFT][
|
||||
animationFrame];
|
||||
}
|
||||
if (atlRect.w != 0 && atlRect.h != 0) {
|
||||
//SDL_RenderCopy(renderer, tex, NULL, &dstRect);
|
||||
SDL_RenderCopy(renderer, atlasTexture, &atlRect, &dstRect);
|
||||
if (t.health < TileRegistry[t.type].maxHealth) {
|
||||
char healthStr[12];
|
||||
snprintf(healthStr, 12, "%d/%d", t.health, TileRegistry[t.type].maxHealth);
|
||||
renderText(renderer, fonts[3], healthStr, dstRect.x, dstRect.y);
|
||||
}
|
||||
// if (t.health < TileRegistry[t.type].maxHealth) {
|
||||
// SDL_Color tileHealthColor = {(t.health / TileRegistry[t.type].maxHealth ) * 255, (TileRegistry[t.type].maxHealth / t.health) * 255, 0, 255};
|
||||
// renderBar(mainRenderer, x * TILE_SIZE, (y * TILE_SIZE) + (TILE_SIZE / 2), TILE_SIZE, 8,
|
||||
@@ -439,7 +454,7 @@ void renderAllTiles(SDL_Renderer *renderer, SDL_Rect playerRect) {
|
||||
.h = TILE_SIZE
|
||||
};
|
||||
adjustRect(&dstRect, playerRect);
|
||||
renderText(renderer, fonts[3], locChar, dstRect.x, dstRect.y);
|
||||
renderText(renderer, fonts[4], locChar, dstRect.x, dstRect.y);
|
||||
}
|
||||
if (t.type == TYPE_BELT || itemViewing) {
|
||||
for (uint8_t lane = 0; lane < ItemSlotCount; lane++) {
|
||||
|
10
tiles/tile.h
10
tiles/tile.h
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "../util/util.h"
|
||||
#include "../items/item.h"
|
||||
#include "tilecallbacks.h"
|
||||
|
||||
#define MAP_WIDTH 500
|
||||
#define MAP_HEIGHT 500
|
||||
@@ -83,6 +84,8 @@ typedef enum BackgroundType {
|
||||
#define MAX_BASE_NAMES 512
|
||||
#define MAX_ANIMATION_FRAMES 32
|
||||
|
||||
typedef void (*UpdateTileCallback)(struct Tile *tile);
|
||||
|
||||
typedef struct TileTypeReg {
|
||||
ItemType type;
|
||||
char name[20];
|
||||
@@ -92,9 +95,10 @@ typedef struct TileTypeReg {
|
||||
bool allowedInItems[ItemSlotCount][ITEMREGISTRY_SIZE];
|
||||
bool outputLane[ItemSlotCount];
|
||||
bool needsTicks;
|
||||
char startFrame;
|
||||
bool walkable;
|
||||
bool allDir;
|
||||
uint16_t maxHealth;
|
||||
UpdateTileCallback updateTileCallback;
|
||||
} TileTypeReg;
|
||||
|
||||
bool isWalkable(MiniRect tileCoords);
|
||||
@@ -141,7 +145,7 @@ typedef struct Tile {
|
||||
int neededUpdateIndex;
|
||||
char fixedFrame;
|
||||
PathFindDat pathFind;
|
||||
uint16_t health;
|
||||
int16_t health;
|
||||
} Tile;
|
||||
|
||||
|
||||
@@ -151,6 +155,8 @@ extern BackgroundTile backgroundMap[MAP_HEIGHT][MAP_WIDTH];
|
||||
|
||||
void setupTiles();
|
||||
|
||||
void preSetupTiles();
|
||||
|
||||
void generateTestMap();
|
||||
|
||||
void loadBackgroundTiles(SDL_Renderer *renderer);
|
||||
|
111
tiles/turret.c
111
tiles/turret.c
@@ -8,7 +8,14 @@
|
||||
#include "../entity/entity.h"
|
||||
|
||||
const uint16_t AmmoDamages[ITEMREGISTRY_SIZE] = {
|
||||
[IRON_INGOT] = 1
|
||||
[IRON_INGOT] = 2,
|
||||
[GOLD_INGOT] = 1,
|
||||
[SILVER_INGOT] = 3,
|
||||
[PLATINUM_INGOT] = 5,
|
||||
[IRON_BULLET] = 20,
|
||||
[GOLD_BULLET] = 10,
|
||||
[SILVER_BULLET] = 30,
|
||||
[PLATINUM_BULLET] = 50,
|
||||
};
|
||||
|
||||
void updateTurret(Tile *tile) {
|
||||
@@ -17,45 +24,77 @@ void updateTurret(Tile *tile) {
|
||||
|
||||
uint16_t damage = AmmoDamages[inItem->type];
|
||||
|
||||
if (damage > 0) {
|
||||
bool foundEnt = false;
|
||||
// Reduce cooldown (miscVal) if above 0
|
||||
if (tile->miscVal > 0) {
|
||||
tile->miscVal--;
|
||||
}
|
||||
|
||||
for (int i = 0; i < entities.activeCount; i++) {
|
||||
Entity *ent = &entities.entities[i];
|
||||
int dx = abs(ent->renderRect.x - (tile->rect.x * TILE_SIZE));
|
||||
int dy = abs(ent->renderRect.y - (tile->rect.y * TILE_SIZE));
|
||||
int d = sqrt(pow(dx, 2) + pow(dy, 2));
|
||||
if (d <= (TILE_SIZE * 8)) {
|
||||
ent->health -= damage;
|
||||
inItem->type = 0;
|
||||
tile->audioCh = getAvailableChannel();
|
||||
if (tile->audioCh < NUM_SYNTH_VOICES) {
|
||||
audioData.synthVoices[tile->audioCh].volume = 255;
|
||||
audioData.synthVoices[tile->audioCh].phase = 0;
|
||||
audioData.synthVoices[tile->audioCh].sourceRect.x = TILE_SIZE * tile->rect.x;
|
||||
audioData.synthVoices[tile->audioCh].sourceRect.y = TILE_SIZE * tile->rect.y;
|
||||
audioData.synthVoices[tile->audioCh].waveform = WAVE_TRIANGLE;
|
||||
audioData.synthVoices[tile->audioCh].frequency = 400;
|
||||
}
|
||||
tile->fixedFrame = 0;
|
||||
foundEnt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundEnt) {
|
||||
audioData.synthVoices[tile->audioCh].volume = 0;
|
||||
tile->fixedFrame = 1;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
// If there's no ammo or it's invalid, stop the sound and return
|
||||
if (damage == 0) {
|
||||
if (tile->audioCh < NUM_SYNTH_VOICES) {
|
||||
audioData.synthVoices[tile->audioCh].volume = 0;
|
||||
}
|
||||
tile->fixedFrame = 1;
|
||||
if (animationStep % (TileRegistry[tile->type].animation.frameCount - 1) == 0) {
|
||||
tile->fixedFrame = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (audioData.synthVoices[tile->audioCh].frequency > 80) {
|
||||
audioData.synthVoices[tile->audioCh].frequency--;
|
||||
|
||||
// Search for a target entity
|
||||
bool foundEnt = false;
|
||||
for (int i = 0; i < entities.activeCount; i++) {
|
||||
Entity *ent = &entities.entities[i];
|
||||
int dx = abs(ent->renderRect.x - (tile->rect.x * TILE_SIZE));
|
||||
int dy = abs(ent->renderRect.y - (tile->rect.y * TILE_SIZE));
|
||||
int d = sqrt(dx * dx + dy * dy);
|
||||
|
||||
if (d <= (TILE_SIZE * 8)) {
|
||||
foundEnt = true;
|
||||
|
||||
if (tile->miscVal == 0) {
|
||||
// Do damage and consume ammo
|
||||
ent->health -= damage;
|
||||
inItem->type = 0;
|
||||
|
||||
// Get or reuse audio channel
|
||||
if (tile->audioCh >= NUM_SYNTH_VOICES) {
|
||||
tile->audioCh = getAvailableChannel();
|
||||
}
|
||||
|
||||
if (tile->audioCh < NUM_SYNTH_VOICES) {
|
||||
SynthVoice *voice = &audioData.synthVoices[tile->audioCh];
|
||||
voice->volume = 255;
|
||||
voice->phase = 0;
|
||||
voice->sourceRect.x = tile->rect.x * TILE_SIZE;
|
||||
voice->sourceRect.y = tile->rect.y * TILE_SIZE;
|
||||
voice->waveform = WAVE_TRIANGLE;
|
||||
voice->frequency = 400;
|
||||
}
|
||||
|
||||
tile->fixedFrame = 0;
|
||||
tile->miscVal = 20; // Cooldown (ticks) until next fire
|
||||
}
|
||||
|
||||
break; // Only shoot one entity
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No entity found? Fade sound out
|
||||
if (!foundEnt && tile->audioCh < NUM_SYNTH_VOICES) {
|
||||
SynthVoice *voice = &audioData.synthVoices[tile->audioCh];
|
||||
if (voice->volume > 0) {
|
||||
voice->volume--;
|
||||
}
|
||||
if (animationStep % (TileRegistry[tile->type].animation.frameCount - 1) == 0) {
|
||||
tile->fixedFrame = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Lower frequency for pitch effect if it's still playing
|
||||
if (tile->audioCh < NUM_SYNTH_VOICES) {
|
||||
SynthVoice *voice = &audioData.synthVoices[tile->audioCh];
|
||||
if (voice->frequency > 80) {
|
||||
voice->frequency--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user