diff options
author | Søren Sandmann Pedersen <ssp@l3000.localdomain> | 2010-12-13 12:28:47 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@l3000.localdomain> | 2010-12-20 10:48:52 -0500 |
commit | 47121d21057f95585f7353109f15b55bcab896d0 (patch) | |
tree | 0f5b218a32e76feb5be7e37727b19fb4b139e51a | |
parent | 634415aceeb0e296abe5990bbf79f2c5fb342494 (diff) |
sample_t type
-rw-r--r-- | dda.c | 140 |
1 files changed, 70 insertions, 70 deletions
@@ -49,72 +49,69 @@ typedef int32_t fixed_t; #define SMALL_STEP_X STEP_X_SMALL(8) #define FIRST_STEP_X X_FRAC_FIRST(8) +/* A sample_t is a fixed_t where the fractional bits are replaced with + * a small integer indicating the sample number in the pixel. + */ +typedef int32_t sample_t; + static fixed_t -sample_to_pos_x (int x) +sample_to_pos_x (sample_t x) { - return (x & 0xffffff00) + (x & 0xff) * SMALL_STEP_X + FIRST_STEP_X; + return fixed_floor (x) + FIRST_STEP_X + fixed_frac (x) * SMALL_STEP_X; } static fixed_t -sample_to_pos_y (int y) +sample_to_pos_y (sample_t y) { - return (y & 0xffffff00) + (y & 0xff) * SMALL_STEP_Y + FIRST_STEP_Y; + return fixed_floor (y) + FIRST_STEP_Y + fixed_frac (y) * SMALL_STEP_Y; } -static int +static sample_t next_sample_y (fixed_t y) { fixed_t f = fixed_frac (y); - fixed_t i = fixed_to_int (y); - int sno; + fixed_t i = fixed_floor (y); + uint32_t sample_no; - sno = ((f - FIRST_STEP_Y + SMALL_STEP_Y - fixed_e) / SMALL_STEP_Y); + sample_no = ((f - FIRST_STEP_Y + SMALL_STEP_Y - fixed_e) / SMALL_STEP_Y); - if (sno >= N_GRID_Y) + if (sample_no >= N_GRID_Y) { - if (i == fixed_max_int) - { - sno = N_GRID_Y - 1; /* saturate */ - } - else - { - sno -= (N_GRID_Y + 1); - i++; - } + /* FIXME: i can overflow here, but we should probably just + * reject edges that close to the border + */ + sample_no -= (N_GRID_Y + 1); + i += fixed_1; } - return (i << 8) | sno; + return i + sample_no; } -static int +static sample_t next_sample_x (fixed_t x) { fixed_t f = fixed_frac (x); - fixed_t i = fixed_to_int (x); - int sno; + fixed_t i = fixed_floor (x); + int sample_no; - sno = ((f - FIRST_STEP_X + SMALL_STEP_X - fixed_e) / SMALL_STEP_X); + sample_no = ((f - FIRST_STEP_X + SMALL_STEP_X - fixed_e) / SMALL_STEP_X); - if (sno >= N_GRID_X) + if (sample_no >= N_GRID_X) { - if (i == fixed_max_int) - { - sno = N_GRID_X - 1; /* saturate */ - } - else - { - sno -= (N_GRID_X + 1); - i++; - } + /* FIXME: i can overflow here, but we should probably just + * reject edges that close to the border + */ + sample_no -= (N_GRID_X + 1); + i += fixed_1; } - return (i << 8) | sno; + return i + sample_no; } typedef struct { - int xi; - int bottom; + sample_t xi; + sample_t bottom; int64_t e; int64_t delta_e_big_x; int64_t delta_e_small_x; @@ -140,25 +137,30 @@ edge_init (edge_t *edge, fixed_t x0, fixed_t y0, fixed_t x1, fixed_t y1) edge->delta_e_small_y = SMALL_STEP_Y * dx; } +typedef void (* emitter_t) (sample_t x, sample_t y, void *data); + /* FIXME: * * When updating the xi, we are stepping one sample at a time, but we * can do better because we know how the minimum damage that is done on every Y * step. This means we know we have to undo at least that much damage, so * we can step much more than one sample if the edge is close to horizontal. + * + * The first micro-step is an exception - it may not do as much damage as + * normal. */ static void -edge_step (edge_t *edge, test_data_t *testdata, int i, int *yi) +edge_step (edge_t *edge, int *yi, emitter_t emit, void *data) { if (edge->delta_e_small_y >= 0) { while (edge->e <= 0) { - if ((edge->xi & 0xff) == N_GRID_X - 1) + if (fixed_frac (edge->xi) == N_GRID_X - 1) { edge->e += edge->delta_e_big_x; - edge->xi += (1 << 8); - edge->xi &= 0xffffff00; + edge->xi += fixed_1; + edge->xi = fixed_floor (edge->xi); } else { @@ -170,12 +172,12 @@ edge_step (edge_t *edge, test_data_t *testdata, int i, int *yi) else { begin: - if ((edge->xi & 0xff) == 0) + if (fixed_frac (edge->xi) == 0) { if (edge->e > edge->delta_e_big_x) { edge->e -= edge->delta_e_big_x; - edge->xi -= (1 << 8); + edge->xi -= fixed_1; edge->xi |= (N_GRID_X - 1); goto small; } @@ -192,32 +194,13 @@ edge_step (edge_t *edge, test_data_t *testdata, int i, int *yi) } } -#if 0 - printf ("Pos: %f %f\n", - fixed_to_double (sample_to_pos_x (edge->xi)), - fixed_to_double (sample_to_pos_y (*yi))); -#endif - printf ("Pos: %x %x\n", edge->xi, *yi); -#if 0 - fixed_to_double (sample_to_pos_x (edge->xi)), - fixed_to_double (sample_to_pos_y (*yi))); -#endif - -#if 0 - if (testdata->points[i++] != sample_to_pos (edge->xi) || - testdata->points[i++] != sample_to_pos (*yi)) - { - printf ("%d error %f %f\n", i, testdata->points[i - 1], - sample_to_pos (edge->xi)); - exit (-1); - } -#endif + emit (edge->xi, *yi, data); - if (((*yi) & 0xff) == (N_GRID_Y - 1)) + if (fixed_frac (*yi) == N_GRID_Y - 1) { edge->e -= edge->delta_e_big_y; - (*yi) += (1 << 8); - (*yi) &= 0xffffff00; + (*yi) += fixed_1; + (*yi) = fixed_floor (*yi); } else { @@ -227,6 +210,19 @@ edge_step (edge_t *edge, test_data_t *testdata, int i, int *yi) } static void +emit (sample_t xi, sample_t yi, void *data) +{ + double *points = data; + + printf ("sample %x %x (%f %f)\n", + xi, yi, + fixed_to_double (sample_to_pos_x (xi)), + fixed_to_double (sample_to_pos_y (yi))); + + return; +} + +static void dda (test_data_t *testdata) { fixed_t x0 = double_to_fixed (testdata->segment.x0); @@ -234,13 +230,11 @@ dda (test_data_t *testdata) fixed_t x1 = double_to_fixed (testdata->segment.x1); fixed_t y1 = double_to_fixed (testdata->segment.y1); -#if 0 - printf ("= = = = %f %f %f %f = = = = \n", + printf ("f = = = %f %f %f %f = = = = \n", fixed_to_double (x0), fixed_to_double (y0), fixed_to_double (x1), fixed_to_double (y1)); -#endif edge_t edge; int i = 0; @@ -251,16 +245,22 @@ dda (test_data_t *testdata) yi = next_sample_y (y0); while (yi < edge.bottom) { - edge_step (&edge, testdata, i, &yi); + edge_step (&edge, &yi, emit, &(testdata->points[i])); i += 2; } } +test_data_t td = { { 0.52, -23, 3.5, 10.733 } }; + int main () { - test_data_t td = { { 0.5, 0.5, 3.5, 10.733 } }; + printf (". = = = %f %f %f %f = = = = \n", + td.segment.x0, + td.segment.y0, + td.segment.x1, + td.segment.y1); dda (&td); |