Revision 1
- Date:
- 2009/05/25 21:33:58
- Files:
Legend:
- Added
- Removed
- Modified
-
inc/ma2d.h
1 /* ma2d.h - main header for ma2d.lib */ 2 3 #ifndef _include_ma2d_h 4 #define _include_ma2d_h 5 + 6 #include <allegro.h> 7 8 #ifdef __cplusplus 9 extern "C" { 10 #endif 11 12 13 14 //paraphrase from points.h 15 16 /* MAGE_V2D structures */ 17 18 /* MA2D_VERTEX: 19 * A 2d vertex. every one has its own flags for ease of use in editors. 20 */ 21 22 typedef struct MA2D_VERTEX { 23 int x; // x in pixels 24 int y; // y in pixels 25 int flags; //for editors 26 } MA2D_VERTEX; 27 28 29 #define MA2D_VERTEX_F_USED 0x01 //this bit is set if the structure is valid 30 #define MA2D_VERTEX_F_HANDLE 0x02 //set if the point is a handle for snapping 31 #define MA2D_VERTEX_F_VIS 0x04 //set if the point is visible 32 #define MA2D_VERTEX_F_CTL 0x08 //set if the point is a control point 33 #define MA2D_VERTEX_F_SELECTED 0x80 //this bit is set if the point is selected 34 35 36 /* MA2D_VBUFFER: 37 * An array of MA2D_VERTEX, with length and mem-mgmt flags 38 */ 39 40 typedef struct MA2D_VBUFFER { 41 int flags; 42 int size; //number of points 43 MA2D_VERTEX * verts; //list of points 44 } MA2D_VBUFFER; 45 46 47 #define MA2D_VBUFFER_SELF_ALLOC 0x01 //set if self was created, 0 if staticly defed in program 48 #define MA2D_VBUFFER_VERTS_ALLOC 0x02 //set if points array was created 49 50 51 52 53 54 /* MA2D_LINESEG: 55 * + * line structure 56 * 57 * e1,e2,c1 & c2 are indices to an array of points. The V2D_HEADER and LINE_HEADER 58 * are both usually contained in the same SHAPE or A2D_FRAME structure 59 * 60 */ 61 62 typedef struct MA2D_LINESEG { 63 int e1; // end point 1 64 int c1; // control point 1 65 int c2; // control point 2 66 int e2; // end point 2 67 int flags; 68 } MA2D_LINESEG; 69 70 //most of these were intended for an old editor, and are not currently meaningful 71 72 #define MA2D_LINESEG_F_USED 0x01 //this bit is set if the structure is valid 73 #define MA2D_LINESEG_F_VIS 0x04 //set if the line is visible 74 #define MA2D_LINESEG_F_GUIDE 0x08 //set if the line is a guideline 75 #define MA2D_LINESEG_F_ARC 0x10 //set if the line is an arc (cp1=centre) 76 #define MA2D_LINESEG_F_BEZIER 0x20 //set if the line is a spline (cp1,cp2) 77 #define MA2D_LINESEG_F_SELECTED 0x80 //this bit is set if the line is selected 78 79 #define MA2D_LINESEG_F_P_ARC 0x100 //set if the line can be bent into an arc 80 #define MA2D_LINESEG_F_P_BEZIER 0x200 //set if the line can be bent into a spline 81 82 83 /* MA2D_LBUFFER: 84 * A managed array of MA2D_LINESEG 85 */ 86 typedef struct MA2D_LBUFFER { 87 int flags; 88 int n_segs; //number of lines 89 MA2D_LINESEG * segs; //array of lines 90 } MA2D_LBUFFER; 91 92 #define MA2D_LBUFFER_F_SELF_ALLOC 0x01 //set if lbuffer struct was created 93 #define MA2D_LBUFFER_F_LINES_ALLOC 0x02 //set if *lines was created 94 95 96 /* MA2D_PATH: 97 * a series of line segments between nodes 98 * 99 */ 100 101 typedef struct MA2D_PATH { 102 int e1; // end point 1 103 int e2; // end point 2 104 int n_segs; // number of indices in array 105 int *segs; // array of indices 106 int flags; //used by the editor 107 } MA2D_PATH; 108 109 110 111 // from shape2d.h 112 113 114 typedef struct MA2D_SHAPE { 115 int flags; 116 MA2D_VBUFFER * vbuf; 117 MA2D_LBUFFER * lbuf; 118 // MA2D_POLYLIST * polyl; //header for list of triangles/quads 119 int n_paths; 120 MA2D_PATH * paths; 121 122 } MA2D_SHAPE; 123 124 125 126 127 #define MAGESHAPE_F_USED 0x01 128 #define MAGESHAPE_F_MALLOC 0x02 // set if malloced. if not then this shape 129 // cannot be destroyed. 130 131 #define MAGESHAPE_F_OWNV2D 0x10 // set if this shape owns the point list 132 // if set, then destroying the shape will 133 // attempt to destroy the point list 134 135 136 137 138 // from scanline render.h 139 140 141 /* MA2D_SCANTRANSITION: 142 * This struct is used to store scanlines of rendered shapes. 143 * These are kept in sorted lists. 144 */ 145 146 typedef struct MA2D_SCANTRANSITION { 147 148 int t; /* type */ 149 float x; /* x position (in subpixels) of transition */ 150 int r; /* index to region */ 151 152 } MA2D_SCANTRANSITION; 153 154 enum MA2D_TRANSIT_T { MA2D_TRANSIT_T_END=-1, MA2D_TRANSIT_T_EMPTY=0, 155 MA2D_TRANSIT_T_SOLID }; 156 157 158 /* MA2D_SCANLINE: 159 * This struct is used to store scanlines of rendered shapes. 160 * These are kept in sorted lists. 161 */ 162 163 typedef struct MA2D_SCANLINE { 164 int n_transits; 165 MA2D_SCANTRANSITION * transits; 166 } MA2D_SCANLINE; 167 168 169 170 171 /* MA2D_REGION: 172 * Used to store information about a slice of a scanline 173 */ 174 typedef struct MA2D_REGION { 175 176 int t; /* type */ 177 int alpha, red, green, blue; /* for solid colours */ 178 179 180 } MA2D_REGION; 181 182 183 184 #ifdef __cplusplus 185 } 186 #endif 187 188 #endif -
Makefile
1 # Make file for the ma2d library 2 3 CC:= gcc 4 CFLAGS:= -Wall -O2 5 6 ifdef DJDIR 7 LDLIBS := -lalleg 8 EXE := .exe 9 else 10 ifdef MINGW 11 LDLIBS := -lalleg 12 EXE := .exe 13 else 14 # Assume Unix. 15 LDLIBS := `allegro-config --libs` 16 endif 17 endif 18 19 EXENAME:= test1$(EXE) 20 21 OBJS:= test1.o 22 #shape2d.o scanrend.o 23 24 default : $(EXENAME) 25 26 $(EXENAME) : $(OBJS) 27 gcc -o $(EXENAME) $(OBJS) $(CFLAGS) $(LDLIBS) 28 29 test1.o : src/test1.c 30 gcc -c src/test1.c 31 32 shape2d.o : shape2d.c 33 gcc -c shape2d.c 34 35 scanrend.o : scanrend.c 36 gcc -c scanrend.c 37 38 clean : 39 rm -f $(TEST1) $(OBJS) 40 41 42 43 44 -
src/test1.c
1 /* test1.c */ 2 3 #include <stdio.h> 4 #include <allegro.h> 5 #include "../inc/ma2d.h" 6 7 8 PALETTE pal; 9 10 11 12 13 void 14 draw_rough (BITMAP * bmp, MA2D_SHAPE * shape, 15 float pos_x, float pos_y, 16 float scale_x, float scale_y, 17 float rot) { 18 19 MA2D_VBUFFER * vbuf; MA2D_VERTEX * verts; 20 MA2D_LBUFFER * lbuf; MA2D_LINESEG * segs; 21 int points[8]; 22 int s; 23 24 vbuf = shape->vbuf; 25 lbuf = shape->lbuf; 26 27 verts = vbuf->verts; 28 segs = lbuf->segs; 29 30 for (s=0; s < lbuf->n_segs; s++) { 31 if ((segs[s].c1 == -1) || (segs[s].c2 == -1)) { //cubics ignored for now 32 33 line( bmp, 34 verts[segs[s].e1].x * scale_x + pos_x, 35 verts[segs[s].e1].y * scale_y + pos_y, 36 verts[segs[s].e2].x * scale_x + pos_x, 37 verts[segs[s].e2].y * scale_y + pos_y, 38 makecol(255, 128, 128) 39 ); 40 41 } else { 42 points[0] = verts[segs[s].e1].x * scale_x + pos_x; 43 points[1] = verts[segs[s].e1].y * scale_y + pos_y; 44 points[2] = verts[segs[s].c1].x * scale_x + pos_x; 45 points[3] = verts[segs[s].c1].y * scale_y + pos_y; 46 points[4] = verts[segs[s].c2].x * scale_x + pos_x; 47 points[5] = verts[segs[s].c2].y * scale_y + pos_y; 48 points[6] = verts[segs[s].e2].x * scale_x + pos_x; 49 points[7] = verts[segs[s].e2].y * scale_y + pos_y; 50 51 spline( bmp, 52 points, 53 makecol(255, 128, 128) 54 ); 55 } 56 } 57 58 } 59 60 /* scanlines: 61 * global array of MA2D_SCANLINE for testing 62 */ 63 MA2D_SCANLINE scanlines[480]; 64 65 void init_scanlines() { 66 int a; 67 for (a=0; a<480; a++) { 68 scanlines[a].n_transits = 0; 69 scanlines[a].transits = NULL; 70 } 71 } 72 73 void free_all_transits() { 74 int a; 75 for (a=0; a<480; a++) { 76 if (scanlines[a].n_transits >0) free(scanlines[a].transits); 77 } 78 } 79 80 void render_all_scanlines() { 81 int a; 82 for (a=0; a<480; a++) { 83 int n; 84 MA2D_SCANTRANSITION * transits = scanlines[a].transits; 85 n = scanlines[a].n_transits; 86 87 if (n>0) { 88 int i = 0, x=0, r=0; 89 while (i < n) { 90 if (x < transits[i].x) 91 { 92 if (r) putpixel(screen, x, a, makecol(128, 64, 0)); 93 x++; 94 } else { 95 r = transits[i].r; 96 i++; 97 } 98 } 99 100 } 101 102 } 103 104 } 105 106 107 108 void 109 add_transition( MA2D_SCANLINE * scanline, int x, int r ) { 110 111 MA2D_SCANTRANSITION * transits; 112 int n, a, i; 113 114 i = n = scanline->n_transits; 115 116 printf("i=%d ,n=%d\n", i, n); 117 118 if (n==0) { 119 transits = malloc(sizeof (MA2D_SCANTRANSITION)); 120 i=0; 121 } else { 122 transits = realloc(scanline->transits, (n+1) *sizeof (MA2D_SCANTRANSITION)); 123 124 a = 0; i = n; 125 126 while (a<n) { 127 if (transits[a].x > x) { 128 printf("a=%d ,n=%d\n", a, n); 129 memmove(&transits[a+1], &transits[a], sizeof(MA2D_SCANTRANSITION) * (n-a)); 130 i = a; a = n; 131 132 } 133 a++; 134 } 135 136 137 } 138 139 transits[i].t = MA2D_TRANSIT_T_SOLID; 140 transits[i].x = x; 141 transits[i].r = r; 142 143 scanline->transits = transits; 144 scanline->n_transits = ++n; 145 146 } 147 148 149 void 150 change_transition_i(BITMAP * bmp, int x,int y, int d){ 151 if (d==0) { 152 putpixel(bmp, x, y, makecol(255,0,0)); 153 } else if (d<0) { 154 add_transition(&scanlines[y], x, 1); 155 } else { 156 add_transition(&scanlines[y], x, 0); 157 } 158 } 159 160 void 161 draw_rough_fill (BITMAP * bmp, MA2D_SHAPE * shape, 162 float pos_x, float pos_y, 163 float scale_x, float scale_y, 164 float rot) { 165 166 MA2D_VBUFFER * vbuf; MA2D_VERTEX * verts; 167 MA2D_LBUFFER * lbuf; MA2D_LINESEG * segs; 168 int points[8]; 169 int s; 170 171 vbuf = shape->vbuf; 172 lbuf = shape->lbuf; 173 174 verts = vbuf->verts; 175 segs = lbuf->segs; 176 177 for (s=0; s < lbuf->n_segs; s++) { 178 if ((segs[s].c1 == -1) || (segs[s].c2 == -1)) { //cubics ignored for now 179 180 do_line( bmp, 181 verts[segs[s].e1].x * scale_x + pos_x, 182 verts[segs[s].e1].y * scale_y + pos_y, 183 verts[segs[s].e2].x * scale_x + pos_x, 184 verts[segs[s].e2].y * scale_y + pos_y, 185 verts[segs[s].e2].y - verts[segs[s].e1].y , 186 &change_transition_i 187 ); 188 189 } else { 190 int a,sx[20],sy[20]; 191 192 points[0] = verts[segs[s].e1].x * scale_x + pos_x; 193 points[1] = verts[segs[s].e1].y * scale_y + pos_y; 194 points[2] = verts[segs[s].c1].x * scale_x + pos_x; 195 points[3] = verts[segs[s].c1].y * scale_y + pos_y; 196 points[4] = verts[segs[s].c2].x * scale_x + pos_x; 197 points[5] = verts[segs[s].c2].y * scale_y + pos_y; 198 points[6] = verts[segs[s].e2].x * scale_x + pos_x; 199 points[7] = verts[segs[s].e2].y * scale_y + pos_y; 200 201 calc_spline( points, 20, sx,sy); 202 for (a=0; a<19; a++) { 203 do_line( bmp, sx[a], sy[a], sx[a+1], sy[a+1], 204 sy[a+1] - sy[a], 205 &change_transition_i 206 ); 207 } 208 } 209 } 210 211 } 212 213 214 215 int main() 216 { 217 int my_depth=16; 218 int button=13; //index in the_dlg 219 220 #define VV MA2D_VERTEX_F_USED | MA2D_VERTEX_F_VIS 221 #define VVC MA2D_VERTEX_F_USED | MA2D_VERTEX_F_VIS | MA2D_VERTEX_F_CTL 222 223 MA2D_VERTEX test1_verts[17] = { 224 /* x, y, flags */ 225 { 0.0, 0.0, VV }, 226 { 6.0, 0.0, VV }, 227 {10.0, 0.0, VVC}, 228 {11.0, 6.0, VVC}, 229 { 6.0, 7.0, VV }, 230 { 9.0,11.0, VV }, 231 { 7.0,11.0, VV }, 232 { 4.0, 7.0, VV }, 233 { 2.0, 7.0, VV }, 234 { 2.0,11.0, VV }, 235 { 0.0,11.0, VV }, 236 { 2.0, 2.0, VV }, 237 { 5.0, 2.0, VV }, 238 { 8.0, 2.0, VVC}, 239 { 8.0, 5.0, VVC}, 240 { 5.0, 5.0, VV }, 241 { 2.0, 5.0, VV } 242 243 }; 244 245 MA2D_VBUFFER test1_vbuf = { 0, 17, test1_verts }; 246 247 248 MA2D_LINESEG test1_linesegs[13] = { 249 250 { 0, -1, -1, 1}, 251 { 1, 2, 3, 4}, 252 { 4, -1, -1, 5}, 253 { 5, -1, -1, 6}, 254 { 6, -1, -1, 7}, 255 { 7, -1, -1, 8}, 256 { 8, -1, -1, 9}, 257 { 9, -1, -1, 10}, 258 {10, -1, -1, 0}, 259 260 {11, -1, -1, 16}, 261 {16, -1, -1, 15}, 262 {15, 14, 13, 12}, 263 {12, -1, -1, 11} 264 265 }; 266 267 MA2D_LBUFFER test1_lbuf = {MA2D_LINESEG_F_USED, 13, test1_linesegs}; 268 269 int test1_outerpath[9] = {0,1,2,3,4,5,6,7,8}; 270 int test1_innerpath[4] = {9,10,11,12}; 271 272 MA2D_PATH test1_paths[2] = { 273 { 0, 0, 9, test1_outerpath}, 274 { 11,11, 4, test1_innerpath} 275 }; 276 277 MA2D_SHAPE test1_shape = { 278 MAGESHAPE_F_USED, 279 &test1_vbuf, 280 &test1_lbuf, 281 2, test1_paths 282 }; 283 284 285 286 allegro_init(); 287 install_keyboard(); 288 install_mouse(); 289 install_timer(); 290 291 292 set_color_depth(my_depth); 293 294 if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0) != 0) { 295 printf("Video Error: %s", allegro_error); //screen would still be in text mode on error 296 return 1; 297 } else { 298 299 300 clear_to_color(screen,makecol(0,0,0)); 301 302 draw_rough(screen, &test1_shape, 200,100, 20,20, 0); 303 304 textout_centre_ex(screen, font, "Press any key to continue", SCREEN_W/2, 305 SCREEN_H - 20, makecol(255, 255, 0),makecol(0, 0, 255)); 306 307 //Wait for a key to be pressed 308 while (!keypressed()) {} 309 310 readkey(); 311 312 clear_to_color(screen,makecol(0,0,0)); 313 314 init_scanlines(); 315 draw_rough_fill(screen, &test1_shape, 200,100, 20,20, 0); 316 render_all_scanlines(); 317 free_all_transits(); 318 319 textout_centre_ex(screen, font, "Press any key to continue", SCREEN_W/2, 320 SCREEN_H - 20, makecol(255, 255, 0),makecol(0, 0, 255)); 321 322 //Wait for a key to be pressed 323 while (!keypressed()) {} 324 325 326 327 328 } 329 330 331 return 0; 332 } 333 334 END_OF_MAIN()