5 static int current_pal[256];
6 static SDL_Surface *jnb_surface;
7 static int fullscreen = 0;
8 static int vinited = 0;
9 static unsigned char screen_buffer[2][JNB_WIDTH*JNB_HEIGHT];
10 static int drawing_enable = 0;
11 static char *background;
12 static int background_drawn;
14 typedef unsigned char uint8;
15 typedef unsigned short uint16;
16 typedef unsigned int uint32;
18 char *get_vgaptr(int page, int x, int y)
20 assert(drawing_enable==1);
22 return &screen_buffer[page][y*JNB_WIDTH+x];
26 void open_screen(void)
30 lval = SDL_Init(SDL_INIT_EVERYTHING | SDL_INIT_AUDIO);
32 fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError());
38 jnb_surface = SDL_SetVideoMode(JNB_WIDTH*2, JNB_HEIGHT*2, 16, SDL_SWSURFACE | SDL_FULLSCREEN);
40 jnb_surface = SDL_SetVideoMode(JNB_WIDTH*2, JNB_HEIGHT*2, 16, SDL_SWSURFACE);
43 jnb_surface = SDL_SetVideoMode(JNB_WIDTH, JNB_HEIGHT, JNB_BPP, SDL_SWSURFACE | SDL_FULLSCREEN);
45 jnb_surface = SDL_SetVideoMode(JNB_WIDTH, JNB_HEIGHT, JNB_BPP, SDL_SWSURFACE);
48 fprintf(stderr, "SDL ERROR: %s\n", SDL_GetError());
56 memset(current_pal, 0, sizeof(current_pal));
68 if (SDL_WM_ToggleFullScreen(jnb_surface))
73 void wait_vrt(int mix)
79 void clear_page(int page, int color)
81 assert(drawing_enable==1);
83 memset((void *) get_vgaptr(page, 0, 0), color, JNB_WIDTH * JNB_HEIGHT);
87 void clear_lines(int page, int y, int count, int color)
91 assert(drawing_enable==1);
93 for (i=0; i<count; i++)
95 memset((void *) get_vgaptr(page, 0, i+y), color, JNB_WIDTH);
99 int get_pixel(int page, int x, int y)
101 assert(drawing_enable==1);
103 return *(char *) get_vgaptr(page, x, y);
107 void set_pixel(int page, int x, int y, int color)
109 assert(drawing_enable==1);
111 *(char *) get_vgaptr(page, x, y) = color;
115 static uint32 colorMask = 0xF7DEF7DE;
116 static uint32 lowPixelMask = 0x08210821;
117 static uint32 qcolorMask = 0xE79CE79C;
118 static uint32 qlowpixelMask = 0x18631863;
119 static uint32 redblueMask = 0xF81F;
120 static uint32 greenMask = 0x7E0;
122 int Init_2xSaI (uint32 BitFormat)
124 if (BitFormat == 565)
126 colorMask = 0xF7DEF7DE;
127 lowPixelMask = 0x08210821;
128 qcolorMask = 0xE79CE79C;
129 qlowpixelMask = 0x18631863;
130 redblueMask = 0xF81F;
133 else if (BitFormat == 555)
135 colorMask = 0x7BDE7BDE;
136 lowPixelMask = 0x04210421;
137 qcolorMask = 0x739C739C;
138 qlowpixelMask = 0x0C630C63;
139 redblueMask = 0x7C1F;
148 Init_2xSaIMMX (BitFormat);
155 #define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
157 #define INTERPOLATE(A, B) (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask))
159 #define Q_INTERPOLATE(A, B, C, D) ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2) \
160 + ((((A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask)) >> 2) & qlowpixelMask)
162 #define GET_COLOR(x) (current_pal[(x)])
165 void Super2xSaI2 (uint8 *src, uint32 src_pitch, int src_bytes_per_pixel,
166 uint8 *dst, uint32 dst_pitch, int dst_bytes_per_pixel,
167 int width, int height)
169 unsigned char *src_line[4];
170 unsigned char *dst_line[2];
172 unsigned long color[16];
174 /* Point to the first 3 lines. */
177 src_line[2] = src + src_pitch;
178 src_line[3] = src + (src_pitch * 2);
181 dst_line[1] = dst + dst_pitch;
185 if (src_bytes_per_pixel == 1) {
188 color[0] = GET_COLOR(*sbp); color[1] = color[0]; color[2] = color[0]; color[3] = color[0];
189 color[4] = color[0]; color[5] = color[0]; color[6] = GET_COLOR(*(sbp + 1)); color[7] = GET_COLOR(*(sbp + 2));
191 color[8] = GET_COLOR(*sbp); color[9] = color[8]; color[10] = GET_COLOR(*(sbp + 1)); color[11] = GET_COLOR(*(sbp + 2));
193 color[12] = GET_COLOR(*sbp); color[13] = color[12]; color[14] = GET_COLOR(*(sbp + 1)); color[15] = GET_COLOR(*(sbp + 2));
194 } else if (src_bytes_per_pixel == 2) {
196 sbp = (unsigned short*)src_line[0];
197 color[0] = *sbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0];
198 color[4] = color[0]; color[5] = color[0]; color[6] = *(sbp + 1); color[7] = *(sbp + 2);
199 sbp = (unsigned short*)src_line[2];
200 color[8] = *sbp; color[9] = color[8]; color[10] = *(sbp + 1); color[11] = *(sbp + 2);
201 sbp = (unsigned short*)src_line[3];
202 color[12] = *sbp; color[13] = color[12]; color[14] = *(sbp + 1); color[15] = *(sbp + 2);
205 lbp = (unsigned long*)src_line[0];
206 color[0] = *lbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0];
207 color[4] = color[0]; color[5] = color[0]; color[6] = *(lbp + 1); color[7] = *(lbp + 2);
208 lbp = (unsigned long*)src_line[2];
209 color[8] = *lbp; color[9] = color[8]; color[10] = *(lbp + 1); color[11] = *(lbp + 2);
210 lbp = (unsigned long*)src_line[3];
211 color[12] = *lbp; color[13] = color[12]; color[14] = *(lbp + 1); color[15] = *(lbp + 2);
214 for (y = 0; y < height; y++) {
216 /* Todo: x = width - 2, x = width - 1 */
218 for (x = 0; x < width; x++) {
219 unsigned long product1a, product1b, product2a, product2b;
221 //--------------------------------------- B0 B1 B2 B3 0 1 2 3
222 // 4 5* 6 S2 -> 4 5* 6 7
223 // 1 2 3 S1 8 9 10 11
224 // A0 A1 A2 A3 12 13 14 15
225 //--------------------------------------
226 if (color[9] == color[6] && color[5] != color[10]) {
227 product2b = color[9];
228 product1b = product2b;
230 else if (color[5] == color[10] && color[9] != color[6]) {
231 product2b = color[5];
232 product1b = product2b;
234 else if (color[5] == color[10] && color[9] == color[6]) {
237 r += GET_RESULT(color[6], color[5], color[8], color[13]);
238 r += GET_RESULT(color[6], color[5], color[4], color[1]);
239 r += GET_RESULT(color[6], color[5], color[14], color[11]);
240 r += GET_RESULT(color[6], color[5], color[2], color[7]);
243 product1b = color[6];
245 product1b = color[5];
247 product1b = INTERPOLATE(color[5], color[6]);
249 product2b = product1b;
253 if (color[6] == color[10] && color[10] == color[13] && color[9] != color[14] && color[10] != color[12])
254 product2b = Q_INTERPOLATE(color[10], color[10], color[10], color[9]);
255 else if (color[5] == color[9] && color[9] == color[14] && color[13] != color[10] && color[9] != color[15])
256 product2b = Q_INTERPOLATE(color[9], color[9], color[9], color[10]);
258 product2b = INTERPOLATE(color[9], color[10]);
260 if (color[6] == color[10] && color[6] == color[1] && color[5] != color[2] && color[6] != color[0])
261 product1b = Q_INTERPOLATE(color[6], color[6], color[6], color[5]);
262 else if (color[5] == color[9] && color[5] == color[2] && color[1] != color[6] && color[5] != color[3])
263 product1b = Q_INTERPOLATE(color[6], color[5], color[5], color[5]);
265 product1b = INTERPOLATE(color[5], color[6]);
268 if (color[5] == color[10] && color[9] != color[6] && color[4] == color[5] && color[5] != color[14])
269 product2a = INTERPOLATE(color[9], color[5]);
270 else if (color[5] == color[8] && color[6] == color[5] && color[4] != color[9] && color[5] != color[12])
271 product2a = INTERPOLATE(color[9], color[5]);
273 product2a = color[9];
275 if (color[9] == color[6] && color[5] != color[10] && color[8] == color[9] && color[9] != color[2])
276 product1a = INTERPOLATE(color[9], color[5]);
277 else if (color[4] == color[9] && color[10] == color[9] && color[8] != color[5] && color[9] != color[0])
278 product1a = INTERPOLATE(color[9], color[5]);
280 product1a = color[5];
282 if (dst_bytes_per_pixel == 2) {
283 *((unsigned long *) (&dst_line[0][x * 4])) = product1a | (product1b << 16);
284 *((unsigned long *) (&dst_line[1][x * 4])) = product2a | (product2b << 16);
286 *((unsigned long *) (&dst_line[0][x * 8])) = product1a;
287 *((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b;
288 *((unsigned long *) (&dst_line[1][x * 8])) = product2a;
289 *((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b;
292 /* Move color matrix forward */
293 color[0] = color[1]; color[4] = color[5]; color[8] = color[9]; color[12] = color[13];
294 color[1] = color[2]; color[5] = color[6]; color[9] = color[10]; color[13] = color[14];
295 color[2] = color[3]; color[6] = color[7]; color[10] = color[11]; color[14] = color[15];
299 if (src_bytes_per_pixel == 1) {
300 color[3] = GET_COLOR(*(((unsigned char*)src_line[0]) + x));
301 color[7] = GET_COLOR(*(((unsigned char*)src_line[1]) + x));
302 color[11] = GET_COLOR(*(((unsigned char*)src_line[2]) + x));
303 color[15] = GET_COLOR(*(((unsigned char*)src_line[3]) + x));
304 } else if (src_bytes_per_pixel == 2) {
305 color[3] = *(((unsigned short*)src_line[0]) + x);
306 color[7] = *(((unsigned short*)src_line[1]) + x);
307 color[11] = *(((unsigned short*)src_line[2]) + x);
308 color[15] = *(((unsigned short*)src_line[3]) + x);
310 color[3] = *(((unsigned long*)src_line[0]) + x);
311 color[7] = *(((unsigned long*)src_line[1]) + x);
312 color[11] = *(((unsigned long*)src_line[2]) + x);
313 color[15] = *(((unsigned long*)src_line[3]) + x);
319 /* We're done with one line, so we shift the source lines up */
320 src_line[0] = src_line[1];
321 src_line[1] = src_line[2];
322 src_line[2] = src_line[3];
326 src_line[3] = src_line[2];
328 src_line[3] = src_line[2] + src_pitch;
330 /* Then shift the color matrix up */
331 if (src_bytes_per_pixel == 1) {
334 color[0] = GET_COLOR(*sbp); color[1] = color[0]; color[2] = GET_COLOR(*(sbp + 1)); color[3] = GET_COLOR(*(sbp + 2));
336 color[4] = GET_COLOR(*sbp); color[5] = color[4]; color[6] = GET_COLOR(*(sbp + 1)); color[7] = GET_COLOR(*(sbp + 2));
338 color[8] = GET_COLOR(*sbp); color[9] = color[8]; color[10] = GET_COLOR(*(sbp + 1)); color[11] = GET_COLOR(*(sbp + 2));
340 color[12] = GET_COLOR(*sbp); color[13] = color[12]; color[14] = GET_COLOR(*(sbp + 1)); color[15] = GET_COLOR(*(sbp + 2));
341 } else if (src_bytes_per_pixel == 2) {
343 sbp = (unsigned short*)src_line[0];
344 color[0] = *sbp; color[1] = color[0]; color[2] = *(sbp + 1); color[3] = *(sbp + 2);
345 sbp = (unsigned short*)src_line[1];
346 color[4] = *sbp; color[5] = color[4]; color[6] = *(sbp + 1); color[7] = *(sbp + 2);
347 sbp = (unsigned short*)src_line[2];
348 color[8] = *sbp; color[9] = color[9]; color[10] = *(sbp + 1); color[11] = *(sbp + 2);
349 sbp = (unsigned short*)src_line[3];
350 color[12] = *sbp; color[13] = color[12]; color[14] = *(sbp + 1); color[15] = *(sbp + 2);
353 lbp = (unsigned long*)src_line[0];
354 color[0] = *lbp; color[1] = color[0]; color[2] = *(lbp + 1); color[3] = *(lbp + 2);
355 lbp = (unsigned long*)src_line[1];
356 color[4] = *lbp; color[5] = color[4]; color[6] = *(lbp + 1); color[7] = *(lbp + 2);
357 lbp = (unsigned long*)src_line[2];
358 color[8] = *lbp; color[9] = color[9]; color[10] = *(lbp + 1); color[11] = *(lbp + 2);
359 lbp = (unsigned long*)src_line[3];
360 color[12] = *lbp; color[13] = color[12]; color[14] = *(lbp + 1); color[15] = *(lbp + 2);
363 if (y < height - 1) {
364 dst_line[0] += dst_pitch * 2;
365 dst_line[1] += dst_pitch * 2;
371 void flippage(int page)
378 assert(drawing_enable==0);
380 SDL_LockSurface(jnb_surface);
381 dest=(char *)jnb_surface->pixels;
382 src=screen_buffer[page];
384 Super2xSaI2(src, JNB_WIDTH, 1, dest, jnb_surface->pitch, 2, JNB_WIDTH, JNB_HEIGHT);
386 w=(jnb_surface->clip_rect.w>JNB_WIDTH)?(JNB_WIDTH):(jnb_surface->clip_rect.w);
387 h=(jnb_surface->clip_rect.h>JNB_HEIGHT)?(JNB_HEIGHT):(jnb_surface->clip_rect.h);
390 dest+=jnb_surface->pitch;
394 SDL_UnlockSurface(jnb_surface);
395 SDL_Flip(jnb_surface);
399 void draw_begin(void)
401 assert(drawing_enable==0);
404 if (background_drawn == 0) {
406 put_block(0, 0, 0, JNB_WIDTH, JNB_HEIGHT, background);
407 put_block(1, 0, 0, JNB_WIDTH, JNB_HEIGHT, background);
412 background_drawn = 1;
419 assert(drawing_enable==1);
425 void setpalette(int index, int count, char *palette)
427 SDL_Color colors[256];
430 assert(drawing_enable==0);
432 for (i = 0; i < count; i++) {
433 colors[i+index].r = palette[i * 3 + 0] << 2;
434 colors[i+index].g = palette[i * 3 + 1] << 2;
435 colors[i+index].b = palette[i * 3 + 2] << 2;
436 current_pal[i+index] = SDL_MapRGB(jnb_surface->format, colors[i+index].r, colors[i+index].g, colors[i+index].b);
439 SDL_SetColors(jnb_surface, &colors[index], index, count);
444 void fillpalette(int red, int green, int blue)
446 SDL_Color colors[256];
449 assert(drawing_enable==0);
451 for (i = 0; i < 256; i++) {
452 colors[i].r = red << 2;
453 colors[i].g = green << 2;
454 colors[i].b = blue << 2;
455 current_pal[i] = SDL_MapRGB(jnb_surface->format, colors[i].r, colors[i].g, colors[i].b);
458 SDL_SetColors(jnb_surface, colors, 0, 256);
463 void get_block(int page, int x, int y, int width, int height, char *buffer)
466 char *buffer_ptr, *vga_ptr;
468 assert(drawing_enable==1);
474 if (y + height >= JNB_HEIGHT)
475 height = JNB_HEIGHT - y;
476 if (x + width >= JNB_WIDTH)
477 width = JNB_WIDTH - x;
479 for (h = 0; h < height; h++) {
480 buffer_ptr = &buffer[h * width];
482 vga_ptr = get_vgaptr(page, x, h + y);
484 for (w = 0; w < width; w++) {
496 void put_block(int page, int x, int y, int width, int height, char *buffer)
499 char *vga_ptr, *buffer_ptr;
501 assert(drawing_enable==1);
507 if (y + height >= JNB_HEIGHT)
508 height = JNB_HEIGHT - y;
509 if (x + width >= JNB_WIDTH)
510 width = JNB_WIDTH - x;
512 for (h = 0; h < height; h++) {
513 vga_ptr = get_vgaptr(page, x, y + h);
515 buffer_ptr = &buffer[h * width];
516 for (w = 0; w < width; w++) {
517 *vga_ptr = *buffer_ptr;
525 void put_text(int page, int x, int y, char *text, int align)
533 assert(drawing_enable==1);
535 if (text == NULL || strlen(text) == 0)
537 if (font_gobs == NULL)
542 while (text[c1] != 0) {
549 if (t1 >= 33 && t1 <= 34)
552 else if (t1 >= 39 && t1 <= 41)
555 else if (t1 >= 44 && t1 <= 59)
558 else if (t1 >= 64 && t1 <= 90)
561 else if (t1 >= 97 && t1 <= 122)
587 width += pob_width(image, font_gobs) + 1;
598 cur_x = x - width / 2;
601 cur_x = 0; /* this should cause error? -Chuck */
606 while (text[c1] != 0) {
613 if (t1 >= 33 && t1 <= 34)
616 else if (t1 >= 39 && t1 <= 41)
619 else if (t1 >= 44 && t1 <= 59)
622 else if (t1 >= 64 && t1 <= 90)
625 else if (t1 >= 97 && t1 <= 122)
651 put_pob(page, cur_x, y, image, font_gobs, 1, mask_pic);
652 cur_x += pob_width(image, font_gobs) + 1;
657 void put_pob(int page, int x, int y, int image, char *pob_data, int mask, char *mask_pic)
661 char *pob_ptr, *vga_ptr, *mask_ptr;
663 long draw_width, draw_height;
666 assert(drawing_enable==1);
668 if (image < 0 || image >= *(short *) (pob_data))
671 vga_ptr = get_vgaptr(page, 0, 0);
672 pob_offset = *(unsigned long *) (pob_data + (image * 4) + 2);
673 width = draw_width = *(short *) (pob_data + pob_offset);
674 height = draw_height = *(short *) (pob_data + pob_offset + 2);
675 x -= *(short *) (pob_data + pob_offset + 4);
676 y -= *(short *) (pob_data + pob_offset + 6);
678 if ((x + width) <= 0 || x >= 400)
680 if ((y + height) <= 0 || y >= 256)
687 if ((x + width) > 400)
688 draw_width -= x + width - 400;
690 pob_offset += -y * width;
694 if ((y + height) > 256)
695 draw_height -= y + height - 256;
697 pob_ptr = &pob_data[pob_offset];
700 vga_ptr = get_vgaptr(page, x, y);
701 mask_ptr = (char *) (mask_pic + (y * 400) + x);
702 for (c1 = 0; c1 < draw_height; c1++) {
703 for (c2 = 0; c2 < draw_width; c2++) {
705 if (mask == 0 || (mask == 1 && colour == 0)) {
714 pob_ptr += width - c2;
715 vga_ptr += (400 - c2);
716 mask_ptr += (400 - c2);
721 int pob_col(int x1, int y1, int image1, char *pob_data1, int x2, int y2, int image2, char *pob_data2)
724 long pob_offset1, pob_offset2;
725 short width1, width2;
726 short height1, height2;
727 short check_width, check_height;
728 char *pob_ptr1, *pob_ptr2;
730 pob_offset1 = *(long *) (pob_data1 + image1 * 4 + 2);
731 width1 = *(short *) (pob_data1 + pob_offset1);
732 height1 = *(short *) (pob_data1 + pob_offset1 + 2);
733 x1 -= *(short *) (pob_data1 + pob_offset1 + 4);
734 y1 -= *(short *) (pob_data1 + pob_offset1 + 6);
736 pob_offset2 = *(long *) (pob_data2 + image2 * 4 + 2);
737 width2 = *(short *) (pob_data2 + pob_offset2);
738 height2 = *(short *) (pob_data2 + pob_offset2 + 2);
739 x2 -= *(short *) (pob_data2 + pob_offset2 + 4);
740 y2 -= *(short *) (pob_data2 + pob_offset2 + 6);
744 if ((x1 + width1) <= x2)
747 else if ((x1 + width1) <= (x2 + width2)) {
748 pob_offset1 += x2 - x1;
749 check_width = x1 + width1 - x2;
753 pob_offset1 += x2 - x1;
754 check_width = width2;
759 if ((x2 + width2) <= x1)
762 else if ((x2 + width2) <= (x1 + width1)) {
763 pob_offset2 += x1 - x2;
764 check_width = x2 + width2 - x1;
768 pob_offset2 += x1 - x2;
769 check_width = width1;
773 if ((y1 + height1) <= y2)
776 else if ((y1 + height1) <= (y2 + height2)) {
777 pob_offset1 += (y2 - y1) * width1;
778 check_height = y1 + height1 - y2;
782 pob_offset1 += (y2 - y1) * width1;
783 check_height = height2;
788 if ((y2 + height2) <= y1)
791 else if ((y2 + height2) <= (y1 + height1)) {
792 pob_offset2 += (y1 - y2) * width2;
793 check_height = y2 + height2 - y1;
797 pob_offset2 += (y1 - y2) * width2;
798 check_height = height1;
801 pob_ptr1 = (char *) (pob_data1 + pob_offset1);
802 pob_ptr2 = (char *) (pob_data2 + pob_offset2);
803 for (c1 = 0; c1 < check_height; c1++) {
804 for (c2 = 0; c2 < check_width; c2++) {
805 if (*pob_ptr1 != 0 && *pob_ptr2 != 0)
810 pob_ptr1 += width1 - check_width;
811 pob_ptr2 += width2 - check_width;
817 int pob_width(int image, char *pob_data)
819 return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2));
823 int pob_height(int image, char *pob_data)
825 return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 2);
829 int pob_hs_x(int image, char *pob_data)
831 return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 4);
835 int pob_hs_y(int image, char *pob_data)
837 return *(short *) (pob_data + *(long *) (pob_data + image * 4 + 2) + 6);
841 int read_pcx(FILE * handle, char *buffer, int buf_len, char *pal)
847 fseek(handle, 128, SEEK_CUR);
849 while (ofs1 < buf_len) {
851 if ((a & 0xc0) == 0xc0) {
854 for (c1 = 0; c1 < a && ofs1 < buf_len; c1++)
855 buffer[ofs1++] = (char) b;
857 buffer[ofs1++] = (char) a;
860 fseek(handle, 1, SEEK_CUR);
861 for (c1 = 0; c1 < 768; c1++)
862 pal[c1] = fgetc(handle) >> 2;
869 void register_background(char *pixels)
872 background_drawn = 0;