rev |
line source |
nuclear@1
|
1 #include <stdio.h>
|
nuclear@1
|
2 #include <stdlib.h>
|
nuclear@1
|
3 #include <string.h>
|
nuclear@1
|
4 #include <math.h>
|
nuclear@1
|
5 #include "inttypes.h"
|
nuclear@1
|
6 #include "gfx.h"
|
nuclear@1
|
7 #include "keyb.h"
|
nuclear@1
|
8 #include "mouse.h"
|
nuclear@1
|
9 #include "logger.h"
|
nuclear@1
|
10
|
nuclear@1
|
11 static void display();
|
nuclear@1
|
12 static void swap_buffers();
|
nuclear@1
|
13 static void handle_keyboard();
|
nuclear@1
|
14 static void handle_mouse();
|
nuclear@1
|
15 static bool parse_args(int argc, char **argv);
|
nuclear@1
|
16
|
nuclear@1
|
17 static int xsz = 800;
|
nuclear@1
|
18 static int ysz = 600;
|
nuclear@1
|
19 static int bpp = 16;
|
nuclear@1
|
20 static int bytespp;
|
nuclear@1
|
21 static unsigned char *fb;
|
nuclear@1
|
22 static unsigned char *backbuf;
|
nuclear@1
|
23 static int rbits, gbits, bbits;
|
nuclear@1
|
24 static int rshift, gshift, bshift;
|
nuclear@1
|
25 static unsigned int rmask, gmask, bmask;
|
nuclear@1
|
26
|
nuclear@1
|
27 static bool quit;
|
nuclear@1
|
28
|
nuclear@1
|
29 int main(int argc, char **argv)
|
nuclear@1
|
30 {
|
nuclear@1
|
31 if(!parse_args(argc, argv)) {
|
nuclear@1
|
32 return 1;
|
nuclear@1
|
33 }
|
nuclear@1
|
34 if(kb_init(32) == -1) {
|
nuclear@1
|
35 fprintf(stderr, "failed to initialize keyboard driver\n");
|
nuclear@1
|
36 return 1;
|
nuclear@1
|
37 }
|
nuclear@1
|
38 if(!(fb = (unsigned char*)set_video_mode(xsz, ysz, bpp))) {
|
nuclear@1
|
39 set_text_mode();
|
nuclear@1
|
40 fprintf(stderr, "failed to set video mode: %dx%d %dbpp\n", xsz, ysz, bpp);
|
nuclear@1
|
41 return 1;
|
nuclear@1
|
42 }
|
nuclear@1
|
43 bpp = get_color_depth();
|
nuclear@1
|
44 get_color_bits(&rbits, &gbits, &bbits);
|
nuclear@1
|
45 get_color_shift(&rshift, &gshift, &bshift);
|
nuclear@1
|
46 get_color_mask(&rmask, &gmask, &bmask);
|
nuclear@1
|
47 bytespp = (int)ceil(bpp / 8.0);
|
nuclear@1
|
48
|
nuclear@1
|
49 printlog("bpp: %d (%d %d %d)\n", bpp, rbits, gbits, bbits);
|
nuclear@1
|
50 printlog("shift: %d %d %d\n", rshift, gshift, bshift);
|
nuclear@1
|
51 printlog("mask: %x %x %x\n", rmask, gmask, bmask);
|
nuclear@1
|
52
|
nuclear@1
|
53 backbuf = new unsigned char[xsz * ysz * 3];
|
nuclear@1
|
54
|
nuclear@1
|
55 // main loop
|
nuclear@1
|
56 for(;;) {
|
nuclear@1
|
57 handle_keyboard();
|
nuclear@1
|
58 handle_mouse();
|
nuclear@1
|
59 if(quit) break;
|
nuclear@1
|
60
|
nuclear@1
|
61 display();
|
nuclear@1
|
62 }
|
nuclear@1
|
63
|
nuclear@1
|
64 delete [] backbuf;
|
nuclear@1
|
65
|
nuclear@1
|
66 set_text_mode();
|
nuclear@1
|
67 kb_shutdown();
|
nuclear@1
|
68
|
nuclear@1
|
69 printf("Thank you for using Rayzor!\n");
|
nuclear@1
|
70 return 0;
|
nuclear@1
|
71 }
|
nuclear@1
|
72
|
nuclear@1
|
73 static void display()
|
nuclear@1
|
74 {
|
nuclear@1
|
75 unsigned char *fbptr = backbuf;
|
nuclear@1
|
76
|
nuclear@1
|
77 for(int i=0; i<ysz; i++) {
|
nuclear@1
|
78 for(int j=0; j<xsz; j++) {
|
nuclear@1
|
79 bool chess = ((i / 16) & 1) == ((j / 16) & 1);
|
nuclear@1
|
80 fbptr[chess ? 0 : 2] = 255;
|
nuclear@1
|
81 fbptr[1] = 128;
|
nuclear@1
|
82 fbptr[chess ? 2 : 0] = 32;
|
nuclear@1
|
83 fbptr += 3;
|
nuclear@1
|
84 }
|
nuclear@1
|
85 }
|
nuclear@1
|
86
|
nuclear@1
|
87 swap_buffers();
|
nuclear@5
|
88 wait_vsync();
|
nuclear@1
|
89 }
|
nuclear@1
|
90
|
nuclear@1
|
91 #define PACK_RGB(r, g, b) \
|
nuclear@1
|
92 ((((r) << rshift) & rmask) | \
|
nuclear@1
|
93 (((g) << gshift) & gmask) | \
|
nuclear@1
|
94 (((b) << bshift) & bmask))
|
nuclear@1
|
95
|
nuclear@1
|
96 static void swap_buffers()
|
nuclear@1
|
97 {
|
nuclear@1
|
98 unsigned char *src = backbuf;
|
nuclear@1
|
99 int num_pixels = xsz * ysz;
|
nuclear@1
|
100
|
nuclear@1
|
101 switch(bpp) {
|
nuclear@1
|
102 case 32:
|
nuclear@1
|
103 {
|
nuclear@1
|
104 uint32_t *dest = (uint32_t*)fb;
|
nuclear@1
|
105 for(int i=0; i<num_pixels; i++) {
|
nuclear@1
|
106 *dest++ = PACK_RGB(src[0], src[1], src[2]);
|
nuclear@1
|
107 src += 3;
|
nuclear@1
|
108 }
|
nuclear@1
|
109 }
|
nuclear@1
|
110 break;
|
nuclear@1
|
111
|
nuclear@1
|
112 case 24:
|
nuclear@1
|
113 memcpy(fb, backbuf, num_pixels * 3);
|
nuclear@1
|
114 break;
|
nuclear@1
|
115
|
nuclear@1
|
116 case 16:
|
nuclear@1
|
117 case 15:
|
nuclear@1
|
118 {
|
nuclear@1
|
119 int srs = 8 - rbits;
|
nuclear@1
|
120 int sgs = 8 - gbits;
|
nuclear@1
|
121 int sbs = 8 - bbits;
|
nuclear@1
|
122 uint16_t *dest = (uint16_t*)fb;
|
nuclear@1
|
123 for(int i=0; i<num_pixels; i++) {
|
nuclear@1
|
124 *dest++ = PACK_RGB(src[0] >> srs, src[1] >> sgs, src[2] >> sbs);
|
nuclear@1
|
125 src += 3;
|
nuclear@1
|
126 }
|
nuclear@1
|
127 }
|
nuclear@1
|
128 break;
|
nuclear@1
|
129
|
nuclear@1
|
130 default:
|
nuclear@1
|
131 break;
|
nuclear@1
|
132 }
|
nuclear@1
|
133 }
|
nuclear@1
|
134
|
nuclear@1
|
135 static void handle_keyboard()
|
nuclear@1
|
136 {
|
nuclear@5
|
137 int key;
|
nuclear@1
|
138
|
nuclear@5
|
139 while((key = kb_getkey()) != -1) {
|
nuclear@5
|
140 switch(key) {
|
nuclear@5
|
141 case 27:
|
nuclear@5
|
142 quit = true;
|
nuclear@5
|
143 return;
|
nuclear@5
|
144 }
|
nuclear@1
|
145 }
|
nuclear@1
|
146 }
|
nuclear@1
|
147
|
nuclear@1
|
148 static void handle_mouse()
|
nuclear@1
|
149 {
|
nuclear@1
|
150 }
|
nuclear@1
|
151
|
nuclear@1
|
152 static struct {
|
nuclear@1
|
153 int opt;
|
nuclear@1
|
154 const char *lopt;
|
nuclear@1
|
155 const char *desc;
|
nuclear@1
|
156 } options[] = {
|
nuclear@1
|
157 {'s', "size", "resolution <xres>x<yres>[:bpp]"},
|
nuclear@1
|
158 {'h', "help", "print usage information and exit"},
|
nuclear@1
|
159 {-1, 0, 0}
|
nuclear@1
|
160 };
|
nuclear@1
|
161
|
nuclear@1
|
162 static void print_usage(const char *argv0)
|
nuclear@1
|
163 {
|
nuclear@1
|
164 printf("%s usage\n", argv0);
|
nuclear@1
|
165 for(int i=0; options[i].opt != -1; i++) {
|
nuclear@1
|
166 printf(" -%c, -%s: %s\n", options[i].opt, options[i].lopt, options[i].desc);
|
nuclear@1
|
167 }
|
nuclear@1
|
168 exit(0);
|
nuclear@1
|
169 }
|
nuclear@1
|
170
|
nuclear@1
|
171 static bool parse_args(int argc, char **argv)
|
nuclear@1
|
172 {
|
nuclear@1
|
173 for(int i=1; i<argc; i++) {
|
nuclear@1
|
174 if(argv[i][0] == '-') {
|
nuclear@1
|
175 int opt = -1;
|
nuclear@1
|
176
|
nuclear@1
|
177 for(int j=0; options[j].opt != -1; j++) {
|
nuclear@1
|
178 if(argv[i][2] == 0) {
|
nuclear@1
|
179 if(argv[i][1] == options[j].opt) {
|
nuclear@1
|
180 opt = options[j].opt;
|
nuclear@1
|
181 break;
|
nuclear@1
|
182 }
|
nuclear@1
|
183 } else {
|
nuclear@1
|
184 if(strcmp(argv[i] + 1, options[j].lopt) == 0) {
|
nuclear@1
|
185 opt = options[j].opt;
|
nuclear@1
|
186 break;
|
nuclear@1
|
187 }
|
nuclear@1
|
188 }
|
nuclear@1
|
189 }
|
nuclear@1
|
190
|
nuclear@1
|
191 switch(opt) {
|
nuclear@1
|
192 case 's':
|
nuclear@1
|
193 if(sscanf(argv[++i], "%dx%d:%d", &xsz, &ysz, &bpp) < 2) {
|
nuclear@1
|
194 fprintf(stderr, "%s must be followed by a resolution: WxH\n", argv[i - 1]);
|
nuclear@1
|
195 return false;
|
nuclear@1
|
196 }
|
nuclear@1
|
197 break;
|
nuclear@1
|
198
|
nuclear@1
|
199 case 'h':
|
nuclear@1
|
200 print_usage(argv[0]); // doesn't return
|
nuclear@1
|
201 break;
|
nuclear@1
|
202
|
nuclear@1
|
203 default:
|
nuclear@1
|
204 fprintf(stderr, "unknown option: %s\n", argv[i]);
|
nuclear@1
|
205 return false;
|
nuclear@1
|
206 }
|
nuclear@1
|
207 } else {
|
nuclear@1
|
208 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
|
nuclear@1
|
209 return false;
|
nuclear@1
|
210 }
|
nuclear@1
|
211 }
|
nuclear@1
|
212 return true;
|
nuclear@1
|
213 }
|