From: Peep P. <so...@us...> - 2004-08-05 13:24:24
|
Update of /cvsroot/agd/client In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24458 Added Files: gfx.c gfx.h Log Message: AGI PICTURE drawing - only absolute line and fill at the moment --- NEW FILE: gfx.c --- #include <math.h> #include <stdio.h> #include "gfx.h" #include "sys.h" PALETTE agipal = { {0x00, 0x00, 0x00}, /* black */ {0x00, 0x00, 0x2A}, /* blue */ {0x00, 0x2A, 0x00}, /* green */ {0x00, 0x2A, 0x2A}, /* cyan */ {0x2A, 0x00, 0x00}, /* red */ {0x2A, 0x00, 0x2A}, /* magenta */ {0x2A, 0x15, 0x00}, /* brown */ {0x2A, 0x2A, 0x2A}, /* light grey */ {0x15, 0x15, 0x15}, /* dark grey */ {0x15, 0x15, 0x3F}, /* light blue */ {0x15, 0x3F, 0x15}, /* light green */ {0x15, 0x3F, 0x3F}, /* light cyan */ {0x3F, 0x15, 0x15}, /* light red */ {0x3F, 0x15, 0x3F}, /* light magenta */ {0x3F, 0x3F, 0x15}, /* yellow */ {0x3F, 0x3F, 0x3F} /* white */ }; int vis_drawing, vis_col, pri_drawing, pri_col; BITMAP *buffer; extern BITMAP *bg_pic; void gfx_init(void) { allegro_init(); install_keyboard(); install_mouse(); set_palette(agipal); set_window_title("AGD client " VERSION); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 400, 0, 0); buffer = create_bitmap(SCREEN_W, SCREEN_H); clear_to_color(buffer, AGI_BLACK); } void agi_putpixel(BITMAP *bmp, int x, int y, int color) { int vx; vx = (x << 1); if(vx > 319) return; if(y > 199) return; bmp->line[y][vx] = color; bmp->line[y][vx+1] = color; } void do_pixel(int x, int y) { if(vis_drawing) agi_putpixel(bg_pic, x, y, vis_col); /* if(pri_drawing) agi_putpixel(curr_pri, x, y, pri_col);*/ } unsigned char agi_getpixel(BITMAP *bmp, int x, int y, int vis) { int vx; vx = (x<<1); if(vx > 319 || y > 199) if(vis) return AGI_WHITE; else return AGI_RED; return bmp->line[y][vx]; } int round(float aNumber, float dirn) { float num; if(dirn < 0) num = 0.501; else num = 0.499; return ((int)((aNumber - floor(aNumber) <= num) ? floor(aNumber) : ceil(aNumber))); } void agi_line(BITMAP *bmp, int x1, int y1, int x2, int y2, int color) { int height, width; float x, y, addX, addY; height = (y2 - y1); width = (x2 - x1); addX = (height==0? height:(float)width/abs(height)); addY = (width==0? width:(float)height/abs(width)); if (abs(width) > abs(height)) { y = y1; addX = (width == 0? 0 : (width/abs(width))); for (x=x1; x!=x2; x+=addX) { agi_putpixel(bmp, round(x, addX), round(y, addY), color); y+=addY; } agi_putpixel(bmp, x2,y2, color); } else { x = x1; addY = (height == 0? 0 : (height/abs(height))); for (y=y1; y!=y2; y+=addY) { agi_putpixel(bmp, round(x, addX), round(y, addY), color); x+=addX; } agi_putpixel(bmp, x2,y2, color); } } int ok_to_fill(unsigned char x, unsigned char y) { if(!vis_drawing && !pri_drawing) return 0; if(vis_col == AGI_WHITE) return 0; if(!pri_drawing) return agi_getpixel(bg_pic, x, y, 1) == AGI_WHITE; /* if(pri_drawing && !vis_drawing) return agi_getpixel(curr_pri, x, y, 0) == AGI_RED;*/ return agi_getpixel(bg_pic, x, y, 1) == AGI_WHITE; } #define QUEUE_SIZE 4000 #define EMPTY 0xFF unsigned char buf[QUEUE_SIZE+1]; int rpos = QUEUE_SIZE, spos; void qstore(unsigned char c) { if(spos+1 == rpos || (spos+1 == QUEUE_SIZE && !rpos)) return; buf[spos] = c; spos++; if(spos == QUEUE_SIZE) spos = 0; /* loop back */ } unsigned char qretrieve(void) { if(rpos == QUEUE_SIZE) rpos = 0; /* loop back */ if(rpos == spos) return EMPTY; rpos++; return buf[rpos-1]; } void agi_fill(BITMAP *bmp, int x, int y, int color) { unsigned char x1, y1; rpos = spos = 0; qstore(x); qstore(y); while(1) { x1 = qretrieve(); y1 = qretrieve(); if((x1 == EMPTY) || (y1 == EMPTY)) break; else if(ok_to_fill(x1, y1)) { agi_putpixel(bmp, x1, y1, vis_col); if(ok_to_fill(x1, y1-1) && (y1!=0)) { qstore(x1); qstore(y1-1); } if(ok_to_fill(x1-1, y1) && (x1!=0)) { qstore(x1-1); qstore(y1); } if(ok_to_fill(x1+1, y1) && (x1!=159)) { qstore(x1+1); qstore(y1); } if(ok_to_fill(x1, y1+1) && (y1!=167)) { qstore(x1); qstore(y1+1); } } } } long file_length(FILE *file) { long tmp; fseek(file, 0, SEEK_END); tmp = ftell(file); fseek(file, 0, SEEK_SET); return tmp; } void draw_ycorner(unsigned char **data) { (*data) += 2; while(*(*data)++ < 0xF0); } void draw_xcorner(unsigned char **data) { (*data) += 2; while(*(*data)++ < 0xF0); } void draw_absline(unsigned char **data) { unsigned char x1, y1, x2, y2; x1 = *((*data)++); y1 = *((*data)++); agi_putpixel(bg_pic, x1, y1, vis_col); while(1) { x2 = *((*data)++); if(x2 >= 0xF0) break; y2 = *((*data)++); if(y2 >= 0xF0) break; agi_line(bg_pic, x1, y1, x2, y2, vis_col); x1 = x2; y1 = y2; } (*data)--; } void draw_relline(unsigned char **data) { (*data) += 2; while(1) { if(*(*data) >= 0xF0) break; (*data)++; } } void fill(unsigned char **data) { unsigned char x1, y1; while(1) { x1 = *((*data)++); if(x1 >= 0xF0) break; y1 = *((*data)++); if(y1 >= 0xF0) break; agi_fill(bg_pic, x1, y1, vis_col); } (*data)--; } void draw_brush(unsigned char **data) { (*data) += 2; while(1) { if(*(*data) >= 0xF0) break; (*data)++; } } picture_t *load_picture(char *filename) { FILE *f; picture_t *ret; f = fopen(filename, "rb"); if(!f) { printf("can't open PICTURE %s for reading\n", filename); return NULL; } ret = xmalloc(sizeof(picture_t)); ret->len = file_length(f); ret->data = xmalloc(sizeof(unsigned char) * ret->len); if(fread(ret->data, 1, ret->len, f) < 0) { perror("error reading PICTURE"); free(ret->data); free(ret); return NULL; } fclose(f); return ret; } void dump(unsigned char *ptr, picture_t *pic) { unsigned char *begin, *my_ptr; int i; printf("dumping at %d/%d\n", ptr-pic->data, pic->len); begin = ptr - 5; if(begin < pic->data) begin = pic->data; my_ptr = begin; for(;my_ptr<ptr+5;my_ptr++) { printf("%x ", *my_ptr); } putchar('\n'); for(i=0;i<ptr-begin;i++) printf(" "); printf("*\n"); } void draw_picture(picture_t *pic) { unsigned char *ptr; int drawing; bg_pic = create_bitmap(320, 200); clear_to_color(bg_pic, AGI_WHITE); ptr = pic->data; drawing = 1; do { switch(*ptr++) { case 0xFF: drawing = 0; break; case 0xF0: vis_col = *ptr++; vis_drawing = 1; break; case 0xF1: vis_drawing = 0; break; case 0xF2: pri_col = *ptr++; pri_drawing = 1; break; case 0xF3: pri_drawing = 0; break; case 0xF4: draw_ycorner(&ptr); break; case 0xF5: draw_xcorner(&ptr); break; case 0xF6: draw_absline(&ptr); break; case 0xF7: draw_relline(&ptr); break; case 0xF8: fill(&ptr); break; case 0xF9: ptr++; /*pattern = *ptr++;*/ break; case 0xFA: draw_brush(&ptr); break; default: printf("Unknown picture code %x at index %d of %d\n", ptr[-1], ptr-pic->data, pic->len); dump(ptr, pic); return; break; } } while((ptr < (pic->data + pic->len)) && drawing); stretch_blit(bg_pic, screen, 0, 0, 320, 168, 0, 0, 640, 336); } --- NEW FILE: gfx.h --- #ifndef _AGI_H #define _AGI_H #include <allegro.h> #define AGI_ORIGINAL_W 160 #define AGI_ORIGINAL_H 200 extern int agipix_w, agipix_h; #define AGI_BLACK 0 #define AGI_BLUE 1 #define AGI_GREEN 2 #define AGI_CYAN 3 #define AGI_RED 4 #define AGI_MAGENTA 5 #define AGI_BROWN 6 #define AGI_LGREY 7 #define AGI_DGREY 8 #define AGI_LBLUE 9 #define AGI_LGREEN 10 #define AGI_LCYAN 11 #define AGI_LRED 12 #define AGI_LMAGENTA 13 #define AGI_YELLOW 14 #define AGI_WHITE 15 extern PALETTE agipal; void agi_putpixel(BITMAP *, int, int, int); void agi_line(BITMAP *, int, int, int, int, int); typedef struct { unsigned char *data; int len; } picture_t; #endif |