Most texure work
This commit is contained in:
216
items/item.c
216
items/item.c
@@ -42,6 +42,72 @@ bool putOntoNext(ItemOnBelt *itm, int nx, int ny, Tile *next, TileTypeReg *ntt,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OrientDirection rotateMainDirection(OrientDirection dir, int steps) {
|
||||
|
||||
// The main directions indices array
|
||||
int mainDirs[] = {1, 3, 5, 7};
|
||||
int count = 4;
|
||||
|
||||
// Find index of dir in mainDirs
|
||||
int index = 0;
|
||||
for (; index < count; index++) {
|
||||
if (mainDirs[index] == dir) break;
|
||||
}
|
||||
if (index == count) index = 0; // fallback
|
||||
|
||||
// Rotate steps (positive = clockwise, negative = counterclockwise)
|
||||
int newIndex = (index + steps) % count;
|
||||
if (newIndex < 0) newIndex += count;
|
||||
|
||||
return (OrientDirection)mainDirs[newIndex];
|
||||
}
|
||||
|
||||
// Map 8 directions to main 4 for code output
|
||||
int map8To4DirectionCode(OrientDirection dir) {
|
||||
switch (dir) {
|
||||
case ORIENT_LEFT:
|
||||
return 4; // left
|
||||
|
||||
case ORIENT_UP:
|
||||
return 5; // up
|
||||
|
||||
case ORIENT_RIGHT:
|
||||
return 2; // right
|
||||
|
||||
case ORIENT_DOWN:
|
||||
return 3; // down
|
||||
|
||||
default:
|
||||
return 1; // undefined/error
|
||||
}
|
||||
}
|
||||
|
||||
int getDirectionCode(OrientDirection dir, OrientDirection dir2) {
|
||||
// Apply dir2 rotation:
|
||||
switch (dir2) {
|
||||
case ORIENT_UP:
|
||||
// no change
|
||||
break;
|
||||
case ORIENT_LEFT:
|
||||
// move dir one step to the right (clockwise)
|
||||
dir = rotateMainDirection(dir, +1);
|
||||
break;
|
||||
case ORIENT_RIGHT:
|
||||
// move dir one step to the left (counterclockwise)
|
||||
dir = rotateMainDirection(dir, -1);
|
||||
break;
|
||||
case ORIENT_DOWN:
|
||||
// move dir two steps to the left (counterclockwise)
|
||||
dir = rotateMainDirection(dir, -2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return map8To4DirectionCode(dir);
|
||||
}
|
||||
|
||||
|
||||
void updateItems() {
|
||||
|
||||
for (int i = 0; i < neededUpdates.activeCount; i++) {
|
||||
@@ -70,52 +136,87 @@ void updateItems() {
|
||||
itm->offset -= 1.0f;
|
||||
}
|
||||
|
||||
// target coords
|
||||
int nx = x + dirDx[dir];
|
||||
int ny = y + dirDy[dir];
|
||||
|
||||
// bounds & belt?
|
||||
if (nx < 0 || nx >= MAP_WIDTH || ny < 0 || ny >= MAP_HEIGHT) {
|
||||
if (tt.itemMoves) {
|
||||
itm->offset += 1.0f - speed;
|
||||
}
|
||||
continue;
|
||||
int inputDir = -1; // invalid by default
|
||||
// Only valid if this tile is a belt and we can infer the input direction
|
||||
if (tt.itemMoves) {
|
||||
inputDir = (t->direction + 2) % 4; // Assume item entered from opposite of its direction
|
||||
}
|
||||
Tile *next = &tileMap[ny][nx];
|
||||
TileTypeReg ntt = TileRegistry[next->type];
|
||||
int newLane = lane;
|
||||
switch (next->type) {
|
||||
case TYPE_BELT:
|
||||
int newDir = next->direction;
|
||||
bool nH = (newDir == ORIENT_LEFT || newDir == ORIENT_RIGHT);
|
||||
bool nV = (newDir == ORIENT_UP || newDir == ORIENT_DOWN);
|
||||
|
||||
if ((horz && nH) || (vert && nV)) {
|
||||
// same axis → keep lane
|
||||
} else if (horz && nV) {
|
||||
// came off a horizontal: lane0=top→vertical.left, lane1=bottom→vertical.right
|
||||
newLane = (dir == ORIENT_RIGHT ^ newDir == ORIENT_UP ? 0 : 1);
|
||||
itm->offset = 0.0f;
|
||||
} else if (vert && nH) {
|
||||
// came off vertical: lane0=left→horizontal.top, lane1=right→horizontal.bottom
|
||||
newLane = (dir == ORIENT_UP ^ newDir == ORIENT_RIGHT ? 1 : 0);
|
||||
itm->offset = 0.0f;
|
||||
bool handled = false;
|
||||
if (tt.allDir) {
|
||||
for (OrientDirection outDir = 0; outDir < ORIENT_DIRECTION_COUNT; outDir++) {
|
||||
if (outDir == inputDir) continue; // skip input dir
|
||||
|
||||
int nx = x + dirDx[outDir];
|
||||
int ny = y + dirDy[outDir];
|
||||
|
||||
if (nx < 0 || nx >= MAP_WIDTH || ny < 0 || ny >= MAP_HEIGHT)
|
||||
continue;
|
||||
|
||||
Tile *next = &tileMap[ny][nx];
|
||||
TileTypeReg ntt = TileRegistry[next->type];
|
||||
|
||||
// Try to put item into any slot
|
||||
for (uint8_t nLane = 0; nLane < ItemSlotCount; nLane++) {
|
||||
if (putOntoNext(itm, nx, ny, next, &ntt, nLane)) {
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// (diagonals fall back to same-lane)
|
||||
|
||||
// Find a free slot in
|
||||
break;
|
||||
|
||||
default:
|
||||
itm->offset += 1.0f - speed;
|
||||
}
|
||||
|
||||
|
||||
if (!putOntoNext(itm, nx, ny, next, &ntt, newLane) && next->type != TYPE_BELT) {
|
||||
for (uint8_t nLane = 0; nLane < ItemSlotCount; nLane++) {
|
||||
if (putOntoNext(itm, nx, ny, next, &ntt, nLane)) {
|
||||
if (handled) {
|
||||
t->fixedFrame = getDirectionCode(outDir, t->direction);
|
||||
break;
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// target coords
|
||||
int nx = x + dirDx[dir];
|
||||
int ny = y + dirDy[dir];
|
||||
|
||||
// bounds & belt?
|
||||
if (nx < 0 || nx >= MAP_WIDTH || ny < 0 || ny >= MAP_HEIGHT) {
|
||||
if (tt.itemMoves) {
|
||||
itm->offset += 1.0f - speed;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Tile *next = &tileMap[ny][nx];
|
||||
TileTypeReg ntt = TileRegistry[next->type];
|
||||
int newLane = lane;
|
||||
switch (next->type) {
|
||||
case TYPE_BELT:
|
||||
int newDir = next->direction;
|
||||
bool nH = (newDir == ORIENT_LEFT || newDir == ORIENT_RIGHT);
|
||||
bool nV = (newDir == ORIENT_UP || newDir == ORIENT_DOWN);
|
||||
|
||||
if ((horz && nH) || (vert && nV)) {
|
||||
// same axis → keep lane
|
||||
} else if (horz && nV) {
|
||||
// came off a horizontal: lane0=top→vertical.left, lane1=bottom→vertical.right
|
||||
newLane = (dir == ORIENT_RIGHT ^ newDir == ORIENT_UP ? 0 : 1);
|
||||
itm->offset = 0.0f;
|
||||
} else if (vert && nH) {
|
||||
// came off vertical: lane0=left→horizontal.top, lane1=right→horizontal.bottom
|
||||
newLane = (dir == ORIENT_UP ^ newDir == ORIENT_RIGHT ? 1 : 0);
|
||||
itm->offset = 0.0f;
|
||||
}
|
||||
// (diagonals fall back to same-lane)
|
||||
|
||||
// Find a free slot in
|
||||
break;
|
||||
|
||||
default:
|
||||
itm->offset += 1.0f - speed;
|
||||
}
|
||||
|
||||
|
||||
if (!putOntoNext(itm, nx, ny, next, &ntt, newLane) && (next->type != TYPE_BELT || newLane >= 2)) {
|
||||
for (uint8_t nLane = 0; nLane < ItemSlotCount; nLane++) {
|
||||
if (putOntoNext(itm, nx, ny, next, &ntt, nLane)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -284,10 +385,15 @@ void renderItem(ItemOnBelt item, SDL_Renderer *renderer, int lane, SDL_Rect play
|
||||
SDL_RenderFillRect(renderer, &rectA);
|
||||
}
|
||||
//SDL_RenderCopyx(renderer, ItemRegistry[item.type].textureOnBelt[ORIENT_LEFT], NULL, &tileRect);
|
||||
|
||||
SDL_RenderCopy(renderer, atlasTexture,
|
||||
&ItemRegistry[item.type].beltAnimation.atlasRects[ORIENT_LEFT][
|
||||
(animationStep / ItemRegistry[item.type].beltAnimation.divisor) %
|
||||
ItemRegistry[item.type].beltAnimation.frameCount],
|
||||
&ItemRegistry[item.type].beltAnimation.atlasRects[ORIENT_LEFT][(
|
||||
(animationStep /
|
||||
ItemRegistry[item.type].beltAnimation.divisor) %
|
||||
(
|
||||
ItemRegistry[item.type].beltAnimation.frameCount -
|
||||
ItemRegistry[item.type].beltAnimation.startFrame)) +
|
||||
ItemRegistry[item.type].beltAnimation.startFrame],
|
||||
&rect);
|
||||
|
||||
if (debugMode) {
|
||||
@@ -311,24 +417,30 @@ void loadItems(SDL_Renderer *renderer) {
|
||||
strcpy(item->name, tile.name);
|
||||
memcpy(&item->animation, &tile.animation, sizeof(tile.animation));
|
||||
|
||||
SDL_Texture *texTmp = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, TILE_SIZE,
|
||||
TILE_SIZE);
|
||||
for (int frame = 0; frame < item->animation.frameCount; frame++) {
|
||||
for (int a = 0; a < ORIENT_DIRECTION_COUNT; a++) {
|
||||
SDL_SetTextureBlendMode(item->animation.textures[a][frame], SDL_BLENDMODE_BLEND);
|
||||
item->beltAnimation.textures[a][frame] = ScaleTexture(renderer, tile.animation.textures[a][frame],
|
||||
TILE_SIZE / 2, TILE_SIZE / 2);
|
||||
item->beltAnimation.atlasRects[a][frame] = allocate_16x16(item->beltAnimation.textures[a][frame],
|
||||
SDL_SetRenderTarget(renderer, texTmp);
|
||||
SDL_RenderCopy(renderer, atlasTexture, &tile.animation.atlasRects[a][frame], NULL);
|
||||
SDL_Texture *tex = ScaleTexture(renderer, texTmp,
|
||||
TILE_SIZE / 2, TILE_SIZE / 2);
|
||||
item->beltAnimation.atlasRects[a][frame] = allocate_16x16(tex,
|
||||
renderer);
|
||||
SDL_DestroyTexture(tex);
|
||||
if (frame + 1 > item->beltAnimation.frameCount) {
|
||||
item->beltAnimation.frameCount = frame + 1;
|
||||
}
|
||||
SDL_SetTextureBlendMode(item->beltAnimation.textures[a][frame], SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
}
|
||||
SDL_DestroyTexture(texTmp);
|
||||
|
||||
item->type = itemRegistryIndex;
|
||||
item->isTile = true;
|
||||
item->animation.divisor = 1;
|
||||
item->beltAnimation.divisor = 1;
|
||||
item->animation.divisor = tile.animation.divisor;
|
||||
item->beltAnimation.divisor = tile.animation.divisor;
|
||||
item->animation.startFrame = tile.animation.startFrame;
|
||||
item->beltAnimation.startFrame = tile.animation.startFrame;
|
||||
|
||||
itemRegistryIndex++;
|
||||
}
|
||||
@@ -384,8 +496,6 @@ void loadItems(SDL_Renderer *renderer) {
|
||||
SDL_Rect beltRect = allocate_16x16(beltTex, renderer);
|
||||
// Assign to all orientations
|
||||
for (int o = 0; o < ORIENT_DIRECTION_COUNT; o++) {
|
||||
item->animation.textures[o][frame] = tex;
|
||||
item->beltAnimation.textures[o][frame] = beltTex;
|
||||
item->animation.atlasRects[o][frame] = mainRect;
|
||||
item->beltAnimation.atlasRects[o][frame] = beltRect;
|
||||
if (frame + 1 > item->animation.frameCount) {
|
||||
|
@@ -20,6 +20,8 @@ typedef enum ItemType {
|
||||
TYPE_FURNACE,
|
||||
TYPE_MINER,
|
||||
TYPE_TURRET,
|
||||
TYPE_SPLITTER,
|
||||
TYPE_CORE,
|
||||
IRON_ORE = ITEMREGISTRY_SIZE / 2,
|
||||
SILVER_ORE,
|
||||
GOLD_ORE,
|
||||
@@ -28,7 +30,11 @@ typedef enum ItemType {
|
||||
SILVER_INGOT,
|
||||
GOLD_INGOT,
|
||||
PLATINUM_INGOT,
|
||||
LOG
|
||||
LOG,
|
||||
IRON_BULLET,
|
||||
SILVER_BULLET,
|
||||
GOLD_BULLET,
|
||||
PLATINUM_BULLET,
|
||||
} ItemType;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user