njetris/gridutils.c
2025-10-03 23:42:48 +02:00

120 lines
3.2 KiB
C

#include "tetris.h"
void grid_set(bitgrid_t* grid, int x, int y, bool value){
if(x < 0 || x >= TOTAL_WIDTH || y < 0 || y >= TOTAL_HEIGHT) return;
int bitIndex = y * TOTAL_WIDTH + x;
int wordIndex = bitIndex / 32;
int bitPosition = bitIndex % 32;
if(value){
grid->bits[wordIndex] |= (1U << bitPosition);
} else {
grid->bits[wordIndex] &= ~(1U << bitPosition);
}
}
void grid_get(bitgrid_t* grid, int x, int y, bool* value) {
if(x < 0 || x >= TOTAL_WIDTH || y < 0 || y >= TOTAL_HEIGHT) {
*value = false;
return;
}
int bitIndex = y * TOTAL_WIDTH + x;
int wordIndex = bitIndex / 32;
int bitPosition = bitIndex % 32;
*value = (grid->bits[wordIndex] & (1U << bitPosition)) != 0;
}
bool grid_equals(bitgrid_t* a, bitgrid_t* b){
for(int i = 0; i < GRID_WORDS; i++){
if(a->bits[i] != b->bits[i]){
return false;
}
}
return true;
}
bitgrid_t grid_copy(bitgrid_t* src){
bitgrid_t result;
for(int i = 0; i < GRID_WORDS; i++){
result.bits[i] = src->bits[i];
}
return result;
}
void bitgrid_bitwise_and(bitgrid_t* dest, bitgrid_t* a, bitgrid_t* b){
for(int i = 0; i < GRID_WORDS; i++){
dest->bits[i] = a->bits[i] & b->bits[i];
}
}
void bitgrid_bitwise_or(bitgrid_t* dest, bitgrid_t* a, bitgrid_t* b){
for(int i = 0; i < GRID_WORDS; i++){
dest->bits[i] = a->bits[i] | b->bits[i];
}
}
void bitgrid_bitwise_xor(bitgrid_t* dest, bitgrid_t* a, bitgrid_t* b){
for(int i = 0; i < GRID_WORDS; i++){
dest->bits[i] = a->bits[i] ^ b->bits[i];
}
}
void bitgrid_bitwise_not(bitgrid_t* dest, bitgrid_t* src){
for(int i = 0; i < GRID_WORDS; i++){
dest->bits[i] = ~(src->bits[i]);
}
}
void bitgrid_bitwise_shift_left(bitgrid_t* dest, bitgrid_t* src, int shift){
if(shift < 0) return; // Invalid shift
if(shift == 0){
*dest = *src;
return;
}
int totalBits = TOTAL_WIDTH * TOTAL_HEIGHT;
if(shift >= totalBits){
for(int i = 0; i < GRID_WORDS; i++){
dest->bits[i] = 0;
}
return;
}
int wordShift = shift / 32;
int bitShift = shift % 32;
for(int i = GRID_WORDS - 1; i >= 0; i--){
uint32_t upper = (i - wordShift - 1 >= 0 && bitShift != 0) ? (src->bits[i - wordShift - 1] >> (32 - bitShift)) : 0;
uint32_t lower = (i - wordShift >= 0) ? (src->bits[i - wordShift] << bitShift) : 0;
dest->bits[i] = upper | lower;
}
}
void bitgrid_bitwise_shift_right(bitgrid_t* dest, bitgrid_t* src, int shift){
if(shift < 0) return; // Invalid shift
if(shift == 0){
*dest = *src;
return;
}
int totalBits = TOTAL_WIDTH * TOTAL_HEIGHT;
if(shift >= totalBits){
for(int i = 0; i < GRID_WORDS; i++){
dest->bits[i] = 0;
}
return;
}
int wordShift = shift / 32;
int bitShift = shift % 32;
for(int i = 0; i < GRID_WORDS; i++){
uint32_t lower = (i + wordShift + 1 < GRID_WORDS && bitShift != 0) ? (src->bits[i + wordShift + 1] << (32 - bitShift)) : 0;
uint32_t upper = (i + wordShift < GRID_WORDS) ? (src->bits[i + wordShift] >> bitShift) : 0;
dest->bits[i] = upper | lower;
}
}