bytepusher.c (2886B)
1 #include <stdlib.h> 2 3 #include <SDL2/SDL.h> 4 5 #ifdef _WIN_32 6 typedef unsigned int u_int32_t; 7 typedef unsigned short u_int16_t; 8 typedef unsigned char u_int8_t; 9 #else 10 #include <sys/types.h> 11 #endif /* _WIN_32 */ 12 13 #define RGB_CALC ((r) * 0x33 << 16 | (g) * 0x33 << 8 | (b) * 0x33) 14 #define RGB_POS ((r) * 36 + (g) * 6 + (b)) 15 #define PC_POS (pc[3] << 16 | pc[4] << 8 | pc[5]) 16 17 static u_int32_t palette[0x100]; 18 static u_int8_t mem[0x1000008]; 19 static const u_int8_t keys[16] = { 20 SDLK_1, SDLK_2, SDLK_3, SDLK_4, 21 SDLK_q, SDLK_w, SDLK_e, SDLK_r, 22 SDLK_a, SDLK_s, SDLK_d, SDLK_f, 23 SDLK_z, SDLK_x, SDLK_c, SDLK_v 24 }; 25 26 static int 27 evhandle(void) 28 { 29 SDL_Event ev; 30 size_t i; 31 u_int16_t keybits; 32 33 keybits = mem[0] << 8 | mem[1]; 34 while (SDL_PollEvent(&ev)) { 35 if (ev.type == SDL_QUIT || ev.key.keysym.sym == SDLK_ESCAPE) 36 return (0); 37 if (ev.type == SDL_KEYDOWN) 38 for (i = 0; i < 16; i++) 39 if (ev.key.keysym.sym == keys[i]) 40 keybits = (keybits & ~(1 << i)) | 41 (ev.type == SDL_KEYDOWN) << i; 42 } 43 mem[0] = keybits >> 8; 44 mem[1] = keybits & 0xFF; 45 return (1); 46 } 47 48 static void 49 cycle(void) 50 { 51 size_t i = 0x10000; 52 u_int8_t *pc; 53 54 pc = mem + (mem[2] << 16 | mem[3] << 8 | mem[4]); 55 while (i--) { 56 mem[PC_POS] = mem[pc[0] << 16 | pc[1] << 8 | pc[2]]; 57 pc = mem + (pc[6] << 16 | pc[7] << 8 | pc[8]); 58 } 59 } 60 61 static void 62 render(SDL_Renderer *ren, SDL_Texture *tex) 63 { 64 u_int32_t pixels[0x10000]; 65 u_int32_t *out; 66 u_int8_t *in; 67 68 in = mem + (mem[5] << 16); 69 out = pixels; 70 for (; out < (pixels + 0x10000); *out++ = palette[*in++]) 71 ; 72 SDL_UpdateTexture(tex, 0, pixels, 73 0x100 * SDL_BYTESPERPIXEL(SDL_PIXELFORMAT_BGRA32)); 74 SDL_RenderClear(ren); 75 SDL_RenderCopy(ren, tex, 0, 0); 76 SDL_RenderPresent(ren); 77 } 78 79 int 80 main(int argc, char *argv[]) 81 { 82 SDL_Window *win; 83 SDL_Renderer *ren; 84 SDL_Texture *tex; 85 FILE *fp; 86 size_t i; 87 int w = 256, h = 256; 88 u_int8_t r, g, b; 89 90 if (argc != 2) { 91 fprintf(stderr, "usage: %s rom\n", argv[0]); 92 return (1); 93 } 94 if ((fp = fopen(argv[1], "r")) == NULL) { 95 fprintf(stderr, "fopen: %s\n", argv[1]); 96 return (1); 97 } 98 for (i = 0; (mem[i] = fgetc(fp)) != EOF && i < sizeof(mem); i++) 99 ; 100 fclose(fp); 101 102 /* TODO: implement audio */ 103 win = SDL_CreateWindow("bytepusher", SDL_WINDOWPOS_UNDEFINED, 104 SDL_WINDOWPOS_UNDEFINED, w, h, SDL_WINDOW_SHOWN); 105 ren = SDL_CreateRenderer(win, -1, 0); 106 tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_BGRA32, 107 SDL_TEXTUREACCESS_STATIC, w, h); 108 109 if (!win || !ren || !tex) { 110 fprintf(stderr, "SDL error: %s\n", SDL_GetError()); 111 return (1); 112 } 113 114 for (r = 0; r < 6; r++) 115 for (g = 0; g < 6; g++) 116 for (b = 0; b < 6; b++) 117 palette[RGB_POS] = RGB_CALC; 118 119 for (i = 0xd8; i < 0x100; i++) 120 palette[i] = 0x000000; 121 122 for (;;) { 123 if (!evhandle()) 124 break; 125 cycle(); 126 render(ren, tex); 127 SDL_Delay(10); 128 } 129 130 SDL_DestroyTexture(tex); 131 SDL_DestroyRenderer(ren); 132 SDL_DestroyWindow(win); 133 SDL_Quit(); 134 135 return (0); 136 }