Files
factorygame/util/crafter.c
2025-06-11 15:42:06 +02:00

99 lines
3.1 KiB
C

//
// Created by bruno on 10.6.2025.
//
#include "crafter.h"
#include "audio.h"
void initMachineTile(ItemType type, const MachineRecipe *recipes, size_t count, uint8_t startFrame, uint8_t divisor) {
// Force slot assignments for allowed items based on recipes
for (size_t i = 0; i < count; i++) {
const MachineRecipe *r = &recipes[i];
if (r->input1 != TYPE_AIR)
TileRegistry[type].allowedInItems[SLOT_INPUT1][r->input1] = true;
if (r->input2 != TYPE_AIR)
TileRegistry[type].allowedInItems[SLOT_INPUT2][r->input2] = true;
}
// Output slot is fixed to SLOT_OUTPUT
TileRegistry[type].outputLane[SLOT_OUTPUT] = 1;
// Animation and behavior settings
TileRegistry[type].animation.startFrame = startFrame;
TileRegistry[type].animation.divisor = divisor;
TileRegistry[type].needsTicks = true;
}
bool findMachineRecipe(const MachineRecipe *recipes, size_t count, ItemType in1, ItemType in2,
ItemType *out, uint16_t *ticks) {
for (size_t i = 0; i < count; i++) {
const MachineRecipe *r = &recipes[i];
if (r->input1 == in1 && r->input2 == in2) {
*out = r->output;
*ticks = r->ticksRequired;
return true;
}
}
return false;
}
void updateMachine(Tile *tile,
const MachineRecipe *recipes, size_t recipeCount,
uint8_t waveform, uint16_t freqStart, uint16_t freqStep) {
ItemOnBelt *in1 = &tile->items[SLOT_INPUT1];
ItemOnBelt *in2 = &tile->items[SLOT_INPUT2];
ItemOnBelt *out = &tile->items[SLOT_OUTPUT];
ItemType result;
uint16_t ticksNeeded;
if (!findMachineRecipe(recipes, recipeCount, in1->type, in2->type, &result, &ticksNeeded)) {
tile->fixedFrame = 1;
return;
}
if (tile->miscVal == 0) {
if (out->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) {
SynthVoice *v = &audioData.synthVoices[tile->audioCh];
v->volume = 255;
v->phase = 0;
v->waveform = waveform;
v->frequency = freqStart;
v->sourceRect.x = TILE_SIZE * tile->rect.x;
v->sourceRect.y = TILE_SIZE * tile->rect.y;
}
tile->fixedFrame = 0;
}
if (tile->audioCh < NUM_SYNTH_VOICES) {
SynthVoice *v = &audioData.synthVoices[tile->audioCh];
v->frequency += freqStep;
}
if (++tile->miscVal >= ticksNeeded) {
if (tile->audioCh < NUM_SYNTH_VOICES)
audioData.synthVoices[tile->audioCh].volume = 0;
tile->miscVal = 0;
tile->fixedFrame = 1;
in1->type = TYPE_AIR;
if (in2->type != TYPE_AIR) in2->type = TYPE_AIR;
out->type = result;
out->prevTile = out->tile;
out->tile.x = tile->rect.x;
out->tile.y = tile->rect.y;
out->offset = -0.5f;
}
}