Files
jix/main.c

313 lines
10 KiB
C

#include <SDL2/SDL.h>
#include <stdio.h>
#define SCREEN_WIDTH 240
#define SCREEN_HEIGHT 256
#define SCREEN_ZOOM 3
#define CAMP_WIDTH 225
#define CAMP_HEIGHT 201
#define AMUNT 0
#define DRETA 1
#define AVALL 2
#define ESQUERRA 3
#define OFFSET_X 8
#define OFFSET_Y 39
#define MODE_NORMAL 0
#define MODE_CREANT 1
#define COLOR_BLACK 0
#define COLOR_WHITE 1
#define COLOR_GREY 2
#define COLOR_RED 3
#define COLOR_YELLOW 4
#define COLOR_DARKRED 5
#define COLOR_DARKTEAL 6
SDL_Window *win;
SDL_Renderer *ren;
SDL_Texture *tex;
SDL_Texture *gfx;
Uint8 pixels[CAMP_WIDTH*CAMP_HEIGHT];
int player_x = CAMP_WIDTH/2;
int player_y = CAMP_HEIGHT-1;
int mode = MODE_NORMAL;
int lento = 0;
int last_x = CAMP_WIDTH/2;
int last_y = CAMP_HEIGHT-1;
void set_color(int color)
{
switch (color) {
case COLOR_BLACK: SDL_SetRenderDrawColor(ren, 0, 0, 0, 255); break;
case COLOR_WHITE: SDL_SetRenderDrawColor(ren, 255, 255, 255, 255); break;
case COLOR_GREY: SDL_SetRenderDrawColor(ren, 128, 128, 128, 255); break;
case COLOR_RED: SDL_SetRenderDrawColor(ren, 217, 87, 99, 255); break;
case COLOR_YELLOW: SDL_SetRenderDrawColor(ren, 251, 242, 54, 255); break;
case COLOR_DARKRED: SDL_SetRenderDrawColor(ren, 172, 50, 50, 255); break;
case COLOR_DARKTEAL: SDL_SetRenderDrawColor(ren, 48, 128, 130, 255); break;
}
}
void set_color_mod(int color)
{
switch (color) {
case COLOR_BLACK: SDL_SetTextureColorMod(gfx, 0, 0, 0); break;
case COLOR_WHITE: SDL_SetTextureColorMod(gfx, 255, 255, 255); break;
case COLOR_GREY: SDL_SetTextureColorMod(gfx, 128, 128, 128); break;
case COLOR_RED: SDL_SetTextureColorMod(gfx, 217, 87, 99); break;
case COLOR_YELLOW: SDL_SetTextureColorMod(gfx, 251, 242, 54); break;
case COLOR_DARKRED: SDL_SetTextureColorMod(gfx, 172, 50, 50); break;
case COLOR_DARKTEAL: SDL_SetTextureColorMod(gfx, 48, 128, 130); break;
}
}
void print(char *text, int x, int y, int color, int grid, int offset)
{
const int len = strlen(text);
set_color_mod(color);
for (int i=0; i<len; ++i)
{
const int chr = text[i]+offset;
SDL_Rect src_rect = {8*(chr%16), 8*(chr/16), 8, 8};
SDL_Rect dest_rect = {x+grid*i, y, 8, 8};
SDL_RenderCopy(ren, gfx, &src_rect, &dest_rect);
}
//set_color_mod(COLOR_WHITE);
}
void draw_player()
{
const int x = player_x+OFFSET_X;
const int y = player_y+OFFSET_Y;
set_color(COLOR_RED);
SDL_RenderDrawLine(ren, x, y-3, x+3, y);
SDL_RenderDrawLine(ren, x+3, y, x, y+3);
SDL_RenderDrawLine(ren, x, y+3, x-3, y);
SDL_RenderDrawLine(ren, x-3, y, x, y-3);
}
void put_pix()
{
if (pixels[player_x+player_y*CAMP_WIDTH]==COLOR_WHITE) return;
last_x = player_x; last_y = player_y;
pixels[player_x+player_y*CAMP_WIDTH] = COLOR_DARKRED;
SDL_SetRenderTarget(ren, tex);
if (lento)
set_color(COLOR_DARKRED);
else
set_color(COLOR_DARKTEAL);
SDL_RenderDrawPoint(ren, player_x, player_y);
SDL_SetRenderTarget(ren, NULL);
}
int any_black(int x, int y)
{
return (pixels[x+1+y*CAMP_WIDTH]==0 || pixels[x-1+y*CAMP_WIDTH]==0 || pixels[x+(y+1)*CAMP_WIDTH]==0 || pixels[x+(y-1)*CAMP_WIDTH]==0);
}
int get_sector_size(int x, int y, int size, int fill)
{
if (x>=0 && y>=0 && x<CAMP_WIDTH && y<CAMP_HEIGHT && pixels[x+y*CAMP_WIDTH]==0)
{
pixels[x+y*CAMP_WIDTH]=fill;
size++;
size = get_sector_size(x-1, y, size, fill);
size = get_sector_size(x, y-1, size, fill);
size = get_sector_size(x+1, y, size, fill);
size = get_sector_size(x, y+1, size, fill);
}
return size;
}
void fill_sector(int fill)
{
const Uint8 color = lento ? COLOR_DARKRED : COLOR_DARKTEAL;
set_color(color);
for (int y=0;y<CAMP_HEIGHT;++y)
for (int x=0;x<CAMP_WIDTH;++x)
if (pixels[x+y*CAMP_WIDTH]>=254)
if (pixels[x+y*CAMP_WIDTH]==fill) {
pixels[x+y*CAMP_WIDTH]=color;
SDL_RenderDrawPoint(ren, x, y);
} else {
pixels[x+y*CAMP_WIDTH]=0;
}
}
int get_percent()
{
int claimed = 0;
for (int y=0;y<CAMP_HEIGHT;++y)
for (int x=0;x<CAMP_WIDTH;++x)
if (pixels[x+y*CAMP_WIDTH]!=0) claimed++;
return (claimed*100)/(CAMP_WIDTH*CAMP_HEIGHT);
}
void close_sector()
{
SDL_SetRenderTarget(ren, tex);
set_color(COLOR_WHITE);
for (int y=0;y<CAMP_HEIGHT;++y)
for (int x=0;x<CAMP_WIDTH;++x)
if ((pixels[x+y*CAMP_WIDTH]==COLOR_DARKRED || pixels[x+y*CAMP_WIDTH]==COLOR_DARKTEAL) && any_black(x,y))
{
pixels[x+y*CAMP_WIDTH]=COLOR_WHITE;
SDL_RenderDrawPoint(ren, x, y);
}
if (last_x==player_x) {
int sector1 = get_sector_size(player_x-1, last_y, 0, 254);
int sector2 = get_sector_size(player_x+1, last_y, 0, 255);
if (sector2>sector1) fill_sector(254); else fill_sector(255);
} else {
int sector1 = get_sector_size(last_x, player_y-1, 0, 254);
int sector2 = get_sector_size(last_x, player_y+1, 0, 255);
if (sector2>sector1) fill_sector(254); else fill_sector(255);
}
char result[20];
print(SDL_itoa(get_percent(), result, 10), 10, 10, COLOR_YELLOW, 8, 0);
SDL_SetRenderTarget(ren, NULL);
}
void make_rapid()
{
SDL_SetRenderTarget(ren, tex);
set_color(COLOR_DARKTEAL);
for (int y=0;y<CAMP_HEIGHT;++y)
for (int x=0;x<CAMP_WIDTH;++x)
if (pixels[x+y*CAMP_WIDTH]==COLOR_DARKRED && any_black(x,y))
{
pixels[x+y*CAMP_WIDTH]=COLOR_DARKTEAL;
SDL_RenderDrawPoint(ren, x, y);
}
SDL_SetRenderTarget(ren, NULL);
}
int main(int argc, char *argv[])
{
srand(SDL_GetTicks());
SDL_Init(SDL_INIT_EVERYTHING);
win = SDL_CreateWindow("JIX", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH*SCREEN_ZOOM, SCREEN_HEIGHT*SCREEN_ZOOM, SDL_WINDOW_SHOWN);
ren = SDL_CreateRenderer(win, -1, 0);
SDL_RenderSetLogicalSize(ren, SCREEN_WIDTH, SCREEN_HEIGHT);
tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, CAMP_WIDTH, CAMP_HEIGHT);
gfx = SDL_CreateTextureFromSurface(ren, SDL_LoadBMP("jix.bmp"));
SDL_SetTextureBlendMode(gfx, SDL_BLENDMODE_ADD);
for (int i=0; i<CAMP_WIDTH*CAMP_HEIGHT; ++i) pixels[i]=0;
for (int i=0; i<CAMP_WIDTH; ++i) pixels[i]=pixels[i+(CAMP_HEIGHT-1)*CAMP_WIDTH]=1;
for (int i=0; i<CAMP_HEIGHT; ++i) pixels[i*CAMP_WIDTH]=pixels[CAMP_WIDTH-1+i*CAMP_WIDTH]=1;
SDL_SetRenderTarget(ren, tex);
set_color(COLOR_BLACK);
SDL_RenderClear(ren);
set_color(COLOR_WHITE);
SDL_RenderDrawLine(ren, 0, 0, CAMP_WIDTH-1, 0);
SDL_RenderDrawLine(ren, 0, 0, 0, CAMP_HEIGHT-1);
SDL_RenderDrawLine(ren, CAMP_WIDTH-1, CAMP_HEIGHT-1, CAMP_WIDTH-1, 0);
SDL_RenderDrawLine(ren, CAMP_WIDTH-1, CAMP_HEIGHT-1, 0, CAMP_HEIGHT-1);
SDL_SetRenderTarget(ren, NULL);
int should_exit = 0;
SDL_Event e;
Uint32 t = SDL_GetTicks();
const Uint8 *keys = SDL_GetKeyboardState(NULL);
while (!should_exit)
{
while (SDL_PollEvent(&e))
{
if (e.type == SDL_QUIT) {should_exit=1;break;}
if (e.type == SDL_KEYDOWN)
{
switch(e.key.keysym.scancode) {
case SDL_SCANCODE_ESCAPE: should_exit = 1; break;
};
}
}
int speed = 30;
if (lento) speed = 60;
if (SDL_GetTicks()-t>=speed)
{
if (keys[SDL_SCANCODE_UP] && player_y>0 && ( ((mode==MODE_CREANT || keys[SDL_SCANCODE_SPACE])&&pixels[player_x+(player_y-2)*CAMP_WIDTH]==0) || pixels[player_x+(player_y-2)*CAMP_WIDTH]==1)) {
if (mode==MODE_CREANT)
put_pix();
else if (pixels[player_x+(player_y-2)*CAMP_WIDTH]==0) {
lento=1;
mode = MODE_CREANT;
}
player_y--; put_pix(); player_y--;
} else if (keys[SDL_SCANCODE_RIGHT] && player_x<CAMP_WIDTH-1 && ( ((mode==MODE_CREANT || keys[SDL_SCANCODE_SPACE])&&pixels[player_x+2+player_y*CAMP_WIDTH]==0) || pixels[player_x+2+player_y*CAMP_WIDTH]==1)) {
if (mode==MODE_CREANT)
put_pix();
else if (pixels[player_x+2+player_y*CAMP_WIDTH]==0) {
lento=1;
mode = MODE_CREANT;
}
player_x++; put_pix(); player_x++;
} else if (keys[SDL_SCANCODE_DOWN] && player_y<CAMP_HEIGHT-1 && ( ((mode==MODE_CREANT || keys[SDL_SCANCODE_SPACE])&&pixels[player_x+(player_y+2)*CAMP_WIDTH]==0) || pixels[player_x+(player_y+2)*CAMP_WIDTH]==1)) {
if (mode==MODE_CREANT)
put_pix();
else if (pixels[player_x+(player_y+2)*CAMP_WIDTH]==0) {
lento=1;
mode = MODE_CREANT;
}
player_y++; put_pix(); player_y++;
} else if (keys[SDL_SCANCODE_LEFT] && player_x>0 && ( ((mode==MODE_CREANT || keys[SDL_SCANCODE_SPACE])&&pixels[player_x-2+player_y*CAMP_WIDTH]==0) || pixels[player_x-2+player_y*CAMP_WIDTH]==1)) {
if (mode==MODE_CREANT)
put_pix();
else if (pixels[player_x-2+player_y*CAMP_WIDTH]==0) {
lento=1;
mode = MODE_CREANT;
}
player_x--; put_pix(); player_x--;
}
if (mode==MODE_CREANT)
{
if (!keys[SDL_SCANCODE_SPACE])
{
make_rapid();
lento=0;
}
if (pixels[player_x+player_y*CAMP_WIDTH]==1)
{
close_sector();
mode = MODE_NORMAL;
}
}
t = SDL_GetTicks();
}
set_color(COLOR_BLACK);
SDL_RenderClear(ren);
print("ABCDEFG", 16, 16, COLOR_WHITE, 8, -65);
print("HICJKLM", 16, 24, COLOR_WHITE, 8, -65);
print("NOOOOP", 24, 32, COLOR_WHITE, 8, -65);
SDL_Rect rect = {OFFSET_X,OFFSET_Y,CAMP_WIDTH,CAMP_HEIGHT};
SDL_RenderCopy(ren, tex, NULL, &rect);
draw_player();
SDL_RenderPresent(ren);
}
SDL_Quit();
return 0;
}