mirror of
https://github.com/sigmasternchen/cli-animations
synced 2025-03-15 03:38:54 +00:00
frist commit
This commit is contained in:
commit
b64dc43112
13 changed files with 1246 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
/obj/**
|
||||
gravity
|
||||
bars
|
||||
font
|
41
Makefile
Normal file
41
Makefile
Normal file
|
@ -0,0 +1,41 @@
|
|||
CC = gcc
|
||||
CFLAGS = -std=c99 -Wall -D_POSIX_C_SOURCE=201112L -D_XOPEN_SOURCE=500 -D_GNU_SOURCE -static -g
|
||||
LD = gcc
|
||||
LDFLAGS = -lm
|
||||
|
||||
COMMON = obj/common/graphics.o\
|
||||
obj/common/compat.o\
|
||||
obj/common/utils.o
|
||||
DEPS = $(OBJS:%.o=%.d)
|
||||
|
||||
all: bars gravity font
|
||||
|
||||
bars: obj/bars.o $(COMMON)
|
||||
$(LD) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
gravity: obj/gravity.o $(COMMON)
|
||||
$(LD) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
font: obj/font.o $(COMMON)
|
||||
$(LD) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
test: obj/test.o $(COMMON)
|
||||
$(LD) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
obj/%.o: src/%.c obj
|
||||
$(CC) $(CFLAGS) -MMD -c -o $@ $<
|
||||
|
||||
obj:
|
||||
@mkdir -p obj/common/
|
||||
|
||||
clean:
|
||||
@echo "Cleaning up..."
|
||||
@rm -f obj/*.o
|
||||
@rm -f obj/*.d
|
||||
@rm -f obj/*/*.o
|
||||
@rm -f obj/*/*.d
|
||||
@rm -f bars
|
||||
@rm -f gravity
|
||||
@rm -f font
|
0
obj/common/.gitkeep
Normal file
0
obj/common/.gitkeep
Normal file
136
src/bars.c
Normal file
136
src/bars.c
Normal file
|
@ -0,0 +1,136 @@
|
|||
#include <locale.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "common/compat.h"
|
||||
#include "common/graphics.h"
|
||||
#include "common/utils.h"
|
||||
|
||||
#define WIDTH (40)
|
||||
#define NUMBER_OF_CHARACTERS (8)
|
||||
#define NUMBER_OF_BLOCKS (20)
|
||||
#define SLEEP_TIME (50000l)
|
||||
|
||||
|
||||
#define NO_CHARACTER (-1)
|
||||
|
||||
wchar_t chars[] = {
|
||||
0x258F,
|
||||
0x258E,
|
||||
0x258D,
|
||||
0x258C,
|
||||
0x258B,
|
||||
0x258A,
|
||||
0x2589,
|
||||
0x2588
|
||||
};
|
||||
|
||||
enum direction {
|
||||
left, right
|
||||
};
|
||||
|
||||
struct block {
|
||||
enum direction direction;
|
||||
int character;
|
||||
float position;
|
||||
float speed;
|
||||
};
|
||||
|
||||
struct buffer {
|
||||
int characters[WIDTH];
|
||||
};
|
||||
|
||||
struct block randomBlock() {
|
||||
return (struct block){
|
||||
direction: (randomInt() % 2) ? left : right,
|
||||
character: (randomInt() % NUMBER_OF_CHARACTERS),
|
||||
position: (randomInt() % WIDTH),
|
||||
speed: 1
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void printBuffer(struct buffer* buffer) {
|
||||
for (int i = 0; i < WIDTH; i++) {
|
||||
if (buffer->characters[i] < 0) {
|
||||
cprintf(" ");
|
||||
} else {
|
||||
cprintf("%lc", chars[buffer->characters[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clearBuffer(struct buffer* buffer) {
|
||||
for (int i = 0; i < WIDTH; i++) {
|
||||
buffer->characters[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void applyBlockToBuffer(struct block* block, struct buffer* buffer) {
|
||||
if (buffer->characters[(int) block->position] <= block->character)
|
||||
buffer->characters[(int) block->position] = block->character;
|
||||
}
|
||||
|
||||
void tickBlock(struct block* block) {
|
||||
if (block->direction == right) {
|
||||
block->position += block->speed;
|
||||
if (block->position >= WIDTH - 1) {
|
||||
block->position = WIDTH - 1;
|
||||
block->direction = left;
|
||||
}
|
||||
} else {
|
||||
block->position -= block->speed;
|
||||
if (block->position <= 0) {
|
||||
block->position = 0;
|
||||
block->direction = right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void doTick(struct block blocks[]) {
|
||||
struct buffer buffer;
|
||||
clearBuffer(&buffer);
|
||||
|
||||
moveCursorRelative(- (WIDTH + 2), 0);
|
||||
eraseLine();
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_BLOCKS; i++) {
|
||||
tickBlock(&(blocks[i]));
|
||||
|
||||
applyBlockToBuffer(&(blocks[i]), &buffer);
|
||||
}
|
||||
|
||||
cprintf("[");
|
||||
printBuffer(&buffer);
|
||||
cprintf("]");
|
||||
}
|
||||
|
||||
void makeBlocks(struct block blocks[]) {
|
||||
for (int i = 0; i < NUMBER_OF_BLOCKS; i++) {
|
||||
blocks[i] = randomBlock();
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
setlocale(LC_CTYPE, "");
|
||||
|
||||
enable_compat_mode(PRINT_WCHAR);
|
||||
|
||||
initRandom();
|
||||
|
||||
hideCursor();
|
||||
|
||||
struct block blocks[NUMBER_OF_BLOCKS];
|
||||
|
||||
makeBlocks(blocks);
|
||||
|
||||
while (true) {
|
||||
doTick(blocks);
|
||||
fflush(stdout);
|
||||
usleep(SLEEP_TIME);
|
||||
}
|
||||
|
||||
cprintf("\n");
|
||||
|
||||
}
|
42
src/common/compat.c
Normal file
42
src/common/compat.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
#include "compat.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int compat_mode = 0;
|
||||
|
||||
void enable_compat_mode(int mode) {
|
||||
compat_mode |= mode;
|
||||
}
|
||||
|
||||
void disable_compat_mode(int mode) {
|
||||
compat_mode &= ~(mode);
|
||||
}
|
||||
|
||||
int cfprintf(FILE* file, char* format, ...) {
|
||||
va_list(args);
|
||||
|
||||
int result;
|
||||
|
||||
va_start(args, format);
|
||||
if (compat_mode & PRINT_WCHAR) {
|
||||
size_t size = mbstowcs(NULL, format, 0) + 1;
|
||||
wchar_t* buffer = malloc(size * sizeof(wchar_t));
|
||||
if (buffer == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
mbstowcs(buffer, format, size);
|
||||
|
||||
result = vfwprintf(file, buffer, args);
|
||||
|
||||
free(buffer);
|
||||
} else {
|
||||
result = vfprintf(file, format, args);
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
return result;
|
||||
}
|
20
src/common/compat.h
Normal file
20
src/common/compat.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef COMPAT_H
|
||||
#define COMPAT_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define PRINT_WCHAR (1<<0)
|
||||
|
||||
void enable_compat_mode(int);
|
||||
void disable_compat_mode(int);
|
||||
|
||||
int cfprintf(FILE* file, char* format, ...);
|
||||
|
||||
#define cprintf(...) cfprintf(stdout, __VA_ARGS__)
|
||||
|
||||
#ifdef SUBSTITUDE_PRINTS
|
||||
#define printf(...) cprintf(__VA_ARGS__)
|
||||
#define fprintf(...) cfprintf(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#endif
|
67
src/common/graphics.c
Normal file
67
src/common/graphics.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
#include "graphics.h"
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void moveCursorRelative(int x, int y) {
|
||||
if (x < 0) {
|
||||
cprintf("\033[%dD", -x);
|
||||
} else if (x > 0) {
|
||||
cprintf("\033[%dC", x);
|
||||
}
|
||||
if (y < 0) {
|
||||
cprintf("\033[%dA", -x);
|
||||
} else if (y > 0) {
|
||||
cprintf("\033[%dB", x);
|
||||
}
|
||||
}
|
||||
|
||||
void moveCursorAbsolute(int x, int y) {
|
||||
cprintf("\033[%d;%dH", y + 1, x + 1);
|
||||
}
|
||||
|
||||
void eraseLine() {
|
||||
cprintf("\033[K");
|
||||
}
|
||||
|
||||
void eraseScreen() {
|
||||
cprintf("\033[2J");
|
||||
}
|
||||
|
||||
void hideCursor() {
|
||||
cprintf("\033[?25l");
|
||||
}
|
||||
|
||||
void showCursor() {
|
||||
cprintf("\033[?25h");
|
||||
}
|
||||
|
||||
struct dimensions getScreenSize() {
|
||||
moveCursorAbsolute(999, 999);
|
||||
cprintf("\033[6n");
|
||||
|
||||
char buffer[12];
|
||||
int i = 0;
|
||||
while (true) {
|
||||
cprintf("--\n");
|
||||
int m = fread(&(buffer[i++]), 1, 1, stdin);
|
||||
cprintf("%d\n", m);
|
||||
cprintf("%c\n", buffer[i - 1]);
|
||||
if (buffer[i - 1] == 'R')
|
||||
break;
|
||||
}
|
||||
buffer[i] = '\0';
|
||||
|
||||
struct dimensions d;
|
||||
|
||||
char* endptr = &(buffer[2]);
|
||||
int tmp = strtol(endptr, &endptr, 10);
|
||||
d.width = tmp;
|
||||
tmp = strtol(endptr, &endptr, 10);
|
||||
d.height = tmp;
|
||||
|
||||
return d;
|
||||
}
|
19
src/common/graphics.h
Normal file
19
src/common/graphics.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef GRAPHICS_H
|
||||
#define GRAPHICS_H
|
||||
|
||||
struct dimensions {
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
void moveCursorRelative(int x, int y);
|
||||
void moveCursorAbsolute(int x, int y);
|
||||
void eraseLine();
|
||||
void eraseScreen();
|
||||
|
||||
void hideCursor();
|
||||
void showCursor();
|
||||
|
||||
struct dimensions getScreenSize();
|
||||
|
||||
#endif
|
16
src/common/utils.c
Normal file
16
src/common/utils.c
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include "utils.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void initRandom() {
|
||||
srandom(time(NULL));
|
||||
}
|
||||
|
||||
int randomInt() {
|
||||
return random();
|
||||
}
|
||||
|
||||
float randomFloat() {
|
||||
return random() * 1.0 / RAND_MAX;
|
||||
}
|
19
src/common/utils.h
Normal file
19
src/common/utils.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include "compat.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void initRandom();
|
||||
|
||||
int randomInt();
|
||||
float randomFloat();
|
||||
|
||||
#ifndef EXIT_PANIC
|
||||
#define EXIT_PANIC (1)
|
||||
#endif
|
||||
|
||||
#define panic(format, ...) { cfprintf(stderr, "panic: " format "\n", #__VA_ARGS__); exit(EXIT_PANIC ); }
|
||||
|
||||
#endif
|
545
src/font.c
Normal file
545
src/font.c
Normal file
|
@ -0,0 +1,545 @@
|
|||
#include <locale.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "common/graphics.h"
|
||||
#include "common/utils.h"
|
||||
|
||||
#define SUBSTITUDE_PRINTS
|
||||
#include "common/compat.h"
|
||||
|
||||
#define MAX_VELOCITY (3)
|
||||
|
||||
#define ANIMATION_SLEEP_TIME (100000)
|
||||
#define SCATTER_SLEEP_TIME (2000000)
|
||||
|
||||
#define OFFSET_X (-50)
|
||||
#define OFFSET_Y (-15)
|
||||
|
||||
#define SCREEN_WIDTH (100)
|
||||
#define SCREEN_HEIGHT (30)
|
||||
|
||||
#define ASPECT_RATIO (3.0/2.0)
|
||||
#define FACTOR_X (1.0)
|
||||
#define FACTOR_Y (FACTOR_X * ASPECT_RATIO)
|
||||
|
||||
#define BRAILLE_PREFIX (0x2800)
|
||||
#define BRAILLE_TOP_LEFT (0x01)
|
||||
#define BRAILLE_MIDDLE_LEFT (0x02)
|
||||
#define BRAILLE_BOTTOM_LEFT (0x04)
|
||||
#define BRAILLE_TOP_RIGHT (0x08)
|
||||
#define BRAILLE_MIDDLE_RIGHT (0x10)
|
||||
#define BRAILLE_BOTTOM_RIGHT (0x20)
|
||||
|
||||
struct vector {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
struct point {
|
||||
struct vector position;
|
||||
struct vector source;
|
||||
struct vector target;
|
||||
};
|
||||
|
||||
float distance(struct vector a, struct vector b) {
|
||||
float dx = b.x - a.x;
|
||||
float dy = b.y - a.y;
|
||||
|
||||
return sqrt((dx * dx) + (dy * dy));
|
||||
}
|
||||
|
||||
struct vector direction(struct vector a, struct vector b) {
|
||||
float dx = b.x - a.x;
|
||||
float dy = b.y - a.y;
|
||||
|
||||
float r = sqrt((dx * dx) + (dy * dy));
|
||||
|
||||
return (struct vector) {
|
||||
x: dx / r,
|
||||
y: dy / r
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void zeroVector(struct vector* vector) {
|
||||
vector->x = 0;
|
||||
vector->y = 0;
|
||||
}
|
||||
|
||||
struct patternAtom {
|
||||
int x; // 0-1
|
||||
int y; // 0-2
|
||||
};
|
||||
|
||||
wchar_t getPattern(struct patternAtom atoms[], int number) {
|
||||
if (number == 0) {
|
||||
return L' ';
|
||||
}
|
||||
|
||||
wchar_t result = BRAILLE_PREFIX;
|
||||
|
||||
for (int i = 0; i < number; i++) {
|
||||
if (atoms[i].x == 0) {
|
||||
if (atoms[i].y == 0) {
|
||||
result |= BRAILLE_TOP_LEFT;
|
||||
} else if (atoms[i].y == 1) {
|
||||
result |= BRAILLE_MIDDLE_LEFT;
|
||||
} else {
|
||||
result |= BRAILLE_BOTTOM_LEFT;
|
||||
}
|
||||
} else {
|
||||
if (atoms[i].y == 0) {
|
||||
result |= BRAILLE_TOP_RIGHT;
|
||||
} else if (atoms[i].y == 1) {
|
||||
result |= BRAILLE_MIDDLE_RIGHT;
|
||||
} else {
|
||||
result |= BRAILLE_BOTTOM_RIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct point randomPoint() {
|
||||
struct point p = {
|
||||
source: {
|
||||
x: randomFloat() * 20 - 10,
|
||||
y: randomFloat() * 20 - 10
|
||||
},
|
||||
target: {
|
||||
x: randomFloat() * 20 - 10,
|
||||
y: randomFloat() * 20 - 10
|
||||
}
|
||||
};
|
||||
|
||||
p.position = p.source;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void initPoints(struct point points[], int number) {
|
||||
for (int i = 0; i < number; i++) {
|
||||
points[i] = randomPoint();
|
||||
}
|
||||
}
|
||||
|
||||
float velocity(float x) {
|
||||
if (x > 1.0) {
|
||||
return MAX_VELOCITY * (-0.2)*(x - 1);
|
||||
} else if (x > 0.5) {
|
||||
return MAX_VELOCITY * (-2)*(x - 1);
|
||||
} else {
|
||||
return MAX_VELOCITY * 2*x + 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
bool tickPoint(struct point* p) {
|
||||
struct vector d = direction(p->position, p->target);
|
||||
|
||||
float x = distance(p->source, p->target);
|
||||
if (fabs(x) < 0.01) {
|
||||
x = 1.0;
|
||||
} else {
|
||||
x = distance(p->source, p->position) / x;
|
||||
}
|
||||
|
||||
float v = fabs(velocity(x));
|
||||
|
||||
if (fabs(1 - x) < 0.01) {
|
||||
p->position = p->target;
|
||||
return true;
|
||||
} else {
|
||||
p->position.x += d.x * v;
|
||||
p->position.y += d.y * v;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool tickPoints(struct point points[], int number) {
|
||||
bool finished = true;
|
||||
|
||||
for (int i = 0; i < number; i++) {
|
||||
if (!tickPoint(&(points[i])))
|
||||
finished = false;
|
||||
}
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
struct screenCell {
|
||||
struct patternAtom* atoms;
|
||||
int number;
|
||||
};
|
||||
|
||||
void displayPoints(struct point points[], int number) {
|
||||
struct screenCell screen[SCREEN_WIDTH][SCREEN_HEIGHT];
|
||||
for (int x = 0; x < SCREEN_WIDTH; x++) {
|
||||
for (int y = 0; y < SCREEN_HEIGHT; y++) {
|
||||
screen[x][y].atoms = NULL;
|
||||
screen[x][y].number = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < number; i++) {
|
||||
struct point p = points[i];
|
||||
float x = p.position.x * FACTOR_X - OFFSET_X;
|
||||
float y = p.position.y * FACTOR_Y - OFFSET_Y;
|
||||
|
||||
int screenX = floor(x);
|
||||
int screenY = floor(y);
|
||||
|
||||
if (screenX < 0 || screenX >= SCREEN_WIDTH) {
|
||||
continue;
|
||||
}
|
||||
if (screenY < 0 || screenY >= SCREEN_HEIGHT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
struct patternAtom atom = {
|
||||
x: floor((x - screenX) * 2),
|
||||
y: floor((y - screenY) * 3)
|
||||
};
|
||||
|
||||
struct screenCell* cell = &(screen[screenX][screenY]);
|
||||
cell->atoms = realloc(cell->atoms, ++cell->number * sizeof(struct patternAtom));
|
||||
if (cell->atoms == NULL) {
|
||||
panic("couldn't allocate screen buffer: %s", strerror(errno));
|
||||
}
|
||||
cell->atoms[cell->number - 1] = atom;
|
||||
}
|
||||
|
||||
for (int x = 0; x < SCREEN_WIDTH + 2; x++) {
|
||||
cprintf("-");
|
||||
}
|
||||
cprintf("\n");
|
||||
for (int y = 0; y < SCREEN_HEIGHT; y++) {
|
||||
cprintf("|");
|
||||
for (int x = 0; x < SCREEN_WIDTH; x++) {
|
||||
cprintf("%lc", getPattern(screen[x][y].atoms, screen[x][y].number));
|
||||
}
|
||||
cprintf("|\n");
|
||||
}
|
||||
for (int x = 0; x < SCREEN_WIDTH + 2; x++) {
|
||||
cprintf("-");
|
||||
}
|
||||
cprintf("\n");
|
||||
}
|
||||
|
||||
void createPoint(struct point points[], int i, struct vector position) {
|
||||
if (points == NULL)
|
||||
return;
|
||||
|
||||
struct vector source = {
|
||||
x: randomFloat() * SCREEN_WIDTH - SCREEN_WIDTH / 2,
|
||||
y: (randomFloat() * SCREEN_HEIGHT - SCREEN_HEIGHT / 2) / ASPECT_RATIO
|
||||
};
|
||||
|
||||
points[i] = (struct point) {
|
||||
target: position,
|
||||
source: source,
|
||||
position: source
|
||||
};
|
||||
}
|
||||
|
||||
struct vector add(struct vector vector, float x, float y) {
|
||||
return (struct vector) {
|
||||
x: vector.x + x,
|
||||
y: (vector.y + y) / ASPECT_RATIO
|
||||
};
|
||||
}
|
||||
|
||||
int char2points(char c, struct point points[], struct vector position) {
|
||||
int i = 0;
|
||||
switch(c) {
|
||||
case 'A':
|
||||
createPoint(points, i++, add(position, 1.0, 0.0));
|
||||
createPoint(points, i++, add(position, 1.5, 0.0));
|
||||
createPoint(points, i++, add(position, 1.0, 0.4));
|
||||
createPoint(points, i++, add(position, 1.5, 0.4));
|
||||
createPoint(points, i++, add(position, 0.5, 0.7));
|
||||
createPoint(points, i++, add(position, 2.0, 0.7));
|
||||
createPoint(points, i++, add(position, 0.0, 1.0));
|
||||
createPoint(points, i++, add(position, 0.5, 1.0));
|
||||
createPoint(points, i++, add(position, 2.0, 1.0));
|
||||
createPoint(points, i++, add(position, 2.5, 1.0));
|
||||
createPoint(points, i++, add(position, 0.0, 1.4));
|
||||
createPoint(points, i++, add(position, 0.5, 1.4));
|
||||
createPoint(points, i++, add(position, 1.0, 1.4));
|
||||
createPoint(points, i++, add(position, 1.5, 1.4));
|
||||
createPoint(points, i++, add(position, 2.0, 1.4));
|
||||
createPoint(points, i++, add(position, 2.5, 1.4));
|
||||
createPoint(points, i++, add(position, 0.0, 1.7));
|
||||
createPoint(points, i++, add(position, 0.5, 1.7));
|
||||
createPoint(points, i++, add(position, 1.0, 1.7));
|
||||
createPoint(points, i++, add(position, 1.5, 1.7));
|
||||
createPoint(points, i++, add(position, 2.0, 1.7));
|
||||
createPoint(points, i++, add(position, 2.5, 1.7));
|
||||
createPoint(points, i++, add(position, 0.0, 2.0));
|
||||
createPoint(points, i++, add(position, 0.5, 2.0));
|
||||
createPoint(points, i++, add(position, 2.0, 2.0));
|
||||
createPoint(points, i++, add(position, 2.5, 2.0));
|
||||
createPoint(points, i++, add(position, 0.0, 2.4));
|
||||
createPoint(points, i++, add(position, 0.5, 2.4));
|
||||
createPoint(points, i++, add(position, 2.0, 2.4));
|
||||
createPoint(points, i++, add(position, 2.5, 2.4));
|
||||
createPoint(points, i++, add(position, 0.0, 2.7));
|
||||
createPoint(points, i++, add(position, 0.5, 2.7));
|
||||
createPoint(points, i++, add(position, 2.0, 2.7));
|
||||
createPoint(points, i++, add(position, 2.5, 2.7));
|
||||
return i;
|
||||
case 'C':
|
||||
return i;
|
||||
case 'D':
|
||||
return i;
|
||||
case 'E':
|
||||
return i;
|
||||
case 'F':
|
||||
return i;
|
||||
case 'G':
|
||||
return i;
|
||||
case 'H':
|
||||
createPoint(points, i++, add(position, 0.0, 0.0));
|
||||
createPoint(points, i++, add(position, 0.0, 0.4));
|
||||
createPoint(points, i++, add(position, 0.0, 0.7));
|
||||
createPoint(points, i++, add(position, 0.0, 1.0));
|
||||
createPoint(points, i++, add(position, 0.0, 1.4));
|
||||
createPoint(points, i++, add(position, 0.0, 1.7));
|
||||
createPoint(points, i++, add(position, 0.0, 2.0));
|
||||
createPoint(points, i++, add(position, 0.0, 2.4));
|
||||
createPoint(points, i++, add(position, 0.0, 2.7));
|
||||
createPoint(points, i++, add(position, 0.5, 0.0));
|
||||
createPoint(points, i++, add(position, 0.5, 0.4));
|
||||
createPoint(points, i++, add(position, 0.5, 0.7));
|
||||
createPoint(points, i++, add(position, 0.5, 1.0));
|
||||
createPoint(points, i++, add(position, 0.5, 1.4));
|
||||
createPoint(points, i++, add(position, 0.5, 1.7));
|
||||
createPoint(points, i++, add(position, 0.5, 2.0));
|
||||
createPoint(points, i++, add(position, 0.5, 2.4));
|
||||
createPoint(points, i++, add(position, 0.5, 2.7));
|
||||
createPoint(points, i++, add(position, 1.0, 1.0));
|
||||
createPoint(points, i++, add(position, 1.0, 1.4));
|
||||
createPoint(points, i++, add(position, 1.0, 1.7));
|
||||
createPoint(points, i++, add(position, 1.5, 1.0));
|
||||
createPoint(points, i++, add(position, 1.5, 1.4));
|
||||
createPoint(points, i++, add(position, 1.5, 1.7));
|
||||
createPoint(points, i++, add(position, 2.0, 0.0));
|
||||
createPoint(points, i++, add(position, 2.0, 0.4));
|
||||
createPoint(points, i++, add(position, 2.0, 0.7));
|
||||
createPoint(points, i++, add(position, 2.0, 1.0));
|
||||
createPoint(points, i++, add(position, 2.0, 1.4));
|
||||
createPoint(points, i++, add(position, 2.0, 1.7));
|
||||
createPoint(points, i++, add(position, 2.0, 2.0));
|
||||
createPoint(points, i++, add(position, 2.0, 2.4));
|
||||
createPoint(points, i++, add(position, 2.0, 2.7));
|
||||
createPoint(points, i++, add(position, 2.5, 0.0));
|
||||
createPoint(points, i++, add(position, 2.5, 0.4));
|
||||
createPoint(points, i++, add(position, 2.5, 0.7));
|
||||
createPoint(points, i++, add(position, 2.5, 1.0));
|
||||
createPoint(points, i++, add(position, 2.5, 1.4));
|
||||
createPoint(points, i++, add(position, 2.5, 1.7));
|
||||
createPoint(points, i++, add(position, 2.5, 2.0));
|
||||
createPoint(points, i++, add(position, 2.5, 2.4));
|
||||
createPoint(points, i++, add(position, 2.5, 2.7));
|
||||
return i;
|
||||
case 'I':
|
||||
return i;
|
||||
case 'J':
|
||||
return i;
|
||||
case 'K':
|
||||
return i;
|
||||
case 'L':
|
||||
createPoint(points, i++, add(position, 0.0, 0.0));
|
||||
createPoint(points, i++, add(position, 0.0, 0.4));
|
||||
createPoint(points, i++, add(position, 0.0, 0.7));
|
||||
createPoint(points, i++, add(position, 0.0, 1.0));
|
||||
createPoint(points, i++, add(position, 0.0, 1.4));
|
||||
createPoint(points, i++, add(position, 0.0, 1.7));
|
||||
createPoint(points, i++, add(position, 0.0, 2.0));
|
||||
createPoint(points, i++, add(position, 0.0, 2.4));
|
||||
createPoint(points, i++, add(position, 0.0, 2.7));
|
||||
createPoint(points, i++, add(position, 0.5, 0.0));
|
||||
createPoint(points, i++, add(position, 0.5, 0.4));
|
||||
createPoint(points, i++, add(position, 0.5, 0.7));
|
||||
createPoint(points, i++, add(position, 0.5, 1.0));
|
||||
createPoint(points, i++, add(position, 0.5, 1.4));
|
||||
createPoint(points, i++, add(position, 0.5, 1.7));
|
||||
createPoint(points, i++, add(position, 0.5, 2.0));
|
||||
createPoint(points, i++, add(position, 0.5, 2.4));
|
||||
createPoint(points, i++, add(position, 0.5, 2.7));
|
||||
createPoint(points, i++, add(position, 1.0, 2.4));
|
||||
createPoint(points, i++, add(position, 1.0, 2.7));
|
||||
createPoint(points, i++, add(position, 1.5, 2.4));
|
||||
createPoint(points, i++, add(position, 1.5, 2.7));
|
||||
createPoint(points, i++, add(position, 2.0, 2.4));
|
||||
createPoint(points, i++, add(position, 2.0, 2.7));
|
||||
createPoint(points, i++, add(position, 2.5, 2.4));
|
||||
createPoint(points, i++, add(position, 2.5, 2.7));
|
||||
return i;
|
||||
case 'M':
|
||||
return i;
|
||||
case 'N':
|
||||
return i;
|
||||
case 'O':
|
||||
createPoint(points, i++, add(position, 0.5, 0.0));
|
||||
createPoint(points, i++, add(position, 1.0, 0.0));
|
||||
createPoint(points, i++, add(position, 1.5, 0.0));
|
||||
createPoint(points, i++, add(position, 2.0, 0.0));
|
||||
createPoint(points, i++, add(position, 0.0, 0.4));
|
||||
createPoint(points, i++, add(position, 0.5, 0.4));
|
||||
createPoint(points, i++, add(position, 1.0, 0.4));
|
||||
createPoint(points, i++, add(position, 1.5, 0.4));
|
||||
createPoint(points, i++, add(position, 2.0, 0.4));
|
||||
createPoint(points, i++, add(position, 2.5, 0.4));
|
||||
createPoint(points, i++, add(position, 0.0, 0.7));
|
||||
createPoint(points, i++, add(position, 0.5, 0.7));
|
||||
createPoint(points, i++, add(position, 1.0, 0.7));
|
||||
createPoint(points, i++, add(position, 1.5, 0.7));
|
||||
createPoint(points, i++, add(position, 2.0, 0.7));
|
||||
createPoint(points, i++, add(position, 2.5, 0.7));
|
||||
createPoint(points, i++, add(position, 0.0, 1.0));
|
||||
createPoint(points, i++, add(position, 0.5, 1.0));
|
||||
createPoint(points, i++, add(position, 2.0, 1.0));
|
||||
createPoint(points, i++, add(position, 2.5, 1.0));
|
||||
createPoint(points, i++, add(position, 0.0, 1.4));
|
||||
createPoint(points, i++, add(position, 0.5, 1.4));
|
||||
createPoint(points, i++, add(position, 2.0, 1.4));
|
||||
createPoint(points, i++, add(position, 2.5, 1.4));
|
||||
createPoint(points, i++, add(position, 0.0, 1.7));
|
||||
createPoint(points, i++, add(position, 0.5, 1.7));
|
||||
createPoint(points, i++, add(position, 2.0, 1.7));
|
||||
createPoint(points, i++, add(position, 2.5, 1.7));
|
||||
createPoint(points, i++, add(position, 0.0, 2.0));
|
||||
createPoint(points, i++, add(position, 0.5, 2.0));
|
||||
createPoint(points, i++, add(position, 1.0, 2.0));
|
||||
createPoint(points, i++, add(position, 1.5, 2.0));
|
||||
createPoint(points, i++, add(position, 2.0, 2.0));
|
||||
createPoint(points, i++, add(position, 2.5, 2.0));
|
||||
createPoint(points, i++, add(position, 0.0, 2.4));
|
||||
createPoint(points, i++, add(position, 0.5, 2.4));
|
||||
createPoint(points, i++, add(position, 1.0, 2.4));
|
||||
createPoint(points, i++, add(position, 1.5, 2.4));
|
||||
createPoint(points, i++, add(position, 2.0, 2.4));
|
||||
createPoint(points, i++, add(position, 2.5, 2.4));
|
||||
createPoint(points, i++, add(position, 0.5, 2.7));
|
||||
createPoint(points, i++, add(position, 1.0, 2.7));
|
||||
createPoint(points, i++, add(position, 1.5, 2.7));
|
||||
createPoint(points, i++, add(position, 2.0, 2.7));
|
||||
return i;
|
||||
case 'P':
|
||||
return i;
|
||||
case 'Q':
|
||||
return i;
|
||||
case 'R':
|
||||
return i;
|
||||
case 'S':
|
||||
return i;
|
||||
case 'T':
|
||||
return i;
|
||||
case 'U':
|
||||
return i;
|
||||
case 'V':
|
||||
return i;
|
||||
case 'W':
|
||||
return i;
|
||||
case 'X':
|
||||
return i;
|
||||
case 'Y':
|
||||
return i;
|
||||
case 'Z':
|
||||
return i;
|
||||
default:
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
void string2points(const char* string, struct point points[]) {
|
||||
int length = strlen(string);
|
||||
|
||||
struct vector position = (struct vector) {
|
||||
x: -(length * 4 / 2),
|
||||
y: -2
|
||||
};
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
index += char2points(string[i], &(points[index]), position);
|
||||
|
||||
position.x += 4;
|
||||
}
|
||||
}
|
||||
|
||||
int numberPoints(const char* string) {
|
||||
int sum = 0;
|
||||
|
||||
int length = strlen(string);
|
||||
for (int i = 0; i < length; i++) {
|
||||
sum += char2points(string[i], NULL, (struct vector) {0, 0});
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
void scatter(struct point points[], int number) {
|
||||
for (int i = 0; i < number; i++) {
|
||||
points[i].source = points[i].position;
|
||||
|
||||
float phi = randomFloat() * M_PI * 2;
|
||||
float r = sqrt(SCREEN_WIDTH * SCREEN_WIDTH + SCREEN_HEIGHT * SCREEN_HEIGHT) / 2;
|
||||
|
||||
points[i].target = (struct vector) {
|
||||
x: r * cos(phi),
|
||||
y: r * sin(phi)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
setlocale(LC_CTYPE, "");
|
||||
enable_compat_mode(PRINT_WCHAR);
|
||||
|
||||
initRandom();
|
||||
|
||||
const char* string = "HALLO";
|
||||
|
||||
int number = numberPoints(string);
|
||||
|
||||
struct point* points = malloc(number * sizeof(struct point));
|
||||
if (points == NULL)
|
||||
panic("could allocate point array: %s", strerror(errno));
|
||||
|
||||
string2points(string, points);
|
||||
|
||||
hideCursor();
|
||||
|
||||
eraseScreen();
|
||||
|
||||
bool scattered = false;
|
||||
|
||||
while(true) {
|
||||
moveCursorAbsolute(0, 0);
|
||||
displayPoints(points, number);
|
||||
//fflush(stdout);
|
||||
usleep(ANIMATION_SLEEP_TIME);
|
||||
|
||||
if (tickPoints(points, number)) {
|
||||
if (scattered) {
|
||||
return 0;
|
||||
} else {
|
||||
scatter(points, number);
|
||||
scattered = true;
|
||||
|
||||
moveCursorAbsolute(0, 0);
|
||||
displayPoints(points, number);
|
||||
usleep(SCATTER_SLEEP_TIME);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
320
src/gravity.c
Normal file
320
src/gravity.c
Normal file
|
@ -0,0 +1,320 @@
|
|||
#include <locale.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "common/graphics.h"
|
||||
#include "common/utils.h"
|
||||
|
||||
#define SUBSTITUDE_PRINTS
|
||||
#include "common/compat.h"
|
||||
|
||||
#define G (10.0)
|
||||
|
||||
#define OFFSET_X (-50)
|
||||
#define OFFSET_Y (-15)
|
||||
|
||||
#define SCREEN_WIDTH (100)
|
||||
#define SCREEN_HEIGHT (30)
|
||||
|
||||
#define NUMBER_OF_POINTS (2)
|
||||
|
||||
#define TERMINAL_VELOCITY (100.0)
|
||||
|
||||
#define ASPECT_RATIO (3.0/2.0)
|
||||
#define FACTOR_X (1.0)
|
||||
#define FACTOR_Y (FACTOR_X * ASPECT_RATIO)
|
||||
|
||||
#define SLEEP_TIME (100000)
|
||||
|
||||
#define TICKS_PER_TIME (1)
|
||||
|
||||
#define BRAILLE_PREFIX (0x2800)
|
||||
#define BRAILLE_TOP_LEFT (0x01)
|
||||
#define BRAILLE_MIDDLE_LEFT (0x02)
|
||||
#define BRAILLE_BOTTOM_LEFT (0x04)
|
||||
#define BRAILLE_TOP_RIGHT (0x08)
|
||||
#define BRAILLE_MIDDLE_RIGHT (0x10)
|
||||
#define BRAILLE_BOTTOM_RIGHT (0x20)
|
||||
|
||||
struct vector {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
struct point {
|
||||
struct vector position;
|
||||
struct vector velocity;
|
||||
struct vector force;
|
||||
float radius;
|
||||
float mass;
|
||||
};
|
||||
|
||||
float distance(struct point* a, struct point* b) {
|
||||
float dx = b->position.x - a->position.x;
|
||||
float dy = b->position.y - a->position.y;
|
||||
|
||||
return sqrt((dx * dx) + (dy * dy));
|
||||
}
|
||||
|
||||
struct vector direction(struct point* a, struct point* b) {
|
||||
float dx = b->position.x - a->position.x;
|
||||
float dy = b->position.y - a->position.y;
|
||||
|
||||
float r = sqrt((dx * dx) + (dy * dy));
|
||||
|
||||
return (struct vector) {
|
||||
x: dx / r,
|
||||
y: dy / r
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void tickPoint(struct point* point) {
|
||||
float factor = SLEEP_TIME / 1000000.0 * TICKS_PER_TIME;
|
||||
|
||||
point->position.x += point->velocity.x * factor;
|
||||
point->position.y += point->velocity.y * factor;
|
||||
}
|
||||
|
||||
void zeroVector(struct vector* vector) {
|
||||
vector->x = 0;
|
||||
vector->y = 0;
|
||||
}
|
||||
|
||||
void merge(struct point* a, struct point* b) {
|
||||
a->position.x = (a->position.x + b->position.x) / 2;
|
||||
a->position.y = (a->position.y + b->position.y) / 2;
|
||||
b->position.x = a->position.x;
|
||||
b->position.y = a->position.y;
|
||||
|
||||
a->velocity.x = (a->velocity.x * a->mass + b->velocity.x * b->mass) / (a->mass + b->mass);
|
||||
a->velocity.y = (a->velocity.y * a->mass + b->velocity.y * b->mass) / (a->mass + b->mass);
|
||||
b->velocity.x = a->velocity.x;
|
||||
b->velocity.y = a->velocity.y;
|
||||
}
|
||||
|
||||
void applyGravityToForce(struct point* a, struct point* b) {
|
||||
float r = distance(a, b);
|
||||
|
||||
cprintf("%f, ", r);
|
||||
|
||||
if (r <= a->radius + b->radius) {
|
||||
//merge(a, b);
|
||||
return;
|
||||
}
|
||||
float f = G * (a->mass * b->mass) / (r * r);
|
||||
|
||||
struct vector directionAtoB = direction(a, b);
|
||||
|
||||
a->force.x += f * directionAtoB.x;
|
||||
a->force.y += f * directionAtoB.y;
|
||||
b->force.x += f * directionAtoB.x * (-1);
|
||||
b->force.y += f * directionAtoB.y * (-1);
|
||||
|
||||
//cprintf("%f, %f\n", a->force.x, a->force.y);
|
||||
}
|
||||
|
||||
void applyForceToVelocity(struct point* point) {
|
||||
point->velocity.x += point->force.x / point->mass;
|
||||
point->velocity.y += point->force.y / point->mass;
|
||||
|
||||
float scalarVelocity = sqrt(point->velocity.x * point->velocity.x + point->velocity.y * point->velocity.y);
|
||||
|
||||
if (scalarVelocity > TERMINAL_VELOCITY) {
|
||||
float capFactor = TERMINAL_VELOCITY / scalarVelocity;
|
||||
|
||||
point->velocity.x *= capFactor;
|
||||
point->velocity.y *= capFactor;
|
||||
}
|
||||
|
||||
zeroVector(&(point->force));
|
||||
}
|
||||
|
||||
struct patternAtom {
|
||||
int x; // 0-1
|
||||
int y; // 0-2
|
||||
};
|
||||
|
||||
wchar_t getPattern(struct patternAtom atoms[], int number) {
|
||||
if (number == 0) {
|
||||
return L' ';
|
||||
}
|
||||
|
||||
wchar_t result = BRAILLE_PREFIX;
|
||||
|
||||
for (int i = 0; i < number; i++) {
|
||||
if (atoms[i].x == 0) {
|
||||
if (atoms[i].y == 0) {
|
||||
result |= BRAILLE_TOP_LEFT;
|
||||
} else if (atoms[i].y == 1) {
|
||||
result |= BRAILLE_MIDDLE_LEFT;
|
||||
} else {
|
||||
result |= BRAILLE_BOTTOM_LEFT;
|
||||
}
|
||||
} else {
|
||||
if (atoms[i].y == 0) {
|
||||
result |= BRAILLE_TOP_RIGHT;
|
||||
} else if (atoms[i].y == 1) {
|
||||
result |= BRAILLE_MIDDLE_RIGHT;
|
||||
} else {
|
||||
result |= BRAILLE_BOTTOM_RIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct point randomPoint() {
|
||||
return (struct point) {
|
||||
position: {
|
||||
x: randomFloat() * 20 - 10,
|
||||
y: randomFloat() * 20 - 10
|
||||
},
|
||||
velocity: {
|
||||
x: (randomFloat() - 0.5) / 1000,
|
||||
y: (randomFloat() - 0.5) / 1000
|
||||
},
|
||||
force: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
radius: 0.1,
|
||||
mass: randomFloat() + 0.1
|
||||
};
|
||||
}
|
||||
|
||||
void initPoints(struct point points[]) {
|
||||
for (int i = 0; i < NUMBER_OF_POINTS; i++) {
|
||||
points[i] = randomPoint();
|
||||
}
|
||||
}
|
||||
|
||||
void tickPoints(struct point points[]) {
|
||||
for (int i = 0; i < NUMBER_OF_POINTS; i++) {
|
||||
for (int j = 0; j < NUMBER_OF_POINTS; j++) {
|
||||
if (i == j)
|
||||
continue;
|
||||
|
||||
applyGravityToForce(&(points[i]), &(points[j]));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_POINTS; i++) {
|
||||
applyForceToVelocity(&(points[i]));
|
||||
tickPoint(&(points[i]));
|
||||
}
|
||||
}
|
||||
|
||||
struct screenCell {
|
||||
struct patternAtom* atoms;
|
||||
int number;
|
||||
};
|
||||
|
||||
void displayPoints(struct point points[]) {
|
||||
struct screenCell screen[SCREEN_WIDTH][SCREEN_HEIGHT];
|
||||
for (int x = 0; x < SCREEN_WIDTH; x++) {
|
||||
for (int y = 0; y < SCREEN_HEIGHT; y++) {
|
||||
screen[x][y].atoms = NULL;
|
||||
screen[x][y].number = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_POINTS; i++) {
|
||||
struct point p = points[i];
|
||||
float x = p.position.x * FACTOR_X - OFFSET_X;
|
||||
float y = p.position.y * FACTOR_Y - OFFSET_Y;
|
||||
|
||||
int screenX = floor(x);
|
||||
int screenY = floor(y);
|
||||
|
||||
if (screenX < 0 || screenX >= SCREEN_WIDTH) {
|
||||
continue;
|
||||
}
|
||||
if (screenY < 0 || screenY >= SCREEN_HEIGHT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
struct patternAtom atom = {
|
||||
x: floor((x - screenX) * 2),
|
||||
y: floor((y - screenY) * 3)
|
||||
};
|
||||
|
||||
struct screenCell* cell = &(screen[screenX][screenY]);
|
||||
cell->atoms = realloc(cell->atoms, ++cell->number * sizeof(struct patternAtom));
|
||||
if (cell->atoms == NULL) {
|
||||
panic("couldn't allocate screen buffer: %s", strerror(errno));
|
||||
}
|
||||
cell->atoms[cell->number - 1] = atom;
|
||||
}
|
||||
|
||||
for (int y = 0; y < SCREEN_HEIGHT; y++) {
|
||||
for (int x = 0; x < SCREEN_WIDTH; x++) {
|
||||
cprintf("%lc", getPattern(screen[x][y].atoms, screen[x][y].number));
|
||||
}
|
||||
cprintf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
setlocale(LC_CTYPE, "");
|
||||
enable_compat_mode(PRINT_WCHAR);
|
||||
|
||||
initRandom();
|
||||
|
||||
struct point points[NUMBER_OF_POINTS];
|
||||
//initPoints(points);
|
||||
|
||||
// hardcoded points to test orbit example
|
||||
points[0] = (struct point) {
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
velocity: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
force: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
radius: 0.1,
|
||||
mass: 5
|
||||
};
|
||||
points[1] = (struct point) {
|
||||
position: {
|
||||
x: 10,
|
||||
y: 0
|
||||
},
|
||||
velocity: {
|
||||
x: 0,
|
||||
y: 10
|
||||
},
|
||||
force: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
radius: 0.1,
|
||||
mass: 0.1
|
||||
};
|
||||
|
||||
hideCursor();
|
||||
|
||||
eraseScreen();
|
||||
|
||||
while(true) {
|
||||
moveCursorAbsolute(0, 0);
|
||||
displayPoints(points);
|
||||
//fflush(stdout);
|
||||
usleep(SLEEP_TIME);
|
||||
for (int i = 0; i < TICKS_PER_TIME; i++)
|
||||
tickPoints(points);
|
||||
}
|
||||
}
|
17
src/test.c
Normal file
17
src/test.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include "common/compat.h"
|
||||
#include "common/graphics.h"
|
||||
#include "common/utils.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
int main() {
|
||||
if (setvbuf(stdin, NULL, _IONBF, 0) != 0) {
|
||||
panic("can't set buffer for stdin: %s", strerror(errno));
|
||||
}
|
||||
|
||||
struct dimensions d = getScreenSize();
|
||||
|
||||
cprintf("%d, %d\n", d.width, d.height);
|
||||
}
|
Loading…
Reference in a new issue