Most texure work
This commit is contained in:
97
util/crafter.c
Normal file
97
util/crafter.c
Normal file
@@ -0,0 +1,97 @@
|
||||
//
|
||||
// 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->tileX = tile->rect.x;
|
||||
out->tileY = tile->rect.y;
|
||||
out->offset = -0.5f;
|
||||
}
|
||||
}
|
37
util/crafter.h
Normal file
37
util/crafter.h
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// Created by bruno on 10.6.2025.
|
||||
//
|
||||
|
||||
#ifndef FACTORYGAME_CRAFTER_H
|
||||
#define FACTORYGAME_CRAFTER_H
|
||||
|
||||
#include "../items/item.h"
|
||||
|
||||
#define MATCHES(a, b, x, y) ((a == x && b == y) || (a == y && b == x))
|
||||
|
||||
|
||||
enum {
|
||||
SLOT_INPUT1 = 0,
|
||||
SLOT_INPUT2 = 1,
|
||||
SLOT_OUTPUT = 2,
|
||||
MACHINE_SLOTS = 3
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
ItemType input1;
|
||||
ItemType input2; // use TYPE_AIR if single-input
|
||||
ItemType output;
|
||||
uint16_t ticksRequired; // used for output delay
|
||||
} MachineRecipe;
|
||||
|
||||
void updateMachine(Tile *tile,
|
||||
const MachineRecipe *recipes, size_t recipeCount,
|
||||
uint8_t waveform, uint16_t freqStart, uint16_t freqStep);
|
||||
|
||||
bool findMachineRecipe(const MachineRecipe *recipes, size_t count, ItemType in1, ItemType in2,
|
||||
ItemType *out, uint16_t *ticks);
|
||||
|
||||
void initMachineTile(ItemType type, const MachineRecipe *recipes, size_t count,
|
||||
uint8_t startFrame, uint8_t divisor);
|
||||
|
||||
#endif //FACTORYGAME_CRAFTER_H
|
72
util/font.c
72
util/font.c
@@ -7,58 +7,78 @@
|
||||
BitmapFont fonts[fontCount];
|
||||
|
||||
|
||||
BitmapFont
|
||||
prepText(SDL_Renderer *renderer, unsigned char pxSize, const char *file, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
|
||||
BitmapFont prepText(SDL_Renderer *renderer, unsigned char pxSize, const char *file) {
|
||||
TTF_Font *gFont = TTF_OpenFont(file, pxSize);
|
||||
BitmapFont out;
|
||||
out.size = pxSize;
|
||||
out.color = (SDL_Color) {r, g, b, a};
|
||||
unsigned int i = 1;
|
||||
do {
|
||||
if (i == 173) { //specifically this char is 0 width (IDK why)
|
||||
out.surface[i] = SDL_CreateRGBSurface(0, pxSize, pxSize, 32, 0, 0, 0, 0);
|
||||
out.color = (SDL_Color) {255, 255, 255, 255};
|
||||
|
||||
const int glyphsPerRow = 16;
|
||||
const int glyphsPerCol = 16;
|
||||
const int atlasWidth = glyphsPerRow * (pxSize + 1);
|
||||
const int atlasHeight = glyphsPerCol * (pxSize + 1);
|
||||
|
||||
SDL_Surface *atlasSurface = SDL_CreateRGBSurface(0, atlasWidth, atlasHeight, 32,
|
||||
0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
|
||||
out.atlasRect.x = 0;
|
||||
out.atlasRect.y = 0;
|
||||
out.atlasRect.w = atlasWidth;
|
||||
out.atlasRect.h = atlasHeight;
|
||||
SDL_FillRect(atlasSurface, NULL, SDL_MapRGBA(atlasSurface->format, 0, 0, 0, 0)); // transparent
|
||||
|
||||
for (uint16_t i = 1; i < 256; i++) {
|
||||
SDL_Surface *surf;
|
||||
|
||||
if (i == 173) {
|
||||
surf = SDL_CreateRGBSurface(0, pxSize, pxSize, 32,
|
||||
0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
|
||||
SDL_FillRect(surf, NULL, SDL_MapRGBA(surf->format, 0, 0, 0, 0)); // transparent
|
||||
} else {
|
||||
char tmpOut[2] = {i, 0};
|
||||
out.surface[i] = TTF_RenderText_Solid(gFont, tmpOut, out.color);
|
||||
surf = TTF_RenderText_Solid(gFont, tmpOut, out.color);
|
||||
}
|
||||
out.texture[i] = SDL_CreateTextureFromSurface(renderer, out.surface[i]);
|
||||
i++;
|
||||
} while (i < 256);
|
||||
|
||||
int x = (i % glyphsPerRow) * (pxSize + 1);
|
||||
int y = (i / glyphsPerRow) * (pxSize + 1);
|
||||
|
||||
SDL_Rect dest = {x, y, pxSize, pxSize};
|
||||
SDL_BlitSurface(surf, NULL, atlasSurface, &dest);
|
||||
|
||||
out.glyphs[i] = dest;
|
||||
|
||||
SDL_FreeSurface(surf);
|
||||
}
|
||||
|
||||
out.atlas = SDL_CreateTextureFromSurface(renderer, atlasSurface);
|
||||
SDL_SetTextureBlendMode(out.atlas, SDL_BLENDMODE_BLEND);
|
||||
SDL_FreeSurface(atlasSurface);
|
||||
TTF_CloseFont(gFont);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void renderText(SDL_Renderer *renderer, BitmapFont font, char *string, uint16_t x, uint16_t y) {
|
||||
SDL_Rect charRect;
|
||||
charRect.x = 0;
|
||||
charRect.y = 0;
|
||||
charRect.w = font.size;
|
||||
charRect.h = font.size;
|
||||
SDL_Rect outRect = charRect;
|
||||
SDL_Rect outRect;
|
||||
outRect.x = x;
|
||||
outRect.y = y;
|
||||
outRect.w = font.size;
|
||||
outRect.h = font.size;
|
||||
|
||||
while (*string) {
|
||||
if (*string == '\n') {
|
||||
outRect.x = x;
|
||||
outRect.y += charRect.h + 4;
|
||||
outRect.y += outRect.h + 4;
|
||||
string++;
|
||||
continue;
|
||||
}
|
||||
SDL_RenderCopy(renderer, font.texture[*string], &charRect, &outRect); //TODO CONSIDER FONTS IN ONE ATLAS
|
||||
outRect.x += charRect.w + 1;
|
||||
SDL_RenderCopy(renderer, font.atlas, &font.glyphs[*string], &outRect); //TODO CONSIDER FONTS IN ONE ATLAS
|
||||
outRect.x += outRect.w + 1;
|
||||
string++;
|
||||
}
|
||||
}
|
||||
|
||||
void destroyFont(BitmapFont *font) {
|
||||
for (uint16_t i = 1; i < 256; i++) {
|
||||
if (font->texture[i]) {
|
||||
SDL_DestroyTexture(font->texture[i]);
|
||||
}
|
||||
if (font->surface[i]) {
|
||||
SDL_FreeSurface(font->surface[i]);
|
||||
}
|
||||
SDL_DestroyTexture(font->atlas);
|
||||
}
|
||||
}
|
13
util/font.h
13
util/font.h
@@ -9,19 +9,20 @@
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
#include <math.h>
|
||||
|
||||
#define fontCount 4
|
||||
#define fontCount 5
|
||||
|
||||
typedef struct BitmapFont {
|
||||
SDL_Texture *texture[256];
|
||||
SDL_Surface *surface[256];
|
||||
typedef struct {
|
||||
SDL_Texture *atlas;
|
||||
SDL_Rect glyphs[256];
|
||||
uint8_t size;
|
||||
SDL_Rect atlasRect;
|
||||
SDL_Color color;
|
||||
} BitmapFont;
|
||||
|
||||
|
||||
extern BitmapFont fonts[fontCount];
|
||||
|
||||
BitmapFont
|
||||
prepText(SDL_Renderer *renderer, unsigned char pxSize, const char *file, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
|
||||
BitmapFont prepText(SDL_Renderer *renderer, unsigned char pxSize, const char *file);
|
||||
|
||||
void destroyFont(BitmapFont *font);
|
||||
|
||||
|
@@ -134,7 +134,7 @@ void renderBar(SDL_Renderer *renderer,
|
||||
char barString[20];
|
||||
sprintf(barString, "%d/%d", currentValue, maxValue);
|
||||
|
||||
renderText(mainRenderer, fonts[3], barString, width / 2, margin);
|
||||
renderText(mainRenderer, fonts[1], barString, x + (width / 2 - (fonts[2].size * strlen(barString))), y - fonts[2].size - barRect.h);
|
||||
}
|
||||
|
||||
int cmpstringp(const void *p1, const void *p2) {
|
||||
|
@@ -38,7 +38,6 @@ extern bool itemViewing;
|
||||
extern bool renderAtlas;
|
||||
|
||||
typedef struct Animation {
|
||||
SDL_Texture *textures[TILE_SIZE];
|
||||
SDL_Rect atlasRects[TILE_SIZE];
|
||||
unsigned char frameCount;
|
||||
unsigned char divisor;
|
||||
@@ -46,10 +45,10 @@ typedef struct Animation {
|
||||
|
||||
|
||||
typedef struct OrientedAnimation {
|
||||
SDL_Texture *textures[ORIENT_DIRECTION_COUNT][TILE_SIZE * 2];
|
||||
SDL_Rect atlasRects[ORIENT_DIRECTION_COUNT][TILE_SIZE * 2];
|
||||
unsigned char frameCount;
|
||||
unsigned char divisor;
|
||||
char startFrame;
|
||||
} OrientedAnimation;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user