- 
      
- 
        Save JettMonstersGoBoom/06932170a8348d302fee5cf08e61318e to your computer and use it in GitHub Desktop. 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | // Windows | |
| // gcc c6.c tigr\tigr.c -I tigr -lopengl32 -lgdi32 -Os -s -o c6.exe | |
| // Linux | |
| // gcc c6.c tigr\tigr.c -I tigr -lGLU -lGL -lX11 -Os -s -o c6.exe | |
| // OSX | |
| // gcc c6.c tigr\tigr.c -I tigr -framework OpenGL -framework Cocoa -Os -s -o c6.exe | |
| // using Tigr | |
| // from https://github.com/erkkah/tigr | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <stdint.h> | |
| #include "tigr.h" | |
| // NOTE Zoom is removed as it's not needed with Tigr | |
| // PAD is reduced | |
| #define PAD 8 | |
| #define color1 0x000000 | |
| #define color2 0x72DEC2 | |
| #define color3 0xFFFFFF | |
| #define color4 0x444444 | |
| #define color0 0x111111 | |
| typedef struct Point { | |
| int x; | |
| int y; | |
| } Point; | |
| typedef struct Brush { | |
| int color; | |
| int down; | |
| Point pos; | |
| } Brush; | |
| unsigned char buffer[4096]; | |
| int colors[] = {color1, color2, color3, color4, color0}; | |
| int WIDTH = 128 + PAD * 2; | |
| int HEIGHT = 128 + PAD * 2; | |
| int GUIDES = 1; | |
| Tigr *screen; | |
| uint32_t* pixels; | |
| Point *setpt(Point* p, int x, int y) | |
| { | |
| p->x = x; | |
| p->y = y; | |
| return p; | |
| } | |
| void pixel(uint32_t* dst, Point p, int c) | |
| { | |
| int x, y; | |
| p.x = (p.x) + PAD; | |
| p.y = (p.y) + PAD; | |
| dst[(p.y) * WIDTH + (p.x)] = c; | |
| } | |
| void draw(uint32_t* dst, int id, int color) | |
| { | |
| int ti = id / 64; | |
| int px = (ti / 256) * 128; | |
| int tx = (ti % 16) * 8; | |
| int ty = ((ti / 16) * 8) % 128; | |
| int odd = (ti + (ti / 16 + 2)) % 2 == 0; | |
| Point p; | |
| p.x = px + tx + (id % 8); | |
| p.y = ty + ((id % 64) / 8); | |
| pixel(dst, p, colors[GUIDES && odd && color == 0 ? 4 : color]); | |
| } | |
| void redraw(void) | |
| { | |
| int b, i, j, id = 0, ch1, ch2, color; | |
| for(b = 0; b < 4096; b += 16) | |
| { | |
| for(i = 0; i < 8; i++) | |
| { | |
| for(j = 7; j >= 0; j--) | |
| { | |
| ch1 = buffer[b + i]; | |
| ch2 = buffer[b + i + 8]; | |
| color = ((ch1 >> j) & 0x1) + (((ch2 >> j) & 0x1) << 1); | |
| draw(pixels, id, color); | |
| id++; | |
| } | |
| } | |
| } | |
| } | |
| void write(int tx, int ty, int px, int py, int color) | |
| { | |
| int id = tx + ty * 16; | |
| int row = py + id * 16; | |
| if(id > 255) | |
| return; | |
| if(color == 0) { | |
| buffer[row] &= ~(1UL << (7 - px)); | |
| buffer[row + 8] &= ~(1UL << (7 - px)); | |
| } else if(color == 2) { | |
| buffer[row] |= 1UL << (7 - px); | |
| buffer[row + 8] &= ~(1UL << (7 - px)); | |
| } else if(color == 1) { | |
| buffer[row] &= ~(1UL << (7 - px)); | |
| buffer[row + 8] |= 1UL << (7 - px); | |
| } else if(color == 3) { | |
| buffer[row] |= 1UL << (7 - px); | |
| buffer[row + 8] |= 1UL << (7 - px); | |
| } | |
| } | |
| void edit(Brush* b) | |
| { | |
| Point p1; | |
| setpt(&p1, b->pos.x - PAD, b->pos.y - PAD); | |
| if(p1.x < 0 || p1.y < 0 || p1.x > 128 || p1.y > 128 ) | |
| return; | |
| write( | |
| p1.x / (8), | |
| p1.y / (8), | |
| (p1.x) % 8, | |
| (p1.y) % 8, | |
| b->color); | |
| redraw(); | |
| } | |
| void erase(Brush* b) | |
| { | |
| int i, id; | |
| Point p1; | |
| setpt(&p1, b->pos.x - PAD, b->pos.y - PAD); | |
| if(p1.x < 0 || p1.y < 0 || p1.x > 128 || p1.y > 128) | |
| return; | |
| id = (p1.x / (8)) + (p1.y / (8)) * 16; | |
| for(i = 0; i < 8; ++i) { | |
| buffer[(id * 16) + i] = 0x00; | |
| buffer[(id * 16) + i + 8] = 0x00; | |
| } | |
| redraw(); | |
| } | |
| int error(char* msg, const char* err) | |
| { | |
| printf("Error %s: %s\n", msg, err); | |
| return 0; | |
| } | |
| void create(void) | |
| { | |
| int i; | |
| for(i = 0; i < 4096; ++i) | |
| buffer[i] = 0x00; | |
| redraw(); | |
| } | |
| void save(void) | |
| { | |
| FILE* f = fopen("output.chr", "wb"); | |
| if(!fwrite(buffer, sizeof(buffer), 1, f)) | |
| error("Save", "Invalid output file"); | |
| fclose(f); | |
| } | |
| void load(char* path) | |
| { | |
| FILE* f = fopen(path, "rb"); | |
| if(f == NULL) | |
| error("Load", "Invalid input file"); | |
| if(!fread(buffer, sizeof(buffer), 1, f)) | |
| error("Load", "Invalid file size"); | |
| fclose(f); | |
| redraw(); | |
| } | |
| void quit(void) | |
| { | |
| tigrFree(screen); | |
| exit(0); | |
| } | |
| void domouse(void* event, Brush* b) | |
| { | |
| static int last_buttons = 0x0000; | |
| int input_buttons,x,y; | |
| tigrMouse(screen,&x,&y,&input_buttons); | |
| // left released | |
| if (((input_buttons&1)==0) && ((last_buttons&1)!=0)) | |
| b->down = 0; | |
| // left held or pressed | |
| if ((input_buttons&1)==1) | |
| b->down = 1; | |
| // right released | |
| if (((input_buttons&4)==0) && ((last_buttons&4)!=0)) | |
| { | |
| setpt(&b->pos, x, y); | |
| erase(b); | |
| } | |
| // left held or pressed | |
| if ((input_buttons&1)==1) | |
| b->down = 1; | |
| if(b->down==1) { | |
| setpt(&b->pos, x, y); | |
| edit(b); | |
| } | |
| last_buttons = input_buttons; | |
| } | |
| void dokey(void* event, Brush* b) | |
| { | |
| if (tigrKeyDown(screen,'1')) | |
| b->color = 0; | |
| if (tigrKeyDown(screen,'2')) | |
| b->color = 1; | |
| if (tigrKeyDown(screen,'3')) | |
| b->color = 2; | |
| if (tigrKeyDown(screen,'4')) | |
| b->color = 3; | |
| if (tigrKeyDown(screen,'H')) | |
| { | |
| GUIDES = !GUIDES; | |
| redraw(); | |
| } | |
| } | |
| int | |
| init(void) | |
| { | |
| int i, j; | |
| screen = tigrWindow(WIDTH, HEIGHT, "CHR66", TIGR_3X); | |
| pixels = (uint32_t*)&screen->pix[0]; | |
| for(i = 0; i < HEIGHT; i++) | |
| for(j = 0; j < WIDTH; j++) | |
| pixels[i * WIDTH + j] = 0x000000; | |
| return 1; | |
| } | |
| int | |
| main(int argc, char** argv) | |
| { | |
| int ticknext = 0; | |
| Brush brush; | |
| brush.color = 1; | |
| if(!init()) | |
| return error("TIGR", "failure"); | |
| /* IO */ | |
| if(argc > 1) | |
| load(argv[1]); | |
| else | |
| create(); | |
| /* main loop */ | |
| while (!tigrClosed(screen) && !tigrKeyDown(screen, TK_ESCAPE)) | |
| { | |
| tigrUpdate(screen); | |
| domouse(NULL,&brush); | |
| dokey(NULL,&brush); | |
| } | |
| quit(); | |
| return 0; | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment