std::string SVG::get_path_d(const MultiPoint &mp, bool closed) const { std::ostringstream d; d << "M "; for (Points::const_iterator p = mp.points.begin(); p != mp.points.end(); ++p) { d << COORD(p->x - origin.x) << " "; d << COORD(p->y - origin.y) << " "; } if (closed) d << "z"; return d.str(); }
void SVG::draw_legend(const Point &pt, const char *text, const char *color) { fprintf(this->f, "<circle cx=\"%f\" cy=\"%f\" r=\"10\" fill=\"%s\"/>", COORD(pt.x-origin.x), COORD(pt.y-origin.y), color); fprintf(this->f, "<text x=\"%f\" y=\"%f\" font-family=\"sans-serif\" font-size=\"10px\" fill=\"%s\">%s</text>", COORD(pt.x-origin.x) + 20.f, COORD(pt.y-origin.y), "black", text); }
static void random_point (double x[], coord bin[], double *bin_vol, const coord box[], const double xl[], const double xu[], gsl_monte_vegas_state * s, gsl_rng * r) { /* Use the random number generator r to return a random position x in a given box. The value of bin gives the bin location of the random position (there may be several bins within a given box) */ double vol = 1.0; size_t j; size_t dim = s->dim; size_t bins = s->bins; size_t boxes = s->boxes; DISCARD_POINTER(xu); /* prevent warning about unused parameter */ for (j = 0; j < dim; ++j) { /* box[j] + ran gives the position in the box units, while z is the position in bin units. */ double z = ((box[j] + gsl_rng_uniform_pos (r)) / boxes) * bins; int k = z; double y, bin_width; bin[j] = k; if (k == 0) { bin_width = COORD (s, 1, j); y = z * bin_width; } else { bin_width = COORD (s, k + 1, j) - COORD (s, k, j); y = COORD (s, k, j) + (z - k) * bin_width; } x[j] = xl[j] + y * s->delx[j]; vol *= bin_width; } *bin_vol = vol; }
void primRectSolidTexturedFullRectC2(rectangle *rect, color c) { glColor4ub(colRed(c), colGreen(c), colBlue(c), colAlpha(c)); rndTextureEnable(TRUE); glBegin(GL_QUADS); COORD(0.0f, 0.0f, rect->x0, rect->y0); COORD(0.0f, 1.0f, rect->x0, rect->y1); COORD(1.0f, 1.0f, rect->x1, rect->y1); COORD(1.0f, 0.0f, rect->x1, rect->y0); glEnd(); rndTextureEnable(FALSE); }
void hrRectSolidTextured2(rectangle *rect) { glColor3ub(255, 255, 255); rndTextureEnvironment(RTE_Replace); rndTextureEnable(TRUE); glBegin(GL_QUADS); COORD(0.0f, 0.0f, rect->x0, rect->y0); COORD(0.0f, 1.0f, rect->x0, rect->y1 - 1); COORD(1.0f, 1.0f, rect->x1, rect->y1 - 1); COORD(1.0f, 0.0f, rect->x1, rect->y0); glEnd(); rndTextureEnable(FALSE); rndTextureEnvironment(RTE_Modulate); }
static Imlib_Image regenerate_from_original(const char *filename, int size) { /* load image */ Imlib_Load_Error err; Imlib_Image orig = imlib_load_image_with_error_return(filename, &err); if (orig == NULL) { const char *errmsg = imlib_load_error_string(err); warnx("couldn't load %s for thumbnailing: %s", filename, errmsg); return NULL; /* XXX do what with error message? extra param? */ } imlib_context_set_image(orig); struct coord image_dim = COORD( imlib_image_get_width(), imlib_image_get_height() ); /* make thumbnail, but without upscaling smaller images. */ struct coord thumb_dim = coord_downscale_to_fit(image_dim, COORD(size, size)); Imlib_Image thumb = imlib_create_cropped_scaled_image(0, 0, image_dim.width, image_dim.height, thumb_dim.width, thumb_dim.height ); /* can free original image now */ imlib_context_set_image(orig); imlib_free_image(); /* done */ if (thumb == NULL) { warnx("error while downscaling %s for thumbnailing", filename); return NULL; } return thumb; }
bool SVG::open(const char* afilename, const BoundingBox &bbox, const coord_t bbox_offset, bool aflipY) { this->filename = afilename; this->origin = bbox.min - Point(bbox_offset, bbox_offset); this->flipY = aflipY; this->f = boost::nowide::fopen(afilename, "w"); if (f == NULL) return false; float w = COORD(bbox.max.x - bbox.min.x + 2 * bbox_offset); float h = COORD(bbox.max.y - bbox.min.y + 2 * bbox_offset); fprintf(this->f, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n" "<svg height=\"%f\" width=\"%f\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n" " <marker id=\"endArrow\" markerHeight=\"8\" markerUnits=\"strokeWidth\" markerWidth=\"10\" orient=\"auto\" refX=\"1\" refY=\"5\" viewBox=\"0 0 10 10\">\n" " <polyline fill=\"darkblue\" points=\"0,0 10,5 0,10 1,5\" />\n" " </marker>\n", h, w); return true; }
int pointSearch( ObjectDB *odb, float pos[ 3 ] ) { int lt = 0, rt = ARRAYSIZE - 1, x, key = KEY, ipos = IPOS; while ( rt >= lt ) { x = ( lt + rt ) / 2; if ( pos[ key ] < SORTVAL( x )) rt = x - 1; else lt = x + 1; if ( pos[ key ] == SORTVAL( x )) { lt = rt = x; while ( lt > 0 && pos[ key ] == SORTVAL( lt - 1 )) --lt; while ( rt < ARRAYSIZE - 1 && pos[ key ] == SORTVAL( rt + 1 )) ++rt; for ( x = lt; x <= rt; x++ ) if ( pos[ 0 ] == COORD( x, 0 ) && pos[ 1 ] == COORD( x, 1 ) && pos[ 2 ] == COORD( x, 2 )) return ARRAY( x ); return -1; } } return -1; }
static void init_grid (gsl_monte_vegas_state * s, double xl[], double xu[], size_t dim) { size_t j; double vol = 1.0; s->bins = 1; for (j = 0; j < dim; j++) { double dx = xu[j] - xl[j]; s->delx[j] = dx; vol *= dx; COORD (s, 0, j) = 0.0; COORD (s, 1, j) = 1.0; } s->vol = vol; }
static void resize_grid (gsl_monte_vegas_state * s, unsigned int bins) { size_t j, k; size_t dim = s->dim; /* weight is ratio of bin sizes */ double pts_per_bin = (double) s->bins / (double) bins; for (j = 0; j < dim; j++) { double xold; double xnew = 0; double dw = 0; int i = 1; for (k = 1; k <= s->bins; k++) { dw += 1.0; xold = xnew; xnew = COORD (s, k, j); for (; dw > pts_per_bin; i++) { dw -= pts_per_bin; NEW_COORD (s, i) = xnew - (xnew - xold) * dw; } } for (k = 1 ; k < bins; k++) { COORD(s, k, j) = NEW_COORD(s, k); } COORD (s, bins, j) = 1; } s->bins = bins; }
void TerrainChunk::ComputeIndicesArray(unsigned int lod, unsigned int depth, ivec2 pos, ivec2 HMsize) { assert(lod < TERRAIN_CHUNKS_LOD); ivec2 vHeightmapDataPos = pos; unsigned int offset = (unsigned int)pow(2.0f, (float)(lod)); unsigned int div = (unsigned int)pow(2.0f, (float)(depth+lod)); ivec2 vHeightmapDataSize = HMsize/(div) + ivec2(1,1); GLuint nHMWidth = (GLuint)vHeightmapDataSize.x; GLuint nHMHeight = (GLuint)vHeightmapDataSize.y; GLuint nHMOffsetX = (GLuint)vHeightmapDataPos.x; GLuint nHMOffsetY = (GLuint)vHeightmapDataPos.y; GLuint nHMTotalWidth = (GLuint)HMsize.x; GLuint nHMTotalHeight = (GLuint)HMsize.y; m_tIndOffsetW[lod] = nHMWidth*2; m_tIndOffsetH[lod] = nHMWidth-1; GLuint nIndice = (nHMWidth)*(nHMHeight-1)*2; m_tIndice[lod].reserve( nIndice ); for(GLuint j=0; j<(GLuint)nHMHeight-1; j++) { for(GLuint i=0; i<(GLuint)nHMWidth; i++) { GLuint id0 = COORD(i*(offset) + nHMOffsetX+0, j*(offset) + nHMOffsetY+0); GLuint id1 = COORD(i*(offset) + nHMOffsetX+0, j*(offset) + nHMOffsetY+(offset)); m_tIndice[lod].push_back( id0 ); m_tIndice[lod].push_back( id1 ); } } assert(nIndice == m_tIndice[lod].size()); }
void SVG::draw(const ThickLine &line, const std::string &fill, const std::string &stroke, coordf_t stroke_width) { Pointf dir(line.b.x-line.a.x, line.b.y-line.a.y); Pointf perp(-dir.y, dir.x); coordf_t len = sqrt(perp.x*perp.x + perp.y*perp.y); coordf_t da = coordf_t(0.5)*line.a_width/len; coordf_t db = coordf_t(0.5)*line.b_width/len; fprintf(this->f, " <polygon points=\"%f,%f %f,%f %f,%f %f,%f\" style=\"fill:%s; stroke: %s; stroke-width: %f\"/>\n", COORD(line.a.x-da*perp.x-origin.x), COORD(line.a.y-da*perp.y-origin.y), COORD(line.b.x-db*perp.x-origin.x), COORD(line.b.y-db*perp.y-origin.y), COORD(line.b.x+db*perp.x-origin.x), COORD(line.b.y+db*perp.y-origin.y), COORD(line.a.x+da*perp.x-origin.x), COORD(line.a.y+da*perp.y-origin.y), fill.c_str(), stroke.c_str(), (stroke_width == 0) ? 1.f : COORD(stroke_width)); }
void SVG::path(const std::string &d, bool fill, coordf_t stroke_width, const float fill_opacity) { float lineWidth = 0.f; if (! fill) lineWidth = (stroke_width == 0) ? 2.f : COORD(stroke_width); fprintf( this->f, " <path d=\"%s\" style=\"fill: %s; stroke: %s; stroke-width: %f; fill-type: evenodd\" %s fill-opacity=\"%f\" />\n", d.c_str(), fill ? this->fill.c_str() : "none", this->stroke.c_str(), lineWidth, (this->arrows && !fill) ? " marker-end=\"url(#endArrow)\"" : "", fill_opacity ); }
static void my_expulse_right(t_server *serv, t_player *drone, t_player *victim) { int x; int y; char buff[512]; int len; x = victim->pos % serv->width; y = victim->pos / serv->width; x += 1; adjust_coord(serv, &x, &y); move_player(serv, victim, victim->pos, COORD(x, y)); len = snprintf(buff, sizeof(buff), "deplacement: %d\n", get_direction(serv, drone, victim)); buff_append(victim->wrbuff, buff, len); }
static void print_grid (gsl_monte_vegas_state * state, unsigned long dim) { unsigned long i, j; int p = state->verbose; if (p < 1) return; for (j = 0; j < dim; ++j) { fprintf (state->ostream, "\n axis %lu \n", j); fprintf (state->ostream, " x \n"); for (i = 0; i <= state->bins; i++) { fprintf (state->ostream, "%11.2e", COORD (state, i, j)); if (i % 5 == 4) fprintf (state->ostream, "\n"); } fprintf (state->ostream, "\n"); } fprintf (state->ostream, "\n"); fflush (state->ostream); }
void my_bct(t_server *serv, t_player *client, char *str) { int pos; char *strx; char *stry; int i; strx = get_second_word(str); stry = get_second_word(strx); i = 0; while (strx[i] != '\0' && strx[i] != ' ') i += 1; strx[i] = '\0'; if (my_valid_number(strx) == 0 || my_valid_number(stry) == 0) graphic_instr(serv, client, NULL, SBP); else { pos = COORD(atoi(strx), atoi(stry)); if (pos > serv->width * serv->height || pos < 0) graphic_instr(serv, client, NULL, SBP); else graphic_instr(serv, client, &pos, BCT); } }
static void draw_tile(drawing *dr, game_drawstate *ds, struct clues *clues, int x, int y, long tile) { int w = clues->w /* , a = w*w */; int tx, ty, bg; char str[64]; tx = COORD(x); ty = COORD(y); bg = (tile & DF_HIGHLIGHT) ? COL_HIGHLIGHT : COL_BACKGROUND; /* draw tower */ if (ds->three_d && (tile & DF_PLAYAREA) && (tile & DF_DIGIT_MASK)) { int coords[8]; int xoff = X_3D_DISP(tile & DF_DIGIT_MASK, w); int yoff = Y_3D_DISP(tile & DF_DIGIT_MASK, w); /* left face of tower */ coords[0] = tx; coords[1] = ty - 1; coords[2] = tx; coords[3] = ty + TILESIZE - 1; coords[4] = coords[2] + xoff; coords[5] = coords[3] - yoff; coords[6] = coords[0] + xoff; coords[7] = coords[1] - yoff; draw_polygon(dr, coords, 4, bg, COL_GRID); /* bottom face of tower */ coords[0] = tx + TILESIZE; coords[1] = ty + TILESIZE - 1; coords[2] = tx; coords[3] = ty + TILESIZE - 1; coords[4] = coords[2] + xoff; coords[5] = coords[3] - yoff; coords[6] = coords[0] + xoff; coords[7] = coords[1] - yoff; draw_polygon(dr, coords, 4, bg, COL_GRID); /* now offset all subsequent drawing to the top of the tower */ tx += xoff; ty -= yoff; } /* erase background */ draw_rect(dr, tx, ty, TILESIZE, TILESIZE, bg); /* pencil-mode highlight */ if (tile & DF_HIGHLIGHT_PENCIL) { int coords[6]; coords[0] = tx; coords[1] = ty; coords[2] = tx+TILESIZE/2; coords[3] = ty; coords[4] = tx; coords[5] = ty+TILESIZE/2; draw_polygon(dr, coords, 3, COL_HIGHLIGHT, COL_HIGHLIGHT); } /* draw box outline */ if (tile & DF_PLAYAREA) { int coords[8]; coords[0] = tx; coords[1] = ty - 1; coords[2] = tx + TILESIZE; coords[3] = ty - 1; coords[4] = tx + TILESIZE; coords[5] = ty + TILESIZE - 1; coords[6] = tx; coords[7] = ty + TILESIZE - 1; draw_polygon(dr, coords, 4, -1, COL_GRID); } /* new number needs drawing? */ if (tile & DF_DIGIT_MASK) { str[1] = '\0'; str[0] = (tile & DF_DIGIT_MASK) + '0'; draw_text(dr, tx + TILESIZE/2, ty + TILESIZE/2, FONT_VARIABLE, (tile & DF_PLAYAREA ? TILESIZE/2 : TILESIZE*2/5), ALIGN_VCENTRE | ALIGN_HCENTRE, (tile & DF_ERROR) ? COL_ERROR : (x < 0 || y < 0 || x >= w || y >= w) ? COL_GRID : (tile & DF_IMMUTABLE) ? COL_GRID : COL_USER, str); } else { int i, j, npencil; int pl, pr, pt, pb; float bestsize; int pw, ph, minph, pbest, fontsize; /* Count the pencil marks required. */ for (i = 1, npencil = 0; i <= w; i++) if (tile & (1L << (i + DF_PENCIL_SHIFT))) npencil++; if (npencil) { minph = 2; /* * Determine the bounding rectangle within which we're going * to put the pencil marks. */ /* Start with the whole square, minus space for impinging towers */ pl = tx + (ds->three_d ? X_3D_DISP(w,w) : 0); pr = tx + TILESIZE; pt = ty; pb = ty + TILESIZE - (ds->three_d ? Y_3D_DISP(w,w) : 0); /* * We arrange our pencil marks in a grid layout, with * the number of rows and columns adjusted to allow the * maximum font size. * * So now we work out what the grid size ought to be. */ bestsize = 0.0; pbest = 0; /* Minimum */ for (pw = 3; pw < max(npencil,4); pw++) { float fw, fh, fs; ph = (npencil + pw - 1) / pw; ph = max(ph, minph); fw = (pr - pl) / (float)pw; fh = (pb - pt) / (float)ph; fs = min(fw, fh); if (fs > bestsize) { bestsize = fs; pbest = pw; } } assert(pbest > 0); pw = pbest; ph = (npencil + pw - 1) / pw; ph = max(ph, minph); /* * Now we've got our grid dimensions, work out the pixel * size of a grid element, and round it to the nearest * pixel. (We don't want rounding errors to make the * grid look uneven at low pixel sizes.) */ fontsize = min((pr - pl) / pw, (pb - pt) / ph); /* * Centre the resulting figure in the square. */ pl = pl + (pr - pl - fontsize * pw) / 2; pt = pt + (pb - pt - fontsize * ph) / 2; /* * Now actually draw the pencil marks. */ for (i = 1, j = 0; i <= w; i++) if (tile & (1L << (i + DF_PENCIL_SHIFT))) { int dx = j % pw, dy = j / pw; str[1] = '\0'; str[0] = i + '0'; draw_text(dr, pl + fontsize * (2*dx+1) / 2, pt + fontsize * (2*dy+1) / 2, FONT_VARIABLE, fontsize, ALIGN_VCENTRE | ALIGN_HCENTRE, COL_PENCIL, str); j++; } } } }
void COORD::UnitTest() { assert(COORD(3, 3) + COORD(2, 2) == COORD(5, 5)); COORD coord(5, 2); coord += COORD(2, 5); assert(coord == COORD(7, 7)); assert(COORD(2, 2) + coord::North == COORD(2, 3)); assert(COORD(2, 2) + coord::East == COORD(3, 2)); assert(COORD(2, 2) + coord::South == COORD(2, 1)); assert(COORD(2, 2) + coord::West == COORD(1, 2)); assert(coord::Compass[coord::E_NORTH] == coord::North); assert(coord::Compass[coord::E_EAST] == coord::East); assert(coord::Compass[coord::E_WEST] == coord::West); assert(coord::Compass[coord::E_SOUTH] == coord::South); assert(coord::Clockwise(coord::E_NORTH) == coord::E_EAST); assert(coord::Clockwise(coord::E_EAST) == coord::E_SOUTH); assert(coord::Clockwise(coord::E_SOUTH) == coord::E_WEST); assert(coord::Clockwise(coord::E_WEST) == coord::E_NORTH); assert(coord::Opposite(coord::E_NORTH) == coord::E_SOUTH); assert(coord::Opposite(coord::E_EAST) == coord::E_WEST); assert(coord::Opposite(coord::E_SOUTH) == coord::E_NORTH); assert(coord::Opposite(coord::E_WEST) == coord::E_EAST); assert(coord::Anticlockwise(coord::E_NORTH) == coord::E_WEST); assert(coord::Anticlockwise(coord::E_EAST) == coord::E_NORTH); assert(coord::Anticlockwise(coord::E_SOUTH) == coord::E_EAST); assert(coord::Anticlockwise(coord::E_WEST) == coord::E_SOUTH); assert(coord::ManhattanDistance(COORD(3, 2), COORD(-4, -7)) == 16); assert(coord::DirectionalDistance(COORD(3, 2), COORD(-4, -7), coord::E_NORTH) == -9); assert(coord::DirectionalDistance(COORD(3, 2), COORD(-4, -7), coord::E_EAST) == -7); assert(coord::DirectionalDistance(COORD(3, 2), COORD(-4, -7), coord::E_SOUTH) == 9); assert(coord::DirectionalDistance(COORD(3, 2), COORD(-4, -7), coord::E_WEST) == 7); }
void main_loop(void) { Doubly_linked_node *iterator; int direction, dx, dy, count; int x, y; uint32_t last_time; uint32_t current_time; uint32_t ellapsed_time; uint32_t start_time; Point *save_eye; float speed; last_time = SDL_GetTicks(); while (!conf->key[SDLK_ESCAPE] && !conf->quit) { start_time = SDL_GetTicks(); save_eye = point_new(conf->eye->x, conf->eye->y, conf->eye->z); speed = (conf->free_fly) ? 5 : 0.5; update_event(); if (!conf->viewMode && conf->key[SDLK_F1]) { conf->key[SDLK_F1] = 0; conf->free_fly = !conf->free_fly; if (!conf->free_fly) { save_eye->x = CELL_SIZE / 2; save_eye->y = CELL_SIZE / 2; save_eye->z = CHARACTER_SIZE; } else { conf->jump_duration = 0; } } if (!conf->viewMode && (conf->key[SDLK_LSHIFT] || conf->key[SDLK_LALT])) { if ( conf->jump_duration == 0 ) { /* j'ai du mal a courir quand je saute */ speed = (conf->free_fly) ? 7.51337 : 0.91337; } } if (!conf->viewMode && conf->key[SDLK_LCTRL]) { speed = (conf->free_fly) ? 0.1 : 0.3; } if (conf->key[SDLK_F2]) { conf->key[SDLK_F2] = 0; conf->time = !conf->time; } if (conf->key[SDLK_F3]) { conf->key[SDLK_F3] = 0; conf->display = !conf->display; } if (!conf->viewMode && conf->key[SDLK_F4]) { conf->key[SDLK_F4] = 0; conf->quadTreeView = !conf->quadTreeView; } if (conf->key[SDLK_F5]) { conf->key[SDLK_F5] = 0; if (!strcmp(conf->music, "music/music2.mp3")) { conf->music = "music/music.mp3"; music_new(); } else if (!strcmp(conf->music, "music/music.mp3")) { conf->music = "music/music2.mp3"; music_new(); } } if (!conf->viewMode && (conf->key[SDLK_UP] || conf->key[SDLK_z])) { forward_move(save_eye, speed); } if (!conf->viewMode && (conf->key[SDLK_DOWN] || conf->key[SDLK_s])) { backward_move(save_eye, speed); } if (!conf->viewMode && (conf->key[SDLK_RIGHT] || conf->key[SDLK_d])) { right_move(save_eye, speed); } if (!conf->viewMode && (conf->key[SDLK_LEFT] || conf->key[SDLK_q])) { left_move(save_eye, speed); } if (!conf->viewMode && conf->key[SDLK_a]) { conf->key[SDLK_a] = 0; conf->theta += 180; } if (!conf->viewMode && conf->key[SDLK_r]) { conf->key[SDLK_r] = 0; conf->life = MAX_HEALTH; save_eye->x = CELL_SIZE / 2; save_eye->y = CELL_SIZE / 2; save_eye->z = CHARACTER_SIZE; portals->bleu->actif = 0; portals->orange->actif = 0; conf->timer = SDL_GetTicks(); } if (conf->key[SDLK_KP2] || (conf->key[SDLK_n])) { if (conf->free_fly) { save_eye->z -= 3; } else if (conf->viewMode) { save_eye->z -= 10; } } if (conf->key[SDLK_KP8] || (conf->key[SDLK_SPACE])) { if (!conf->free_fly && !conf->viewMode) { conf->key[SDLK_KP8] = 0; conf->key[SDLK_SPACE] = 0; if ( !conf->viewMode && conf->jump_duration == 0 ) { conf->jump_duration = 120; } } else if (conf->free_fly){ save_eye->z += 3; } else { save_eye->z += 10; } } conf->eye->z += jump(save_eye); if ( conf->key[SDLK_p] ) { conf->key[SDLK_p] = 0; if(Mix_PausedMusic() == 1) { Mix_ResumeMusic(); } else { Mix_PauseMusic(); } } if ( conf->key[SDLK_PLUS] || conf->key[SDLK_m] || conf->key[SDLK_KP_PLUS] ) { change_volume(CHANG_VOL); } if ( conf->key[SDLK_MINUS] || conf->key[SDLK_l] || conf->key[SDLK_KP_MINUS] ) { change_volume(-CHANG_VOL); } if (!conf->mousebutton[SDL_BUTTON_LEFT] && !conf->mousebutton[SDL_BUTTON_RIGHT]) { conf->shoot = 0; } if (!conf->viewMode && conf->mousebutton[SDL_BUTTON_LEFT]) { conf->mousebutton[SDL_BUTTON_LEFT] = 0; conf->mousebutton[SDL_BUTTON_RIGHT] = 0; conf->shoot = 1; } if (!conf->viewMode && conf->mousebutton[SDL_BUTTON_RIGHT]) { conf->mousebutton[SDL_BUTTON_LEFT] = 0; conf->mousebutton[SDL_BUTTON_RIGHT] = 0; conf->shoot = 2; } if (!conf->viewMode && portals->orange->actif && portals->bleu->actif ) { if ( abs(save_eye->x - portals->bleu->portail->x ) < TRIGGER_DISTANCE && abs(save_eye->y - portals->bleu->portail->y) < TRIGGER_DISTANCE) { save_eye->x = portals->orange->portail->x - (sin(portals->orange->rotation) * PUSH_DISTANCE); save_eye->y = portals->orange->portail->y + (cos(portals->orange->rotation) * PUSH_DISTANCE); conf->theta += 180 + ( portals->orange->rotation - portals->bleu->rotation); } else if ( abs(save_eye->x - portals->orange->portail->x ) < TRIGGER_DISTANCE && abs(save_eye->y - portals->orange->portail->y) < TRIGGER_DISTANCE) { save_eye->x = portals->bleu->portail->x - (sin(portals->bleu->rotation) * PUSH_DISTANCE); save_eye->y = portals->bleu->portail->y + (cos(portals->bleu->rotation) * PUSH_DISTANCE); conf->theta += 180 + ( portals->bleu->rotation - portals->orange->rotation); } } if (COORD((int)(save_eye->x / CELL_SIZE), (int)(save_eye->y / CELL_SIZE)) != COORD((int)((conf->eye)->x / CELL_SIZE), (int)((conf->eye)->y / CELL_SIZE))) { iterator = mwl->last; while (1) { if ((iterator->object)->type == MOVING_WALL) { x = (((int)((iterator->object)->anchor)->x ) / CELL_SIZE); y = (((int)((iterator->object)->anchor)->y ) / CELL_SIZE); count = 0; direction = rand() % 4; while (count < 4) { dx = 0; dy = 0; switch (direction) { case 0: dx = 1; break; case 1: dy = 1; break; case 2: dx = -1; break; default: dy = -1; break; } if(COORD((x+dx),(y+dy)) == COORD(((int)save_eye->x / CELL_SIZE), ((int)save_eye->y / CELL_SIZE)) || !IS_PLAYABLE(COORD((x+dx),(y+dy))) || (dx == 1 && END_RIGHT(COORD(x,y))) || (dy == 1 && END_TOP(COORD(x,y))) || (dx == -1 && END_LEFT(COORD(x,y))) || (dy == -1 && END_BOTTOM(COORD(x,y))) ) { direction = (direction + 1) % 4; ++count; } else { if(laby->matrix[COORD(x,y)] == SPIKES_MW) { laby->matrix[COORD(x,y)] = SPIKES; } else if (laby->matrix[COORD(x,y)] == MOVING_WALL) { laby->matrix[COORD(x,y)] = PASS; } if(laby->matrix[COORD((x+dx),(y+dy))] == PASS) { laby->matrix[COORD((x+dx),(y+dy))] = MOVING_WALL; } else if (laby->matrix[COORD((x+dx),(y+dy))] == SPIKES) { laby->matrix[COORD((x+dx),(y+dy))] = SPIKES_MW; } ((iterator->object)->anchor)->x += (dx * CELL_SIZE); ((iterator->object)->anchor)->y += (dy * CELL_SIZE); count = 4; } } } if (iterator->next != NULL) { iterator = iterator->next; } else { break; } } } /*fprintf(stderr, "%d %d\n", conf->mousex - SCREEN_MID_WIDTH, conf->mousey - SCREEN_MID_HEIGHT);*/ if (!conf->viewMode && (( save_eye->x > 2 && save_eye->y > 2 && save_eye->x < (CELL_SIZE * WIDTH) - 2 && save_eye->y < (CELL_SIZE * HEIGHT) - 2 /*&& save_eye->z <= CHARACTER_SIZE && save_eye->z > CHARACTER_SIZE - 3*/ && IS_PLAYABLE(COORD((int)(save_eye->x / CELL_SIZE),(int)(save_eye->y / CELL_SIZE))) && IS_PLAYABLE(COORD((int)((save_eye->x + 2) / CELL_SIZE),(int)((save_eye->y) / CELL_SIZE))) && IS_PLAYABLE(COORD((int)((save_eye->x) / CELL_SIZE),(int)((save_eye->y + 2) / CELL_SIZE))) && IS_PLAYABLE(COORD((int)((save_eye->x - 2) / CELL_SIZE),(int)((save_eye->y) / CELL_SIZE))) && IS_PLAYABLE(COORD((int)((save_eye->x) / CELL_SIZE),(int)((save_eye->y - 2) / CELL_SIZE))) ) || conf->free_fly == 1 )) { conf->eye->x = save_eye->x; conf->eye->y = save_eye->y; conf->eye->z = save_eye->z; } /* Mouse motion */ if(!conf->viewMode) { conf->theta -= (conf->mousex - SCREEN_MID_WIDTH) * SENSITIVITY; conf->phi -= (conf->mousey - SCREEN_MID_HEIGHT) * SENSITIVITY; SDL_WarpMouse(SCREEN_MID_WIDTH, SCREEN_MID_HEIGHT); modify_direction(); change_center(); } else { conf->eye->x = conf->center->x + CELL_SIZE * WIDTH * cos(conf->theta * M_PI / 180); conf->eye->y = conf->center->y + CELL_SIZE * HEIGHT * sin(conf->theta * M_PI / 180); conf->theta += 0.5; if (conf->theta >= 360) { conf->theta = 0; } } if (conf->life <= 0) { fprintf(stderr," .,---.\n"); fprintf(stderr," ,/XM#MMMX;,\n"); fprintf(stderr," -%%##########M%%,\n"); fprintf(stderr," -@######%% $###@=\n"); fprintf(stderr," .,--, -H#######$ $###M:\n"); fprintf(stderr," ,;$M###MMX; .;##########$;HM###X=\n"); fprintf(stderr," ,/@##########H= ;################+\n"); fprintf(stderr,"-+#############M/, %%##############+\n"); fprintf(stderr,"%%M###############= /##############:\n"); fprintf(stderr,"H################ .M#############;.\n"); fprintf(stderr,"@###############M ,@###########M:.\n"); fprintf(stderr,"X################, -$=X#######@:\n"); fprintf(stderr,"/@##################%%- +######$-\n"); fprintf(stderr,".;##################X .X#####+,\n"); fprintf(stderr," .;H################/ -X####+.\n"); fprintf(stderr," ,;X##############, .MM/\n"); fprintf(stderr," ,:+$H@M#######M#$- .$$=\n"); fprintf(stderr," .,-=;+$@###X: ;/=.\n"); fprintf(stderr," .,/X$; .::,\n"); fprintf(stderr," ., ..\n"); fprintf(stderr,"Haw Haw ! You lose !\n"); conf->quit = 1; } if (IS_EXIT(COORD((int)(conf->eye->x / CELL_SIZE), (int)(conf->eye->y / CELL_SIZE))) && !conf->free_fly) { if (!conf->win) { fprintf(stderr, "\n #,\n"); fprintf(stderr, " ###\n"); fprintf(stderr, " ## ##\n"); fprintf(stderr, " ## ##\n"); fprintf(stderr, " ####\n"); fprintf(stderr, " |\n"); fprintf(stderr, " #####\n"); fprintf(stderr, " ######\n"); fprintf(stderr, " ## ##\n"); fprintf(stderr, " ## ##\n"); fprintf(stderr, " ## ##\n"); fprintf(stderr, " ## ##########\n"); fprintf(stderr, " ## #############\n"); fprintf(stderr, " ####### ###############\n"); fprintf(stderr, " #############################\n"); fprintf(stderr, " .###################################\n"); fprintf(stderr, " #####################################;\n"); fprintf(stderr, " ## ##.\n"); fprintf(stderr, " ## ##\n"); fprintf(stderr, " #####################################\n"); fprintf(stderr, " ## ##\n"); fprintf(stderr, " ## ##\n"); fprintf(stderr, " ## ###\n"); fprintf(stderr, " ##### #####\n"); fprintf(stderr, " ### ##################################### ###\n"); fprintf(stderr, " ### ## ## ###\n"); fprintf(stderr, " ## ## ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ## ##\n"); fprintf(stderr, " ## ##################################### ##\n"); fprintf(stderr, " ## ##\n"); fprintf(stderr, " #### ####\n"); fprintf(stderr, " ###### ######\n"); fprintf(stderr, " ###############################\n"); fprintf(stderr, "The cake was not a lie !\n"); } if (strcmp(conf->music, "music/music3.mp3")) { conf->music = "music/music3.mp3"; music_new(); } conf->win = 1; } /* Display with FPS care */ current_time = SDL_GetTicks(); ellapsed_time = current_time - last_time; last_time = current_time; display(); ellapsed_time = SDL_GetTicks() - start_time; if (ellapsed_time < 25) { SDL_Delay(25 - ellapsed_time); } point_free(save_eye); } }
static void refine_grid (gsl_monte_vegas_state * s) { size_t i, j, k; size_t dim = s->dim; size_t bins = s->bins; for (j = 0; j < dim; j++) { double grid_tot_j, tot_weight; double * weight = s->weight; double oldg = VALUE (s, 0, j); double newg = VALUE (s, 1, j); VALUE (s, 0, j) = (oldg + newg) / 2; grid_tot_j = VALUE (s, 0, j); /* This implements gs[i][j] = (gs[i-1][j]+gs[i][j]+gs[i+1][j])/3 */ for (i = 1; i < bins - 1; i++) { double rc = oldg + newg; oldg = newg; newg = VALUE (s, i + 1, j); VALUE (s, i, j) = (rc + newg) / 3; grid_tot_j += VALUE (s, i, j); } VALUE (s, bins - 1, j) = (newg + oldg) / 2; grid_tot_j += VALUE (s, bins - 1, j); tot_weight = 0; for (i = 0; i < bins; i++) { weight[i] = 0; if (VALUE (s, i, j) > 0) { oldg = grid_tot_j / VALUE (s, i, j); /* damped change */ weight[i] = pow (((oldg - 1) / oldg / log (oldg)), s->alpha); } tot_weight += weight[i]; #ifdef DEBUG printf("weight[%d] = %g\n", i, weight[i]); #endif } { double pts_per_bin = tot_weight / bins; double xold; double xnew = 0; double dw = 0; i = 1; for (k = 0; k < bins; k++) { dw += weight[k]; xold = xnew; xnew = COORD (s, k + 1, j); for (; dw > pts_per_bin; i++) { dw -= pts_per_bin; NEW_COORD (s, i) = xnew - (xnew - xold) * dw / weight[k]; } } for (k = 1 ; k < bins ; k++) { COORD(s, k, j) = NEW_COORD(s, k); } COORD (s, bins, j) = 1; } } }
void COORD::UnitTest() { assert(COORD(3, 3) + COORD(2, 2) == COORD(5, 5)); COORD coord(5, 2); coord += COORD(2, 5); assert(coord == COORD(7, 7)); assert(COORD(2, 2) + North == COORD(2, 3)); assert(COORD(2, 2) + East == COORD(3, 2)); assert(COORD(2, 2) + South == COORD(2, 1)); assert(COORD(2, 2) + West == COORD(1, 2)); assert(Compass[E_NORTH] == North); assert(Compass[E_EAST] == East); assert(Compass[E_WEST] == West); assert(Compass[E_SOUTH] == South); assert(Clockwise(E_NORTH) == E_EAST); assert(Clockwise(E_EAST) == E_SOUTH); assert(Clockwise(E_SOUTH) == E_WEST); assert(Clockwise(E_WEST) == E_NORTH); assert(Opposite(E_NORTH) == E_SOUTH); assert(Opposite(E_EAST) == E_WEST); assert(Opposite(E_SOUTH) == E_NORTH); assert(Opposite(E_WEST) == E_EAST); assert(Anticlockwise(E_NORTH) == E_WEST); assert(Anticlockwise(E_EAST) == E_NORTH); assert(Anticlockwise(E_SOUTH) == E_EAST); assert(Anticlockwise(E_WEST) == E_SOUTH); assert(ManhattanDistance(COORD(3, 2), COORD(-4, -7)) == 16); assert(DirectionalDistance(COORD(3, 2), COORD(-4, -7), E_NORTH) == -9); assert(DirectionalDistance(COORD(3, 2), COORD(-4, -7), E_EAST) == -7); assert(DirectionalDistance(COORD(3, 2), COORD(-4, -7), E_SOUTH) == 9); assert(DirectionalDistance(COORD(3, 2), COORD(-4, -7), E_WEST) == 7); }
static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds, int x, int y, int button) { int w = state->par.w; int tx, ty; char buf[80]; button &= ~MOD_MASK; tx = FROMCOORD(x); ty = FROMCOORD(y); if (ds->three_d) { /* * In 3D mode, just locating the mouse click in the natural * square grid may not be sufficient to tell which tower the * user clicked on. Investigate the _tops_ of the nearby * towers to see if a click on one grid square was actually * a click on a tower protruding into that region from * another. */ int dx, dy; for (dy = 0; dy <= 1; dy++) for (dx = 0; dx >= -1; dx--) { int cx = tx + dx, cy = ty + dy; if (cx >= 0 && cx < w && cy >= 0 && cy < w) { int height = state->grid[cy*w+cx]; int bx = COORD(cx), by = COORD(cy); int ox = bx + X_3D_DISP(height, w); int oy = by - Y_3D_DISP(height, w); if (/* on top face? */ (x - ox >= 0 && x - ox < TILESIZE && y - oy >= 0 && y - oy < TILESIZE) || /* in triangle between top-left corners? */ (ox > bx && x >= bx && x <= ox && y <= by && (by-y) * (ox-bx) <= (by-oy) * (x-bx)) || /* in triangle between bottom-right corners? */ (ox > bx && x >= bx+TILESIZE && x <= ox+TILESIZE && y >= oy+TILESIZE && (by-y+TILESIZE)*(ox-bx) >= (by-oy)*(x-bx-TILESIZE))) { tx = cx; ty = cy; } } } } if (tx >= 0 && tx < w && ty >= 0 && ty < w) { if (button == LEFT_BUTTON) { if (tx == ui->hx && ty == ui->hy && ui->hshow && ui->hpencil == 0) { ui->hshow = 0; } else { ui->hx = tx; ui->hy = ty; ui->hshow = !state->clues->immutable[ty*w+tx]; ui->hpencil = 0; } ui->hcursor = 0; return ""; /* UI activity occurred */ } if (button == RIGHT_BUTTON) { /* * Pencil-mode highlighting for non filled squares. */ if (state->grid[ty*w+tx] == 0) { if (tx == ui->hx && ty == ui->hy && ui->hshow && ui->hpencil) { ui->hshow = 0; } else { ui->hpencil = 1; ui->hx = tx; ui->hy = ty; ui->hshow = 1; } } else { ui->hshow = 0; } ui->hcursor = 0; return ""; /* UI activity occurred */ } } if (IS_CURSOR_MOVE(button)) { move_cursor(button, &ui->hx, &ui->hy, w, w, 0); ui->hshow = ui->hcursor = 1; return ""; } if (ui->hshow && (button == CURSOR_SELECT)) { ui->hpencil = 1 - ui->hpencil; ui->hcursor = 1; return ""; } if (ui->hshow && ((button >= '0' && button <= '9' && button - '0' <= w) || button == CURSOR_SELECT2 || button == '\b')) { int n = button - '0'; if (button == CURSOR_SELECT2 || button == '\b') n = 0; /* * Can't make pencil marks in a filled square. This can only * become highlighted if we're using cursor keys. */ if (ui->hpencil && state->grid[ui->hy*w+ui->hx]) return NULL; /* * Can't do anything to an immutable square. */ if (state->clues->immutable[ui->hy*w+ui->hx]) return NULL; sprintf(buf, "%c%d,%d,%d", (char)(ui->hpencil && n > 0 ? 'P' : 'R'), ui->hx, ui->hy, n); if (!ui->hcursor) ui->hshow = 0; return dupstr(buf); } if (button == 'M' || button == 'm') return dupstr("M"); return NULL; }
int main(){ SetTileTable(tiles); //Set the tileset to use (set this first) SetFontTilesIndex(TILES_SIZE); //Set the tile number in the tilset that contains the first font ClearVram(); //Clear the screen (fills the vram with tile zero) long sectorStart; sdCardInitNoBuffer(); sectorStart = sdCardFindFileFirstSectorFlash(fileName); if(sectorStart == 0){ Print(0,0,PSTR("FILE HELLWRLD.TXT NOT FOUND ON SD CARD")); } else { sdCardCueSectorAddress(sectorStart); /* HELLO WORLD FROM THE SD CARD VERTICAL TEXT DOUBLE SPACES DOUBLE LINE SPACING DOUBLE LINE SPACING DOUBLE LINE SPACING DOUBLE LINE SPACING RUN2SPANXFOR16BITINDEX */ // sdCardDirectReadSimple(uint8_t *dest, uint16_t count); // sdDirectRead(uint8_t *dest, uint16_t count, uint8_t span, uint8_t run); // // // HELLO WORLD FROM THE SD CARD // Read 28 bytes of test straight to VRAM // sdCardDirectReadSimple(address, length) == sdDriectReadSimple(address, length, 0, 0) // That is SPAN = 0 RUN = 0 sdCardDirectReadSimple(&vram[COORD(0,0)], 28); // HELLO WORLD sdCardSkipBytes(1); // Skip the CR/LF // VERTICAL TEXT // SPAN = 39 // RUN = 1 // // Every 1 (RUN) byte skip 39 (SPAN) bytes // // Screen width = 40 so 39 is screen width - 1 sdCardDirectRead(&vram[COORD(0,2)], 13, 39, 1); // VERTICAL TEXT sdCardSkipBytes(1); // Skip the CR/LF // DOUBLE SPACES // SPAN = 1 // RUN = 1 // // Every 1 (RUN) byte skip 1 (SPAN) bytes sdCardDirectRead(&vram[COORD(3,2)], 13, 1, 1); // DOUBLE SPACES sdCardSkipBytes(1); // Skip the CR/LF // DOUBLE SPACES // SPAN = 39 // RUN = 80 // // Every 40 (RUN) bytes skip 39 (SPAN) bytes // 40 is one whole line of text // 39 is (40-1) sdCardDirectRead(&vram[COORD(0,17)], 80, 39, 40); // DOUBLE LINE SPACING sdCardSkipBytes(1); // Skip the CR/LF // 16 bit modes // SPAN = 38 // RUN = 2 // // Every 2 (RUN) bytes skip 38 (SPAN) bytes // 2 bytes = 16 bits. So modes with a 16 bit tile index could use this to fill in a column // 38 is (40-2) sdCardDirectRead(&vram[COORD(20,4)], 22, 38, 2); // 16 BIT MODES } while(1); }
static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate, game_state *state, int dir, game_ui *ui, float animtime, float flashtime) { int i, pass, bgcolour; if (flashtime > 0) { int frame = (int)(flashtime / FLASH_FRAME); bgcolour = (frame % 2 ? COL_LOWLIGHT : COL_HIGHLIGHT); } else bgcolour = COL_BACKGROUND; if (!ds->started) { int coords[10]; draw_rect(dr, 0, 0, TILE_SIZE * state->w + 2 * BORDER, TILE_SIZE * state->h + 2 * BORDER, COL_BACKGROUND); draw_update(dr, 0, 0, TILE_SIZE * state->w + 2 * BORDER, TILE_SIZE * state->h + 2 * BORDER); /* * Recessed area containing the whole puzzle. */ coords[0] = COORD(state->w) + HIGHLIGHT_WIDTH - 1; coords[1] = COORD(state->h) + HIGHLIGHT_WIDTH - 1; coords[2] = COORD(state->w) + HIGHLIGHT_WIDTH - 1; coords[3] = COORD(0) - HIGHLIGHT_WIDTH; coords[4] = coords[2] - TILE_SIZE; coords[5] = coords[3] + TILE_SIZE; coords[8] = COORD(0) - HIGHLIGHT_WIDTH; coords[9] = COORD(state->h) + HIGHLIGHT_WIDTH - 1; coords[6] = coords[8] + TILE_SIZE; coords[7] = coords[9] - TILE_SIZE; draw_polygon(dr, coords, 5, COL_HIGHLIGHT, COL_HIGHLIGHT); coords[1] = COORD(0) - HIGHLIGHT_WIDTH; coords[0] = COORD(0) - HIGHLIGHT_WIDTH; draw_polygon(dr, coords, 5, COL_LOWLIGHT, COL_LOWLIGHT); ds->started = TRUE; } /* * Now draw each tile. We do this in two passes to make * animation easy. */ for (pass = 0; pass < 2; pass++) { for (i = 0; i < state->n; i++) { int t, t0; /* * Figure out what should be displayed at this * location. It's either a simple tile, or it's a * transition between two tiles (in which case we say * -1 because it must always be drawn). */ if (oldstate && oldstate->tiles[i] != state->tiles[i]) t = -1; else t = state->tiles[i]; t0 = t; if (ds->bgcolour != bgcolour || /* always redraw when flashing */ ds->tiles[i] != t || ds->tiles[i] == -1 || t == -1) { int x, y; /* * Figure out what to _actually_ draw, and where to * draw it. */ if (t == -1) { int x0, y0, x1, y1; int j; /* * On the first pass, just blank the tile. */ if (pass == 0) { x = COORD(X(state, i)); y = COORD(Y(state, i)); t = 0; } else { float c; t = state->tiles[i]; /* * Don't bother moving the gap; just don't * draw it. */ if (t == 0) continue; /* * Find the coordinates of this tile in the old and * new states. */ x1 = COORD(X(state, i)); y1 = COORD(Y(state, i)); for (j = 0; j < oldstate->n; j++) if (oldstate->tiles[j] == state->tiles[i]) break; assert(j < oldstate->n); x0 = COORD(X(state, j)); y0 = COORD(Y(state, j)); c = (animtime / ANIM_TIME); if (c < 0.0F) c = 0.0F; if (c > 1.0F) c = 1.0F; x = x0 + (int)(c * (x1 - x0)); y = y0 + (int)(c * (y1 - y0)); } } else { if (pass == 0) continue; x = COORD(X(state, i)); y = COORD(Y(state, i)); } draw_tile(dr, ds, state, x, y, t, bgcolour); } ds->tiles[i] = t0; } } ds->bgcolour = bgcolour; /* * Update the status bar. */ { char statusbuf[256]; /* * Don't show the new status until we're also showing the * new _state_ - after the game animation is complete. */ if (oldstate) state = oldstate; if (state->used_solve) sprintf(statusbuf, "Moves since auto-solve: %d", state->movecount - state->completed); else sprintf(statusbuf, "%sMoves: %d", (state->completed ? "COMPLETED! " : ""), (state->completed ? state->completed : state->movecount)); status_bar(dr, statusbuf); } }
static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate, game_state *state, int dir, game_ui *ui, float animtime, float flashtime) { int w = state->par.w /*, a = w*w */; int i, x, y; if (!ds->started) { /* * The initial contents of the window are not guaranteed and * can vary with front ends. To be on the safe side, all * games should start by drawing a big background-colour * rectangle covering the whole window. */ draw_rect(dr, 0, 0, SIZE(w), SIZE(w), COL_BACKGROUND); draw_update(dr, 0, 0, SIZE(w), SIZE(w)); ds->started = TRUE; } check_errors(state, ds->errtmp); /* * Work out what data each tile should contain. */ for (i = 0; i < (w+2)*(w+2); i++) ds->tiles[i] = 0; /* completely blank square */ /* The clue squares... */ for (i = 0; i < 4*w; i++) { long tile = state->clues->clues[i]; CLUEPOS(x, y, i, w); if (ds->errtmp[(y+1)*(w+2)+(x+1)]) tile |= DF_ERROR; ds->tiles[(y+1)*(w+2)+(x+1)] = tile; } /* ... and the main grid. */ for (y = 0; y < w; y++) { for (x = 0; x < w; x++) { long tile = DF_PLAYAREA; if (state->grid[y*w+x]) tile |= state->grid[y*w+x]; else tile |= (long)state->pencil[y*w+x] << DF_PENCIL_SHIFT; if (ui->hshow && ui->hx == x && ui->hy == y) tile |= (ui->hpencil ? DF_HIGHLIGHT_PENCIL : DF_HIGHLIGHT); if (state->clues->immutable[y*w+x]) tile |= DF_IMMUTABLE; if (flashtime > 0 && (flashtime <= FLASH_TIME/3 || flashtime >= FLASH_TIME*2/3)) tile |= DF_HIGHLIGHT; /* completion flash */ if (ds->errtmp[(y+1)*(w+2)+(x+1)]) tile |= DF_ERROR; ds->tiles[(y+1)*(w+2)+(x+1)] = tile; } } /* * Now actually draw anything that needs to be changed. */ for (y = 0; y < w+2; y++) { for (x = 0; x < w+2; x++) { long tl, tr, bl, br; int i = y*(w+2)+x; tr = ds->tiles[y*(w+2)+x]; tl = (x == 0 ? 0 : ds->tiles[y*(w+2)+(x-1)]); br = (y == w+1 ? 0 : ds->tiles[(y+1)*(w+2)+x]); bl = (x == 0 || y == w+1 ? 0 : ds->tiles[(y+1)*(w+2)+(x-1)]); if (ds->drawn[i*4] != tl || ds->drawn[i*4+1] != tr || ds->drawn[i*4+2] != bl || ds->drawn[i*4+3] != br) { clip(dr, COORD(x-1), COORD(y-1), TILESIZE, TILESIZE); draw_tile(dr, ds, state->clues, x-1, y-1, tr); if (x > 0) draw_tile(dr, ds, state->clues, x-2, y-1, tl); if (y <= w) draw_tile(dr, ds, state->clues, x-1, y, br); if (x > 0 && y <= w) draw_tile(dr, ds, state->clues, x-2, y, bl); unclip(dr); draw_update(dr, COORD(x-1), COORD(y-1), TILESIZE, TILESIZE); ds->drawn[i*4] = tl; ds->drawn[i*4+1] = tr; ds->drawn[i*4+2] = bl; ds->drawn[i*4+3] = br; } } } }
static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate, game_state *state, int dir, game_ui *ui, float animtime, float flashtime) { int i, bgcolour; struct rotation srot, *rot; int lastx = -1, lasty = -1, lastr = -1; int cx, cy, cmoved = 0, n = state->n; cx = ui->cur_visible ? ui->cur_x : -state->n; cy = ui->cur_visible ? ui->cur_y : -state->n; if (cx != ds->cur_x || cy != ds->cur_y) cmoved = 1; if (flashtime > 0) { int frame = (int)(flashtime / FLASH_FRAME); bgcolour = (frame % 2 ? COL_LOWLIGHT : COL_HIGHLIGHT); } else bgcolour = COL_BACKGROUND; if (!ds->started) { int coords[10]; draw_rect(dr, 0, 0, TILE_SIZE * state->w + 2 * BORDER, TILE_SIZE * state->h + 2 * BORDER, COL_BACKGROUND); draw_update(dr, 0, 0, TILE_SIZE * state->w + 2 * BORDER, TILE_SIZE * state->h + 2 * BORDER); /* * Recessed area containing the whole puzzle. */ coords[0] = COORD(state->w) + HIGHLIGHT_WIDTH - 1; coords[1] = COORD(state->h) + HIGHLIGHT_WIDTH - 1; coords[2] = COORD(state->w) + HIGHLIGHT_WIDTH - 1; coords[3] = COORD(0) - HIGHLIGHT_WIDTH; coords[4] = coords[2] - TILE_SIZE; coords[5] = coords[3] + TILE_SIZE; coords[8] = COORD(0) - HIGHLIGHT_WIDTH; coords[9] = COORD(state->h) + HIGHLIGHT_WIDTH - 1; coords[6] = coords[8] + TILE_SIZE; coords[7] = coords[9] - TILE_SIZE; draw_polygon(dr, coords, 5, COL_HIGHLIGHT, COL_HIGHLIGHT); coords[1] = COORD(0) - HIGHLIGHT_WIDTH; coords[0] = COORD(0) - HIGHLIGHT_WIDTH; draw_polygon(dr, coords, 5, COL_LOWLIGHT, COL_LOWLIGHT); ds->started = TRUE; } /* * If we're drawing any rotated tiles, sort out the rotation * parameters, and also zap the rotation region to the * background colour before doing anything else. */ if (oldstate) { float angle; float anim_max = game_anim_length(oldstate, state, dir, ui); if (dir > 0) { lastx = state->lastx; lasty = state->lasty; lastr = state->lastr; } else { lastx = oldstate->lastx; lasty = oldstate->lasty; lastr = -oldstate->lastr; } rot = &srot; rot->cx = COORD(lastx); rot->cy = COORD(lasty); rot->cw = rot->ch = TILE_SIZE * state->n; rot->ox = rot->cx + rot->cw/2; rot->oy = rot->cy + rot->ch/2; angle = (float)((-PI/2 * lastr) * (1.0 - animtime / anim_max)); rot->c = (float)cos(angle); rot->s = (float)sin(angle); /* * Sort out the colours of the various sides of the tile. */ rot->lc = highlight_colour((float)PI + angle); rot->rc = highlight_colour(angle); rot->tc = highlight_colour((float)(PI/2.0) + angle); rot->bc = highlight_colour((float)(-PI/2.0) + angle); draw_rect(dr, rot->cx, rot->cy, rot->cw, rot->ch, bgcolour); } else rot = NULL; /* * Now draw each tile. */ for (i = 0; i < state->w * state->h; i++) { int t, cc = 0; int tx = i % state->w, ty = i / state->w; /* * Figure out what should be displayed at this location. * Usually it will be state->grid[i], unless we're in the * middle of animating an actual rotation and this cell is * within the rotation region, in which case we set -1 * (always display). */ if (oldstate && lastx >= 0 && lasty >= 0 && tx >= lastx && tx < lastx + state->n && ty >= lasty && ty < lasty + state->n) t = -1; else t = state->grid[i]; if (cmoved) { /* cursor has moved (or changed visibility)... */ if (tx == cx || tx == cx+n-1 || ty == cy || ty == cy+n-1) cc = 1; /* ...we're on new cursor, redraw */ if (tx == ds->cur_x || tx == ds->cur_x+n-1 || ty == ds->cur_y || ty == ds->cur_y+n-1) cc = 1; /* ...we were on old cursor, redraw */ } if (ds->bgcolour != bgcolour || /* always redraw when flashing */ ds->grid[i] != t || ds->grid[i] == -1 || t == -1 || cc) { int x = COORD(tx), y = COORD(ty); unsigned cedges = 0; if (tx == cx && ty >= cy && ty <= cy+n-1) cedges |= CUR_LEFT; if (ty == cy && tx >= cx && tx <= cx+n-1) cedges |= CUR_TOP; if (tx == cx+n-1 && ty >= cy && ty <= cy+n-1) cedges |= CUR_RIGHT; if (ty == cy+n-1 && tx >= cx && tx <= cx+n-1) cedges |= CUR_BOTTOM; draw_tile(dr, ds, state, x, y, state->grid[i], bgcolour, rot, cedges); ds->grid[i] = t; } } ds->bgcolour = bgcolour; ds->cur_x = cx; ds->cur_y = cy; /* * Update the status bar. */ { char statusbuf[256]; /* * Don't show the new status until we're also showing the * new _state_ - after the game animation is complete. */ if (oldstate) state = oldstate; if (state->used_solve) sprintf(statusbuf, "Moves since auto-solve: %d", state->movecount - state->completed); else { sprintf(statusbuf, "%sMoves: %d", (state->completed ? "COMPLETED! " : ""), (state->completed ? state->completed : state->movecount)); if (state->movetarget) sprintf(statusbuf+strlen(statusbuf), " (target %d)", state->movetarget); } status_bar(dr, statusbuf); } }