diff options
author | EliteTK <tomasz.kramkowski@gmail.com> | 2015-06-19 19:12:12 +0100 |
---|---|---|
committer | EliteTK <tomasz.kramkowski@gmail.com> | 2015-06-19 19:12:12 +0100 |
commit | da87fcf25e0c94e57f00df84679cd6fadc56ed46 (patch) | |
tree | 3c53eea9db01039990455af870a2ca65e7e5a123 | |
parent | 75d2e00662416224f4b745e0004f48f1fc1d9665 (diff) | |
parent | 7bf25fb8f0e4643a67894417a95d39e5901b1824 (diff) | |
download | c-stuff-da87fcf25e0c94e57f00df84679cd6fadc56ed46.tar.gz c-stuff-da87fcf25e0c94e57f00df84679cd6fadc56ed46.tar.xz c-stuff-da87fcf25e0c94e57f00df84679cd6fadc56ed46.zip |
Merge branch 'master' of https://github.com/EliteTK/c-stuff
-rw-r--r-- | Makefile | 38 | ||||
-rw-r--r-- | README.md | 8 | ||||
-rw-r--r-- | addrofmain.c | 8 | ||||
-rw-r--r-- | advigenere.c | 67 | ||||
-rw-r--r-- | ant.c | 12 | ||||
-rw-r--r-- | blocks.c | 5 | ||||
-rw-r--r-- | editor.c | 95 | ||||
-rw-r--r-- | endianness.c | 23 | ||||
-rw-r--r-- | foursquare.c | 189 | ||||
-rw-r--r-- | genkeypairs.c | 48 | ||||
-rw-r--r-- | guesskeylength.c | 90 | ||||
-rw-r--r-- | hangman.c | 108 | ||||
-rw-r--r-- | imlib2.c | 232 | ||||
-rw-r--r-- | luaing.c | 35 | ||||
-rw-r--r-- | makefile | 27 | ||||
-rw-r--r-- | md5.c | 130 | ||||
-rw-r--r-- | ncurses_windows.c | 66 | ||||
-rw-r--r-- | poly_perim.c | 25 | ||||
-rw-r--r-- | pthreads.c | 45 | ||||
-rw-r--r-- | randtest.c | 56 | ||||
-rw-r--r-- | rot.c | 4 | ||||
-rw-r--r-- | scanf.c | 14 | ||||
-rw-r--r-- | sdl.c | 131 | ||||
-rw-r--r-- | shufflechars.c | 59 | ||||
-rw-r--r-- | simple_x.c | 83 | ||||
-rw-r--r-- | snake.c | 331 | ||||
-rw-r--r-- | strcmp.c | 19 | ||||
-rw-r--r-- | timer.c | 196 | ||||
-rw-r--r-- | undefined.c | 10 | ||||
-rw-r--r-- | vigenere.c | 71 | ||||
-rw-r--r-- | xcb_colormaps.c | 313 | ||||
-rw-r--r-- | xcb_imagereading.c | 126 |
32 files changed, 1911 insertions, 753 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f5da2e9 --- /dev/null +++ b/Makefile @@ -0,0 +1,38 @@ +CFLAGS = -std=gnu11 -Wall -Wextra +LDFLAGS = -Wl,--as-needed + +ifeq ($(DEBUG), 1) + CFLAGS += -Og -g +else + CFLAGS += -O2 +endif + +INSTALL = install -Dm755 + +prefix = /usr/local +bindir = $(prefix)/bin + +all: + @echo 'Error, target not specified.' + @make --no-print-directory help + +help: + @echo 'Usage:' + @echo ' To compile <filename>.c `make <filename>`' + @echo ' To install <filename> `make target=<filename> install`' + @echo ' To uninstall <filename> `make target=<filename> uninstall`' + @echo ' To clean up `make clean`' + + +$(DESTDIR)$(bindir)/%: % + $(INSTALL) $^ $(DESTDIR)$(bindir)/$(target) + +install: $(DESTDIR)$(bindir)/$(target) + +uninstall: + $(RM) "$(DESTDIR)$(bindir)/$(target)" + +clean: + find . -mindepth 1 -maxdepth 1 -executable -type f ! -name "prefix_header" -delete + +.PHONY : all install uninstall clean @@ -1,4 +1,10 @@ c-stuff ======= +This is simply a git repository of a directory in which I store all my +small c tests and other things. Don't expect amazing things, however, +some things in here (like the brainfuck to c parser) are projects that +don't get their own repository because of their size. -This is simply a git repository of a directory in which I store all my small c tests and other things. Don't expect amazing things, however, some things in here (like the brainfuck to c parser) are projects that don't get their own repository because of their size. +Licensing +========= +Only files with a license header are licensed under the GPLv3! The rest are unlicensed for reasons generally specified at the top of the file. diff --git a/addrofmain.c b/addrofmain.c new file mode 100644 index 0000000..547909f --- /dev/null +++ b/addrofmain.c @@ -0,0 +1,8 @@ +#include <stdio.h> + +int main(void) +{ + printf("%p\n", main); + + return 0; +} diff --git a/advigenere.c b/advigenere.c new file mode 100644 index 0000000..5ada41c --- /dev/null +++ b/advigenere.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2015 Tomasz Kramkowski <tk@the-tk.com> + * + * This program is free software. It is licensed under version 3 of the + * GNU General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see [http://www.gnu.org/licenses/]. + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#define CTOI(c) ((c) - 'A') +#define ITOC(c) ((c) + 'A') + +void preprocess(char *str); + +int main(int argc, char **argv) +{ + char *key, *ciphertext, *decoded; + size_t keylength, textlength; + + if (argc != 3) { + fprintf(stderr, "Usage: %s <ciphertext> <key>\n", argv[0]); + exit(EXIT_FAILURE); + } + + ciphertext = argv[1]; + key = argv[2]; + + preprocess(key); + preprocess(ciphertext); + + keylength = strlen(key); + textlength = strlen(ciphertext); + + decoded = malloc(textlength + 1); + + for (size_t i = 0; i < textlength; i++) + decoded[i] = (CTOI(ciphertext[i]) + CTOI(key[i % keylength])) % 26; + + for (unsigned offset = 0; offset < 26; offset++) { + printf("%.2u : ", offset); + for (unsigned i = 0; i < textlength; i++) + putchar(ITOC((decoded[i] + offset) % 26)); + putchar('\n'); + } + + free(decoded); + + return EXIT_SUCCESS; +} + +void preprocess(char *str) +{ + char *src = str, *dest = str; + + while (*src != '\0') { + if (isalpha(*src)) + *(dest++) = toupper(*src); + src++; + } + + *dest = '\0'; +} @@ -54,24 +54,24 @@ Ant *ant_new(uint16_t width, uint16_t height, char *actions) return ant; } -void ant_del(Ant *ant) +static void ant_del(Ant *ant) { free(ant->buffer); free(ant->actions); free(ant); } -void inline ant_left(Ant *ant) +static inline void ant_left(Ant *ant) { ant->direction = ant->direction == 0 ? 3 : ant->direction - 1; } -void inline ant_right(Ant *ant) +static inline void ant_right(Ant *ant) { ant->direction = ant->direction == 3 ? 0 : ant->direction + 1; } -void inline ant_forward(Ant *ant) +static inline void ant_forward(Ant *ant) { if (ant->direction & 1) { /* EAST or WEST */ ant->posx = ant->direction == EAST ? ant->posx + 1 : ant->posx - 1; @@ -109,7 +109,7 @@ int main(int argc, char **argv) xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data; uint32_t mask = XCB_CW_BACK_PIXEL; - uint32_t values[] = {screen->black_pixel}; + uint32_t values[2] = {screen->black_pixel}; xcb_drawable_t window = xcb_generate_id(connection); xcb_create_window(connection, @@ -194,5 +194,7 @@ int main(int argc, char **argv) ant_simulate(ant); } + + ant_del(ant); return 0; } diff --git a/blocks.c b/blocks.c deleted file mode 100644 index baf31f6..0000000 --- a/blocks.c +++ /dev/null @@ -1,5 +0,0 @@ -int main(void) -{ - int i = ({ static int i = 3; i + 5; }); - return i; -} diff --git a/editor.c b/editor.c new file mode 100644 index 0000000..afea796 --- /dev/null +++ b/editor.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2015 Tomasz Kramkowski <tk@the-tk.com> + * + * This program is free software. It is licensed under version 3 of the + * GNU General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see [http://www.gnu.org/licenses/]. + */ + +#define _GNU_SOURCE +#include <errno.h> +#include <error.h> +#include <ncurses.h> +#include <stdbool.h> +#include <stdio.h> + +bool running = true; +size_t position = 0; + +char *program = "#include <stdio.h>\n" \ + "\n" \ + "int main(void)\n" \ + "{\n" \ + "\tprintf(\"Hello World\\n\");\n" \ + "\n" \ + "\treturn 0;\n" \ + "}"; + +char *usage = "%sUsage:\n" \ + "\t%s <filename>"; + +void print_screen(void) +{ + mvaddnstr(0, 0, program, position); +} + +int getch_nodelay(void) +{ + int retval; + + nodelay(stdscr, TRUE); + retval = getch(); + nodelay(stdscr, FALSE); + + return retval; +} + + +void poll_input(void) +{ + int c = getch(); + + if (c == 27 && getch_nodelay() == ERR) { + running = false; + return; + } + + if (program[position] == c) + position++; +} + +int main(int argc, char **argv) +{ + FILE *file; + + if (argc != 2) + error(1, 0, usage, "Incorrect number of arguments\n", + program_invocation_name); + + cbreak(); + initscr(); + noecho(); + + intrflush(stdscr, FALSE); + + print_screen(); + while (running) { + poll_input(); + print_screen(); + } + + endwin(); + + if (file = fopen(argv[1], "w"), file == NULL) + error(1, errno, "Could not access %s", argv[1]); + + fwrite(program, 1, position, file); + + fclose(file); + + printf("Saved.\n"); + + return 0; +} diff --git a/endianness.c b/endianness.c new file mode 100644 index 0000000..c893be2 --- /dev/null +++ b/endianness.c @@ -0,0 +1,23 @@ +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +int main(void) +{ + bool big_endian; + + union { + uint32_t i; + char c[4]; + } test = {0x01020304}; + + big_endian = test.c[0] == 1; + + if (big_endian) + printf("%s\n", "Big Endian"); + else + printf("%s\n", "Small Endian"); + + return EXIT_SUCCESS; +} diff --git a/foursquare.c b/foursquare.c index c5ab68c..6fc894e 100644 --- a/foursquare.c +++ b/foursquare.c @@ -14,119 +14,118 @@ #include <ctype.h> #include <stdlib.h> #include <string.h> +#include <stdbool.h> #define Q ('Q'-'A') -typedef struct vec2 { - int x; - int y; -} Vec2; +#define CTOI(c) ((c) - 'A') +#define ITOC(c) ((c) + 'A') + +struct vec2 { + int x; + int y; +}; int increinc(int *); -void allupper(char *); +void preprocess(char *); void genkey(char *, char *); -Vec2 *newVec2(const int, const int); +struct vec2 *newVec2(const int, const int); int main(int argc, char **argv) { - int x, y, c=0; - - if(argc!=4){ - printf("Usage: %s <key1> <key2> <cipher>", *argv); - exit(1); - } - - printf("%s, %s ", *(argv+1), *(argv+2)); - - char *trkey = *(argv+1); - allupper(trkey); - char *trfullkey = malloc(26); - genkey(trkey, trfullkey); - - char *blkey = *(argv+2); - allupper(blkey); - char *blfullkey = malloc(26); - genkey(blkey, blfullkey); - - char *cipher = *(argv+3); - allupper(cipher); - - int i=0; - Vec2 *trtable[25]; - for(x=0; x<5; x++) - for(y=0; y<5; y++) - trtable[trfullkey[i++]-'A'] = newVec2(x, y); - free(trfullkey); - - i = 0; - Vec2 *bltable[25]; - for(x=0; x<5; x++) - for(y=0; y<5; y++) - bltable[blfullkey[i++]-'A'] = newVec2(x, y); - free(blfullkey); - - char basetable[5][5]; - for(x=0; x<5; x++) - for(y=0; y<5; y++){ - if(c==Q) - c++; - basetable[x][y] = 'A' + c++; - } - - for(i=0; i<strlen(cipher)/2; i++){ - char c1 = cipher[2*i]; - char c2 = cipher[2*i+1]; - - putchar(basetable[trtable[c1-'A']->x][bltable[c2-'A']->y]); - putchar(basetable[bltable[c2-'A']->x][trtable[c1-'A']->y]); - } - putchar('\n'); - - for(i=0; i++; i<25){ - free(trtable[i]); - free(bltable[i]); - } - - return 0; + int x, y, c = 0, i; + char trfullkey[26], blfullkey[26], *trkey, *blkey, *cipher; + struct vec2 trtable[25], bltable[25]; + + if(argc!=4){ + printf("Usage: %s <key1> <key2> <cipher>", *argv); + exit(1); + } + + printf("%s, %s ", *(argv+1), *(argv+2)); + + trkey = argv[1]; + preprocess(trkey); + genkey(trkey, trfullkey); + + blkey = argv[2]; + preprocess(blkey); + genkey(blkey, blfullkey); + + cipher = argv[3]; + preprocess(cipher); + + i = 0; + for(x=0; x<5; x++) + for(y=0; y<5; y++) { + trtable[CTOI(trfullkey[i])].x = x; + trtable[CTOI(trfullkey[i])].y = y; + i++; + } + + i = 0; + for(x=0; x<5; x++) + for(y=0; y<5; y++) { + bltable[CTOI(blfullkey[i])].x = x; + bltable[CTOI(blfullkey[i])].y = y; + i++; + } + + + char basetable[5][5]; + for (x = 0; x < 5; x++) + for (y = 0; y < 5; y++){ + if (c == Q) + c++; + basetable[x][y] = 'A' + c++; + } + + for(size_t i = 0; i < strlen(cipher) / 2; i++){ + char c1 = cipher[2*i]; + char c2 = cipher[2*i+1]; + + putchar(basetable[trtable[CTOI(c1)].x][bltable[CTOI(c2)].y]); + putchar(basetable[bltable[CTOI(c2)].x][trtable[CTOI(c1)].y]); + } + putchar('\n'); + + return EXIT_SUCCESS; } -int increinc(int *num) +inline int increinc(int *num) { - (*num)++; - return (*num)++; + (*num)++; + return (*num)++; } -void allupper(char *input) +void preprocess(char *str) { - int i; - for(i=0; i<strlen(input); i++) - if(isalpha(input[i])) - input[i]=toupper(input[i]); + char *src = str, *dest = str; + + while (*src != '\0') { + if (isalpha(*src)) + *(dest++) = toupper(*src); + src++; + } + + *(++dest) = '\0'; } void genkey(char *input, char *output) { - int dict[26]; - memset(dict, 0, 26*sizeof(int)); - - int i, outpt = 0; - for(i=0; i<strlen(input); i++){ - if(!dict[input[i]-'A']){ - output[outpt++]=input[i]; - } - dict[input[i]-'A'] += 1; - } - - for(i=0; i<26; i++) - if(!dict[i] && i!=Q) - output[outpt++]=i+'A'; - output[outpt]='\0'; -} + bool dict[26] = {0}; + int ii = 0; -Vec2 *newVec2(const int x, const int y) -{ - Vec2 *v = malloc(sizeof(Vec2)); - v->x = x; - v->y = y; - return v; + for (size_t i = 0; i < strlen(input); i++) { + if (!dict[CTOI(input[i])]) { + output[ii++] = input[i]; + dict[CTOI(input[i])] = true; + } + } + + for (unsigned i = 0; i < 26; i++) + if (!dict[i] && i != Q) + output[ii++] = ITOC(i); + + output[ii]='\0'; } diff --git a/genkeypairs.c b/genkeypairs.c index f6043fe..12f145b 100644 --- a/genkeypairs.c +++ b/genkeypairs.c @@ -13,31 +13,41 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <ctype.h> #define MAXLIST 1000 #define MAXKEY 100 -int main(int argc, char **argv) +int getword(char *output, int maxlength) { - int c, i, ii, listsize; - char *list[MAXLIST]; - char *word = malloc(MAXKEY+1); - for(i=0; i<MAXLIST; i++) - if(!getword(word, MAXKEY)) - break; - else - memcpy(list[i]=malloc(strlen(word)+1), word, strlen(word)+1); - listsize = ++i; - for(i=0; i<listsize; i++) - for(ii=i+1; ii<listsize-1; ii++) - printf("./justkeys %s %s\n", list[i], list[ii]); + int c, p=0; + while((c = getchar())!=EOF && isalpha(c) && p<maxlength) + output[p++] = (char)c; + output[p] = '\0'; + return p; } -int getword(char *output, int maxlength) +int main(int argc, char **argv) { - int c, p=0; - while((c=getchar())!=EOF && isalpha(c) && p<maxlength) - output[p++] = (char)c; - output[p] = '\0'; - return p; + int i, ii, listsize; + char *list[MAXLIST], word[MAXKEY+1], *command, *ciphertext; + + if (argc != 3) { + fprintf(stderr, "Usage: %s <command> <ciphertext>", argv[0]); + exit(EXIT_FAILURE); + } + + command = argv[1]; + ciphertext = argv[2]; + + for(i=0; i<MAXLIST; i++) + if(!getword(word, MAXKEY)) + break; + else + memcpy(list[i] = malloc(strlen(word)+1), word, strlen(word)+1); + + listsize = ++i; + for(i=0; i<listsize; i++) + for(ii=i+1; ii<listsize-1; ii++) + printf("%s %s %s %s\n", command, list[i], list[ii], ciphertext); } diff --git a/guesskeylength.c b/guesskeylength.c new file mode 100644 index 0000000..8b4409c --- /dev/null +++ b/guesskeylength.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2015 Tomasz Kramkowski <tk@the-tk.com> + * + * This program is free software. It is licensed under version 3 of the + * GNU General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see [http://www.gnu.org/licenses/]. + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#define CTOI(c) ((c) - 'A') +#define ITOC(c) ((c) + 'A') + +#define ALPHACHARS 26 + +void preprocess(char *str) +{ + char *src = str, *dest = str; + + while (*src != '\0') { + if (isalpha(*src)) + *(dest++) = toupper(*src); + src++; + } + + *dest = '\0'; +} + +double calc_ic_column(const char *text, size_t length, size_t offset, size_t spacing) +{ + unsigned foundc[ALPHACHARS] = {0}, total_chars = 0; + unsigned long pre_sum = 0; + + for (size_t i = offset; i < length; i += spacing, total_chars++) + foundc[CTOI(text[i])]++; + + for (unsigned i = 0; i < ALPHACHARS; i++) + pre_sum += foundc[i] * (foundc[i] - 1); + + return (double)pre_sum / ((double)total_chars * (double)(total_chars - 1) / ALPHACHARS); +} + +double calc_ic(const char *text, size_t length, size_t width) +{ + double total = 0; + + for (size_t offset = 0; offset < width; offset++) + total += calc_ic_column(text, length, offset, width); + + return total / width; +} + +int main(int argc, char **argv) +{ + char *text; + size_t length; + unsigned long max; + + if (argc != 3) { + fprintf(stderr, "Usage: %s <text> <max>\a\n", argv[0]); + exit(EXIT_FAILURE); + } + + text = argv[1]; + max = strtoul(argv[2], NULL, 10); + + preprocess(text); + length = strlen(text); + + for (unsigned long spacing = 1; spacing <= max; spacing++) { + double ic = calc_ic(text, length, spacing); + unsigned barlen; + + if (ic > 0.8 && ic < 4) + barlen = (ic - 0.8) / 3.2 * 40.0; + else + barlen = ic <= 0.8 ? 0 : 40; + + printf("%3lu - %6.3f ", spacing, ic); + for (unsigned i = 0; i < barlen; i++) + putchar('#'); + putchar('\n'); + } + + return EXIT_SUCCESS; +} diff --git a/hangman.c b/hangman.c new file mode 100644 index 0000000..dfb75dd --- /dev/null +++ b/hangman.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2015 Tomasz Kramkowski <tk@the-tk.com> + * + * This program is free software. It is licensed under version 3 of the + * GNU General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see [http://www.gnu.org/licenses/]. + */ +#include <ctype.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define ALPHABET_CHARS 26 +#define MAX_GUESS 5 + +enum state { + NONE, + WIN, + LOSS +}; + +int main(int argc, char **argv) +{ + bool guessed[ALPHABET_CHARS] = {0}, in_secret[ALPHABET_CHARS] = {0}; + char *secret; + int bad_guesses = 0, c; + size_t dest, length; + enum state state = NONE; + + if (argc != 2) { + fprintf(stderr, "Usage: %s <word>\n", argv[0]); + return EXIT_FAILURE; + } + + secret = argv[1]; + dest = 0; + length = strlen(secret); + for (size_t i = 0; i < length; i++) + if (isalpha(secret[i]) || isspace(secret[i])) + secret[dest++] = toupper(secret[i]); + + length = dest; + for (size_t i = 0; i < length; i++) + if (isalpha(secret[i])) + in_secret[secret[i] - 'A'] = true; + + printf("Hangman\n=======\n\n"); + for (size_t i = 0; i < length; i++) + if (isalpha(secret[i]) && !guessed[secret[i] - 'A']) + putchar('_'); + else + putchar(secret[i]); + putchar('\n'); + + while ((c = getchar()) != EOF) { + if (!isalpha(c)) + continue; + + c = toupper(c); + + if (guessed[c - 'A']) + goto print_state; + + if (!in_secret[c - 'A']) { + bad_guesses++; + printf("Wrong!\n"); + goto print_state; + } + + guessed[c - 'A'] = true; + + for (unsigned i = 0; i < ALPHABET_CHARS; i++) + if (in_secret[i] && !guessed[i]) + goto print_state; + + state = WIN; + + break; +print_state: + for (size_t i = 0; i < length; i++) + if (isalpha(secret[i]) && !guessed[secret[i] - 'A']) + putchar('_'); + else + putchar(secret[i]); + putchar('\n'); + printf("You have %d guesses left.\n", MAX_GUESS - bad_guesses); + + if (bad_guesses >= MAX_GUESS) { + state = LOSS; + break; + } + } + + switch (state) { + case WIN: + printf("You won.\n"); + break; + case LOSS: + printf("You lost, the secret word was: %s\n", secret); + break; + case NONE: + printf("Something weird happened.\n"); + break; + } +} diff --git a/imlib2.c b/imlib2.c deleted file mode 100644 index 4b4c72a..0000000 --- a/imlib2.c +++ /dev/null @@ -1,232 +0,0 @@ -// Imlib2 stuff which I think I copied from somewhere. - -#include <Imlib2.h> -#include <X11/Xlib.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> - -Display *disp; -Window win; -Visual *vis; -Colormap cm; -int depth; - -int main(int argc, char **argv) -{ - XEvent ev; - - Imlib_Updates updates, current_update; - Imlib_Image buffer; - Imlib_Font font; - Imlib_Color_Range range; - int mouse_x = 0, mouse_y = 0; - - disp = XOpenDisplay(NULL); - - vis = DefaultVisual(disp, DefaultScreen(disp)); - depth = DefaultDepth(disp, DefaultScreen(disp)); - cm = DefaultColormap(disp, DefaultScreen(disp)); - - win = XCreateSimpleWindow(disp, DefaultRootWindow(disp), - 0, 0, 640, 480, 0, 0, 0); - - XSelectInput(disp, win, ButtonPressMask | ButtonReleaseMask | - PointerMotionMask | ExposureMask); - - XMapWindow(disp, win); - - imlib_set_cache_size(2048 * 1024); - - imlib_set_font_cache_size(512 * 1024); - - imlib_add_path_to_font_path("./ttfonts"); - - imlib_set_color_usage(128); - - imlib_context_set_dither(1); - - imlib_context_set_display(disp); - imlib_context_set_visual(vis); - imlib_context_set_colormap(cm); - imlib_context_set_drawable(win); - - while(true) { - Imlib_Image image; - int w, h, text_w, text_h; - - updates = imlib_updates_init(); - - do { - XNextEvent(disp, &ev); - switch (ev.type) { - case Expose: - updates = imlib_update_append_rect(updates, - ev.xexpose.x, ev.xexpose.y, - ev.xexpose.width, ev.xexpose.height); - break; - case ButtonPress: - exit(0); - break; - case MotionNotify: - image = imlib_load_image("./test_images/mush.png"); - imlib_context_set_image(image); - w = imlib_image_get_width(); - h = imlib_image_get_height(); - - imlib_context_set_image(image); - imlib_free_image(); - - updates = imlib_update_append_rect(updates, - mouse_x - (w / 2), mouse_y - (h / 2), - w, h); - font = imlib_load_font("notepad/30"); - if (font) { - char text[4096]; - imlib_context_set_font(font); - sprintf(text, "Mouse is at %i, %i", mouse_x, mouse_y); - imlib_get_text_size(text, &text_w, &text_h); - imlib_free_font(); - - updates = imlib_update_append_rect(updates, - 320 - text_w / 2, 240 - text_h / 2, - text_w, text_h); - } - - mouse_x = ev.xmotion.x; - mouse_y = ev.xmotion.y; - - updates = imlib_update_append_rect(updates, - mouse_x - w / 2, mouse_y - h / 2, - w, h); - font = imlib_load_font("notepad/30"); - if (font) { - char text[4096]; - - imlib_context_set_font(font); - sprintf(text, "Mouse is at %i, %i", mouse_x, mouse_y); - imlib_get_text_size(text, &text_w, &text_h); - imlib_free_font(); - updates = imlib_update_append_rect(updates, - 320 - text_w / 2, 240 - text_h / 2, - text_w, text_h); - } - default: - break; - } - } while (XPending(disp)); - - - updates = imlib_updates_merge_for_rendering(updates, 640, 480); - for (current_update = updates; - current_update; - current_update = imlib_updates_get_next(current_update)) { - int up_x, up_y, up_w, up_h; - - imlib_updates_get_coordinates(current_update, &up_x, &up_y, &up_w, &up_h); - - buffer = imlib_create_image(up_w, up_h); - - imlib_context_set_blend(1); - - image = imlib_load_image("./test_images/bg.png"); - - imlib_context_set_image(image); - - w = imlib_image_get_width(); - h = imlib_image_get_height(); - - imlib_context_set_image(buffer); - - if (image) { - imlib_blend_image_onto_image(image, 0, 0, 0, - w, h, -up_x, -up_y, 640, 480); - - imlib_context_set_image(image); - - imlib_free_image(); - } - - image = imlib_load_image("./test_images/mush.png"); - imlib_context_set_image(image); - w = imlib_image_get_width(); - h = imlib_image_get_height(); - imlib_context_set_image(image); - if (image) { - imlib_blend_image_onto_image(image, 0, 0, 0, w, h, - mouse_x - w / 2 - up_x, - mouse_y - h / 2 - up_y, - w, h); - imlib_context_set_image(image); - imlib_free_image(); - } - - range = imlib_create_color_range(); - imlib_context_set_color_range(range); - - imlib_context_set_color(255, 255, 255, 255); - imlib_add_color_to_color_range(0); - - imlib_context_set_color(255, 200, 10, 100); - imlib_add_color_to_color_range(10); - - imlib_context_set_color(0, 0, 0, 0); - imlib_add_color_to_color_range(20); - - imlib_context_set_image(buffer); - imlib_image_fill_color_range_rectangle(-up_x, -up_y, 128, 128, -45); - - imlib_free_color_range(); - - font = imlib_load_font("notepad/30"); - if (font) { - char text[4096]; - - imlib_context_set_font(font); - imlib_context_set_image(buffer); - imlib_context_set_color(0, 0, 0, 255); - sprintf(text, "Mouse is at %i, %i", mouse_x, mouse_y); - imlib_get_text_size(text, &text_w, &text_h); - imlib_text_draw(320 - text_w / 2 - up_x, - 240 - text_h / 2 - up_y, - text); - imlib_free_font(); - } - - imlib_context_set_blend(0); - imlib_context_set_image(buffer); - imlib_render_image_on_drawable(up_x, up_y); - imlib_free_image(); - } - if (updates) - imlib_updates_free(updates); - } - return 0; -} - - /*Imlib_Image image = imlib_create_image(640, 480);*/ - - /*imlib_context_set_image(image);*/ - - /*imlib_context_set_color(255, 255, 255, 255);*/ - - /*imlib_image_fill_rectangle(0, 0, 640, 480);*/ - - /*imlib_context_set_color(255, 128, 0, 255);*/ - - /*ImlibPolygon poly = imlib_polygon_new();*/ - - /*imlib_polygon_add_point(poly, 0, 0);*/ - /*imlib_polygon_add_point(poly, 10, 440);*/ - /*imlib_polygon_add_point(poly, 600, 10);*/ - - /*imlib_image_fill_polygon(poly);*/ - - /*imlib_polygon_free(poly);*/ - - /*imlib_save_image("imlibtest.png");*/ - - /*imlib_free_image();*/ - - /*return 0;*/ -/*}*/ @@ -1,3 +1,12 @@ +/* + * Copyright (C) 2015 Tomasz Kramkowski <tk@the-tk.com> + * + * This program is free software. It is licensed under version 3 of the + * GNU General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see [http://www.gnu.org/licenses/]. + */ #include <stdio.h> #include <string.h> #include <lua.h> @@ -6,20 +15,18 @@ int main(int argc, char **argv) { - char buffer[256]; - int error; - lua_State *L = luaL_newstate(); - luaL_openlibs(L); + char buffer[256]; - while (fgets(buffer, sizeof(buffer), stdin) != NULL) { - error = luaL_loadbuffer(L, buffer, strlen(buffer), "line") - || lua_pcall(L, 0, 0, 0); - if (error) { - fprintf(stderr, "%s", lua_tostring(L, -1)); - lua_pop(L, 1); - } - } + lua_State *state = luaL_newstate(); + luaL_openlibs(state); - lua_close(L); - return 0; + while (fgets(buffer, sizeof(buffer), stdin) != NULL) { + if (luaL_loadbuffer(state, buffer, strlen(buffer), "line") || lua_pcall(state, 0, 0, 0)) { + fprintf(stderr, "%s", lua_tostring(state, -1)); + lua_pop(state, 1); + } + } + + lua_close(state); + return 0; } diff --git a/makefile b/makefile deleted file mode 100644 index 4bffe01..0000000 --- a/makefile +++ /dev/null @@ -1,27 +0,0 @@ -CFLAGS = -Wall -Wextra -Wpedantic -O2 -std=gnu11 - -PREFIX = /usr -BINDIR = /bin -INSPATH = $(DESTDIR)$(PREFIX)$(BINDIR) - -.PHONY : all install uninstall - -all: - @echo 'Error, target not specified.' - @echo ' To compile <filename>.c `make <filename>`' - @echo ' To install <filename> `make target=<filename> install`' - @echo ' To uninstall <filename> `make target=<filename> uninstall`' - -% : %.c - $(CC) $(CFLAGS) -o $@ $^ - -$(DESTDIR)$(PREFIX)$(BINDIR)/% : % - install -Dm755 "$^" "$@" - -install : $(DESTDIR)$(PREFIX)$(BINDIR)/$(target) - -uninstall : - rm "$(DESTDIR)$(PREFIX)$(BINDIR)/$(target)" - -clean : - find . -mindepth 1 -maxdepth 1 -executable -type f ! -name "prefix_header" -delete @@ -0,0 +1,130 @@ +/* + * This is an attempt at implementing md5 in c, so far it doesn't work :(. + * I took the values from wikipedia (https://en.wikipedia.org/wiki/MD5). + * + * Copyright (C) 2015 Tomasz Kramkowski <tk@the-tk.com> + * + * This program is free software. It is licensed under version 3 of the + * GNU General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see [http://www.gnu.org/licenses/]. + */ +#include <math.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +void shuffle_bytes(char *buf, size_t length) +{ + length = length - length % 4; + + for (size_t i = 0; i < length / 4; i++) { + char *bufc = buf + i * 4; + char chars[4] = { + bufc[3], + bufc[2], + bufc[1], + bufc[0] + }; + strncpy(bufc, chars, 4); + } +} + +int main(void) +{ + uint32_t *s, *K, a0, b0, c0, d0, length; + char input[64] = ""; + + length = strlen(input); + + s = (uint32_t []){ + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}; + + K = (uint32_t []){ + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391}; + + a0 = 0x67452301; + b0 = 0xefcdab89; + c0 = 0x98badcfe; + d0 = 0x10325476; + + input[length] = 128; + + for (uint8_t i = length + 1; i < 56; i++) + input[i] = 0; + + /*((uint64_t *)input)[7] = (uint64_t)length;*/ + input[63] = 0; + + for (uint8_t i = 0; i < 64; i++) + putchar(input[i]); + + /*shuffle_bytes(input, 64);*/ + uint32_t *M = (uint32_t *)input; + + uint32_t A = a0, B = b0, C = c0, D = d0; + + for (uint32_t i = 0; i < 64; i ++) { + uint16_t F, g, dTemp; + + switch (i) { + case 0 ... 15: + F = (B & C) | ((~B) & D); + g = i; + break; + case 16 ... 31: + F = (D & B) | ((~D) & C); + g = (5 * i + 1) % 16; + break; + case 32 ... 47: + F = B ^ C ^ D; + g = (3 * i + 5) % 16; + break; + case 48 ... 63: + F = C ^ (B | (~D)); + g = (7 * i) % 16; + break; + } + + dTemp = D; + + D = C; + C = B; + B += ((A + F + K[i] + M[g]) << s[i]) | ((A + F + K[i] + M[g]) >> (32-s[i])); + A = dTemp; + } + + a0 += A; + b0 += B; + c0 += C; + d0 += D; + + /*shuffle_bytes((char *)&a0, 4);*/ + /*shuffle_bytes((char *)&b0, 4);*/ + /*shuffle_bytes((char *)&c0, 4);*/ + /*shuffle_bytes((char *)&d0, 4);*/ + + printf("%.8x%.8x%.8x%.8x\n", a0, b0, c0, d0); + + return EXIT_SUCCESS; +} diff --git a/ncurses_windows.c b/ncurses_windows.c new file mode 100644 index 0000000..4a733ba --- /dev/null +++ b/ncurses_windows.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2015 Tomasz Kramkowski <tk@the-tk.com> + * + * This program is free software. It is licensed under version 3 of the + * GNU General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see [http://www.gnu.org/licenses/]. + */ +// -*- compile-command: "make LDLIBS=-lncurses ncurses_windows" -*- +#include <stdio.h> +#include <stdlib.h> +#include <ncurses.h> +#include <unistd.h> + +#define WIDTH 20 +#define HEIGHT 10 + +int main(void) +{ + WINDOW *box; + int c; + + initscr(); + cbreak(); + noecho(); + nonl(); + intrflush(stdscr, FALSE); + keypad(stdscr, TRUE); + start_color(); + + init_pair(1, COLOR_WHITE, COLOR_BLUE); + init_pair(2, COLOR_WHITE, COLOR_RED); + + box = derwin(stdscr, 10, 10, 10, 10); + + bkgd(COLOR_PAIR(1)); + wbkgd(box, COLOR_PAIR(2)); + + while ((c = getch()) != EOF) { + if (c == KEY_RESIZE) { + int x, y, width, height; + + erase(); + + getmaxyx(stdscr, y, x); + + width = x < WIDTH ? x : WIDTH; + height = y < HEIGHT ? y : HEIGHT; + + wresize(box, height, width); + + mvderwin(box, (y - height) / 2, (x - width) / 2); + + bkgd(COLOR_PAIR(1)); + + wbkgd(box, COLOR_PAIR(2)); + + box(box, 0, 0); + + refresh(); + } + } + + return EXIT_SUCCESS; +} diff --git a/poly_perim.c b/poly_perim.c new file mode 100644 index 0000000..8f1528f --- /dev/null +++ b/poly_perim.c @@ -0,0 +1,25 @@ +#include <stdio.h> +#include <math.h> + +double poly_perim(unsigned ndims, double *xcoords, double *ycoords) +{ + double retval = 0; + + for (unsigned i = 0; i < ndims; i++) { + double left = xcoords[(i + 1) % ndims] - xcoords[i]; + double right = ycoords[(i + 1) % ndims] - ycoords[i]; + + retval += sqrt(left * left + right * right); + } + + return retval; +} + +int main(void) +{ + printf("Perimiter: %f\n", poly_perim(3, + (double []){1, 1, 4}, + (double []){2, 5, 5})); + + return 0; +} diff --git a/pthreads.c b/pthreads.c new file mode 100644 index 0000000..87945fd --- /dev/null +++ b/pthreads.c @@ -0,0 +1,45 @@ +#define _GNU_SOURCE +#include <assert.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> + +#define NUM_THREADS 100 + +typedef void *(* thread_func)(void *); + +void *somefunction(int *arg) +{ + int loops = rand(); + + for (int i = 0; i < loops; i++) { + pthread_yield(); + for (;i < loops; i++); + } + + printf("%d:\t%d\n", *arg, loops); + + return NULL; +} + +int main(void) +{ + srand(time(NULL)); + + pthread_t threads[NUM_THREADS]; + int args[NUM_THREADS]; + + for (int i = 0; i < NUM_THREADS; i++) { + args[i] = i; + if (pthread_create(&threads[i], NULL, (thread_func)somefunction, args + i)) + return EXIT_FAILURE; + } + + for (int i = 0; i < NUM_THREADS; i++) + if (pthread_join(threads[i], NULL)) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} @@ -1,3 +1,12 @@ +/* + * Copyright (C) 2015 Tomasz Kramkowski <tk@the-tk.com> + * + * This program is free software. It is licensed under version 3 of the + * GNU General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see [http://www.gnu.org/licenses/]. + */ #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -8,28 +17,39 @@ int8_t randrange(int8_t from, int8_t to) { - int base_random = rand(); - if (RAND_MAX == base_random) return randrange(from, to); - int range = to - from, - remainder = RAND_MAX % range, - bucket = RAND_MAX / range; - if (base_random < RAND_MAX - remainder) { - return from + base_random/bucket; - } else { - return randrange(from, to); - } + int base_random = rand(); + if (RAND_MAX == base_random) return randrange(from, to); + int range = to - from, + remainder = RAND_MAX % range, + bucket = RAND_MAX / range; + if (base_random < RAND_MAX - remainder) { + return from + base_random/bucket; + } else { + return randrange(from, to); + } +} + + +static unsigned rand_to_max(unsigned max) +{ + double random; + + while ((random = rand()) == (double)RAND_MAX); + + return random / (double)RAND_MAX * (double)max; } int main(int argc, char **argv) { - srand(time(NULL)); - int r; - uint16_t *amounts = calloc(sizeof(uint16_t), (TO - FROM + 1)); - for (int i = 0; i < 1000; i++) - amounts[randrange(FROM, TO) - FROM]++; + srand(time(NULL)); + + uint64_t counter[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + for (int i = 0; i < 1000000; i++) + counter[rand_to_max(9)]++; - for (int i = 0; i < TO - FROM + 1; i++) - printf("%d: %d\n", i, amounts[i]); + for (int i = 0; i < 10; i++) + printf("%d: %lu\n", i, counter[i]); - return 0; + return EXIT_SUCCESS; } @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Tomasz Kramkowski <tk@the-tk.com> + * Copyright (C) 2014 - 2015 Tomasz Kramkowski <tk@the-tk.com> * * This program is free software. It is licensed under version 3 of the * GNU General Public License. @@ -16,7 +16,7 @@ int main(int argc, char **argv) { if (argc != 3) { - printf("Incorrect number of arguments.\n"); + fprintf(stderr, "Usage: <text> <rotation>\a\n"); exit(1); } @@ -0,0 +1,14 @@ +#include <stdio.h> +#include <stdlib.h> + +int main(void) +{ + char *input; + + scanf("%ms", &input); + + printf("%s", input); + free(input); + + return EXIT_SUCCESS; +} @@ -0,0 +1,131 @@ +#include <SDL2/SDL.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#define WIDTH 640 +#define HEIGHT 480 +#define DEPTH 32 + +enum obj_type { + O_QUAD, + O_TRIG, + O_CIRC +}; + +struct quad { + uint32_t x, y, width, height; +}; + +struct circle { + uint32_t x, y, diameter; +}; + +typedef union colour_t { + struct { + uint8_t a, r, g, b; + } comp; + uint32_t colour; +} colour_t; + +struct object { + enum obj_type type; + colour_t colour; + union { + struct quad quad; + struct circle circle; + } obj; +}; + +SDL_Window *window; +SDL_Renderer *renderer; +SDL_Texture *screen; +colour_t *buffer; + +struct object *objects; +uint32_t object_count; + +volatile bool running = true; + +#define QUOTE(text) "`" #text "'" +#define SDL_ASSERT(expr, comp, val) \ + if ((expr) comp val) { \ + fprintf(stderr, "SDL Error: %s - %s\n", QUOTE(expr), SDL_GetError()); \ + exit(EXIT_FAILURE); \ + } + +#define SDL_ASSERT_NN(expr) SDL_ASSERT(expr, ==, NULL) +#define SDL_ASSERT_Z(expr) SDL_ASSERT(expr, !=, 0) + +void prep_objects() +{ + objects = malloc(1 * sizeof *objects); + objects[0] = (struct object){O_QUAD, {{255, 0, 0, 0}}, {.quad = {30, 30, 30, 30}}}; + + object_count = 1; +} + +void draw_screen() +{ + for (size_t i = 0; i < WIDTH * HEIGHT; i++) + buffer[i] = (colour_t){{0, 255, 0, 0}}; + + SDL_UpdateTexture(screen, NULL, buffer, 640 * sizeof *buffer); + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, screen, NULL, NULL); + SDL_RenderPresent(renderer); +} + +void poll_for_events() +{ + SDL_Event event; + + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + exit(EXIT_SUCCESS); + break; + case SDL_KEYDOWN: + printf("Key.\n"); + break; + } + } +} + +void simulate(uint32_t difference) +{ + printf("%lu\n", difference); +} + +uint32_t get_time_delta() +{ + static uint32_t old_time; + uint32_t time = SDL_GetTicks(); + uint32_t difference = time - old_time; + old_time = time; + return difference; +} + +int main(void) +{ + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS); + atexit(SDL_Quit); + + window = SDL_CreateWindow("Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_OPENGL); + renderer = SDL_CreateRenderer(window, -1, 0); + screen = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 640, 480); + buffer = malloc(sizeof *buffer * 640 * 480); + + prep_objects(); + + get_time_delta(); + + while (running) { + draw_screen(); + poll_for_events(); + simulate(get_time_delta()); + } + + return(EXIT_SUCCESS); +} diff --git a/shufflechars.c b/shufflechars.c new file mode 100644 index 0000000..84a2c55 --- /dev/null +++ b/shufflechars.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 Tomasz Kramkowski <tk@the-tk.com> + * + * This program is free software. It is licensed under version 3 of the + * GNU General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see [http://www.gnu.org/licenses/]. + */ +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <time.h> + +static inline unsigned rand_to_max(unsigned max) +{ + double random; + + while ((random = rand()) == (double)RAND_MAX); + + return random / (double)RAND_MAX * (double)max; +} + +int main(int argc, char **argv) +{ + size_t length; + char *text, *dest; + + srand(time(NULL)); + + if (argc != 2) { + fprintf(stderr, "Usage: %s <text>\a\n", argv[0]); + exit(EXIT_FAILURE); + } + + text = argv[1]; + length = strlen(text); + + bool relocated[length]; + + memset(relocated, 0, length); + dest = malloc(length + 1); + + for (size_t i = 0; i < length; i++) { + size_t index; + while (index = rand_to_max(length), relocated[index]) + ; + + dest[i] = text[index]; + relocated[index] = true; + } + + dest[length] = '\0'; + + printf("%s\n", dest); + + return EXIT_SUCCESS; +} diff --git a/simple_x.c b/simple_x.c deleted file mode 100644 index 98ddbbe..0000000 --- a/simple_x.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * SimplX - Proposed name if not taken already. - * - * Copyright (C) 2014 Tomasz Kramkowski <tk@the-tk.com> - * - * This program is free software. It is licensed under version 3 of the - * GNU General Public License. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see [http://www.gnu.org/licenses/]. - */ -#include <stdlib.h> -#include <xcb/xcb.h> -#include <xcb/xcb_image.h> - -/* - * TODO: Figure out the alignment of these things fix the arrangement. - * Find a good name for this. - */ -typedef struct sx_gc { - /*struct {*/ - xcb_connection_t *connection; - xcb_screen_t *screen; - xcb_drawable_t window; - xcb_pixmap_t pixmap; - xcb_image_t *image; - xcb_gcontext_t gc; - /*} xcb;*/ -} SX; - -SX *sx_new_gc(uint16_t width, uint16_t height) -{ - SX *sx = malloc(sizeof(SX)); - - sx->connection = xcb_connect(NULL, NULL); - - sx->screen = xcb_setup_roots_iterator(xcb_get_setup(sx->connection)).data; - - uint32_t mask = XCB_CW_BACK_PIXEL; /* Needs events */ - uint32_t values[] = {sx->screen->black_pixel}; - - sx->window = xcb_generate_id(sx->connection); - xcb_create_window(sx->connection, - 24, - sx->window, - sx->screen->root, - 0, 0, - width, height, - 1, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - sx->screen->root_visual, - mask, values); - - sx->pixmap = xcb_generate_id(sx->connection); - xcb_create_pixmap(sx->connection, - 24, - sx->pixmap, - sx->window, - width, height); - - uint8_t *img = malloc(width * height * 4); - xcb_image_t *image = xcb_image_create(width, height, - XCB_IMAGE_FORMAT_Z_PIXMAP, - 8, 24, 32, - 0, - XCB_IMAGE_ORDER_MSB_FIRST, - XCB_IMAGE_ORDER_LSB_FIRST, - img, - width * height * 4, - img); - - mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND; - values[0] = sx->screen->black_pixel; - values[1] = 0xFFFFFF; - - sx->gc = xcb_generate_id(sx->connection); - xcb_create_gc(sx->connection, - sx->gc, - sx->pixmap, - mask, values); - - return sx; -} @@ -0,0 +1,331 @@ +/* + * A simple implementation of the snake game. + * Compile with: `make LDLIBS=-lncurses snake' + * + * Copyright (C) 2015 Tomasz Kramkowski <tk@the-tk.com> + * + * This program is free software. It is licensed under version 3 of the + * GNU General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see [http://www.gnu.org/licenses/]. + */ +#include <argp.h> +#include <ncurses.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> + +#define USEC_SECOND 1000000 + +enum colorpair { + C_BLANK = 1, + C_WALL, + C_SEGMENT0, + C_SEGMENT1, + C_APPLE +}; + +enum direction { + D_UP, + D_DOWN, + D_LEFT, + D_RIGHT +}; + +enum state { + S_NORMAL, + S_WON, + S_FAIL +}; + +struct segment { + uint32_t x, y; +}; + +struct snake { + struct segment segments[UINT16_MAX]; + uint16_t head, tail; + enum direction direction; +}; + +struct apple { + uint32_t x, y; +}; + +struct { + struct snake snake; + struct apple apple; + uint32_t width, height; + bool running; + enum state state; + bool alternate_color; +} game; + +struct arguments { + useconds_t delay; + uint16_t desired_width, desired_height; + bool alternate_color; +} arguments; + +const char *argp_program_version = "1.0rc1"; +const char *argp_program_bug_address = "<snake@the-tk.com>"; + +void init_ncurses(void) +{ + cbreak(); + initscr(); + noecho(); + nonl(); + start_color(); + + intrflush(stdscr, FALSE); + keypad(stdscr, TRUE); + nodelay(stdscr, TRUE); + + init_pair(C_BLANK, COLOR_BLACK, COLOR_BLACK); + init_pair(C_WALL, COLOR_WHITE, COLOR_WHITE); + init_pair(C_SEGMENT0, COLOR_YELLOW, COLOR_YELLOW); + init_pair(C_SEGMENT1, COLOR_GREEN, COLOR_GREEN); + init_pair(C_APPLE, COLOR_RED, COLOR_RED); + + bkgd(COLOR_PAIR(C_BLANK)); +} + +void init_game(void) +{ + game.running = true; + game.state = S_NORMAL; + + game.snake.direction = D_UP; + + getmaxyx(stdscr, game.height, game.width); + + game.snake.head = 1; + game.snake.tail = 0; + + game.snake.segments[game.snake.tail].x = game.width / 2; + game.snake.segments[game.snake.tail].y = game.height / 2; + + game.snake.segments[game.snake.head].x = game.width / 2; + game.snake.segments[game.snake.head].y = game.height / 2 - 1; + + game.apple.x = game.width / 2; + game.apple.y = game.height / 2 + 1; +} + +void print_board(void) +{ + erase(); + + for (uint16_t i = game.snake.tail; i <= game.snake.head; i++) { + chtype ch; + + if ((i - game.snake.head * !arguments.alternate_color) % 2) + ch = ACS_BLOCK | COLOR_PAIR(C_SEGMENT0); + else + ch = ACS_BLOCK | COLOR_PAIR(C_SEGMENT1); + mvaddch(game.snake.segments[i].y, game.snake.segments[i].x, ch); + } + + + mvaddch(game.apple.y, game.apple.x, ACS_BLOCK | COLOR_PAIR(C_APPLE)); + + refresh(); +} + +void redirect(enum direction desired_dir) +{ + struct segment *current = &game.snake.segments[game.snake.head]; + struct segment *previous = &game.snake.segments[game.snake.head - 1]; + + if (desired_dir == game.snake.direction) + return; + + if (current->x == previous->x) { + if (current->y > previous->y) { + if (desired_dir == D_UP) + return; + } else { + if (desired_dir == D_DOWN) + return; + } + } else if (current->y == previous->y) { + if (current->x > previous->x) { + if (desired_dir == D_LEFT) + return; + } else { + if (desired_dir == D_RIGHT) + return; + } + } + + game.snake.direction = desired_dir; +} + +void poll_input(void) +{ + int c; + + while ((c = getch()) != ERR) + switch (c) { + case 'h': redirect(D_LEFT); break; + case 'j': redirect(D_DOWN); break; + case 'k': redirect(D_UP); break; + case 'l': redirect(D_RIGHT); break; + case 'q': game.running = false; break; + } +} + +inline uint16_t rand_to_max(uint16_t max) +{ + double random; + + while ((random = rand()) == (double)RAND_MAX); + return random / (double)RAND_MAX * (double)max; +} + +inline bool part_of_snake(uint16_t x, uint16_t y) +{ + for (uint16_t i = game.snake.tail; i != game.snake.head; i++) + if (game.snake.segments[i].x == x && game.snake.segments[i].y == y) + return true; + + return false; +} + +void replace_apple(void) +{ + uint16_t x, y; + + while (true) { + x = rand_to_max(game.width); + y = rand_to_max(game.height); + + if (part_of_snake(x, y)) + continue; + + game.apple.x = x; + game.apple.y = y; + + break; + } +} + +void simulate(void) +{ + struct segment *head = &game.snake.segments[game.snake.head]; + struct segment *tail = &game.snake.segments[game.snake.tail]; + int64_t dx = 0, dy = 0, nx, ny; + + switch (game.snake.direction) { + case D_UP: dy = -1; break; + case D_DOWN: dy = 1; break; + case D_LEFT: dx = -1; break; + case D_RIGHT: dx = 1; break; + } + + nx = (int64_t)head->x + dx; + ny = (int64_t)head->y + dy; + + if (nx < 0 || nx >= game.width || ny < 0 || ny >= game.height) { + game.running = false; + game.state = S_FAIL; + return; + } + + if (nx == game.apple.x && ny == game.apple.y) { + game.snake.head++; + game.snake.segments[game.snake.head].x = nx; + game.snake.segments[game.snake.head].y = ny; + + replace_apple(); + return; + } + + if (part_of_snake(nx, ny) && !(tail->x == nx && tail->y == ny)) { + game.running = false; + game.state = S_FAIL; + return; + } + + game.snake.head++; + game.snake.segments[game.snake.head].x = nx; + game.snake.segments[game.snake.head].y = ny; + + game.snake.tail++; +} + +void main_loop(void) +{ + print_board(); + poll_input(); + + while (game.running) { + usleep(arguments.delay); + poll_input(); + simulate(); + print_board(); + } +} + +error_t parse_arg(int key, char *arg, struct argp_state *state) +{ + struct arguments *arguments = state->input; + + switch (key) { + case 'w': + fprintf(stderr, "Width setting is not yet implemented.\n"); + arguments->desired_width = strtol(arg, NULL, 10); + break; + case 'h': + fprintf(stderr, "Height setting is not yet implemented.\n"); + arguments->desired_height = strtol(arg, NULL, 10); + break; + case 'a': + arguments->alternate_color = true; + break; + case 'd': + arguments->delay = strtod(arg, NULL) * (double)USEC_SECOND; + break; + default: + return ARGP_ERR_UNKNOWN; + } + + return 0; +} + +void parse_args(int argc, char **argv) +{ + char *doc = "An ncurses implementation of snake in c."; + + struct argp_option options[] = { + {"width", 'w', "<width>", 0, "Desired width.", 0}, + {"height", 'h', "<height>", 0, "Desired height.", 0}, + {"alternate", 'a', NULL, 0, "Alternate snake colour.", 0}, + {"delay", 'd', "<seconds>", 0, "Delay between ticks in seconds. (default: 0.1)", 0}, + {0} + }; + + struct argp argp = {options, parse_arg, NULL, doc, NULL, NULL, NULL}; + + arguments.desired_width = 0; + arguments.desired_height = 0; + arguments.alternate_color = false; + arguments.delay = (double)USEC_SECOND * 0.1; + + argp_parse(&argp, argc, argv, 0, 0, &arguments); +} + +int main(int argc, char **argv) +{ + parse_args(argc, argv); + init_ncurses(); + init_game(); + + main_loop(); + + endwin(); + return EXIT_SUCCESS; +} diff --git a/strcmp.c b/strcmp.c new file mode 100644 index 0000000..7633d80 --- /dev/null +++ b/strcmp.c @@ -0,0 +1,19 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int main(void) +{ + char *input; + + scanf("%ms", &input); + + if (strcmp(input, "Test") == 0) + printf("Match\n"); + else + printf("Fail\n"); + + free(input); + + return EXIT_SUCCESS; +} @@ -10,70 +10,198 @@ * along with this program. If not, see [http://www.gnu.org/licenses/]. */ +#include <errno.h> +#include <error.h> +#include <signal.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/ioctl.h> #include <time.h> #include <unistd.h> +#include <limits.h> -unsigned long int get_seconds(char *); +#define SEC_SECOND 1 +#define SEC_MINUTE 60 +#define SEC_HOUR 3600 +#define SEC_DAY 86400 +#define SEC_MONTH 2629746 +#define SEC_YEAR 31556940 + +static const unsigned long interval_nsec = 1000000000 / 4; + +unsigned long int get_seconds(char *code) +{ + int length = strlen(code), multiplier = 0; + char suffix = code[length - 1], value[length + 1]; + unsigned long retval; + + if (length < 2) { + return 0; + } + + switch (suffix) { + case 's': multiplier = SEC_SECOND; break; // 1 second + case 'm': multiplier = SEC_MINUTE; break; // 1 minute + case 'h': multiplier = SEC_HOUR; break; // 1 hour + case 'D': multiplier = SEC_DAY; break; // 1 day + case 'M': multiplier = SEC_MONTH; break; // 30.4368 days + case 'Y': multiplier = SEC_YEAR; break; // 365.242 days + default : return 0; + } + + strncpy(value, code, length + 1); + + value[length - 1] = '\0'; + + errno = 0; + + retval = strtoul(value, NULL, 10) * multiplier; + + if (retval == ULONG_MAX && errno != 0) + error(1, errno, "Error converting time specifier %s", code); + + return retval; +} + +void clear_line(void) +{ + struct winsize ws; + + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1) + error(1, errno, "IOCTL failed"); + + if (ws.ws_col <= 1) + return; + + for (unsigned short i = 0; i < ws.ws_col - 1; i++) + putchar(' '); + + putchar('\r'); + + if (fflush(stdout) != 0) + error(1, errno, "Failed to flush stdout"); +} + + +void print_time(unsigned long total_sec, bool show_colon) +{ + unsigned long years, months, days, hours, minutes, seconds; + char colon = show_colon ? ':' : ' '; + + years = total_sec / SEC_YEAR; + total_sec %= SEC_YEAR; + + months = total_sec / SEC_MONTH; + total_sec %= SEC_MONTH; + + days = total_sec / SEC_DAY; + total_sec %= SEC_DAY; + + hours = total_sec / SEC_HOUR; + total_sec %= SEC_HOUR; + + minutes = total_sec / SEC_MINUTE; + total_sec %= SEC_MINUTE; + + seconds = total_sec / SEC_SECOND; + total_sec %= SEC_SECOND; + + if (total_sec != 0) + error(1, 0, "An error occured during time formatting"); + + printf(" %luY %luM %luD %.2lu%c%.2lu%c%.2lu\r", years, months, + days, hours, colon, minutes, colon, seconds); + + if (fflush(stdout) != 0) + error(1, errno, "Failed to flush stdout"); +} void usage(char *cmd) { - printf("Usage:\n" - "\t%s <n>{s,m,h,D,M,Y} ...\n", cmd); + printf("Usage:\n\t%s <n>{s,m,h,D,M,Y} ...\n", cmd); } int main(int argc, char **argv) { + bool blink = false; + int sig; + sigset_t sigset; + struct itimerspec its; + struct sigevent sev; + timer_t timerid; + + unsigned long total_seconds = 0; + if (argc < 2) { printf("Not enough arguments.\n"); usage(argv[0]); exit(1); } - unsigned long int total_seconds = 0; - for (int i = 1; i < argc; i++) total_seconds += get_seconds(argv[i]); - printf("Total time: %lu second(s).\nStarted at: %d\n", total_seconds, time(NULL)); + sev.sigev_notify = SIGEV_SIGNAL; + sev.sigev_signo = SIGRTMIN; + sev.sigev_value.sival_ptr = &timerid; - sleep(total_seconds); + if (timer_create(CLOCK_MONOTONIC, &sev, &timerid) != 0) + error(1, errno, "Could not create timer"); - printf("Ended at: %d\n", time(NULL)); + its = (struct itimerspec){ + {0, interval_nsec}, + {0, interval_nsec} + }; - while (1) { - printf("Ring!\a\n"); - sleep(1); - } + if (sigemptyset(&sigset) != 0) + error(1, errno, "Could not empty signal set"); - return 0; -} + if (sigaddset(&sigset, SIGRTMIN) != 0) + error(1, errno, "Could not add SIGRTMIN to signal set"); -unsigned long int get_seconds(char *code) -{ - int length = strlen(code); - if (length < 2) { - return 0; - } + if (sigprocmask(SIG_BLOCK, &sigset, NULL) != 0) + error(1, errno, "Could not block SIGRTMIN"); - int multiplier = 0; - char suffix = code[length - 1]; - switch (suffix) { - case 's': multiplier = 1; break; // 1 second - case 'm': multiplier = 60; break; // 1 minute - case 'h': multiplier = 3600; break; // 1 hour - case 'D': multiplier = 86400; break; // 1 day - case 'M': multiplier = 2629746; break; // 30.4368 days - case 'Y': multiplier = 31556940; break; // 365.242 days - default : return 0; + if (timer_settime(timerid, 0, &its, NULL) != 0) + error(1, errno, "Could not set timer"); + + for (unsigned long i = 0; i < total_seconds; i++) + for (int ii = 0; ii < 4; ii++) { + if (sigwait(&sigset, &sig), sig != SIGRTMIN) + error(1, 0, "sigwait returned unexpected signal %d", sig); + if (sigaddset(&sigset, SIGRTMIN) != 0) + error(1, errno, "Could not add signal to set"); + + clear_line(); + print_time(total_seconds - i, ii < 2); + } + + if (sigaddset(&sigset, SIGINT) != 0) + error(1, errno, "Could not add SIGINT to signal set"); + + while (true) { + blink = !blink; + sigwait(&sigset, &sig); + if (sig != SIGRTMIN) + break; + + if (sigaddset(&sigset, SIGRTMIN) != 0) + error(1, errno, "Could not add signal to set"); + + clear_line(); + + if (blink) + printf(" -- BEEP -- \a\r"); + + if (fflush(stdout) != 0) + error(1, errno, "Failed to flush stdout"); } - char value[length + 1]; - strncpy(value, code, length + 1); + timer_delete(timerid); - value[length - 1] = '\0'; + clear_line(); - return strtoul(value, NULL, 10) * multiplier; + return 0; } diff --git a/undefined.c b/undefined.c new file mode 100644 index 0000000..38977d8 --- /dev/null +++ b/undefined.c @@ -0,0 +1,10 @@ +#include <stdio.h> + +int main(void) +{ + int i = 0; + + printf("%d %d %d %d\n", i, i++, i, i++); + + return 0; +} diff --git a/vigenere.c b/vigenere.c new file mode 100644 index 0000000..9a64c3c --- /dev/null +++ b/vigenere.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2015 Tomasz Kramkowski <tk@the-tk.com> + * + * This program is free software. It is licensed under version 3 of the + * GNU General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see [http://www.gnu.org/licenses/]. + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#define CTOI(c) ((c) - 'A') +#define ITOC(c) ((c) + 'A') + +void preprocess(char *str); + +int main(int argc, char **argv) +{ + char *key, *ciphertext, *decodepos, *decodeneg; + long offset; + size_t keylength, textlength; + + if (argc != 4) { + fprintf(stderr, "Usage: %s <offset> <ciphertext> <key>\n", argv[0]); + exit(EXIT_FAILURE); + } + + offset = strtol(argv[1], NULL, 10); + ciphertext = argv[2]; + key = argv[3]; + + preprocess(key); + preprocess(ciphertext); + + keylength = strlen(key); + textlength = strlen(ciphertext); + + decodepos = malloc(textlength + 1); + decodeneg = malloc(textlength + 1); + + for (size_t i = 0; i < textlength; i++) { + decodepos[i] = ITOC((CTOI(ciphertext[i]) + offset + CTOI(key[i % keylength])) % 26); + decodeneg[i] = ITOC((CTOI(ciphertext[i]) + 52 - offset - CTOI(key[i % keylength])) % 26); + } + + decodepos[textlength] = '\0'; + decodeneg[textlength] = '\0'; + + printf("+ %s\n- %s\n", decodepos, decodeneg); + + free(decodepos); + free(decodeneg); + + return EXIT_SUCCESS; +} + +void preprocess(char *str) +{ + char *src = str, *dest = str; + + while (*src != '\0') { + if (isalpha(*src)) + *(dest++) = toupper(*src); + src++; + } + + *dest = '\0'; +} diff --git a/xcb_colormaps.c b/xcb_colormaps.c index 1aacea0..f417fdc 100644 --- a/xcb_colormaps.c +++ b/xcb_colormaps.c @@ -22,174 +22,175 @@ void perlin(uint8_t * const, uint16_t, uint16_t); int main(int arg, char **argv) { - srand(time(NULL)); - xcb_connection_t *connection = xcb_connect(NULL, NULL); - - xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data; - - xcb_colormap_t colormap = screen->default_colormap; - - xcb_drawable_t window = xcb_generate_id(connection); - uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; - uint32_t values[] = {screen->black_pixel, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS}; - xcb_create_window(connection, - /*screen->root_depth,*/ - 24, - window, - screen->root, - 0, 0, - WIDTH, HEIGHT, - 1, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - screen->root_visual, - mask, values); - - xcb_pixmap_t pixmap = xcb_generate_id(connection); - xcb_create_pixmap(connection, - 24, - pixmap, - window, - WIDTH, HEIGHT); - - uint8_t *img = malloc(WIDTH * HEIGHT * 4); - - uint8_t *limg = img; - /*for (int y = 0; y < HEIGHT; y++)*/ - /*for (int x = 0; x < WIDTH; x++) {*/ - /**(limg++) = 128;*/ - /**(limg++) = 128;*/ - /**(limg++) = 128;*/ - /*limg++;*/ - /*}*/ - perlin(img, WIDTH, HEIGHT); - - xcb_image_t *image = xcb_image_create(WIDTH, HEIGHT, - XCB_IMAGE_FORMAT_Z_PIXMAP, - 8, 24, 32, - 0, - /*xcb_get_setup(connection)->image_byte_order,*/ - XCB_IMAGE_ORDER_MSB_FIRST, - XCB_IMAGE_ORDER_LSB_FIRST, - img, - WIDTH * HEIGHT * 4, - img); - - xcb_gcontext_t gc = xcb_generate_id(connection); - xcb_create_gc(connection, - gc, - pixmap, - 0, NULL); - - xcb_image_put(connection, pixmap, gc, image, 0, 0, 0); - - xif_write(image, "test.xif"); - - xcb_map_window(connection, window); - xcb_flush(connection); - - xcb_generic_event_t *event; - while ((event = xcb_wait_for_event(connection))) { - switch (event->response_type & ~0x80) { - case XCB_EXPOSE: ; - xcb_expose_event_t *expose = (xcb_expose_event_t *)event; - xcb_copy_area(connection, - pixmap, - window, - gc, - expose->x, expose->y, - expose->x, expose->y, - expose->width, expose->height); - xcb_flush(connection); - break; - case XCB_BUTTON_PRESS: - goto end; - break; - default: - break; - } - free(event); - } + srand(time(NULL)); + xcb_connection_t *connection = xcb_connect(NULL, NULL); + + xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data; + + xcb_colormap_t colormap = screen->default_colormap; + + xcb_drawable_t window = xcb_generate_id(connection); + uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; + uint32_t values[] = {screen->black_pixel, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS}; + xcb_create_window(connection, + /*screen->root_depth,*/ + 24, + window, + screen->root, + 0, 0, + WIDTH, HEIGHT, + 1, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + screen->root_visual, + mask, values); + + xcb_pixmap_t pixmap = xcb_generate_id(connection); + xcb_create_pixmap(connection, + 24, + pixmap, + window, + WIDTH, HEIGHT); + + uint8_t *img = malloc(WIDTH * HEIGHT * 4); + + uint8_t *limg = img; + /*for (int y = 0; y < HEIGHT; y++)*/ + /*for (int x = 0; x < WIDTH; x++) {*/ + /**(limg++) = 128;*/ + /**(limg++) = 128;*/ + /**(limg++) = 128;*/ + /*limg++;*/ + /*}*/ + perlin(img, WIDTH, HEIGHT); + + xcb_image_t *image = xcb_image_create(WIDTH, HEIGHT, + XCB_IMAGE_FORMAT_Z_PIXMAP, + 8, 24, 32, + 0, + /*xcb_get_setup(connection)->image_byte_order,*/ + XCB_IMAGE_ORDER_MSB_FIRST, + XCB_IMAGE_ORDER_LSB_FIRST, + img, + WIDTH * HEIGHT * 4, + img); + + xcb_gcontext_t gc = xcb_generate_id(connection); + xcb_create_gc(connection, + gc, + pixmap, + 0, NULL); + + xcb_image_put(connection, pixmap, gc, image, 0, 0, 0); + + xif_write(image, "test.xif"); + + xcb_map_window(connection, window); + xcb_flush(connection); + + xcb_generic_event_t *event; + xcb_expose_event_t *expose; + while ((event = xcb_wait_for_event(connection))) { + switch (event->response_type & ~0x80) { + case XCB_EXPOSE: + expose = (xcb_expose_event_t *)event; + xcb_copy_area(connection, + pixmap, + window, + gc, + expose->x, expose->y, + expose->x, expose->y, + expose->width, expose->height); + xcb_flush(connection); + break; + case XCB_BUTTON_PRESS: + goto end; + break; + default: + break; + } + free(event); + } end: - xcb_free_pixmap(connection, pixmap); - xcb_disconnect(connection); + xcb_free_pixmap(connection, pixmap); + xcb_disconnect(connection); - xcb_image_destroy(image); + xcb_image_destroy(image); - return 0; + return 0; } int8_t randrange(int8_t from, int8_t to) { - int base_random = rand(); - if (RAND_MAX == base_random) return randrange(from, to); - int range = to - from, - remainder = RAND_MAX % range, - bucket = RAND_MAX / range; - if (base_random < RAND_MAX - remainder) { - return from + base_random/bucket; - } else { - return randrange(from, to); - } + int base_random = rand(); + if (RAND_MAX == base_random) return randrange(from, to); + int range = to - from, + remainder = RAND_MAX % range, + bucket = RAND_MAX / range; + if (base_random < RAND_MAX - remainder) { + return from + base_random/bucket; + } else { + return randrange(from, to); + } } #define lerp(t, a, b) (a + t * (b - a)) void perlin(uint8_t * const img, uint16_t width, uint16_t height) { - uint8_t *limg = img; - for (int y = 0; y < HEIGHT; y++) - for (int x = 0; x < WIDTH; x++) { - *(limg++) = 128; - *(limg++) = 128; - *(limg++) = 128; - limg++; - } - - int8_t *mipmap = malloc(sizeof(int8_t) * (2 * 2 + 4 * 4 + 8 * 8 + 16 * 16) * 4); - - int8_t *lmipmap = mipmap; - for (int s = 2; s <= 16; s*=2) - for (int x = 0; x < s * s; x++) { - *(lmipmap++) = randrange(-128 / s, 128 / s); - *(lmipmap++) = randrange(-128 / s, 128 / s); - *(lmipmap++) = randrange(-128 / s, 128 / s); - lmipmap++; - printf("S: %d X: %d Y: %d R: %d G: %d B: %d\n", s, x / s, x, *(lmipmap-4), *(lmipmap-3), *(lmipmap-2)); - }; - - limg = img; - lmipmap = mipmap; - for (int y = 0; y < height; y++) - for (int x = 0; x < width; x++) - for (int bit = 0; bit < 2; bit ++) { - for (int s = 2; s <= 16; s*=2) { - size_t offset = 0; - for (int i = s / 2; i >= 2; i/=2) - offset += i * i; - lmipmap = mipmap + offset; - uint16_t xblock = width / (s - 1); - uint16_t yblock = height / (s - 1); - - uint8_t xbpos = (float)x / (float)xblock; - uint8_t ybpos = (float)y / (float)yblock; - - float xmul = (float)x / (float)width - (float)xbpos; - float ymul = (float)y / (float)height - (float)ybpos; - - int8_t valtl, valtr, valbl, valbr; - valtl = lmipmap[bit + 4 * (ybpos * s + xbpos)]; - valtr = lmipmap[bit + 4 * (ybpos * s + xbpos + 1)]; - valbl = lmipmap[bit + 4 * ((ybpos + 1) * s + xbpos)]; - valbr = lmipmap[bit + 4 * ((ybpos + 1) * s + xbpos + 1)]; - - int8_t wlerpu = lerp(xmul, valtl, valtr); - int8_t wlerpl = lerp(xmul, valbl, valbr); - - int8_t endval = lerp(ymul, wlerpl, wlerpu); - - limg[bit + 4 * (y * width + x)] = limg[bit + 4 * (y * width + x)] + endval; - } - } - free(mipmap); + uint8_t *limg = img; + for (int y = 0; y < HEIGHT; y++) + for (int x = 0; x < WIDTH; x++) { + *(limg++) = 128; + *(limg++) = 128; + *(limg++) = 128; + limg++; + } + + int8_t *mipmap = malloc(sizeof(int8_t) * (2 * 2 + 4 * 4 + 8 * 8 + 16 * 16) * 4); + + int8_t *lmipmap = mipmap; + for (int s = 2; s <= 16; s*=2) + for (int x = 0; x < s * s; x++) { + *(lmipmap++) = randrange(-128 / s, 128 / s); + *(lmipmap++) = randrange(-128 / s, 128 / s); + *(lmipmap++) = randrange(-128 / s, 128 / s); + lmipmap++; + printf("S: %d X: %d Y: %d R: %d G: %d B: %d\n", s, x / s, x, *(lmipmap-4), *(lmipmap-3), *(lmipmap-2)); + }; + + limg = img; + lmipmap = mipmap; + for (int y = 0; y < height; y++) + for (int x = 0; x < width; x++) + for (int bit = 0; bit < 2; bit ++) { + for (int s = 2; s <= 16; s*=2) { + size_t offset = 0; + for (int i = s / 2; i >= 2; i/=2) + offset += i * i; + lmipmap = mipmap + offset; + uint16_t xblock = width / (s - 1); + uint16_t yblock = height / (s - 1); + + uint8_t xbpos = (float)x / (float)xblock; + uint8_t ybpos = (float)y / (float)yblock; + + float xmul = (float)x / (float)width - (float)xbpos; + float ymul = (float)y / (float)height - (float)ybpos; + + int8_t valtl, valtr, valbl, valbr; + valtl = lmipmap[bit + 4 * (ybpos * s + xbpos)]; + valtr = lmipmap[bit + 4 * (ybpos * s + xbpos + 1)]; + valbl = lmipmap[bit + 4 * ((ybpos + 1) * s + xbpos)]; + valbr = lmipmap[bit + 4 * ((ybpos + 1) * s + xbpos + 1)]; + + int8_t wlerpu = lerp(xmul, valtl, valtr); + int8_t wlerpl = lerp(xmul, valbl, valbr); + + int8_t endval = lerp(ymul, wlerpl, wlerpu); + + limg[bit + 4 * (y * width + x)] = limg[bit + 4 * (y * width + x)] + endval; + } + } + free(mipmap); } diff --git a/xcb_imagereading.c b/xcb_imagereading.c index 26e5852..4a3e18c 100644 --- a/xcb_imagereading.c +++ b/xcb_imagereading.c @@ -19,78 +19,80 @@ int main(int arg, char **argv) { - xcb_connection_t *connection = xcb_connect(NULL, NULL); + xcb_connection_t *connection = xcb_connect(NULL, NULL); - xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data; + xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data; - xcb_colormap_t colormap = screen->default_colormap; + xcb_colormap_t colormap = screen->default_colormap; - xcb_drawable_t window = xcb_generate_id(connection); - uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; - uint32_t values[] = {screen->black_pixel, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS}; - xcb_create_window(connection, - /*screen->root_depth,*/ - 24, - window, - screen->root, - 0, 0, - WIDTH, HEIGHT, - 1, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - screen->root_visual, - mask, values); + xcb_drawable_t window = xcb_generate_id(connection); + uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; + uint32_t values[] = {screen->black_pixel, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS}; + xcb_create_window(connection, + /*screen->root_depth,*/ + 24, + window, + screen->root, + 0, 0, + WIDTH, HEIGHT, + 1, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + screen->root_visual, + mask, values); - xcb_pixmap_t pixmap = xcb_generate_id(connection); - xcb_create_pixmap(connection, - 24, - pixmap, - window, - WIDTH, HEIGHT); - xcb_image_t *image; - if (!(image = xif_read("test.xif"))) { - fputs("Error: xif_read returned null.\n", stderr); - exit(1); - } + xcb_pixmap_t pixmap = xcb_generate_id(connection); + xcb_create_pixmap(connection, + 24, + pixmap, + window, + WIDTH, HEIGHT); + xcb_image_t *image; + if (!(image = xif_read("test.xif"))) { + fputs("Error: xif_read returned null.\n", stderr); + exit(1); + } - xcb_gcontext_t gc = xcb_generate_id(connection); - xcb_create_gc(connection, - gc, - pixmap, - 0, NULL); + xcb_gcontext_t gc = xcb_generate_id(connection); + xcb_create_gc(connection, + gc, + pixmap, + 0, NULL); - xcb_image_put(connection, pixmap, gc, image, 0, 0, 0); + xcb_image_put(connection, pixmap, gc, image, 0, 0, 0); - xcb_map_window(connection, window); - xcb_flush(connection); + xcb_map_window(connection, window); + xcb_flush(connection); - xcb_generic_event_t *event; - while ((event = xcb_wait_for_event(connection))) { - switch (event->response_type & ~0x80) { - case XCB_EXPOSE: ; - xcb_expose_event_t *expose = (xcb_expose_event_t *)event; - xcb_copy_area(connection, - pixmap, - window, - gc, - expose->x, expose->y, - expose->x, expose->y, - expose->width, expose->height); - xcb_flush(connection); - break; - case XCB_BUTTON_PRESS: - goto end; - break; - default: - break; - } - free(event); - } + xcb_generic_event_t *event; + while ((event = xcb_wait_for_event(connection))) { + switch (event->response_type & ~0x80) { + case XCB_EXPOSE: + { + xcb_expose_event_t *expose = (xcb_expose_event_t *)event; + xcb_copy_area(connection, + pixmap, + window, + gc, + expose->x, expose->y, + expose->x, expose->y, + expose->width, expose->height); + xcb_flush(connection); + break; + } + case XCB_BUTTON_PRESS: + goto end; + break; + default: + break; + } + free(event); + } end: - xcb_free_pixmap(connection, pixmap); - xcb_disconnect(connection); + xcb_free_pixmap(connection, pixmap); + xcb_disconnect(connection); - xcb_image_destroy(image); + xcb_image_destroy(image); - return 0; + return 0; } |