Revision 1

Date:
2009/05/25 21:33:58
Author:
MattyMatt
Revision Log:
test1
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()