rayzor
diff src/main.cc @ 0:2a5340a6eee4
rayzor first commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 05 Apr 2014 08:46:27 +0300 |
parents | |
children | a826bf0fb169 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/main.cc Sat Apr 05 08:46:27 2014 +0300 1.3 @@ -0,0 +1,212 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <string.h> 1.7 +#include <math.h> 1.8 +#include "inttypes.h" 1.9 +#include "gfx.h" 1.10 +#include "keyb.h" 1.11 +#include "mouse.h" 1.12 +#include "logger.h" 1.13 + 1.14 +static void display(); 1.15 +static void swap_buffers(); 1.16 +static void handle_keyboard(); 1.17 +static void handle_mouse(); 1.18 +static bool parse_args(int argc, char **argv); 1.19 + 1.20 +static int xsz = 800; 1.21 +static int ysz = 600; 1.22 +static int bpp = 16; 1.23 +static int bytespp; 1.24 +static unsigned char *fb; 1.25 +static unsigned char *backbuf; 1.26 +static int rbits, gbits, bbits; 1.27 +static int rshift, gshift, bshift; 1.28 +static unsigned int rmask, gmask, bmask; 1.29 + 1.30 +static bool quit; 1.31 + 1.32 +int main(int argc, char **argv) 1.33 +{ 1.34 + if(!parse_args(argc, argv)) { 1.35 + return 1; 1.36 + } 1.37 + if(kb_init(32) == -1) { 1.38 + fprintf(stderr, "failed to initialize keyboard driver\n"); 1.39 + return 1; 1.40 + } 1.41 + if(!(fb = (unsigned char*)set_video_mode(xsz, ysz, bpp))) { 1.42 + set_text_mode(); 1.43 + fprintf(stderr, "failed to set video mode: %dx%d %dbpp\n", xsz, ysz, bpp); 1.44 + return 1; 1.45 + } 1.46 + bpp = get_color_depth(); 1.47 + get_color_bits(&rbits, &gbits, &bbits); 1.48 + get_color_shift(&rshift, &gshift, &bshift); 1.49 + get_color_mask(&rmask, &gmask, &bmask); 1.50 + bytespp = (int)ceil(bpp / 8.0); 1.51 + 1.52 + printlog("bpp: %d (%d %d %d)\n", bpp, rbits, gbits, bbits); 1.53 + printlog("shift: %d %d %d\n", rshift, gshift, bshift); 1.54 + printlog("mask: %x %x %x\n", rmask, gmask, bmask); 1.55 + 1.56 + backbuf = new unsigned char[xsz * ysz * 3]; 1.57 + 1.58 + // main loop 1.59 + for(;;) { 1.60 + handle_keyboard(); 1.61 + handle_mouse(); 1.62 + if(quit) break; 1.63 + 1.64 + display(); 1.65 + } 1.66 + 1.67 + delete [] backbuf; 1.68 + 1.69 + set_text_mode(); 1.70 + kb_shutdown(); 1.71 + 1.72 + printf("Thank you for using Rayzor!\n"); 1.73 + return 0; 1.74 +} 1.75 + 1.76 +static void display() 1.77 +{ 1.78 + unsigned char *fbptr = backbuf; 1.79 + 1.80 + for(int i=0; i<ysz; i++) { 1.81 + for(int j=0; j<xsz; j++) { 1.82 + bool chess = ((i / 16) & 1) == ((j / 16) & 1); 1.83 + fbptr[chess ? 0 : 2] = 255; 1.84 + fbptr[1] = 128; 1.85 + fbptr[chess ? 2 : 0] = 32; 1.86 + fbptr += 3; 1.87 + } 1.88 + } 1.89 + 1.90 + swap_buffers(); 1.91 +} 1.92 + 1.93 +#define PACK_RGB(r, g, b) \ 1.94 + ((((r) << rshift) & rmask) | \ 1.95 + (((g) << gshift) & gmask) | \ 1.96 + (((b) << bshift) & bmask)) 1.97 + 1.98 +static void swap_buffers() 1.99 +{ 1.100 + unsigned char *src = backbuf; 1.101 + int num_pixels = xsz * ysz; 1.102 + 1.103 + switch(bpp) { 1.104 + case 32: 1.105 + { 1.106 + uint32_t *dest = (uint32_t*)fb; 1.107 + for(int i=0; i<num_pixels; i++) { 1.108 + *dest++ = PACK_RGB(src[0], src[1], src[2]); 1.109 + src += 3; 1.110 + } 1.111 + } 1.112 + break; 1.113 + 1.114 + case 24: 1.115 + memcpy(fb, backbuf, num_pixels * 3); 1.116 + break; 1.117 + 1.118 + case 16: 1.119 + case 15: 1.120 + { 1.121 + int srs = 8 - rbits; 1.122 + int sgs = 8 - gbits; 1.123 + int sbs = 8 - bbits; 1.124 + uint16_t *dest = (uint16_t*)fb; 1.125 + for(int i=0; i<num_pixels; i++) { 1.126 + *dest++ = PACK_RGB(src[0] >> srs, src[1] >> sgs, src[2] >> sbs); 1.127 + src += 3; 1.128 + } 1.129 + } 1.130 + break; 1.131 + 1.132 + default: 1.133 + break; 1.134 + } 1.135 +} 1.136 + 1.137 +static void handle_keyboard() 1.138 +{ 1.139 + if(!kb_isdown(KB_ANY)) 1.140 + return; 1.141 + 1.142 + int c = kb_getkey(); 1.143 + switch(c) { 1.144 + case 27: 1.145 + quit = true; 1.146 + return; 1.147 + } 1.148 +} 1.149 + 1.150 +static void handle_mouse() 1.151 +{ 1.152 +} 1.153 + 1.154 +static struct { 1.155 + int opt; 1.156 + const char *lopt; 1.157 + const char *desc; 1.158 +} options[] = { 1.159 + {'s', "size", "resolution <xres>x<yres>[:bpp]"}, 1.160 + {'h', "help", "print usage information and exit"}, 1.161 + {-1, 0, 0} 1.162 +}; 1.163 + 1.164 +static void print_usage(const char *argv0) 1.165 +{ 1.166 + printf("%s usage\n", argv0); 1.167 + for(int i=0; options[i].opt != -1; i++) { 1.168 + printf(" -%c, -%s: %s\n", options[i].opt, options[i].lopt, options[i].desc); 1.169 + } 1.170 + exit(0); 1.171 +} 1.172 + 1.173 +static bool parse_args(int argc, char **argv) 1.174 +{ 1.175 + for(int i=1; i<argc; i++) { 1.176 + if(argv[i][0] == '-') { 1.177 + int opt = -1; 1.178 + 1.179 + for(int j=0; options[j].opt != -1; j++) { 1.180 + if(argv[i][2] == 0) { 1.181 + if(argv[i][1] == options[j].opt) { 1.182 + opt = options[j].opt; 1.183 + break; 1.184 + } 1.185 + } else { 1.186 + if(strcmp(argv[i] + 1, options[j].lopt) == 0) { 1.187 + opt = options[j].opt; 1.188 + break; 1.189 + } 1.190 + } 1.191 + } 1.192 + 1.193 + switch(opt) { 1.194 + case 's': 1.195 + if(sscanf(argv[++i], "%dx%d:%d", &xsz, &ysz, &bpp) < 2) { 1.196 + fprintf(stderr, "%s must be followed by a resolution: WxH\n", argv[i - 1]); 1.197 + return false; 1.198 + } 1.199 + break; 1.200 + 1.201 + case 'h': 1.202 + print_usage(argv[0]); // doesn't return 1.203 + break; 1.204 + 1.205 + default: 1.206 + fprintf(stderr, "unknown option: %s\n", argv[i]); 1.207 + return false; 1.208 + } 1.209 + } else { 1.210 + fprintf(stderr, "unexpected argument: %s\n", argv[i]); 1.211 + return false; 1.212 + } 1.213 + } 1.214 + return true; 1.215 +}