gplanarity-17906/0000755000175000017500000000000011543161637013621 5ustar vincentvincentgplanarity-17906/graph_generate_data.c0000644000175000017500000000440011543161637017727 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include "graph.h" #include "graph_generate.h" typedef struct d_vertex{ int x; int y; } d_vertex; typedef struct d_edge{ int a; int b; } d_edge; typedef struct d_level{ int obj; int less; d_vertex *v; d_edge *e; } d_level; static d_vertex v_level1[] = { {400,30}, {143,216}, {241,518}, {559,518}, {657,216}, {282,138}, {210,362}, {400,500}, {590,362}, {518,138}, {-1,-1}, }; static d_edge e_level1[] = { {0,5}, {5,1}, {0,2}, {0,3}, {0,9}, {9,4}, {1,6}, {6,2}, {1,3}, {1,4}, {2,7}, {7,3}, {2,4}, {3,8}, {8,4},{-1,-1}, }; static d_level leveldata[] = { {1,0,v_level1,e_level1} }; void generate_data(graph *g, int order){ int i; d_level *l = leveldata+order; vertex *vlist; vertex **flat; // scan for number of verticies i=0; while(l->v[i].x != -1)i++; vlist=new_board(g, i); flat = alloca(i*sizeof(*flat)); // build graph from data // add verticies { vertex *v=vlist; i=0; while(v){ v->x = l->v[i].x; v->y = l->v[i].y; flat[i++]=v; v=v->next; } } // add edges { int i=0; while(l->e[i].a != -1){ add_edge(g,flat[l->e[i].a],flat[l->e[i].b]); i++; } } g->objective = l->obj; g->objective_lessthan = l->less; } gplanarity-17906/gameboard_draw_box.c0000644000175000017500000001535411543161637017603 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include "graph.h" #include "gameboard.h" #include "gameboard_draw_button.h" void topbox (Gameboard *g,cairo_t *c, double w, double h){ double x0 = B_BORDER+B_RADIUS; double y0 = B_BORDER; double x1 = B_BORDER; double y1 = B_BORDER+B_RADIUS; double x2 = B_BORDER; double y2 = h-B_BORDER-B_RADIUS; double x3 = B_BORDER+B_RADIUS; double y3 = h-B_BORDER; double x4 = w/2 - B_HUMP - B_RADIUS; double y4 = h-B_BORDER; double x5 = x4+B_RADIUS; double y5 = y4; double x7 = w/2 + B_HUMP + B_RADIUS; double y7 = h-B_BORDER; double x8 = w - B_BORDER -B_RADIUS; double y8 = h-B_BORDER; double x9 = w - B_BORDER; double y9 = h-B_BORDER-B_RADIUS; double x10 = w - B_BORDER; double y10 = B_BORDER+B_RADIUS; double x11 = w - B_BORDER-B_RADIUS; double y11 = B_BORDER; cairo_set_line_width(c,B_LINE); cairo_move_to (c, x0, y0); cairo_curve_to (c, x1,y0, x1,y0, x1,y1); cairo_line_to (c, x2,y2); cairo_curve_to (c, x2,y3, x2,y3, x3,y3); cairo_line_to (c, x4,y4); { double hh = g->g.orig_height*.5+50; double radius = sqrt( (w*.5-x5) * (w*.5-x5) + (hh-y5) * (hh-y5)); double siderad = atan( (x5-w*.5)/(hh-y5)); double xx = sin(siderad+.05)*radius+w*.5; double yy = -cos(siderad+.05)*radius+hh; double x = sin(siderad+.1)*radius+w*.5; double y = -cos(siderad+.1)*radius+hh; cairo_curve_to (c, x4+B_RADIUS,y4, xx,yy, x,y); cairo_arc(c,w*.5,hh,radius,-M_PI*.5+siderad+.1,-M_PI*.5-siderad-.1); xx = -sin(siderad+.05)*radius+w*.5; yy = -cos(siderad+.05)*radius+hh; xx = -sin(siderad+.1)*radius+w*.5; yy = -cos(siderad+.1)*radius+hh; cairo_curve_to (c, xx,yy, x7-B_RADIUS,y7, x7,y7); } cairo_line_to (c, x8,y8); cairo_curve_to (c, x9,y8, x9,y8, x9,y9); cairo_line_to (c, x10,y10); cairo_curve_to (c, x10,y11, x10,y11, x11,y11); cairo_close_path (c); cairo_set_source_rgba (c, B_COLOR); cairo_fill_preserve (c); cairo_set_source_rgba (c, B_LINE_COLOR); cairo_stroke (c); } void bottombox (Gameboard *g, cairo_t *c, double w, double h){ double x0 = B_BORDER+B_RADIUS; double y0 = h-B_BORDER; double x1 = B_BORDER; double y1 = h-B_BORDER-B_RADIUS; double x2 = B_BORDER; double y2 = B_BORDER+B_RADIUS; double x3 = B_BORDER+B_RADIUS; double y3 = B_BORDER; double x4 = w/2 - B_HUMP - B_RADIUS; double y4 = B_BORDER; double x5 = x4+B_RADIUS; double y5 = y4; double x7 = w/2 + B_HUMP + B_RADIUS; double y7 = B_BORDER; double x8 = w - B_BORDER -B_RADIUS; double y8 = B_BORDER; double x9 = w - B_BORDER; double y9 = B_BORDER+B_RADIUS; double x10 = w - B_BORDER; double y10 = h- B_BORDER -B_RADIUS; double x11 = w - B_BORDER-B_RADIUS; double y11 = h-B_BORDER; cairo_set_line_width(c,B_LINE); cairo_move_to (c, x0, y0); cairo_curve_to (c, x1,y0, x1,y0, x1,y1); cairo_line_to (c, x2,y2); cairo_curve_to (c, x2,y3, x2,y3, x3,y3); cairo_line_to (c, x4,y4); { double hh = g->g.orig_height*.5+50; double radius = sqrt( (w*.5-x5) * (w*.5-x5) + (y5+hh-h) * (y5+hh-h)); double siderad = atan( (x5-w*.5)/(y5+hh-h)); double xx = sin(siderad+.05)*radius+w*.5; double yy = cos(siderad+.05)*radius-hh+h; double x = sin(siderad+.1)*radius+w*.5; double y = cos(siderad+.1)*radius-hh+h; cairo_curve_to (c, x4+B_RADIUS,y4, xx,yy, x,y); cairo_arc_negative(c,w*.5,h-hh,radius,M_PI*.5-siderad-.1,M_PI*.5+siderad+.1); xx = -sin(siderad+.05)*radius+w*.5; yy = cos(siderad+.05)*radius-hh+h; xx = -sin(siderad+.1)*radius+w*.5; yy = cos(siderad+.1)*radius-hh+h; cairo_curve_to (c, xx,yy, x7-B_RADIUS,y7, x7,y7); } cairo_line_to (c, x8,y8); cairo_curve_to (c, x9,y8, x9,y8, x9,y9); cairo_line_to (c, x10,y10); cairo_curve_to (c, x10,y11, x10,y11, x11,y11); cairo_close_path (c); cairo_set_source_rgba (c, B_COLOR); cairo_fill_preserve (c); cairo_set_source_rgba (c, B_LINE_COLOR); cairo_stroke (c); } void centerbox (cairo_t *c, int x, int y, double w, double h){ double x0 = B_BORDER+B_RADIUS; double y0 = h-B_BORDER; double x1 = B_BORDER; double y1 = h-B_BORDER-B_RADIUS; double x2 = B_BORDER; double y2 = B_BORDER+B_RADIUS; double x3 = B_BORDER+B_RADIUS; double y3 = B_BORDER; double x8 = w - B_BORDER -B_RADIUS; double y8 = B_BORDER; double x9 = w - B_BORDER; double y9 = B_BORDER+B_RADIUS; double x10 = w - B_BORDER; double y10 = h- B_BORDER -B_RADIUS; double x11 = w - B_BORDER-B_RADIUS; double y11 = h-B_BORDER; cairo_save(c); cairo_translate(c,x,y); cairo_set_line_width(c,B_LINE); cairo_move_to (c, x0, y0); cairo_curve_to (c, x1,y0, x1,y0, x1,y1); cairo_line_to (c, x2,y2); cairo_curve_to (c, x2,y3, x2,y3, x3,y3); cairo_line_to (c, x8,y8); cairo_curve_to (c, x9,y8, x9,y8, x9,y9); cairo_line_to (c, x10,y10); cairo_curve_to (c, x10,y11, x10,y11, x11,y11); cairo_close_path (c); cairo_set_source_rgba (c, B_COLOR); cairo_fill_preserve (c); cairo_set_source_rgba (c, B_LINE_COLOR); cairo_stroke (c); cairo_restore(c); } void borderbox_path (cairo_t *c, double x, double y, double w, double h){ double x0 = x+ B_RADIUS; double y0 = y+ h; double x1 = x; double y1 = y+ h-B_RADIUS; double x2 = x; double y2 = y+ B_RADIUS; double x3 = x+ B_RADIUS; double y3 = y; double x8 = x+ w -B_RADIUS; double y8 = y; double x9 = x+ w; double y9 = y+ B_RADIUS; double x10 = x+ w; double y10 = y+ h -B_RADIUS; double x11 = x+ w -B_RADIUS; double y11 = y+h; cairo_move_to (c, x0, y0); cairo_curve_to (c, x1,y0, x1,y0, x1,y1); cairo_line_to (c, x2,y2); cairo_curve_to (c, x2,y3, x2,y3, x3,y3); cairo_line_to (c, x8,y8); cairo_curve_to (c, x9,y8, x9,y8, x9,y9); cairo_line_to (c, x10,y10); cairo_curve_to (c, x10,y11, x10,y11, x11,y11); cairo_close_path (c); } gplanarity-17906/graph_generate_mesh1.c0000644000175000017500000005225211543161637020043 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include #include "graph.h" #include "random.h" #include "gameboard.h" #include "graph_generate.h" #include "graph_arrange.h" typedef struct { vertex **v; edge_list *embed_list; int width; int height; } mesh; typedef struct { int vnum[8]; vertex *center; mesh *m; } neighbors_grid; typedef struct { int vnum[8]; int num; } neighbors_list; /* The 'embed_list' is a set of edges that don't obey or neighboring intersection calculation mode and are thus tracked seperately/explicitly. They're added to the main graph after the rest of the graph is generated. */ /* add edge to the embed_list */ static void embedlist_add_edge(mesh *m, vertex *A, vertex *B){ edge *e = new_edge(A,B); m->embed_list = add_edge_to_list(m->embed_list,e); } /* move embed_list edges into the real graph */ static void embedlist_add_to_mesh(graph *g, mesh *m){ edge_list *el = m->embed_list; /* move the edges out of the embed_list and add them to the main graph */ while(el){ edge *e = el->edge; el->edge = 0; insert_edge(g,e); el=el->next; } release_edge_list(m->embed_list); m->embed_list=0; /* be pedantic */ } static int embedlist_intersects(mesh *m, vertex *A, vertex *B){ edge_list *el = m->embed_list; double dummy_x,dummy_y; while(el){ edge *e = el->edge; if(intersectsV(A,B,e->A,e->B,&dummy_x,&dummy_y)) return 1; el=el->next; } return 0; } static void embedlist_filter_intersections(neighbors_grid *ng){ int i; vertex *A = ng->center; for(i=0;i<8;i++){ if(ng->vnum[i] != -1){ vertex *B = ng->m->v[ng->vnum[i]]; if(embedlist_intersects(ng->m,A,B)) ng->vnum[i]=-1; } } } static int embedlist_contains_vertex(mesh *m,vertex *v){ edge_list *el = m->embed_list; while(el){ edge *e = el->edge; if(e->A == v) return 1; if(e->B == v) return 1; el=el->next; } return 0; } static int embedlist_vertex_poisoned(mesh *m, vertex *v){ return v->selected; } static void poison_vertex(mesh *m, vertex *v){ v->selected=1; } /* neighboring intersection model */ static void populate_neighbors(int vnum, mesh *m, neighbors_grid *ng){ int width = m->width; int y = vnum/width; int x = vnum - (y*width); int i; for(i=0;i<8;i++)ng->vnum[i]=-1; ng->center = m->v[vnum]; ng->m = m; if(y-1 >= 0){ if(x-1 >= 0) ng->vnum[0]= (y-1)*width+(x-1); ng->vnum[1]= (y-1)*width+x; if(x+1 < m->width) ng->vnum[2]= (y-1)*width+(x+1); } if(x-1 >= 0) ng->vnum[3]= y*width+(x-1); if(x+1 < m->width) ng->vnum[4]= y*width+(x+1); if(y+1 < m->height){ if(x-1 >= 0) ng->vnum[5]= (y+1)*width+(x-1); ng->vnum[6]= (y+1)*width+x; if(x+1 < m->width) ng->vnum[7]= (y+1)*width+(x+1); } } // eliminate from neighbor structs the verticies that already have at // least one edge static void filter_spanned_neighbors(neighbors_grid *ng, neighbors_list *nl){ int i; int count=0; for(i=0;i<8;i++) if(ng->vnum[i]==-1 || ng->m->v[ng->vnum[i]]->edges){ ng->vnum[i]=-1; }else{ nl->vnum[count++]=ng->vnum[i]; } nl->num=count; } // eliminate from neighbor struct any verticies to which we can't make // an edge without crossing another edge. Only 0,2,5,7 possible. static void filter_intersections(neighbors_grid *ng){ int i; for(i=0;i<8;i++){ switch(i){ case 0: if(ng->vnum[1] != -1 && ng->vnum[3] != -1 && exists_edge(ng->m->v[ng->vnum[1]], ng->m->v[ng->vnum[3]])) ng->vnum[i]=-1; break; case 2: if(ng->vnum[1] != -1 && ng->vnum[4] != -1 && exists_edge(ng->m->v[ng->vnum[1]], ng->m->v[ng->vnum[4]])) ng->vnum[i]=-1; break; case 5: if(ng->vnum[3] != -1 && ng->vnum[6] != -1 && exists_edge(ng->m->v[ng->vnum[3]], ng->m->v[ng->vnum[6]])) ng->vnum[i]=-1; break; case 7: if(ng->vnum[4] != -1 && ng->vnum[6] != -1 && exists_edge(ng->m->v[ng->vnum[4]], ng->m->v[ng->vnum[6]])) ng->vnum[i]=-1; break; } } embedlist_filter_intersections(ng); } /* eliminate verticies we've already connected to */ static void filter_edges(neighbors_grid *ng, neighbors_list *nl){ vertex *v=ng->center; int count=0,i; for(i=0;i<8;i++){ if(ng->vnum[i]!=-1){ if(!exists_edge(v,ng->m->v[ng->vnum[i]])) nl->vnum[count++]=ng->vnum[i]; else ng->vnum[i]=-1; } } nl->num=count; } static void random_populate(graph *g, int current, mesh *m, int min_connect, int prob_128){ int num_edges=0,i; neighbors_grid ng; neighbors_list nl; populate_neighbors(current, m, &ng); filter_intersections(&ng); filter_edges(&ng,&nl); { edge_list *el=m->v[current]->edges; while(el){ num_edges++; el=el->next; } } while(num_edgesv[current], m->v[nl.vnum[choice]]); num_edges++; filter_intersections(&ng); filter_edges(&ng,&nl); } for(i=0;iv[current], m->v[nl.vnum[i]]); } } static void span_depth_first(graph *g,int current, mesh *m){ neighbors_grid ng; neighbors_list nl; while(1){ populate_neighbors(current, m, &ng); // don't reverse the order of the next two filter_intersections(&ng); filter_spanned_neighbors(&ng,&nl); if(nl.num == 0) break; { int choice = random_number() % nl.num; add_edge(g,m->v[current], m->v[nl.vnum[choice]]); span_depth_first(g,nl.vnum[choice], m); } } } /* nastiness adds long edges along the outer perimeter to make it harder to rely on verticies always being near each other; mesh 2 takes this further, but we can add some of the same flavor to mesh1. */ static void nasty_horizontal(graph *g, mesh *m, int A, int B, int limit){ if(limit == 0) return; if(A+2 > B)return; /* adjacent is too close */ add_edge(g,m->v[A],m->v[B]); A++; B--; nasty_horizontal(g,m,A,B,limit-1); } static void nasty_vertical(graph *g, mesh *m, int A, int B, int limit){ if(limit == 0) return; if(A+(m->width*2) > B)return; /* adjacent is too close */ add_edge(g,m->v[A],m->v[B]); A+=m->width; B-=m->width; nasty_vertical(g,m,A,B,limit-1); } /* Don't use this along with k5 embedding; the assumptions the nastiness algorithm makes about solvable conditions won't always coexist with the assumptions the k5 embedding makes about solvable conditions. */ static void mesh_nastiness(graph *g, mesh *m, int limit){ nasty_horizontal(g,m,0,m->width-1, limit); nasty_horizontal(g,m,(m->height-1)*m->width,m->width*m->height-1, limit); nasty_vertical(g,m,0,(m->height-1)*m->width,limit); nasty_vertical(g,m,m->width-1,m->width*m->height-1, limit); } /* Embed one k5 in the solved graph */ /* Don't use this along with 'nastiness'; the assumptions the nastiness algorithm makes about solvable conditions won't always coexist with the assumptions that non-planar embedding makes about solvable conditions. */ static void mesh_embed_k5(graph *g, mesh *m,int x, int y){ /* Add the k5s up front in their own special edge list; This list will also be checked explicitly by the various neighboring algorithms as the k5's edges don't all conceptually work within the implicit neighboring algorithm we're using. Also, by using a special edge list and not adding the k5 edges to the vertex edge lists up front, we can still use the unmodified initial spanning walk algorithm. */ int w = m->width; vertex *A = m->v[y*w+x+1]; vertex *B = m->v[(y+1)*w+x+1]; vertex *C = m->v[(y+1)*w+x+2]; vertex *D = m->v[(y+1)*w+x+3]; vertex *E = m->v[(y+2)*w+x]; // poisoned verticies are already inside another kernel (the regular // mesh is deflectable and thus not really regular) if(embedlist_vertex_poisoned(m,A))return; if(embedlist_vertex_poisoned(m,B))return; if(embedlist_vertex_poisoned(m,C))return; if(embedlist_vertex_poisoned(m,D))return; if(embedlist_vertex_poisoned(m,E))return; // the way k5 works we don't need to poison the internal verticies embedlist_add_edge(m, A,B); embedlist_add_edge(m, A,C); embedlist_add_edge(m, A,D); embedlist_add_edge(m, A,E); embedlist_add_edge(m, B,C); embedlist_add_edge(m, B,D); embedlist_add_edge(m, B,E); embedlist_add_edge(m, C,D); embedlist_add_edge(m, C,E); embedlist_add_edge(m, D,E); g->objective++; } /* Embed one k3,3 in the solved graph */ /* Don't use this along with 'nastiness'; the assumptions the nastiness algorithm makes about solvable conditions won't always coexist with the assumptions that k5 embedding makes about solvable conditions. */ static void mesh_embed_k33(graph *g, mesh *m, int x, int y){ /* same disclaimers as k5 */ /* the k3,3 embedding works with the standard walk algorithm only because an edge with an endpoint exactly on another edge is considered an intersection. */ /* the way it is added, the walk/population can add additional edges inside the embedded kernel; this is fine, the population will be certain not to introduce intersections. */ int w = m->width; vertex *A = m->v[y*w+x]; vertex *B = m->v[y*w+x+1]; vertex *C = m->v[y*w+x+2]; vertex *D = m->v[(y+1)*w+x]; vertex *E = m->v[(y+1)*w+x+1]; vertex *F = m->v[(y+1)*w+x+2]; // poisoned verticies are already inside another kernel (the regular // mesh is deflectable and thus not really regular) if(embedlist_vertex_poisoned(m,A))return; if(embedlist_vertex_poisoned(m,B))return; if(embedlist_vertex_poisoned(m,C))return; if(embedlist_vertex_poisoned(m,D))return; if(embedlist_vertex_poisoned(m,E))return; if(embedlist_vertex_poisoned(m,F))return; // check that verticies we want to poison ourselves are not already in use if(embedlist_contains_vertex(m,B))return; if(embedlist_contains_vertex(m,E))return; /* B and E are internal according to x/y, but according to the position in the mesh, they're on the outside. Poison them so that they're explicitly marked inside. */ poison_vertex(m,B); poison_vertex(m,E); /* need to mode two of the intersections to avoid unwanted intersections (not spurious; they are in fact intersections until moved) */ B->y+=2; E->y-=2; embedlist_add_edge(m, A,C); embedlist_add_edge(m, A,D); embedlist_add_edge(m, A,E); embedlist_add_edge(m, B,C); embedlist_add_edge(m, B,D); embedlist_add_edge(m, B,E); embedlist_add_edge(m, C,F); embedlist_add_edge(m, D,F); embedlist_add_edge(m, E,F); g->objective++; } /* Embed one non-miminal k3,3 in the solved graph */ /* Don't use this along with 'nastiness'; the assumptions the nastiness algorithm makes about solvable conditions won't always coexist with the assumptions that k5 embedding makes about solvable conditions. */ static void mesh_embed_bigk33(graph *g, mesh *m, int x, int y){ /* as above */ int w = m->width; vertex *A = m->v[(y+2)*w+x]; vertex *B = m->v[(y+1)*w+x+2]; vertex *C = m->v[y*w+x+4]; vertex *D = m->v[(y+4)*w+x+1]; vertex *E = m->v[(y+3)*w+x+3]; vertex *F = m->v[(y+2)*w+x+5]; // poisoned verticies are already inside another kernel (the regular // mesh is deflectable and thus not really regular) if(embedlist_vertex_poisoned(m,A))return; if(embedlist_vertex_poisoned(m,B))return; if(embedlist_vertex_poisoned(m,C))return; if(embedlist_vertex_poisoned(m,D))return; if(embedlist_vertex_poisoned(m,E))return; if(embedlist_vertex_poisoned(m,F))return; // check that verticies we want to poison ourselves are not already in use if(embedlist_contains_vertex(m,B))return; if(embedlist_contains_vertex(m,E))return; /* B and E are internal according to x/y, but according to the position in the mesh, they're on the outside. Poison them so that they're explicitly marked inside. */ poison_vertex(m,B); poison_vertex(m,E); /* need to move two of the intersections to avoid unwanted intersections (not spurious; they are in fact intersections until moved) */ B->y+=2; E->y-=2; embedlist_add_edge(m, A,C); embedlist_add_edge(m, A,D); embedlist_add_edge(m, A,E); embedlist_add_edge(m, B,C); embedlist_add_edge(m, B,D); embedlist_add_edge(m, B,E); embedlist_add_edge(m, C,F); embedlist_add_edge(m, D,F); embedlist_add_edge(m, E,F); g->objective++; } static void mesh_embed_recurse(graph *g,mesh *m,int x, int y, int w, int h, int k5, int k33, int bigk33){ int xd,yd,wd,hd; // not minimal spacing; the k33 needs vertical offset, but the others are larger just to space them out. if( bigk33 && w>=6 && h>=5 ){ wd = 5; hd = 4; xd = random_number() % (w-wd); yd = random_number() % (h-hd); mesh_embed_bigk33(g,m,x+xd,y+yd); }else if(k5 && w>=4 && h>=3){ wd = 3; hd = 2; xd = random_number() % (w-wd); yd = random_number() % (h-hd); mesh_embed_k5(g,m,x+xd,y+yd); }else if(k33 && w>=3 && h>=2 ){ wd = 2; hd = 1; xd = random_number() % (w-wd); yd = random_number() % (h-hd); mesh_embed_k33(g,m,x+xd,y+yd); }else return; mesh_embed_recurse(g,m, x, y, w, yd+1, k5,k33,bigk33); mesh_embed_recurse(g,m, x, y+yd+hd, w, h-yd-hd, k5,k33,bigk33); mesh_embed_recurse(g,m, x, y+yd, xd+1, hd+1, k5,k33,bigk33); mesh_embed_recurse(g,m, x+xd+wd,y+yd, w-xd-wd, hd+1, k5,k33,bigk33); } /* Embed k5s and k3,3s in the solved graph in such a way that we know each added non-planar kernel adds exactly one and only one certain intersection. */ /* Don't use this along with 'nastiness'; the assumptions the nastiness algorithm makes about solvable conditions won't always coexist with the assumptions that non-planar embedding makes about solvable conditions. */ static void mesh_embed_nonplanar(graph *g, mesh *m,int k5, int k33, int bigk33){ // selection is used as a poison flag during embedding deselect_verticies(g); mesh_embed_recurse(g, m, 0,0,m->width,m->height, k5,k33,bigk33); deselect_verticies(g); } /* Rogues are added lines inserted between verticies on neighboring rows/columns; the idea is to choose the longest ones that cross the smallest number of lines. */ /* Right now, the rogue insertion doesn't take embedded kernel poisoning or niceness constraints into account, so don't mix them */ static int count_intersections(graph *g, vertex *A, vertex *B){ edge *e=g->edges; double dummy_x,dummy_y; int count=0; while(e){ if(intersectsV(A,B,e->A,e->B,&dummy_x,&dummy_y)) count++; e=e->next; } return count; } static void scan_rogue(graph *g, mesh *m, int aoff,int boff, int step, int end, float *metric, edge *best, int *cross){ int a,b; for(a=0;a+1v[a*step+aoff]; vertex *vb = m->v[b*step+boff]; if(!va->selected && !vb->selected){ if(!exists_edge(va,vb)){ int count = count_intersections(g,va,vb); if(count){ float test = (b-a)/count; if(test>=*metric){ *metric=test; best->A=va; best->B=vb; *cross=count; } } } } } } } /* scan the entire mesh looking for the candidate edge with the highest rogue objective value */ static void mesh_add_rogues(graph *g, mesh *m){ int w = m->width; int h = m->height; deselect_verticies(g); while(1){ int i; edge best; float metric=2.1; int cross = 0; best.A=0; best.B=0; for(i=0;i+1selected=1; best.B->selected=1; g->objective+=cross; g->objective_lessthan = 1; }else{ break; } } deselect_verticies(g); } /* Initial generation setup */ static void mesh_setup(graph *g, mesh *m, int order, int divis){ int flag=0; int wiggle=0; int n; m->width=3; m->height=2; { while(--order){ if(flag){ flag=0; m->height+=1; }else{ flag=1; m->width+=2; } } } n=m->width*m->height; // is this divisible by our requested divisor if any? if(divis>0 && n%divis){ while(1){ wiggle++; if(!((n+wiggle)%divis)) break; if(n-wiggle>6 && !((n-wiggle)%divis)){ wiggle = -wiggle; break; } } // refactor the rectangular mesh's dimensions. { int h = (int)sqrt(n+wiggle),w; while( (n+wiggle)%h )h--; if(h==1){ // double it and be content with a working result h=2; w=(n+wiggle); }else{ // good factoring w = (n+wiggle)/h; } m->width=w; m->height=h; } } new_board(g, m->width * m->height); m->embed_list=0; // used for rogue calcs { int x,y; vertex *v = g->verticies; for(y=0;yheight;y++) for(x=0;xwidth;x++){ v->x=x*50; // not a random number; other things depend on this v->y=y*50; // not a random number; other things depend on this v=v->next; } } g->objective = 0; g->objective_lessthan = 0; } static void mesh_flatten(graph *g,mesh *m){ /* a flat vector is easier to address while building the mesh */ int i; vertex *v=g->verticies; for(i=0;iwidth*m->height;i++){ m->v[i]=v; v=v->next; } } static void generate_mesh(graph *g, mesh *m, int density_128){ /* first walk a random spanning tree */ span_depth_first(g, 0, m); /* now iterate the whole mesh adding random edges */ { int i; for(i=0;iwidth*m->height;i++) random_populate(g, i, m, 2, density_128); } } void generate_simple(graph *g, int order){ mesh m; random_seed(order); mesh_setup(g,&m, order, 0); m.v=alloca(m.width*m.height * sizeof(*m.v)); mesh_flatten(g,&m); generate_mesh(g,&m,40); randomize_verticies(g); if((m.width*m.height)&1) arrange_verticies_circle(g,0,0); else arrange_verticies_circle(g,M_PI/2,M_PI/2); } void generate_sparse(graph *g, int order){ mesh m; random_seed(order); mesh_setup(g,&m, order, 3); m.v=alloca(m.width*m.height * sizeof(*m.v)); mesh_flatten(g,&m); generate_mesh(g,&m,2); mesh_nastiness(g,&m,-1); randomize_verticies(g); if((m.width*m.height)&1) arrange_verticies_circle(g,0,0); else arrange_verticies_circle(g,M_PI/2,M_PI/2); } void generate_dense(graph *g, int order){ mesh m; random_seed(order); mesh_setup(g,&m, order, 3); m.v=alloca(m.width*m.height * sizeof(*m.v)); mesh_flatten(g,&m); generate_mesh(g,&m,96); mesh_nastiness(g,&m,-1); randomize_verticies(g); if((m.width*m.height)&1) arrange_verticies_circle(g,0,0); else arrange_verticies_circle(g,M_PI/2,M_PI/2); } void generate_nasty(graph *g, int order){ mesh m; random_seed(order+8236); mesh_setup(g,&m, order,4); m.v=alloca(m.width*m.height * sizeof(*m.v)); mesh_flatten(g,&m); generate_mesh(g,&m,32); mesh_nastiness(g,&m,-1); randomize_verticies(g); arrange_verticies_polycircle(g,3,0,.3,25,0,25); } void generate_rogue(graph *g, int order){ mesh m; random_seed(order+3005); mesh_setup(g,&m, order,5); m.v=alloca(m.width*m.height * sizeof(*m.v)); mesh_flatten(g,&m); generate_mesh(g,&m,24); mesh_add_rogues(g,&m); randomize_verticies(g); if(order*.03<.3) arrange_verticies_polycircle(g,5,0,order*.03,0,0,0); else arrange_verticies_polycircle(g,5,0,.3,0,0,0); } void generate_embed(graph *g, int order){ mesh m; random_seed(order+347); mesh_setup(g,&m, order, 6); m.v=alloca(m.width*m.height * sizeof(*m.v)); mesh_flatten(g,&m); mesh_embed_nonplanar(g,&m,1,1,1); generate_mesh(g,&m,48); embedlist_add_to_mesh(g,&m); randomize_verticies(g); if(order*.03<.3) arrange_verticies_polycircle(g,6,0,order*.03,0,0,0); else arrange_verticies_polycircle(g,6,0,.3,0,0,0); } void generate_crest(graph *g, int order){ int n; mesh m; random_seed(order); mesh_setup(g,&m, order,0); m.v=alloca(m.width*m.height * sizeof(*m.v)); mesh_flatten(g,&m); generate_mesh(g,&m,128); n=m.width*m.height; arrange_verticies_circle(g,M_PI/n,M_PI/n); } gplanarity-17906/gameboard_logic_buttonbar.c0000644000175000017500000001234111543161637021144 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include #include #include "nls.h" #include "graph.h" #include "timer.h" #include "gameboard.h" #include "gameboard_draw_button.h" #include "gameboard_logic_buttonbar.h" #include "dialog_finish.h" #include "dialog_pause.h" #include "dialog_level.h" /************************ the lower button bar *********************/ /* initialize the rather weird little animation engine */ void setup_buttonbar(Gameboard *g){ buttonstate *states=g->b.states; int xcount=BUTTONBAR_BORDER; int dcount=0; int i; int w=g->g.width; int h=g->g.height; states[0].rollovertext=_("exit gPlanarity"); states[1].rollovertext=_("level selection menu"); states[2].rollovertext=_("reset board"); states[3].rollovertext=_("pause"); states[4].rollovertext=_("help / about"); states[5].rollovertext=_("expand"); states[6].rollovertext=_("shrink"); states[7].rollovertext=_("hide/show lines"); states[8].rollovertext=_("mark intersections"); states[9].rollovertext=_("click when finished!"); states[0].callback = quit_action; states[1].callback = level_action; states[2].callback = reset_action; states[3].callback = pause_action; states[4].callback = about_action; states[5].callback = expand_action; states[6].callback = shrink_action; states[7].callback = toggle_hide_lines; states[8].callback = toggle_show_intersections; states[9].callback = finish_action; for(i=0;iposition == 1){ b->x = b->x_target = xcount; b->y_active = h - BUTTONBAR_Y_FROM_BOTTOM; b->y = b->y_target = b->y_inactive = h - BUTTONBAR_Y_FROM_BOTTOM + BUTTON_EXPOSE; b->sweepdeploy = dcount; xcount += BUTTONBAR_SPACING; dcount += SWEEP_DELTA; rollover_extents(g,states+i); } } xcount = w-BUTTONBAR_BORDER; dcount = 0; for(i=NUMBUTTONS-1;i>=0;i--){ buttonstate *b=states+i; if(b->position == 3){ b->x = b->x_target = xcount; b->y_active = h - BUTTONBAR_Y_FROM_BOTTOM; b->y = b->y_target = b->y_inactive = h - BUTTONBAR_Y_FROM_BOTTOM + BUTTON_EXPOSE; b->sweepdeploy = dcount; if(i!=9 || g->checkbutton_deployed){ // special-case the checkbutton xcount -= BUTTONBAR_SPACING; dcount += SWEEP_DELTA; }else{ states[9].position = -3; //deactivate it for the deploy } rollover_extents(g,states+i); } } } /* effects animated 'rollout' of buttons when level begins */ void deploy_buttonbar(Gameboard *g){ if(!g->b.buttons_ready ){ if(g->g.active_intersections <= g->g.objective) g->checkbutton_deployed=1; else g->checkbutton_deployed=0; setup_buttonbar(g); deploy_buttons(g,0); } } /* effects animated rollout of 'check' button */ void deploy_check(Gameboard *g){ buttonstate *states=g->b.states; if(g->b.buttons_ready && !g->checkbutton_deployed){ int i; for(i=5;i<9;i++){ states[i].x_target-=BUTTONBAR_SPACING; states[i].sweepdeploy += SWEEP_DELTA; } states[9].position = 3; //activate it states[9].y_target = states[9].y_active; states[i].sweepdeploy = 0; if(g->button_timer!=0) g_source_remove(g->button_timer); g->button_callback=0; g->button_timer = g_timeout_add(BUTTON_ANIM_INTERVAL, animate_button_frame, (gpointer)g); g->checkbutton_deployed=1; } } /* effects animated rollback of 'check' button */ void undeploy_check(Gameboard *g){ buttonstate *states=g->b.states; if(g->checkbutton_deployed){ int i; for(i=5;i<9;i++){ states[i].x_target+=BUTTONBAR_SPACING; states[i].sweepdeploy -= SWEEP_DELTA; } states[9].y_target=states[9].y_inactive; if(g->button_timer!=0) g_source_remove(g->button_timer); g->button_callback=0; g->button_timer = g_timeout_add(BUTTON_ANIM_INTERVAL, animate_button_frame, (gpointer)g); g->checkbutton_deployed=0; } } gplanarity-17906/dialog_finish.h0000644000175000017500000000220111543161637016564 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define FINISH_BUTTON_BORDER 35 #define FINISH_BUTTON_Y 25 #define FINISHBOX_WIDTH 270 #define FINISHBOX_HEIGHT 330 extern void finish_level_dialog(Gameboard *g); gplanarity-17906/graph_arrange.h0000644000175000017500000000401311543161637016570 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ extern void arrange_verticies_circle(graph *g, float off1, float off2); extern void arrange_verticies_polygon(graph *g, int sides, float angle, float rad, int xoff, int yoff, float xa, float ya); extern void arrange_verticies_polycircle(graph *g, int sides, float angle, float split, int radplus,int xoff,int yoff); extern void arrange_verticies_mesh(graph *g, int width, int height); extern void arrange_verticies_nastymesh(graph *g, int w, int h, vertex **flat); extern void arrange_region_star(graph *g); extern void arrange_region_rainbow(graph *g); extern void arrange_region_dashed_circle(graph *g); extern void arrange_region_bifur(graph *g); extern void arrange_region_dairyqueen(graph *g); extern void arrange_region_cloud(graph *g); extern void arrange_region_ring(graph *g); extern void arrange_region_storm(graph *g); extern void arrange_region_target(graph *g); extern void arrange_region_plus(graph *g); extern void arrange_region_hole3(graph *g); extern void arrange_region_hole4(graph *g); extern void arrange_region_ovals(graph *g); gplanarity-17906/gameboard_draw_button.c0000644000175000017500000001506611543161637020326 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include "graph.h" #include "gameboard.h" #include "gameboard_draw_button.h" /************************* simple round icon drawing *********************/ void path_button_help(cairo_t *c, double x, double y){ cairo_save(c); cairo_translate(c,x,y); cairo_set_fill_rule(c,CAIRO_FILL_RULE_EVEN_ODD); cairo_set_line_width(c,1); cairo_arc(c,0,0,14,0,2*M_PI); cairo_move_to(c,-9,-2); cairo_curve_to(c,-8,-7, -4.5,-12, 0,-12); cairo_curve_to(c, 7,-12, 9,-6, 9,-4); cairo_curve_to(c, 9,0 ,6,2, 5,2); cairo_curve_to(c, 4,2, 2.5,3, 2.5,6); cairo_line_to(c,-2.5,6); cairo_curve_to(c,-2.5,3, -3,1, 0,-1); cairo_curve_to(c, 11,-4, -3,-12, -4,-2); cairo_close_path(c); cairo_move_to(c,-2.5,8); cairo_line_to(c,2.5,8); cairo_line_to(c,2.5,12); cairo_line_to(c,-2.5,12); cairo_close_path(c); cairo_fill_preserve(c); cairo_restore(c); } void path_button_pause(cairo_t *c, double x, double y){ cairo_save(c); cairo_translate(c,x,y); cairo_set_fill_rule(c,CAIRO_FILL_RULE_EVEN_ODD); cairo_set_line_width(c,1); cairo_arc(c,0,0,14,0,2*M_PI); cairo_rectangle(c,-7,-9,5,18); cairo_rectangle(c,2,-9,5,18); cairo_fill_preserve(c); cairo_restore(c); } void path_button_exit(cairo_t *c, double x, double y){ cairo_save(c); cairo_translate(c,x,y); cairo_set_fill_rule(c,CAIRO_FILL_RULE_EVEN_ODD); cairo_set_line_width(c,1); cairo_arc(c,0,0,14,0,2*M_PI); cairo_move_to(c,-6,-9.5); cairo_line_to(c,0,-3.5); cairo_line_to(c,6,-9.5); cairo_line_to(c,9.5,-6); cairo_line_to(c,3.5,0); cairo_line_to(c,9.5,6); cairo_line_to(c,6,9.5); cairo_line_to(c,0,3.5); cairo_line_to(c,-6,9.5); cairo_line_to(c,-9.5,6); cairo_line_to(c,-3.5,0); cairo_line_to(c,-9.5,-6); cairo_close_path(c); cairo_fill_preserve(c); cairo_restore(c); } void path_button_back(cairo_t *c, double x, double y){ cairo_save(c); cairo_translate(c,x,y); cairo_set_fill_rule(c,CAIRO_FILL_RULE_EVEN_ODD); cairo_set_line_width(c,1); cairo_arc(c,0,0,14,0,2*M_PI); cairo_move_to(c,0,-11); cairo_line_to(c,-9,0); cairo_line_to(c,-3,0); cairo_line_to(c,-3,10); cairo_line_to(c,3,10); cairo_line_to(c,3,0); cairo_line_to(c,9,0); cairo_close_path(c); cairo_fill_preserve(c); cairo_restore(c); } void path_button_reset(cairo_t *c, double x, double y){ cairo_save(c); cairo_translate(c,x,y); cairo_set_fill_rule(c,CAIRO_FILL_RULE_EVEN_ODD); cairo_set_line_width(c,1); cairo_arc(c,0,0,14,0,2*M_PI); cairo_move_to(c,-11,-5); cairo_line_to(c,-12,1); cairo_line_to(c,-6,1); cairo_line_to(c,0, 11); cairo_line_to(c,6,1); cairo_line_to(c,12,1); cairo_line_to(c,11,-5); cairo_line_to(c,4,-5); cairo_line_to(c,0,2); cairo_line_to(c,-4,-5); cairo_close_path(c); cairo_fill_preserve(c); cairo_restore(c); } void path_button_expand(cairo_t *c, double x, double y){ cairo_save(c); cairo_translate(c,x,y); cairo_set_fill_rule(c,CAIRO_FILL_RULE_EVEN_ODD); cairo_set_line_width(c,1); cairo_arc(c,0,0,14,0,2*M_PI); cairo_move_to(c,-8.5,-3); cairo_line_to(c,-2.5,-3); cairo_line_to(c,-3,-8.5); cairo_line_to(c,3, -8.5); cairo_line_to(c,3,-3); cairo_line_to(c,8.5,-3); cairo_line_to(c,8.5,3); cairo_line_to(c,3,3); cairo_line_to(c,3,8.5); cairo_line_to(c,-3,8.5); cairo_line_to(c,-3,3); cairo_line_to(c,-8.5,3); cairo_close_path(c); cairo_fill_preserve(c); cairo_restore(c); } void path_button_shrink(cairo_t *c, double x, double y){ cairo_save(c); cairo_translate(c,x,y); cairo_set_fill_rule(c,CAIRO_FILL_RULE_EVEN_ODD); cairo_set_line_width(c,1); cairo_arc(c,0,0,14,0,2*M_PI); cairo_move_to(c,-10,-3); cairo_line_to(c,10,-3); cairo_line_to(c,10,3); cairo_line_to(c,-10,3); cairo_close_path(c); cairo_fill_preserve(c); cairo_restore(c); } void path_button_lines(cairo_t *c, double x, double y){ cairo_save(c); cairo_translate(c,x,y); cairo_set_fill_rule(c,CAIRO_FILL_RULE_EVEN_ODD); cairo_set_line_width(c,1); cairo_arc(c,0,0,14,0,2*M_PI); cairo_move_to(c,6,-4); cairo_arc(c,0,-4,6,0,2*M_PI); cairo_move_to(c,0,2); cairo_line_to(c,0,10); cairo_close_path(c); cairo_move_to(c,2.68328,5.36656-4); cairo_rel_line_to(c,4,8); cairo_close_path(c); cairo_move_to(c,-2.68328,5.36656-4); cairo_rel_line_to(c,-4,8); cairo_close_path(c); cairo_fill_preserve(c); cairo_restore(c); } void path_button_int(cairo_t *c, double x, double y){ cairo_save(c); cairo_translate(c,x,y); cairo_set_fill_rule(c,CAIRO_FILL_RULE_EVEN_ODD); cairo_set_line_width(c,1); cairo_arc(c,0,0,14,0,2*M_PI); cairo_move_to(c,8,0); cairo_line_to(c,0,8); cairo_line_to(c,-8,0); cairo_line_to(c,0,-8); cairo_close_path(c); cairo_fill_preserve(c); cairo_restore(c); } void path_button_check(cairo_t *c, double x, double y){ cairo_save(c); cairo_translate(c,x,y); cairo_set_fill_rule(c,CAIRO_FILL_RULE_EVEN_ODD); cairo_set_line_width(c,1); cairo_arc(c,0,0,14,0,2*M_PI); cairo_move_to(c,8,-8); cairo_curve_to(c, 7,-7, 11,-7.3, 10,-6); cairo_line_to(c,0,9); cairo_curve_to(c, -1,9.1, -2,11, -3,10); cairo_line_to(c,-11,4); cairo_curve_to(c, -12,3, -10,.5, -9,1); cairo_line_to(c,-3,3); cairo_close_path(c); cairo_fill_preserve(c); cairo_restore(c); } void path_button_play(cairo_t *c, double x, double y){ cairo_save(c); cairo_translate(c,x,y); cairo_set_fill_rule(c,CAIRO_FILL_RULE_EVEN_ODD); cairo_set_line_width(c,1); cairo_arc(c,0,0,14,0,2*M_PI); cairo_move_to(c,-8,-8); cairo_line_to(c,10,0); cairo_line_to(c,-8,8); cairo_close_path(c); cairo_fill_preserve(c); cairo_restore(c); } gplanarity-17906/main.c0000644000175000017500000002515511543161637014721 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include "version.h" #include "graph.h" #include "gameboard.h" #include "levelstate.h" #include "main.h" #define boardstate "/.gPlanarity/boards/" #define mainstate "/.gPlanarity/" char *boarddir; char *statedir; Gameboard *gameboard; GtkWidget *toplevel_window; graph maingraph; char *version = ""; static cairo_font_face_t *font_face=0; static cairo_font_face_t *bold_face=0; static cairo_font_face_t *ital_face=0; static float adjust_x_normal; static float adjust_y_normal; static float adjust_x_bold; static float adjust_y_bold; static int dir_create(char *name){ if(mkdir(name,0700)){ switch(errno){ case EEXIST: // this is ok return 0; default: fprintf(stderr,_("ERROR: Could not create directory (%s) to save game state:\n\t%s\n"), name,strerror(errno)); return errno; } } return 0; } void request_resize(int width, int height){ gtk_window_resize(GTK_WINDOW(toplevel_window),width,height); if(gameboard->resize_timeout) gameboard->resize_timeout = time(NULL)+3; gameboard->resize_w = width; gameboard->resize_h = height; } static void clean_exit(int sig){ signal(sig,SIG_IGN); if(sig!=SIGINT) fprintf(stderr, _("\nTrapped signal %d; saving state and exiting!\n"),sig); levelstate_write(statedir); gtk_main_quit(); exit(0); } static void clean_exit_delete_post(Gameboard *g){ gameboard = 0; gtk_main_quit(); } static gint clean_exit_delete(gpointer p){ levelstate_write(statedir); undeploy_buttons(gameboard,clean_exit_delete_post); return 1; // we're handling it, don't continue the delete chain } /* font handling... still a pain in the ass! ...but mostly due to lack of documentation. Try first to find one of the default fonts we prefer (FontConfig can search for a list, Cairo cannot). Regardless of what's found, try to determine the approximate best aspect ratio of the text; gPlanarity looks best with a relatively tall/narrow font that renders with horizontal/vertical strokes of approximately identical width */ static cairo_font_face_t *init_font(char *list, int slant,int bold){ cairo_font_face_t *ret; char *fontface; FcPattern *fc_pattern; FcBool scalable; fc_pattern = FcNameParse((unsigned char *)list); // load the system config FcConfigSubstitute(0, fc_pattern, FcMatchPattern); FcPatternDel(fc_pattern,FC_SLANT); FcPatternDel(fc_pattern,FC_WEIGHT); if(slant) FcPatternAddInteger(fc_pattern,FC_SLANT,FC_SLANT_ITALIC); if(bold) FcPatternAddInteger(fc_pattern,FC_WEIGHT,FC_WEIGHT_BOLD); // fill in missing defaults FcDefaultSubstitute(fc_pattern); // find a font face on our list if possible fc_pattern = FcFontMatch(0, fc_pattern, 0); if(!fc_pattern){ fprintf(stderr,_("\nUnable to find any suitable %s fonts!\n" "Continuing, but the the results are likely to be poor.\n\n"), (slant?(bold?_("bold italic"):_("italic")):(bold?_("bold"):_("medium")))); } FcPatternGetString (fc_pattern, FC_FAMILY, 0, (FcChar8 **)&fontface); /* if(!strstr(list,fontface)){ fprintf(stderr,"\nUnable to find any of gPlanarity's preferred %s fonts (%s);\n" "Using system default font \"%s\".\n\n", (slant?(bold?"bold italic":"italic"):(bold?"bold":"medium")), list,fontface); }*/ FcPatternGetBool(fc_pattern, FC_SCALABLE, 0, &scalable); if (scalable != FcTrue) { fprintf(stderr,_("\nSelected %s font \"%s\" is not scalable! This is almost as bad\n" "as not finding any font at all. Continuing, but this may look\n" "very poor indeed.\n\n"), (slant?(bold?_("bold italic"):_("italic")):(bold?_("bold"):_("medium"))), fontface); } /* Set the hinting behavior we want; only the autohinter is giving decent results across a wide range of sizes and face options. Don't obey the system config with respect to hinting; every one of my systems installed a default config that resulted in the available fonts looking like ass. Bitstream Vera Sans especially looks bad without the autohinter, and that's the font most systems will have as the only sans default. */ // Must remove the preexisting settings! The settings are a list, // and we're tacking ours on the end; Cairo only inspects first hit FcPatternDel(fc_pattern,FC_HINT_STYLE); FcPatternDel(fc_pattern,FC_HINTING); FcPatternDel(fc_pattern,FC_AUTOHINT); // Add ours requesting autohint FcPatternAddBool(fc_pattern,FC_HINTING,FcTrue); FcPatternAddBool(fc_pattern,FC_AUTOHINT,FcTrue); // Make the font face ret = cairo_ft_font_face_create_for_pattern(fc_pattern); FcPatternDestroy(fc_pattern); return ret; } static void init_fonts(char *list){ font_face = init_font(list,0,0); bold_face = init_font(list,0,1); ital_face = init_font(list,1,0); // We've done the best we can, font-choice-wise. Determine an // aspect ratio correction for whatever font we've got. Arial is // declared to be the ideal aspect, correct other fonts to the same // rough proportions (it looks better). This is a rough hack, but // yields an unmistakable improvement. { cairo_text_extents_t ex; char *test_string = "Practice Before the Handbasket: Three of Three"; cairo_surface_t *s = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,16,16); cairo_t *c = cairo_create(s); cairo_matrix_t m; cairo_set_font_face (c, font_face); cairo_matrix_init_scale (&m, 50.,50.); cairo_set_font_matrix (c,&m); cairo_text_extents (c, test_string, &ex); adjust_x_normal = 1058 / ex.width; adjust_y_normal = -37 / ex.y_bearing; cairo_set_font_face (c, bold_face); cairo_text_extents (c, test_string, &ex); adjust_x_bold = 1130 / ex.width; adjust_y_bold = -37 / ex.y_bearing; cairo_destroy(c); cairo_surface_destroy(s); } } void set_font (cairo_t *c, float w, float h, int slant, int bold){ cairo_matrix_t m; if(slant){ cairo_set_font_face(c,ital_face); cairo_matrix_init_scale (&m, ceil(w*adjust_x_normal),ceil(h*adjust_y_normal)); }else if (bold){ cairo_set_font_face(c,bold_face); cairo_matrix_init_scale (&m, ceil(w*adjust_x_bold),ceil(h*adjust_y_bold)); }else{ cairo_set_font_face(c,font_face); cairo_matrix_init_scale (&m, ceil(w*adjust_x_normal),ceil(h*adjust_y_normal)); } cairo_set_font_matrix (c,&m); } #include "icon.h" void set_icons(){ GError *error=NULL; GList *pb=NULL; //GdkPixbufLoader *pbl1 = gdk_pixbuf_loader_new(); GdkPixbufLoader *pbl2 = gdk_pixbuf_loader_new(); GdkPixbufLoader *pbl3 = gdk_pixbuf_loader_new(); //gdk_pixbuf_loader_write(pbl1,icon134,sizeof(icon134),&error); gdk_pixbuf_loader_write(pbl2,icon64,sizeof(icon64),&error); gdk_pixbuf_loader_write(pbl3,icon32,sizeof(icon32),&error); //gdk_pixbuf_loader_close(pbl1,NULL); gdk_pixbuf_loader_close(pbl2,NULL); gdk_pixbuf_loader_close(pbl3,NULL); //pb = g_list_append(pb, gdk_pixbuf_loader_get_pixbuf(pbl1)); pb = g_list_append(pb, gdk_pixbuf_loader_get_pixbuf(pbl2)); pb = g_list_append(pb, gdk_pixbuf_loader_get_pixbuf(pbl3)); gtk_window_set_icon_list(GTK_WINDOW(toplevel_window),pb); } int main(int argc, char *argv[]){ #ifdef ENABLE_NLS setlocale(LC_ALL, ""); textdomain(GT_DOMAIN); bindtextdomain(GT_DOMAIN, GT_DIR); #endif char *homedir = getenv("home"); if(!homedir) homedir = getenv("HOME"); if(!homedir) homedir = getenv("homedir"); if(!homedir) homedir = getenv("HOMEDIR"); if(!homedir){ fprintf(stderr, _("No homedir environment variable set! gPlanarity will be\n" "unable to permanently save any progress or board state.\n")); boarddir=NULL; statedir=NULL; }else{ boarddir=calloc(strlen(homedir)+strlen(boardstate)+1,1); strcat(boarddir,homedir); strcat(boarddir,boardstate); statedir=calloc(strlen(homedir)+strlen(mainstate)+1,1); strcat(statedir,homedir); strcat(statedir,mainstate); dir_create(statedir); dir_create(boarddir); } version=strstr(VERSION,"version.h"); if(version){ char *versionend=strchr(version,' '); if(versionend)versionend=strchr(versionend+1,' '); if(versionend)versionend=strchr(versionend+1,' '); if(versionend)versionend=strchr(versionend+1,' '); if(versionend){ int len=versionend-version-9; version=strdup(version+10); version[len-1]=0; } }else{ version=""; } init_fonts(""); gtk_init (&argc, &argv); toplevel_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_signal_connect (G_OBJECT (toplevel_window), "delete-event", G_CALLBACK (clean_exit_delete), NULL); gameboard = gameboard_new(); levelstate_read(); gtk_container_add (GTK_CONTAINER (toplevel_window), GTK_WIDGET(gameboard)); gtk_widget_realize(toplevel_window); gtk_widget_realize(GTK_WIDGET(gameboard)); memset(&maingraph,0,sizeof(maingraph)); /* get the setup processed before we fire up animations */ while (gtk_events_pending ()){ gtk_main_iteration (); gdk_window_process_updates(toplevel_window->window,1); gdk_flush(); } levelstate_resume(); set_icons(); gtk_widget_show_all(toplevel_window); signal(SIGINT,clean_exit); //signal(SIGSEGV,clean_exit); /* would be a bad idea; corrupt state //could prevent us from restarting */ gtk_main (); if(gameboard !=0 ) levelstate_write(); cairo_font_face_destroy(font_face); cairo_font_face_destroy(bold_face); cairo_font_face_destroy(ital_face); return 0; } gplanarity-17906/gPicon.png0000644000175000017500000000447211543161637015555 0ustar vincentvincentPNG  IHDR szz pHYs+tIME 3iIDATXíWiPS~IHB6A"Ec$pE-5 ZN* N[Go:Z;V2Rr]([P\((ZC$$INNF;Bw;ϻa45'x[w~k_{AiiyP8gs@LuWZ-]V׷pDI{ L&SNkn?_vIP6x_Dap8rJ57^ ց72of7}۷$XhHB67n^p8A娮ޟ|X.7tNuVXt: jzBxxx00apP@0 sW###d/<KƏ?O?} 'OR(ru@,>Ru v{bZZڃc,[LTfZEN-&g/)pՇ%VCMkȚ5[ȶm{ 0;v hjIH9s4%z;n'σO<"#m$88fc50f~X|<R n "mZmѠdKM6A {.jlHSPiEERkEcl&6( Nq%'''3 `uJJJP"Qn7sbޏF}ӆ#(j$|>&ܹ1okHH}kjuFcLFrsg]"{8Z[[sZ^ddhaXu+bqbcYO]po"!A ݎ}B'fyQF3g e/\ɘ7oFdzD~%$=}'8BH}}=hF#imm%}$*!V2i'dڴ#:$&~L<>I^^^V]e0(::z֪?uvgGM AQ|G]SX?6a7a ; :|?b 9 ;qA~wwg툏  mtRPap|>palL)++ǭP83/[8 o v( ρ f`N3L ܹsWD@ BdjrB||SUTeC( 5k6fG֤Ssl" :M".. P]] '9s&rr04qp``M\~y'˲bfB |2%&ܺude周(;IMimmmիOm,BNg##hql8cDym@,Yr >˕/ g!""bTd kc,h M?qℝSL1㳚G 8{|i~~4o#44tԽ";;== V͝5|C~a1PT2^Ѩju=`r0aF\\[Ӹq^ |S!>ҿ<--MhJLvvىO/CV֊QwGwGq$'`^0`0nܸ15!!뱇SSSCCBuaE/ * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include "graph.h" #include "gameboard.h" /* draw/cache vertex surfaces; direct surface copies are faster than always redrawing lots of circles */ void draw_vertex(cairo_t *c,vertex *v,cairo_surface_t *s){ cairo_set_source_surface(c, s, v->x-V_LINE-V_RADIUS, v->y-V_LINE-V_RADIUS); cairo_paint(c); } void draw_vertex_with_alpha(cairo_t *c,vertex *v,cairo_surface_t *s,float alpha){ cairo_set_source_surface(c, s, v->x-V_LINE-V_RADIUS, v->y-V_LINE-V_RADIUS); cairo_paint_with_alpha(c,alpha); } // normal unlit vertex cairo_surface_t *cache_vertex(Gameboard *g){ cairo_t *wc = gdk_cairo_create(g->w.window); cairo_surface_t *ret= cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR_ALPHA, (V_RADIUS+V_LINE)*2, (V_RADIUS+V_LINE)*2); cairo_t *c = cairo_create(ret); cairo_destroy(wc); cairo_set_line_width(c,V_LINE); cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS,0,2*M_PI); cairo_set_source_rgb(c,V_FILL_IDLE_COLOR); cairo_fill_preserve(c); cairo_set_source_rgb(c,V_LINE_COLOR); cairo_stroke(c); cairo_destroy(c); return ret; } // selected vertex cairo_surface_t *cache_vertex_sel(Gameboard *g){ cairo_t *wc = gdk_cairo_create(g->w.window); cairo_surface_t *ret= cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR_ALPHA, (V_RADIUS+V_LINE)*2, (V_RADIUS+V_LINE)*2); cairo_t *c = cairo_create(ret); cairo_destroy(wc); cairo_set_line_width(c,V_LINE); cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS,0,2*M_PI); cairo_set_source_rgb(c,V_FILL_LIT_COLOR); cairo_fill_preserve(c); cairo_set_source_rgb(c,V_LINE_COLOR); cairo_stroke(c); cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS*.5,0,2*M_PI); cairo_set_source_rgb(c,V_FILL_IDLE_COLOR); cairo_fill(c); cairo_destroy(c); return ret; } // grabbed vertex cairo_surface_t *cache_vertex_grabbed(Gameboard *g){ cairo_t *wc = gdk_cairo_create(g->w.window); cairo_surface_t *ret= cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR_ALPHA, (V_RADIUS+V_LINE)*2, (V_RADIUS+V_LINE)*2); cairo_t *c = cairo_create(ret); cairo_destroy(wc); cairo_set_line_width(c,V_LINE); cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS,0,2*M_PI); cairo_set_source_rgb(c,V_FILL_LIT_COLOR); cairo_fill_preserve(c); cairo_set_source_rgb(c,V_LINE_COLOR); cairo_stroke(c); cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS*.5,0,2*M_PI); cairo_set_source_rgb(c,V_FILL_ADJ_COLOR); cairo_fill(c); cairo_destroy(c); return ret; } // vertex under mouse rollover cairo_surface_t *cache_vertex_lit(Gameboard *g){ cairo_t *wc = gdk_cairo_create(g->w.window); cairo_surface_t *ret= cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR_ALPHA, (V_RADIUS+V_LINE)*2, (V_RADIUS+V_LINE)*2); cairo_t *c = cairo_create(ret); cairo_destroy(wc); cairo_set_line_width(c,V_LINE); cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS,0,2*M_PI); cairo_set_source_rgb(c,V_FILL_LIT_COLOR); cairo_fill_preserve(c); cairo_set_source_rgb(c,V_LINE_COLOR); cairo_stroke(c); cairo_destroy(c); return ret; } // verticies attached to grabbed vertex cairo_surface_t *cache_vertex_attached(Gameboard *g){ cairo_t *wc = gdk_cairo_create(g->w.window); cairo_surface_t *ret= cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR_ALPHA, (V_RADIUS+V_LINE)*2, (V_RADIUS+V_LINE)*2); cairo_t *c = cairo_create(ret); cairo_destroy(wc); cairo_set_line_width(c,V_LINE); cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS,0,2*M_PI); cairo_set_source_rgb(c,V_FILL_ADJ_COLOR); cairo_fill_preserve(c); cairo_set_source_rgb(c,V_LINE_COLOR); cairo_stroke(c); cairo_destroy(c); return ret; } // vertex being dragged in a group cairo_surface_t *cache_vertex_ghost(Gameboard *g){ cairo_t *wc = gdk_cairo_create(g->w.window); cairo_surface_t *ret= cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR_ALPHA, (V_RADIUS+V_LINE)*2, (V_RADIUS+V_LINE)*2); cairo_t *c = cairo_create(ret); cairo_destroy (wc); cairo_set_line_width(c,V_LINE); cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS,0,2*M_PI); cairo_set_source_rgb(c,V_FILL_LIT_COLOR); cairo_fill_preserve(c); cairo_set_source_rgb(c,V_LINE_COLOR); cairo_stroke(c); cairo_arc(c,V_RADIUS+V_LINE,V_RADIUS+V_LINE,V_RADIUS*.5,0,2*M_PI); cairo_set_source_rgb(c,V_FILL_ADJ_COLOR); cairo_fill(c); cairo_destroy(c); return ret; } /* region invalidation operations; do exposes efficiently! **********/ // invalidate the box around a single offset vertex void invalidate_vertex_off(GtkWidget *widget, vertex *v, int dx, int dy){ if(v){ GdkRectangle r; r.x = v->x - V_RADIUS - V_LINE + dx; r.y = v->y - V_RADIUS - V_LINE + dy; r.width = (V_RADIUS + V_LINE)*2; r.height = (V_RADIUS + V_LINE)*2; gdk_window_invalidate_rect (widget->window, &r, FALSE); } } // invalidate the box around a single vertex void invalidate_vertex(Gameboard *g, vertex *v){ invalidate_vertex_off(&g->w,v,0,0); } // invalidate a vertex and any other attached verticies void invalidate_attached(GtkWidget *widget, vertex *v){ if(v){ edge_list *el=v->edges; while (el){ edge *e=el->edge; if(e->A != v)invalidate_vertex(GAMEBOARD(widget),e->A); if(e->B != v)invalidate_vertex(GAMEBOARD(widget),e->B); el=el->next; } invalidate_vertex(GAMEBOARD(widget),v); } } gplanarity-17906/version.h0000644000175000017500000000022411543161637015455 0ustar vincentvincent#define VERSION "$Id: version.h 17906 2011-03-23 09:33:07Z xiphmont $ " /* DO NOT EDIT: Automated versioning hack [Wed Mar 23 05:30:26 EDT 2011] */ gplanarity-17906/gameboard_logic.c0000644000175000017500000002223211543161637017064 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include "graph.h" #include "timer.h" #include "gameboard.h" #include "levelstate.h" #include "dialog_finish.h" #include "dialog_pause.h" #include "dialog_level.h" #include "main.h" /* game state helpers ************************************************************************************/ void prepare_reenter_game(Gameboard *g){ g->lit_vertex=0; g->grabbed_vertex=0; g->delayed_background=0; g->group_drag=0; g->button_grabbed=0; g->selection_grab=0; g->selection_active=num_selected_verticies(&g->g); update_full(g); update_score(g); } void reenter_game(Gameboard *g){ deploy_buttonbar(g); unpause_timer(); set_in_progress(); } void enter_game(Gameboard *g){ set_timer(0); prepare_reenter_game(g); reenter_game(g); } static void animate_verticies(Gameboard *g, int *x_target, int *y_target, float *delta){ int flag=1,count=0; vertex *v=g->g.verticies; float *tx=alloca(g->g.vertex_num * sizeof(*tx)); float *ty=alloca(g->g.vertex_num * sizeof(*ty)); // hide intersections now; deactivating the verticies below will hide them anyway g->show_intersections = 0; g->realtime_background = 1; update_full(g); // deactivate all the verticies so they can be moved en-masse // without graph metadata updates at each move v=g->g.verticies; while(v){ deactivate_vertex(&g->g,v); tx[count]=v->x; ty[count++]=v->y; v=v->next; } // animate while(flag){ count=0; flag=0; v=g->g.verticies; while(v){ if(v->x!=x_target[count] || v->y!=y_target[count]){ float xd = x_target[count] - tx[count]; float yd = y_target[count] - ty[count]; float m = hypot(xd,yd); tx[count]+= xd/m*delta[count]; ty[count]+= yd/m*delta[count]; invalidate_vertex(g,v); invalidate_edges(GTK_WIDGET(g),v,0,0); v->x = rint(tx[count]); v->y = rint(ty[count]); if( (v->x > x_target[count] && xd > 0) || (v->x < x_target[count] && xd < 0) || (v->y > y_target[count] && yd > 0) || (v->y < y_target[count] && yd < 0) ){ v->x = x_target[count]; v->y = y_target[count]; }else flag=1; invalidate_vertex(g,v); invalidate_edges(GTK_WIDGET(g),v,0,0); } count++; v=v->next; } gdk_window_process_all_updates(); gdk_flush(); } // reactivate all the verticies activate_verticies(&g->g); // update the score update_score(g); // it's a reset; show lines is default. This also has the side // effect of forcing a full board redraw and expose g->realtime_background=0; update_full(g); // possible if(g->g.active_intersections <= g->g.objective){ deploy_check(g); }else{ undeploy_check(g); } } static void scale(Gameboard *g,double scale){ int x=g->g.width/2; int y=g->g.height/2; int sel = num_selected_verticies(&g->g); vertex *v; int *tx=alloca(g->g.vertex_num * sizeof(*tx)); int *ty=alloca(g->g.vertex_num * sizeof(*ty)); float *tm=alloca(g->g.vertex_num * sizeof(*ty)); int i=0; int minx=0; int maxx=g->g.width-1; int miny=0; int maxy=g->g.height-1; int okflag=0; // if selected, expand from center of selected mass if(sel){ double xac=0; double yac=0; v=g->g.verticies; while(v){ if(v->selected){ xac+=v->x; yac+=v->y; } v=v->next; } x = xac / sel; y = yac / sel; } while(!okflag){ okflag=1; i=0; v=g->g.verticies; while(v){ if(!sel || v->selected){ float nx = rint((v->x - x)*scale+x); float ny = rint((v->y - y)*scale+y); float m = hypot(nx - v->x,ny-v->y)/5; if(nxx-x); okflag=0; } if(nx>maxx){ scale = (float)(maxx-x) / (v->x - x); okflag=0; } if(nyy-y); okflag=0; } if(ny>maxy){ scale = (float)(maxy-y) / (v->y - y); okflag=0; } if(m<1)m=1; tx[i] = rint(nx); ty[i] = rint(ny); tm[i++] = m; }else{ tx[i] = v->x; ty[i] = v->y; tm[i++] = 0; } v=v->next; } } if(scale>=.99999 && scale<=1.00001){ ungrab_verticies(&g->g); v=g->g.verticies; while(v){ if(v->x<2 || v->x>=g->g.width-3)v->grabbed=1; if(v->y<2 || v->y>=g->g.height-3)v->grabbed=1; v=v->next; } fade_marked(g); ungrab_verticies(&g->g); }else{ animate_verticies(g,tx,ty,tm); } } static void gtk_main_quit_wrapper(Gameboard *g){ fade_cancel(g); gtk_main_quit(); } static void level_wrapper(Gameboard *g){ fade_cancel(g); level_dialog(g,0); } static void finish_wrapper(Gameboard *g){ fade_cancel(g); finish_level_dialog(g); } /* toplevel main gameboard action entry points; when a button is clicked and decoded to a specific action or a game state change triggers an action, one of the below functions is the entry point **************************************************************************************************************/ void quit_action(Gameboard *g){ pause_timer(); undeploy_buttons(g,gtk_main_quit_wrapper); } void level_action(Gameboard *g){ pause_timer(); undeploy_buttons(g,level_wrapper); } void finish_action(Gameboard *g){ if(g->g.active_intersections<=g->g.original_intersections){ pause_timer(); levelstate_finish(); undeploy_buttons(g,finish_wrapper); } } void pause_action(Gameboard *g){ pause_timer(); undeploy_buttons(g,pause_dialog); } void about_action(Gameboard *g){ pause_timer(); undeploy_buttons(g,about_dialog); } void expand_action(Gameboard *g){ scale(g,1.2); } void shrink_action(Gameboard *g){ scale(g,.8); } void set_hide_lines(Gameboard *g, int state){ g->hide_lines=state; update_full(g); } void toggle_hide_lines(Gameboard *g){ g->hide_lines= !g->hide_lines; update_full(g); } void set_show_intersections(Gameboard *g, int state){ if(g->show_intersections != state){ g->show_intersections=state; expose_full(g); } } void toggle_show_intersections(Gameboard *g){ g->show_intersections=!g->show_intersections; expose_full(g); } void reset_action(Gameboard *g){ vertex *v=g->g.verticies; int *target_x = alloca(g->g.vertex_num * sizeof(*target_x)); int *target_y = alloca(g->g.vertex_num * sizeof(*target_y)); float *target_m = alloca(g->g.vertex_num * sizeof(*target_m)); int i=0; int xd = (g->g.width-g->g.orig_width)>>1; int yd = (g->g.height-g->g.orig_height)>>1; while(v){ target_x[i]=v->orig_x+xd; target_y[i]=v->orig_y+yd; target_m[i++]=RESET_DELTA; v=v->next; } animate_verticies(g,target_x,target_y,target_m); // reset timer set_timer(0); unpause_timer(); } /***************** save/load gameboard the widget state we want to be persistent **************/ // there are only a few things; lines, intersections int gameboard_write(char *basename, Gameboard *g){ char *name; FILE *f; name=alloca(strlen(boarddir)+strlen(basename)+1); name[0]=0; strcat(name,boarddir); strcat(name,basename); f = fopen(name,"wb"); if(f==NULL){ fprintf(stderr,_("ERROR: Could not save board state for \"%s\":\n\t%s\n"), get_level_desc(),strerror(errno)); return errno; } graph_write(&g->g,f); if(g->hide_lines) fprintf(f,"hide_lines 1\n"); if(g->show_intersections) fprintf(f,"show_intersections 1\n"); fclose(f); return 0; } int gameboard_read(char *basename, Gameboard *g){ FILE *f; char *name; char *line=NULL; size_t n=0; name=alloca(strlen(boarddir)+strlen(basename)+3); name[0]=0; strcat(name,boarddir); strcat(name,basename); f = fopen(name,"rb"); if(f==NULL){ fprintf(stderr,_("ERROR: Could not read saved board state for \"%s\":\n\t%s\n"), get_level_desc(),strerror(errno)); return errno; } graph_read(&g->g,f); // get local game state while(getline(&line,&n,f)>0){ int i; if (sscanf(line,"hide_lines %d",&i)==1) if(i) g->hide_lines = 1; if (sscanf(line,"show_intersections %d",&i)==1) if(i) g->show_intersections = 1; } fclose (f); free(line); request_resize(g->g.width,g->g.height); activate_verticies(&g->g); return 0; } gplanarity-17906/dialog_pause.h0000644000175000017500000000232611543161637016431 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define PAUSE_BUTTON_BORDER 35 #define PAUSE_BUTTON_Y 25 #define PAUSEBOX_WIDTH 180 #define PAUSEBOX_HEIGHT 250 #define ABOUTBOX_WIDTH 350 #define ABOUTBOX_HEIGHT 400 extern void pause_dialog(Gameboard *g); extern void about_dialog(Gameboard *g); gplanarity-17906/touch-version0000755000175000017500000000057211543161637016360 0ustar vincentvincent#!/usr/bin/perl if(open F,"version.h"){ $line=; close F; if(open F,">version.h"){ print F "$line"; chomp($line=`date`); print F "/* DO NOT EDIT: Automated versioning hack [$line] */\n"; close F; 0; }else{ print "touch-version: Failed to write new version.h\n"; 1; } }else{ print "touch-version: Failed to open version.h\n"; 1; } gplanarity-17906/gameboard.h0000644000175000017500000002414311543161637015717 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include #include #include #include "nls.h" #define V_RADIUS 8 #define V_LINE 2 #define V_LINE_COLOR 0, 0, 0 #define V_FILL_IDLE_COLOR .2,.2, 1 #define V_FILL_LIT_COLOR 1, 1, 1 #define V_FILL_ADJ_COLOR 1,.2,.2 #define E_LINE 1.5 #define E_LINE_F_COLOR 0, 0, 0, 1 #define E_LINE_B_COLOR .5,.5,.5, 1 #define SELECTBOX_COLOR .2,.8,.8,.3 #define INTERSECTION_COLOR 1,.1,.1,.8 #define INTERSECTION_RADIUS 10 #define INTERSECTION_LINE_WIDTH 2 #define RESET_DELTA 2 #define SCALE_DELTA 8 #define B_LINE 1 #define B_BORDER 6.5 #define B_RADIUS 20 #define B_HUMP 130 #define B_COLOR .1,.1,.7,.1 #define B_LINE_COLOR 0, 0,.7,.3 #define TEXT_COLOR .0,.0,.7,.6 #define HIGH_COLOR .7,.0,.0,.6 #define SCOREHEIGHT 50 #define ICON_WIDTH 160 #define ICON_HEIGHT 120 #define FADE_FRAMES 50 #define FADE_ANIM_INTERVAL 100 G_BEGIN_DECLS #define GAMEBOARD_TYPE (gameboard_get_type ()) #define GAMEBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAMEBOARD_TYPE, Gameboard)) #define GAMEBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAMEBOARD_TYPE, GameboardClass)) #define IS_GAMEBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAMEBOARD_TYPE)) #define IS_GAMEBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAMEBOARD_TYPE)) typedef struct _Gameboard Gameboard; typedef struct _GameboardClass GameboardClass; typedef struct fade_list{ vertex *v; struct fade_list *next; } fade_list; typedef struct { fade_list *head; int count; gint fade_timer; } fade_state; #define NUMBUTTONS 11 typedef struct { int position; // 0 inactive // 1 left // 2 center // 3 right // negative indicates active but undeployed int x_target; int x; int y_target; int y_inactive; int y_active; int y; int sweepdeploy; int alphad; double alpha; cairo_surface_t *idle; cairo_surface_t *lit; char *rollovertext; cairo_text_extents_t ex; int rollover; int press; void (*callback)(); } buttonstate; typedef struct { buttonstate states[NUMBUTTONS]; int buttons_ready; int allclear; // short-circuit hint int sweeper; int sweeperd; buttonstate *grabbed; } buttongroup; typedef struct { int num; double alpha; cairo_surface_t *icon; int x; int y; int w; int h; } dialog_level_oneicon; typedef struct { dialog_level_oneicon level_icons[5]; int center_x; int center_done; int level_lit; int reset_deployed; GdkRectangle text1; GdkRectangle text2; GdkRectangle text3; GdkRectangle text4; gint icon_timer; // used for buttons and icons } dialog_level_state; struct _Gameboard{ GtkWidget w; graph g; int pushed_curtain; void (*redraw_callback)(Gameboard *g); cairo_surface_t *vertex; cairo_surface_t *vertex_lit; cairo_surface_t *vertex_grabbed; cairo_surface_t *vertex_attached; cairo_surface_t *vertex_sel; cairo_surface_t *vertex_ghost; cairo_surface_t *forescore; cairo_surface_t *forebutton; cairo_surface_t *background; cairo_surface_t *foreground; cairo_pattern_t *curtainp; cairo_surface_t *curtains; int delayed_background; int first_expose; int hide_lines; int realtime_background; int show_intersections; int finish_dialog_active; int about_dialog_active; int pause_dialog_active; int level_dialog_active; buttongroup b; dialog_level_state d; fade_state fade; vertex *grabbed_vertex; vertex *lit_vertex; int group_drag; int button_grabbed; int grabx; int graby; int dragx; int dragy; int graboffx; int graboffy; int selection_grab; int selection_active; int selectionx; int selectiony; int selectionw; int selectionh; int checkbutton_deployed; int buttonbar_sweeper; gint button_timer; // used for buttons and icons void (*button_callback)(Gameboard *); time_t resize_timeout; // watch for ignored resize events int resize_w; // watch for ignored resize events int resize_h; // watch for ignored resize events }; struct _GameboardClass{ GtkWidgetClass parent_class; void (* gameboard) (Gameboard *m); }; GType gameboard_get_type (void); Gameboard* gameboard_new (void); G_END_DECLS extern void init_buttons(Gameboard *g); extern buttonstate *find_button(Gameboard *g,int x,int y); extern void button_set_state(Gameboard *g, buttonstate *b, int rollover, int press); extern void rollover_extents(Gameboard *g, buttonstate *b); extern gboolean animate_button_frame(gpointer ptr); extern void expose_buttons(Gameboard *g,cairo_t *c, int x,int y,int w,int h); extern void resize_buttons(Gameboard *g,int oldw,int oldh,int w,int h); extern void button_clear_state(Gameboard *g); extern void update_push(Gameboard *g, cairo_t *c); extern void push_curtain(Gameboard *g,void(*redraw_callback)(Gameboard *g)); extern void pop_curtain(Gameboard *g); extern void prepare_reenter_game(Gameboard *g); extern void reenter_game(Gameboard *g); extern void enter_game(Gameboard *g); extern void quit_action(Gameboard *g); extern void finish_action(Gameboard *g); extern void expand_action(Gameboard *g); extern void shrink_action(Gameboard *g); extern void pause_action(Gameboard *g); extern void about_action(Gameboard *g); extern void level_action(Gameboard *g); extern void set_hide_lines(Gameboard *g, int state); extern void toggle_hide_lines(Gameboard *g); extern void set_show_intersections(Gameboard *g, int state); extern void toggle_show_intersections(Gameboard *g); extern void reset_action(Gameboard *g); extern int gameboard_write(char *basename, Gameboard *g); extern int gameboard_read(char *basename, Gameboard *g); extern void topbox (Gameboard *g,cairo_t *c, double w, double h); extern void bottombox (Gameboard *g,cairo_t *c, double w, double h); extern void centerbox (cairo_t *c, int x, int y, double w, double h); extern void borderbox_path (cairo_t *c, double x, double y, double w, double h); extern void setup_buttonbar(Gameboard *g); extern void deploy_buttonbar(Gameboard *g); extern void deploy_check(Gameboard *g); extern void undeploy_check(Gameboard *g); extern void update_draw(Gameboard *g); extern void update_full(Gameboard *g); extern void expose_full(Gameboard *g); extern void update_full_delayed(Gameboard *g); extern void update_add_vertex(Gameboard *g, vertex *v); extern void update_add_selgroup(Gameboard *g); extern void gameboard_draw(Gameboard *g, int x, int y, int w, int h); extern void draw_foreground(Gameboard *g,cairo_t *c, int x,int y,int width,int height); extern void draw_intersections(Gameboard *b,graph *g,cairo_t *c, int x,int y,int w,int h); extern void draw_score(Gameboard *g); extern void update_score(Gameboard *g); extern void draw_vertex(cairo_t *c,vertex *v,cairo_surface_t *s); extern void draw_vertex_with_alpha(cairo_t *c,vertex *v,cairo_surface_t *s,float alpha); extern cairo_surface_t *cache_vertex(Gameboard *g); extern cairo_surface_t *cache_vertex_sel(Gameboard *g); extern cairo_surface_t *cache_vertex_grabbed(Gameboard *g); extern cairo_surface_t *cache_vertex_lit(Gameboard *g); extern cairo_surface_t *cache_vertex_attached(Gameboard *g); extern cairo_surface_t *cache_vertex_ghost(Gameboard *g); extern void invalidate_vertex_off(GtkWidget *widget, vertex *v, int dx, int dy); extern void invalidate_vertex(Gameboard *g, vertex *v); extern void invalidate_attached(GtkWidget *widget, vertex *v); extern void invalidate_edges(GtkWidget *widget, vertex *v, int offx, int offy); extern void draw_selection_rectangle(Gameboard *g,cairo_t *c); extern void invalidate_selection(GtkWidget *widget); extern void invalidate_verticies_selection(GtkWidget *widget); extern void cache_curtain(Gameboard *g); extern void draw_curtain(Gameboard *g); extern void draw_buttonbar_box (Gameboard *g); extern gint mouse_motion(GtkWidget *widget,GdkEventMotion *event); extern gboolean mouse_press (GtkWidget *widget,GdkEventButton *event); extern gboolean mouse_release (GtkWidget *widget,GdkEventButton *event); extern void setup_background_edge(cairo_t *c); extern void setup_foreground_edge(cairo_t *c); extern void draw_edge(cairo_t *c,edge *e); extern void draw_edges(cairo_t *c, vertex *v, int offx, int offy); extern void finish_edge(cairo_t *c); extern cairo_surface_t *gameboard_read_icon(char *filename, char *ext,Gameboard *b); extern int gameboard_write_icon(char *filename, char *ext,Gameboard *b, graph *g, int lines, int intersections); extern int gameboard_icon_exists(char *filename, char *ext); extern void deploy_buttons(Gameboard *g, void (*callback)(Gameboard *)); extern void undeploy_buttons(Gameboard *g, void (*callback)(Gameboard *)); extern GdkRectangle render_text_centered(cairo_t *c, char *s, int x, int y); extern GdkRectangle render_border_centered(cairo_t *c, char *s, int x, int y); extern GdkRectangle render_bordertext_centered(cairo_t *c, char *s, int x, int y); extern void gameboard_size_allocate (GtkWidget *widget, GtkAllocation *allocation); extern void fade_cancel(Gameboard *g); extern void fade_attached(Gameboard *g,vertex *v); extern void fade_grabbed(Gameboard *g); extern void fade_marked(Gameboard *g); gplanarity-17906/graph.c0000644000175000017500000004553511543161637015102 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include #include #include "nls.h" #include "graph.h" #include "random.h" #include "timer.h" #include "gameboard.h" #define CHUNK 64 static vertex *vertex_pool=0; static edge *edge_pool=0; static edge_list *edge_list_pool=0; static intersection *intersection_pool=0; /* mesh/board state */ /************************ edge list maint operations ********************/ edge_list *add_edge_to_list(edge_list *l, edge *e){ edge_list *ret; if(edge_list_pool==0){ int i; edge_list_pool = calloc(CHUNK,sizeof(*edge_list_pool)); for(i=0;inext; ret->edge=e; ret->next=l; return ret; } /* releases the edge list but not the edges */ void release_edge_list(edge_list *el){ if(el){ edge_list *end=el; while(end->next)end=end->next; end->next = edge_list_pool; edge_list_pool = el; } } /* releases the edge list but not the edges */ static void release_vertex_edge_list(vertex *v){ edge_list *el = v->edges; release_edge_list(el); v->edges=0; } /************************ intersection maint operations ********************/ static intersection *new_intersection(){ intersection *ret; if(intersection_pool==0){ int i; intersection_pool = calloc(CHUNK,sizeof(*intersection_pool)); for(i=0;inext; return ret; } static void add_paired_intersection(edge *a, edge *b, double x, double y){ intersection *A=new_intersection(); intersection *B=new_intersection(); A->paired=B; B->paired=A; A->next=a->i.next; if(A->next) A->next->prev=A; A->prev=&(a->i); a->i.next=A; B->next=b->i.next; if(B->next) B->next->prev=B; B->prev=&(b->i); b->i.next=B; A->x=B->x=x; A->y=B->y=y; } static void release_intersection(intersection *i){ memset(i,0,sizeof(*i)); i->next=intersection_pool; intersection_pool=i; } static void release_intersection_list(edge *e){ intersection *i=e->i.next; while(i!=0){ intersection *next=i->next; release_intersection(i); i=next; } e->i.next=0; } static int release_paired_intersection_list(edge *e){ intersection *i=e->i.next; int count=0; while(i){ intersection *next=i->next; intersection *j=i->paired; j->prev->next=j->next; if(j->next) j->next->prev=j->prev; release_intersection(i); release_intersection(j); i=next; count++; } e->i.next=0; return count; } /************************ edge maint operations ******************************/ edge *new_edge(vertex *A, vertex *B){ edge *ret; if(edge_pool==0){ int i; edge_pool = calloc(CHUNK,sizeof(*edge_pool)); for(i=0;inext; ret->A=A; ret->B=B; ret->active=0; ret->i.next=0; return ret; } /* makes a new egde and adds it to the vertex and graph edge lists */ edge *add_edge(graph *g, vertex *A, vertex *B){ edge *ret = new_edge(A,B); ret->next=g->edges; g->edges=ret; A->edges=add_edge_to_list(A->edges,ret); B->edges=add_edge_to_list(B->edges,ret); g->num_edges++; return ret; } /* adds existing edge to the vertex and graph edge lists, but only if it's not already there */ void insert_edge(graph *g, edge *e){ vertex *A = e->A; vertex *B = e->B; if(exists_edge(A,B)){ // already a matching edge; release this one release_intersection_list(e); e->next=edge_pool; edge_pool=e; }else{ e->next=g->edges; g->edges=e; A->edges=add_edge_to_list(A->edges,e); B->edges=add_edge_to_list(B->edges,e); g->num_edges++; } } static void release_edges(graph *g){ edge *e = g->edges; while(e){ edge *next=e->next; release_intersection_list(e); e->next=edge_pool; edge_pool=e; e=next; } g->edges=0; g->num_edges=0; g->num_edges_active=0; } int intersectsV(vertex *L1, vertex *L2, vertex *M1, vertex *M2, double *xo, double *yo){ // edges that share a vertex don't intersect by definition if(L1==M1) return 0; if(L1==M2) return 0; if(L2==M1) return 0; if(L2==M2) return 0; return intersects(L1->x,L1->y,L2->x,L2->y,M1->x,M1->y,M2->x,M2->y,xo,yo); } int intersects(int L1x, int L1y, int L2x, int L2y, int M1x, int M1y, int M2x, int M2y, double *xo, double *yo){ /* y = ax + b */ float La=0; float Lb=0; float Ma=0; float Mb=0; if(L1x != L2x){ La = (float)(L2y - L1y) / (L2x - L1x); Lb = (L1y - L1x * La); } if(M1x != M2x){ Ma = (float)(M2y - M1y) / (M2x - M1x); Mb = (M1y - M1x * Ma); } if(L1x == L2x){ // L is vertical line if(M1x == M2x){ // M is also a vertical line if(L1x == M1x){ // L and M vertical on same x, overlap? if(M1y > L1y && M1y > L2y && M2y > L1y && M2y > L2y) return 0; if(M1y < L1y && M1y < L2y && M2y < L1y && M2y < L2y) return 0; { double y1=max( min(M1y,M2y), min(L1y, L2y)); double y2=min( max(M1y,M2y), max(L1y, L2y)); *xo = M1x; *yo = (y1+y2)*.5; } }else // L and M vertical, different x return 0; }else{ // L vertical, M not vertical // needed if L is vertical and M is horizontal if(L1x < M1x && L1x < M2x) return 0; if(L1x > M1x && L1x > M2x) return 0; { float y = Ma*L1x + Mb; if(y < L1y && y < L2y) return 0; if(y > L1y && y > L2y) return 0; if(y < M1y && y < M2y) return 0; if(y > M1y && y > M2y) return 0; *xo = L1x; *yo=y; } } }else{ if(M1x == M2x){ // M vertical, L not vertical // needed if L is vertical and M is horizontal if(M1x < L1x && M1x < L2x) return 0; if(M1x > L1x && M1x > L2x) return 0; { float y = La*M1x + Lb; if(y < L1y && y < L2y) return 0; if(y > L1y && y > L2y) return 0; if(y < M1y && y < M2y) return 0; if(y > M1y && y > M2y) return 0; *xo = M1x; *yo=y; } }else{ // L and M both have non-infinite slope if(La == Ma){ //L and M have the same slope if(Mb != Lb) return 0; // two segments on same line... if(M1x > L1x && M1x > L2x && M2x > L1x && M2x > L2x) return 0; if(M1x < L1x && M1x < L2x && M2x < L1x && M2x < L2x) return 0; { double x1=max( min(M1x,M2x), min(L1x, L2x)); double x2=min( max(M1x,M2x), max(L1x, L2x)); double y1=max( min(M1y,M2y), min(L1y, L2y)); double y2=min( max(M1y,M2y), max(L1y, L2y)); *xo = (x1+x2)*.5; *yo = (y1+y2)*.5; } }else{ // finally typical case: L and M have different non-infinite slopes float x = (Mb-Lb) / (La - Ma); if(x < L1x && x < L2x) return 0; if(x > L1x && x > L2x) return 0; if(x < M1x && x < M2x) return 0; if(x > M1x && x > M2x) return 0; *xo = x; *yo = La*x + Lb; } } } return 1; } static void activate_edge(graph *g, edge *e){ /* computes all intersections */ if(!e->active && e->A->active && e->B->active){ edge *test=g->edges; while(test){ if(test != e && test->active){ double x,y; if(intersectsV(e->A,e->B,test->A,test->B,&x,&y)){ add_paired_intersection(e,test,x,y); g->active_intersections++; } } test=test->next; } e->active=1; g->num_edges_active++; if(g->num_edges_active == g->num_edges && g->original_intersections==0) g->original_intersections = g->active_intersections; } } static void deactivate_edge(graph *g, edge *e){ /* releases all associated intersections */ if(e->active){ g->active_intersections -= release_paired_intersection_list(e); g->num_edges_active--; e->active=0; } } int exists_edge(vertex *a, vertex *b){ edge_list *el=a->edges; while(el){ if(el->edge->A == b) return 1; if(el->edge->B == b) return 1; el=el->next; } return 0; } /*********************** vertex maint operations *************************/ static vertex *get_vertex(graph *g){ vertex *ret; if(vertex_pool==0){ int i; vertex_pool = calloc(CHUNK,sizeof(*vertex_pool)); for(i=0;inext; ret->x=0; ret->y=0; ret->active=0; ret->selected=0; ret->selected_volatile=0; ret->grabbed=0; ret->attached_to_grabbed=0; ret->fading=0; ret->edges=0; ret->num=g->vertex_num++; ret->next=g->verticies; g->verticies=ret; return ret; } static void release_vertex(vertex *v){ release_vertex_edge_list(v); v->next=vertex_pool; vertex_pool=v; } static void set_num_verticies(graph *g, int num){ /* do it the simple way; release all, link anew */ vertex *v=g->verticies; while(v){ vertex *next=v->next; release_vertex(v); v=next; } g->verticies=0; g->vertex_num=0; release_edges(g); while(num--) get_vertex(g); g->original_intersections = 0; g->active_intersections = 0; g->num_edges=0; // hopefully redundant g->num_edges_active=0; // hopefully redundant } void graph_release(graph *g){ set_num_verticies(g,0); } void activate_vertex(graph *g,vertex *v){ edge_list *el=v->edges; v->active=1; while(el){ activate_edge(g,el->edge); el=el->next; } } void deactivate_vertex(graph *g, vertex *v){ edge_list *el=v->edges; while(el){ edge_list *next=el->next; deactivate_edge(g,el->edge); el=next; } v->active=0; } void activate_verticies(graph *g){ vertex *v=g->verticies; while(v){ activate_vertex(g,v); v=v->next; } } void grab_vertex(graph *g, vertex *v){ edge_list *el=v->edges; deactivate_vertex(g,v); while(el){ edge_list *next=el->next; edge *e=el->edge; vertex *other=(e->A==v?e->B:e->A); other->attached_to_grabbed=1; el=next; } v->grabbed=1; } void grab_selected(graph *g){ vertex *v = g->verticies; while(v){ if(v->selected){ edge_list *el=v->edges; deactivate_vertex(g,v); while(el){ edge_list *next=el->next; edge *e=el->edge; vertex *other=(e->A==v?e->B:e->A); other->attached_to_grabbed=1; el=next; } v->grabbed=1; } v=v->next; } } void ungrab_vertex(graph *g,vertex *v){ edge_list *el=v->edges; activate_vertex(g,v); while(el){ edge_list *next=el->next; edge *e=el->edge; vertex *other=(e->A==v?e->B:e->A); other->attached_to_grabbed=0; el=next; } v->grabbed=0; } void ungrab_verticies(graph *g){ vertex *v = g->verticies; while(v){ if(v->grabbed){ edge_list *el=v->edges; activate_vertex(g,v); while(el){ edge_list *next=el->next; edge *e=el->edge; vertex *other=(e->A==v?e->B:e->A); other->attached_to_grabbed=0; el=next; } v->grabbed=0; } v=v->next; } } vertex *find_vertex(graph *g, int x, int y){ vertex *v = g->verticies; vertex *match = 0; while(v){ vertex *next=v->next; int xd=x-v->x; int yd=y-v->y; if(xd*xd + yd*yd <= V_RADIUS_SQ) match=v; v=next; } return match; } // tenative selection; must be confirmed if next call should not clear void select_verticies(graph *g,int x1, int y1, int x2, int y2){ vertex *v = g->verticies; if(x1>x2){ int temp=x1; x1=x2; x2=temp; } if(y1>y2){ int temp=y1; y1=y2; y2=temp; } x1-=V_RADIUS; x2+=V_RADIUS; y1-=V_RADIUS; y2+=V_RADIUS; while(v){ if(v->selected_volatile)v->selected=0; if(!v->selected){ if(v->x>=x1 && v->x<=x2 && v->y>=y1 && v->y<=y2){ v->selected=1; v->selected_volatile=1; } } v=v->next; } } int num_selected_verticies(graph *g){ vertex *v = g->verticies; int count=0; while(v){ if(v->selected)count++; v=v->next; } return count; } void deselect_verticies(graph *g){ vertex *v = g->verticies; while(v){ v->selected=0; v->selected_volatile=0; v=v->next; } } void commit_volatile_selection(graph *g){ vertex *v = g->verticies; while(v){ v->selected_volatile=0; v=v->next; } } static vertex *split_vertex_list(vertex *v){ vertex *half=v; vertex *prevhalf=v; while(v){ v=v->next; if(v)v=v->next; prevhalf=half; half=half->next; } prevhalf->next=0; return half; } static vertex *randomize_helper(vertex *v){ vertex *w=split_vertex_list(v); if(w){ vertex *a = randomize_helper(v); vertex *b = randomize_helper(w); v=0; w=0; while(a && b){ if(random_yes(64)&1){ // pull off head of a if(w) w=w->next=a; else v=w=a; a=a->next; }else{ // pull off head of b if(w) w=w->next=b; else v=w=b; b=b->next; } } if(a) w->next=a; if(b) w->next=b; } return v; } void randomize_verticies(graph *g){ g->verticies=randomize_helper(g->verticies); } static void check_vertex_helper(graph *g, vertex *v, int reactivate){ int flag=0; if(v->x>=g->width){ v->x=g->width-1; flag=1; } if(v->x<0){ v->x=0; flag=1; } if(v->y>=g->height){ v->y=g->height-1; flag=0; } if(v->y<0){ v->y=0; flag=1; } if(flag){ if(v->edges){ deactivate_vertex(g,v); if(reactivate)activate_vertex(g,v); } } } static void check_vertex(graph *g, vertex *v){ check_vertex_helper(g,v,1); } void check_verticies(graph *g){ vertex *v=g->verticies; while(v){ vertex *next=v->next; check_vertex_helper(g,v,0); v=next; } v=g->verticies; while(v){ vertex *next=v->next; activate_vertex(g,v); v=next; } } void move_vertex(graph *g, vertex *v, int x, int y){ if(!v->grabbed) deactivate_vertex(g,v); v->x=x; v->y=y; check_vertex_helper(g,v,0); if(!v->grabbed) activate_vertex(g,v); } void move_selected_verticies(graph *g,int dx, int dy){ vertex *v = g->verticies; /* move selected verticies; do not reactivate, done during ungrab */ v=g->verticies; while(v){ vertex *next=v->next; if(v->selected){ v->x+=dx; v->y+=dy; check_vertex(g,v); //activate_vertex(g,v); } v=next; } } void scale_verticies(graph *g,float amount){ vertex *v=g->verticies; int x=g->width/2; int y=g->height/2; while(v){ vertex *next=v->next; deactivate_vertex(g,v); v->x=rint((v->x-x)*amount)+x; v->y=rint((v->y-y)*amount)+y; v=next; } v=g->verticies; while(v){ vertex *next=v->next; check_vertex(g,v); activate_vertex(g,v); v=next; } } vertex *new_board(graph *g, int num_v){ set_num_verticies(g,num_v); return g->verticies; } // take the mesh, which is always generated for a 'normal sized' board // (right now, 800x600), set the original vertex coordinates to the // 'nominal' board, and move the 'live' vertex positions to be // centered on what the current board size is. void impress_location(graph *g){ int xd = (g->width-g->orig_width)>>1; int yd = (g->height-g->orig_height)>>1; vertex *v=g->verticies; while(v){ v->orig_x=v->x; v->orig_y=v->y; v->x+=xd; v->y+=yd; v=v->next; } } /******** read/write board **********/ int graph_write(graph *g, FILE *f){ int i; vertex *v=g->verticies; edge *e=g->edges; vertex **flat = alloca(g->vertex_num*sizeof(*flat)); int *iflat = alloca(g->vertex_num*sizeof(*iflat)); i=0; while(v){ flat[v->num]=v; iflat[v->num]=i++; v=v->next; } fprintf(f,"scoring %ld %f %f %ld %c %d\n", g->original_intersections, g->intersection_mult, g->objective_mult, (long)get_timer(), (g->objective_lessthan?'*':'='),g->objective); fprintf(f,"board %d %d %d %d\n", g->width,g->height,g->orig_width,g->orig_height); v=g->verticies; while(v){ fprintf(f,"vertex %d %d %d %d %d\n", v->orig_x,v->orig_y,v->x,v->y,v->selected); v=v->next; } while(e){ fprintf(f,"edge %d %d\n",iflat[e->A->num],iflat[e->B->num]); e=e->next; } return 0; } int graph_read(graph *g,FILE *f){ char *line=NULL,c; int i,x,y,ox,oy,sel,A,B; size_t n=0; vertex **flat,*v; long l; new_board(g,0); // get all verticies / scoring first while(getline(&line,&n,f)>0){ if(sscanf(line,"vertex %d %d %d %d %d", &ox,&oy,&x,&y,&sel)==5){ v=get_vertex(g); v->orig_x=ox; v->orig_y=oy; v->x=x; v->y=y; v->selected=sel; } if(sscanf(line,"scoring %ld %f %f %ld %c %d\n", &g->original_intersections, &g->intersection_mult, &g->objective_mult, &l, &c,&g->objective)==6){ pause_timer(); set_timer(l); if(c == '*') g->objective_lessthan = 1; else g->objective_lessthan = 0; } sscanf(line,"board %d %d %d %d",&g->width,&g->height,&g->orig_width,&g->orig_height); } rewind(f); flat=alloca(g->vertex_num*sizeof(*flat)); v=g->verticies; i=0; while(v){ flat[v->num]=v; v=v->next; } // get edges next while(getline(&line,&n,f)>0){ if(sscanf(line,"edge %d %d",&A,&B)==2){ if(A>=0 && Avertex_num && B>=0 && Bvertex_num) add_edge(g,flat[A],flat[B]); else fprintf(stderr,_("WARNING: edge references out of range vertex in save file\n")); } sscanf(line,"int %ld",&g->original_intersections); } rewind(f); free(line); return 0; } void graph_resize(graph *g, int width, int height){ vertex *v=g->verticies; edge *e=g->edges; int xd=(width-g->width)*.5; int yd=(height-g->height)*.5; // recenter all the verticies; doesn't require recomputation while(v){ v->x+=xd; v->y+=yd; v=v->next; } // recenter associated intersections as well; they all have // cached location (used only for drawing) while(e){ intersection *i = e->i.next; while(i){ if(i->paired > i){ i->x+=xd; i->y+=yd; } i=i->next; } e=e->next; } g->width=width; g->height=height; // verify all verticies are onscreen check_verticies(g); } gplanarity-17906/gameboard_draw_main.c0000644000175000017500000002715711543161637017743 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include "graph.h" #include "gameboard.h" #include "dialog_level.h" #include "main.h" /* The gPlanarity gameboard consists of a background and a foreground. The background is a predrawn backdrop of anything not currently being animated. The foreground is 'active' elements of the UI and anything that floats above them. There are also two translucent bars, top and bottom, that hold the score and buttonbar respectively. These are prerendered surfaces that are blitted onto the foreground during exposes */ void draw_foreground(Gameboard *g,cairo_t *c,int x,int y,int w,int h){ /* Edges attached to the grabbed vertex are drawn here */ if(g->grabbed_vertex && !g->hide_lines){ edge_list *el=g->grabbed_vertex->edges; setup_foreground_edge(c); while(el){ edge *e=el->edge; /* no need to check rectangle; if they're to be drawn, they'll always be in the rect due to expose combining */ draw_edge(c,e); el=el->next; } finish_edge(c); } if(g->group_drag){ vertex *v = g->g.verticies; setup_foreground_edge(c); while(v){ if(v->grabbed){ /* no need to check rectangle; if they're to be drawn, they'll always be in the rect due to expose combining */ draw_edges(c,v,g->dragx,g->dragy); } v=v->next; } finish_edge(c); } /* verticies drawn over the edges */ { vertex *v = g->g.verticies; float alpha = 1.*g->fade.count/FADE_FRAMES; int clipx = x-V_RADIUS; int clipw = x+w+V_RADIUS; int clipy = y-V_RADIUS; int cliph = y+h+V_RADIUS; while(v){ if(v->grabbed && g->group_drag){ vertex tv; tv.x=v->x+g->dragx; tv.y=v->y+g->dragy; /* is the vertex in the expose rectangle? */ if(tv.x>=clipx && tv.x<=clipw && tv.y>=clipy && tv.y<=cliph){ draw_vertex(c,&tv,g->vertex_ghost); } }else{ /* is the vertex in the expose rectangle? */ if(v->x>=clipx && v->x<=clipw && v->y>=clipy && v->y<=cliph){ if(v == g->grabbed_vertex && !g->group_drag) { draw_vertex(c,v,g->vertex_grabbed); } else if( v->selected ){ draw_vertex(c,v,g->vertex_sel); if(v->fading) draw_vertex_with_alpha(c,v,g->vertex_ghost,alpha); } else if ( v == g->lit_vertex){ draw_vertex(c,v,g->vertex_lit); } else if (v->attached_to_grabbed){ draw_vertex(c,v,g->vertex_attached); }else{ draw_vertex(c,v,g->vertex); if(v->fading) draw_vertex_with_alpha(c,v,g->vertex_attached,alpha); } } } v=v->next; } } if(g->selection_grab) draw_selection_rectangle(g,c); } static void draw_background(Gameboard *g,cairo_t *c){ edge *e=g->g.edges; cairo_set_source_rgb(c,1,1,1); cairo_paint(c); if(!g->hide_lines){ setup_background_edge(c); while(e){ if(e->active) draw_edge(c,e); e=e->next; } finish_edge(c); } } static void draw_background_realpart(Gameboard *g,cairo_t *c, int x, int y, int w, int h){ edge *e=g->g.edges; int x2 = x+w-1+E_LINE; int y2 = y+h-1+E_LINE; x-=E_LINE; y-=E_LINE; cairo_set_source_rgb(c,1,1,1); cairo_paint(c); if(!g->hide_lines){ setup_background_edge(c); while(e){ int ex1 = e->A->x; int ex2 = e->B->x; int ey1 = e->A->y; int ey2 = e->B->y; if(ex1ex2 || x2next;continue;} }else{ if(x>ex1 || x2next;continue;} } if(ey1ey2 || y2next;continue;} }else{ if(y>ey1 || y2next;continue;} } draw_edge(c,e); e=e->next; } finish_edge(c); } } /* Several very-high-level drawing sequences triggered by various actions in the game *********************************************/ /* request that the background plane be redrawn from scratch to match current game state and the full window invalidated to request an expose. As other layers are always drawn on the fly, this is effectively a full refresh of the screen. This is done as sparingly as possible and only within large state changes as it's not fast enough for animation. */ void update_full(Gameboard *g){ cairo_t *c = cairo_create(g->background); g->delayed_background=0; // render the far background plane draw_background(g,c); update_push(g,c); cairo_destroy(c); expose_full(g); } void expose_full(Gameboard *g){ GtkWidget *widget = GTK_WIDGET(g); GdkRectangle r; r.x=0; r.y=0; r.width=g->g.width; r.height=g->g.height; gdk_window_invalidate_rect (widget->window, &r, FALSE); } void update_draw(Gameboard *g){ cairo_t *c = cairo_create(g->background); g->delayed_background=0; // render the far background plane draw_background(g,c); update_push(g,c); cairo_destroy(c); gameboard_draw(g,0,0,g->g.width,g->g.height); } /* request a full redraw update to be processed immediately *after* the next expose. This is used to increase apparent interactivity of a vertex 'grab' where the background must be redrawn, but the vertex itself should react immediately */ void update_full_delayed(Gameboard *g){ g->delayed_background=1; } /* specialized update request for when re-adding a grabbed vertex's edges to the background. Doesn't require a full redraw. */ void update_add_vertex(Gameboard *g, vertex *v){ GtkWidget *widget = GTK_WIDGET(g); edge_list *el=v->edges; cairo_t *c = cairo_create(g->background); if(!g->hide_lines){ setup_background_edge(c); while(el){ edge *e=el->edge; draw_edge(c,e); el=el->next; } finish_edge(c); } cairo_destroy(c); invalidate_attached(widget,v); } /* as above for re-inserting group drag edges to the background. Doesn't require a full redraw. */ void update_add_selgroup(Gameboard *g){ if(!g->hide_lines){ GtkWidget *widget = GTK_WIDGET(g); cairo_t *c = cairo_create(g->background); vertex *v = g->g.verticies; setup_background_edge(c); while(v){ if(v->grabbed){ edge_list *el=v->edges; while(el){ edge *e=el->edge; // draw the edge only once if it spans two grabbed verticies if(e->A->grabbed==0 || e->B->grabbed==0 || v==e->A) draw_edge(c,e); el=el->next; } } invalidate_attached(widget,v); v=v->next; } finish_edge(c); cairo_destroy(c); } } /* top level draw function called by expose. May also be called directly to immediately render a region of the board without going through the expose mechanism (necessary for some button draw operations where expose combining causes huge, slow in-server alpha blends that are undesirable) */ void gameboard_draw(Gameboard *g, int x, int y, int w, int h){ cairo_t *c = cairo_create(g->foreground); if (w==0 || h==0) return; if(g->realtime_background){ draw_background_realpart(g,c,x,y,w,h); }else{ // copy background to foreground draw buffer cairo_set_source_surface(c,g->background,0,0); cairo_rectangle(c,x,y,w,h); cairo_fill(c); } if(!g->pushed_curtain){ draw_foreground(g,c,x,y,w,h); // copy in any of the score or button surfaces? if(yforescore,0,0); cairo_rectangle(c, x,y,w, min(SCOREHEIGHT-y,h)); cairo_fill(c); } if(y+h>g->w.allocation.height-SCOREHEIGHT){ cairo_set_source_surface(c,g->forebutton,0, g->w.allocation.height-SCOREHEIGHT); cairo_rectangle(c, x,y,w,h); cairo_fill(c); } if(g->show_intersections) draw_intersections(g,&g->g,c,x,y,w,h); } render_level_icons(g,c,x,y,w,h); expose_buttons(g,c,x,y,w,h); cairo_destroy(c); // blit to window { cairo_t *wc = gdk_cairo_create(g->w.window); cairo_set_source_surface(wc,g->foreground,0,0); cairo_rectangle(wc,x,y,w,h); cairo_fill(wc); cairo_destroy(wc); } if(g->delayed_background)update_full(g); g->first_expose=1; } cairo_surface_t *gameboard_read_icon(char *filename, char *ext, Gameboard *b){ char *name=alloca(strlen(boarddir)+strlen(filename)+strlen(ext)+2); name[0]=0; strcat(name,boarddir); strcat(name,filename); strcat(name,"."); strcat(name,ext); cairo_surface_t *s = cairo_image_surface_create_from_png(name); if(s==NULL || cairo_surface_status(s)!=CAIRO_STATUS_SUCCESS) fprintf(stderr,_("ERROR: Could not load board icon \"%s\"\n"), name); cairo_t *c = cairo_create(s); borderbox_path(c,1.5,1.5,ICON_WIDTH-3,ICON_HEIGHT-3); cairo_set_operator (c, CAIRO_OPERATOR_DEST_OVER); cairo_set_line_width(c,B_LINE); //cairo_set_source_rgba (c, B_COLOR); //cairo_fill_preserve (c); cairo_set_source_rgba (c, B_LINE_COLOR); cairo_stroke (c); cairo_destroy(c); return s; } int gameboard_write_icon(char *filename, char *ext, Gameboard *b, graph *g, int lines, int intersections){ char *name=alloca(strlen(boarddir)+strlen(filename)+strlen(ext)+2); name[0]=0; strcat(name,boarddir); strcat(name,filename); strcat(name,"."); strcat(name,ext); { cairo_surface_t *s = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ICON_WIDTH, ICON_HEIGHT); cairo_t *c = cairo_create(s); edge *e=g->edges; vertex *v = g->verticies; cairo_save(c); cairo_set_operator(c,CAIRO_OPERATOR_CLEAR); cairo_set_source_rgba (c, 1,1,1,1); cairo_paint(c); cairo_restore(c); cairo_scale(c,(float)ICON_WIDTH/g->width,(float)ICON_HEIGHT/g->height); if(lines){ setup_background_edge(c); while(e){ draw_edge(c,e); e=e->next; } finish_edge(c); } cairo_set_line_width(c,V_LINE); while(v){ // dirty, but we may not have the cached vertex surface yet. cairo_arc(c,v->x,v->y,V_RADIUS,0,2*M_PI); cairo_set_source_rgb(c,V_FILL_IDLE_COLOR); cairo_fill_preserve(c); cairo_set_source_rgb(c,V_LINE_COLOR); cairo_stroke(c); v=v->next; } if(intersections) draw_intersections(b,g,c,0,0,g->width,g->height); if(cairo_surface_write_to_png(s,name) != CAIRO_STATUS_SUCCESS){ fprintf(stderr,_("ERROR: Could not save board icon \"%s\"\n"), name); return -1; } cairo_destroy(c); cairo_surface_destroy(s); } return 0; } int gameboard_icon_exists(char *filename, char *ext){ struct stat s; char *name=alloca(strlen(boarddir)+strlen(filename)+strlen(ext)+2); name[0]=0; strcat(name,boarddir); strcat(name,filename); strcat(name,"."); strcat(name,ext); if(stat(name,&s))return 0; return 1; } gplanarity-17906/gameboard_logic_button.c0000644000175000017500000003700711543161637020465 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include #include #include #include "graph.h" #include "gameboard.h" #include "gameboard_draw_button.h" #include "main.h" /************************ manage the buttons for buttonbar and dialogs *********************/ /* determine the x/y/w/h box around the rollover text */ static GdkRectangle rollover_box(Gameboard *g, buttonstate *b){ GdkRectangle r; int width = g->g.width; int height = g->g.height; int x = b->x - b->ex.width/2 + b->ex.x_bearing -2; int y = b->y - BUTTON_RADIUS - BUTTON_TEXT_BORDER + b->ex.y_bearing -2; if(xex.width >= width - BUTTON_TEXT_BORDER) x = width - BUTTON_TEXT_BORDER - b->ex.width; if(y+b->ex.height >= height - BUTTON_TEXT_BORDER) y = height - BUTTON_TEXT_BORDER - b->ex.height; r.x=x; r.y=y; r.width=b->ex.width+5; r.height=b->ex.height+5; return r; } /* draw the actual rollover */ static void stroke_rollover(Gameboard *g, buttonstate *b, cairo_t *c){ set_font(c, BUTTON_TEXT_SIZE, 0, 1); { GdkRectangle r=rollover_box(g,b); cairo_move_to (c, r.x - b->ex.x_bearing +2, r.y -b->ex.y_bearing+2 ); cairo_set_line_width(c,3); cairo_set_source_rgba(c,1,1,1,.9); cairo_text_path (c, b->rollovertext); cairo_stroke(c); cairo_set_source_rgba(c,BUTTON_TEXT_COLOR); cairo_move_to (c, r.x - b->ex.x_bearing +2, r.y -b->ex.y_bearing+2 ); cairo_show_text (c, b->rollovertext); } } /* request an expose for a button region*/ static void invalidate_button(Gameboard *g,buttonstate *b){ GdkRectangle r; r.x=b->x-BUTTON_RADIUS-1; r.y=b->y-BUTTON_RADIUS-1; r.width=BUTTON_RADIUS*2+2; r.height=BUTTON_RADIUS*2+2; gdk_window_invalidate_rect(g->w.window,&r,FALSE); } /* request an expose for a rollover region*/ static void invalidate_rollover(Gameboard *g,buttonstate *b){ GdkRectangle r = rollover_box(g,b); invalidate_button(g,b); gdk_window_invalidate_rect(g->w.window,&r,FALSE); } /* like invalidation, but just expands a rectangular region */ static void expand_rectangle_button(buttonstate *b,GdkRectangle *r){ int x=b->x-BUTTON_RADIUS-1; int y=b->y-BUTTON_RADIUS-1; int x2=x+BUTTON_RADIUS*2+2; int y2=y+BUTTON_RADIUS*2+2; int rx2=r->x+r->width; int ry2=r->y+r->height; if(r->width==0 || r->height==0){ r->x=x; r->y=y; r->width=x2-x; r->height=y2-y; } if(xx) r->x=x; if(yy) r->y=y; if(rx2width=rx2-r->x; if(ry2height=ry2-r->y; } /* like invalidation, but just expands a rectangular region */ static void expand_rectangle_rollover(Gameboard *g,buttonstate *b,GdkRectangle *r){ GdkRectangle rr = rollover_box(g,b); int x=rr.x; int y=rr.y; int x2=x+rr.width; int y2=y+rr.height; int rx2=r->x+r->width; int ry2=r->y+r->height; if(r->width==0 || r->height==0){ r->x=x; r->y=y; r->width=x2-x; r->height=y2-y; } if(xx) r->x=x; if(yy) r->y=y; if(rx2width=rx2-r->x; if(ry2height=ry2-r->y; } /* cache buttons as small surfaces */ static cairo_surface_t *cache_button(Gameboard *g, void (*draw)(cairo_t *c, double x, double y), double pR,double pG,double pB,double pA, double fR,double fG,double fB,double fA){ cairo_t *wc = gdk_cairo_create(g->w.window); cairo_surface_t *ret = cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR_ALPHA, BUTTON_RADIUS*2+1, BUTTON_RADIUS*2+1); cairo_t *c = cairo_create(ret); cairo_destroy (wc); cairo_save(c); cairo_set_operator(c,CAIRO_OPERATOR_CLEAR); cairo_set_source_rgba (c, 1,1,1,1); cairo_paint(c); cairo_restore(c); cairo_set_source_rgba(c,fR,fG,fB,fA); cairo_set_line_width(c,BUTTON_LINE_WIDTH); draw(c,BUTTON_RADIUS+.5,BUTTON_RADIUS+.5); cairo_set_source_rgba(c,pR,pG,pB,pA); cairo_stroke(c); cairo_destroy(c); return ret; } /* determine the x/y/w/h box around a button */ static GdkRectangle button_box(buttonstate *b){ GdkRectangle r; int x = b->x - BUTTON_RADIUS-1; int y = b->y - BUTTON_RADIUS-1; r.x=x; r.y=y; r.width = BUTTON_RADIUS*2+2; r.height= BUTTON_RADIUS*2+2; return r; } static int animate_x_axis(Gameboard *g, buttonstate *b, GdkRectangle *r){ int ret=0; if(b->x_target != b->x){ ret=1; expand_rectangle_button(b,r); if(b->rollover) expand_rectangle_rollover(g,b,r); if(b->x_target > b->x){ b->x+=DEPLOY_DELTA; if(b->x>b->x_target)b->x=b->x_target; }else{ b->x-=DEPLOY_DELTA; if(b->xx_target)b->x=b->x_target; } expand_rectangle_button(b,r); if(b->rollover) expand_rectangle_rollover(g,b,r); } return ret; } static int animate_y_axis(Gameboard *g, buttonstate *b, GdkRectangle *r){ int ret=0; if(b->y_target != b->y){ ret=1; expand_rectangle_button(b,r); if(b->rollover) expand_rectangle_rollover(g,b,r); if(b->y_target > b->y){ b->y+=DEPLOY_DELTA; if(b->y>b->y_target)b->y=b->y_target; }else{ b->y-=DEPLOY_DELTA; if(b->yy_target)b->y=b->y_target; } expand_rectangle_button(b,r); if(b->rollover) expand_rectangle_rollover(g,b,r); } if(b->alphad != b->y_active - b->y){ double alpha=0; if(b->y_inactive>b->y_active){ if(b->y<=b->y_active) alpha=1.; else if (b->y>=b->y_inactive) alpha=0.; else alpha = (double)(b->y_inactive-b->y)/(b->y_inactive-b->y_active); }else if (b->y_inactivey_active){ if(b->y>=b->y_active) alpha=1.; else if (b->y<=b->y_inactive) alpha=0.; else alpha = (double)(b->y_inactive-b->y)/(b->y_inactive-b->y_active); } if(alpha != b->alpha){ ret=1; expand_rectangle_button(b,r); b->alpha=alpha; } b->alphad = b->y_active - b->y; } return ret; } /* do the animation math for one button for one frame */ static int animate_one(Gameboard *g,buttonstate *b, GdkRectangle *r){ int ret=0; /* does this button need to be deployed? */ if(g->b.sweeperd>0){ if(b->y_target != b->y_active){ if(g->b.sweeper >= b->sweepdeploy){ b->y_target=b->y_active; ret=1; } } } /* does this button need to be undeployed? */ if(g->b.sweeperd<0){ if(b->y_target != b->y_inactive){ if(-g->b.sweeper >= b->sweepdeploy){ b->y_target=b->y_inactive; ret=1; } } } ret |= animate_x_axis(g,b,r); ret |= animate_y_axis(g,b,r); return ret; } /******************** toplevel abstraction calls *********************/ /* initialize the persistent caches; called once when gameboard is first created */ void init_buttons(Gameboard *g){ buttonstate *states=g->b.states; memset(g->b.states,0,sizeof(g->b.states)); states[0].idle = cache_button(g, path_button_exit, BUTTON_QUIT_IDLE_PATH, BUTTON_QUIT_IDLE_FILL); states[0].lit = cache_button(g, path_button_exit, BUTTON_QUIT_LIT_PATH, BUTTON_QUIT_LIT_FILL); states[1].idle = cache_button(g, path_button_back, BUTTON_IDLE_PATH, BUTTON_IDLE_FILL); states[1].lit = cache_button(g, path_button_back, BUTTON_LIT_PATH, BUTTON_LIT_FILL); states[2].idle = cache_button(g, path_button_reset, BUTTON_IDLE_PATH, BUTTON_IDLE_FILL); states[2].lit = cache_button(g, path_button_reset, BUTTON_LIT_PATH, BUTTON_LIT_FILL); states[3].idle = cache_button(g, path_button_pause, BUTTON_IDLE_PATH, BUTTON_IDLE_FILL); states[3].lit = cache_button(g, path_button_pause, BUTTON_LIT_PATH, BUTTON_LIT_FILL); states[4].idle = cache_button(g, path_button_help, BUTTON_IDLE_PATH, BUTTON_IDLE_FILL); states[4].lit = cache_button(g, path_button_help, BUTTON_LIT_PATH, BUTTON_LIT_FILL); states[5].idle = cache_button(g, path_button_expand, BUTTON_IDLE_PATH, BUTTON_IDLE_FILL); states[5].lit = cache_button(g, path_button_expand, BUTTON_LIT_PATH, BUTTON_LIT_FILL); states[6].idle = cache_button(g, path_button_shrink, BUTTON_IDLE_PATH, BUTTON_IDLE_FILL); states[6].lit = cache_button(g, path_button_shrink, BUTTON_LIT_PATH, BUTTON_LIT_FILL); states[7].idle = cache_button(g, path_button_lines, BUTTON_IDLE_PATH, BUTTON_IDLE_FILL); states[7].lit = cache_button(g, path_button_lines, BUTTON_LIT_PATH, BUTTON_LIT_FILL); states[8].idle = cache_button(g, path_button_int, BUTTON_IDLE_PATH, BUTTON_IDLE_FILL); states[8].lit = cache_button(g, path_button_int, BUTTON_LIT_PATH, BUTTON_LIT_FILL); states[9].idle = cache_button(g, path_button_check, BUTTON_CHECK_IDLE_PATH, BUTTON_CHECK_IDLE_FILL); states[9].lit = cache_button(g, path_button_check, BUTTON_CHECK_LIT_PATH, BUTTON_CHECK_LIT_FILL); states[10].idle= cache_button(g, path_button_play, BUTTON_CHECK_IDLE_PATH, BUTTON_CHECK_IDLE_FILL); states[10].lit = cache_button(g, path_button_play, BUTTON_CHECK_LIT_PATH, BUTTON_CHECK_LIT_FILL); } /* match x/y to a button if any */ buttonstate *find_button(Gameboard *g, int x,int y){ int i; buttonstate *states=g->b.states; for(i=0;iposition>0) if( (b->x-x)*(b->x-x) + (b->y-y)*(b->y-y) <= BUTTON_RADIUS*BUTTON_RADIUS+4) if(b->y != b->y_inactive) return b; } return 0; } /* set a button to pressed or lit */ void button_set_state(Gameboard *g, buttonstate *b, int rollover, int press){ int i; buttonstate *states=g->b.states; if(b->rollover == rollover && b->press == press)return; for(i=0;iposition>0){ if(bb!=b){ if(bb->rollover) invalidate_rollover(g,bb); if(bb->press) invalidate_button(g,bb); bb->rollover=0; bb->press=0; }else{ if(bb->rollover != rollover) invalidate_rollover(g,bb); if(bb->press != press) invalidate_button(g,bb); bb->rollover=rollover; bb->press=press; } } } g->b.allclear=0; } /* cache the text extents of a rollover */ void rollover_extents(Gameboard *g, buttonstate *b){ cairo_t *c = cairo_create(g->foreground); set_font(c, BUTTON_TEXT_SIZE, 0, 1); cairo_text_extents (c, b->rollovertext, &b->ex); cairo_destroy(c); } /* perform a single frame of animation for all buttons/rollovers */ gboolean animate_button_frame(gpointer ptr){ Gameboard *g=(Gameboard *)ptr; GdkRectangle expose; buttonstate *states=g->b.states; int ret=0,i,pos; if(!g->first_expose)return 1; g->b.sweeper += g->b.sweeperd; /* avoid the normal expose event mechanism during the button animations. This direct method is much faster as it won't accidentally combine exposes over long stretches of alpha-blended surfaces. */ for(pos=1;pos<=3;pos++){ memset(&expose,0,sizeof(expose)); for(i=0;ib.sweeperd = 0; if(!ret && g->button_timer!=0){ g_source_remove(g->button_timer); g->button_timer=0; } if(!ret && g->button_callback) // undeploy finished... call the undeploy callback g->button_callback(g); return ret; } /* the normal expose method for all buttons; called from the master widget's expose */ void expose_buttons(Gameboard *g,cairo_t *c, int x,int y,int w,int h){ int i; buttonstate *states=g->b.states; for(i=0;iposition>0){ GdkRectangle r = rollover_box(g,b); GdkRectangle br = button_box(b); if(x < br.x+br.width && y < br.y+br.height && x+w > br.x && y+h > br.y) { cairo_set_source_surface(c, (b->rollover || b->press ? b->lit : b->idle), br.x, br.y); if(b->press) cairo_paint_with_alpha(c,b->alpha); cairo_paint_with_alpha(c,b->alpha); } if((b->rollover || b->press) && b->y_target!=b->y_inactive) if(x < r.x+r.width && y < r.y+r.height && x+w > r.x && y+h > r.y) stroke_rollover(g,b,c); } } } /* resize the button bar; called from master resize in gameboard */ void resize_buttons(Gameboard *g,int oldw,int oldh,int w,int h){ int i; int dx=w/2-oldw/2; int dy=h/2-oldh/2; buttonstate *states=g->b.states; for(i=0;ib.states; if(!g->b.allclear){ for(i=0;iposition){ if(bb->rollover) invalidate_rollover(g,bb); if(bb->press) invalidate_button(g,bb); bb->rollover=0; bb->press=0; } } } g->b.allclear=1; g->b.grabbed=0; } void deploy_buttons(Gameboard *g, void (*callback)(Gameboard *g)){ if(!g->b.buttons_ready){ // sweep across the buttons inward from the horizontal edges; when // the sweep passes a button it is set to deploy by making the // target y equal to the active y target. g->b.sweeper = 0; g->b.sweeperd = 1; g->button_callback = callback; if(g->button_timer!=0) g_source_remove(g->button_timer); g->button_timer = g_timeout_add(BUTTON_ANIM_INTERVAL, animate_button_frame, (gpointer)g); g->b.buttons_ready=1; } } void undeploy_buttons(Gameboard *g, void (*callback)(Gameboard *ptr)){ if(g->b.buttons_ready){ button_clear_state(g); g->b.buttons_ready=0; // sweep across the buttons outward from the center; when // the sweep passes a button it is set to undeploy by making the // target y equal to the inactive y target. g->b.sweeper = 0; g->b.sweeperd = -1; g->button_callback = callback; if(g->button_timer!=0) g_source_remove(g->button_timer); g->button_timer = g_timeout_add(BUTTON_ANIM_INTERVAL, animate_button_frame, (gpointer)g); }else callback(g); } gplanarity-17906/levelstate.h0000644000175000017500000000276711543161637016156 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ extern int levelstate_write(); extern int levelstate_read(); extern long levelstate_total_hiscore(); extern long levelstate_get_hiscore(); extern int levelstate_in_progress(); extern int levelstate_next(); extern int levelstate_prev(); extern int get_level_num(); extern char *get_level_desc(); extern void levelstate_finish(); extern void levelstate_go(); extern void levelstate_resume(); extern void levelstate_reset(); extern void set_in_progress(); extern int levelstate_limit(); extern cairo_surface_t* levelstate_get_icon(int num); gplanarity-17906/gameboard_draw_selection.c0000644000175000017500000000427211543161637020775 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include "graph.h" #include "gameboard.h" // draw selection box void draw_selection_rectangle(Gameboard *g,cairo_t *c){ cairo_set_source_rgba(c,SELECTBOX_COLOR); cairo_rectangle(c,g->selectionx, g->selectiony, g->selectionw, g->selectionh); cairo_fill(c); } // invalidate the selection box plus enough area to catch any verticies void invalidate_selection(GtkWidget *widget){ Gameboard *g = GAMEBOARD (widget); GdkRectangle r; r.x = g->selectionx - (V_RADIUS + V_LINE)*2; r.y = g->selectiony - (V_RADIUS + V_LINE)*2; r.width = g->selectionw + (V_RADIUS + V_LINE)*4; r.height = g->selectionh + (V_RADIUS + V_LINE)*4; gdk_window_invalidate_rect (widget->window, &r, FALSE); } // invalidate the selection box plus enough area to catch any verticies void invalidate_verticies_selection(GtkWidget *widget){ Gameboard *g = GAMEBOARD (widget); vertex *v=g->g.verticies; while(v){ if(v->selected){ invalidate_vertex_off(widget,v,g->dragx,g->dragy); invalidate_edges(widget,v,g->dragx,g->dragy); } v=v->next; } } gplanarity-17906/dialog_finish.c0000644000175000017500000001351611543161637016572 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include #include #include "graph.h" #include "timer.h" #include "gameboard.h" #include "gameboard_draw_button.h" #include "levelstate.h" #include "dialog_finish.h" #include "dialog_level.h" #include "main.h" static void finish_post (Gameboard *g){ // back to buttonbar activity! g->finish_dialog_active=0; pop_curtain(g); levelstate_next(); levelstate_go(); enter_game(g); } static void finish_level (Gameboard *g){ // back to buttonbar activity! g->finish_dialog_active=0; pop_curtain(g); level_dialog(g,1); } static void finish_quit (Gameboard *g){ gtk_main_quit(); } static void local_go (Gameboard *g){ undeploy_buttons(g,finish_post); } static void local_level (Gameboard *g){ undeploy_buttons(g,finish_level); } static void local_quit (Gameboard *g){ undeploy_buttons(g,finish_quit); } /* initialize the rather weird little animation engine */ static void setup_finish_buttons(Gameboard *g,int bw, int bh){ int i; int w=g->g.width; int h=g->g.height; buttonstate *states=g->b.states; states[0].rollovertext=_("exit gPlanarity"); states[1].rollovertext=_("level selection menu"); states[10].rollovertext=_("play next level!"); states[0].callback = local_quit; states[1].callback = local_level; states[10].callback = local_go; for(i=0;ix = b->x_target = w/2 - bw/2 + FINISH_BUTTON_BORDER; b->y_active = h/2 + bh/2 - FINISH_BUTTON_Y; b->y = b->y_target = b->y_inactive = b->y_active + BUTTON_EXPOSE; b->sweepdeploy = 0; } { buttonstate *b=states+1; b->x = b->x_target = w/2; b->y_active = h/2 + bh/2 - FINISH_BUTTON_Y; b->y = b->y_target = b->y_inactive = b->y_active + BUTTON_EXPOSE; b->sweepdeploy = SWEEP_DELTA; } { buttonstate *b=states+10; b->x = b->x_target = w/2 + bw/2 - FINISH_BUTTON_BORDER; b->y_active = h/2 + bh/2 - FINISH_BUTTON_Y; b->y = b->y_target = b->y_inactive = b->y_active + BUTTON_EXPOSE; b->sweepdeploy = SWEEP_DELTA*2; } for(i=0;ig.width; int h= g->g.height; cairo_t *c = cairo_create(g->background); borderbox_path(c, w/2 - FINISHBOX_WIDTH/2, h/2 - FINISHBOX_HEIGHT/2, FINISHBOX_WIDTH, FINISHBOX_HEIGHT); cairo_set_source_rgb(c,1,1,1); cairo_fill(c); centerbox(c, w/2 - FINISHBOX_WIDTH/2, h/2 - FINISHBOX_HEIGHT/2, FINISHBOX_WIDTH, SCOREHEIGHT); centerbox(c, w/2 - FINISHBOX_WIDTH/2 , h/2 + FINISHBOX_HEIGHT/2 - SCOREHEIGHT, FINISHBOX_WIDTH, SCOREHEIGHT); { char *time = get_timer_string(); char buffer[160]; int time_bonus=graphscore_get_bonus(&g->g); int y; set_font(c,18,18,0,1); cairo_set_source_rgba (c, TEXT_COLOR); y=h/2-FINISHBOX_HEIGHT/2+SCOREHEIGHT/2; render_text_centered(c,_("Level Complete!"), w/2,y);y+=45; set_font(c,16,16,0,0); snprintf(buffer,160,_("Elapsed: %s"),time); render_bordertext_centered(c,buffer, w/2,y);y+=24; snprintf(buffer,160,_("Base score: %d points"),graphscore_get_raw_score(&g->g)); render_bordertext_centered(c,buffer, w/2,y);y+=24; if(graphscore_get_multiplier_percent(&g->g)>100){ cairo_save(c); set_font(c,16,16,0,1); cairo_set_source_rgba (c, HIGH_COLOR); snprintf(buffer,160,_("Objective Exceeded! %d%%"),graphscore_get_multiplier_percent(&g->g)); render_bordertext_centered(c,buffer, w/2,y);y+=24; cairo_restore(c); } snprintf(buffer,160,_("Time bonus: %d points"),time_bonus); render_bordertext_centered(c,buffer, w/2,y);y+=35; set_font(c,16,16,0,1); snprintf(buffer,160,_("Final score: %d points"),graphscore_get_score(&g->g)+time_bonus); render_bordertext_centered(c,buffer, w/2,y);y+=24; if(graphscore_get_score(&g->g)+time_bonus >= levelstate_get_hiscore()){ cairo_set_source_rgba (c, HIGH_COLOR); render_bordertext_centered(c,_("A high score!"), w/2,y);y+=43; cairo_set_source_rgba (c, TEXT_COLOR); }else{ snprintf(buffer,160,_("Previous best: %ld points"),levelstate_get_hiscore()); render_bordertext_centered(c,buffer, w/2,y);y+=43; } render_bordertext_centered(c,_("Total score to date:"), w/2,y); y+=21; snprintf(buffer,160,_("%ld points"),levelstate_total_hiscore()); render_bordertext_centered(c,buffer, w/2,y); } cairo_destroy(c); } void finish_level_dialog(Gameboard *g){ g->finish_dialog_active=1; // set up new buttons setup_finish_buttons(g,FINISHBOX_WIDTH, FINISHBOX_HEIGHT); // draw pausebox push_curtain(g,draw_finishbox); // deploy new buttons deploy_buttons(g,0); } gplanarity-17906/gameboard_draw_buttonbar.c0000644000175000017500000000257411543161637021013 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include #include #include "graph.h" #include "gameboard.h" void draw_buttonbar_box (Gameboard *g){ cairo_t *c = cairo_create(g->forebutton); cairo_save(c); cairo_set_operator(c,CAIRO_OPERATOR_CLEAR); cairo_set_source_rgba (c, 1,1,1,1); cairo_paint(c); cairo_restore(c); bottombox(g,c,g->g.width,SCOREHEIGHT); cairo_destroy(c); } gplanarity-17906/graph.h0000644000175000017500000001016711543161637015100 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define V_RADIUS_SQ (V_RADIUS*V_RADIUS) #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) typedef struct vertex { int num; int x; int y; int orig_x; int orig_y; int active; int selected_volatile; int selected; int grabbed; int attached_to_grabbed; int fading; struct edge_list *edges; struct vertex *next; } vertex; typedef struct intersection { struct intersection *prev; struct intersection *next; struct intersection *paired; double x; double y; } intersection; typedef struct edge{ vertex *A; vertex *B; int active; intersection i; // correct, not a pointer struct edge *next; } edge; typedef struct edge_list{ edge *edge; struct edge_list *next; } edge_list; typedef struct graph { vertex *verticies; int vertex_num; edge *edges; long active_intersections; int num_edges; int num_edges_active; int width; int height; int orig_width; int orig_height; // scoring related metadata long original_intersections; float intersection_mult; int objective; int objective_lessthan; float objective_mult; } graph; typedef struct graphmeta{ int num; char *id; char *desc; void (*gen)(graph *,int arg); int gen_arg; int unlock_plus; } graphmeta; #include extern vertex *new_board(graph *g, int num_v); extern vertex *find_vertex(graph *g, int x, int y); extern edge_list *add_edge_to_list(edge_list *l, edge *e); extern void release_edge_list(edge_list *el); extern edge *new_edge(vertex *A, vertex *B); extern void release_edge_list(edge_list *el); extern void insert_edge(graph *g, edge *e); extern int intersectsV(vertex *L1, vertex *L2, vertex *M1, vertex *M2, double *xo, double *yo); extern int intersects(int L1x, int L1y, int L2x, int L2y, int M1x, int M1y, int M2x, int M2y, double *xo, double *yo); extern void move_vertex(graph *g, vertex *v, int x, int y); extern void grab_vertex(graph *g, vertex *v); extern void grab_selected(graph *g); extern void ungrab_vertex(graph *g,vertex *v); extern void ungrab_verticies(graph *g); extern void activate_vertex(graph *g, vertex *v); extern void deactivate_vertex(graph *g, vertex *v); extern void select_verticies(graph *g, int x1, int y1, int x2, int y2); extern void deselect_verticies(graph *g); extern void move_selected_verticies(graph *g, int dx, int dy); extern void scale_verticies(graph *g, float amount); extern void randomize_verticies(graph *g); extern edge *add_edge(graph *g,vertex *A, vertex *B); extern int exists_edge(vertex *a, vertex *b); extern int num_selected_verticies(graph *g); extern void check_verticies(graph *g); extern void impress_location(graph *g); extern void commit_volatile_selection(graph *g); extern void activate_verticies(graph *g); extern int graph_write(graph *g, FILE *f); extern int graph_read(graph *g, FILE *f); extern void graph_release(graph *g); extern int graphscore_get_score(graph *g); extern int graphscore_get_raw_score(graph *g); extern int graphscore_get_multiplier_percent(graph *g); extern int graphscore_get_bonus(graph *g); extern char *graphscore_objective_string(graph *g); extern void graph_resize(graph *g, int width, int height); gplanarity-17906/dialog_level.c0000644000175000017500000001003111543161637016406 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include #include #include "graph.h" #include "timer.h" #include "gameboard.h" #include "gameboard_draw_button.h" #include "dialog_level.h" #include "levelstate.h" #include "main.h" static void unlevel_post (Gameboard *g){ g->level_dialog_active=0; pop_curtain(g); levelstate_go(); prepare_reenter_game(g); reenter_game(g); } static void unlevel_quit (Gameboard *g){ gtk_main_quit(); } static void local_go (Gameboard *g){ undeploy_buttons(g,unlevel_post); } static void local_quit (Gameboard *g){ undeploy_buttons(g,unlevel_quit); } /* initialize the rather weird little animation engine */ static void setup_level_buttons(Gameboard *g,int bw, int bh){ int i; int w=g->g.width; int h=g->g.height; buttonstate *states=g->b.states; states[0].rollovertext=_("exit gPlanarity"); states[2].rollovertext=_("reset level"); states[10].rollovertext=_("play level!"); states[0].callback = local_quit; states[2].callback = local_reset; states[10].callback = local_go; for(i=0;ix = b->x_target = w/2 - bw/2 + LEVEL_BUTTON_BORDER; b->y_active = h/2 + bh/2 - LEVEL_BUTTON_Y; b->y = b->y_target = b->y_inactive = b->y_active + BUTTON_EXPOSE; b->sweepdeploy = 0; } { buttonstate *b=states+2; b->x = b->x_target = w/2; b->y_active = h/2 + bh/2 - LEVEL_BUTTON_Y; b->y = b->y_target = b->y_inactive = b->y_active + BUTTON_EXPOSE; b->sweepdeploy = SWEEP_DELTA; } { buttonstate *b=states+10; b->x = b->x_target = w/2 + bw/2 - LEVEL_BUTTON_BORDER; b->y_active = h/2 + bh/2 - LEVEL_BUTTON_Y; b->y = b->y_target = b->y_inactive = b->y_active + BUTTON_EXPOSE; b->sweepdeploy = SWEEP_DELTA; } rollover_extents(g,states); rollover_extents(g,states+2); rollover_extents(g,states+10); } static void draw_levelbox(Gameboard *g){ int w= g->g.width; int h= g->g.height; cairo_t *c = cairo_create(g->background); borderbox_path(c, w/2 - LEVELBOX_WIDTH/2, h/2 - LEVELBOX_HEIGHT/2, LEVELBOX_WIDTH, LEVELBOX_HEIGHT); cairo_set_source_rgb(c,1,1,1); cairo_fill(c); centerbox(c, w/2 - LEVELBOX_WIDTH/2, h/2 - LEVELBOX_HEIGHT/2, LEVELBOX_WIDTH, SCOREHEIGHT); centerbox(c, w/2 - LEVELBOX_WIDTH/2, h/2 + LEVELBOX_HEIGHT/2 - SCOREHEIGHT, LEVELBOX_WIDTH, SCOREHEIGHT); set_font(c,18,18,0,1); cairo_set_source_rgba (c, TEXT_COLOR); render_text_centered(c,_("Available Levels"), w/2,h/2-LEVELBOX_HEIGHT/2+SCOREHEIGHT/2); cairo_destroy(c); } void level_dialog(Gameboard *g, int advance){ g->level_dialog_active=1; levelstate_write(); if(advance) levelstate_next(); // set up new buttons setup_level_buttons(g,LEVELBOX_WIDTH, LEVELBOX_HEIGHT); level_icons_init(g); // draw pausebox push_curtain(g,draw_levelbox); // deploy new buttons deploy_buttons(g,0); } gplanarity-17906/icon.h0000644000175000017500000023731511543161637014735 0ustar vincentvincentstatic unsigned char icon32[]={ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, 0xf4, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0e, 0xc4, 0x00, 0x00, 0x0e, 0xc4, 0x01, 0x95, 0x2b, 0x0e, 0x1b, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xd5, 0x0a, 0x11, 0x00, 0x19, 0x33, 0x08, 0xe2, 0xc7, 0x69, 0x00, 0x00, 0x08, 0xd9, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xad, 0x57, 0x69, 0x50, 0x53, 0xe7, 0x1a, 0x7e, 0xce, 0x49, 0x48, 0x42, 0x36, 0x41, 0x83, 0x08, 0x22, 0x45, 0x63, 0x24, 0x01, 0x83, 0x90, 0x70, 0x91, 0x45, 0x14, 0xbd, 0x2d, 0x35, 0xa1, 0xbd, 0x08, 0x83, 0x0b, 0x5a, 0x9d, 0x4e, 0xad, 0xf6, 0x2a, 0x0c, 0x9d, 0xab, 0xd3, 0x4e, 0x5b, 0x47, 0x6f, 0xa5, 0xd8, 0x3a, 0x5a, 0x1d, 0x3b, 0x56, 0xc7, 0x32, 0xad, 0x52, 0xac, 0xb6, 0xa2, 0xdc, 0x72, 0x5d, 0x28, 0x88, 0xc5, 0x5b, 0x50, 0x5c, 0x28, 0x28, 0xa6, 0x5a, 0x14, 0x17, 0x16, 0xd9, 0x43, 0x24, 0x24, 0x07, 0xc2, 0x49, 0x4e, 0xbe, 0xfb, 0x83, 0x4e, 0x46, 0x3b, 0xe3, 0x42, 0xf5, 0xf9, 0x77, 0xe6, 0xbc, 0xdf, 0x3b, 0xcf, 0xf7, 0xbd, 0xcf, 0xbb, 0xf1, 0xf0, 0x17, 0x61, 0x34, 0x1a, 0x35, 0x1c, 0xa7, 0xda, 0x27, 0x97, 0xcf, 0x78, 0x5b, 0xa3, 0x19, 0xdb, 0x77, 0xff, 0x7e, 0x6b, 0xd3, 0x5f, 0xf1, 0xc3, 0x7b, 0x9a, 0x41, 0x69, 0x69, 0xa9, 0xa4, 0xb6, 0xb6, 0x79, 0xb3, 0x50, 0x38, 0x67, 0x73, 0x40, 0x80, 0x4c, 0x75, 0xf0, 0xe0, 0x57, 0x17, 0xb5, 0x5a, 0x2d, 0x5d, 0x56, 0xe6, 0xfc, 0xd9, 0xd7, 0xb7, 0x70, 0x8e, 0x44, 0x92, 0xa9, 0xec, 0xee, 0xee, 0x49, 0x7b, 0xed, 0xb5, 0x09, 0xc7, 0x4c, 0x26, 0x53, 0x9f, 0x4e, 0x97, 0xb0, 0xd2, 0xcb, 0x6b, 0xf6, 0x6e, 0x3f, 0xbf, 0xc0, 0xbf, 0xa7, 0xa4, 0xc4, 0x5f, 0xba, 0x76, 0xed, 0x9a, 0xed, 0x49, 0xfe, 0xa9, 0xa7, 0x11, 0x50, 0xab, 0xe3, 0x36, 0xf2, 0x78, 0x5f, 0xe7, 0x8a, 0x44, 0x61, 0x70, 0x38, 0x1a, 0xe1, 0x72, 0xbd, 0xf5, 0xb1, 0x4a, 0x35, 0xee, 0xab, 0x1b, 0x37, 0x5e, 0xed, 0xf4, 0xf5, 0xcd, 0x06, 0x00, 0x0c, 0x0e, 0xd6, 0x81, 0x90, 0x37, 0x32, 0x03, 0x03, 0x03, 0xcd, 0xcd, 0xcd, 0x6f, 0x97, 0xfb, 0xfa, 0x66, 0xd2, 0x1c, 0x37, 0x00, 0xbb, 0x7d, 0xe5, 0x99, 0xdb, 0xb7, 0x8f, 0xbd, 0xf2, 0x24, 0xff, 0xf4, 0xd3, 0x08, 0x58, 0xad, 0x8a, 0x68, 0x91, 0x48, 0x03, 0x00, 0x10, 0x89, 0x42, 0x11, 0x16, 0x36, 0x37, 0xa7, 0xa4, 0xa4, 0xa4, 0x6e, 0xfa, 0xf4, 0x5e, 0x70, 0x9c, 0x15, 0x84, 0x38, 0x41, 0xd3, 0xe5, 0xa8, 0xae, 0xae, 0xde, 0x9f, 0x9c, 0x9c, 0x7c, 0x58, 0x2e, 0x37, 0xd0, 0x00, 0xc0, 0xe3, 0xc9, 0xe1, 0x74, 0x4e, 0x8b, 0x1e, 0x75, 0x08, 0x56, 0xac, 0x58, 0xe1, 0xed, 0x74, 0x3a, 0x0d, 0x6a, 0xb5, 0x7a, 0x42, 0x78, 0x78, 0x78, 0x1b, 0x30, 0x30, 0x61, 0x70, 0x50, 0xf5, 0xaa, 0x40, 0x30, 0x09, 0x0c, 0x73, 0x01, 0xab, 0x57, 0x8b, 0xbc, 0x23, 0x23, 0x23, 0x64, 0x2f, 0xbf, 0x3c, 0x1d, 0x16, 0x4b, 0x01, 0xc6, 0x8f, 0x3f, 0x87, 0x4f, 0x3f, 0x7d, 0x0d, 0x93, 0x27, 0x4f, 0xf6, 0x52, 0x28, 0x14, 0x92, 0xc2, 0xc2, 0x13, 0x10, 0x08, 0xa2, 0xe0, 0x72, 0x75, 0x40, 0x2c, 0x3e, 0x52, 0xd9, 0xd5, 0x75, 0xfd, 0xf0, 0x82, 0x05, 0x0b, 0xc2, 0xed, 0x76, 0x7b, 0x62, 0x5a, 0x5a, 0xda, 0x83, 0x86, 0x86, 0x06, 0xfb, 0x63, 0xd9, 0x2c, 0x5b, 0xb6, 0x4c, 0xac, 0x54, 0x66, 0xfe, 0x1a, 0x1a, 0x5a, 0x45, 0xa6, 0x4e, 0x2d, 0x26, 0xb3, 0x67, 0x2f, 0x29, 0x70, 0xbb, 0xdd, 0xd5, 0x87, 0x0f, 0x1f, 0x25, 0xab, 0x56, 0xe5, 0x91, 0x43, 0x87, 0x8e, 0x12, 0xb7, 0xdb, 0x4d, 0x9e, 0x84, 0xf3, 0xe7, 0x6b, 0xc8, 0x9a, 0x35, 0x5b, 0xc8, 0xb6, 0x6d, 0x7b, 0x09, 0xc3, 0x30, 0xb6, 0x1d, 0x3b, 0x76, 0x1f, 0x08, 0x09, 0xd9, 0xe5, 0xd0, 0x68, 0x6a, 0x49, 0x48, 0xc8, 0xfa, 0xde, 0x39, 0x73, 0x92, 0x34, 0x8f, 0x25, 0x10, 0x1e, 0x1e, 0x9e, 0x1a, 0x1a, 0x7a, 0x9e, 0xe8, 0xf5, 0x84, 0xe8, 0xf5, 0x84, 0xa8, 0xd5, 0x3b, 0x88, 0xdd, 0x6e, 0x27, 0xcf, 0x83, 0xd4, 0xd4, 0x4f, 0x3c, 0xfe, 0x22, 0x23, 0x6d, 0x24, 0x38, 0x38, 0x66, 0xe7, 0x63, 0x35, 0x30, 0x66, 0xcc, 0x18, 0xc6, 0xed, 0x7e, 0xe0, 0xf9, 0x16, 0x89, 0x58, 0xf0, 0xf9, 0x7c, 0x3c, 0x0f, 0xa4, 0x52, 0x0a, 0x84, 0xb8, 0x00, 0x00, 0x6e, 0xb7, 0x0d, 0x22, 0x11, 0x6d, 0x7f, 0xac, 0x06, 0xb4, 0x5a, 0x6d, 0x8b, 0xc3, 0xd1, 0xa0, 0x64, 0x18, 0x4b, 0x04, 0x4d, 0xff, 0x0f, 0x9b, 0x36, 0x85, 0x41, 0xab, 0x0d, 0x7b, 0x2e, 0x02, 0x6a, 0xb5, 0x1f, 0xca, 0xca, 0xf6, 0xc1, 0x6c, 0xbe, 0x05, 0xb9, 0xfc, 0x48, 0x53, 0x50, 0x10, 0xbb, 0xba, 0xa9, 0xa9, 0x69, 0xf0, 0xcf, 0x45, 0x45, 0xaa, 0x52, 0xa9, 0x96, 0x6b, 0xb5, 0xda, 0x45, 0x0e, 0x87, 0x63, 0x9f, 0xd9, 0x6c, 0x26, 0x36, 0x9b, 0x8d, 0xbc, 0x28, 0x0c, 0x0f, 0x0f, 0x93, 0xce, 0xce, 0x4e, 0xc2, 0x71, 0x9c, 0x25, 0x27, 0x27, 0x27, 0x33, 0x20, 0x20, 0x60, 0x75, 0x4a, 0x4a, 0x4a, 0x10, 0x00, 0x50, 0x05, 0x05, 0x05, 0x82, 0xdc, 0xdc, 0xf2, 0x8b, 0x22, 0xd1, 0x07, 0x51, 0x6e, 0x37, 0x83, 0xb9, 0x73, 0xcf, 0x62, 0xef, 0xde, 0x8f, 0x46, 0x7d, 0xd3, 0x86, 0x86, 0x06, 0xec, 0xdc, 0xf9, 0x23, 0x28, 0x6a, 0x24, 0xaa, 0x7c, 0x3e, 0x1f, 0x13, 0x26, 0x8c, 0xc7, 0xdc, 0xb9, 0x93, 0x31, 0x6f, 0xde, 0x3c, 0x50, 0x14, 0x85, 0x82, 0x82, 0x1f, 0xf0, 0xd9, 0x67, 0x7c, 0x08, 0x04, 0x3a, 0x30, 0xcc, 0x3e, 0x6b, 0x48, 0x48, 0x9d, 0x8e, 0xd7, 0xdc, 0xdc, 0x3c, 0xdb, 0xe5, 0x5a, 0xff, 0x81, 0x54, 0x9a, 0x00, 0x81, 0x60, 0x12, 0x7e, 0xff, 0xfd, 0x26, 0x32, 0x32, 0x02, 0x20, 0x93, 0xc9, 0x46, 0x45, 0xa0, 0xb0, 0xf0, 0x04, 0x2a, 0x2b, 0xb3, 0x70, 0xff, 0x7e, 0x30, 0x1a, 0x1b, 0xdb, 0xd1, 0xd3, 0xf3, 0x2a, 0x5a, 0x5a, 0xe6, 0xe3, 0xd4, 0xa9, 0x21, 0x10, 0x72, 0x1a, 0x31, 0x31, 0x11, 0x78, 0xf7, 0xdd, 0x12, 0x50, 0xd4, 0x3f, 0xc1, 0xe7, 0xfb, 0x42, 0x20, 0x98, 0x29, 0x6a, 0x6d, 0xdd, 0xfa, 0x80, 0x56, 0x2a, 0x95, 0x7d, 0x1c, 0xd7, 0xf1, 0x90, 0xf0, 0xac, 0x90, 0x4a, 0xa5, 0x7f, 0x2a, 0x46, 0x56, 0x1c, 0x39, 0x72, 0x04, 0xbb, 0x77, 0xef, 0x46, 0x65, 0x65, 0x25, 0x5a, 0x5a, 0x5a, 0x50, 0x57, 0x57, 0x87, 0xdb, 0xb7, 0x6f, 0x7b, 0x6c, 0x7e, 0xfd, 0xd5, 0x01, 0x9a, 0x16, 0x21, 0x28, 0xe8, 0x14, 0xae, 0x5d, 0x5b, 0x8e, 0x82, 0x82, 0x61, 0x10, 0x52, 0x0a, 0xa1, 0x30, 0x1c, 0x45, 0x45, 0x3d, 0x00, 0x00, 0x85, 0x82, 0x80, 0x10, 0x0e, 0x00, 0xe0, 0x74, 0xde, 0xc7, 0xd8, 0xb1, 0x3e, 0x7d, 0xfc, 0xe2, 0xe2, 0xe2, 0x6b, 0x6a, 0x75, 0xf7, 0x46, 0xab, 0xb5, 0x63, 0x83, 0x4c, 0x46, 0x89, 0x72, 0x73, 0x67, 0x3c, 0x72, 0xfb, 0xaa, 0xaa, 0x2a, 0xac, 0x5b, 0xd7, 0x08, 0x96, 0x35, 0x82, 0xcf, 0xf7, 0x01, 0xcb, 0xde, 0x03, 0xd0, 0x84, 0xe1, 0xe1, 0x61, 0xa4, 0xa5, 0x55, 0x62, 0xdb, 0xb6, 0xf7, 0xc0, 0x30, 0x0c, 0x1a, 0x1b, 0x25, 0x10, 0x08, 0x00, 0xbd, 0x9e, 0x82, 0x8f, 0x8f, 0x0f, 0xf4, 0x7a, 0x1d, 0x14, 0x8a, 0x72, 0xf4, 0xf5, 0x01, 0x2e, 0x17, 0x01, 0x00, 0xe4, 0xe5, 0x65, 0x20, 0x2b, 0x2b, 0x17, 0x2d, 0x2d, 0x62, 0xf0, 0xf9, 0xe7, 0xff, 0x13, 0x16, 0xf6, 0x52, 0x3e, 0x1f, 0x00, 0x1a, 0x1b, 0xcf, 0xe5, 0xf5, 0xf7, 0x9f, 0xfc, 0x5d, 0x22, 0x91, 0x1c, 0x7b, 0x38, 0xed, 0x5a, 0x5b, 0x5b, 0x91, 0x93, 0x73, 0x17, 0x14, 0xb5, 0x04, 0x5a, 0xed, 0x5e, 0x64, 0x64, 0x68, 0x61, 0xb1, 0x58, 0xb0, 0x75, 0x2b, 0x1f, 0x62, 0x71, 0x12, 0x62, 0x63, 0x59, 0x4f, 0xfc, 0x5d, 0xae, 0x19, 0x70, 0xbb, 0x6f, 0x22, 0x21, 0x41, 0x0d, 0xbb, 0xdd, 0x8e, 0x83, 0x07, 0x8f, 0xa3, 0xbd, 0x7d, 0x06, 0x84, 0x42, 0x27, 0x66, 0xce, 0x1c, 0x79, 0x51, 0x8d, 0x46, 0x83, 0x33, 0x67, 0xfe, 0x0d, 0x96, 0x65, 0xeb, 0x2f, 0x5c, 0x88, 0xc9, 0x98, 0x37, 0x6f, 0xde, 0x08, 0xb3, 0xd8, 0xd8, 0xd8, 0xf9, 0x46, 0xa3, 0xf1, 0xb0, 0xc9, 0x64, 0x7a, 0x44, 0xbd, 0x1f, 0x7e, 0xf8, 0x25, 0xd1, 0xe9, 0x9c, 0x24, 0x3d, 0x7d, 0x27, 0xe1, 0x38, 0x8e, 0x10, 0x42, 0x48, 0x7d, 0x7d, 0x3d, 0xd1, 0x68, 0xea, 0x88, 0x46, 0xf3, 0x23, 0x69, 0x6d, 0x6d, 0x25, 0x84, 0x10, 0xb2, 0x7d, 0xfb, 0xd7, 0x24, 0x2a, 0x8a, 0x21, 0x91, 0x91, 0x56, 0x32, 0x69, 0xd2, 0x27, 0x64, 0xda, 0xb4, 0x12, 0xa2, 0xd5, 0xde, 0x23, 0x3a, 0x9d, 0x93, 0x24, 0x26, 0x7e, 0x4c, 0xba, 0xba, 0xba, 0x3c, 0x3e, 0xbb, 0xbb, 0xbb, 0x49, 0x5e, 0x5e, 0x5e, 0xbb, 0x56, 0xab, 0x5d, 0x65, 0x30, 0x18, 0x28, 0x3a, 0x3a, 0x7a, 0xd6, 0xaa, 0xde, 0xde, 0xf5, 0x3f, 0x75, 0x76, 0x16, 0x67, 0xa6, 0xa5, 0x9d, 0x47, 0x4d, 0xcd, 0x05, 0xcf, 0x0b, 0xd4, 0xd6, 0x0a, 0x41, 0x51, 0x7c, 0xa4, 0xa7, 0x07, 0x83, 0xa6, 0x47, 0xd4, 0x5d, 0x53, 0xd3, 0x00, 0xb1, 0x58, 0x07, 0x3f, 0xbf, 0x36, 0x04, 0x05, 0x05, 0xfd, 0x61, 0x37, 0x08, 0x9a, 0x16, 0x83, 0x61, 0xce, 0x01, 0x20, 0xa0, 0xe9, 0x3b, 0x08, 0x0a, 0x3a, 0x89, 0xcc, 0xcc, 0x7c, 0x94, 0x96, 0xae, 0x87, 0xbf, 0xbf, 0x3f, 0x00, 0xc0, 0x62, 0xb1, 0x20, 0x39, 0xf9, 0x0b, 0x1c, 0x3b, 0x96, 0x1d, 0xc8, 0x71, 0x07, 0xf3, 0xef, 0xdd, 0xc3, 0x41, 0x7e, 0x77, 0x77, 0xf0, 0x1b, 0xe3, 0xc7, 0x67, 0x00, 0x00, 0xe4, 0xf2, 0x95, 0xf8, 0xe1, 0x87, 0xed, 0x88, 0x8f, 0x8f, 0x03, 0x00, 0xf4, 0xf4, 0xf4, 0xc0, 0xcb, 0x0b, 0x10, 0x0a, 0x85, 0x0f, 0x89, 0x6d, 0xa4, 0xbd, 0xeb, 0x74, 0x52, 0x50, 0x14, 0x05, 0x86, 0x61, 0x70, 0xf3, 0xa6, 0x04, 0x7c, 0x3e, 0xb0, 0x70, 0x61, 0x13, 0xb6, 0x6c, 0xd9, 0xf8, 0xd8, 0x4c, 0x29, 0x2b, 0x2b, 0x03, 0xc7, 0xad, 0x84, 0x50, 0x38, 0x06, 0xde, 0xde, 0x33, 0xd0, 0xdf, 0x1f, 0xb7, 0x8c, 0x2f, 0x12, 0x99, 0x5b, 0x38, 0xce, 0x0a, 0x1e, 0x6f, 0x0c, 0x9c, 0xce, 0x76, 0x28, 0x95, 0x0a, 0xcf, 0x81, 0x80, 0x00, 0x09, 0xcc, 0x66, 0x60, 0xe7, 0x4e, 0x33, 0x4c, 0xa6, 0x0a, 0xdc, 0xb9, 0x73, 0x17, 0x57, 0xae, 0x44, 0x40, 0x20, 0xb0, 0x42, 0xaf, 0x1f, 0x11, 0xaa, 0xc9, 0x64, 0x02, 0xcb, 0x6a, 0xe1, 0x72, 0xdd, 0x42, 0x7c, 0x7c, 0xe8, 0x13, 0x53, 0x55, 0xa9, 0x54, 0x82, 0x65, 0xaf, 0x43, 0x28, 0x9c, 0x02, 0xc0, 0x0d, 0x1e, 0xaf, 0xbb, 0x85, 0x9e, 0x35, 0x6b, 0xe2, 0x07, 0x36, 0xdb, 0xca, 0xd3, 0x66, 0xf3, 0x47, 0xd6, 0xa4, 0xa4, 0xef, 0xdd, 0xef, 0xbc, 0xb3, 0xdc, 0x73, 0xe0, 0xfd, 0xf7, 0xa3, 0x01, 0x14, 0xc2, 0x6c, 0x1e, 0x87, 0xa2, 0x22, 0x0b, 0xfa, 0xfa, 0x3a, 0xc0, 0xe3, 0x4d, 0x06, 0xcb, 0xd6, 0x22, 0x2e, 0x2e, 0x0a, 0x00, 0x50, 0x5d, 0x5d, 0x0b, 0x87, 0xa3, 0x09, 0x03, 0x03, 0xfb, 0x11, 0x1b, 0xfb, 0xb7, 0x27, 0x12, 0x98, 0x39, 0x73, 0x26, 0x72, 0x72, 0xfa, 0x30, 0x34, 0xb4, 0x71, 0x70, 0x60, 0x60, 0x4d, 0xa3, 0x5c, 0x7e, 0x79, 0xb1, 0xe7, 0x27, 0xcb, 0xb2, 0x94, 0xc5, 0x62, 0xa9, 0x66, 0x18, 0x86, 0x10, 0x42, 0xc8, 0xe0, 0xe0, 0x20, 0xb9, 0x7c, 0xf9, 0x32, 0xe9, 0xed, 0xed, 0x25, 0x26, 0x93, 0x89, 0xdc, 0xba, 0x75, 0x8b, 0x64, 0x65, 0xe5, 0x91, 0xa8, 0x28, 0x3b, 0x49, 0x4d, 0xdd, 0xea, 0x69, 0xcb, 0x6d, 0x6d, 0x6d, 0xe4, 0xea, 0xd5, 0xab, 0xe4, 0xfa, 0xf5, 0xeb, 0x4f, 0x6d, 0xd5, 0x2c, 0xcb, 0x12, 0x8b, 0xc5, 0x42, 0x9c, 0x4e, 0x67, 0xe2, 0x23, 0x23, 0x99, 0xd1, 0x68, 0xa4, 0xee, 0xdc, 0x71, 0x6c, 0xe7, 0x38, 0x63, 0x8e, 0x44, 0xc2, 0x79, 0x6d, 0xd8, 0x10, 0x8a, 0x90, 0x90, 0x40, 0x2c, 0x59, 0x72, 0x17, 0x0a, 0x85, 0x00, 0xbe, 0xbe, 0x3e, 0xe8, 0xed, 0xed, 0x85, 0xcb, 0x95, 0x00, 0x8a, 0xfa, 0x2f, 0x0a, 0x0b, 0x67, 0x21, 0x22, 0x22, 0x62, 0x54, 0x95, 0xd2, 0x64, 0xfa, 0x0d, 0x6b, 0xd7, 0x16, 0xa3, 0xa3, 0x63, 0x2c, 0x68, 0xfa, 0x97, 0x0a, 0x8d, 0x86, 0x4d, 0x3f, 0x71, 0xe2, 0x84, 0x9d, 0x07, 0x00, 0x53, 0xa6, 0x4c, 0x89, 0x31, 0x9b, 0xdf, 0xda, 0xef, 0xe3, 0xb3, 0x9a, 0x47, 0xd3, 0x09, 0x38, 0x7b, 0xf6, 0x14, 0x92, 0x92, 0x7c, 0xd0, 0xd9, 0x69, 0x81, 0xdd, 0xde, 0x0e, 0x9b, 0xad, 0x19, 0x7e, 0x7e, 0x34, 0x12, 0x13, 0x6f, 0xe3, 0xf3, 0xcf, 0xe7, 0x23, 0x34, 0x34, 0x74, 0xd4, 0xbd, 0x22, 0x3b, 0x3b, 0x1f, 0x3d, 0x3d, 0x1b, 0xe0, 0xed, 0x1d, 0x0b, 0x8a, 0x8a, 0x56, 0x9a, 0xcd, 0xdf, 0xf4, 0x9b, 0xcd, 0x9d, 0x35, 0x7c, 0x00, 0xe8, 0xee, 0xee, 0x1e, 0x43, 0xd3, 0x7e, 0x1e, 0xe3, 0xe1, 0x61, 0x31, 0xa2, 0xa2, 0xa2, 0x50, 0x54, 0xf4, 0x32, 0x5e, 0x14, 0xfa, 0xfb, 0x01, 0x8a, 0xe2, 0xfd, 0xd1, 0xa8, 0xc6, 0xc1, 0x6a, 0x75, 0xc8, 0x3d, 0x03, 0x89, 0xc1, 0x60, 0xa8, 0x72, 0xbb, 0xbf, 0xb9, 0xcc, 0x30, 0x17, 0x61, 0xb3, 0x9d, 0x46, 0x5c, 0x5c, 0x5b, 0xd3, 0xb8, 0x71, 0xe3, 0x08, 0x5e, 0x20, 0xde, 0x7c, 0x53, 0xfd, 0xe0, 0xc1, 0x83, 0xfd, 0xae, 0xa1, 0x21, 0x13, 0xac, 0xd6, 0xdc, 0x3e, 0xa5, 0xd2, 0xbf, 0xe0, 0x91, 0xb1, 0x3c, 0x2d, 0x2d, 0x4d, 0xdc, 0xd8, 0xd8, 0x68, 0x90, 0x4a, 0xa5, 0x4c, 0x76, 0x76, 0xf6, 0xd9, 0x89, 0x13, 0x83, 0x8a, 0x4f, 0x9e, 0xbc, 0x9c, 0xe2, 0xef, 0x2f, 0x43, 0x56, 0xd6, 0x8a, 0x51, 0x77, 0x47, 0x8e, 0xe3, 0xf0, 0xdd, 0x77, 0x47, 0x71, 0xe9, 0xd2, 0x1d, 0x24, 0x27, 0xcf, 0x60, 0x5e, 0x7f, 0xdd, 0x30, 0xc7, 0x60, 0x30, 0xf0, 0x6e, 0xdc, 0xb8, 0x31, 0x35, 0x21, 0x21, 0xa1, 0xb2, 0xa8, 0xa8, 0xa8, 0xeb, 0xb1, 0x87, 0x53, 0x53, 0x53, 0x43, 0x43, 0x42, 0xb6, 0xd8, 0x75, 0xba, 0x61, 0x12, 0x11, 0xd1, 0x45, 0x96, 0x2f, 0xdf, 0x3c, 0xea, 0x21, 0xe4, 0xcb, 0x2f, 0xf7, 0x13, 0x8d, 0xa6, 0x96, 0xe8, 0x74, 0x2e, 0xa2, 0x52, 0x1d, 0x77, 0x47, 0x46, 0xc6, 0x2f, 0x7b, 0xe6, 0xbd, 0xa0, 0xa6, 0xa6, 0x26, 0x5e, 0x2a, 0x5d, 0x2c, 0xa1, 0x28, 0x01, 0xbc, 0xbc, 0xfc, 0x71, 0xee, 0x9c, 0x17, 0x38, 0x8e, 0xf3, 0x14, 0x9e, 0xfc, 0xfc, 0x7c, 0xdc, 0xbd, 0x7b, 0xf7, 0xa1, 0xf8, 0xf6, 0xe3, 0xdb, 0x6f, 0xbf, 0x45, 0x45, 0x45, 0x05, 0x08, 0x19, 0x89, 0x5c, 0x45, 0xc5, 0x7d, 0x88, 0xc5, 0xd1, 0xa0, 0x28, 0x1e, 0x64, 0x32, 0x03, 0xd5, 0xd9, 0xc9, 0x7f, 0xe5, 0x99, 0x09, 0xe8, 0xf5, 0xfa, 0xdf, 0x18, 0xe6, 0x67, 0x27, 0x00, 0x10, 0xe2, 0x00, 0x8f, 0x77, 0xf3, 0x2a, 0x45, 0x51, 0xef, 0x15, 0x17, 0x97, 0xb4, 0xa7, 0xa7, 0x5f, 0xc1, 0x9e, 0x3d, 0xff, 0x80, 0xd1, 0x78, 0x1c, 0xf5, 0xf5, 0x57, 0x30, 0x30, 0x30, 0x00, 0x83, 0x61, 0x1b, 0x76, 0xec, 0x48, 0x42, 0x4e, 0x8e, 0x08, 0x9b, 0x36, 0xed, 0x72, 0x02, 0xf8, 0x9e, 0x61, 0x6e, 0x1e, 0x65, 0xd9, 0x36, 0x00, 0xc0, 0xd0, 0x50, 0x3d, 0xfc, 0xfc, 0x5c, 0x75, 0xa3, 0x5a, 0xcd, 0xf4, 0xfa, 0x59, 0x4b, 0xcd, 0xe6, 0x90, 0xb5, 0x5e, 0x5e, 0x03, 0xe6, 0x69, 0xd3, 0xb8, 0xf7, 0x4a, 0x4b, 0x4f, 0x35, 0x05, 0x07, 0x2f, 0xfd, 0xc5, 0xcf, 0xef, 0xd0, 0xec, 0x11, 0x62, 0x2c, 0x22, 0x23, 0x3f, 0xe9, 0x8a, 0x8b, 0x7b, 0xc9, 0xb6, 0x6b, 0x57, 0xa2, 0x4a, 0x24, 0x0a, 0xfd, 0x63, 0x78, 0xc9, 0x23, 0x0a, 0xc5, 0x29, 0xfe, 0xe2, 0xc5, 0x8b, 0xe5, 0x7b, 0xf6, 0x1c, 0xcf, 0x1b, 0x1a, 0x0a, 0x8e, 0x96, 0xcb, 0xef, 0x95, 0x6d, 0xde, 0x9c, 0xbd, 0x75, 0xd1, 0xa2, 0x45, 0x8e, 0x51, 0xef, 0x86, 0x0f, 0x43, 0xa5, 0x4a, 0x29, 0x92, 0x4a, 0x8f, 0x2e, 0xa4, 0x69, 0x6f, 0x38, 0x9d, 0x1d, 0x60, 0xd9, 0xcc, 0x6d, 0xbe, 0xbe, 0xce, 0xaa, 0xbe, 0xbe, 0x4d, 0x27, 0x65, 0xb2, 0xf9, 0x00, 0x00, 0xbb, 0x7d, 0x5d, 0x57, 0x7c, 0x7c, 0x7f, 0xe0, 0x81, 0x03, 0x07, 0x9e, 0x29, 0x8b, 0x78, 0xa3, 0x21, 0x90, 0x94, 0xa4, 0xad, 0x6d, 0x6d, 0x2d, 0x4d, 0x60, 0x98, 0xeb, 0x13, 0xdd, 0xee, 0x03, 0xe5, 0x31, 0x31, 0x8a, 0x7f, 0x01, 0x30, 0xf5, 0xf7, 0x57, 0xc9, 0x06, 0x07, 0x9b, 0x63, 0x9c, 0xce, 0x92, 0x1e, 0x91, 0xa8, 0x6a, 0x69, 0x79, 0xf9, 0x4f, 0xf7, 0x9e, 0xd5, 0xe7, 0xff, 0x01, 0x15, 0x6f, 0x09, 0x08, 0x2b, 0xc2, 0x8e, 0x36, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static unsigned char icon134[]={ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x86, 0x08, 0x06, 0x00, 0x00, 0x00, 0x18, 0x79, 0xf2, 0x91, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0e, 0xc4, 0x00, 0x00, 0x0e, 0xc4, 0x01, 0x95, 0x2b, 0x0e, 0x1b, 0x00, 0x00, 0x13, 0xa2, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0x5d, 0x7b, 0x50, 0x14, 0x57, 0xba, 0xff, 0xf5, 0x3c, 0x14, 0x1c, 0x40, 0x86, 0xc4, 0xc5, 0x2b, 0x83, 0xb2, 0x42, 0x56, 0x9d, 0x19, 0xbc, 0x0e, 0x23, 0xb8, 0x26, 0xa8, 0x51, 0x63, 0x14, 0xd0, 0x80, 0x2b, 0x56, 0xa2, 0xae, 0x31, 0x9b, 0x58, 0xc9, 0xdd, 0x1b, 0x22, 0xc6, 0xd4, 0x1a, 0xd7, 0x64, 0xeb, 0xd6, 0xee, 0xc6, 0x4d, 0xb2, 0xb5, 0x46, 0xc5, 0xca, 0x63, 0x2b, 0x31, 0x15, 0xad, 0x75, 0x89, 0xa5, 0xf8, 0x48, 0x0c, 0xe8, 0x4a, 0x15, 0x61, 0x56, 0x13, 0x79, 0x0c, 0xbe, 0x06, 0x88, 0x96, 0xc8, 0x43, 0x7c, 0x60, 0xa2, 0x83, 0x3c, 0xe5, 0x35, 0xe7, 0xfe, 0x81, 0x3d, 0x8b, 0x08, 0xd3, 0x67, 0x66, 0xba, 0x7b, 0x7a, 0xa0, 0x7f, 0x55, 0x5d, 0x25, 0xce, 0xe9, 0xaf, 0x4f, 0x7f, 0xdf, 0xaf, 0xcf, 0xf9, 0xce, 0x77, 0xbe, 0x73, 0x0e, 0x30, 0x8c, 0x41, 0x08, 0xb9, 0x40, 0x06, 0xc7, 0x85, 0xe1, 0xac, 0x1b, 0x66, 0x98, 0x12, 0x82, 0xb8, 0xa5, 0x24, 0x86, 0x19, 0x76, 0x7a, 0x52, 0x0c, 0x67, 0x52, 0x94, 0x94, 0x94, 0x60, 0xfd, 0xfa, 0xf5, 0x30, 0x1a, 0x8d, 0x08, 0x0a, 0x0a, 0x42, 0x50, 0x50, 0x10, 0x8c, 0x46, 0x23, 0xd6, 0xaf, 0x5f, 0x8f, 0x92, 0x92, 0x12, 0x8f, 0x89, 0x24, 0xc3, 0x0f, 0x49, 0x41, 0x08, 0x21, 0x97, 0x2f, 0x5f, 0x26, 0x49, 0x49, 0x49, 0x04, 0x80, 0xcb, 0x2b, 0x29, 0x29, 0x89, 0x5c, 0xbe, 0x7c, 0xd9, 0xd9, 0xb7, 0xc8, 0x1a, 0x1c, 0x82, 0x7e, 0x00, 0x7b, 0x43, 0x61, 0x61, 0x21, 0xd1, 0x6a, 0xb5, 0x04, 0x00, 0x51, 0xab, 0x23, 0x88, 0x4e, 0xb7, 0x95, 0xe8, 0xf5, 0x36, 0x62, 0x32, 0xb5, 0x10, 0x93, 0xa9, 0x85, 0xe8, 0xf5, 0x36, 0xa2, 0xd3, 0x6d, 0x25, 0x6a, 0x75, 0x04, 0x01, 0x40, 0xb4, 0x5a, 0x2d, 0x29, 0x2c, 0x2c, 0x74, 0x9b, 0x1c, 0xfe, 0xee, 0xbf, 0x30, 0x52, 0xfe, 0xba, 0xf9, 0xf2, 0x03, 0x58, 0x59, 0x55, 0x55, 0x55, 0x98, 0x3e, 0x7d, 0x3a, 0x1a, 0x1b, 0x1b, 0xa1, 0xd5, 0x2e, 0x43, 0x54, 0xd4, 0x6e, 0x28, 0x14, 0x9a, 0x01, 0xef, 0x71, 0x38, 0x5a, 0x51, 0x53, 0xb3, 0x06, 0x76, 0x7b, 0x0e, 0x42, 0x43, 0x43, 0x51, 0x5a, 0x5a, 0x8a, 0xe8, 0xe8, 0x68, 0xea, 0x67, 0xf9, 0xbb, 0xff, 0xa2, 0x90, 0x3a, 0x29, 0xf8, 0xf4, 0x03, 0xd6, 0xad, 0x5b, 0xe7, 0x24, 0xc5, 0xc4, 0x89, 0xfb, 0x07, 0x25, 0x05, 0x00, 0x28, 0x14, 0x1a, 0x4c, 0x9c, 0xb8, 0x1f, 0x5a, 0xed, 0x32, 0x34, 0x36, 0x36, 0x62, 0xdd, 0xba, 0x75, 0xb2, 0xff, 0x32, 0x94, 0xfc, 0x00, 0x42, 0x88, 0x95, 0x10, 0x42, 0x8a, 0x8a, 0x8a, 0xee, 0x77, 0x1f, 0x3a, 0x62, 0x32, 0xb5, 0x10, 0xb3, 0x99, 0x50, 0x5d, 0x26, 0x53, 0x0b, 0x51, 0xab, 0x75, 0x04, 0x00, 0x29, 0x2a, 0x2a, 0x62, 0x1f, 0x63, 0x1d, 0xea, 0xfe, 0x8b, 0x42, 0x8a, 0x2d, 0x85, 0xc5, 0x62, 0x41, 0x7c, 0x7c, 0x3c, 0xf2, 0xf2, 0xf2, 0xa0, 0x56, 0x47, 0x40, 0xa7, 0xdb, 0x0a, 0xbd, 0xde, 0x06, 0x93, 0xa9, 0x05, 0x26, 0x53, 0x0b, 0xf4, 0x7a, 0x1b, 0x74, 0xba, 0xad, 0x50, 0xab, 0x23, 0x90, 0x97, 0x97, 0x87, 0xf8, 0xf8, 0x78, 0x58, 0x2c, 0x96, 0xc1, 0xbe, 0xc0, 0x38, 0x00, 0xc8, 0xce, 0xce, 0x06, 0x00, 0x84, 0x87, 0xbf, 0xee, 0xb2, 0xa5, 0x18, 0xa8, 0xe5, 0x08, 0x0f, 0x7f, 0x1d, 0x7d, 0x65, 0xb0, 0x32, 0x05, 0xae, 0xb7, 0xec, 0x63, 0x08, 0xe9, 0x07, 0xb0, 0x72, 0x8d, 0x46, 0x23, 0xca, 0xcb, 0xcb, 0xa1, 0xd7, 0xdb, 0x10, 0x18, 0x68, 0x70, 0xab, 0x6e, 0xed, 0xed, 0xe5, 0xa8, 0xa8, 0x30, 0xc2, 0x60, 0x30, 0xc0, 0x66, 0xb3, 0x0d, 0x28, 0x5f, 0x0c, 0xff, 0x65, 0x58, 0xfb, 0x18, 0x42, 0xf9, 0x01, 0x75, 0x75, 0x75, 0x00, 0x80, 0x11, 0x23, 0xc6, 0xbb, 0x5d, 0x27, 0xf6, 0x1e, 0x56, 0x86, 0x2f, 0xfc, 0x97, 0x61, 0x49, 0x0c, 0xb6, 0xcf, 0x2e, 0x2e, 0x2e, 0x46, 0x6e, 0x6e, 0x2e, 0xd4, 0x6a, 0x1d, 0xa2, 0xa2, 0x76, 0x53, 0x36, 0x68, 0x0c, 0xa2, 0xa2, 0x76, 0x43, 0xad, 0xd6, 0x21, 0x37, 0x37, 0x17, 0xc5, 0xc5, 0xc5, 0xac, 0xcc, 0x4a, 0x42, 0x48, 0x86, 0x80, 0x75, 0xce, 0x20, 0x84, 0x54, 0x0a, 0x50, 0x6f, 0xab, 0x4c, 0x0c, 0x61, 0xfd, 0x80, 0xc9, 0x00, 0x76, 0xb2, 0x7f, 0x8c, 0x1f, 0xdf, 0xfb, 0xd5, 0x77, 0x76, 0xd6, 0xb9, 0x5d, 0x39, 0xf6, 0x1e, 0x56, 0xc6, 0x7d, 0xec, 0xbc, 0xff, 0x0c, 0x41, 0xfd, 0x17, 0xb9, 0x2b, 0x01, 0x70, 0xe2, 0xc4, 0x09, 0x00, 0x40, 0x48, 0xc8, 0x42, 0xb7, 0xef, 0x65, 0xef, 0x61, 0x65, 0xf4, 0xc7, 0x82, 0x05, 0x0b, 0x00, 0x00, 0x4d, 0x4d, 0xc7, 0xdd, 0x96, 0xcd, 0xde, 0xc3, 0xca, 0x10, 0xb3, 0xde, 0x32, 0x31, 0x04, 0xf6, 0x03, 0x56, 0xac, 0x58, 0x01, 0x00, 0x68, 0x68, 0xd8, 0x06, 0x87, 0xa3, 0x95, 0x5a, 0xae, 0xc3, 0xd1, 0x8a, 0x86, 0x86, 0x6d, 0x0f, 0xc8, 0x10, 0xdb, 0x7f, 0x91, 0x9d, 0x4f, 0x01, 0x91, 0x90, 0x90, 0x80, 0xe4, 0xe4, 0x64, 0x74, 0x75, 0xd5, 0xa3, 0xa6, 0x66, 0xcd, 0xfd, 0x70, 0x02, 0xa7, 0x27, 0x81, 0x9a, 0x9a, 0x35, 0xe8, 0xea, 0xaa, 0x47, 0x72, 0x72, 0x32, 0x12, 0x12, 0x12, 0x86, 0x4d, 0x3c, 0x49, 0x52, 0xc4, 0x10, 0xc0, 0x0f, 0x78, 0x00, 0x59, 0x59, 0x59, 0x08, 0x0d, 0x0d, 0x85, 0xdd, 0x9e, 0x83, 0x2b, 0x57, 0x96, 0xbb, 0x6c, 0x39, 0x1c, 0x8e, 0x56, 0x5c, 0xb9, 0xb2, 0xdc, 0x39, 0xa4, 0xcc, 0xca, 0xca, 0xf2, 0x59, 0xbd, 0x87, 0x3d, 0x31, 0x84, 0xf4, 0x03, 0x00, 0x20, 0x3a, 0x3a, 0x1a, 0x47, 0x8e, 0x1c, 0x81, 0x56, 0xab, 0x85, 0xdd, 0x9e, 0x03, 0x9b, 0x6d, 0x12, 0x1a, 0x1a, 0x3e, 0x40, 0x7b, 0x7b, 0x39, 0x1c, 0x8e, 0x56, 0x38, 0x1c, 0xad, 0x68, 0x6f, 0x2f, 0x47, 0x43, 0xc3, 0x07, 0xb0, 0xd9, 0x26, 0xc1, 0x6e, 0xcf, 0x81, 0x56, 0xab, 0xc5, 0x91, 0x23, 0x47, 0x9c, 0x71, 0x06, 0x5f, 0xd4, 0x7b, 0xc8, 0x04, 0xb8, 0xee, 0xcf, 0x1e, 0x1a, 0x07, 0xf9, 0xd9, 0xc6, 0x30, 0x4c, 0xec, 0x00, 0xc3, 0xd5, 0xb8, 0xe2, 0xe2, 0x62, 0xcc, 0x98, 0x31, 0x03, 0x6a, 0xb5, 0x0e, 0x46, 0xe3, 0x0f, 0xd4, 0x1e, 0xbe, 0xc3, 0xd1, 0x0a, 0x9b, 0x6d, 0x32, 0xba, 0xba, 0xea, 0x51, 0x54, 0x54, 0xc4, 0xd9, 0xe4, 0x57, 0x55, 0x55, 0xe1, 0xb5, 0xd7, 0x5e, 0x43, 0x5e, 0x5e, 0x9e, 0xcb, 0x72, 0x49, 0x49, 0x49, 0xd8, 0xb9, 0x73, 0xa7, 0x4b, 0x52, 0xb0, 0xc3, 0x55, 0x1e, 0xeb, 0x5d, 0xc6, 0x30, 0x8c, 0xb9, 0x9f, 0x7e, 0x5c, 0xf6, 0x7b, 0x42, 0x04, 0xc5, 0x18, 0x9e, 0x09, 0xe1, 0xf1, 0xcc, 0x22, 0x7b, 0x6f, 0x4a, 0x4a, 0x0a, 0x72, 0x73, 0x73, 0x9d, 0x81, 0x22, 0xee, 0x2a, 0x12, 0x67, 0x93, 0x9f, 0x9c, 0x9c, 0x8c, 0x6f, 0xbe, 0xf9, 0x86, 0xfa, 0xf9, 0x25, 0x25, 0x25, 0xd8, 0xbb, 0x77, 0x2f, 0xf2, 0xf3, 0xf3, 0x51, 0x53, 0x53, 0x03, 0x00, 0x88, 0x8a, 0x8a, 0xc2, 0x53, 0x4f, 0x3d, 0x85, 0x55, 0xab, 0x56, 0x21, 0x3e, 0x3e, 0x9e, 0x5a, 0x16, 0x5f, 0xf5, 0x1e, 0x48, 0x27, 0x9e, 0xe8, 0x53, 0x32, 0xc4, 0xe8, 0x3f, 0xb3, 0x48, 0xab, 0x70, 0xa1, 0x42, 0xcb, 0x62, 0x43, 0xa8, 0x50, 0xbe, 0xa7, 0xfa, 0x94, 0x04, 0xbc, 0x9d, 0x59, 0x24, 0x84, 0x6c, 0xee, 0xfb, 0x87, 0xb7, 0xc9, 0x34, 0xbe, 0x02, 0x4f, 0xf5, 0xde, 0x3c, 0x24, 0x66, 0x6a, 0x85, 0x32, 0xa6, 0x17, 0x24, 0xf3, 0x29, 0xf8, 0xaa, 0xb7, 0x58, 0x99, 0x66, 0x82, 0x74, 0x25, 0x62, 0x34, 0xff, 0x7c, 0xfa, 0x01, 0x62, 0xc2, 0x9b, 0x7a, 0x4b, 0x61, 0xa6, 0x96, 0x17, 0x62, 0x88, 0xe9, 0x30, 0x0e, 0x07, 0x08, 0xe1, 0xc8, 0x8a, 0x46, 0x0c, 0xb1, 0x87, 0x98, 0xc3, 0x05, 0x7c, 0xeb, 0xd3, 0x53, 0x72, 0x78, 0x13, 0xe0, 0x12, 0x62, 0x46, 0x74, 0xd8, 0x43, 0x2a, 0xfa, 0xf4, 0x3a, 0xf2, 0x39, 0x14, 0x67, 0x16, 0x7d, 0x09, 0xa9, 0xe8, 0xd3, 0x6b, 0x62, 0x0c, 0xc5, 0x99, 0x45, 0x5f, 0x42, 0x2a, 0xfa, 0x54, 0xc8, 0xa6, 0x90, 0x21, 0x08, 0x31, 0x86, 0xe2, 0xcc, 0xa2, 0x2f, 0x21, 0x15, 0x7d, 0x7a, 0x4d, 0x8c, 0xa1, 0x38, 0xb3, 0xe8, 0x4b, 0x48, 0x45, 0x9f, 0xde, 0x10, 0xa3, 0x0c, 0x10, 0x36, 0x33, 0x6a, 0x38, 0x42, 0x2a, 0xfa, 0xf4, 0x98, 0x18, 0xec, 0xd4, 0xb0, 0x9c, 0x19, 0xc5, 0x2f, 0xf8, 0xd4, 0xa7, 0xcf, 0x23, 0x9f, 0xfe, 0x3a, 0x23, 0x2a, 0x55, 0x0c, 0x89, 0xc5, 0x4b, 0xfe, 0x3e, 0x23, 0x2a, 0x55, 0xf8, 0x7a, 0x12, 0x8d, 0x57, 0x72, 0xf8, 0xeb, 0x8c, 0xa8, 0x54, 0xe1, 0xcb, 0x69, 0x77, 0x9f, 0x27, 0xea, 0xc8, 0xe0, 0x86, 0x2f, 0x12, 0x75, 0x18, 0x4a, 0xa3, 0xbb, 0xcc, 0xe1, 0x04, 0x30, 0x13, 0xc0, 0x0f, 0x00, 0x22, 0x64, 0x33, 0xfa, 0x14, 0xd7, 0xd0, 0xbb, 0x3a, 0xee, 0xaf, 0x00, 0x7e, 0x3b, 0x48, 0x99, 0x8f, 0x19, 0x86, 0xf9, 0x5f, 0xaf, 0x88, 0x21, 0x6f, 0xea, 0x31, 0xb4, 0xe1, 0xaa, 0x75, 0x51, 0xd0, 0x76, 0x0d, 0x34, 0xbb, 0xc3, 0xc8, 0x90, 0x4e, 0xd7, 0x23, 0xc8, 0x6e, 0x3e, 0xb2, 0x33, 0xe9, 0x1a, 0xc5, 0xc5, 0x35, 0x9c, 0x3a, 0x19, 0xfc, 0x52, 0x12, 0xa5, 0x32, 0x98, 0x8c, 0x18, 0x11, 0x4e, 0x46, 0x8d, 0x9a, 0x48, 0xc6, 0x8e, 0x9d, 0x43, 0x4c, 0xa6, 0x17, 0xc9, 0xd2, 0xa5, 0x5b, 0xc8, 0xdf, 0xff, 0xfe, 0x2d, 0x69, 0x6b, 0xeb, 0x94, 0xa6, 0xb3, 0x2a, 0x0f, 0x3f, 0xb9, 0xf1, 0xfa, 0xeb, 0xbb, 0xbd, 0x20, 0x86, 0xeb, 0x4b, 0xa9, 0x0c, 0x26, 0x53, 0xa6, 0x3c, 0x47, 0x8e, 0x1e, 0x3d, 0xef, 0xd3, 0xe1, 0x2d, 0x23, 0x07, 0xac, 0xdc, 0x87, 0xd9, 0xbc, 0x16, 0x65, 0x65, 0xbb, 0x60, 0x36, 0xf3, 0xef, 0x82, 0x59, 0xad, 0x8c, 0xd3, 0x34, 0x7a, 0xfd, 0x73, 0xf8, 0xd7, 0xbf, 0x3e, 0x46, 0x44, 0xc4, 0x68, 0xd1, 0x03, 0x62, 0x03, 0xfa, 0x18, 0x43, 0x6d, 0x77, 0x18, 0xbe, 0x71, 0xf1, 0x62, 0xa1, 0x80, 0xa4, 0x23, 0xf7, 0x09, 0x47, 0x50, 0x51, 0x91, 0x0d, 0xbd, 0x3e, 0x11, 0xa5, 0xa5, 0xae, 0x67, 0x5a, 0x85, 0xb0, 0x57, 0xdf, 0x55, 0x4f, 0x72, 0x0e, 0x27, 0x05, 0x6c, 0xb6, 0x1b, 0x88, 0x8d, 0x1d, 0xe7, 0x34, 0xa2, 0xd0, 0xb0, 0x5a, 0x19, 0x04, 0x05, 0xfd, 0x02, 0x75, 0x75, 0x67, 0xa1, 0xd5, 0x06, 0x3e, 0xf4, 0x3b, 0xcf, 0xf6, 0xda, 0xc1, 0x30, 0xcc, 0xfa, 0xfe, 0x2d, 0x86, 0x9c, 0xc3, 0x49, 0x81, 0xbd, 0x7b, 0x0b, 0x45, 0x23, 0x05, 0xfb, 0x9c, 0x96, 0x96, 0x4b, 0x48, 0x4b, 0x7b, 0x6b, 0xc0, 0xdf, 0x79, 0xb6, 0x57, 0xe6, 0xa0, 0x5d, 0x89, 0x9c, 0xc3, 0xe9, 0x1a, 0x05, 0x05, 0x16, 0xea, 0x2f, 0xbd, 0xff, 0xe5, 0x0d, 0x2c, 0x96, 0x2c, 0x58, 0xad, 0x57, 0x21, 0x96, 0xbd, 0x1e, 0x22, 0x86, 0x9c, 0xc3, 0xe9, 0x1a, 0x15, 0x15, 0x85, 0x54, 0xa4, 0xe0, 0x93, 0x2c, 0xbd, 0xad, 0x53, 0x0f, 0xde, 0x7f, 0xff, 0xe1, 0x96, 0x58, 0x28, 0x7b, 0xc9, 0x39, 0x9f, 0x6e, 0xa0, 0xaa, 0xea, 0x27, 0x34, 0x37, 0x57, 0x52, 0x95, 0x3d, 0x74, 0xe8, 0x0c, 0x08, 0x21, 0xce, 0xab, 0xab, 0xab, 0x07, 0x37, 0x6e, 0x34, 0xe1, 0xd8, 0xb1, 0x72, 0x6c, 0xd8, 0xb0, 0x07, 0xe3, 0xc7, 0x2f, 0x72, 0x49, 0xa2, 0x81, 0x50, 0x54, 0x54, 0x20, 0xda, 0xbb, 0x3e, 0x44, 0x0c, 0x29, 0xe6, 0x70, 0x1e, 0x3c, 0x78, 0x06, 0x4b, 0x97, 0x6e, 0x41, 0x54, 0x54, 0x0a, 0x34, 0x9a, 0x68, 0xa8, 0x54, 0x21, 0x60, 0x18, 0x15, 0xd4, 0xea, 0x30, 0x68, 0x34, 0x31, 0x88, 0x8a, 0x4a, 0x41, 0x7a, 0xfa, 0xbb, 0xc8, 0xc9, 0x29, 0x13, 0xd8, 0xbf, 0xf8, 0x37, 0x00, 0xe2, 0xd2, 0xbf, 0xb0, 0x5a, 0x19, 0x28, 0x95, 0xa1, 0x58, 0xbc, 0x78, 0xea, 0x03, 0xff, 0xaf, 0x52, 0x29, 0x30, 0x76, 0x6c, 0x30, 0x16, 0x2e, 0xd4, 0x63, 0xeb, 0xd6, 0xd5, 0xa8, 0xad, 0xcd, 0xc3, 0x9f, 0xff, 0x7c, 0x18, 0x0c, 0x33, 0x92, 0x9a, 0x1c, 0x3f, 0xfe, 0x78, 0x11, 0x62, 0xd9, 0xeb, 0x21, 0x62, 0x48, 0x25, 0xe7, 0xd0, 0xe1, 0x20, 0x78, 0xf3, 0xcd, 0x7f, 0x22, 0x2c, 0x2c, 0x0e, 0xcb, 0x96, 0xc5, 0xe1, 0xf0, 0xe1, 0xb7, 0x51, 0x5b, 0x9b, 0x8b, 0xb6, 0xb6, 0x2b, 0xe8, 0xe9, 0x69, 0x06, 0xd0, 0x83, 0xee, 0x6e, 0x3b, 0xda, 0xda, 0xaa, 0x50, 0x5b, 0x9b, 0x8b, 0x9c, 0x9c, 0xcd, 0x48, 0x4f, 0x37, 0x23, 0x2c, 0x2c, 0x0e, 0x9b, 0x36, 0x65, 0xa3, 0xb3, 0xb3, 0x07, 0xa3, 0x47, 0x1b, 0xc1, 0x30, 0x0c, 0xe7, 0xb5, 0x69, 0x13, 0x9d, 0xb3, 0x7c, 0xe2, 0x04, 0xdd, 0x30, 0x35, 0x32, 0xf2, 0x09, 0xa8, 0x54, 0xdc, 0x8d, 0xf1, 0xdb, 0x6f, 0xa7, 0x62, 0xf1, 0xe2, 0xcd, 0xd4, 0x3a, 0xe9, 0xe8, 0xb8, 0x05, 0xb1, 0xec, 0x25, 0xc9, 0xe1, 0xea, 0xf1, 0xe3, 0x15, 0x58, 0xb5, 0xea, 0x05, 0xdc, 0xbe, 0x5d, 0xd2, 0xaf, 0x9f, 0xa5, 0xef, 0xdb, 0x35, 0x9a, 0x18, 0xb4, 0xb6, 0x5e, 0xa6, 0x7a, 0x5e, 0x69, 0x69, 0x1d, 0xcc, 0xe6, 0x48, 0xce, 0x72, 0x61, 0x61, 0x71, 0xb0, 0xdb, 0xcf, 0x70, 0xb6, 0x18, 0xcf, 0x3e, 0xfb, 0x57, 0x7c, 0xf9, 0xe5, 0xef, 0xa8, 0x9e, 0x7d, 0xf2, 0x64, 0x15, 0x66, 0xcd, 0x8a, 0xe1, 0x7c, 0xbf, 0xde, 0x77, 0x53, 0x82, 0x90, 0x6e, 0x51, 0x86, 0xab, 0x2a, 0x27, 0x43, 0x18, 0xc6, 0x4c, 0x08, 0x21, 0x6c, 0xce, 0x61, 0x6e, 0x6e, 0x2e, 0x6a, 0x6a, 0xd6, 0x50, 0x2f, 0xaa, 0xe5, 0x2b, 0x87, 0x73, 0xc3, 0x86, 0x3d, 0xd8, 0xbe, 0xfd, 0x15, 0x10, 0x72, 0xcf, 0xed, 0x21, 0xa1, 0xbb, 0xe5, 0xad, 0x56, 0x06, 0x01, 0x01, 0xe3, 0xa9, 0x48, 0x71, 0xed, 0xda, 0x5d, 0xd8, 0xed, 0xe7, 0xa8, 0xe4, 0x3e, 0xf3, 0xcc, 0x6c, 0xea, 0x3a, 0x98, 0x4c, 0x91, 0xd4, 0x65, 0x95, 0xca, 0x51, 0x0f, 0xfd, 0x1f, 0x9f, 0xf6, 0x62, 0x49, 0x31, 0xa8, 0xf3, 0x29, 0xd4, 0xee, 0x76, 0x5c, 0x48, 0x4f, 0x7f, 0x17, 0xdb, 0xb6, 0xad, 0xf1, 0x88, 0x14, 0x9e, 0x22, 0x3a, 0x3a, 0x91, 0xd2, 0xbf, 0x38, 0x09, 0xc0, 0xc1, 0xd9, 0x5a, 0x28, 0x14, 0x1a, 0xfc, 0xea, 0x57, 0x66, 0xea, 0xe7, 0xd7, 0xd5, 0xd9, 0xa9, 0xcb, 0x8e, 0x1c, 0x39, 0x06, 0x62, 0xd9, 0xeb, 0x01, 0x62, 0xb0, 0xb1, 0x72, 0xa1, 0x76, 0xb7, 0x73, 0x85, 0xd5, 0xab, 0xb7, 0x23, 0x27, 0x67, 0xb3, 0xa8, 0xc1, 0x23, 0x00, 0x98, 0x39, 0x93, 0x8e, 0x18, 0xc7, 0x8f, 0xd3, 0xf9, 0x17, 0xe3, 0xc6, 0x3d, 0x8e, 0x80, 0x00, 0x95, 0x1b, 0xf1, 0x89, 0x4a, 0xea, 0xb2, 0x63, 0xc6, 0x4c, 0x1e, 0x84, 0xdc, 0xde, 0xdb, 0xab, 0x7f, 0x6e, 0xc6, 0x43, 0x6f, 0xc0, 0x30, 0x0c, 0x43, 0x08, 0x21, 0xb3, 0x67, 0xcf, 0x46, 0x49, 0x49, 0x89, 0x73, 0x77, 0xbb, 0xfa, 0xfa, 0x37, 0x00, 0xbc, 0x31, 0x60, 0xc5, 0x68, 0x77, 0xb7, 0x1b, 0x0c, 0xef, 0xbf, 0x7f, 0x14, 0xff, 0xf8, 0xc7, 0x06, 0x2a, 0x52, 0xb8, 0x37, 0xf6, 0xe7, 0x46, 0x5a, 0x1a, 0x1d, 0x31, 0xce, 0x9f, 0xb7, 0x50, 0x3e, 0x77, 0xb6, 0x5b, 0xef, 0xfe, 0xc5, 0x17, 0xfb, 0xa9, 0xcb, 0x4e, 0x9b, 0x36, 0x73, 0xd0, 0xdf, 0xbc, 0xb1, 0xd7, 0x40, 0x09, 0x3b, 0x54, 0x67, 0x7b, 0x09, 0x99, 0xc3, 0x69, 0xb5, 0x5e, 0xc5, 0x2f, 0x7f, 0xf9, 0xdf, 0xe8, 0xee, 0xb6, 0x53, 0x91, 0x82, 0x61, 0xd4, 0x88, 0x8e, 0x4e, 0xc1, 0xf2, 0xe5, 0xcf, 0x61, 0xfe, 0xfc, 0x69, 0x88, 0x8d, 0x8d, 0x80, 0x42, 0xc1, 0xe0, 0xfb, 0xef, 0xab, 0xf0, 0xf5, 0xd7, 0xdf, 0x21, 0x3f, 0xff, 0x1b, 0x54, 0x57, 0xe7, 0x01, 0xe8, 0xe1, 0x6c, 0xf6, 0x55, 0x2a, 0x2d, 0x3a, 0x3a, 0x6e, 0x43, 0xa1, 0x70, 0x4d, 0xb6, 0x9f, 0x7e, 0x6a, 0xc5, 0x98, 0x31, 0xa1, 0x00, 0xba, 0x39, 0x65, 0x7e, 0xfa, 0x69, 0x21, 0xd6, 0xae, 0xa5, 0x23, 0x47, 0x5e, 0x5e, 0x39, 0x52, 0x52, 0xe2, 0x40, 0x48, 0x27, 0xa7, 0x5c, 0x00, 0x38, 0x70, 0xc0, 0x8a, 0x65, 0xcb, 0xb8, 0xf7, 0xa0, 0xe7, 0x23, 0x47, 0xd4, 0xe7, 0xa9, 0x7d, 0x13, 0x27, 0x2e, 0x41, 0x75, 0xf5, 0x51, 0x2a, 0x52, 0x84, 0x85, 0x4d, 0xc7, 0x17, 0x5f, 0xec, 0xc2, 0x92, 0x25, 0x53, 0x5d, 0x96, 0x9d, 0x34, 0x69, 0x39, 0x2e, 0x5d, 0x3a, 0xc0, 0xa9, 0xec, 0xa8, 0xa8, 0x14, 0x54, 0x57, 0x1f, 0xe5, 0xac, 0x63, 0x56, 0xd6, 0x09, 0x64, 0x66, 0x3e, 0xcd, 0x29, 0x8f, 0x61, 0x02, 0x70, 0xf7, 0x6e, 0x23, 0x82, 0x83, 0x47, 0x72, 0xca, 0x3c, 0x75, 0xea, 0x0a, 0x9e, 0x7e, 0x7a, 0x01, 0xda, 0xda, 0xae, 0x50, 0xbd, 0xbb, 0x56, 0x1b, 0x87, 0x3b, 0x77, 0xf8, 0x3d, 0xb1, 0xc2, 0xa3, 0xd4, 0x3e, 0xf6, 0xc6, 0xfb, 0x37, 0xdb, 0x84, 0x20, 0xc5, 0xdf, 0xfe, 0x96, 0x47, 0x65, 0x18, 0xab, 0x95, 0xc1, 0x84, 0x09, 0xc9, 0xa8, 0xab, 0x3b, 0xc5, 0x49, 0x0a, 0x00, 0xa8, 0xad, 0xfd, 0x8e, 0xea, 0xf9, 0xd3, 0xa7, 0x27, 0x52, 0x7e, 0xd9, 0x74, 0xdd, 0x48, 0x78, 0x78, 0x02, 0x27, 0x29, 0x3a, 0x3b, 0x7b, 0xf0, 0xf2, 0xcb, 0x9f, 0xe0, 0xc9, 0x27, 0x13, 0xa8, 0x49, 0x01, 0x00, 0x19, 0x19, 0xbf, 0xe7, 0x4b, 0xed, 0x1f, 0xf7, 0xb1, 0xeb, 0xa0, 0x50, 0x51, 0x32, 0x2b, 0x96, 0x10, 0xf2, 0x22, 0x80, 0x5d, 0x7c, 0x12, 0xe3, 0xbd, 0xf7, 0xfe, 0x8f, 0xd3, 0x1f, 0xb0, 0x5a, 0x19, 0x8c, 0x19, 0x33, 0x13, 0xe7, 0xce, 0xe5, 0x40, 0xa3, 0x19, 0xc1, 0x29, 0xf3, 0xfb, 0xef, 0xab, 0xd1, 0xd1, 0x71, 0x9d, 0xea, 0xf9, 0xc9, 0xc9, 0x74, 0xc4, 0x38, 0x73, 0x86, 0xce, 0xf1, 0x9c, 0x36, 0xed, 0xc1, 0x2e, 0xa4, 0xbd, 0xbd, 0x0b, 0x37, 0x6e, 0x34, 0xa1, 0xaa, 0xea, 0x16, 0x0a, 0x0a, 0xce, 0xa3, 0xb0, 0xf0, 0x24, 0x4a, 0x4b, 0xf7, 0xa3, 0xb3, 0xb3, 0xc1, 0x2d, 0x3f, 0x68, 0xdc, 0xb8, 0xb9, 0xf8, 0xd3, 0x9f, 0xd2, 0xf9, 0x50, 0xf9, 0x4b, 0x0c, 0xc3, 0x7c, 0x4e, 0x53, 0x50, 0xe5, 0x86, 0xd0, 0x28, 0x3e, 0x49, 0xb1, 0x7b, 0xf7, 0x77, 0x0f, 0x04, 0xb0, 0x06, 0x6f, 0x9e, 0x47, 0x20, 0x3b, 0xfb, 0x73, 0x8c, 0x1e, 0x1d, 0x40, 0x25, 0xf7, 0xc0, 0x81, 0x93, 0x54, 0x64, 0x63, 0x98, 0x91, 0x48, 0x4f, 0xe7, 0xf6, 0x8d, 0xee, 0xde, 0xbd, 0x87, 0x5b, 0xb7, 0x8a, 0xa9, 0x9e, 0x7d, 0xec, 0xd8, 0x3b, 0x60, 0x98, 0x77, 0x78, 0x73, 0x8c, 0xad, 0x56, 0x06, 0x6a, 0xf5, 0xa3, 0x38, 0x7a, 0x74, 0x0f, 0x5f, 0x6a, 0xa7, 0xb6, 0xa1, 0x8a, 0xc3, 0xc7, 0x70, 0xb5, 0x9e, 0xc4, 0x2b, 0x64, 0x65, 0x7d, 0x4e, 0xa5, 0xa4, 0x79, 0xf3, 0xd6, 0x63, 0xfe, 0xfc, 0xc9, 0x6e, 0x0c, 0xff, 0x4e, 0x52, 0x0e, 0xfd, 0xa6, 0x53, 0xf9, 0x02, 0xfb, 0xf6, 0x15, 0x81, 0x90, 0x0e, 0xce, 0x7a, 0x9a, 0xcd, 0x64, 0xc0, 0x11, 0x93, 0xa7, 0x43, 0x6f, 0x36, 0x26, 0xf2, 0xe9, 0xa7, 0x47, 0x60, 0x32, 0xe9, 0xf8, 0x52, 0xfb, 0x1f, 0x08, 0x21, 0x7f, 0xa0, 0xf1, 0x31, 0x54, 0xbe, 0x70, 0x3a, 0xbb, 0xbb, 0x1d, 0xb8, 0x70, 0xe1, 0x08, 0x45, 0xdf, 0xaa, 0xc0, 0x96, 0x2d, 0xbf, 0x75, 0x4b, 0xf6, 0xa5, 0x4b, 0xa7, 0xa8, 0xca, 0x4d, 0x9d, 0x4a, 0xd7, 0x8d, 0xe4, 0xe6, 0x5a, 0xa8, 0x9f, 0xcd, 0x57, 0xfc, 0xa5, 0x77, 0xc4, 0x14, 0x86, 0x4f, 0x3e, 0x39, 0x8c, 0x35, 0x6b, 0x1e, 0x17, 0xcc, 0x0e, 0xac, 0x9d, 0x07, 0x22, 0x88, 0x82, 0x6b, 0x98, 0x2a, 0xc4, 0x7a, 0x92, 0xfd, 0xfb, 0x4b, 0xd1, 0xd5, 0xf5, 0x13, 0xa7, 0x22, 0x23, 0x22, 0xe6, 0x62, 0xc6, 0x0c, 0xfa, 0x1e, 0xac, 0xb6, 0xd6, 0x8e, 0xa6, 0xa6, 0x0a, 0xaa, 0xb2, 0x0b, 0x16, 0xcc, 0xa2, 0x2a, 0x57, 0x5a, 0x5a, 0x08, 0xb1, 0xc0, 0xe6, 0x68, 0x68, 0xb5, 0x26, 0xe4, 0xe7, 0x9f, 0xc6, 0x4b, 0x2f, 0xcd, 0xf2, 0x4a, 0x9e, 0x37, 0xeb, 0x4b, 0x54, 0x03, 0x91, 0xc2, 0xd5, 0xb1, 0x0d, 0xe5, 0xe5, 0xe5, 0x28, 0x2f, 0x2f, 0xc7, 0x8e, 0x1d, 0x3b, 0x3c, 0x0e, 0x6c, 0x1d, 0x3b, 0x76, 0x9a, 0x72, 0xd4, 0x30, 0xc7, 0x2d, 0xb9, 0xfb, 0xf6, 0x7d, 0x07, 0x9a, 0x69, 0x71, 0x80, 0xc1, 0x8a, 0x15, 0x4f, 0x70, 0xca, 0xeb, 0x75, 0x1e, 0x4f, 0x8b, 0x42, 0x08, 0xa0, 0x37, 0xdd, 0x2e, 0x25, 0x65, 0x23, 0xf6, 0xed, 0xfb, 0x3d, 0x02, 0x03, 0xd5, 0x1e, 0xcb, 0xf3, 0xc4, 0x7e, 0x84, 0x10, 0xd2, 0xb7, 0xe5, 0x50, 0xf5, 0x27, 0x85, 0xc5, 0x62, 0x41, 0x5a, 0x5a, 0x1a, 0xec, 0x76, 0x3b, 0xd4, 0xea, 0x08, 0x84, 0x87, 0x6f, 0x40, 0x48, 0xc8, 0x42, 0x8c, 0x1c, 0xd9, 0xfb, 0xe5, 0x76, 0x74, 0xd4, 0xa0, 0xa9, 0xe9, 0x38, 0x1a, 0x1a, 0x3e, 0x70, 0x9e, 0x36, 0x7c, 0xf8, 0xf0, 0x61, 0xcc, 0x9e, 0x4d, 0x1f, 0xf1, 0x3b, 0x77, 0xee, 0x0c, 0x55, 0xb9, 0xb9, 0x73, 0x67, 0xb8, 0xa5, 0x90, 0xfc, 0x7c, 0x3a, 0xff, 0x22, 0x24, 0xc4, 0x80, 0xc8, 0xc8, 0x50, 0xce, 0x72, 0x39, 0x39, 0x56, 0x38, 0x1c, 0xad, 0x02, 0x2f, 0x13, 0x00, 0x94, 0xca, 0x50, 0x3c, 0xf1, 0xc4, 0x6f, 0xf0, 0xd1, 0x47, 0x1b, 0x61, 0x30, 0x8c, 0xf5, 0x4a, 0xae, 0x37, 0xf6, 0xeb, 0x4b, 0x0e, 0x55, 0xff, 0x96, 0x22, 0x35, 0x35, 0xd5, 0xe5, 0xfa, 0x84, 0xc0, 0x40, 0x03, 0x02, 0x03, 0x0d, 0x18, 0x33, 0xe6, 0x15, 0xe7, 0xfa, 0x84, 0xd4, 0xd4, 0x54, 0xb7, 0xd6, 0x93, 0xdc, 0xbc, 0x49, 0x37, 0x1d, 0x6e, 0x36, 0xbb, 0xd7, 0x12, 0x9d, 0x3f, 0x4f, 0xe7, 0x5f, 0x4c, 0x9e, 0x4c, 0xe7, 0x5f, 0x1c, 0x39, 0x52, 0xe8, 0xb6, 0x91, 0x69, 0xa1, 0x54, 0x86, 0x20, 0x3a, 0x7a, 0x01, 0x52, 0x53, 0x97, 0x62, 0xd3, 0xa6, 0xa5, 0x08, 0x0b, 0x1b, 0xe5, 0x35, 0xd9, 0xf8, 0xb0, 0x1f, 0x4b, 0x8e, 0x07, 0xba, 0x92, 0xfe, 0xeb, 0x13, 0x5c, 0x05, 0x46, 0xd9, 0xf5, 0x09, 0xec, 0x4c, 0xdd, 0xba, 0x75, 0xeb, 0xa8, 0xf7, 0x04, 0x6f, 0x6a, 0xba, 0x46, 0x55, 0x4e, 0xa7, 0xd3, 0x52, 0x2b, 0xa5, 0xb5, 0xb5, 0x13, 0xb7, 0x6e, 0xd1, 0xf9, 0x3d, 0x73, 0xe6, 0xd0, 0x11, 0xa3, 0xa4, 0xc4, 0xe2, 0x21, 0x29, 0x7a, 0x87, 0xd9, 0x0a, 0xc5, 0x48, 0xa8, 0xd5, 0x21, 0x08, 0x0c, 0xfc, 0x19, 0x42, 0x43, 0xc7, 0x21, 0x32, 0xf2, 0x31, 0x18, 0x0c, 0x53, 0xb0, 0x68, 0x51, 0x02, 0x92, 0x93, 0x63, 0xa9, 0x92, 0x79, 0xdc, 0x01, 0x9f, 0xf6, 0x53, 0xf1, 0x71, 0x4a, 0x72, 0x4b, 0x4b, 0x91, 0xf3, 0xb4, 0x61, 0x9a, 0x5c, 0x8c, 0xce, 0xce, 0xdb, 0x54, 0x2f, 0x3a, 0x76, 0x6c, 0x08, 0xb5, 0x52, 0x0e, 0x1c, 0x28, 0xe5, 0x9c, 0xae, 0x67, 0x8d, 0xb8, 0x7c, 0x39, 0x37, 0x31, 0xba, 0xbb, 0x1d, 0xa8, 0xaf, 0xa7, 0xeb, 0x9a, 0xde, 0x7b, 0xef, 0x6b, 0xbc, 0xf9, 0xe6, 0x62, 0xf8, 0x12, 0x7c, 0xda, 0x8f, 0x10, 0x42, 0x14, 0xf0, 0xc1, 0x7a, 0x12, 0x87, 0xe3, 0x1e, 0x65, 0xcb, 0x72, 0x8f, 0xba, 0x1e, 0x79, 0x79, 0x74, 0xdd, 0x48, 0x40, 0x80, 0x0e, 0xf1, 0xf1, 0x13, 0x28, 0xba, 0x91, 0xb3, 0xe8, 0xe9, 0x69, 0xa2, 0x20, 0x9a, 0x02, 0x2b, 0x57, 0x26, 0xc2, 0xd7, 0xe0, 0xdb, 0x7e, 0xce, 0xb6, 0x4c, 0xdc, 0xf5, 0x24, 0x74, 0xce, 0x9c, 0xc5, 0x72, 0xd1, 0x8d, 0xa1, 0x19, 0xdd, 0xd7, 0x3d, 0x71, 0x22, 0xdd, 0x10, 0xf0, 0xd0, 0x21, 0x3a, 0xff, 0x22, 0x34, 0x34, 0x96, 0xca, 0x91, 0x15, 0x1a, 0x7c, 0xdb, 0xcf, 0x49, 0x0c, 0x31, 0xd7, 0x93, 0xa8, 0x54, 0x74, 0x8a, 0xfc, 0xec, 0xb3, 0x43, 0x94, 0x2d, 0x10, 0xc1, 0xd5, 0xab, 0x74, 0x13, 0x67, 0xb4, 0x89, 0x39, 0x45, 0x45, 0x74, 0x81, 0x2d, 0xbd, 0x7e, 0x36, 0xa4, 0x00, 0xbe, 0xed, 0xe7, 0x93, 0x75, 0x25, 0x01, 0x01, 0x8f, 0x50, 0x7e, 0x05, 0xdb, 0x71, 0xe2, 0x44, 0x25, 0x47, 0x13, 0x5a, 0x8c, 0x71, 0xe3, 0x66, 0x53, 0x05, 0xcc, 0x00, 0x20, 0x35, 0x35, 0x91, 0x8a, 0x68, 0x35, 0x35, 0xff, 0xa6, 0xaa, 0xe3, 0xfc, 0xf9, 0xd2, 0x20, 0x06, 0xdf, 0x70, 0x12, 0x43, 0xcc, 0xf5, 0x24, 0x91, 0x91, 0x26, 0x8a, 0xa1, 0x2a, 0x81, 0xc3, 0xd1, 0x8a, 0xe4, 0xe4, 0x27, 0x90, 0x9e, 0xfe, 0x2e, 0x72, 0x73, 0x6d, 0xb8, 0x75, 0xab, 0x05, 0xcd, 0xcd, 0x1d, 0x38, 0x75, 0xea, 0x0a, 0x32, 0x32, 0x76, 0x21, 0x22, 0x62, 0x1e, 0x56, 0xae, 0x9c, 0x81, 0x86, 0x86, 0x93, 0x54, 0xd3, 0xd7, 0x4a, 0x65, 0x28, 0x92, 0x92, 0xb8, 0xa7, 0x7e, 0x8e, 0x1d, 0x2b, 0x47, 0x77, 0xf7, 0x6d, 0x2a, 0x47, 0x76, 0xd5, 0x2a, 0x69, 0x10, 0x83, 0x6f, 0xfb, 0x39, 0x89, 0x21, 0xe6, 0x7a, 0x92, 0xc4, 0x44, 0xba, 0x88, 0xa6, 0xd9, 0x4c, 0xd0, 0xdd, 0x6d, 0x47, 0x4e, 0xce, 0x66, 0xa4, 0xa4, 0xc4, 0x22, 0x3c, 0x3c, 0x18, 0x21, 0x21, 0x01, 0x48, 0x4c, 0x8c, 0xc6, 0x87, 0x1f, 0xae, 0xc5, 0xf5, 0xeb, 0x05, 0xce, 0x72, 0x74, 0xc3, 0xdf, 0x99, 0x54, 0x43, 0xc4, 0x83, 0x07, 0xe9, 0xba, 0x91, 0xe0, 0xe0, 0xc9, 0x98, 0x34, 0xe9, 0x67, 0x92, 0x20, 0x06, 0xdf, 0xf6, 0x53, 0xc0, 0x07, 0x7b, 0x82, 0x6f, 0xdc, 0xb8, 0x0c, 0x0a, 0xc5, 0x28, 0xaa, 0xc0, 0x10, 0xbb, 0x5f, 0x84, 0xab, 0x8b, 0x16, 0x71, 0x71, 0x74, 0xfe, 0xc5, 0xa9, 0x53, 0x74, 0x8e, 0xe7, 0xa4, 0x49, 0xd2, 0xe9, 0x46, 0xf8, 0xb6, 0x9f, 0xc2, 0x17, 0x7b, 0x82, 0x47, 0x47, 0x3f, 0x8a, 0x59, 0xb3, 0xfe, 0x47, 0x74, 0xe5, 0xd1, 0x26, 0xe6, 0x5c, 0xb9, 0x42, 0xd7, 0x62, 0xcc, 0x9d, 0x2b, 0x1d, 0x62, 0xf0, 0xbd, 0x07, 0xb9, 0xcf, 0x4e, 0x49, 0xbe, 0x73, 0xa7, 0x0d, 0x31, 0x31, 0xb3, 0x60, 0xb7, 0x97, 0x79, 0x34, 0x17, 0xf1, 0x9f, 0xd6, 0x46, 0x09, 0xb3, 0xb9, 0x9b, 0xb3, 0xac, 0x42, 0x31, 0x0a, 0x8d, 0x8d, 0x77, 0x38, 0x73, 0x30, 0x0a, 0x0a, 0x2e, 0x61, 0xde, 0xbc, 0x49, 0x2e, 0xbb, 0x28, 0xf6, 0xd9, 0xb4, 0x2b, 0xd8, 0xc4, 0x02, 0x9f, 0x5b, 0x2e, 0x29, 0xd8, 0x7f, 0xf4, 0x7e, 0xc9, 0xe2, 0xad, 0x27, 0x09, 0x0b, 0x1b, 0x85, 0x82, 0x82, 0xaf, 0x10, 0x16, 0x36, 0xdd, 0xad, 0x2d, 0x01, 0xfe, 0x53, 0x56, 0x85, 0xf9, 0xf3, 0x37, 0x22, 0x2e, 0xee, 0x05, 0xaa, 0x7b, 0x23, 0x23, 0xe7, 0x50, 0x25, 0xe6, 0x1c, 0x38, 0x60, 0xa1, 0xf2, 0x5b, 0x02, 0x03, 0xa3, 0x24, 0x45, 0x0a, 0xbe, 0xec, 0x37, 0x60, 0xf2, 0x8e, 0x2f, 0xb6, 0x71, 0x6c, 0x69, 0xe9, 0x20, 0x0b, 0x17, 0xbe, 0x45, 0x94, 0xca, 0xd1, 0xd4, 0xdb, 0x21, 0x1a, 0x0c, 0xab, 0x48, 0x7e, 0x7e, 0x25, 0x21, 0x84, 0x10, 0x8d, 0xe6, 0x31, 0x02, 0x80, 0x98, 0xcd, 0x64, 0xd0, 0x0b, 0x00, 0x79, 0xf9, 0xe5, 0x4f, 0xa8, 0xea, 0x63, 0x34, 0xfe, 0x9a, 0xaa, 0x1e, 0x53, 0xa7, 0x3e, 0x3f, 0xbc, 0xf6, 0x20, 0x7f, 0x70, 0x3f, 0xcb, 0x62, 0x92, 0x99, 0x99, 0x49, 0x0c, 0x06, 0x03, 0xd1, 0x68, 0x34, 0x44, 0xa3, 0xd1, 0x10, 0x83, 0xc1, 0x40, 0x32, 0x33, 0x33, 0x49, 0x71, 0x71, 0x31, 0xaf, 0x2f, 0x73, 0xe3, 0x46, 0x13, 0xc9, 0xc8, 0xd8, 0x45, 0xa6, 0x4e, 0x7d, 0x9e, 0x04, 0x07, 0xeb, 0x89, 0x5a, 0x3d, 0x86, 0x30, 0x8c, 0x9a, 0x28, 0x95, 0x21, 0x44, 0xa3, 0x89, 0x21, 0x13, 0x26, 0x24, 0x93, 0xe7, 0x9f, 0xdf, 0x41, 0x8a, 0x8b, 0x6b, 0x9c, 0xf7, 0x7c, 0xf5, 0xd5, 0x39, 0xe7, 0x4b, 0xba, 0x22, 0x05, 0xc3, 0xa8, 0x49, 0x75, 0xf5, 0x6d, 0xaa, 0x7a, 0x04, 0x04, 0x8c, 0xa7, 0x22, 0xc6, 0xab, 0xaf, 0x7e, 0xe6, 0x07, 0xfb, 0x91, 0xd2, 0xdb, 0xaf, 0x3f, 0x0f, 0x98, 0xc1, 0xc8, 0xe1, 0x0f, 0x41, 0x18, 0xbd, 0x7e, 0x05, 0x2a, 0x2b, 0xbf, 0xe4, 0x8c, 0x37, 0x18, 0x0c, 0x2b, 0x61, 0xb3, 0xed, 0x85, 0x8c, 0x81, 0x41, 0x95, 0xda, 0xe7, 0xf4, 0x4a, 0x05, 0x5c, 0x4f, 0xc2, 0x07, 0x36, 0x6c, 0xd8, 0x83, 0xca, 0xca, 0x2f, 0x29, 0x1c, 0x54, 0x06, 0xef, 0xbc, 0xf3, 0x3b, 0xd9, 0xfa, 0xae, 0xed, 0x0c, 0x2a, 0x62, 0xf4, 0xb9, 0x31, 0x96, 0x19, 0x00, 0x00, 0x6e, 0x7b, 0x5a, 0x99, 0xb8, 0xb8, 0x97, 0xa0, 0x50, 0x8c, 0x40, 0x4c, 0x4c, 0x1a, 0xfe, 0xf8, 0xc7, 0x83, 0xb0, 0xdb, 0xdb, 0xdd, 0xba, 0xff, 0xe6, 0xcd, 0x66, 0x2c, 0x5a, 0xf4, 0x36, 0xb6, 0x6d, 0x7b, 0x81, 0xca, 0x49, 0x34, 0x1a, 0x57, 0x21, 0x2d, 0x6d, 0xda, 0x70, 0xb6, 0xff, 0x6d, 0x66, 0x10, 0xb8, 0xb4, 0xbd, 0x3b, 0x4f, 0xe0, 0xa3, 0x8b, 0xd1, 0x6a, 0x4d, 0x68, 0x6c, 0x3c, 0xdb, 0x87, 0x7c, 0x01, 0xd0, 0xe9, 0x66, 0x23, 0x21, 0xe1, 0x49, 0x3c, 0xfe, 0xb8, 0x09, 0xb3, 0x66, 0x4d, 0xc1, 0xcf, 0x7f, 0xfe, 0x28, 0x42, 0x42, 0x02, 0x70, 0xe7, 0x4e, 0x1b, 0x7e, 0xfc, 0xb1, 0x19, 0x65, 0x65, 0x35, 0xb0, 0x5a, 0x2f, 0xe2, 0xdb, 0x6f, 0x0b, 0x50, 0x59, 0x79, 0x14, 0xdd, 0xdd, 0x76, 0x4e, 0x52, 0xf4, 0x66, 0x5a, 0x3f, 0x82, 0x33, 0x67, 0x2e, 0xc0, 0x68, 0xfc, 0x2f, 0xb9, 0x79, 0x80, 0x7b, 0x67, 0x99, 0x30, 0x9e, 0x90, 0xc2, 0xd3, 0x45, 0xce, 0xad, 0xad, 0x9d, 0x08, 0x0e, 0x0e, 0x02, 0x21, 0x5d, 0x4e, 0xa3, 0x7a, 0x92, 0x16, 0x47, 0xb7, 0xac, 0x8f, 0xc1, 0x96, 0x2d, 0x87, 0xb1, 0x79, 0xf3, 0x33, 0x43, 0xde, 0xe0, 0x42, 0x1c, 0x74, 0xc3, 0xb8, 0x43, 0x0a, 0x57, 0xd9, 0xc7, 0x7d, 0x31, 0x58, 0xf6, 0x78, 0x4e, 0x4e, 0x19, 0xd2, 0xd3, 0xcd, 0x82, 0xee, 0x7f, 0xc1, 0x12, 0x6d, 0xf5, 0xea, 0xed, 0xd8, 0xb3, 0x27, 0x73, 0x48, 0x13, 0xc2, 0x53, 0x7b, 0xd0, 0x90, 0x83, 0xa1, 0x25, 0x85, 0x3b, 0xd9, 0xc7, 0x5d, 0x5d, 0xd7, 0xa0, 0xd5, 0x6a, 0x1f, 0xca, 0x1e, 0xcf, 0xc8, 0xd8, 0x85, 0x0f, 0x3f, 0x5c, 0x2b, 0x18, 0x31, 0xd8, 0x8c, 0xaa, 0x17, 0x5f, 0xcc, 0xc2, 0xae, 0x5d, 0xaf, 0x0e, 0x69, 0x52, 0x78, 0x6b, 0x0f, 0xaf, 0x7c, 0x0c, 0xbe, 0x43, 0xe5, 0x33, 0x67, 0xbe, 0x8a, 0xd3, 0xa7, 0x3f, 0xe2, 0x9d, 0x18, 0x6c, 0x2b, 0x11, 0x10, 0x10, 0x89, 0xed, 0xdb, 0xf7, 0xe0, 0x95, 0x57, 0x9e, 0x1c, 0xf2, 0x2d, 0x85, 0xd0, 0xc7, 0x6f, 0x52, 0x25, 0xea, 0xf0, 0xb5, 0xbb, 0x7d, 0x55, 0xd5, 0x19, 0x5e, 0xc9, 0xc0, 0x5e, 0x4a, 0x65, 0x30, 0x16, 0x2e, 0x7c, 0x0b, 0x57, 0xaf, 0x56, 0x0e, 0x79, 0x52, 0xf0, 0x69, 0x0f, 0x8f, 0x5a, 0x0c, 0x21, 0xb6, 0x77, 0xd4, 0xe9, 0x9e, 0xc2, 0xf5, 0xeb, 0x27, 0x41, 0x48, 0x07, 0x2f, 0x0a, 0xd2, 0x6a, 0x4d, 0x48, 0x4a, 0xfa, 0x35, 0xfe, 0xf2, 0x97, 0xdf, 0x60, 0xc2, 0x04, 0x2d, 0x86, 0x03, 0x78, 0xde, 0xbe, 0xb1, 0x8c, 0x9d, 0x5d, 0xef, 0x0f, 0x57, 0xab, 0xdd, 0x79, 0xc9, 0x1e, 0xaf, 0xaf, 0x7f, 0x03, 0xd9, 0xd9, 0xd9, 0x48, 0x48, 0x48, 0x40, 0x7d, 0x7d, 0x3e, 0x5a, 0x5b, 0x3b, 0x71, 0xfc, 0x78, 0x39, 0x4e, 0x9f, 0xae, 0xc0, 0x85, 0x0b, 0x3f, 0xe0, 0xea, 0xd5, 0x6a, 0xd8, 0xed, 0x37, 0xd0, 0xdc, 0x7c, 0x13, 0x1d, 0x1d, 0xb7, 0xd1, 0xd3, 0xd3, 0x0e, 0x87, 0xe3, 0x1e, 0x08, 0xe9, 0x82, 0x42, 0x11, 0x08, 0xa5, 0x32, 0x08, 0x6a, 0x75, 0x10, 0x02, 0x03, 0x1f, 0xc1, 0xd8, 0xb1, 0x8f, 0x21, 0x26, 0x66, 0x32, 0xa6, 0x4e, 0x9d, 0x82, 0x67, 0x9f, 0x4d, 0xf4, 0x7a, 0xd5, 0x96, 0x3f, 0x82, 0x4f, 0x7b, 0xb0, 0x36, 0x76, 0xb7, 0xc5, 0x20, 0xbd, 0x01, 0x22, 0x23, 0xca, 0xcb, 0xcb, 0xa1, 0xd7, 0xdb, 0x10, 0x18, 0x68, 0x70, 0xeb, 0x25, 0xda, 0xdb, 0xcb, 0x51, 0x51, 0x61, 0x84, 0xc1, 0x60, 0x80, 0xcd, 0x66, 0x83, 0x0c, 0xef, 0xc1, 0xb7, 0x3d, 0x3c, 0x8a, 0x7c, 0x02, 0xf2, 0x69, 0x04, 0x52, 0x83, 0x58, 0xf6, 0x90, 0x4f, 0x1f, 0x90, 0xe1, 0x19, 0x31, 0xa4, 0x78, 0x1a, 0xc1, 0x70, 0x86, 0x58, 0xf6, 0xe0, 0x24, 0x86, 0x54, 0x4e, 0x23, 0x90, 0x21, 0xae, 0x3d, 0x5c, 0x11, 0x43, 0xf4, 0xec, 0x71, 0x19, 0xdc, 0xe0, 0xd9, 0x1e, 0x65, 0x6e, 0x13, 0xc3, 0x17, 0xd9, 0xe3, 0x32, 0xb8, 0xc1, 0x73, 0x36, 0xb8, 0xd9, 0xed, 0xe1, 0x6a, 0xdf, 0x21, 0xab, 0x7c, 0x40, 0xaf, 0xb4, 0x20, 0x46, 0x48, 0x9c, 0x9b, 0x6b, 0xf2, 0x91, 0xde, 0x92, 0x04, 0xdf, 0x47, 0x76, 0x7b, 0x45, 0x0e, 0x31, 0xb3, 0xc7, 0x65, 0xf8, 0x28, 0x1b, 0xdc, 0x53, 0x72, 0x78, 0x90, 0x3d, 0xbe, 0x44, 0x36, 0x21, 0xef, 0x58, 0xc2, 0x57, 0x36, 0x38, 0xef, 0xe4, 0xa0, 0x41, 0x9f, 0xfb, 0xd6, 0xf8, 0x6a, 0x59, 0x82, 0x3f, 0xc0, 0x4d, 0x7d, 0xac, 0xf1, 0xd6, 0x1e, 0x82, 0x81, 0x10, 0x72, 0xc1, 0xc5, 0xf3, 0x2f, 0xc8, 0x5d, 0x91, 0xb8, 0x5d, 0x81, 0xbb, 0xf6, 0x90, 0x04, 0x64, 0xe7, 0x55, 0xc2, 0xce, 0xa3, 0x0b, 0x30, 0x42, 0x93, 0x42, 0x1e, 0xee, 0x4a, 0x74, 0xb8, 0x29, 0x85, 0x49, 0x34, 0x31, 0x32, 0x8e, 0xfc, 0x09, 0xfe, 0xa0, 0x0f, 0x46, 0xc0, 0xd6, 0x42, 0x32, 0x07, 0xfc, 0x4a, 0x09, 0x62, 0x65, 0x60, 0x49, 0xb9, 0xc5, 0x10, 0x7d, 0xff, 0x50, 0x7f, 0x00, 0xcf, 0xfa, 0x88, 0x13, 0xaa, 0x9e, 0x82, 0x77, 0x25, 0xe2, 0xee, 0x1f, 0x2a, 0x7d, 0xf8, 0x8b, 0x3e, 0x04, 0x27, 0x86, 0x9c, 0x01, 0xe6, 0x9f, 0xfa, 0x18, 0x72, 0x19, 0x5c, 0x42, 0x1d, 0xbe, 0x23, 0x94, 0x5c, 0xa9, 0x42, 0x48, 0xe7, 0x53, 0xd4, 0x64, 0x62, 0x6f, 0x97, 0x4f, 0x8a, 0x25, 0x57, 0xac, 0x64, 0x5e, 0xc9, 0xb7, 0x18, 0x62, 0x64, 0x1c, 0x59, 0x2c, 0x16, 0xc4, 0xc7, 0xc7, 0x23, 0x2f, 0x2f, 0x0f, 0x6a, 0x75, 0x04, 0x74, 0xba, 0xad, 0xd0, 0xeb, 0x6d, 0x30, 0x99, 0x5a, 0x60, 0x32, 0xb5, 0x40, 0xaf, 0xb7, 0x41, 0xa7, 0xdb, 0x0a, 0xb5, 0x3a, 0xc2, 0x79, 0x78, 0x8b, 0xc5, 0xc2, 0xbd, 0x33, 0x9f, 0x10, 0x72, 0xfd, 0x25, 0x23, 0xce, 0xef, 0x87, 0xab, 0x42, 0x05, 0xcf, 0x84, 0x92, 0x3b, 0xec, 0x87, 0xab, 0x02, 0x65, 0x80, 0x65, 0x01, 0x68, 0x11, 0x23, 0x58, 0xc4, 0xb3, 0xdc, 0x96, 0xfb, 0x75, 0x17, 0x2d, 0x03, 0x4b, 0xb2, 0x2d, 0x46, 0x5f, 0x3f, 0x83, 0xcf, 0x10, 0x30, 0x21, 0x64, 0x24, 0x80, 0x4b, 0x00, 0xc6, 0x0b, 0xd5, 0x1a, 0xf1, 0x2c, 0xb7, 0x0e, 0xc0, 0x2f, 0x18, 0x86, 0xe9, 0x10, 0x42, 0x1f, 0x7e, 0x39, 0x2a, 0xe1, 0x73, 0xff, 0x50, 0x56, 0x16, 0xc3, 0x30, 0x1d, 0x00, 0xc6, 0x0b, 0x19, 0x3c, 0xe3, 0x59, 0xee, 0xf8, 0xfb, 0x75, 0x16, 0x44, 0x1f, 0x7e, 0xd9, 0x62, 0x0c, 0xd4, 0x72, 0xf0, 0xb1, 0xd1, 0x87, 0xd0, 0x23, 0x1e, 0xa1, 0x47, 0x0e, 0x7c, 0xeb, 0xc3, 0x6f, 0x89, 0xd1, 0x57, 0x19, 0x6c, 0x4c, 0xc0, 0x9b, 0xad, 0x81, 0x58, 0x59, 0x21, 0x21, 0x21, 0x68, 0x6e, 0x6e, 0xc6, 0xb4, 0x69, 0x4d, 0x50, 0x2a, 0x83, 0xdd, 0xaa, 0x4f, 0x4f, 0x4f, 0x33, 0xce, 0x9e, 0x0d, 0x41, 0x70, 0x70, 0x30, 0x9a, 0x9a, 0x9a, 0xfa, 0x45, 0x18, 0xf9, 0x95, 0xeb, 0xea, 0x1d, 0xf8, 0xd0, 0x87, 0x10, 0x50, 0x89, 0x16, 0x30, 0xe9, 0xf5, 0x0f, 0x08, 0x00, 0xc4, 0xc7, 0xc7, 0x0f, 0xba, 0x4f, 0xd7, 0x40, 0x5d, 0xd1, 0x50, 0x84, 0xd4, 0xf5, 0xa1, 0x10, 0x5b, 0x19, 0x14, 0xfb, 0x87, 0xda, 0x68, 0xb6, 0x1b, 0x04, 0x84, 0x5b, 0xae, 0x27, 0xd6, 0x32, 0x40, 0xbe, 0xf5, 0xe1, 0xb7, 0xc4, 0xe8, 0xa3, 0x90, 0x58, 0x66, 0x70, 0xc4, 0xfa, 0x3a, 0x78, 0x26, 0x76, 0x10, 0x8a, 0x2f, 0x7d, 0xf8, 0x3d, 0x31, 0x78, 0x80, 0x10, 0xcb, 0x27, 0xcb, 0x04, 0x94, 0xeb, 0x77, 0xf0, 0x4b, 0x62, 0x08, 0x11, 0x3c, 0x63, 0x18, 0xc6, 0x2c, 0x94, 0x5c, 0xbf, 0xd4, 0xb1, 0xbf, 0x3a, 0x6f, 0x42, 0x05, 0x8b, 0xfc, 0x29, 0x08, 0x25, 0xc3, 0x05, 0x39, 0x84, 0xc8, 0xb8, 0xf6, 0x97, 0x4c, 0x6e, 0x19, 0x14, 0xe4, 0xe0, 0x7b, 0xb9, 0x9e, 0xa4, 0x96, 0x01, 0xca, 0xf0, 0x8e, 0x1c, 0x7c, 0x2f, 0xd7, 0x93, 0xd4, 0x32, 0x40, 0xd9, 0xc7, 0xf0, 0xce, 0xe7, 0x70, 0x27, 0xa6, 0xe2, 0x4b, 0xb9, 0xf2, 0xa8, 0xc4, 0x4f, 0x83, 0x67, 0xfe, 0x10, 0x84, 0x92, 0x21, 0x43, 0x74, 0xfc, 0x3f, 0xcb, 0x88, 0xe5, 0xa1, 0xe9, 0x09, 0x6b, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static unsigned char icon64[]={ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0xaa, 0x69, 0x71, 0xde, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0e, 0xc4, 0x00, 0x00, 0x0e, 0xc4, 0x01, 0x95, 0x2b, 0x0e, 0x1b, 0x00, 0x00, 0x16, 0x09, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xd5, 0x5b, 0x79, 0x58, 0x93, 0x67, 0xb6, 0xff, 0xe5, 0xcb, 0x42, 0x08, 0x49, 0xc8, 0x4a, 0x04, 0xd9, 0x14, 0x41, 0x50, 0x41, 0x09, 0xa2, 0x56, 0x1d, 0x50, 0xc1, 0xad, 0x96, 0xd2, 0x5a, 0x9d, 0x6e, 0x2e, 0xb5, 0x2d, 0xd5, 0xd6, 0x56, 0x3b, 0x4a, 0xed, 0xad, 0xd7, 0xf6, 0xd6, 0x8e, 0xda, 0x65, 0xdc, 0xed, 0xae, 0xd3, 0x5b, 0x47, 0x6b, 0xf5, 0x8e, 0x9d, 0x22, 0xde, 0x16, 0xab, 0x8c, 0x0f, 0x32, 0x3a, 0x4c, 0x0b, 0x95, 0xc7, 0x0a, 0xb8, 0xd4, 0x8e, 0xa8, 0x10, 0x84, 0x40, 0x08, 0x21, 0x0b, 0x49, 0xbe, 0x2f, 0xe7, 0xfe, 0x21, 0xc4, 0x04, 0x82, 0x56, 0xad, 0xcb, 0x7d, 0x9f, 0x87, 0x3f, 0x78, 0xbf, 0x37, 0xe7, 0x7b, 0xcf, 0x79, 0xcf, 0xf2, 0x3b, 0xe7, 0xbc, 0x1f, 0x0f, 0x77, 0x61, 0x10, 0x11, 0xb1, 0x2c, 0x0b, 0x97, 0xcb, 0x05, 0x00, 0x10, 0x89, 0x44, 0x10, 0x08, 0x04, 0xe0, 0xf1, 0x78, 0x3c, 0xfc, 0x7f, 0x1e, 0xd4, 0x6d, 0x04, 0x5a, 0xc3, 0xb2, 0x2c, 0x1d, 0x39, 0x72, 0x84, 0x72, 0x72, 0xa6, 0x93, 0x52, 0xd9, 0x8f, 0x94, 0xca, 0x7e, 0x94, 0x93, 0x33, 0x9d, 0x8e, 0x1c, 0x39, 0x42, 0x2c, 0xcb, 0xd2, 0xcd, 0xd2, 0xbd, 0x27, 0x98, 0x6f, 0x6f, 0x6f, 0xa7, 0x0b, 0x17, 0x2e, 0xd0, 0x85, 0x0b, 0x17, 0xc8, 0x62, 0xb1, 0xf4, 0xd8, 0x2c, 0x11, 0x51, 0x41, 0x41, 0x01, 0x69, 0xb5, 0xc3, 0x28, 0x2e, 0xee, 0x6b, 0x4a, 0x4d, 0x6d, 0xa7, 0xd4, 0xd4, 0x76, 0x8a, 0x8b, 0xfb, 0x9a, 0xb4, 0xda, 0x61, 0x54, 0x50, 0x50, 0x10, 0xf0, 0x37, 0x16, 0x8b, 0xc5, 0x4b, 0xb7, 0xbd, 0xbd, 0xfd, 0xde, 0x13, 0x82, 0xcb, 0xe5, 0xa2, 0x82, 0x82, 0x02, 0x1a, 0x37, 0x6e, 0x1a, 0xa9, 0xd5, 0x69, 0xa4, 0x52, 0xe9, 0x29, 0x23, 0x63, 0x2a, 0xed, 0xdd, 0xbb, 0x97, 0x9c, 0x4e, 0x27, 0x75, 0x31, 0x62, 0x32, 0x99, 0x28, 0x2d, 0x2d, 0x83, 0x06, 0x0e, 0xfc, 0x07, 0xa5, 0xa5, 0x91, 0xdf, 0xdf, 0x95, 0xb9, 0x0c, 0x32, 0x99, 0x4c, 0x5e, 0x06, 0x9d, 0x4e, 0x27, 0xed, 0xdd, 0xbb, 0x97, 0x32, 0x32, 0xa6, 0x92, 0x4a, 0xa5, 0x27, 0xb5, 0x3a, 0x8d, 0xc6, 0x8d, 0x9b, 0x46, 0x05, 0x05, 0x05, 0xe4, 0x72, 0xb9, 0x7e, 0x13, 0x21, 0x08, 0x7e, 0x8b, 0x93, 0xdf, 0xb5, 0x6b, 0x17, 0x5e, 0x7e, 0xf9, 0x7d, 0x28, 0x95, 0xab, 0x10, 0x1d, 0x3d, 0x0a, 0x00, 0x0f, 0x8d, 0x8d, 0xe5, 0x58, 0xb0, 0xe0, 0x35, 0x58, 0xad, 0x56, 0x74, 0x31, 0x54, 0x53, 0x53, 0x83, 0xfa, 0x7a, 0x05, 0xc2, 0xc3, 0x87, 0xf7, 0xa0, 0x23, 0x91, 0x0c, 0x47, 0x7d, 0xbd, 0x02, 0x35, 0x35, 0x35, 0x18, 0x33, 0x66, 0x0c, 0x88, 0x88, 0xb6, 0x6f, 0xdf, 0x8e, 0xfc, 0xfc, 0x4f, 0xa1, 0x56, 0xbf, 0x8d, 0x98, 0x98, 0x74, 0x00, 0x04, 0x83, 0xe1, 0x5f, 0xc8, 0xcb, 0x5b, 0x81, 0x8d, 0x1b, 0x6d, 0x20, 0x22, 0xba, 0x55, 0xbf, 0xc1, 0xdc, 0x2a, 0xf3, 0xcd, 0xcd, 0xcd, 0x58, 0xbb, 0xf6, 0x53, 0xa8, 0xd5, 0x1b, 0x21, 0x93, 0x4d, 0x00, 0xc3, 0x48, 0xc0, 0x30, 0xc1, 0x90, 0x4a, 0x33, 0x10, 0x16, 0xf6, 0x01, 0xd6, 0xae, 0xdd, 0x8a, 0xa6, 0xa6, 0x26, 0x00, 0x80, 0xcd, 0x66, 0x03, 0xcb, 0x8a, 0xc0, 0xe3, 0x09, 0x7b, 0xd0, 0xe2, 0xf1, 0x84, 0x60, 0x59, 0x11, 0x6c, 0x36, 0x1b, 0x00, 0xa0, 0xa9, 0xa9, 0x09, 0x6b, 0xd7, 0x6e, 0x45, 0x58, 0xd8, 0x07, 0x90, 0x4a, 0x33, 0xc0, 0x30, 0xc1, 0x60, 0x18, 0x09, 0x64, 0xb2, 0x09, 0x50, 0xab, 0x37, 0x62, 0xed, 0xda, 0x4f, 0xd1, 0xdc, 0xdc, 0x8c, 0x5b, 0x35, 0x07, 0xe6, 0x56, 0x35, 0xe0, 0xcc, 0x99, 0x33, 0x30, 0x18, 0xe4, 0x90, 0x48, 0x86, 0xf6, 0x78, 0x26, 0x16, 0x0f, 0x82, 0xd1, 0xa8, 0x43, 0x75, 0x75, 0x35, 0x00, 0x20, 0x26, 0x26, 0x06, 0x21, 0x21, 0xcd, 0xe0, 0xb8, 0xd6, 0x1e, 0x6b, 0x39, 0xae, 0x15, 0x21, 0x21, 0xcd, 0x88, 0x89, 0x89, 0x01, 0x00, 0x54, 0x57, 0x57, 0xc3, 0x68, 0xd4, 0x41, 0x2c, 0x1e, 0x14, 0x40, 0x5b, 0x86, 0xc2, 0x60, 0x90, 0xe3, 0xcc, 0x99, 0x33, 0xb7, 0x6c, 0x02, 0xb7, 0x2c, 0x00, 0xa7, 0xd3, 0x09, 0x8e, 0x13, 0x00, 0xe0, 0x07, 0x78, 0xca, 0x07, 0xc7, 0x09, 0xe1, 0x74, 0x3a, 0x01, 0x00, 0x03, 0x06, 0x0c, 0xc0, 0xa4, 0x49, 0x09, 0x68, 0x6c, 0x7c, 0x1b, 0x44, 0x4e, 0x1f, 0x4d, 0x72, 0xa2, 0xb1, 0xf1, 0x6d, 0x4c, 0x9a, 0x94, 0x80, 0x01, 0x03, 0x06, 0xf8, 0xd0, 0x15, 0x5e, 0x83, 0xae, 0xc0, 0x4b, 0xf7, 0x8e, 0xf8, 0x80, 0xee, 0xaa, 0xd6, 0x65, 0x7b, 0xfd, 0xfa, 0xf5, 0x83, 0x5c, 0xde, 0x0c, 0x96, 0x35, 0x42, 0x28, 0x0c, 0xef, 0x71, 0xaa, 0x12, 0x49, 0xbd, 0x97, 0x29, 0x3e, 0x9f, 0x8f, 0x55, 0xab, 0xfe, 0x08, 0xb3, 0x79, 0x31, 0x0e, 0x1e, 0xbc, 0x1f, 0x52, 0xe9, 0x64, 0x00, 0x80, 0xd5, 0xfa, 0x1d, 0x26, 0x4d, 0x0a, 0xc3, 0xaa, 0x55, 0x9b, 0xc0, 0xe7, 0xf3, 0xbd, 0xc2, 0x92, 0x48, 0xea, 0xc1, 0x71, 0xad, 0x10, 0x08, 0x34, 0xdd, 0x42, 0xa9, 0x11, 0x72, 0x79, 0x33, 0xfa, 0xf5, 0xeb, 0x77, 0xdd, 0xfd, 0xdd, 0xb2, 0x00, 0xba, 0x08, 0x57, 0x55, 0x55, 0xe1, 0xd8, 0xb1, 0x63, 0x10, 0x0a, 0x85, 0xc8, 0xc8, 0xc8, 0xf0, 0xce, 0xc7, 0xc6, 0xc6, 0xe2, 0xe1, 0x87, 0x47, 0x62, 0xfb, 0xf6, 0xd7, 0x10, 0x15, 0xf5, 0x21, 0x18, 0x46, 0x02, 0x00, 0xf0, 0x78, 0x3a, 0x60, 0x30, 0xbc, 0x86, 0x47, 0x1f, 0x1d, 0x86, 0xb8, 0xb8, 0x38, 0x2f, 0xbd, 0xb0, 0xb0, 0x30, 0xec, 0xd8, 0xf1, 0x39, 0xca, 0xcb, 0xcb, 0x71, 0xf8, 0xf0, 0x61, 0x00, 0xc0, 0x84, 0x09, 0x2b, 0x91, 0x9e, 0x9e, 0x8e, 0xa0, 0xa0, 0x20, 0xef, 0xba, 0xb8, 0xb8, 0x38, 0x3c, 0xf8, 0xe0, 0x30, 0xec, 0xd9, 0xf3, 0x1a, 0x22, 0x23, 0xb7, 0x80, 0x61, 0xc4, 0x9d, 0x74, 0xed, 0x30, 0x18, 0x5e, 0xc3, 0xdc, 0xb9, 0x23, 0x11, 0x1b, 0x1b, 0xeb, 0xdd, 0xe3, 0xb9, 0x73, 0xe7, 0x50, 0x5a, 0x5a, 0x0a, 0xb7, 0xdb, 0xed, 0x75, 0xa2, 0x37, 0x22, 0x88, 0x5e, 0x99, 0x37, 0x9b, 0xcd, 0x34, 0x7b, 0xf6, 0x1c, 0x92, 0xcb, 0x53, 0x49, 0xa7, 0x5b, 0x42, 0x3a, 0xdd, 0x4b, 0xa4, 0x54, 0x26, 0xd3, 0xd2, 0xa5, 0x4b, 0xc9, 0x6a, 0xb5, 0x52, 0x57, 0x9c, 0x9e, 0x3f, 0x7f, 0x01, 0xc9, 0xe5, 0x43, 0x3b, 0xd7, 0xe4, 0x93, 0x5c, 0x3e, 0x8c, 0x9e, 0x7e, 0xfa, 0x19, 0x6a, 0x6b, 0x6b, 0xa3, 0x9b, 0x1d, 0x6d, 0x6d, 0x6d, 0xf4, 0xf4, 0xd3, 0xcf, 0x90, 0x5c, 0x3e, 0x8c, 0x74, 0xba, 0x7c, 0xd2, 0xe9, 0x96, 0x90, 0x5c, 0x3e, 0x94, 0xe6, 0xcf, 0x5f, 0xe0, 0xc5, 0x19, 0x56, 0xab, 0x95, 0x96, 0x2e, 0x5d, 0x4a, 0x4a, 0x65, 0x32, 0xe9, 0x74, 0x2f, 0x75, 0xae, 0x49, 0xa5, 0xd9, 0xb3, 0xe7, 0x90, 0xd9, 0x6c, 0xbe, 0x2e, 0x66, 0xb8, 0xa6, 0x74, 0x3c, 0x1e, 0x0f, 0xe5, 0xe5, 0xe5, 0x61, 0xff, 0x7e, 0x11, 0x22, 0x23, 0x37, 0x79, 0xbd, 0x37, 0xc7, 0x59, 0x70, 0xf1, 0xe2, 0xb3, 0x58, 0xb4, 0x68, 0x30, 0xde, 0x78, 0xe3, 0x0d, 0x74, 0x09, 0xf9, 0xf4, 0xe9, 0xd3, 0x38, 0x72, 0xe4, 0x08, 0x88, 0x08, 0x19, 0x19, 0x19, 0x18, 0x34, 0x68, 0xd0, 0x6f, 0x82, 0x33, 0x6a, 0x6a, 0x6a, 0x50, 0x5a, 0x5a, 0x0a, 0x1e, 0x8f, 0x87, 0xcc, 0xcc, 0x4c, 0x24, 0x26, 0x26, 0x76, 0x1d, 0x10, 0xde, 0x7a, 0xeb, 0x2d, 0x6c, 0xde, 0x5c, 0x8d, 0xe8, 0xe8, 0x6d, 0xe0, 0xf3, 0xe5, 0x9d, 0xf3, 0x6e, 0xd4, 0xd5, 0x2d, 0x46, 0x4e, 0x8e, 0x0b, 0x5b, 0xb7, 0x6e, 0x05, 0xc3, 0x30, 0xbc, 0x1b, 0x16, 0x00, 0x11, 0xd1, 0xa9, 0x53, 0xa7, 0x90, 0x95, 0xf5, 0x2c, 0x74, 0xba, 0x22, 0x2f, 0xf1, 0xab, 0xe0, 0xa7, 0x16, 0x6e, 0xf7, 0x53, 0x28, 0x2e, 0xfe, 0x02, 0x7d, 0xfb, 0xf6, 0xbd, 0x2b, 0x00, 0xac, 0xbe, 0xbe, 0x1e, 0xd9, 0xd9, 0x4f, 0x42, 0x28, 0xfc, 0x1c, 0x22, 0x51, 0x6c, 0x37, 0xff, 0x63, 0x41, 0x63, 0xe3, 0x54, 0x1c, 0x3e, 0xfc, 0x67, 0x24, 0x26, 0x26, 0xf6, 0x6a, 0x0a, 0xcc, 0xf5, 0x24, 0xcf, 0xb2, 0x09, 0xe0, 0xf3, 0xa5, 0x3d, 0x9e, 0x09, 0x85, 0x7d, 0x61, 0x34, 0x8a, 0x51, 0x57, 0x57, 0x77, 0xd7, 0x10, 0x68, 0x5d, 0x5d, 0x1d, 0x8c, 0x46, 0x31, 0x84, 0xc2, 0x9e, 0x07, 0xc0, 0xe7, 0x4b, 0xc1, 0xb2, 0x09, 0xde, 0x10, 0x7c, 0x53, 0x61, 0x50, 0x2c, 0x16, 0x83, 0xc7, 0x73, 0x82, 0xc8, 0x13, 0x40, 0x43, 0x58, 0x08, 0x04, 0x04, 0xa1, 0x50, 0x78, 0xd7, 0x04, 0x20, 0x14, 0x0a, 0x21, 0x10, 0x10, 0x88, 0xd8, 0x00, 0xfb, 0xf3, 0x80, 0xc7, 0x73, 0x42, 0x2c, 0x16, 0xdf, 0xbc, 0x00, 0xf4, 0x7a, 0x3d, 0x64, 0xb2, 0x9f, 0xe1, 0x72, 0x9d, 0xef, 0xf1, 0xcc, 0x6e, 0xaf, 0x40, 0xbf, 0x7e, 0x84, 0xfe, 0xfd, 0xfb, 0xdf, 0x35, 0x01, 0xf4, 0xef, 0xdf, 0x1f, 0xfd, 0xfa, 0x11, 0xec, 0xf6, 0x8a, 0x00, 0xf9, 0xc9, 0x79, 0xc8, 0x64, 0x3f, 0x43, 0xaf, 0xd7, 0xdf, 0x9c, 0x00, 0x78, 0x3c, 0x1e, 0x2f, 0x3c, 0x3c, 0x1c, 0x4b, 0x96, 0xcc, 0x83, 0xc1, 0xf0, 0x0c, 0x6c, 0xb6, 0x1f, 0x40, 0xe4, 0x84, 0xc7, 0x63, 0x83, 0xc5, 0x72, 0x08, 0x66, 0xf3, 0xab, 0xc8, 0xcf, 0x9f, 0x0f, 0x85, 0x42, 0x71, 0xd7, 0x04, 0xa0, 0x50, 0x28, 0x90, 0x9f, 0x3f, 0x1f, 0x66, 0xf3, 0xab, 0xb0, 0x58, 0x0e, 0xc1, 0xe3, 0xb1, 0x81, 0xc8, 0x09, 0x9b, 0xed, 0x07, 0x18, 0x0c, 0xcf, 0x60, 0xc9, 0x92, 0x79, 0x08, 0x0f, 0x0f, 0xbf, 0xb5, 0x50, 0xe8, 0x74, 0x3a, 0x69, 0xc7, 0x8e, 0x1d, 0x34, 0x6a, 0xd4, 0x44, 0x52, 0x2a, 0xd3, 0x49, 0xa3, 0x19, 0x41, 0xe3, 0xc7, 0x3f, 0x40, 0x85, 0x85, 0x85, 0xc4, 0xb2, 0x2c, 0xdd, 0xed, 0xc1, 0xb2, 0x2c, 0x15, 0x16, 0x16, 0xd2, 0xf8, 0xf1, 0x0f, 0x90, 0x46, 0x33, 0x82, 0x94, 0xca, 0x74, 0x1a, 0x35, 0x6a, 0x22, 0xed, 0xd8, 0xb1, 0xc3, 0x9b, 0x89, 0xfe, 0xea, 0x30, 0x78, 0xad, 0x98, 0xd9, 0xd6, 0xd6, 0x86, 0x96, 0x96, 0x16, 0xf0, 0x78, 0x3c, 0x68, 0xb5, 0x5a, 0x48, 0xa5, 0xd2, 0x7b, 0x2a, 0x25, 0xb7, 0x5a, 0xad, 0x30, 0x1a, 0x8d, 0x20, 0x22, 0xa8, 0xd5, 0x6a, 0x84, 0x86, 0x86, 0xe2, 0x5a, 0xda, 0xdd, 0x43, 0x00, 0x44, 0x44, 0x46, 0xa3, 0x11, 0x1f, 0x7f, 0xfc, 0x31, 0xf6, 0xed, 0xdb, 0x07, 0x8b, 0xc5, 0x82, 0xf4, 0xf4, 0x74, 0x2c, 0x5c, 0xb8, 0x10, 0xf7, 0xdd, 0x77, 0x1f, 0xee, 0x54, 0xb5, 0xca, 0xed, 0xe6, 0x50, 0x50, 0x50, 0x80, 0xa6, 0xa6, 0xcb, 0x01, 0xcf, 0x8b, 0xc7, 0x13, 0x40, 0x20, 0x90, 0x20, 0x34, 0xb4, 0x0f, 0x92, 0x93, 0x13, 0x91, 0x94, 0x14, 0x89, 0x40, 0x5b, 0x23, 0x22, 0x94, 0x95, 0x95, 0xe1, 0x83, 0x0f, 0x3e, 0x40, 0x79, 0x79, 0x39, 0xe4, 0x72, 0x39, 0x72, 0x73, 0x73, 0xb1, 0x60, 0xc1, 0x02, 0x68, 0xb5, 0x5a, 0xaf, 0x10, 0x78, 0x5d, 0xcc, 0xd7, 0xd7, 0xd7, 0xe3, 0xa1, 0x87, 0x66, 0xa2, 0xae, 0xee, 0x3e, 0xa8, 0xd5, 0x79, 0xe0, 0xf3, 0x43, 0x61, 0xb5, 0x1e, 0x45, 0x6b, 0xeb, 0x5b, 0xd8, 0xbc, 0xf9, 0x55, 0xcc, 0x9a, 0x35, 0xeb, 0x8e, 0x08, 0xe0, 0xe7, 0x9f, 0xeb, 0x91, 0x95, 0x35, 0x07, 0x6e, 0xf7, 0xf0, 0x6b, 0x28, 0x2d, 0x0f, 0x0c, 0x23, 0x00, 0xc3, 0x18, 0xa1, 0xd5, 0x9e, 0xc5, 0xeb, 0xaf, 0xaf, 0x40, 0x6e, 0xee, 0x78, 0xf8, 0xe2, 0x9d, 0x9d, 0x3b, 0x77, 0x62, 0xd1, 0xa2, 0x77, 0xa1, 0x54, 0xbe, 0x01, 0xa9, 0x74, 0x2c, 0x38, 0xae, 0x0d, 0x2d, 0x2d, 0x5b, 0x11, 0x19, 0x59, 0x86, 0x82, 0x82, 0xbf, 0xa2, 0x6f, 0xdf, 0xbe, 0xe0, 0x75, 0x49, 0xc1, 0xed, 0x76, 0xd3, 0xe2, 0xc5, 0x7f, 0x40, 0x41, 0x81, 0x16, 0xe1, 0xe1, 0xaf, 0xfb, 0x59, 0x86, 0xd3, 0x79, 0x16, 0x8d, 0x8d, 0x39, 0xa8, 0xae, 0x3e, 0x0a, 0xad, 0x56, 0x7b, 0xdb, 0x05, 0x50, 0x5c, 0x7c, 0x14, 0x33, 0x67, 0xbe, 0x87, 0xb8, 0xb8, 0xc2, 0x5f, 0x03, 0xd6, 0xd1, 0xd1, 0xf1, 0x33, 0x9a, 0x9a, 0xde, 0xc5, 0xf2, 0xe5, 0xbf, 0xc3, 0xe2, 0xc5, 0x73, 0xc1, 0xe3, 0xf1, 0x60, 0x34, 0x1a, 0x31, 0x78, 0xf0, 0x58, 0xe8, 0x74, 0xfb, 0x11, 0x14, 0x94, 0xe0, 0xb7, 0xbe, 0xa1, 0xe1, 0x8f, 0x78, 0xe8, 0x21, 0x23, 0x36, 0x6d, 0xda, 0x00, 0xa1, 0x50, 0xc8, 0x63, 0xba, 0xec, 0xa7, 0xa8, 0xe8, 0x5f, 0xd0, 0x68, 0xf2, 0x7a, 0x80, 0xc3, 0x2b, 0x04, 0xb2, 0xf1, 0xed, 0xb7, 0xdf, 0xde, 0x11, 0x0d, 0x38, 0x70, 0xe0, 0x9f, 0x08, 0x0b, 0xfb, 0x83, 0x0f, 0x1c, 0xef, 0x80, 0xc1, 0xb0, 0x02, 0x75, 0x75, 0x4b, 0xd1, 0xd6, 0xf6, 0x0d, 0x58, 0xb6, 0x05, 0x1c, 0x67, 0xf6, 0x6a, 0x83, 0x58, 0x9c, 0x80, 0xe8, 0xe8, 0x3f, 0x63, 0xf5, 0xea, 0x9d, 0x38, 0x7d, 0xfa, 0x02, 0x00, 0x74, 0xee, 0x35, 0xbb, 0x1b, 0xf3, 0x57, 0xd6, 0x6b, 0x34, 0x79, 0x28, 0x2a, 0xfa, 0x17, 0xac, 0x56, 0xeb, 0xd5, 0x30, 0xe8, 0x76, 0xbb, 0xd1, 0xdc, 0x6c, 0x81, 0x40, 0xa0, 0xee, 0x05, 0x70, 0xf4, 0x85, 0xc1, 0x60, 0xb8, 0xee, 0xe6, 0x59, 0xd6, 0x83, 0xc6, 0xc6, 0x56, 0x5c, 0xbc, 0x58, 0x87, 0x8b, 0x17, 0x2f, 0xa1, 0xbe, 0xbe, 0x11, 0x56, 0x6b, 0xc7, 0x0d, 0xd4, 0x16, 0x39, 0x54, 0x55, 0xfd, 0xe8, 0xcd, 0xfc, 0x00, 0xc0, 0x68, 0xdc, 0x82, 0x79, 0xf3, 0x82, 0xb0, 0x72, 0x65, 0x02, 0x5e, 0x7c, 0xb1, 0x16, 0xc3, 0x86, 0xad, 0x81, 0xd1, 0x98, 0x85, 0xf6, 0xf6, 0x12, 0xbf, 0xdf, 0x4a, 0xa5, 0xb3, 0xb1, 0x77, 0xef, 0x01, 0x00, 0x80, 0xc1, 0x60, 0x08, 0x88, 0x0e, 0x01, 0x40, 0x20, 0x50, 0xa3, 0xb9, 0xd9, 0x02, 0xb7, 0xdb, 0x7d, 0x35, 0x1d, 0x0e, 0x0a, 0x0a, 0x42, 0x74, 0xb4, 0x16, 0x4e, 0x67, 0x2d, 0xc4, 0xe2, 0x84, 0x00, 0x6a, 0x56, 0x8d, 0xc4, 0xc4, 0x19, 0xd7, 0x64, 0xbc, 0xac, 0xec, 0x04, 0x3e, 0xfa, 0xe8, 0x13, 0x1c, 0x3b, 0x76, 0x19, 0x2d, 0x2d, 0x97, 0xe0, 0xf1, 0xb0, 0x90, 0x48, 0xd4, 0x48, 0x4c, 0xd4, 0xe2, 0xd1, 0x47, 0x73, 0xd0, 0xd2, 0x52, 0x87, 0x73, 0xe7, 0xaa, 0xfc, 0x7e, 0xb7, 0x7c, 0xf9, 0x1a, 0x0c, 0x1a, 0x14, 0xed, 0xfd, 0xdf, 0x60, 0x30, 0xe2, 0xdc, 0x39, 0x31, 0x14, 0x8a, 0xfb, 0x7c, 0x00, 0xd7, 0xdf, 0x90, 0x9f, 0x7f, 0x00, 0x4a, 0xe5, 0x55, 0xaf, 0x5e, 0x59, 0xf9, 0x33, 0x1e, 0x79, 0xe4, 0x3f, 0x00, 0x8c, 0xf3, 0xa3, 0x67, 0x34, 0x9e, 0x03, 0x00, 0x24, 0x26, 0x26, 0xa2, 0xa3, 0x63, 0x2f, 0x00, 0xea, 0xa1, 0xd1, 0x4e, 0x67, 0x2d, 0xa2, 0xa3, 0xb5, 0xde, 0xd4, 0x5b, 0x70, 0x45, 0x7a, 0x52, 0x3c, 0xfe, 0xf8, 0xfd, 0xd8, 0xb4, 0xe9, 0x3d, 0x44, 0x46, 0x6e, 0x04, 0xc3, 0x48, 0xbd, 0xcc, 0xb7, 0xb5, 0x15, 0x41, 0xa7, 0x3b, 0x83, 0xec, 0xec, 0xec, 0x80, 0xcc, 0xdb, 0xed, 0x4e, 0xbc, 0xfb, 0xee, 0x47, 0xf8, 0xfc, 0xf3, 0x7f, 0x43, 0x28, 0x9c, 0x02, 0x8d, 0x66, 0x1a, 0xb4, 0xda, 0xab, 0xf0, 0xd8, 0x64, 0xfa, 0x11, 0x9b, 0x37, 0xd7, 0x03, 0x18, 0x0c, 0xa2, 0x44, 0x1f, 0x66, 0x17, 0x63, 0xf3, 0x66, 0x7f, 0x10, 0x75, 0xe1, 0xc2, 0x45, 0xb4, 0xb6, 0x3a, 0xd1, 0x85, 0xad, 0x58, 0xb6, 0x05, 0x69, 0x69, 0x29, 0x90, 0x48, 0x24, 0x7e, 0xeb, 0x86, 0x0c, 0xe9, 0x0f, 0xbd, 0x3e, 0x19, 0xb5, 0xb5, 0x3d, 0xe1, 0x2f, 0x00, 0x64, 0x67, 0x67, 0x43, 0xa7, 0x5b, 0x8d, 0xb6, 0xb6, 0x22, 0x84, 0x86, 0x4e, 0xf5, 0x0a, 0xc1, 0xe3, 0xb1, 0xa2, 0xa9, 0xe9, 0x3d, 0x2c, 0x5e, 0x7c, 0xbf, 0x37, 0x8c, 0x0b, 0x00, 0x80, 0x61, 0x18, 0x2c, 0x58, 0x30, 0x1f, 0x35, 0x35, 0x7f, 0xc0, 0xc1, 0x83, 0xb3, 0x21, 0x93, 0xcd, 0xec, 0x8c, 0x02, 0xc7, 0x10, 0x1a, 0x7a, 0x18, 0x1f, 0x7d, 0xb4, 0x0e, 0x32, 0x99, 0x2c, 0x00, 0x48, 0x72, 0xe3, 0xf5, 0xd7, 0xd7, 0xe2, 0x8b, 0x2f, 0xce, 0x23, 0x22, 0x62, 0xb3, 0xb7, 0x18, 0x72, 0x45, 0x3d, 0xc9, 0xcf, 0x84, 0x24, 0x92, 0x34, 0xbf, 0xdf, 0x86, 0x86, 0xee, 0x46, 0x48, 0x48, 0xb0, 0xdf, 0xdc, 0xa1, 0x43, 0x65, 0x50, 0xa9, 0xae, 0x46, 0x1b, 0x8b, 0xe5, 0x00, 0x26, 0x4f, 0xee, 0x87, 0xa0, 0x20, 0x61, 0xb7, 0x98, 0xdf, 0x01, 0x83, 0xc1, 0x14, 0x00, 0x19, 0x5e, 0xa9, 0x27, 0xca, 0x64, 0x32, 0x7c, 0xf4, 0xd1, 0x3a, 0xcc, 0x9f, 0xff, 0x2a, 0xea, 0xeb, 0x8f, 0x42, 0x2a, 0x1d, 0x03, 0x8e, 0x6b, 0x43, 0x7b, 0xfb, 0x5f, 0x31, 0x69, 0x92, 0x0c, 0x0b, 0x16, 0xcc, 0x07, 0xc3, 0x30, 0x57, 0x05, 0xc0, 0xe3, 0xf1, 0x78, 0x44, 0x44, 0x9f, 0x7c, 0xf2, 0x21, 0x8a, 0x8b, 0x8b, 0xf1, 0xed, 0xb7, 0xdf, 0xa2, 0xad, 0xad, 0x0d, 0xe9, 0xe9, 0xe9, 0x98, 0x31, 0x63, 0xb7, 0xb7, 0x50, 0xd9, 0x7d, 0x7c, 0xf9, 0xe5, 0x7e, 0xec, 0xde, 0x5d, 0x87, 0x88, 0x88, 0x4d, 0x5e, 0xe6, 0x1b, 0x1b, 0xdf, 0x46, 0x4a, 0x4a, 0x35, 0x72, 0x73, 0x73, 0x11, 0x1b, 0xab, 0x41, 0x79, 0xf9, 0x59, 0x6c, 0xdf, 0xbe, 0x13, 0x36, 0xdb, 0x7a, 0x84, 0x84, 0xa4, 0x77, 0x82, 0xaa, 0xfd, 0x98, 0x3a, 0x35, 0x01, 0x22, 0x91, 0xd0, 0xcf, 0xfe, 0x4f, 0x9e, 0x3c, 0x09, 0x81, 0x60, 0xb4, 0x8f, 0x80, 0xcf, 0x21, 0x33, 0x33, 0xbb, 0x5b, 0x8d, 0x82, 0xb0, 0x7f, 0x7f, 0x31, 0xce, 0x9d, 0xb3, 0x20, 0xfa, 0xaa, 0xf5, 0xa0, 0xb5, 0xf5, 0x4b, 0x64, 0x65, 0xad, 0xf1, 0xfe, 0x9f, 0x91, 0x91, 0x81, 0x03, 0x07, 0x76, 0x63, 0xef, 0xde, 0xbd, 0x28, 0x2f, 0xff, 0x0b, 0x42, 0x43, 0x43, 0x71, 0xff, 0xfd, 0x73, 0x91, 0x9d, 0x9d, 0x0d, 0xa9, 0x54, 0x1a, 0x18, 0x1e, 0xdf, 0x08, 0x04, 0xad, 0xaf, 0x37, 0x52, 0x52, 0xd2, 0x24, 0x1a, 0x3c, 0xf8, 0x94, 0xb7, 0xb9, 0x11, 0x19, 0xb9, 0x86, 0x36, 0x6c, 0xd8, 0x4e, 0x1d, 0x1d, 0x2e, 0x1f, 0xa8, 0xca, 0x51, 0x6e, 0xee, 0xe3, 0x14, 0x1f, 0x7f, 0xd0, 0xbb, 0x2e, 0x26, 0x66, 0x1b, 0x7d, 0xf6, 0xd9, 0xff, 0xfa, 0xd1, 0x33, 0x18, 0x9a, 0xa9, 0x5f, 0xbf, 0x99, 0x7e, 0xcd, 0x12, 0xad, 0x36, 0x9b, 0xea, 0xea, 0x1a, 0xc9, 0xe3, 0xf1, 0x50, 0x4b, 0x8b, 0x8d, 0x8e, 0x1e, 0xad, 0xa2, 0x65, 0xcb, 0xd6, 0x50, 0x54, 0xd4, 0x1c, 0x1a, 0x36, 0xcc, 0xec, 0x5d, 0x17, 0x1f, 0x7f, 0x90, 0x32, 0x32, 0x66, 0x90, 0xd5, 0xea, 0xf8, 0x55, 0x7b, 0xff, 0x4d, 0x1a, 0x23, 0x5f, 0x7d, 0x75, 0x10, 0x2d, 0x2d, 0x89, 0x88, 0x8a, 0xba, 0x62, 0xd7, 0x66, 0xf3, 0xdf, 0x30, 0x7e, 0x7c, 0x33, 0x16, 0x2e, 0x5c, 0x06, 0xa1, 0xf0, 0x6a, 0x25, 0xb7, 0xa9, 0xc9, 0x8c, 0xb3, 0x67, 0xf9, 0x90, 0x4a, 0xc7, 0xfa, 0x9c, 0xd6, 0x76, 0x4c, 0x98, 0xb0, 0xbb, 0x9b, 0xfd, 0xd7, 0xa3, 0xbd, 0x5d, 0x0a, 0x95, 0xca, 0x77, 0xb6, 0x2f, 0xc6, 0x8c, 0x19, 0x09, 0x3e, 0x9f, 0x81, 0x4c, 0x36, 0x0b, 0x66, 0xb3, 0x03, 0x7c, 0xfe, 0x08, 0xa8, 0xd5, 0x2f, 0x82, 0xcf, 0x97, 0x75, 0x6a, 0x4e, 0x1d, 0x5c, 0xae, 0x2d, 0xf8, 0xd3, 0x9f, 0xd6, 0x20, 0x24, 0x44, 0x7c, 0xf3, 0x55, 0x61, 0x22, 0xa2, 0xc6, 0xc6, 0x46, 0x1c, 0x39, 0x72, 0x04, 0x66, 0xb3, 0x19, 0x29, 0x29, 0x29, 0x18, 0x3e, 0x7c, 0x38, 0x04, 0x02, 0x41, 0x80, 0x70, 0xc5, 0xa2, 0xb8, 0xf8, 0x18, 0xb4, 0xda, 0x17, 0x7d, 0x3c, 0xf0, 0x06, 0xe4, 0xe7, 0x7f, 0xe6, 0xc7, 0xfc, 0x95, 0xf9, 0x26, 0xd4, 0xd7, 0x5f, 0x42, 0x7c, 0xfc, 0x55, 0x7b, 0x8f, 0x8a, 0x8a, 0x84, 0x52, 0xe9, 0xef, 0x00, 0x0f, 0x1e, 0xfc, 0x27, 0x64, 0xb2, 0x49, 0x7e, 0x73, 0x91, 0x91, 0x1f, 0x83, 0xe3, 0xda, 0x3a, 0xc3, 0x57, 0x18, 0x34, 0x1a, 0x7f, 0xad, 0x35, 0x9b, 0xf7, 0x81, 0x61, 0xbe, 0xc0, 0xd6, 0xad, 0xcb, 0x91, 0x9e, 0x3e, 0xb8, 0x97, 0x08, 0xc5, 0xa2, 0xa2, 0xa2, 0x02, 0x3f, 0xfd, 0xf4, 0x13, 0x14, 0x0a, 0x05, 0x32, 0x33, 0x33, 0xfd, 0x3a, 0x4a, 0x82, 0x2e, 0x24, 0xf8, 0xe9, 0xa7, 0x9f, 0xe2, 0xcd, 0x37, 0xd7, 0x83, 0x65, 0x47, 0x83, 0x61, 0x14, 0x70, 0xb9, 0x76, 0x61, 0xf8, 0xf0, 0x20, 0x6c, 0xdb, 0xb6, 0x15, 0xd1, 0xbe, 0xc6, 0x06, 0xc0, 0x68, 0x34, 0xa3, 0xaa, 0xca, 0x0c, 0xa5, 0x32, 0xc9, 0x27, 0x37, 0x8f, 0x43, 0x4c, 0x4c, 0x44, 0x8f, 0x0d, 0x1c, 0x3e, 0x7c, 0x1c, 0x1a, 0xcd, 0x42, 0x9f, 0xd3, 0xdf, 0x8b, 0xdf, 0xfd, 0x4e, 0x09, 0xa9, 0x34, 0xd8, 0x67, 0x93, 0x1c, 0xaa, 0xaa, 0xaa, 0x11, 0x1c, 0x9c, 0xe7, 0x9f, 0xab, 0x33, 0x62, 0x3f, 0x4c, 0x70, 0xa5, 0xd4, 0xd5, 0x0e, 0xa3, 0x71, 0x0b, 0xec, 0xf6, 0xbf, 0x23, 0x37, 0x77, 0x38, 0xde, 0x7c, 0x73, 0x0b, 0xa2, 0xa3, 0x75, 0x01, 0xf3, 0x81, 0x8b, 0x17, 0x2f, 0xe2, 0xd9, 0x67, 0xf3, 0x50, 0x51, 0xe1, 0x84, 0x48, 0xa4, 0x87, 0xc7, 0x63, 0x86, 0x40, 0xf0, 0x06, 0xde, 0x7c, 0x73, 0x09, 0xdc, 0x6e, 0x37, 0x09, 0x85, 0x42, 0x9e, 0x80, 0x88, 0xa8, 0xb0, 0xb0, 0x10, 0xf9, 0xf9, 0x9f, 0x22, 0x36, 0xf6, 0x3b, 0x88, 0x44, 0x5d, 0x0e, 0xcf, 0x83, 0xd3, 0xa7, 0x37, 0x62, 0xf6, 0xec, 0xa7, 0x51, 0x54, 0x54, 0xe8, 0x17, 0x8a, 0x1c, 0x0e, 0x1b, 0x5a, 0x5a, 0x0c, 0x50, 0x2a, 0xaf, 0xbe, 0x2c, 0x21, 0x21, 0x0a, 0x12, 0x89, 0xb8, 0x47, 0x42, 0x52, 0x59, 0xf9, 0x4f, 0x30, 0xcc, 0x14, 0x1f, 0x27, 0xe6, 0xc0, 0xd0, 0xa1, 0x63, 0xfc, 0x70, 0xbb, 0xc5, 0x62, 0x43, 0x59, 0xd9, 0x2f, 0xd0, 0xe9, 0x52, 0x7c, 0xea, 0x7d, 0x4b, 0xd1, 0xde, 0xfe, 0x89, 0x37, 0x01, 0x12, 0x0a, 0xe5, 0x50, 0xab, 0x23, 0x91, 0x9a, 0x9a, 0x8c, 0xe7, 0x9e, 0xcb, 0x44, 0x6e, 0xee, 0x5e, 0x44, 0x44, 0x28, 0x7b, 0x55, 0x6d, 0xbb, 0xdd, 0x8e, 0xd9, 0xb3, 0x9f, 0xc6, 0xf9, 0xf3, 0xf7, 0xa3, 0x7f, 0xff, 0x97, 0xbd, 0xa5, 0x0f, 0x97, 0xeb, 0x02, 0xf2, 0xf3, 0x1f, 0x41, 0x9f, 0x3e, 0x7d, 0x40, 0x44, 0x24, 0x70, 0xbb, 0xdd, 0xd8, 0xb0, 0xe1, 0x43, 0x84, 0x87, 0xaf, 0xf3, 0x61, 0xfe, 0x0a, 0x48, 0x0c, 0x0b, 0x7b, 0x19, 0x27, 0x4e, 0x94, 0xa0, 0xb4, 0xb4, 0x14, 0x53, 0xa6, 0xf8, 0x32, 0xe1, 0x02, 0xcb, 0xda, 0xfc, 0x5e, 0x18, 0x1c, 0x2c, 0x04, 0x9f, 0xcf, 0x74, 0x53, 0x51, 0x1b, 0x4e, 0x9e, 0xec, 0x40, 0x68, 0xe8, 0x03, 0xde, 0xb9, 0xe6, 0xe6, 0x2d, 0x98, 0x38, 0x71, 0x67, 0x37, 0xfb, 0x6f, 0x80, 0xd3, 0x79, 0xb5, 0xc9, 0xd1, 0xd1, 0x71, 0x06, 0x49, 0x49, 0x46, 0xec, 0xdf, 0xdf, 0x82, 0x90, 0x90, 0xa0, 0x9b, 0xf2, 0x51, 0xa5, 0xa5, 0xa5, 0x38, 0x71, 0x42, 0x82, 0x01, 0x03, 0x5e, 0xf6, 0xab, 0xfb, 0x88, 0x44, 0x31, 0x08, 0x0f, 0x5f, 0x87, 0x0d, 0x1b, 0xde, 0xc6, 0xd4, 0xa9, 0x53, 0xc1, 0xb8, 0xdd, 0x6e, 0x54, 0x56, 0x9e, 0xf6, 0x86, 0xa8, 0xee, 0x05, 0x23, 0x99, 0x2c, 0x13, 0x65, 0x65, 0x65, 0xdd, 0xf2, 0x69, 0xa6, 0x47, 0x31, 0xe9, 0xf8, 0xf1, 0x33, 0x68, 0x69, 0xb1, 0xf8, 0x9d, 0x7e, 0x6d, 0xed, 0x25, 0xd4, 0xd6, 0xd6, 0xfb, 0xad, 0xeb, 0xdb, 0x77, 0x20, 0xb4, 0xda, 0xb0, 0x6e, 0xf6, 0x7f, 0x14, 0x12, 0x89, 0xde, 0xc7, 0xc7, 0x5c, 0xc4, 0xc0, 0x81, 0x31, 0x37, 0xcd, 0x3c, 0x00, 0x94, 0x95, 0x95, 0x41, 0x26, 0xcb, 0x0c, 0x58, 0xf4, 0x0a, 0x09, 0x49, 0x47, 0x65, 0xe5, 0x69, 0xb8, 0xdd, 0x6e, 0x08, 0x78, 0x3c, 0x1e, 0xc4, 0xe2, 0x20, 0x78, 0x3c, 0x1d, 0xde, 0x58, 0xee, 0x1f, 0x77, 0x1d, 0x3d, 0x90, 0x98, 0x50, 0x18, 0x0c, 0x99, 0xcc, 0x9f, 0x09, 0x93, 0x29, 0x05, 0x2f, 0xbe, 0xf8, 0x9f, 0x98, 0x37, 0xef, 0xf7, 0x10, 0x8b, 0x85, 0xd8, 0xbf, 0xbf, 0x04, 0xfb, 0xf6, 0x7d, 0x8f, 0xc8, 0xc8, 0x8f, 0x7d, 0xd4, 0xf2, 0x38, 0x92, 0x93, 0x43, 0xa1, 0x56, 0xcb, 0x7d, 0x6c, 0xda, 0x83, 0xe3, 0xc7, 0x4f, 0x42, 0x26, 0x5b, 0xe4, 0x53, 0x7c, 0x29, 0x44, 0x76, 0xf6, 0x03, 0xb7, 0x94, 0x54, 0x49, 0x24, 0x12, 0x78, 0x3c, 0x8e, 0x5e, 0xfa, 0x1d, 0x1d, 0x10, 0x8b, 0x83, 0xc0, 0xe3, 0xf1, 0xc0, 0x08, 0x85, 0x42, 0x64, 0x65, 0x8d, 0x82, 0xd9, 0x5c, 0x10, 0xa0, 0x63, 0x6b, 0x86, 0xc3, 0x51, 0x84, 0x89, 0x13, 0x27, 0xfa, 0xcd, 0xeb, 0x74, 0x1a, 0xa4, 0xa6, 0xea, 0x60, 0xb7, 0xff, 0xe8, 0x9d, 0xeb, 0xd3, 0xe7, 0x55, 0x54, 0x56, 0x3e, 0x84, 0x97, 0x5e, 0xb2, 0x20, 0x2f, 0xaf, 0x05, 0x85, 0x85, 0xc9, 0x90, 0x48, 0x36, 0xf9, 0x99, 0x95, 0xdb, 0x6d, 0xc0, 0xe0, 0xc1, 0x83, 0x20, 0x10, 0x30, 0x3e, 0xa7, 0xed, 0xc6, 0xd1, 0xa3, 0x95, 0x08, 0x0a, 0xea, 0xef, 0xa3, 0xa6, 0xad, 0x48, 0x4a, 0x4a, 0xb8, 0x25, 0x01, 0x4c, 0x9c, 0x38, 0x11, 0x0e, 0x47, 0x91, 0x4f, 0xe6, 0xe8, 0x6b, 0x9a, 0x05, 0xc8, 0xca, 0x1a, 0x05, 0x91, 0x48, 0x04, 0x46, 0x20, 0x10, 0x60, 0xd9, 0xb2, 0x25, 0x20, 0x7a, 0x1f, 0x26, 0xd3, 0x97, 0xe0, 0xb8, 0x36, 0x10, 0xb9, 0xd1, 0xd1, 0x71, 0x16, 0x97, 0x2e, 0x2d, 0xc4, 0x13, 0x4f, 0xa4, 0x21, 0x39, 0x39, 0xb9, 0x9b, 0xbd, 0x8b, 0xb0, 0x6c, 0xd9, 0x7c, 0xb8, 0xdd, 0x9f, 0xc1, 0x6e, 0xaf, 0xf4, 0xce, 0xcb, 0xe5, 0xd9, 0x08, 0x0d, 0x7d, 0x00, 0x3c, 0x9e, 0x10, 0xed, 0xed, 0xff, 0x0d, 0xbb, 0xfd, 0xef, 0xdd, 0x5e, 0xbc, 0x17, 0x13, 0x27, 0x8e, 0xf2, 0x9b, 0x3b, 0x77, 0xce, 0x00, 0x8b, 0x85, 0xf5, 0x71, 0xb0, 0xd5, 0x88, 0x8a, 0xb2, 0x22, 0x3a, 0x3a, 0xfc, 0x96, 0x04, 0x90, 0x9c, 0x9c, 0x8c, 0x27, 0x9e, 0x48, 0xc3, 0xa5, 0x4b, 0x0b, 0xd1, 0xd1, 0x71, 0x16, 0x44, 0x6e, 0x70, 0x5c, 0x1b, 0x4c, 0xa6, 0x2f, 0x41, 0xf4, 0x3e, 0x96, 0x2d, 0x5b, 0xe2, 0x6d, 0xc4, 0x82, 0xe3, 0x38, 0x2a, 0x2b, 0x2b, 0xa3, 0x9c, 0x9c, 0x19, 0x14, 0x11, 0x31, 0x86, 0x14, 0x8a, 0x91, 0x34, 0x64, 0xc8, 0x38, 0x5a, 0xbd, 0x7a, 0x4d, 0xaf, 0xbd, 0x3d, 0x8e, 0xf3, 0x50, 0x49, 0x49, 0x05, 0x4d, 0x9b, 0xf6, 0x1c, 0x85, 0x87, 0x3f, 0x4c, 0x52, 0xe9, 0x18, 0x92, 0xc9, 0xc6, 0x52, 0x54, 0xd4, 0xef, 0x69, 0xc6, 0x8c, 0x67, 0x69, 0xcf, 0x9e, 0x83, 0x24, 0x95, 0xa6, 0x78, 0xd1, 0xda, 0xd0, 0xa1, 0x46, 0x4a, 0x4e, 0x7e, 0x8c, 0x2e, 0x5f, 0x36, 0xf9, 0xd1, 0xd9, 0xb8, 0x71, 0x07, 0x89, 0x44, 0xd1, 0x14, 0x12, 0x92, 0x4e, 0x21, 0x21, 0xe9, 0x24, 0x16, 0x27, 0xd1, 0x53, 0x4f, 0xe5, 0xff, 0x26, 0x05, 0xd3, 0xb6, 0xb6, 0x36, 0x5a, 0xbd, 0x7a, 0x0d, 0x0d, 0x19, 0x32, 0x8e, 0x14, 0x8a, 0x91, 0x14, 0x11, 0x31, 0x86, 0x72, 0x72, 0x66, 0x50, 0x59, 0x59, 0x19, 0x71, 0x1c, 0x47, 0x3d, 0x6a, 0x82, 0x76, 0xbb, 0x1d, 0x8d, 0x8d, 0x8d, 0x70, 0xb9, 0x5c, 0x50, 0xa9, 0x54, 0xd0, 0x68, 0x34, 0xd7, 0xad, 0x05, 0x3a, 0x1c, 0x2e, 0x34, 0x34, 0x18, 0xe1, 0x74, 0x5a, 0x01, 0xf0, 0x10, 0x1c, 0x2c, 0x43, 0x44, 0x84, 0x16, 0xcb, 0x97, 0xaf, 0xc3, 0x97, 0x5f, 0xb2, 0x08, 0x0f, 0xff, 0xcf, 0x4e, 0x44, 0xf8, 0x3e, 0x66, 0xce, 0x6c, 0xc3, 0xda, 0xb5, 0xcb, 0xfd, 0x68, 0x1a, 0x8d, 0xcd, 0x30, 0x1a, 0x9b, 0xfc, 0x68, 0x6a, 0x34, 0x7d, 0x10, 0x16, 0xa6, 0xfa, 0x4d, 0x0a, 0x2c, 0x44, 0x84, 0xe6, 0xe6, 0x66, 0x98, 0x4c, 0x26, 0x88, 0x44, 0x22, 0xe8, 0x74, 0x3a, 0x48, 0x24, 0x12, 0xff, 0x9a, 0xe0, 0xaf, 0xad, 0x0c, 0x77, 0x8d, 0xb7, 0xde, 0xda, 0x82, 0x7d, 0xfb, 0xbe, 0xc6, 0x8c, 0x19, 0xd3, 0x91, 0x9e, 0x3e, 0x06, 0x29, 0x29, 0x03, 0xa0, 0x50, 0x48, 0xd0, 0xdc, 0x6c, 0x45, 0x55, 0xd5, 0x2f, 0xf8, 0xea, 0xab, 0xff, 0xc1, 0x57, 0x5f, 0x55, 0x21, 0x3a, 0x7a, 0x37, 0x18, 0x46, 0x0a, 0x96, 0x35, 0xc2, 0x66, 0xcb, 0xc3, 0x37, 0xdf, 0x6c, 0x41, 0x42, 0x42, 0xd4, 0x5d, 0xaf, 0x20, 0x07, 0xac, 0x0a, 0xfb, 0x0a, 0xe0, 0xe2, 0xc5, 0x8b, 0xd8, 0xb4, 0x69, 0x13, 0xbe, 0xf9, 0xe6, 0x1b, 0x38, 0x1c, 0x0e, 0x8c, 0x19, 0x33, 0x06, 0x4b, 0x97, 0x2e, 0x45, 0x5a, 0x5a, 0x1a, 0x58, 0x96, 0xc3, 0xe3, 0x8f, 0x2f, 0xc2, 0xc9, 0x93, 0x4f, 0xc0, 0xe1, 0xf8, 0x09, 0x44, 0x06, 0x04, 0x07, 0x07, 0x81, 0xcf, 0x67, 0xc0, 0xb2, 0x1c, 0x3a, 0x3a, 0x5c, 0x10, 0x89, 0xd2, 0x21, 0x97, 0x4f, 0x04, 0xc3, 0x04, 0x83, 0x65, 0x5b, 0x50, 0x57, 0xf7, 0x28, 0xd6, 0xad, 0x5b, 0x84, 0x39, 0x73, 0x1e, 0xc4, 0x9d, 0x28, 0x2e, 0xff, 0xf8, 0xe3, 0x8f, 0x58, 0xb7, 0x6e, 0x1d, 0x8e, 0x1d, 0x3b, 0x86, 0xe0, 0xe0, 0x60, 0x4c, 0x9b, 0x36, 0x0d, 0x8b, 0x17, 0x2f, 0x46, 0x74, 0x74, 0x74, 0x8f, 0x2c, 0xb0, 0x47, 0x5f, 0xa0, 0xba, 0xba, 0x1a, 0x0f, 0x3f, 0xfc, 0x24, 0xec, 0xf6, 0x47, 0xa1, 0x52, 0xcd, 0x06, 0xc3, 0x04, 0xa3, 0xbd, 0xfd, 0xef, 0x68, 0x69, 0x59, 0x8e, 0xbf, 0xfc, 0x65, 0x3d, 0xc6, 0x8e, 0x1d, 0x8f, 0xd1, 0xa3, 0xf3, 0x20, 0x95, 0xee, 0xbe, 0x8e, 0xea, 0xb1, 0xb0, 0x58, 0x0e, 0xc0, 0x6e, 0xff, 0x18, 0xab, 0x57, 0xe7, 0x61, 0xee, 0xdc, 0x07, 0xef, 0x48, 0x69, 0xbd, 0xb0, 0xb0, 0x10, 0x73, 0xe6, 0x2c, 0x81, 0x5a, 0xbd, 0x06, 0x32, 0x59, 0x16, 0x3c, 0x1e, 0x07, 0x4c, 0xa6, 0x1d, 0x90, 0x48, 0xf6, 0xe0, 0xeb, 0xaf, 0xbf, 0xc0, 0xe0, 0xc1, 0x83, 0x7b, 0xd7, 0x00, 0x87, 0xc3, 0x41, 0xb3, 0x66, 0x3d, 0x85, 0x8a, 0x8a, 0x6c, 0x68, 0x34, 0xcf, 0x76, 0xb3, 0xf5, 0x2a, 0xd8, 0x6c, 0x33, 0x71, 0xe8, 0xd0, 0xb7, 0x18, 0x37, 0xee, 0x09, 0x08, 0x85, 0x53, 0xe0, 0x76, 0xb3, 0xf0, 0x78, 0x38, 0x00, 0x9e, 0xce, 0x02, 0x08, 0x03, 0x1e, 0x8f, 0x81, 0x40, 0xc0, 0xa0, 0xa3, 0x63, 0x07, 0xa6, 0x4f, 0x7f, 0x02, 0xaf, 0xbc, 0xb2, 0x08, 0x71, 0x71, 0x7d, 0xee, 0x88, 0x6a, 0x5b, 0x2c, 0x16, 0xa4, 0xa4, 0x8c, 0x44, 0x48, 0xc8, 0x5f, 0x11, 0x1c, 0x3c, 0xc4, 0xef, 0x59, 0x73, 0xf3, 0x36, 0x0c, 0x1f, 0x5e, 0x8c, 0x9d, 0x3b, 0x3f, 0x47, 0x70, 0x70, 0x30, 0x2f, 0x60, 0x36, 0x78, 0xfe, 0xfc, 0x79, 0xfc, 0xf0, 0x43, 0x03, 0x54, 0xaa, 0xe9, 0x3d, 0x88, 0x07, 0x07, 0x0f, 0x86, 0xd1, 0xa8, 0xc7, 0xa9, 0x53, 0x27, 0xf1, 0xef, 0x7f, 0xff, 0x03, 0x27, 0x4e, 0xd4, 0xe2, 0xfc, 0xf9, 0x0b, 0xb0, 0x58, 0x9a, 0xc0, 0xb2, 0x56, 0x10, 0x71, 0x60, 0x18, 0x31, 0x24, 0x12, 0x15, 0x62, 0x62, 0xe2, 0x30, 0x72, 0xe4, 0x7f, 0x41, 0x2c, 0x16, 0xdc, 0x51, 0xdb, 0x2e, 0x29, 0x29, 0x81, 0xdd, 0xae, 0x87, 0x46, 0x33, 0x38, 0x40, 0xb5, 0x68, 0x3a, 0x7e, 0xf8, 0x61, 0x07, 0x1a, 0x1a, 0x1a, 0x7a, 0x66, 0x83, 0xbe, 0x09, 0x44, 0x7b, 0x3b, 0x0b, 0xad, 0x56, 0x1e, 0xb0, 0x21, 0xc1, 0x30, 0x5a, 0x18, 0x8d, 0x46, 0x04, 0x05, 0x09, 0x30, 0x62, 0xc4, 0x00, 0x8c, 0x18, 0x31, 0xe0, 0x9e, 0x6a, 0x8f, 0x19, 0x8d, 0x46, 0x30, 0x8c, 0x36, 0x90, 0x6b, 0x03, 0x9f, 0x2f, 0x47, 0x7b, 0x3b, 0x0b, 0xbb, 0xdd, 0xde, 0x7b, 0x77, 0x58, 0xa1, 0x50, 0x20, 0x2c, 0x4c, 0x04, 0xb7, 0xdb, 0x10, 0xc0, 0xa6, 0x39, 0xb0, 0xec, 0x19, 0xc4, 0xc7, 0xc7, 0xe3, 0x5e, 0x1d, 0xf1, 0xf1, 0xf1, 0x60, 0xd9, 0x33, 0x20, 0xe2, 0x02, 0xb4, 0xdc, 0x0c, 0x08, 0x0b, 0x13, 0xf5, 0xe8, 0x66, 0x33, 0xbe, 0xa1, 0x41, 0xa7, 0xd3, 0x21, 0x27, 0x67, 0x38, 0x9a, 0x9a, 0x36, 0xc0, 0xe3, 0xb1, 0xfb, 0x95, 0xc6, 0x5b, 0x5b, 0x77, 0x21, 0x31, 0xd1, 0x8e, 0x51, 0xa3, 0x46, 0xdd, 0xb3, 0x02, 0x18, 0x35, 0x6a, 0x14, 0x12, 0x13, 0xed, 0x68, 0x6d, 0xdd, 0xe5, 0x57, 0x94, 0xf5, 0x78, 0xec, 0x68, 0x6a, 0xda, 0x80, 0x9c, 0x9c, 0xe1, 0xd0, 0xe9, 0x74, 0xbd, 0x3b, 0xc1, 0x2b, 0xb5, 0x39, 0x03, 0x16, 0x2d, 0x5a, 0x82, 0x23, 0x47, 0x58, 0x48, 0xa5, 0xb9, 0x9d, 0x51, 0xe0, 0x30, 0xfa, 0xf6, 0x3d, 0x81, 0x1d, 0x3b, 0x3e, 0xc1, 0x90, 0x21, 0x43, 0x70, 0x2f, 0x8f, 0xaa, 0xaa, 0x2a, 0xcc, 0x9e, 0x3d, 0x1f, 0xf5, 0xf5, 0x43, 0x21, 0x93, 0x4d, 0x80, 0xc7, 0xe3, 0x80, 0xd5, 0xba, 0x0f, 0x99, 0x99, 0x02, 0x6c, 0xde, 0xbc, 0x1e, 0x11, 0x11, 0x11, 0xd7, 0xc7, 0x01, 0x16, 0x8b, 0x05, 0x87, 0x0f, 0x1f, 0xc6, 0x77, 0xdf, 0x7d, 0xe7, 0xc5, 0x01, 0xb9, 0xb9, 0xb9, 0x08, 0x0b, 0x0b, 0xeb, 0x82, 0xce, 0x38, 0x73, 0xe6, 0x0c, 0x7e, 0xf9, 0xe5, 0x17, 0x84, 0x84, 0x84, 0x20, 0x35, 0x35, 0x15, 0x4a, 0xa5, 0xf2, 0x8e, 0x32, 0xda, 0xda, 0xda, 0x8a, 0xca, 0xca, 0x4a, 0xd8, 0x6c, 0x36, 0xc4, 0xc5, 0xc5, 0x61, 0xe0, 0xc0, 0x81, 0x5e, 0x6c, 0xdf, 0xd4, 0xd4, 0x84, 0x7d, 0xfb, 0xf6, 0x79, 0x71, 0xc0, 0xe4, 0xc9, 0x93, 0x31, 0x61, 0xc2, 0x04, 0xc8, 0xe5, 0xf2, 0x5f, 0x77, 0x59, 0xe2, 0x5a, 0xf8, 0xfa, 0xf2, 0xe5, 0xcb, 0x34, 0x77, 0xee, 0x3c, 0x8a, 0x8c, 0xcc, 0x24, 0xad, 0xf6, 0x49, 0xd2, 0xe9, 0x1e, 0xa1, 0x21, 0x43, 0xee, 0xa3, 0x3d, 0x7b, 0xf6, 0x10, 0xc7, 0x71, 0xb7, 0xfd, 0x42, 0x04, 0xc7, 0x71, 0xb4, 0x67, 0xcf, 0x1e, 0x1a, 0x32, 0xe4, 0x3e, 0xd2, 0xe9, 0x1e, 0x21, 0xad, 0xf6, 0x49, 0x8a, 0x8c, 0xcc, 0xa4, 0xb9, 0x73, 0xe7, 0xd1, 0xe5, 0xcb, 0x97, 0x7f, 0x75, 0x35, 0xf8, 0xa6, 0x86, 0xd3, 0xe9, 0xa4, 0xe9, 0xd3, 0x67, 0x52, 0x9f, 0x3e, 0xaf, 0xd0, 0xb0, 0x61, 0xad, 0x94, 0x96, 0xc6, 0x91, 0x5e, 0xef, 0xa4, 0xa4, 0xa4, 0x72, 0x52, 0xab, 0xf5, 0x74, 0xe8, 0xd0, 0xa1, 0xdb, 0x2e, 0x80, 0x43, 0x87, 0x0e, 0x91, 0x5a, 0xad, 0xa7, 0xa4, 0xa4, 0x72, 0xd2, 0xeb, 0x9d, 0x94, 0x96, 0xc6, 0xd1, 0xb0, 0x61, 0xad, 0xd4, 0xa7, 0xcf, 0x2b, 0x34, 0x7d, 0xfa, 0xcc, 0x5f, 0x75, 0x2b, 0xa4, 0xd7, 0x28, 0x70, 0x3d, 0xad, 0x28, 0x2f, 0x2f, 0x47, 0x71, 0xb1, 0x11, 0x11, 0x11, 0xab, 0xc0, 0xe7, 0x2b, 0x3a, 0x81, 0x8f, 0x08, 0x12, 0xc9, 0x70, 0x28, 0x95, 0xab, 0xb0, 0x6e, 0xdd, 0x16, 0x6f, 0xd3, 0xf1, 0xf6, 0x5c, 0x9e, 0x70, 0x63, 0xdd, 0xba, 0x2d, 0x50, 0x2a, 0x57, 0x41, 0x22, 0x19, 0x0e, 0x1e, 0x4f, 0x04, 0x80, 0x01, 0x9f, 0xaf, 0x40, 0x44, 0xc4, 0x2a, 0x14, 0x17, 0x1b, 0x51, 0x5e, 0x5e, 0x7e, 0x43, 0x57, 0xe8, 0x6f, 0xe8, 0xb6, 0x78, 0x49, 0x49, 0x09, 0x64, 0xb2, 0xc9, 0x9d, 0x2f, 0xf6, 0x1f, 0x32, 0x59, 0x06, 0xbe, 0xff, 0xbe, 0x06, 0x0e, 0x87, 0x23, 0x60, 0x69, 0xda, 0xe9, 0x74, 0xc2, 0xe5, 0x72, 0xc1, 0xe3, 0xf1, 0xf4, 0x4a, 0xdf, 0xe3, 0xf1, 0xc0, 0xe5, 0x72, 0xc1, 0xe9, 0x74, 0x82, 0x65, 0xd9, 0x00, 0x99, 0xa7, 0x03, 0xdf, 0x7f, 0x5f, 0x03, 0x99, 0x2c, 0x23, 0x40, 0x82, 0x23, 0x82, 0x4c, 0x36, 0x19, 0x25, 0x25, 0x25, 0xb8, 0x2d, 0x1a, 0x70, 0x05, 0x4c, 0xf0, 0x03, 0xc6, 0xd8, 0xae, 0xc6, 0x24, 0xc3, 0x30, 0x7e, 0x78, 0xdf, 0xe5, 0x72, 0x61, 0xd7, 0xae, 0x5d, 0xc8, 0xcc, 0x9c, 0x04, 0x8d, 0xa6, 0x3f, 0xe2, 0xe2, 0x86, 0x62, 0xe1, 0xc2, 0x97, 0x50, 0xdb, 0xbd, 0xab, 0x09, 0xa0, 0xb6, 0xb6, 0x16, 0x0b, 0x17, 0xbe, 0x84, 0xb8, 0xb8, 0xa1, 0xd0, 0x68, 0xfa, 0x23, 0x33, 0x73, 0x12, 0x76, 0xed, 0xda, 0xe5, 0xfd, 0xb2, 0xac, 0x33, 0x54, 0x83, 0x61, 0x98, 0x80, 0xf7, 0x16, 0xbb, 0xb0, 0x8a, 0xb7, 0xc8, 0x71, 0x3b, 0x04, 0x30, 0x7e, 0xfc, 0x78, 0xd8, 0x6c, 0xdf, 0x75, 0xc3, 0x08, 0xe8, 0x6c, 0x88, 0x16, 0x63, 0xf4, 0xe8, 0x64, 0xef, 0xc5, 0x44, 0x8e, 0xe3, 0xf0, 0xce, 0x3b, 0xef, 0xe2, 0x85, 0x17, 0xb6, 0xc1, 0x64, 0x5a, 0x83, 0xf8, 0xf8, 0x5f, 0xa0, 0x52, 0x95, 0x60, 0xff, 0xfe, 0x18, 0x4c, 0x99, 0x32, 0x03, 0xe7, 0xcf, 0x5f, 0xbd, 0x7b, 0x78, 0xfe, 0xfc, 0x79, 0x4c, 0x99, 0x32, 0x03, 0xfb, 0xf7, 0xc7, 0x40, 0xa5, 0x2a, 0x41, 0x7c, 0xfc, 0x2f, 0x30, 0x99, 0xd6, 0xe0, 0x85, 0x17, 0xb6, 0xe1, 0x9d, 0x77, 0xde, 0x05, 0xc7, 0x5d, 0x11, 0xba, 0x58, 0x2c, 0xc6, 0xe8, 0xd1, 0xc9, 0x68, 0x6f, 0x2f, 0x0e, 0xa0, 0x3d, 0x76, 0xd8, 0x6c, 0xdf, 0x61, 0xfc, 0xf8, 0xf1, 0xb7, 0x2f, 0xf4, 0xb8, 0x5c, 0x2e, 0x9a, 0x35, 0x6b, 0x2e, 0x85, 0x85, 0xbd, 0x40, 0x29, 0x29, 0x0d, 0xa4, 0xd7, 0xb3, 0x94, 0x9a, 0x6a, 0xa7, 0x84, 0x84, 0xc3, 0xa4, 0xd3, 0xe9, 0xa9, 0xb4, 0xb4, 0xd4, 0xeb, 0xac, 0x6a, 0x6a, 0x6a, 0x48, 0xad, 0x4e, 0xa3, 0x94, 0x94, 0x86, 0x1e, 0x1f, 0x48, 0x45, 0x46, 0xbe, 0x47, 0xcf, 0x3d, 0xf7, 0x3c, 0x71, 0x1c, 0x47, 0x1c, 0xc7, 0xd1, 0x73, 0xcf, 0x3d, 0x4f, 0x91, 0x91, 0xef, 0xf5, 0x58, 0x97, 0x92, 0xd2, 0x40, 0x6a, 0x75, 0x1a, 0xd5, 0xd4, 0xd4, 0x78, 0xe9, 0x96, 0x96, 0x96, 0x92, 0x4e, 0xa7, 0xa7, 0x84, 0x84, 0xc3, 0x94, 0x9a, 0x6a, 0x27, 0xbd, 0x9e, 0xa5, 0x94, 0x94, 0x06, 0x0a, 0x0b, 0x7b, 0x81, 0x66, 0xcd, 0x9a, 0x7b, 0xc3, 0x1f, 0x53, 0xdd, 0x90, 0x06, 0x08, 0x85, 0x42, 0xac, 0x5f, 0xff, 0x27, 0x3c, 0xf6, 0x98, 0x10, 0x56, 0xeb, 0x63, 0xb8, 0x70, 0x61, 0x3a, 0x1a, 0x1a, 0x66, 0x40, 0xa5, 0x5a, 0x85, 0x6d, 0xdb, 0x56, 0x62, 0xf4, 0xe8, 0xd1, 0xde, 0x38, 0x7b, 0xe0, 0xc0, 0x01, 0x88, 0x44, 0x53, 0x21, 0x14, 0xf6, 0xcc, 0x04, 0x55, 0xaa, 0x39, 0x28, 0x2a, 0x2a, 0x85, 0xd3, 0xe9, 0x84, 0xd3, 0xe9, 0x44, 0x51, 0x51, 0x29, 0x54, 0xaa, 0x39, 0x01, 0xde, 0xd7, 0x07, 0x22, 0xd1, 0x54, 0x1c, 0x38, 0x70, 0xc0, 0x8b, 0x56, 0x47, 0x8f, 0x1e, 0x8d, 0x6d, 0xdb, 0x56, 0x42, 0xa5, 0x5a, 0x85, 0x86, 0x86, 0x19, 0xb8, 0x70, 0x61, 0x3a, 0xac, 0xd6, 0xc7, 0xf0, 0xd8, 0x63, 0x57, 0xf6, 0x76, 0xa3, 0x57, 0x77, 0x6f, 0x28, 0x5d, 0xeb, 0x6a, 0xa3, 0xaf, 0x5f, 0xbf, 0x0e, 0x8b, 0x16, 0xd5, 0xa2, 0xae, 0xae, 0x0e, 0xc1, 0xc1, 0xc1, 0x48, 0x48, 0x48, 0x80, 0x42, 0xa1, 0xf0, 0x03, 0x19, 0x26, 0x93, 0x09, 0x7c, 0xbe, 0xaa, 0x17, 0x5f, 0x12, 0x0a, 0xb3, 0xb9, 0x1d, 0x5d, 0xce, 0xda, 0x6c, 0x6e, 0x87, 0x46, 0x13, 0xda, 0xcb, 0x5a, 0x15, 0x4c, 0xa6, 0xab, 0x77, 0x01, 0x04, 0x02, 0x01, 0x8f, 0x88, 0x68, 0xec, 0xd8, 0xb1, 0x38, 0x7b, 0xf6, 0x2c, 0x1c, 0x0e, 0x07, 0x22, 0x23, 0x23, 0x11, 0x1b, 0x1b, 0x0b, 0x3e, 0x9f, 0x7f, 0xc3, 0xb7, 0x42, 0x6f, 0x38, 0x5f, 0xed, 0x7a, 0x01, 0x11, 0x91, 0xef, 0x97, 0x20, 0xdd, 0x5f, 0x9c, 0x9a, 0x9a, 0x8a, 0x0f, 0x3f, 0x0c, 0x7c, 0x4d, 0xc5, 0xe1, 0x38, 0x89, 0x41, 0x83, 0xfa, 0x7b, 0x1b, 0xaf, 0x83, 0x06, 0xf5, 0x47, 0x5b, 0xdb, 0xc9, 0x00, 0xcd, 0x19, 0x82, 0xdd, 0x5e, 0x8e, 0xd4, 0xd4, 0x19, 0x01, 0x0f, 0x62, 0xc4, 0x88, 0x11, 0xbd, 0xbe, 0xff, 0xb6, 0x98, 0x40, 0xf7, 0x4d, 0xf8, 0x8e, 0xee, 0xcf, 0xb3, 0xb2, 0xb2, 0x10, 0x1b, 0x7b, 0x09, 0x26, 0x93, 0x7f, 0x62, 0xc2, 0xb2, 0x4d, 0xb8, 0x7c, 0x79, 0x05, 0x9e, 0x7f, 0xfe, 0x29, 0x08, 0x85, 0x42, 0x08, 0x85, 0x42, 0x3c, 0xff, 0xfc, 0x53, 0xb8, 0x7c, 0x79, 0x05, 0x58, 0xb6, 0xc9, 0x8f, 0x79, 0x93, 0x69, 0x17, 0x62, 0x63, 0x2f, 0x21, 0x2b, 0x2b, 0xeb, 0x86, 0xdf, 0x7f, 0xd7, 0x87, 0xc7, 0xe3, 0xa1, 0x8a, 0x8a, 0x0a, 0xd2, 0xeb, 0xc7, 0x92, 0x4a, 0xf5, 0x24, 0x45, 0x45, 0x6d, 0xa1, 0x88, 0x88, 0x95, 0xa4, 0x52, 0x8d, 0xa0, 0x15, 0x2b, 0x5e, 0x27, 0xbb, 0xdd, 0xee, 0x75, 0x6c, 0x76, 0xbb, 0x9d, 0x56, 0xac, 0x78, 0x9d, 0x54, 0xaa, 0x11, 0x14, 0x11, 0xb1, 0x92, 0xa2, 0xa2, 0xb6, 0x90, 0x4a, 0xf5, 0x24, 0xe9, 0xf5, 0x63, 0xa9, 0xa2, 0xa2, 0x82, 0x3c, 0x1e, 0xcf, 0x6d, 0xfb, 0x54, 0x96, 0x77, 0xbb, 0x85, 0x60, 0x36, 0x9b, 0x51, 0x5c, 0x5c, 0x8c, 0xe3, 0xc7, 0x8f, 0x43, 0xa9, 0x54, 0x62, 0xea, 0xd4, 0xa9, 0x48, 0x4a, 0x4a, 0xf2, 0xfb, 0x5a, 0xbc, 0xeb, 0x6b, 0xf2, 0x53, 0xa7, 0x4e, 0xa1, 0xa8, 0xa8, 0x08, 0xad, 0xad, 0xad, 0xd0, 0xeb, 0xf5, 0xc8, 0xce, 0xce, 0x86, 0x42, 0xa1, 0xb8, 0xe6, 0x27, 0x2f, 0xf7, 0xb4, 0x00, 0x7a, 0x2b, 0xb3, 0xf7, 0xa6, 0xb2, 0x37, 0xb2, 0xf6, 0xb7, 0x1a, 0xff, 0x07, 0x0d, 0x60, 0x29, 0xa2, 0x56, 0x90, 0xc6, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; gplanarity-17906/gameboard_draw_text.c0000644000175000017500000000410211543161637017764 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include #include #include "graph.h" #include "gameboard.h" GdkRectangle render_text_centered(cairo_t *c, char *s, int x, int y){ cairo_text_extents_t ex; GdkRectangle r; cairo_text_extents (c, s, &ex); r.x=x-(ex.width/2); r.y=y+(ex.y_bearing/2); r.width=ex.width; r.height=ex.height; cairo_move_to (c, r.x-ex.x_bearing, r.y-ex.y_bearing); cairo_show_text (c, s); return r; } GdkRectangle render_border_centered(cairo_t *c, char *s, int x, int y){ cairo_text_extents_t ex; GdkRectangle r; cairo_text_extents (c, s, &ex); r.x=x-(ex.width/2)-2; r.y=y+(ex.y_bearing/2)-2; r.width=ex.width+5; r.height=ex.height+5; cairo_save(c); cairo_move_to (c, r.x-ex.x_bearing+2, r.y-ex.y_bearing+2 ); cairo_set_line_width(c,3); cairo_set_source_rgba(c,1,1,1,.9); cairo_text_path (c, s); cairo_stroke(c); cairo_restore(c); return r; } GdkRectangle render_bordertext_centered(cairo_t *c, char *s, int x, int y){ GdkRectangle r = render_border_centered(c,s,x,y); render_text_centered(c,s,x,y); return r; } gplanarity-17906/graph_generate_mesh2.c0000644000175000017500000003060411543161637020041 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include #include "graph.h" #include "random.h" #include "gameboard.h" #include "graph_generate.h" #include "graph_arrange.h" #include "graph_region.h" /* Mesh1 has three primary considerations in mind: 1) By default, act like the algorithm in the original planarity 2) Conform to a population contraint that is easy to work with/modify 3) Playability; short edges result in graphs that are easier to solve. Mesh2 is intended to be a freeform populator with two different uses; harder levels that disrupt the easy solution algorithms that mesh1 allows, as well as being able to densely populate arbitrary regions. */ typedef struct { graph *g; int width; int height; int active_current; int active_max; } mesh; // check for intersections with other edges static int check_intersects_edge(mesh *m, edge *e, int intersections){ edge *ge = m->g->edges; int count=0; while(ge){ double xo,yo; // edges that aren't in this region don't exist (for // now) by definition if(ge->A->active == m->active_current || ge->B->active == m->active_current){ // edges that share a vertex don't intersect by definition if(ge->A!=e->A && ge->A!=e->B && ge->B!=e->A && ge->B!=e->B) if(intersects(ge->A->orig_x,ge->A->orig_y, ge->B->orig_x,ge->B->orig_y, e->A->orig_x,e->A->orig_y, e->B->orig_x,e->B->orig_y, &xo,&yo)){ count++; if(count>intersections)return 1; } } ge=ge->next; } return 0; } static float dot(vertex *A, vertex *B, vertex *C){ return (float)(B->orig_x-A->orig_x)*(float)(C->orig_x-B->orig_x) + (float)(B->orig_y-A->orig_y)*(float)(C->orig_y-B->orig_y); } static float cross(vertex *A, vertex *B, vertex *C){ return (float)(B->orig_x-A->orig_x)*(float)(C->orig_y-A->orig_y) - (float)(B->orig_y-A->orig_y)*(float)(C->orig_x-A->orig_x); } static float sq_point_distance(vertex *A, vertex *B){ float xd = A->orig_x-B->orig_x; float yd = A->orig_y-B->orig_y; return xd*xd+yd*yd; } static float sq_line_distance(edge *e, vertex *v){ if(dot(e->A,e->B,v) > 0) return sq_point_distance(e->B,v); if(dot(e->B,e->A,v) > 0) return sq_point_distance(e->A,v); { float c = cross(e->A,e->B,v); return c*c/sq_point_distance(e->A,e->B); } } // Does this edge pass within ten pixels of another vertex static int check_intersects_vertex(mesh *m, edge *e){ vertex *v = m->g->verticies; while(v){ if(v->active == m->active_current) if(v!=e->A && v!=e->B && sq_line_distance(e,v)<16)return 1; v=v->next; } return 0; } static int select_available(mesh *m,vertex *current,float length_limit,int intersections){ int count=0; vertex *v = m->g->verticies; // mark all possible choices while(v){ v->selected = 0; if(v!=current && current->active == m->active_current){ if(length_limit==0 || sq_point_distance(v,current)<=length_limit){ if(!exists_edge(v,current)){ edge e; e.A = v; e.B = current; if(!region_intersects(&e)){ if(!check_intersects_edge(m,&e,intersections)){ if(!check_intersects_vertex(m,&e)){ v->selected=1; count++; } } } } } } v=v->next; } return count; } // Although very inefficient, it is simple and correct. Even // impossibly large boards generate in a fraction of a second on old // boxen. There's likely no need to bother optimizing this step of // board creation. */ typedef struct insort{ int metric; vertex *v; } insort; static int insort_c(const void *a, const void *b){ insort *A=(insort *)a; insort *B=(insort *)b; return(A->metric-B->metric); } static vertex *vertex_num_sel(graph *g,int num){ vertex *v=g->verticies; if(num<0)return 0; while(v){ if(v->selected){ if(!num) break; else num--; } v=v->next; } return v; } static void prepopulate(mesh *m,int length_limit){ // sort all verticies in ascending order by their number of potential edges int i=0; int num=0; insort index[m->g->vertex_num]; vertex *v=m->g->verticies; while(v){ if(v->active == m->active_current){ index[num].v=v; index[num].metric = select_available(m,v,0,0); num++; } v=v->next; } qsort(index,num,sizeof(*index),insort_c); // populate in ascending order for(i=0;iedges; while(el){ edges++; el=el->next; if(edges>=2)break; } } if(edges>=2)continue; // it's possible some intersections will be necessary, but go for // fewest possible while(edges<2 && intersections<10){ int count = select_available(m,v,length_limit,intersections); if(count){ vertex *short0=0; vertex *short1=0; vertex *w=m->g->verticies; long d0; long d1; if(length_limit){ // choose two at random int a=random_number()%count; int b=-1; if(count>1) while(b==-1){ b=random_number()%count; if(b==a)b=-1; } short0=vertex_num_sel(m->g,a); short1=vertex_num_sel(m->g,b); }else{ // used with region-constrined meshes // of the possible edges, choose the shortest two while(w){ if(w!=v && w->selected){ int xd=w->orig_x-v->orig_x; int yd=w->orig_y-v->orig_y; long d=xd*xd+yd*yd; if(!short0){ short0=w; d0=d; }else if(!short1 || dnext; } } if(short0){ add_edge(m->g,v,short0); edges++; m->g->objective +=intersections; if(intersections)m->g->objective_lessthan=1; } if(edges<2 && short1){ add_edge(m->g,v,short1); edges++; m->g->objective +=intersections; if(intersections)m->g->objective_lessthan=1; } } intersections++; } } } // the spanning walk is to make an attempt at a single, connected graph. static void span_depth_first2(mesh *m,vertex *current, float length_limit){ current->grabbed=1; // overloaded; "we walked this already" while(1){ // prefer walking along edges that already exist { edge_list *el=current->edges; while(el){ edge *e=el->edge; vertex *v; if(e->A==current) v=e->B; else v=e->A; if(!v->grabbed){ span_depth_first2(m, v, length_limit); } el=el->next; } } // now walk any possible edges that have not been walked { int count=select_available(m,current,length_limit,0); int count2=0; int choice; vertex *v = m->g->verticies; // filter out already-walked edges while(v){ if(v->grabbed && v->selected){ // grabbed is also overloaded to mean walked v->selected = 0; count--; } v=v->next; } if(count == 0) return; choice = random_number()%count; v = m->g->verticies; while(v){ if(v->selected){ if(count2++ == choice){ add_edge(m->g,v,current); span_depth_first2(m,v, length_limit); break; } } v=v->next; } if(count == 1) return; // because we just took care of it } } } static void random_populate(mesh *m,vertex *current,int dense_128, float length_limit){ if(current->active == m->active_current){ int count=select_available(m,current,length_limit,0); if(count){ vertex *v = m->g->verticies; while(v){ if(v->selected && random_yes(dense_128)){ add_edge(m->g,v,current); v->selected=0; } v=v->next; } } } } /* Initial generation setup */ static void mesh_setup(graph *g, mesh *m, int order, int divis){ int flag=0; int wiggle=0; int n; m->g = g; m->width=3; m->height=2; { while(--order){ if(flag){ flag=0; m->height+=1; }else{ flag=1; m->width+=2; } } } n=m->width*m->height; // is this divisible by our requested divisor if any? if(divis>0 && n%divis){ while(1){ wiggle++; if(!((n+wiggle)%divis)) break; if(n-wiggle>6 && !((n-wiggle)%divis)){ wiggle = -wiggle; break; } } // refactor the rectangular mesh's dimensions. { int h = (int)sqrt(n+wiggle),w; while( (n+wiggle)%h )h--; if(h==1){ // double it and be content with a working result h=2; w=(n+wiggle); }else{ // good factoring w = (n+wiggle)/h; } m->width=w; m->height=h; } } new_board(g, m->width * m->height); region_init(); // clear it // used for intersection calcs { int x,y; vertex *v = g->verticies; for(y=0;yheight;y++) for(x=0;xwidth;x++){ v->orig_x=x*50; // not a random number v->orig_y=y*50; // not a random number v=v->next; } } g->objective = 0; g->objective_lessthan = 0; m->active_max=0; } static void generate_mesh2(mesh *m, int density_128, float length_limit){ vertex *v; int i; length_limit*=50; length_limit*=length_limit; for(i=0;i<=m->active_max;i++){ m->active_current=i; if(have_region()) prepopulate(m,0); /* connect the graph into as few discrete sections as possible */ v = m->g->verticies; while(v){ v->grabbed = 0; v=v->next; } v = m->g->verticies; // make sure we walk all verticies while(v){ if(v->active == m->active_current && !v->grabbed) span_depth_first2(m, m->g->verticies, length_limit); v=v->next; } if(!have_region()) prepopulate(m,length_limit); /* now iterate the whole mesh adding random edges */ v=m->g->verticies; while(v){ random_populate(m, v, density_128, length_limit); v=v->next; } } } void generate_freeform(graph *g, int order){ mesh m; random_seed(order+1); mesh_setup(g, &m, order, 0); generate_mesh2(&m,48,4); randomize_verticies(g); if(order*.03<.3) arrange_verticies_polycircle(g,4,0,order*.03,0,0,0); else arrange_verticies_polycircle(g,4,0,.3,0,0,0); } void generate_shape(graph *g, int order){ int mod=0; int dens=64; int min=8; mesh m; random_seed(order+1); switch(order%13){ case 0: // star mod=10; break; case 1: break; case 2: // dashed circle dens=48; break; case 3: // bifur dens=80; break; case 4: break; case 5: min = 12; dens = 10; break; case 6: min = 10; break; case 7: min = 10; break; case 8: min = 10; break; case 9: min = 10; break; case 10: // ring dens=128; min = 11; break; case 11: min = 12; break; case 12: // target min = 14; break; } mesh_setup(g, &m, (order>min?order:min), mod); randomize_verticies(g); switch(order % 13){ case 0: // star arrange_region_star(g); break; //4 case 1: // rainbow arrange_region_rainbow(g); break; //9 case 2: // dashed circle arrange_region_dashed_circle(g); break; //0 case 3: // bifur arrange_region_bifur(g); break; //0 case 4: // dairyqueen arrange_region_dairyqueen(g); break; //0 case 5: // cloud arrange_region_cloud(g); break; //0 case 6: // storm arrange_region_storm(g); break; //11 case 7: // plus; arrange_region_plus(g); break; //2 case 8: arrange_region_hole3(g); break; //4 case 9: arrange_region_hole4(g); break; //15 case 10: // ring arrange_region_ring(g); break; //29 case 11: arrange_region_ovals(g); break; //95 case 12: // target arrange_region_target(g); break; //108 } m.active_max=region_layout(g); generate_mesh2(&m,dens,0); } gplanarity-17906/graph_generate.c0000644000175000017500000003004211543161637016737 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include "graph.h" #include "graph_generate.h" #include "nls.h" typedef struct { char *class; int instancenum; char *desc; void (*gen)(graph *g, int num); float intersection_mult; float objective_mult; int unlock; } gen_instance; #define FINITE_LEVELS 79 static gen_instance i_list[FINITE_LEVELS]={ {"simple", 1, "A Small Beginning", generate_simple, 1.,4., 1 }, // 1 {"simple", 2, "My First Real Level(tm)", generate_simple, 1.,4., 2 }, // 2 {"data", 0, "My First Mission Impossible(tm)", generate_data, 20.,4., 3 }, // 3 {"simple", 3, "Larger But Not Harder", generate_simple, 1.,4., 2 }, // 4 {"crest", 5, "The Trick Is It's Easy", generate_crest, 1.,4., 2 }, // 5 {"simple", 4, "Practice Before the Handbasket: One of Three", generate_simple, 1.,4., 2 }, // 6 {"simple", 5, "Practice Before the Handbasket: Two of Three", generate_simple, 1.,4., 2 }, // 7 {"simple", 6, "Practice Before the Handbasket: Three of Three", generate_simple, 1.,4., 2 }, // 8 {"sparse", 4, "Tough and Stringy", generate_sparse, 1.2,4., 2 }, // 9 {"sparse", 5, "Threadbare", generate_sparse, 1.2,4., 2 }, // 10 {"nasty", 4, "The Bumpy Circles Are Slightly More Difficult", generate_nasty, 1.5,4., 3 }, // 11 {"nasty", 5, "Three is a Magic Number", generate_nasty, 1.5,4., 3 }, // 12 {"nasty", 6, "Last Call For (Sort of) Triangles (For Now)", generate_nasty, 1.5,4., 3 }, // 13 {"free", 4, "Something Only Subtly Different", generate_freeform, 1.5,4., 3 }, // 14 {"free", 5, "It Can Roll! Granted, Not Very Well", generate_freeform, 1.5,4., 3 }, // 15 {"free", 6, "If You Squint, It's a Round Brick", generate_freeform, 1.5,4., 3 }, // 16 {"rogue", 5, "A New Objective", generate_rogue, 1.6,4., 3 }, // 17 {"rogue", 6, "How Low Can You Go?", generate_rogue, 1.6,4., 3 }, // 18 {"rogue", 7, "Military Industrial Complex", generate_rogue, 1.6,4., 4 }, // 19 {"embed", 4, "The Hexagon is a Subtle and Wily Beast", generate_embed, 2.,4., 4 }, // 20 {"embed", 5, "No, Really, The Hexagon Puzzles Are Harder", generate_embed, 3.,4., 5 }, // 21 {"embed", 6, "Cursed? Call 1-800-HEX-A-GON Today!", generate_embed, 4.,4., 6 }, // 22 {"simple", 7, "Round but Straightforward", generate_simple, 1.,4., 4 }, // 23 {"shape", 0, "A Star Is Born... Then Solved", generate_shape, 1.,2., 6 }, // 24 {"shape", 1, "Oh, Rain*bows*...", generate_shape, 1.,2., 6 }, // 25 {"shape", 2, "Solve Along the Dotted Line", generate_shape, 1.,2., 6 }, // 26 {"shape", 3, "Using All Available Space", generate_shape, 1.,2., 6 }, // 27 {"shape", 4, "Brainfreeze", generate_shape, 1.,2., 6 }, // 28 {"shape", 6, "Tropical Storm Invest", generate_shape, 1.,2., 6 }, // 30 {"dense", 8, "Algorithm: Original/Dense (Order: 8)", generate_dense, .8,1., 5 }, // 31 {"simple", 8, "Algorithm: Original (Order: 8)", generate_simple, 1.,1., 6 }, // 32 {"sparse", 8, "Algorithm: Original/Sparse (Order: 8)",generate_sparse, 1.2,1., 7 }, // 33 {"nasty", 8, "Algorithm: Nasty (Order: 8)", generate_nasty, 1.5,1., 8 }, // 34 {"free", 8, "Algorithm: Freeform/4 (Order: 8)", generate_freeform, 1.5,1., 9 }, // 35 {"rogue", 8, "Algorithm: Rogue (Order: 8)", generate_rogue, 1.6,1.,10 }, // 36 {"embed", 8, "Algorithm: Embed (Order: 8)", generate_embed, 4.,1.,10 }, // 37 {"shape", 7, "Operator", generate_shape, 1.,2.,10 }, // 38 {"dense", 9, "Algorithm: Original/Dense (Order: 9)", generate_dense, .8,1., 5 }, // 39 {"simple", 9, "Algorithm: Original (Order: 9)", generate_simple, 1.,1., 6 }, // 40 {"sparse", 9, "Algorithm: Original/Sparse (Order: 9)",generate_sparse, 1.2,1., 7 }, // 41 {"nasty", 9, "Algorithm: Nasty (Order: 9)", generate_nasty, 1.5,1., 8 }, // 42 {"free", 9, "Algorithm: Freeform/4 (Order: 9)", generate_freeform, 1.5,1., 9 }, // 43 {"rogue", 9, "Algorithm: Rogue (Order: 9)", generate_rogue, 1.6,1.,10 }, // 44 {"embed", 9, "Algorithm: Embed (Order: 9)", generate_embed, 4.,1.,10 }, // 45 {"shape", 8, "The Inside Is Pointy", generate_shape, 1.,2.,10 }, // 46 {"dense", 10, "Algorithm: Original/Dense (Order: 10)", generate_dense, .8,1., 5 }, // 47 {"simple",10, "Algorithm: Original (Order: 10)", generate_simple, 1.,1., 6 }, // 48 {"sparse",10, "Algorithm: Original/Sparse (Order: 10)",generate_sparse, 1.2,1., 7 }, // 49 {"nasty", 10, "Algorithm: Nasty (Order: 10)", generate_nasty, 1.5,1., 8 }, // 50 {"free", 10, "Algorithm: Freeform/4 (Order: 10)", generate_freeform, 1.5,1., 9 }, // 51 {"rogue", 10, "Algorithm: Rogue (Order: 10)", generate_rogue, 1.6,1.,10 }, // 52 {"embed", 10, "Algorithm: Embed (Order: 10)", generate_embed, 4.,1.,10 }, // 53 {"shape", 9, "Riches and Good Luck", generate_shape, 1.,2.,10 }, // 54 {"dense", 11, "Algorithm: Original/Dense (Order: 11)", generate_dense, .8,1., 5 }, // 55 {"simple",11, "Algorithm: Original (Order: 11)", generate_simple, 1.,1., 6 }, // 56 {"sparse",11, "Algorithm: Original/Sparse (Order: 11)",generate_sparse, 1.2,1., 7 }, // 57 {"nasty", 11, "Algorithm: Nasty (Order: 11)", generate_nasty, 1.5,1., 8 }, // 58 {"free", 11, "Algorithm: Freeform/4 (Order: 11)", generate_freeform, 1.5,1., 9 }, // 59 {"rogue", 11, "Algorithm: Rogue (Order: 11)", generate_rogue, 1.6,1.,10 }, // 60 {"embed", 11, "Algorithm: Embed (Order: 11)", generate_embed, 4.,1.,10 }, // 61 {"shape", 10, "Mmmm... Doughnut", generate_shape, 1.,2.,10 }, // 62 {"dense", 12, "Algorithm: Original/Dense (Order: 12)", generate_dense, .8,1., 5 }, // 63 {"simple",12, "Algorithm: Original (Order: 12)", generate_simple, 1.,1., 6 }, // 64 {"sparse",12, "Algorithm: Original/Sparse (Order: 12)",generate_sparse, 1.2,1., 7 }, // 65 {"nasty", 12, "Algorithm: Nasty (Order: 12)", generate_nasty, 1.5,1., 8 }, // 66 {"free", 12, "Algorithm: Freeform/4 (Order: 12)", generate_freeform, 1.5,1., 9 }, // 67 {"rogue", 12, "Algorithm: Rogue (Order: 12)", generate_rogue, 1.6,1.,10 }, // 68 {"embed", 12, "Algorithm: Embed (Order: 12)", generate_embed, 4.,1.,10 }, // 69 {"shape", 11, "Quick and Dirty, or Slow and Steady", generate_shape, 1.,1.,10 }, // 70 {"shape", 5, "Little Fluffy Clouds", generate_shape, 1.,2., 6 }, // 29 {"dense", 13, "Algorithm: Original/Dense (Order: 13)", generate_dense, .8,1., 5 }, // 71 {"simple",13, "Algorithm: Original (Order: 13)", generate_simple, 1.,1., 6 }, // 72 {"sparse",13, "Algorithm: Original/Sparse (Order: 13)",generate_sparse, 1.2,1., 7 }, // 73 {"nasty", 13, "Algorithm: Nasty (Order: 13)", generate_nasty, 1.5,1., 8 }, // 74 {"free", 13, "Algorithm: Freeform/4 (Order: 13)", generate_freeform, 1.5,1., 9 }, // 75 {"rogue", 13, "Algorithm: Rogue (Order: 13)", generate_rogue, 1.6,1.,10 }, // 76 {"embed", 13, "Algorithm: Embed (Order: 13)", generate_embed, 4.,1.,10 }, // 77 {"shape", 12, "A Sudden Urge To Go Shopping", generate_shape, 1.,1.,10 }, // 78 {"shape", 13, "Sweet Reward", generate_shape, 1.,1.,10 }, // 79 }; #define LOOP_LEVELS 8 static gen_instance i_list_loop[LOOP_LEVELS]={ {"dense", 14, "Algorithm: Original/Dense (Order: %d)", generate_dense, .8,1., 5 }, // n {"simple",14, "Algorithm: Original (Order: %d)", generate_simple, 1.,1., 6 }, // n {"sparse",14, "Algorithm: Original/Sparse (Order: %d)",generate_sparse, 1.2,1., 7 }, // n {"nasty", 14, "Algorithm: Nasty (Order: %d)", generate_nasty, 1.5,1., 8 }, // n {"free", 14, "Algorithm: Freeform/4 (Order: %d)", generate_freeform, 1.5,1., 9 }, // n {"rogue", 14, "Algorithm: Rogue (Order: %d)", generate_rogue, 1.6,1.,10 }, // n {"embed", 14, "Algorithm: Embed (Order: %d)", generate_embed, 4.,1.,10 }, // n {"shape", 14, "Algorithm: Region (Order: %d)", generate_shape, 1.,2.,10 }, }; int generate_find_number(char *id){ int i; char buffer[160]; for(i=0;inum = num; gm->desc = _(i_list[num].desc); gm->unlock_plus = i_list[num].unlock+1; if(asprintf(&gm->id,"%s %d",i_list[num].class,i_list[num].instancenum)==-1){ fprintf(stderr,_("Couldn't allocate memory for level name.\n")); return -1; } return 0; }else{ /* past the finite list; one of the loop levels */ int classnum = (num - FINITE_LEVELS) % LOOP_LEVELS; int ordernum = (num - FINITE_LEVELS) / LOOP_LEVELS + i_list_loop[classnum].instancenum; gm->num = num; gm->unlock_plus = i_list_loop[classnum].unlock+1; if(asprintf(&gm->desc,i_list_loop[classnum].desc,ordernum)==-1){ fprintf(stderr,_("Couldn't allocate memory for level description.\n")); return -1; } if(asprintf(&gm->id,"%s %d",i_list_loop[classnum].class,ordernum)==-1){ fprintf(stderr,_("Couldn't allocate memory for level name.\n")); return -1; } return 0; } } void generate_board(graph *g,int num){ gen_instance *gi; if(numgen(g,gi->instancenum); }else{ int classnum = (num - FINITE_LEVELS) % LOOP_LEVELS; int ordernum = (num - FINITE_LEVELS) / LOOP_LEVELS + i_list_loop[classnum].instancenum; gi = i_list_loop+classnum; gi->gen(g,ordernum); } // clear out overloaded flags { vertex *v = g->verticies; while(v){ v->active=0; v->selected=0; v->grabbed=0; v=v->next; } } g->objective_mult = gi->objective_mult; g->intersection_mult = gi->intersection_mult; } gplanarity-17906/graph_region.h0000644000175000017500000000265511543161637016446 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include "nls.h" extern void region_init(); extern int region_intersects(edge *e); extern int region_layout(graph *g); extern void region_circle(int x,int y, float rad, int layout); extern void region_new_area(int x, int y, int layout); extern void region_line_to(int x,int y); extern void region_arc_to(int x,int y, float rad); extern void region_close_line(); extern void region_close_arc(float rad); extern int have_region(); extern void region_split_here(); gplanarity-17906/main.h0000644000175000017500000000237311543161637014723 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include "nls.h" extern char *boarddir; extern char *statedir; extern char *fontface; extern char *version; extern Gameboard *gameboard; extern void request_resize(int width, int height); extern void set_font(cairo_t *c, float w, float h, int slant, int bold); gplanarity-17906/dialog_level_icons.c0000644000175000017500000002531711543161637017616 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include #include #include "graph.h" #include "timer.h" #include "gameboard.h" #include "gameboard_draw_button.h" #include "dialog_level.h" #include "levelstate.h" #include "main.h" static void draw_forward_arrow(graph *g,dialog_level_oneicon *l, cairo_t *c,int fill){ int w = l->w; int h = l->h; int cx = w/2; int cy = h/2; cairo_save(c); cairo_translate(c,l->x+g->width/2+.5,l->y+g->height/2+.5); cairo_set_line_width(c,B_LINE); cairo_move_to(c,w-10,cy); cairo_line_to(c,cx,h-10); cairo_line_to(c,cx,(int)h*.75); cairo_line_to(c,10,(int)h*.75); cairo_line_to(c,10,(int)h*.25); cairo_line_to(c,cx,(int)h*.25); cairo_line_to(c,cx,10); cairo_close_path(c); if(fill){ cairo_set_source_rgba (c, B_COLOR); cairo_fill_preserve (c); } cairo_set_source_rgba (c, B_LINE_COLOR); cairo_stroke (c); cairo_restore(c); } static void draw_backward_arrow(graph *g,dialog_level_oneicon *l, cairo_t *c,int fill){ int w = l->w; int h = l->h; int cx = w/2; int cy = h/2; cairo_save(c); cairo_translate(c,l->x+g->width/2-.5,l->y+g->height/2+.5); cairo_set_line_width(c,B_LINE); cairo_move_to(c,10,cy); cairo_line_to(c,cx,h-10); cairo_line_to(c,cx,(int)h*.75); cairo_line_to(c,w-10,(int)h*.75); cairo_line_to(c,w-10,(int)h*.25); cairo_line_to(c,cx,(int)h*.25); cairo_line_to(c,cx,10); cairo_close_path(c); if(fill){ cairo_set_source_rgba (c, B_COLOR); cairo_fill_preserve (c); } cairo_set_source_rgba (c, B_LINE_COLOR); cairo_stroke (c); cairo_restore(c); } static void invalidate_icon(Gameboard *g,dialog_level_oneicon *l){ int cx = g->g.width/2; int cy = g->g.height/2; GdkRectangle r; r.x=l->x+cx+g->d.center_x; r.y=l->y+cy; r.width=l->w; r.height=l->h; gdk_window_invalidate_rect (GTK_WIDGET(g)->window, &r, FALSE); } static void dialog_level_oneicon_init(Gameboard *g, int num, dialog_level_oneicon *l){ int current = get_level_num(); l->num = num+current; if(l->icon)cairo_surface_destroy(l->icon); l->icon = levelstate_get_icon(num + current); l->alpha = 0.; l->w = ICON_WIDTH; l->h = ICON_HEIGHT; l->x = num*ICON_WIDTH*1.2 - (l->w*.5); l->y = 120 - (LEVELBOX_HEIGHT) / 2; } static void deploy_reset_button(Gameboard *g){ buttonstate *states=g->b.states; if(!g->d.reset_deployed){ states[10].sweepdeploy += SWEEP_DELTA; states[2].position = 2; //activate it states[2].y_target = states[2].y_active; g->d.reset_deployed=1; if(g->b.buttons_ready){ if(g->button_timer!=0) g_source_remove(g->button_timer); g->button_callback=0; g->button_timer = g_timeout_add(BUTTON_ANIM_INTERVAL, animate_button_frame, (gpointer)g); } } } static void undeploy_reset_button(Gameboard *g){ buttonstate *states=g->b.states; if(g->d.reset_deployed){ states[10].sweepdeploy -= SWEEP_DELTA; states[2].y_target = states[2].y_inactive; g->d.reset_deployed=0; if(g->b.buttons_ready){ if(g->button_timer!=0) g_source_remove(g->button_timer); g->button_callback = 0; g->button_timer = g_timeout_add(BUTTON_ANIM_INTERVAL, animate_button_frame, (gpointer)g); } } } static void alpha_update(Gameboard *g,dialog_level_oneicon *l){ int distance = labs(l->x - g->d.level_icons[2].x + g->d.center_x); double alpha = 1. - (distance/300.); if(alpha<0.)alpha=0.; //if(alpha>1.)alpha=1.; l->alpha = alpha; } void level_icons_init(Gameboard *g){ int i; for(i=0;i<5;i++) dialog_level_oneicon_init(g,i-2,g->d.level_icons+i); g->d.center_x = 0; g->d.center_done=1; g->d.level_lit = 2; g->d.reset_deployed = 0; if(levelstate_in_progress()) deploy_reset_button(g); memset(&g->d.text1,0,sizeof(g->d.text1)); memset(&g->d.text2,0,sizeof(g->d.text2)); memset(&g->d.text3,0,sizeof(g->d.text3)); memset(&g->d.text4,0,sizeof(g->d.text4)); } void render_level_icons(Gameboard *g, cairo_t *c, int ex,int ey, int ew, int eh){ if(g->level_dialog_active){ int w= g->g.width; int h= g->g.height; int y = h/2-LEVELBOX_HEIGHT/2+SCOREHEIGHT/2; int i; int ex2 = ex+ew; int ey2 = ey+eh; for(i=0;i<5;i++){ dialog_level_oneicon *l=g->d.level_icons+i; alpha_update(g,l); if(l->num >= 0 && l->num < levelstate_limit() && c){ int iw = l->w; int ih = l->h; int ix = l->x+g->d.center_x+w/2; int iy = l->y+h/2; if( l->alpha == 0.) continue; if( ix+iw < ex ) continue; if( ix > ex2 ) continue; if( iy+ih < ey ) continue; if( iy > ey2 ) continue; if(l->icon && cairo_surface_status(l->icon)==CAIRO_STATUS_SUCCESS){ cairo_set_source_surface(c,l->icon,ix,iy); cairo_paint_with_alpha(c,l->alpha); } if(g->d.center_x==0 && g->d.center_done){ if(i==2){ cairo_set_source_rgba (c, B_COLOR); borderbox_path(c,ix+1.5,iy+1.5,iw-3,ih-3); cairo_fill (c); } if(i==1) draw_backward_arrow(&g->g,l,c,i==g->d.level_lit); if(i==3) draw_forward_arrow(&g->g,l,c,i==g->d.level_lit); } } } // render level related text if(g->d.center_x == 0 && g->d.center_done && c){ char buffer[160]; // above text if(g->d.text1.width==0 || (eyd.text1.y+g->d.text1.height && ey2>g->d.text1.y)){ snprintf(buffer,160,_("Level %d:"),get_level_num()+1); set_font(c,20,20,0,1); cairo_set_source_rgba (c, TEXT_COLOR); g->d.text1=render_bordertext_centered(c, buffer,w/2,y+45); } if(g->d.text2.width==0 || (eyd.text2.y+g->d.text2.height && ey2>g->d.text2.y)){ set_font(c,18,18,0,0); cairo_set_source_rgba (c, TEXT_COLOR); g->d.text2=render_bordertext_centered(c, get_level_desc(),w/2,y+70); } if(g->d.text3.width==0 || (eyd.text3.y+g->d.text3.height && ey2>g->d.text3.y)){ if(levelstate_get_hiscore()==0){ set_font(c,18,18,1,0); snprintf(buffer,160,_("[not yet completed]")); }else{ set_font(c,18,18,0,0); snprintf(buffer,160,_("level high score: %ld"),levelstate_get_hiscore()); } cairo_set_source_rgba (c, TEXT_COLOR); g->d.text3=render_bordertext_centered(c, buffer,w/2,y+245); } if(g->d.text4.width==0 || (eyd.text4.y+g->d.text4.height && ey2>g->d.text4.y)){ snprintf(buffer,160,_("total score all levels: %ld"),levelstate_total_hiscore()); set_font(c,18,18,0,0); cairo_set_source_rgba (c, TEXT_COLOR); g->d.text4=render_bordertext_centered(c, buffer,w/2,y+265); } }else{ memset(&g->d.text1,0,sizeof(g->d.text1)); memset(&g->d.text2,0,sizeof(g->d.text2)); memset(&g->d.text3,0,sizeof(g->d.text3)); memset(&g->d.text4,0,sizeof(g->d.text4)); } } } static gboolean animate_level_frame(gpointer ptr){ Gameboard *g = GAMEBOARD (ptr); int i; if(g->d.center_x == 0){ g->d.center_done=1; g_source_remove(g->d.icon_timer); g->d.icon_timer=0; if(levelstate_in_progress()) deploy_reset_button(g); expose_full(g); return 0; } g->d.center_done=0; for(i=0;i<5;i++) if(g->d.level_icons[i].alpha) invalidate_icon(g, g->d.level_icons+i); if(g->d.center_x < 0){ g->d.center_x += ICON_DELTA; if(g->d.center_x > 0) g->d.center_x = 0; }else{ g->d.center_x -= ICON_DELTA; if(g->d.center_x < 0) g->d.center_x = 0; } // trick 'expose'; run it with a region that does nothing in order // to update the visibility flags render_level_icons(g, 0, 0, 0, 0, 0); for(i=0;i<5;i++) if(g->d.level_icons[i].alpha) invalidate_icon(g, g->d.level_icons+i); return 1; } static int find_icon(Gameboard *b,graph *g, int x, int y){ int i; int w= g->width; int h= g->height; x-=w/2; y-=h/2; for(i=1;i<4;i++){ dialog_level_oneicon *l=b->d.level_icons+i; if(l->num>=0 && l->num= l->x && x <= l->x + l->w && y >= l->y && y <= l->y + l->h) return i; } } return 2; } void local_reset (Gameboard *g){ levelstate_reset(); dialog_level_oneicon_init(g,0,g->d.level_icons+2); invalidate_icon(g, g->d.level_icons+2); undeploy_reset_button(g); } void level_mouse_motion(Gameboard *g, int x, int y){ int icon = find_icon(g,&g->g,x,y); if(icon != g->d.level_lit){ invalidate_icon(g, g->d.level_icons+g->d.level_lit); g->d.level_lit = icon; invalidate_icon(g, g->d.level_icons+g->d.level_lit); } } void level_mouse_press(Gameboard *g, int x, int y){ int i; level_mouse_motion(g, x, y); if(g->d.level_lit == 1){ if(levelstate_prev()){ if(!levelstate_in_progress()) undeploy_reset_button(g); if(g->d.level_icons[4].icon) cairo_surface_destroy(g->d.level_icons[4].icon); for(i=4;i>=1;i--){ g->d.level_icons[i].num = g->d.level_icons[i-1].num; g->d.level_icons[i].icon = g->d.level_icons[i-1].icon; } g->d.level_icons[0].icon=0; dialog_level_oneicon_init(g,-2,g->d.level_icons); if(g->d.center_x==0 && g->d.center_done)expose_full(g); // only needed to 'undraw' the text g->d.center_x = g->d.level_icons[1].x - g->d.level_icons[2].x; } } if(g->d.level_lit == 3){ if(levelstate_next()){ if(!levelstate_in_progress()) undeploy_reset_button(g); if(g->d.level_icons[0].icon) cairo_surface_destroy(g->d.level_icons[0].icon); for(i=0;i<4;i++){ g->d.level_icons[i].num = g->d.level_icons[i+1].num; g->d.level_icons[i].icon = g->d.level_icons[i+1].icon; } g->d.level_icons[4].icon=0; dialog_level_oneicon_init(g,2,g->d.level_icons+4); if(g->d.center_x==0 && g->d.center_done)expose_full(g); // only needed to 'undraw' the text g->d.center_x = g->d.level_icons[3].x - g->d.level_icons[2].x; } } if(g->d.center_x){ if(g->d.icon_timer) g_source_remove(g->d.icon_timer); g->d.icon_timer = g_timeout_add(BUTTON_ANIM_INTERVAL, animate_level_frame, (gpointer)g); } } gplanarity-17906/timer.c0000644000175000017500000000360011543161637015104 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include "timer.h" #include "nls.h" static int paused; static time_t begin_time_add; static time_t begin_time; static char timebuffer[160]; time_t get_timer(){ if(paused) return begin_time_add; else{ time_t ret = time(NULL); return ret - begin_time + begin_time_add; } } char *get_timer_string(){ int ho = get_timer() / 3600; int mi = get_timer() / 60 - ho*60; int se = get_timer() - ho*3600 - mi*60; if(ho){ snprintf(timebuffer,160,_("%d:%02d:%02d"),ho,mi,se); }else if (mi){ snprintf(timebuffer,160,_("%d:%02d"),mi,se); }else{ snprintf(timebuffer,160,_("%d seconds"),se); } return timebuffer; } void set_timer(time_t off){ begin_time_add = off; begin_time = time(NULL); } void pause_timer(){ begin_time_add = get_timer(); paused=1; } void unpause_timer(){ paused=0; set_timer(begin_time_add); } int timer_paused_p(){ return paused; } gplanarity-17906/gameboard_logic_fade.c0000644000175000017500000000663711543161637020056 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include "graph.h" #include "gameboard.h" static fade_list *pool=0; #define CHUNK 32 static void fade_add_vertex(fade_state *f,vertex *v){ fade_list *ret; if(pool==0){ int i; pool = calloc(CHUNK,sizeof(*pool)); for(i=0;inext; ret->v=v; v->fading=1; ret->next = f->head; f->head = ret; } static gint animate_fade(gpointer ptr){ Gameboard *g = (Gameboard *)ptr; fade_state *f = &g->fade; f->count--; if(f->count>0){ fade_list *l = f->head; while(l){ invalidate_vertex(g,l->v); l=l->next; } return 1; } fade_cancel(g); return 0; } void fade_cancel(Gameboard *g){ fade_state *f = &g->fade; fade_list *l = f->head; while(l){ fade_list *n = l->next; /* unflag vertex */ l->v->fading=0; /* invalidate the vertex */ invalidate_vertex(g,l->v); l->next=pool; pool=l; l=n; } f->head = 0; f->count = 0; if(f->fade_timer) g_source_remove(f->fade_timer); f->fade_timer=0; } void fade_attached(Gameboard *g,vertex *v){ fade_state *f = &g->fade; edge_list *el=v->edges; /* If a fade is already in progress, cancel it */ fade_cancel(g); while(el){ edge *e=el->edge; if(v == e->A){ fade_add_vertex(f,e->B); }else{ fade_add_vertex(f,e->A); } el=el->next; } f->count = FADE_FRAMES; f->fade_timer = g_timeout_add(FADE_ANIM_INTERVAL, animate_fade, (gpointer)g); } void fade_grabbed(Gameboard *g){ fade_state *f = &g->fade; vertex *v = g->g.verticies; /* If a fade is already in progress, cancel it */ fade_cancel(g); while(v){ if(v->grabbed){ edge_list *el=v->edges; while(el){ edge *e=el->edge; if(v == e->A){ if(!e->B->grabbed) fade_add_vertex(f,e->B); }else{ if(!e->A->grabbed) fade_add_vertex(f,e->A); } el=el->next; } } v=v->next; } f->count = FADE_FRAMES; f->fade_timer = g_timeout_add(FADE_ANIM_INTERVAL, animate_fade, (gpointer)g); } void fade_marked(Gameboard *g){ fade_state *f = &g->fade; vertex *v = g->g.verticies; /* If a fade is already in progress, cancel it */ fade_cancel(g); while(v){ if(v->grabbed) fade_add_vertex(f,v); v=v->next; } f->count = FADE_FRAMES; f->fade_timer = g_timeout_add(FADE_ANIM_INTERVAL, animate_fade, (gpointer)g); } gplanarity-17906/gameboard_draw_score.c0000644000175000017500000000662111543161637020123 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include "graph.h" #include "gameboard.h" #include "levelstate.h" #include "main.h" void draw_score(Gameboard *g){ char level_string[160]; char score_string[160]; char mult_string[160]; char int_string[160]; char obj_string[160]; cairo_text_extents_t extentsL; cairo_text_extents_t extentsS; cairo_text_extents_t extentsM; cairo_text_extents_t extentsO; cairo_text_extents_t extentsI; cairo_t *c = cairo_create(g->forescore); int xpx = 12; int ty1 = 23; int ty2 = 38; // clear the pane cairo_save(c); cairo_set_operator(c,CAIRO_OPERATOR_CLEAR); cairo_set_source_rgba (c, 1,1,1,1); cairo_paint(c); cairo_restore(c); topbox(g,c,g->g.width,SCOREHEIGHT); snprintf(level_string,160,_("Level %d: %s"),get_level_num()+1,get_level_desc()); snprintf(score_string,160,_("Score: %d"),graphscore_get_raw_score(&g->g)); snprintf(mult_string,160,_("%d%%"),graphscore_get_multiplier_percent(&g->g)); snprintf(int_string,160,_("Intersections: %ld"),g->g.active_intersections); snprintf(obj_string,160,_("Objective: %s"),graphscore_objective_string(&g->g)); set_font(c,xpx,15,0,1); cairo_set_source_rgba (c, TEXT_COLOR); cairo_text_extents (c, obj_string, &extentsO); cairo_text_extents (c, int_string, &extentsI); cairo_text_extents (c, score_string, &extentsS); cairo_text_extents (c, mult_string, &extentsM); cairo_move_to (c, 15, ty1); cairo_show_text (c, int_string); cairo_move_to (c, 15, ty2); cairo_show_text (c, score_string); if(graphscore_get_multiplier_percent(&g->g)>100){ cairo_save(c); cairo_set_source_rgba (c, HIGH_COLOR); cairo_move_to (c, 15 + extentsS.width+10, ty2); cairo_show_text (c, mult_string); cairo_restore(c); } cairo_move_to (c, g->g.width-extentsO.width-15, ty2); cairo_show_text (c, obj_string); while(xpx){ cairo_text_extents (c, level_string, &extentsL); if(extentsL.width > 300){ xpx--; set_font(c,xpx,15,0,1); }else break; } cairo_move_to (c, g->g.width-extentsL.width-15, ty1); cairo_show_text (c, level_string); cairo_destroy(c); } void update_score(Gameboard *g){ GdkRectangle r; draw_score(g); r.x=0; r.y=0; r.width=g->g.width; r.height = SCOREHEIGHT; gdk_window_invalidate_rect (g->w.window, &r, FALSE); } gplanarity-17906/random.c0000644000175000017500000000421211543161637015244 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include "random.h" // Portable 32 bit random number generator. It's not crypto-grade, // but we don't need crypto-grade. We need complete control over the // result sequence and reproducability, so we can't use any local // generator. As long as it's 100% consistent across // platforms/OSes/compilers and fairly uniform (doesn't always return // 17), we're all set. // This is a C derivative of the PASCAL "Integer Version 2" minimal // standard number generator thich appears in the article: // Park, Steven K. and Miller, Keith W., "Random Number // Generators: Good Ones are Hard to Find", Communications of the // ACM, October, 1988. static int32_t next = 123456789; void random_seed(int32_t seed){ next = seed; } #define MPLIER 16807 #define MOBYMP 127773 #define MOMDMP 2836 int32_t random_number(){ int32_t hival, loval, testval; hival = next / MOBYMP; loval = next % MOBYMP; testval = MPLIER*loval - MOMDMP*hival; if (testval > 0) next = testval; else next = testval + MAX_G_RAND; return next; } int random_yes(int per128_yes){ u_int32_t num = (u_int32_t)random_number(); return (num < (unsigned int)per128_yes << 24U); } gplanarity-17906/gameboard_draw_edge.c0000644000175000017500000000544011543161637017712 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include "graph.h" #include "gameboard.h" /******** draw edges ********************************************/ void setup_background_edge(cairo_t *c){ cairo_set_line_width(c,E_LINE); cairo_set_source_rgba(c,E_LINE_B_COLOR); } void setup_foreground_edge(cairo_t *c){ cairo_set_line_width(c,E_LINE); cairo_set_source_rgba(c,E_LINE_F_COLOR); } void draw_edge(cairo_t *c,edge *e){ cairo_move_to(c,e->A->x,e->A->y); cairo_line_to(c,e->B->x,e->B->y); } void finish_edge(cairo_t *c){ cairo_stroke(c); } void draw_edges(cairo_t *c, vertex *v, int offx, int offy){ if(v){ edge_list *el=v->edges; while (el){ edge *e=el->edge; if(e->A->grabbed==0 || e->B->grabbed==0 || v==e->A){ if(e->A->grabbed) cairo_move_to(c,e->A->x+offx,e->A->y+offy); else cairo_move_to(c,e->A->x,e->A->y); if(e->B->grabbed) cairo_line_to(c,e->B->x+offx,e->B->y+offy); else cairo_line_to(c,e->B->x,e->B->y); } el=el->next; } } } /* invalidate edge region for efficient expose *******************/ void invalidate_edges(GtkWidget *widget, vertex *v, int offx, int offy){ GdkRectangle r; if(v){ edge_list *el=v->edges; while (el){ edge *e=el->edge; if(e->A->grabbed==0 || e->B->grabbed==0 || v==e->A){ int Ax = e->A->x + (e->A->grabbed?offx:0); int Ay = e->A->y + (e->A->grabbed?offy:0); int Bx = e->B->x + (e->B->grabbed?offx:0); int By = e->B->y + (e->B->grabbed?offy:0); r.x = min(Ax,Bx) - E_LINE; r.y = min(Ay,By) - E_LINE; r.width = labs(Bx - Ax) + 1 + E_LINE*2; r.height = labs(By - Ay) + 1 + E_LINE*2; gdk_window_invalidate_rect (widget->window, &r, FALSE); } el=el->next; } } } gplanarity-17906/random.h0000644000175000017500000000220211543161637015246 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #define MAX_G_RAND 2147483647 extern void random_seed(int32_t seed); extern int32_t random_number(); extern int random_yes(int per128_yes); gplanarity-17906/graph_arrange.c0000644000175000017500000002342411543161637016572 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include "graph.h" #include "random.h" #include "gameboard.h" #include "graph_arrange.h" #include "graph_region.h" void arrange_verticies_circle(graph *g, float off1, float off2){ vertex *v = g->verticies; int n = g->vertex_num; int bw=g->orig_width; int bh=g->orig_height; int radius=min(bw,bh)*.45; int i; for(i=0;ix = rint( radius * sin( i*M_PI*2./n +off1) + (bw>>1)); v->y = rint( radius * -cos( i*M_PI*2./n +off2) + (bh>>1)); v=v->next; } } void arrange_verticies_polygon(graph *g, int sides, float angle, float rad, int xoff, int yoff, float xstretch, float ystretch){ vertex *v = g->verticies; int n = g->vertex_num; int bw=g->orig_width; int bh=g->orig_height; int radius=min(bw,bh)*rad*.45; float perleg,del,acc=0; int i; for(i=0;ix = rint(((xA + xD*acc) - bw/2) * xstretch + bw/2); v->y = rint(((yA + yD*acc) - bh/2) * ystretch + bh/2); v=v->next; acc+=del; } acc-=perleg; } } void arrange_verticies_polycircle(graph *g, int sides, float angle, float split, int radplus,int xoff,int yoff){ vertex *v = g->verticies; int n = g->vertex_num; int bw=g->orig_width; int bh=g->orig_height; int radius=min(bw,bh)*.45+radplus; float perleg,perarc,del,acc=0; int i; for(i=0;ix = rint( sin(ang0 + aD*acc)*radius+bw/2)+xoff; v->y = rint(-cos(ang0 + aD*acc)*radius+bh/2)+yoff; v=v->next; acc+=del; } acc-=perarc/2; // populate the line segment xD = (xB-xA) / perleg; yD = (yB-yA) / perleg; while(v && acc<=perleg){ v->x = rint(xA + xD*acc)+xoff; v->y = rint(yA + yD*acc)+yoff; v=v->next; acc+=del; } acc-=perleg; // populate the second arc segment while(v && acc<=perarc/2){ v->x = rint( sin(ang2 + aD*acc)*radius+bw/2)+xoff; v->y = rint(-cos(ang2 + aD*acc)*radius+bh/2)+yoff; v=v->next; acc+=del; } acc-=perarc/2; } } void arrange_verticies_mesh(graph *g, int width, int height){ vertex *v = g->verticies; int bw=g->orig_width; int bh=g->orig_height; int spacing=min((float)bw/width,(float)bh/height)*.9; int x,y; int xpad=(bw - (width-1)*spacing)/2; int ypad=(bh - (height-1)*spacing)/2; for(y=0;yx=x*spacing+xpad; v->y=y*spacing+ypad; v=v->next; } } } void arrange_verticies_nastymesh(graph *g, int w, int h, vertex **flat){ int A = 0; int B = w-1; int i; arrange_verticies_mesh(g,w,h); while(Ay-=10; flat[B+i]->y-=10; flat[i+(h-1)*w]->y+=10; flat[B+i+(h-1)*w]->y+=10; } A++; B--; } A = 0; B = (h-1)*w; while(Ax-=10; flat[B+i]->x-=10; flat[i +(w-1)]->x+=10; flat[B+i+(w-1)]->x+=10; } A+=w; B-=w; } } void arrange_region_star(graph *g){ region_init(); region_new_area(400,45,1); region_line_to(340,232); region_line_to(143,232); region_line_to(303,347); region_line_to(241,533); region_line_to(400,417); region_line_to(559,533); region_line_to(497,347); region_line_to(657,232); region_line_to(460,232); region_close_line(); } void arrange_region_rainbow(graph *g){ region_init(); region_new_area(40,500,2); region_arc_to(760,500,-M_PI); region_line_to(660,500); region_arc_to(200,500,M_PI); region_close_line(); } void arrange_region_dashed_circle(graph *g){ int bw=g->orig_width; int bh=g->orig_height; int radius=min(bw,bh)*.45; int i; region_init(); for(i=0;i<20;i+=2){ float phi0=(M_PI*2.f/20*(i-.5)); float phi1=(M_PI*2.f/20*(i+.5)); int x1= cos(phi0)*radius+bw/2; int y1= -sin(phi0)*radius+bh/2; int x2= cos(phi1)*radius+bw/2; int y2= -sin(phi1)*radius+bh/2; region_new_area(x1,y1,3); region_arc_to(x2,y2,M_PI/10); } } void arrange_region_bifur(graph *g){ int bw=g->orig_width; int bh=g->orig_height; region_init(); region_new_area(21,60,2); region_line_to(bw/2-130,60); region_arc_to(bw/2+130,60,-M_PI*.25); region_line_to(bw-21,60); region_new_area(21,bh-60,1); region_line_to(bw/2-130,bh-60); region_arc_to(bw/2+130,bh-60,M_PI*.25); region_line_to(bw-21,bh-60); } void arrange_region_dairyqueen(graph *g){ int bw=g->orig_width; int bh=g->orig_height; int radius=min(bw,bh)*.45; float phi0=(M_PI/2 + M_PI*2.f/8); float phi1=(M_PI/2 - M_PI*2.f/8); int x1= cos(phi0)*radius+bw/2; int x2= cos(phi1)*radius+bw/2; int y1= -sin(phi0)*radius+bh/2; int y2= sin(phi0)*radius+bh/2; region_init(); region_new_area(x1,y1,2); region_arc_to(x2,y1,-M_PI/2); region_line_to(750,bh/2); region_line_to(x2,y2); region_arc_to(x1,y2,-M_PI/2); region_line_to(50,bh/2); region_close_line(); } void arrange_region_cloud(graph *g){ int bw=g->orig_width; int bh=g->orig_height; int radius=min(bw,bh)*.45-20; int i=0; float phi0=(M_PI*2.f/20*(i-.5)),phi1; int x1= cos(phi0)*radius+bw/2,x2; int y1= -sin(phi0)*radius+bh/2,y2; region_init(); region_new_area(x1,y1,1); for(i=0;i<19;i++){ phi1=(M_PI*2.f/20*(i+.5)); x2= cos(phi1)*radius+bw/2; y2= -sin(phi1)*radius+bh/2; region_arc_to(x2,y2,M_PI*.7); } region_close_arc(M_PI*.7); } void arrange_region_ring(graph *g){ int bw=g->orig_width; int bh=g->orig_height; int radius=min(bw,bh)*.45; region_init(); region_circle(bw/2,bh/2,radius,3); region_circle(bw/2,bh/2,radius*.4,1); } void arrange_region_storm(graph *g){ int bw=g->orig_width; int bh=g->orig_height; int radius=min(bw,bh)*.45; int i=0; region_init(); for(i=0;i<10;i++){ float phi0=(M_PI*2.f/10*(i-.5)); float phi1=(M_PI*2.f/10*(i+.5)); int x1= cos(phi0)*radius+bw/2; int y1= -sin(phi0)*radius+bh/2; int x2= cos(phi1)*radius*.8+bw/2; int y2= -sin(phi1)*radius*.8+bh/2; region_new_area(x1,y1,1); region_arc_to(x2,y2,M_PI*.2); } region_circle(bw/2,bh/2,radius*.2,0); } void arrange_region_target(graph *g){ int bw=g->orig_width; int bh=g->orig_height; int radius=min(bw,bh)*.45; region_init(); region_circle(bw/2,bh/2,radius,3); region_circle(bw/2,bh/2,radius*.5,1); region_split_here(); region_circle(bw/2,bh/2,radius*.35,3); } void arrange_region_plus(graph *g){ region_init(); region_new_area(316,43,2); region_arc_to(483,43,-M_PI*2/10); region_line_to(483,216); region_line_to(656,216); region_arc_to(656,384,-M_PI*2/10); region_line_to(483,384); region_line_to(483,556); region_arc_to(316,556,-M_PI*2/10); region_line_to(316,384); region_line_to(143,384); region_arc_to(143,216,-M_PI*2/10); region_line_to(316,216); region_close_line(); } void arrange_region_hole3(graph *g){ int bw=g->orig_width; int bh=g->orig_height; int radius=min(bw,bh)*.45; region_init(); region_circle(bw/2,bh/2,radius,3); region_new_area(400,200,2); region_line_to(313,349); region_line_to(487,349); region_close_line(); } void arrange_region_hole4(graph *g){ int bw=g->orig_width; int bh=g->orig_height; int radius=min(bw,bh)*.45; region_init(); region_circle(bw/2,bh/2,radius,3); region_new_area(325,225,1); region_line_to(475,225); region_line_to(475,375); region_line_to(325,375); region_close_line(); } void arrange_region_ovals(graph *g){ region_init(); region_new_area(270,163,2); region_arc_to(530,163,-M_PI*.99); region_line_to(530,437); region_arc_to(270,437,-M_PI*.99); region_close_line(); region_split_here(); region_new_area(80,263,2); region_arc_to(230,263,-M_PI*.99); region_line_to(230,337); region_arc_to(80,337,-M_PI*.99); region_close_line(); region_split_here(); region_new_area(570,263,2); region_arc_to(720,263,-M_PI*.99); region_line_to(720,337); region_arc_to(570,337,-M_PI*.99); region_close_line(); region_split_here(); } gplanarity-17906/gameboard_logic_mouse.c0000644000175000017500000002366611543161637020310 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include "graph.h" #include "gameboard.h" #include "dialog_level.h" /* does the given x/y fall inside an on-screen vertex? */ static void check_lit(Gameboard *g,int x, int y){ vertex *v = find_vertex(&g->g,x,y); if(v!=g->lit_vertex){ invalidate_vertex(g,v); invalidate_vertex(g,g->lit_vertex); g->lit_vertex = v; } } /* toplevel mouse motion handler */ gint mouse_motion(GtkWidget *widget, GdkEventMotion *event){ Gameboard *g = GAMEBOARD (widget); /* the level selection dialog implements its own icon mouse management */ if(g->level_dialog_active) level_mouse_motion(g,(int)event->x,(int)event->y); /* similarly, if a vertex is grabbed, the only thing that can happen is that we're dragging that vertex */ if(g->grabbed_vertex){ int x = (int)event->x; int y = (int)event->y; g->dragx = x-g->grabx; g->dragy = y-g->graby; invalidate_vertex(g,g->grabbed_vertex); invalidate_edges(widget,g->grabbed_vertex,0,0); move_vertex(&g->g,g->grabbed_vertex,x+g->graboffx,y+g->graboffy); invalidate_vertex(g,g->grabbed_vertex); invalidate_edges(widget,g->grabbed_vertex,0,0); return TRUE; } /* if the selection is grabbed, we can only be dragging a selection box */ if (g->selection_grab){ invalidate_selection(widget); g->selectionx = min(g->grabx, event->x); g->selectionw = labs(g->grabx - event->x); g->selectiony = min(g->graby, event->y); g->selectionh = labs(g->graby - event->y); select_verticies(&g->g, g->selectionx,g->selectiony, g->selectionx+g->selectionw-1, g->selectiony+g->selectionh-1); invalidate_selection(widget); return TRUE; } /* if a selected vertex is grabbed (group drag) we're dragging the whole selection and its lines */ if(g->group_drag){ invalidate_verticies_selection(widget); g->dragx = event->x - g->grabx; g->dragy = event->y - g->graby; /* don't allow the drag to put a vertex offscreen; bound the drag at the edge */ { vertex *v=g->g.verticies; int w=g->g.width; int h=g->g.height; while(v){ if(v->selected){ if(v->x + g->dragx >= w) g->dragx=w - v->x -1; if(v->x + g->dragx < 0 ) g->dragx= -v->x; if(v->y + g->dragy >= h) g->dragy=h - v->y -1; if(v->y + g->dragy < 0 ) g->dragy= -v->y; } v=v->next; } } invalidate_verticies_selection(widget); return TRUE; } /* A vertex rollover has priority over a button rollover. However, a button grab disallows a rollover, as does the curtain. */ if(!g->pushed_curtain && !g->button_grabbed) check_lit(g, (int)event->x,(int)event->y); /* handle button rollovers and ongoing grabs; other grabs are already disallowed, but also verify a vertex rollover isn't already active (and that buttons are currently hot) */ if(!g->lit_vertex && g->b.buttons_ready){ buttonstate *b = find_button(g,(int)event->x,(int)event->y); if(g->b.grabbed){ /* a button is grabbed; a rollover sees only the grabbed button */ if(g->b.grabbed==b) button_set_state(g,b,1,1); else button_set_state(g,g->b.grabbed,0,0); }else{ /* no button is grabbed; any button may see a rollover */ if(b) button_set_state(g,b,1,0); else button_clear_state(g); } } return TRUE; } /* toplevel mouse button press handler */ gboolean mouse_press (GtkWidget *widget, GdkEventButton *event){ if(event->type == GDK_BUTTON_PRESS){ // filter out doubleclicks Gameboard *g = GAMEBOARD (widget); vertex *v = find_vertex(&g->g,(int)event->x,(int)event->y); buttonstate *b = find_button(g,(int)event->x,(int)event->y); int old_intersections = g->show_intersections; /* the level selection dialog implements its own icon mouse management */ if(g->level_dialog_active) level_mouse_press(g,(int)event->x,(int)event->y); button_clear_state(g); g->button_grabbed=0; set_show_intersections(g,0); /* presses that affect board elements other than buttons can only happen when the curtain isn't pushed. */ if(!g->pushed_curtain){ /* case: shift-click addition of a single new vertex to selection */ if(v && event->state&GDK_SHIFT_MASK){ if(v->selected){ v->selected=0; g->selection_active--; }else{ v->selected=1; g->selection_active++; } invalidate_vertex(g,g->lit_vertex); return TRUE; } /* case: shift-click drag of an additional region to add to selection */ if(event->state&GDK_SHIFT_MASK){ g->selection_grab=1; g->grabx = (int)event->x; g->graby = (int)event->y; g->selectionx = g->grabx; g->selectionw = 0; g->selectiony = g->graby; g->selectionh = 0; return TRUE; } /* case: drag the selected group of verticies to new location */ if(g->selection_active && v && v->selected){ g->group_drag=1; g->grabx = (int)event->x; g->graby = (int)event->y; g->dragx = 0; g->dragy = 0; // highlight vertex immediately; update the background after the // vertex change grab_selected(&g->g); invalidate_verticies_selection(widget); fade_cancel(g); update_full_delayed(g); return TRUE; } /* if selection is active, we got this far, and we're not about to take action based on pointing at a button, selection should be inactivated */ if(g->selection_active && (g->lit_vertex || !b)){ deselect_verticies(&g->g); g->selection_active=0; g->group_drag=0; // potentially pull verticies out of background (can happen if // mouse went offscreen during a grab) update_full(g); } /* case: grab/drag a single unselected vertex */ if(g->lit_vertex){ g->grabbed_vertex = g->lit_vertex; g->grabx = (int)event->x; g->graby = (int)event->y; g->graboffx = g->grabbed_vertex->x-g->grabx; g->graboffy = g->grabbed_vertex->y-g->graby; grab_vertex(&g->g,g->grabbed_vertex); invalidate_attached(widget,g->grabbed_vertex); invalidate_edges(widget,g->grabbed_vertex,0,0); fade_cancel(g); // highlight vertex immediately; update the background after the // vertex change update_full_delayed(g); return TRUE; } } /* case: button click */ if(b){ // if intersections were visible, a button press is the only // click that wouldn't auto-hide them, so restore the flag to // its state before entry. g->show_intersections=old_intersections; button_set_state(g,b,1,1); g->b.grabbed = b; return TRUE; } /* clicking anywhere else wtith no modifiers initiates a new selection drag (assuming curtain isn't pushed) */ if(!g->pushed_curtain){ g->selection_grab=1; g->grabx = (int)event->x; g->graby = (int)event->y; g->selectionx = g->grabx; g->selectionw = 0; g->selectiony = g->graby; g->selectionh = 0; return TRUE; } } return TRUE; } /* toplevel mouse button release handler */ gboolean mouse_release (GtkWidget *widget, GdkEventButton *event){ Gameboard *g = GAMEBOARD (widget); /* case: button grabbed */ if(g->b.grabbed){ buttonstate *b = find_button(g,(int)event->x,(int)event->y); if(b && g->b.grabbed==b){ button_set_state(g,b,1,0); if(b->callback) b->callback(g); } g->b.grabbed=0; } /* if the curtain is pushed, no sense checking for other grabs */ if(!g->pushed_curtain){ /* case: release a grabbed vertex */ if(g->grabbed_vertex){ ungrab_vertex(&g->g,g->grabbed_vertex); update_add_vertex(g,g->grabbed_vertex); fade_attached(g,g->grabbed_vertex); update_score(g); g->grabbed_vertex = 0; if(g->g.active_intersections<=g->g.objective) deploy_check(g); else undeploy_check(g); } /* case: release a selection grab */ if(g->selection_grab){ invalidate_selection(widget); g->selection_grab=0; /* are there selected verticies? If only one was selected, that's usually due to an accidental drag while clicking. Treat a single-vertex drag select as a nil selection */ if(num_selected_verticies(&g->g)<=1){ g->selection_active=0; deselect_verticies(&g->g); // could have grabbed just one }else{ commit_volatile_selection(&g->g); g->selection_active=num_selected_verticies(&g->g); } } /* case: release a group drag */ if(g->group_drag){ move_selected_verticies(&g->g,g->dragx,g->dragy); fade_grabbed(g); update_add_selgroup(g); ungrab_verticies(&g->g); update_score(g); g->group_drag=0; if(g->g.active_intersections<=g->g.objective) deploy_check(g); else undeploy_check(g); } } /* a release may result in a new mouse-over; look for it */ mouse_motion(widget,(GdkEventMotion *)event); // the cast is safe in this case return TRUE; } gplanarity-17906/gameboard.c0000644000175000017500000002213211543161637015706 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include "nls.h" #include "graph.h" #include "gameboard.h" #include "levelstate.h" static GtkWidgetClass *parent_class = NULL; static void gameboard_init (Gameboard *g){ // instance initialization g->g.width=g->g.orig_width=800; g->g.height=g->g.orig_height=600; g->resize_w = g->g.width; g->resize_h = g->g.height; g->resize_timeout = 0; } static void gameboard_destroy (GtkObject *object){ if (GTK_OBJECT_CLASS (parent_class)->destroy) (*GTK_OBJECT_CLASS (parent_class)->destroy) (object); // free local resources } static gint gameboard_expose (GtkWidget *widget, GdkEventExpose *event){ if (GTK_WIDGET_REALIZED (widget)){ Gameboard *g = GAMEBOARD (widget); gameboard_draw(g,event->area.x,event->area.y, event->area.width,event->area.height); if(g->resize_h>0 && g->resize_w>0){ if(widget->allocation.width != g->resize_w || widget->allocation.height != g->resize_h){ if(time(NULL) > g->resize_timeout){ fprintf(stderr,_("\n\nERROR: The windowmanager appears to be ignoring resize requests.\n" "This stands a pretty good chance of scrambling any saved board larger\n" "than the default window size.\n\n")); fprintf(stderr,_("Clipping and/or expanding this board to the current window size...\n\n")); g->resize_w = 0; g->resize_h = 0; resize_buttons(g,g->g.width, g->g.height, widget->allocation.width, widget->allocation.height); graph_resize(&g->g, widget->allocation.width, widget->allocation.height); update_score(g); draw_buttonbar_box(g); update_full(g); } }else{ g->resize_h=0; g->resize_w=0; } } } return FALSE; } static void gameboard_size_request (GtkWidget *widget, GtkRequisition *requisition){ Gameboard *g = GAMEBOARD (widget); requisition->width = g->g.orig_width; requisition->height = g->g.orig_height; } static void gameboard_realize (GtkWidget *widget){ Gameboard *g = GAMEBOARD (widget); GdkWindowAttr attributes; gint attributes_mask; cairo_t *wc; GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); attributes.x = widget->allocation.x; attributes.y = widget->allocation.y; attributes.width = widget->allocation.width; attributes.height = widget->allocation.height; attributes.wclass = GDK_INPUT_OUTPUT; attributes.window_type = GDK_WINDOW_CHILD; attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK| GDK_POINTER_MOTION_MASK| GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK| GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK; attributes.visual = gtk_widget_get_visual (widget); attributes.colormap = gtk_widget_get_colormap (widget); attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask); gtk_style_attach (widget->style, widget->window); gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); gdk_window_set_user_data (widget->window, widget); gtk_widget_set_double_buffered (widget, FALSE); wc = gdk_cairo_create(widget->window); g->forescore = cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR_ALPHA, widget->allocation.width, SCOREHEIGHT); g->forebutton = cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR_ALPHA, widget->allocation.width, SCOREHEIGHT); g->background = cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR, widget->allocation.width, widget->allocation.height); g->foreground = cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR, widget->allocation.width, widget->allocation.height); cairo_destroy(wc); g->vertex = cache_vertex(g); g->vertex_lit = cache_vertex_lit(g); g->vertex_attached = cache_vertex_attached(g); g->vertex_grabbed = cache_vertex_grabbed(g); g->vertex_sel = cache_vertex_sel(g); g->vertex_ghost = cache_vertex_ghost(g); update_full(g); update_score(g); draw_buttonbar_box(g); init_buttons(g); cache_curtain(g); } void gameboard_size_allocate (GtkWidget *widget, GtkAllocation *allocation){ Gameboard *g = GAMEBOARD (widget); cairo_t *wc; if (GTK_WIDGET_REALIZED (widget)){ if(allocation->width != g->resize_w && allocation->height != g->resize_h && g->resize_timeout == 0 ){ fprintf(stderr,_("\n\nERROR: The window size granted by the windowmanager is not the\n" "window size gPlanarity requested. If the windowmanager is\n" "configured to ignore application sizing requests, this stands\n" "a pretty good chance of scrambling saved boards later (and\n" "making everything look funny now).\n\n")); fprintf(stderr,_("Clipping and/or expanding this board to the current window size...\n\n")); g->resize_h=0; g->resize_w=0; } g->resize_timeout=1; if(widget->allocation.width == allocation->width && widget->allocation.height == allocation->height) return; if (g->forescore) cairo_surface_destroy(g->forescore); if (g->forebutton) cairo_surface_destroy(g->forebutton); if (g->background) cairo_surface_destroy(g->background); if (g->foreground) cairo_surface_destroy(g->foreground); if (g->curtainp) cairo_pattern_destroy(g->curtainp); if (g->curtains) cairo_surface_destroy(g->curtains); gdk_window_move_resize (widget->window, allocation->x, allocation->y, allocation->width, allocation->height); wc = gdk_cairo_create(widget->window); g->background = cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR, // don't need alpha allocation->width, allocation->height); g->forescore = cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR_ALPHA, allocation->width, SCOREHEIGHT); g->forebutton = cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR_ALPHA, allocation->width, SCOREHEIGHT); g->foreground = cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR, // don't need alpha allocation->width, allocation->height); cairo_destroy(wc); cache_curtain(g); resize_buttons(g,g->g.width, g->g.height, allocation->width, allocation->height); graph_resize(&g->g, allocation->width, allocation->height); draw_buttonbar_box(g); update_score(g); update_full(g); } widget->allocation = *allocation; } static void gameboard_class_init (GameboardClass * class) { GtkObjectClass *object_class; GtkWidgetClass *widget_class; object_class = (GtkObjectClass *) class; widget_class = (GtkWidgetClass *) class; parent_class = gtk_type_class (GTK_TYPE_WIDGET); object_class->destroy = gameboard_destroy; widget_class->realize = gameboard_realize; widget_class->expose_event = gameboard_expose; widget_class->size_request = gameboard_size_request; widget_class->size_allocate = gameboard_size_allocate; widget_class->button_press_event = mouse_press; widget_class->button_release_event = mouse_release; widget_class->motion_notify_event = mouse_motion; } GType gameboard_get_type (void){ static GType gameboard_type = 0; if (!gameboard_type) { static const GTypeInfo gameboard_info = { sizeof (GameboardClass), NULL, NULL, (GClassInitFunc) gameboard_class_init, NULL, NULL, sizeof (Gameboard), 0, (GInstanceInitFunc) gameboard_init, 0 }; gameboard_type = g_type_register_static (GTK_TYPE_WIDGET, "Gameboard", &gameboard_info, 0); } return gameboard_type; } Gameboard *gameboard_new (void) { GtkWidget *g = GTK_WIDGET (g_object_new (GAMEBOARD_TYPE, NULL)); Gameboard *gb = GAMEBOARD (g); return gb; } gplanarity-17906/po/0000755000175000017500000000000011543161637014237 5ustar vincentvincentgplanarity-17906/po/gPlanarity.pot0000644000175000017500000002120711543161637017077 0ustar vincentvincent# SOME DESCRIPTIVE TITLE. # Copyright (C) 2007 Monty # This file is distributed under the same license as the gPlanarity package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: Monty \n" "POT-Creation-Date: 2009-11-25 02:29-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" # # File: ../dialog_finish.c, line: 80 # File: ../dialog_level.c, line: 67 # File: ../dialog_pause.c, line: 67 # File: ../gameboard_logic_buttonbar.c, line: 54 msgid "exit gPlanarity" msgstr "" # # File: ../dialog_finish.c, line: 81 # File: ../gameboard_logic_buttonbar.c, line: 55 msgid "level selection menu" msgstr "" # # File: ../dialog_finish.c, line: 82 msgid "play next level!" msgstr "" # # File: ../dialog_finish.c, line: 160 msgid "Level Complete!" msgstr "" # # File: ../dialog_finish.c, line: 164 #, c-format msgid "Elapsed: %s" msgstr "" # # File: ../dialog_finish.c, line: 168 #, c-format msgid "Base score: %d points" msgstr "" # # File: ../dialog_finish.c, line: 176 #, c-format msgid "Objective Exceeded! %d%%" msgstr "" # # File: ../dialog_finish.c, line: 181 #, c-format msgid "Time bonus: %d points" msgstr "" # # File: ../dialog_finish.c, line: 186 #, c-format msgid "Final score: %d points" msgstr "" # # File: ../dialog_finish.c, line: 191 msgid "A high score!" msgstr "" # # File: ../dialog_finish.c, line: 194 #, c-format msgid "Previous best: %ld points" msgstr "" # # File: ../dialog_finish.c, line: 199 msgid "Total score to date:" msgstr "" # # File: ../dialog_finish.c, line: 201 #, c-format msgid "%ld points" msgstr "" # # File: ../dialog_level.c, line: 68 msgid "reset level" msgstr "" # # File: ../dialog_level.c, line: 69 msgid "play level!" msgstr "" # # File: ../dialog_level.c, line: 139 msgid "Available Levels" msgstr "" # # File: ../dialog_level_icons.c, line: 246 #, c-format msgid "Level %d:" msgstr "" # # File: ../dialog_level_icons.c, line: 264 #, c-format msgid "[not yet completed]" msgstr "" # # File: ../dialog_level_icons.c, line: 267 #, c-format msgid "level high score: %ld" msgstr "" # # File: ../dialog_level_icons.c, line: 277 #, c-format msgid "total score all levels: %ld" msgstr "" # # File: ../dialog_pause.c, line: 68 msgid "resume game!" msgstr "" # # File: ../dialog_pause.c, line: 131 msgid "Game Paused" msgstr "" # # File: ../dialog_pause.c, line: 134 msgid "Time Elapsed:" msgstr "" # # File: ../dialog_pause.c, line: 186 msgid "gPlanarity" msgstr "" # # File: ../dialog_pause.c, line: 190 msgid "Untangle the mess!" msgstr "" # # File: ../dialog_pause.c, line: 194 msgid "Drag vertices to eliminate crossed lines." msgstr "" # # File: ../dialog_pause.c, line: 195 msgid "The objective may be a complete solution or" msgstr "" # # File: ../dialog_pause.c, line: 196 msgid "getting as close as possible to solving an" msgstr "" # # File: ../dialog_pause.c, line: 197 msgid "unsolvable puzzle. Work quickly and" msgstr "" # # File: ../dialog_pause.c, line: 198 msgid "exceed the objective for bonus points!" msgstr "" # # File: ../dialog_pause.c, line: 207 msgid "gPlanarity written by Monty " msgstr "" # # File: ../dialog_pause.c, line: 208 msgid "as a demonstration of Gtk+/Cairo" msgstr "" # # File: ../dialog_pause.c, line: 210 msgid "Original Flash version of Planarity by" msgstr "" # # File: ../dialog_pause.c, line: 211 msgid "John Tantalo " msgstr "" # # File: ../dialog_pause.c, line: 213 msgid "Original game concept by Mary Radcliffe" msgstr "" # # File: ../gameboard.c, line: 75 #, c-format msgid "" "\n" "\n" "ERROR: The windowmanager appears to be ignoring resize requests.\n" "This stands a pretty good chance of scrambling any saved board larger\n" "than the default window size.\n" "\n" msgstr "" # # File: ../gameboard.c, line: 78 # File: ../gameboard.c, line: 189 #, c-format msgid "" "Clipping and/or expanding this board to the current window size...\n" "\n" msgstr "" # # File: ../gameboard.c, line: 184 #, c-format msgid "" "\n" "\n" "ERROR: The window size granted by the windowmanager is not the\n" "window size gPlanarity requested. If the windowmanager is\n" "configured to ignore application sizing requests, this stands\n" "a pretty good chance of scrambling saved boards later (and\n" "making everything look funny now).\n" "\n" msgstr "" # # File: ../gameboard_draw_intersection.c, line: 65 msgid "rather many, really" msgstr "" # # File: ../gameboard_draw_main.c, line: 370 #, c-format msgid "ERROR: Could not load board icon \"%s\"\n" msgstr "" # # File: ../gameboard_draw_main.c, line: 436 #, c-format msgid "ERROR: Could not save board icon \"%s\"\n" msgstr "" # # File: ../gameboard_draw_score.c, line: 67 #, c-format msgid "Level %d: %s" msgstr "" # # File: ../gameboard_draw_score.c, line: 68 #, c-format msgid "Score: %d" msgstr "" # # File: ../gameboard_draw_score.c, line: 69 #, c-format msgid "%d%%" msgstr "" # # File: ../gameboard_draw_score.c, line: 70 #, c-format msgid "Intersections: %ld" msgstr "" # # File: ../gameboard_draw_score.c, line: 71 #, c-format msgid "Objective: %s" msgstr "" # # File: ../gameboard_logic_buttonbar.c, line: 56 msgid "reset board" msgstr "" # # File: ../gameboard_logic_buttonbar.c, line: 57 msgid "pause" msgstr "" # # File: ../gameboard_logic_buttonbar.c, line: 58 msgid "help / about" msgstr "" # # File: ../gameboard_logic_buttonbar.c, line: 59 msgid "expand" msgstr "" # # File: ../gameboard_logic_buttonbar.c, line: 60 msgid "shrink" msgstr "" # # File: ../gameboard_logic_buttonbar.c, line: 61 msgid "hide/show lines" msgstr "" # # File: ../gameboard_logic_buttonbar.c, line: 62 msgid "mark intersections" msgstr "" # # File: ../gameboard_logic_buttonbar.c, line: 63 msgid "click when finished!" msgstr "" # # File: ../gameboard_logic.c, line: 371 #, c-format msgid "" "ERROR: Could not save board state for \"%s\":\n" "\t%s\n" msgstr "" # # File: ../gameboard_logic.c, line: 401 #, c-format msgid "" "ERROR: Could not read saved board state for \"%s\":\n" "\t%s\n" msgstr "" # # File: ../graph.c, line: 923 #, c-format msgid "WARNING: edge references out of range vertex in save file\n" msgstr "" # # File: ../graph_generate.c, line: 196 # File: ../graph_generate.c, line: 215 #, c-format msgid "Couldn't allocate memory for level name.\n" msgstr "" # # File: ../graph_generate.c, line: 210 #, c-format msgid "Couldn't allocate memory for level description.\n" msgstr "" # # File: ../graph_region.c, line: 459 #, c-format msgid "" "region overlap adjustment failed in arc_arc_adj; \n" " This is an internal error that should never happen.\n" msgstr "" # # File: ../graph_score.c, line: 67 msgid "zero intersections" msgstr "" # # File: ../graph_score.c, line: 70 msgid "1 intersection or fewer" msgstr "" # # File: ../graph_score.c, line: 72 msgid "1 intersection" msgstr "" # # File: ../graph_score.c, line: 75 #, c-format msgid "%d intersections%s" msgstr "" # # File: ../graph_score.c, line: 77 msgid " or fewer" msgstr "" # # File: ../levelstate.c, line: 169 #, c-format msgid "" "ERROR: Could not save game state file \"%s\":\n" "\t%s\n" msgstr "" # # File: ../levelstate.c, line: 216 #, c-format msgid "" "ERROR: Could not read game state file \"%s\":\n" "\t%s\n" msgstr "" # # File: ../main.c, line: 73 #, c-format msgid "" "ERROR: Could not create directory (%s) to save game state:\n" "\t%s\n" msgstr "" # # File: ../main.c, line: 93 #, c-format msgid "" "\n" "Trapped signal %d; saving state and exiting!\n" msgstr "" # # File: ../main.c, line: 146 #, c-format msgid "" "\n" "Unable to find any suitable %s fonts!\n" "Continuing, but the the results are likely to be poor.\n" "\n" msgstr "" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "bold italic" msgstr "" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "italic" msgstr "" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "bold" msgstr "" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "medium" msgstr "" # # File: ../main.c, line: 164 #, c-format msgid "" "\n" "Selected %s font \"%s\" is not scalable! This is almost as bad\n" "as not finding any font at all. Continuing, but this may look\n" "very poor indeed.\n" "\n" msgstr "" # # File: ../main.c, line: 288 #, c-format msgid "" "No homedir environment variable set! gPlanarity will be\n" "unable to permanently save any progress or board state.\n" msgstr "" # # File: ../timer.c, line: 51 #, c-format msgid "%d:%02d:%02d" msgstr "" # # File: ../timer.c, line: 53 #, c-format msgid "%d:%02d" msgstr "" # # File: ../timer.c, line: 55 #, c-format msgid "%d seconds" msgstr "" gplanarity-17906/po/ca.po0000644000175000017500000002753411543161637015175 0ustar vincentvincent# Gplanarity catalan translation. # Copyright (C) 2007 Monty # This file is distributed under the same license as the gPlanarity package. # Àngel Mompó , 2010. # msgid "" msgstr "" "Project-Id-Version: 16723\n" "Report-Msgid-Bugs-To: Monty \n" "POT-Creation-Date: 2009-12-11 14:15-0500\n" "PO-Revision-Date: 2010-11-27 12:01+0100\n" "Last-Translator: Àngel Mompó \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ca_ES\n" "Plural-Forms: nplurals=2; plural=n != 1\n" # # File: ../dialog_finish.c, line: 80 # File: ../dialog_level.c, line: 67 # File: ../dialog_pause.c, line: 67 # File: ../gameboard_logic_buttonbar.c, line: 54 msgid "exit gPlanarity" msgstr "surt del gPlanarity" # # File: ../dialog_finish.c, line: 81 # File: ../gameboard_logic_buttonbar.c, line: 55 msgid "level selection menu" msgstr "menú de selecció del nivell" # # File: ../dialog_finish.c, line: 82 msgid "play next level!" msgstr "Juga al següent nivell!" # # File: ../dialog_finish.c, line: 160 msgid "Level Complete!" msgstr "Nivell completat!" # # File: ../dialog_finish.c, line: 164 #, c-format msgid "Elapsed: %s" msgstr "Transcorregut: %s" # # File: ../dialog_finish.c, line: 168 #, c-format msgid "Base score: %d points" msgstr "Puntuació base: %d punts" # # File: ../dialog_finish.c, line: 176 #, c-format msgid "Objective Exceeded! %d%%" msgstr "Objectiu superat! %d%%" # # File: ../dialog_finish.c, line: 181 #, c-format msgid "Time bonus: %d points" msgstr "Bonificació de temps: %d punts" # # File: ../dialog_finish.c, line: 186 #, c-format msgid "Final score: %d points" msgstr "Puntuació final: %d punts" # # File: ../dialog_finish.c, line: 191 msgid "A high score!" msgstr "És un rècord!" # # File: ../dialog_finish.c, line: 194 #, c-format msgid "Previous best: %ld points" msgstr "Rècord anterior: %ld punts" # # File: ../dialog_finish.c, line: 199 msgid "Total score to date:" msgstr "Puntuació total:" # # File: ../dialog_finish.c, line: 201 #, c-format msgid "%ld points" msgstr "%ld punts" # # File: ../dialog_level.c, line: 68 msgid "reset level" msgstr "Torna a iniciar el nivell" # # File: ../dialog_level.c, line: 69 msgid "play level!" msgstr "Juga el nivell!" # # File: ../dialog_level.c, line: 139 msgid "Available Levels" msgstr "Nivells disponibles" # # File: ../dialog_level_icons.c, line: 246 #, c-format msgid "Level %d:" msgstr "Nivell %d:" # # File: ../dialog_level_icons.c, line: 264 #, c-format msgid "[not yet completed]" msgstr "[encara no l'heu completat]" # # File: ../dialog_level_icons.c, line: 267 #, c-format msgid "level high score: %ld" msgstr "rècord del nivell: %ld" # # File: ../dialog_level_icons.c, line: 277 #, c-format msgid "total score all levels: %ld" msgstr "puntuació total sumant tots els nivells: %ld" # # File: ../dialog_pause.c, line: 68 msgid "resume game!" msgstr "continueu jugant!" # # File: ../dialog_pause.c, line: 131 msgid "Game Paused" msgstr "Joc en pausa" # # File: ../dialog_pause.c, line: 134 msgid "Time Elapsed:" msgstr "Temps transcorregut:" # # File: ../dialog_pause.c, line: 186 msgid "gPlanarity" msgstr "gPlanarity" # # File: ../dialog_pause.c, line: 190 msgid "Untangle the mess!" msgstr "Desfés l'embolic!" # # File: ../dialog_pause.c, line: 194 msgid "Drag vertices to eliminate crossed lines." msgstr "Arrossegueu els vèrtex per desfer els encreuaments." # # File: ../dialog_pause.c, line: 195 msgid "The objective may be a complete solution or" msgstr "L'objectiu ha de ser una solució completa o" # # File: ../dialog_pause.c, line: 196 msgid "getting as close as possible to solving an" msgstr "estar-hi tant a prop com sigui possible en un" # # File: ../dialog_pause.c, line: 197 msgid "unsolvable puzzle. Work quickly and" msgstr "puzle sense solució. Aneu de pressa i" # # File: ../dialog_pause.c, line: 198 msgid "exceed the objective for bonus points!" msgstr "supereu l'objectiu per obtenir una bonificació!" # # File: ../dialog_pause.c, line: 207 msgid "gPlanarity written by Monty " msgstr "El gPlanarity ha estat escrit per Monty " # # File: ../dialog_pause.c, line: 208 msgid "as a demonstration of Gtk+/Cairo" msgstr "com a demostració del GTK+/Cairo" # # File: ../dialog_pause.c, line: 210 msgid "Original Flash version of Planarity by" msgstr "La versió en Flash original és de" # # File: ../dialog_pause.c, line: 211 msgid "John Tantalo " msgstr "John Tantalo " # # File: ../dialog_pause.c, line: 213 msgid "Original game concept by Mary Radcliffe" msgstr "El concepte original és de Mary Radcliffe" # # File: ../gameboard.c, line: 75 #, c-format msgid "" "\n" "\n" "ERROR: The windowmanager appears to be ignoring resize requests.\n" "This stands a pretty good chance of scrambling any saved board larger\n" "than the default window size.\n" "\n" msgstr "" "\n" "\n" "Error: El gestor de finestres sembla que ignora les peticions de canvi de " "mida.\n" "El més probable és que s'estigui intentant descodificar un tauler desat \n" "més gran que la mida de la finestra per defecte.\n" # # File: ../gameboard.c, line: 78 # File: ../gameboard.c, line: 189 #, c-format msgid "" "Clipping and/or expanding this board to the current window size...\n" "\n" msgstr "Retallant i/o expandint el tauler a la mida actual de la finestra...\n" # # File: ../gameboard.c, line: 184 #, c-format msgid "" "\n" "\n" "ERROR: The window size granted by the windowmanager is not the\n" "window size gPlanarity requested. If the windowmanager is\n" "configured to ignore application sizing requests, this stands\n" "a pretty good chance of scrambling saved boards later (and\n" "making everything look funny now).\n" "\n" msgstr "" "\n" "\n" "ERROR: La mida de la finestra que pot oferir el gestor de finestres no és\n" "la mida que ha demanat el gPlanarity. Si el gestor de finestres està\n" "configurat per ignorar les peticions de mida, el més probable és que\n" "es barregin els taulers desats (i fa que ara tot es vegi divertit).\n" "\n" # # File: ../gameboard_draw_intersection.c, line: 65 msgid "rather many, really" msgstr "N'hi ha masses" # # File: ../gameboard_draw_main.c, line: 370 #, c-format msgid "ERROR: Could not load board icon \"%s\"\n" msgstr "ERROR: No es pot carregar la icona del tauler «%s»\n" # # File: ../gameboard_draw_main.c, line: 436 #, c-format msgid "ERROR: Could not save board icon \"%s\"\n" msgstr "ERROR: No es pot desar la icona del tauler «%s»\n" # # File: ../gameboard_draw_score.c, line: 67 #, c-format msgid "Level %d: %s" msgstr "Nivell %d: %s" # # File: ../gameboard_draw_score.c, line: 68 #, c-format msgid "Score: %d" msgstr "Puntuació: %d" # # File: ../gameboard_draw_score.c, line: 69 #, c-format msgid "%d%%" msgstr "%d%%" # # File: ../gameboard_draw_score.c, line: 70 #, c-format msgid "Intersections: %ld" msgstr "Interseccions: %ld" # # File: ../gameboard_draw_score.c, line: 71 #, c-format msgid "Objective: %s" msgstr "Objectiu: %s" # # File: ../gameboard_logic_buttonbar.c, line: 56 msgid "reset board" msgstr "torna a iniciar el taulell" # # File: ../gameboard_logic_buttonbar.c, line: 57 msgid "pause" msgstr "pausa" # # File: ../gameboard_logic_buttonbar.c, line: 58 msgid "help / about" msgstr "ajuda / quant a" # # File: ../gameboard_logic_buttonbar.c, line: 59 msgid "expand" msgstr "expandeix" # # File: ../gameboard_logic_buttonbar.c, line: 60 msgid "shrink" msgstr "encongeix" # # File: ../gameboard_logic_buttonbar.c, line: 61 msgid "hide/show lines" msgstr "mostra/amaga les línies" # # File: ../gameboard_logic_buttonbar.c, line: 62 msgid "mark intersections" msgstr "marca les interseccions" # # File: ../gameboard_logic_buttonbar.c, line: 63 msgid "click when finished!" msgstr "cliqueu quan acabeu!" # # File: ../gameboard_logic.c, line: 371 #, c-format msgid "" "ERROR: Could not save board state for \"%s\":\n" "\t%s\n" msgstr "" "ERROR: No es pot desar l'estat del tauler per «%s»:\n" "\t%s\n" # # File: ../gameboard_logic.c, line: 401 #, c-format msgid "" "ERROR: Could not read saved board state for \"%s\":\n" "\t%s\n" msgstr "" "ERROR: No es pot llegir l'estat del tauler per «%s»:\n" "\t%s\n" # # File: ../graph.c, line: 923 #, c-format msgid "WARNING: edge references out of range vertex in save file\n" msgstr "" "AVÍS: referències de les cantonades fora del rang dels vèrtex al fitxer " "desat\n" "\n" # # File: ../graph_generate.c, line: 196 # File: ../graph_generate.c, line: 215 #, c-format msgid "Couldn't allocate memory for level name.\n" msgstr "No es pot assignar memòria pel nom del nivell.\n" # # File: ../graph_generate.c, line: 210 #, c-format msgid "Couldn't allocate memory for level description.\n" msgstr "No es pot assignar memòria per la descripció del nivell.\n" # # File: ../graph_region.c, line: 459 #, c-format msgid "" "region overlap adjustment failed in arc_arc_adj; \n" " This is an internal error that should never happen.\n" msgstr "" "ha fallat l'ajust del sobreposat de la regió a arc_arc_adj; \n" " És un error intern que no hauria de passar mai.\n" # # File: ../graph_score.c, line: 67 msgid "zero intersections" msgstr "zero interseccions" # # File: ../graph_score.c, line: 70 msgid "1 intersection or fewer" msgstr "1 intersecció o menys" # # File: ../graph_score.c, line: 72 msgid "1 intersection" msgstr "1 intersecció" # # File: ../graph_score.c, line: 75 #, c-format msgid "%d intersections%s" msgstr "%d interseccions%s" # # File: ../graph_score.c, line: 77 msgid " or fewer" msgstr " o menys" # # File: ../levelstate.c, line: 169 #, c-format msgid "" "ERROR: Could not save game state file \"%s\":\n" "\t%s\n" msgstr "" "ERROR: No es pot desar el fitxer d'estat del joc «%s»:\n" "\t%s\n" # # File: ../levelstate.c, line: 216 #, c-format msgid "" "ERROR: Could not read game state file \"%s\":\n" "\t%s\n" msgstr "" "ERROR: No es pot llegir el fitxer d'estat del joc «%s»:\n" "\t%s\n" # # File: ../main.c, line: 73 #, c-format msgid "" "ERROR: Could not create directory (%s) to save game state:\n" "\t%s\n" msgstr "" "ERROR: No es pot crear el directori (%s) per desar l'estat del joc:\n" "\t%s\n" # # File: ../main.c, line: 93 #, c-format msgid "" "\n" "Trapped signal %d; saving state and exiting!\n" msgstr "" "\n" "S'ha atrapat el senyal %d. Deso l'estat i surto!\n" # # File: ../main.c, line: 146 #, c-format msgid "" "\n" "Unable to find any suitable %s fonts!\n" "Continuing, but the the results are likely to be poor.\n" "\n" msgstr "" "\n" "No es pot trobar cap font %s disponible!\n" "Continuo, però el resultat podria ser pobre.\n" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "bold italic" msgstr "negreta cursiva" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "italic" msgstr "cursiva" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "bold" msgstr "negreta" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "medium" msgstr "normal" # # File: ../main.c, line: 164 #, c-format msgid "" "\n" "Selected %s font \"%s\" is not scalable! This is almost as bad\n" "as not finding any font at all. Continuing, but this may look\n" "very poor indeed.\n" "\n" msgstr "" "\n" "La font %s seleccionada «%s» no es pot escalar! això és tant dolent\n" "com no trobar cap font. Continuo, però es veurà molt pobre.\n" "\n" # # File: ../main.c, line: 288 #, c-format msgid "" "No homedir environment variable set! gPlanarity will be\n" "unable to permanently save any progress or board state.\n" msgstr "" "No està declarada la variable homedir! gPlanarity no podrà\n" "desar el progrés o l'estat del tauler de manera permanent.\n" # # File: ../timer.c, line: 51 #, c-format msgid "%d:%02d:%02d" msgstr "%d:%02d:%02d" # # File: ../timer.c, line: 53 #, c-format msgid "%d:%02d" msgstr "%d:%02d" # # File: ../timer.c, line: 55 #, c-format msgid "%d seconds" msgstr "%d segons" gplanarity-17906/po/de.po0000644000175000017500000003014211543161637015167 0ustar vincentvincent# SOME DESCRIPTIVE TITLE. # Copyright (C) 2007 Monty # This file is distributed under the same license as the gPlanarity package. # FIRST AUTHOR , YEAR. # Nuke System , 2011. # msgid "" msgstr "" "Project-Id-Version: 16723\n" "Report-Msgid-Bugs-To: Monty \n" "POT-Creation-Date: 2009-11-25 02:29-0500\n" "PO-Revision-Date: 2011-03-13 15:08+0100\n" "Last-Translator: Nuke System \n" "Language-Team: deutsch <>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" # # File: ../dialog_finish.c, line: 80 # File: ../dialog_level.c, line: 67 # File: ../dialog_pause.c, line: 67 # File: ../gameboard_logic_buttonbar.c, line: 54 msgid "exit gPlanarity" msgstr "gPlanarity verlassen" # # File: ../dialog_finish.c, line: 81 # File: ../gameboard_logic_buttonbar.c, line: 55 msgid "level selection menu" msgstr "Auswahl des Spielabschnitts" # # File: ../dialog_finish.c, line: 82 msgid "play next level!" msgstr "nächsten Abschnitt spielen!" # # File: ../dialog_finish.c, line: 160 msgid "Level Complete!" msgstr "Abschnitt gelöst!" # # File: ../dialog_finish.c, line: 164 #, c-format msgid "Elapsed: %s" msgstr "Verstrichen: %s" # # File: ../dialog_finish.c, line: 168 #, c-format msgid "Base score: %d points" msgstr "Grundbonus: %d Punkte" # # File: ../dialog_finish.c, line: 176 #, c-format msgid "Objective Exceeded! %d%%" msgstr "Ziel übertroffen! %d%%" # # File: ../dialog_finish.c, line: 181 #, c-format msgid "Time bonus: %d points" msgstr "Zeitbonus: %d Punkte" # # File: ../dialog_finish.c, line: 186 #, c-format msgid "Final score: %d points" msgstr "Endstand: %d Punkte" # # File: ../dialog_finish.c, line: 191 msgid "A high score!" msgstr "Ein Höchststand!" # # File: ../dialog_finish.c, line: 194 #, c-format msgid "Previous best: %ld points" msgstr "Voriger bester: %ld Punkte" # # File: ../dialog_finish.c, line: 199 msgid "Total score to date:" msgstr "Bisheriger Gesamtpunktestand:" # # File: ../dialog_finish.c, line: 201 #, c-format msgid "%ld points" msgstr "%ld Punkte" # # File: ../dialog_level.c, line: 68 msgid "reset level" msgstr "Abschnitt zurücksetzen" # # File: ../dialog_level.c, line: 69 msgid "play level!" msgstr "Abschnitt spielen!" # # File: ../dialog_level.c, line: 139 msgid "Available Levels" msgstr "Verfügbare Abschnitte" # # File: ../dialog_level_icons.c, line: 246 #, c-format msgid "Level %d:" msgstr "Abschnitt %d:" # # File: ../dialog_level_icons.c, line: 264 #, c-format msgid "[not yet completed]" msgstr "[noch ungelöst]" # # File: ../dialog_level_icons.c, line: 267 #, c-format msgid "level high score: %ld" msgstr "Abschnittshöchststand: %ld" # # File: ../dialog_level_icons.c, line: 277 #, c-format msgid "total score all levels: %ld" msgstr "Gesamtpunktestand für alle Abschnitte: %ld" # # File: ../dialog_pause.c, line: 68 msgid "resume game!" msgstr "Spiel fortsetzen!" # # File: ../dialog_pause.c, line: 131 msgid "Game Paused" msgstr "Spiel pausiert" # # File: ../dialog_pause.c, line: 134 msgid "Time Elapsed:" msgstr "Verstrichene Zeit:" # # File: ../dialog_pause.c, line: 186 msgid "gPlanarity" msgstr "gPlanarity" # # File: ../dialog_pause.c, line: 190 msgid "Untangle the mess!" msgstr "Entwirre das Durcheinander!" # # File: ../dialog_pause.c, line: 194 msgid "Drag vertices to eliminate crossed lines." msgstr "Verschiebe Knoten um Linienüberscheidungen zu beseitigen." # # File: ../dialog_pause.c, line: 195 msgid "The objective may be a complete solution or" msgstr "Das Ziel kann eine vollständige Lösung oder bei" # # File: ../dialog_pause.c, line: 196 msgid "getting as close as possible to solving an" msgstr "unlösbaren Puzzles eine möglichst vollständige" # # File: ../dialog_pause.c, line: 197 msgid "unsolvable puzzle. Work quickly and" msgstr "Lösung sein. Sei schnell und übertreffe die Zeit-" # # File: ../dialog_pause.c, line: 198 msgid "exceed the objective for bonus points!" msgstr "vorgabe um Bonuspunkte zu erhalten!" # # File: ../dialog_pause.c, line: 207 msgid "gPlanarity written by Monty " msgstr "gPlanarity wurde geschrieben von Monty " # # File: ../dialog_pause.c, line: 208 msgid "as a demonstration of Gtk+/Cairo" msgstr "als eine Demonstration von GTK+/Cairo." # # File: ../dialog_pause.c, line: 210 msgid "Original Flash version of Planarity by" msgstr "Die ursprüngliche Flash-Version von Planarity stammt" # # File: ../dialog_pause.c, line: 211 msgid "John Tantalo " msgstr "von John Tantalo " # # File: ../dialog_pause.c, line: 213 msgid "Original game concept by Mary Radcliffe" msgstr "Ursprüngliches Spielkonzept von Mary Radcliffe" # # File: ../gameboard.c, line: 75 #, c-format msgid "" "\n" "\n" "ERROR: The windowmanager appears to be ignoring resize requests.\n" "This stands a pretty good chance of scrambling any saved board larger\n" "than the default window size.\n" "\n" msgstr "" "\n" "\n" "FEHLER: Die Fensterverwaltung scheint Anfragen zur Änderung der\n" "Fenstergröße zu ignorieren. Dies bringt möglicherweise gespeicherte\n" "Aufstellungen durcheinander, die größer als die Vorgabefenstergröße sind.\n" "\n" # # File: ../gameboard.c, line: 78 # File: ../gameboard.c, line: 189 #, c-format msgid "" "Clipping and/or expanding this board to the current window size...\n" "\n" msgstr "" "Beschneide und/oder erweitere Spielbrett auf derzeitige Fenstergröße...\n" "\n" # # File: ../gameboard.c, line: 184 #, fuzzy, c-format msgid "" "\n" "\n" "ERROR: The window size granted by the windowmanager is not the\n" "window size gPlanarity requested. If the windowmanager is\n" "configured to ignore application sizing requests, this stands\n" "a pretty good chance of scrambling saved boards later (and\n" "making everything look funny now).\n" "\n" msgstr "" "\n" "\n" "FEHLER: Die von der Fensterverwaltung gewährte Fenstergröße\n" "entspricht nicht der angeforderten. Sollte die Fensterverwaltung\n" "eingestellt sein, die Größenangaben der Anwendung zu übergehen,\n" "so sind spätere Störungen in gespeicherten Aufstellungen\n" "wahrscheinlich (und jetzt ein seltsames Aussehen).\n" "\n" # # File: ../gameboard_draw_intersection.c, line: 65 msgid "rather many, really" msgstr "ziemlich viele" # # File: ../gameboard_draw_main.c, line: 370 #, c-format msgid "ERROR: Could not load board icon \"%s\"\n" msgstr "FEHLER: Konnte Aufstellungsvorschau \"%s\" nicht laden\n" # # File: ../gameboard_draw_main.c, line: 436 #, c-format msgid "ERROR: Could not save board icon \"%s\"\n" msgstr "FEHLER: Konnte Aufstellungsvorschau \"%s\" nicht speichern\n" # # File: ../gameboard_draw_score.c, line: 67 #, c-format msgid "Level %d: %s" msgstr "Abschnitt %d: %s" # # File: ../gameboard_draw_score.c, line: 68 #, c-format msgid "Score: %d" msgstr "Punktestand: %d" # # File: ../gameboard_draw_score.c, line: 69 #, c-format msgid "%d%%" msgstr "%d%%" # # File: ../gameboard_draw_score.c, line: 70 #, c-format msgid "Intersections: %ld" msgstr "Überschneidungen: %ld" # # File: ../gameboard_draw_score.c, line: 71 #, c-format msgid "Objective: %s" msgstr "Ziel: %s" # # File: ../gameboard_logic_buttonbar.c, line: 56 msgid "reset board" msgstr "Aufstellung zurücksetzen" # # File: ../gameboard_logic_buttonbar.c, line: 57 msgid "pause" msgstr "Pause" # # File: ../gameboard_logic_buttonbar.c, line: 58 msgid "help / about" msgstr "Hilfe / Über" # # File: ../gameboard_logic_buttonbar.c, line: 59 msgid "expand" msgstr "ausdehnen" # # File: ../gameboard_logic_buttonbar.c, line: 60 msgid "shrink" msgstr "schrumpfen" # # File: ../gameboard_logic_buttonbar.c, line: 61 msgid "hide/show lines" msgstr "verberge/zeige Linien" # # File: ../gameboard_logic_buttonbar.c, line: 62 msgid "mark intersections" msgstr "markiere Überschneidungen" # # File: ../gameboard_logic_buttonbar.c, line: 63 msgid "click when finished!" msgstr "klicke wenn fertig!" # # File: ../gameboard_logic.c, line: 371 #, c-format msgid "" "ERROR: Could not save board state for \"%s\":\n" "\t%s\n" msgstr "" "FEHLER: Konnte Spielbrettstatus nicht speichern für \"%s\":\n" "\t%s\n" # # File: ../gameboard_logic.c, line: 401 #, c-format msgid "" "ERROR: Could not read saved board state for \"%s\":\n" "\t%s\n" msgstr "" "FEHLER: Konnte gespeicherten Spielbrettstatus nicht lesen für \"%s\":\n" "\t%s\n" # # File: ../graph.c, line: 923 #, fuzzy, c-format msgid "WARNING: edge references out of range vertex in save file\n" msgstr "" "WARNUNG: Kante referenziert Knoten jenseits darstellbaren\n" "Bereichs in Speicherdatei\n" # # File: ../graph_generate.c, line: 196 # File: ../graph_generate.c, line: 215 #, c-format msgid "Couldn't allocate memory for level name.\n" msgstr "Konnte Speicher für Abschnittsname nicht belegen.\n" # # File: ../graph_generate.c, line: 210 #, c-format msgid "Couldn't allocate memory for level description.\n" msgstr "Konnte Speicher für Abschnittsbeschreibung nicht belegen.\n" # # File: ../graph_region.c, line: 459 #, fuzzy, c-format msgid "" "region overlap adjustment failed in arc_arc_adj; \n" " This is an internal error that should never happen.\n" msgstr "" "Anpassung der Überlappung von Regionen schlug fehl in arc_arc_adj;\n" "Dies ist ein interner Fehler, der nie vorkommen sollte.\n" # # File: ../graph_score.c, line: 67 msgid "zero intersections" msgstr "keine Überschneidungen" # # File: ../graph_score.c, line: 70 msgid "1 intersection or fewer" msgstr "1 Überschneidung oder weniger" # # File: ../graph_score.c, line: 72 msgid "1 intersection" msgstr "1 Überschneidung" # # File: ../graph_score.c, line: 75 #, c-format msgid "%d intersections%s" msgstr "%d Überschneidungen%s" # # File: ../graph_score.c, line: 77 msgid " or fewer" msgstr " oder weniger" # # File: ../levelstate.c, line: 169 #, c-format msgid "" "ERROR: Could not save game state file \"%s\":\n" "\t%s\n" msgstr "" "FEHLER: Konnte Spielstanddatei \"%s\" nicht speichern:\n" "\t%s\n" # # File: ../levelstate.c, line: 216 #, c-format msgid "" "ERROR: Could not read game state file \"%s\":\n" "\t%s\n" msgstr "" "FEHLER: Konnte Spielstanddatei \"%s\" nicht lesen:\n" "\t%s\n" # # File: ../main.c, line: 73 #, c-format msgid "" "ERROR: Could not create directory (%s) to save game state:\n" "\t%s\n" msgstr "" "FEHLER: Konnte Verzeichnis (%s) zum Speichern des Spielstandes nicht " "anlegen:\n" "\t%s\n" # # File: ../main.c, line: 93 #, c-format msgid "" "\n" "Trapped signal %d; saving state and exiting!\n" msgstr "" "\n" "Signal %d empfangen; speichere Status und beende!\n" # # File: ../main.c, line: 146 #, c-format msgid "" "\n" "Unable to find any suitable %s fonts!\n" "Continuing, but the the results are likely to be poor.\n" "\n" msgstr "" "\n" "Kann keine passenden %s-Schriftarten finden!\n" "Setze fort, doch armselige Ergebnisse sind zu erwarten.\n" "\n" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "bold italic" msgstr "fett kursiv" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "italic" msgstr "kursiv" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "bold" msgstr "fett" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 #, fuzzy msgid "medium" msgstr "mittel" # # File: ../main.c, line: 164 #, fuzzy, c-format msgid "" "\n" "Selected %s font \"%s\" is not scalable! This is almost as bad\n" "as not finding any font at all. Continuing, but this may look\n" "very poor indeed.\n" "\n" msgstr "" "\n" "Gewählte %s-Schriftart \"%s\" ist nicht skalierbar! Das ist\n" "fast so schlecht wie überhaupt keine. Fahre fort, obwohl\n" "es tatsächlich sehr armselig aussehen könnte.\n" "\n" # # File: ../main.c, line: 288 #, c-format msgid "" "No homedir environment variable set! gPlanarity will be\n" "unable to permanently save any progress or board state.\n" msgstr "" "Es wurde kein Basisverzeichnis angegeben! gPlanarity wird\n" "Fortschritte und Aufstellungen nicht dauerhaft speichern können.\n" # # File: ../timer.c, line: 51 #, c-format msgid "%d:%02d:%02d" msgstr "%d:%02d:%02d" # # File: ../timer.c, line: 53 #, c-format msgid "%d:%02d" msgstr "%d:%02d" # # File: ../timer.c, line: 55 #, c-format msgid "%d seconds" msgstr "%d Sekunden" gplanarity-17906/po/cs.po0000644000175000017500000002057211543161637015212 0ustar vincentvincent# Czech translation for gPlanarity # Copyright (C) 2007 # This file is distributed under the same license as the gPlanarity package. # Petr Pisar , 2007 # msgid "" msgstr "" "Project-Id-Version: gPlanarity 11496\n" "Report-Msgid-Bugs-To: Monty \n" "POT-Creation-Date: 2009-11-25 02:29-0500\n" "PO-Revision-Date: 2007-05-15 17:58+0200\n" "Last-Translator: Petr Pisar \n" "Language-Team: Czech \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "exit gPlanarity" msgstr "ukončit gPlanarity" msgid "level selection menu" msgstr "nabídka výběru kol" #, fuzzy msgid "play next level!" msgstr "hrát kolo!" msgid "Level Complete!" msgstr "Kolo hotovo!" #, c-format msgid "Elapsed: %s" msgstr "Uplynulo: %s" #, c-format msgid "Base score: %d points" msgstr "Základní skóre: %d bodů" #, c-format msgid "Objective Exceeded! %d%%" msgstr "Úkol překonán! %d%%" #, c-format msgid "Time bonus: %d points" msgstr "Časový bonus: %d bodů" #, c-format msgid "Final score: %d points" msgstr "Konečné skóre: %d bodů" msgid "A high score!" msgstr "Rekord!" #, c-format msgid "Previous best: %ld points" msgstr "Předchozí nejlepší: %ld bodů" msgid "Total score to date:" msgstr "Celkové skóre k datu:" #, c-format msgid "%ld points" msgstr "%ld bodů" msgid "reset level" msgstr "znovu začít kolo" msgid "play level!" msgstr "hrát kolo!" msgid "Available Levels" msgstr "Dostupná kola" #, c-format msgid "Level %d:" msgstr "Kolo %d:" #, c-format msgid "[not yet completed]" msgstr "[ještě nedokončeno]" #, c-format msgid "level high score: %ld" msgstr "rekord pro kolo: %ld" #, c-format msgid "total score all levels: %ld" msgstr "celkové skóre za všechna kola: %ld" msgid "resume game!" msgstr "pokračovat ve hře!" msgid "Game Paused" msgstr "Hra zastavena" msgid "Time Elapsed:" msgstr "Uplynulý čas:" msgid "gPlanarity" msgstr "gPlanarity" msgid "Untangle the mess!" msgstr "Rozmotejte šmodrchanec!" msgid "Drag vertices to eliminate crossed lines." msgstr "Přesunujte vrcholy, abyste odstranili křížící se čáry." msgid "The objective may be a complete solution or" msgstr "Zadání může být uplné řešení nebo" msgid "getting as close as possible to solving an" msgstr "dobrání se podoby co nejblížší řešení" msgid "unsolvable puzzle. Work quickly and" msgstr "neřešitelného rébusu. Pracujte rychle a" msgid "exceed the objective for bonus points!" msgstr "získejte body navíc za překonání zadání!" msgid "gPlanarity written by Monty " msgstr "gPlanarity napsal Monty " msgid "as a demonstration of Gtk+/Cairo" msgstr "jako demo Gtk+/Caira" msgid "Original Flash version of Planarity by" msgstr "Původní verzi Planarity ve flashy napsal" msgid "John Tantalo " msgstr "John Tantalo " msgid "Original game concept by Mary Radcliffe" msgstr "Koncepci hry vymysla Mary Radcliffe." #, c-format msgid "" "\n" "\n" "ERROR: The windowmanager appears to be ignoring resize requests.\n" "This stands a pretty good chance of scrambling any saved board larger\n" "than the default window size.\n" "\n" msgstr "" "\n" "\n" "CHYBA: Zdá se, že správce oken ignoruje požadavky na změnu velikosti okna.\n" "Což znamená docela dobrou šanci, že uložená deska větší než výchozí " "velikost\n" "okna bude poškozená.\n" "\n" #, c-format msgid "" "Clipping and/or expanding this board to the current window size...\n" "\n" msgstr "" "Lze očekávat oříznutí a/nebo roztažení takové desky na rozměry okna…\n" "\n" #, c-format msgid "" "\n" "\n" "ERROR: The window size granted by the windowmanager is not the\n" "window size gPlanarity requested. If the windowmanager is\n" "configured to ignore application sizing requests, this stands\n" "a pretty good chance of scrambling saved boards later (and\n" "making everything look funny now).\n" "\n" msgstr "" "\n" "\n" "CHYBA: Požadovaná velikost okna gPlanarity a velikost zaručena správcem " "oken\n" "se liší. Pokud je správce oken nastaven, aby ignoroval požadavky na změnu\n" "velikosti okna, je docela dobrá šance na poškození později uložených desek\n" "(a na veselý vzhled čehokoliv již od teď).\n" "\n" msgid "rather many, really" msgstr "raději mnoho, opravdu" #, c-format msgid "ERROR: Could not load board icon \"%s\"\n" msgstr "CHYBA: Nelze načíst ikonu desky „%s“\n" #, c-format msgid "ERROR: Could not save board icon \"%s\"\n" msgstr "CHYBA: nelze uložit ikonu desky „%s“\n" #, c-format msgid "Level %d: %s" msgstr "Kolo %d: %s" #, c-format msgid "Score: %d" msgstr "Skóre: %d" #, c-format msgid "%d%%" msgstr "%d%%" #, c-format msgid "Intersections: %ld" msgstr "Průniků: %ld" #, c-format msgid "Objective: %s" msgstr "Zadání: %s" msgid "reset board" msgstr "resetovat desku" msgid "pause" msgstr "pauza" msgid "help / about" msgstr "nápověda / o programu" msgid "expand" msgstr "roztáhnout" msgid "shrink" msgstr "smrštit" msgid "hide/show lines" msgstr "skrýt/zobrazit čáry" msgid "mark intersections" msgstr "označit průniky" msgid "click when finished!" msgstr "po dokončení klikněte!" #, c-format msgid "" "ERROR: Could not save board state for \"%s\":\n" "\t%s\n" msgstr "" "CHYBA: Nelze uložit stav desky pro „%s“:\n" "\t%s\n" #, c-format msgid "" "ERROR: Could not read saved board state for \"%s\":\n" "\t%s\n" msgstr "" "CHYBA: Nelze načíst uložený stav desky pro „%s“:\n" "\t%s\n" #, c-format msgid "WARNING: edge references out of range vertex in save file\n" msgstr "VAROVÁNÍ: hrana odkazuje na vrchol mimo rozsah uložený v souboru\n" #, c-format msgid "Couldn't allocate memory for level name.\n" msgstr "Nelze vyhradit paměť pro jméno kola.\n" #, c-format msgid "Couldn't allocate memory for level description.\n" msgstr "Nelze vyhradit paměť pro popis kola.\n" #, c-format msgid "" "region overlap adjustment failed in arc_arc_adj; \n" " This is an internal error that should never happen.\n" msgstr "" "přizpůsobení překrývajících se oblastí selhalo v arc_arc_arj;\n" " Toto je vnitřní chyba a nemělo by k ní nikdy dojít.\n" msgid "zero intersections" msgstr "žádné průniky" msgid "1 intersection or fewer" msgstr "1 průnik nebo méně" msgid "1 intersection" msgstr "1 průnik" #, c-format msgid "%d intersections%s" msgstr "%d průniků%s" msgid " or fewer" msgstr " nebo méně" #, c-format msgid "" "ERROR: Could not save game state file \"%s\":\n" "\t%s\n" msgstr "" "CHYBA: Nelze uložit soubor se stavem hry „%s“:\n" "\t%s\n" #, c-format msgid "" "ERROR: Could not read game state file \"%s\":\n" "\t%s\n" msgstr "" "CHYBA: Nelze načíst soubor se stavem hry „%s“:\n" "\t%s\n" #, c-format msgid "" "ERROR: Could not create directory (%s) to save game state:\n" "\t%s\n" msgstr "" "CHYBA: Nelze vytvořit adresář (%s) pro ukládání stavu hry:\n" "\t%s\n" #, c-format msgid "" "\n" "Trapped signal %d; saving state and exiting!\n" msgstr "" "\n" "Zachycen signál %d; uložím stav a skončím!\n" #, c-format msgid "" "\n" "Unable to find any suitable %s fonts!\n" "Continuing, but the the results are likely to be poor.\n" "\n" msgstr "" "\n" "Nelze najít žádný vhodný font s %s!\n" "Pokračuji, ale výsledek asi bude ošklivý.\n" "\n" msgid "bold italic" msgstr "tučnou kurzívou" msgid "italic" msgstr "kurzívou" msgid "bold" msgstr "tučným řezem" msgid "medium" msgstr "středním řezem" #, c-format msgid "" "\n" "Selected %s font \"%s\" is not scalable! This is almost as bad\n" "as not finding any font at all. Continuing, but this may look\n" "very poor indeed.\n" "\n" msgstr "" "\n" "Vybraný font s %s „%s“ není škálovatelný!\n" "Toto situace je téměř tak špatná jako když se nenajde font žádný.\n" "Pokračuji, ale výsledek bude asi ošklivý\n" "\n" #, c-format msgid "" "No homedir environment variable set! gPlanarity will be\n" "unable to permanently save any progress or board state.\n" msgstr "" "Žádná proměnná prostředí neudává domovský adresář! gPlanatiry nebude " "schopné\n" "trvale uložit postup hráče nebo stav hrací desky.\n" #, c-format msgid "%d:%02d:%02d" msgstr "%d:%02d:%02d" #, c-format msgid "%d:%02d" msgstr "%d:%02d" #, c-format msgid "%d seconds" msgstr "%d sekund" gplanarity-17906/po/es_ES.po0000644000175000017500000003000511543161637015573 0ustar vincentvincent# # Copyright (C) 2007 Monty # This file is distributed under the same license as the gPlanarity package. # # Federico Vera 2009. msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: Monty \n" "POT-Creation-Date: 2009-11-25 02:29-0500\n" "PO-Revision-Date: 2009-09-12 19:45-0300\n" "Last-Translator: Federico Vera \n" "Language-Team: Spanish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.0\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" # # File: ../dialog_finish.c, line: 80 # File: ../dialog_level.c, line: 67 # File: ../dialog_pause.c, line: 67 # File: ../gameboard_logic_buttonbar.c, line: 54 msgid "exit gPlanarity" msgstr "cerrar gPlanarity" # # File: ../dialog_finish.c, line: 81 # File: ../gameboard_logic_buttonbar.c, line: 55 msgid "level selection menu" msgstr "menú de selección de nivel" # # File: ../dialog_finish.c, line: 82 msgid "play next level!" msgstr "jugar al siguiente nivel!" # # File: ../dialog_finish.c, line: 160 msgid "Level Complete!" msgstr "Nivel Completo!" # # File: ../dialog_finish.c, line: 164 #, c-format msgid "Elapsed: %s" msgstr "Tiempo transcurrido: %s" # # File: ../dialog_finish.c, line: 168 #, c-format msgid "Base score: %d points" msgstr "Puntaje: %d puntos" # # File: ../dialog_finish.c, line: 176 #, c-format msgid "Objective Exceeded! %d%%" msgstr "Superó el objetivo! %d%%" # # File: ../dialog_finish.c, line: 181 #, c-format msgid "Time bonus: %d points" msgstr "Bonus: %d puntos" # # File: ../dialog_finish.c, line: 186 #, c-format msgid "Final score: %d points" msgstr "Puntaje final: %d puntos" # # File: ../dialog_finish.c, line: 191 msgid "A high score!" msgstr "Un record!" # # File: ../dialog_finish.c, line: 194 #, c-format msgid "Previous best: %ld points" msgstr "Record anterior: %ld puntos" # # File: ../dialog_finish.c, line: 199 msgid "Total score to date:" msgstr "Puntaje total al día de hoy:" # # File: ../dialog_finish.c, line: 201 #, c-format msgid "%ld points" msgstr "%ld puntos" # # File: ../dialog_level.c, line: 68 msgid "reset level" msgstr "reiniciar nivel" # # File: ../dialog_level.c, line: 69 msgid "play level!" msgstr "jugar nivel!" # # File: ../dialog_level.c, line: 139 msgid "Available Levels" msgstr "Niveles disponibles" # # File: ../dialog_level_icons.c, line: 246 #, c-format msgid "Level %d:" msgstr "Nivel %d:" # # File: ../dialog_level_icons.c, line: 264 #, c-format msgid "[not yet completed]" msgstr "[sin completar]" # # File: ../dialog_level_icons.c, line: 267 #, c-format msgid "level high score: %ld" msgstr "record para este nivel: %ld" # # File: ../dialog_level_icons.c, line: 277 #, c-format msgid "total score all levels: %ld" msgstr "puntaje total para todos los niveles: %ld" # # File: ../dialog_pause.c, line: 68 msgid "resume game!" msgstr "continuar juego!" # # File: ../dialog_pause.c, line: 131 msgid "Game Paused" msgstr "Juego Pausado" # # File: ../dialog_pause.c, line: 134 msgid "Time Elapsed:" msgstr "Tiempo Transcurrido:" # # File: ../dialog_pause.c, line: 186 msgid "gPlanarity" msgstr "gPlanarity" # # File: ../dialog_pause.c, line: 190 msgid "Untangle the mess!" msgstr "Desenrrede este lío!" # # File: ../dialog_pause.c, line: 194 msgid "Drag vertices to eliminate crossed lines." msgstr "Arrastre los vértices para eliminar los cruces de" # # File: ../dialog_pause.c, line: 195 msgid "The objective may be a complete solution or" msgstr "líneas. El objetivo puede ser una solución" # # File: ../dialog_pause.c, line: 196 msgid "getting as close as possible to solving an" msgstr "completa o acercarse lo más posible a resolver" # # File: ../dialog_pause.c, line: 197 msgid "unsolvable puzzle. Work quickly and" msgstr "un rompezabezas irresolvible. Trabaje rápido y" # # File: ../dialog_pause.c, line: 198 msgid "exceed the objective for bonus points!" msgstr "supere los objetivos para obtener un bonus!" # # File: ../dialog_pause.c, line: 207 msgid "gPlanarity written by Monty " msgstr "gPlanarity escrito por Monty " # # File: ../dialog_pause.c, line: 208 msgid "as a demonstration of Gtk+/Cairo" msgstr "como una demostración de Gtk+/Cairo" # # File: ../dialog_pause.c, line: 210 msgid "Original Flash version of Planarity by" msgstr "Versión Original en Flash de Planarity por" # # File: ../dialog_pause.c, line: 211 msgid "John Tantalo " msgstr "John Tantalo " # # File: ../dialog_pause.c, line: 213 msgid "Original game concept by Mary Radcliffe" msgstr "Concepto original del juego por Mary Radcliffe" # # File: ../gameboard.c, line: 75 #, c-format msgid "" "\n" "\n" "ERROR: The windowmanager appears to be ignoring resize requests.\n" "This stands a pretty good chance of scrambling any saved board larger\n" "than the default window size.\n" "\n" msgstr "" "\n" "\n" "ERROR: El manejador de ventanas parece estar ignorando la petición de " "redimensionamiento.\n" "Hay grandes chances de que se arruine algún tablero guardado más grande que\n" "el tamaño predeterminado de ventana.\n" "\n" # # File: ../gameboard.c, line: 78 # File: ../gameboard.c, line: 189 #, c-format msgid "" "Clipping and/or expanding this board to the current window size...\n" "\n" msgstr "" "Recortando y/o expandiendo este tablero al tamaño actual de ventana...\n" "\n" # # File: ../gameboard.c, line: 184 #, c-format msgid "" "\n" "\n" "ERROR: The window size granted by the windowmanager is not the\n" "window size gPlanarity requested. If the windowmanager is\n" "configured to ignore application sizing requests, this stands\n" "a pretty good chance of scrambling saved boards later (and\n" "making everything look funny now).\n" "\n" msgstr "" "\n" "\n" "ERROR: El tamaño de ventana concedido por el manejador de ventanas no es\n" "el tamaño pedido por gPlanarity. Si el manejador de ventanas está " "configurado\n" "para ignorar los tamaños pedidos por las aplicaciones, hay grandes\n" "chances de que se arruinen los tableros guardados (y de\n" "que ahora todo se vea raro).\n" "\n" # # File: ../gameboard_draw_intersection.c, line: 65 msgid "rather many, really" msgstr "realmente, más bien muchas" # # File: ../gameboard_draw_main.c, line: 370 #, c-format msgid "ERROR: Could not load board icon \"%s\"\n" msgstr "ERROR: No se pudo cargar el icono de tablero \"%s\"\n" # # File: ../gameboard_draw_main.c, line: 436 #, c-format msgid "ERROR: Could not save board icon \"%s\"\n" msgstr "ERROR: no se pudo guardar el icono de tablero \"%s\"\n" # # File: ../gameboard_draw_score.c, line: 67 #, c-format msgid "Level %d: %s" msgstr "Nivel %d: %s" # # File: ../gameboard_draw_score.c, line: 68 #, c-format msgid "Score: %d" msgstr "Puntaje: %d" # # File: ../gameboard_draw_score.c, line: 69 #, c-format msgid "%d%%" msgstr "%d%%" # # File: ../gameboard_draw_score.c, line: 70 #, c-format msgid "Intersections: %ld" msgstr "Intersecciones: %ld" # # File: ../gameboard_draw_score.c, line: 71 #, c-format msgid "Objective: %s" msgstr "Objetivo: %s" # # File: ../gameboard_logic_buttonbar.c, line: 56 msgid "reset board" msgstr "reiniciar tablero" # # File: ../gameboard_logic_buttonbar.c, line: 57 msgid "pause" msgstr "pausa" # # File: ../gameboard_logic_buttonbar.c, line: 58 msgid "help / about" msgstr "ayuda/acerca de" # # File: ../gameboard_logic_buttonbar.c, line: 59 msgid "expand" msgstr "expandir" # # File: ../gameboard_logic_buttonbar.c, line: 60 msgid "shrink" msgstr "achicar" # # File: ../gameboard_logic_buttonbar.c, line: 61 msgid "hide/show lines" msgstr "ocultar/mostrar lineas" # # File: ../gameboard_logic_buttonbar.c, line: 62 msgid "mark intersections" msgstr "marcar intersecciones" # # File: ../gameboard_logic_buttonbar.c, line: 63 msgid "click when finished!" msgstr "haga click cuando termine!" # # File: ../gameboard_logic.c, line: 371 #, c-format msgid "" "ERROR: Could not save board state for \"%s\":\n" "\t%s\n" msgstr "" "ERROR: No se pudo guardar el estado del tablero para \"%s\":\n" "\t%s\n" # # File: ../gameboard_logic.c, line: 401 #, c-format msgid "" "ERROR: Could not read saved board state for \"%s\":\n" "\t%s\n" msgstr "" "ERROR: No se pudo leer el estado de tablero guardado para \"%s\":\n" "\t%s\n" # # File: ../graph.c, line: 923 #, c-format msgid "WARNING: edge references out of range vertex in save file\n" msgstr "" "ADVERTENCIA: las referencias de las esquinas están fuera de rango en el " "archivo guardado\n" # # File: ../graph_generate.c, line: 196 # File: ../graph_generate.c, line: 215 #, c-format msgid "Couldn't allocate memory for level name.\n" msgstr "No se pudo reservar memoria para el nombre del nivel.\n" # # File: ../graph_generate.c, line: 210 #, c-format msgid "Couldn't allocate memory for level description.\n" msgstr "No se pudo reservar memoria para la descripción del nivel.\n" # # File: ../graph_region.c, line: 459 #, c-format msgid "" "region overlap adjustment failed in arc_arc_adj; \n" " This is an internal error that should never happen.\n" msgstr "" "falló el ajuste de la región de superposición en arc_arc_adj; \n" " Este es un error interno que nunca debería ocurrir.\n" # # File: ../graph_score.c, line: 67 msgid "zero intersections" msgstr "cero intersecciones" # # File: ../graph_score.c, line: 70 msgid "1 intersection or fewer" msgstr "1 intersección o menos" # # File: ../graph_score.c, line: 72 msgid "1 intersection" msgstr "1 intersección" # # File: ../graph_score.c, line: 75 #, c-format msgid "%d intersections%s" msgstr "%d intersecciones%s" # # File: ../graph_score.c, line: 77 msgid " or fewer" msgstr " o menos" # # File: ../levelstate.c, line: 169 #, c-format msgid "" "ERROR: Could not save game state file \"%s\":\n" "\t%s\n" msgstr "" "ERROR: No se pudo guardar el archivo de estado del juego \"%s\":\n" "\t%s\n" # # File: ../levelstate.c, line: 216 #, c-format msgid "" "ERROR: Could not read game state file \"%s\":\n" "\t%s\n" msgstr "" "ERROR: No se pudo leer el archivo de estado del juego \"%s\":\n" "\t%s\n" # # File: ../main.c, line: 73 #, c-format msgid "" "ERROR: Could not create directory (%s) to save game state:\n" "\t%s\n" msgstr "" "ERROR: No se pudo crear el directorio (%s) para guardar el estado del " "juego:\n" "\t%s\n" # # File: ../main.c, line: 93 #, c-format msgid "" "\n" "Trapped signal %d; saving state and exiting!\n" msgstr "" "\n" "Señal atrapada %d; guardando estado y saliendo!\n" # # File: ../main.c, line: 146 #, c-format msgid "" "\n" "Unable to find any suitable %s fonts!\n" "Continuing, but the the results are likely to be poor.\n" "\n" msgstr "" "\n" "Imposible encontrar tipografias %s adecuadas!\n" "Se continuará, pero los resultados pueden ser pobres.\n" "\n" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "bold italic" msgstr "negrita cursiva" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "italic" msgstr "cursiva" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "bold" msgstr "negrita" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "medium" msgstr "media" # # File: ../main.c, line: 164 #, c-format msgid "" "\n" "Selected %s font \"%s\" is not scalable! This is almost as bad\n" "as not finding any font at all. Continuing, but this may look\n" "very poor indeed.\n" "\n" msgstr "" "\n" "La tipografía %s seleccionada \"%s\" no es escalable! Esto es casi tan malo\n" "como no encontrar ninguna tipografía. Se continuará, pero se verá\n" "realmente pobre.\n" "\n" # # File: ../main.c, line: 288 #, c-format msgid "" "No homedir environment variable set! gPlanarity will be\n" "unable to permanently save any progress or board state.\n" msgstr "" "No hay asignada una variable de entorno homedir! gPlanarity será\n" "incapaz de guardar permanentemente su prograso o el estado del tablero.\n" # # File: ../timer.c, line: 51 #, c-format msgid "%d:%02d:%02d" msgstr "%d:%02d:%02d" # # File: ../timer.c, line: 53 #, c-format msgid "%d:%02d" msgstr "%d:%02d" # # File: ../timer.c, line: 55 #, c-format msgid "%d seconds" msgstr "%d segundos" gplanarity-17906/po/header.sed0000644000175000017500000000007111543161637016162 0ustar vincentvincent2 c \# Copyright (C) 2007 Monty 3 s/PACKAGE/gPlanarity/ gplanarity-17906/po/fr_FR.po0000755000175000017500000003046411543161637015607 0ustar vincentvincent# SOME DESCRIPTIVE TITLE. # Copyright (C) 2007 Monty # This file is distributed under the same license as the gPlanarity package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: gplanarity 01.10\n" "Report-Msgid-Bugs-To: Monty \n" "POT-Creation-Date: 2009-11-25 02:29-0500\n" "PO-Revision-Date: 2009-11-23 20:59+0100\n" "Last-Translator: Lerique Julien \n" "Language-Team: french \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: French\n" "X-Poedit-Country: FRANCE\n" "X-Poedit-SourceCharset: utf-8\n" # # File: ../dialog_finish.c, line: 80 # File: ../dialog_level.c, line: 67 # File: ../dialog_pause.c, line: 67 # File: ../gameboard_logic_buttonbar.c, line: 54 msgid "exit gPlanarity" msgstr "quitter gPlanarity" # # File: ../dialog_finish.c, line: 81 # File: ../gameboard_logic_buttonbar.c, line: 55 msgid "level selection menu" msgstr "menu de sélection des niveaux" # # File: ../dialog_finish.c, line: 82 msgid "play next level!" msgstr "jouer le niveau suivant!" # # File: ../dialog_finish.c, line: 160 msgid "Level Complete!" msgstr "Niveau Terminé!" # # File: ../dialog_finish.c, line: 164 #, c-format msgid "Elapsed: %s" msgstr "Temps écoulé : %s" # # File: ../dialog_finish.c, line: 168 #, c-format msgid "Base score: %d points" msgstr "Score de base: %d points" # # File: ../dialog_finish.c, line: 176 #, c-format msgid "Objective Exceeded! %d%%" msgstr "Objectif Dépassé! %d%%" # # File: ../dialog_finish.c, line: 181 #, c-format msgid "Time bonus: %d points" msgstr "Bonus temps: %d points" # # File: ../dialog_finish.c, line: 186 #, c-format msgid "Final score: %d points" msgstr "Score final: %d points" # # File: ../dialog_finish.c, line: 191 msgid "A high score!" msgstr "Un meilleur score!" # # File: ../dialog_finish.c, line: 194 #, c-format msgid "Previous best: %ld points" msgstr "Meilleur score précédent: %ld points" # # File: ../dialog_finish.c, line: 199 msgid "Total score to date:" msgstr "Agrégation des scores:" # # File: ../dialog_finish.c, line: 201 #, c-format msgid "%ld points" msgstr "%ld points" # # File: ../dialog_level.c, line: 68 msgid "reset level" msgstr "réinitialiser le niveau" # # File: ../dialog_level.c, line: 69 msgid "play level!" msgstr "jouer à ce niveau!" # # File: ../dialog_level.c, line: 139 msgid "Available Levels" msgstr "Niveaux Disponibles" # # File: ../dialog_level_icons.c, line: 246 #, c-format msgid "Level %d:" msgstr "Niveau %d:" # # File: ../dialog_level_icons.c, line: 264 #, c-format msgid "[not yet completed]" msgstr "[Pas encore achevé]" # # File: ../dialog_level_icons.c, line: 267 #, c-format msgid "level high score: %ld" msgstr "meilleur score sur ce niveau: %ld" # # File: ../dialog_level_icons.c, line: 277 #, c-format msgid "total score all levels: %ld" msgstr "score total sur tous les niveaux: %ld" # # File: ../dialog_pause.c, line: 68 msgid "resume game!" msgstr "retour au jeu!" # # File: ../dialog_pause.c, line: 131 msgid "Game Paused" msgstr "Partie Suspendue" # # File: ../dialog_pause.c, line: 134 msgid "Time Elapsed:" msgstr "Temps écoulé:" # # File: ../dialog_pause.c, line: 186 msgid "gPlanarity" msgstr "gPlanarity" # # File: ../dialog_pause.c, line: 190 msgid "Untangle the mess!" msgstr "Démêlez ce désordre!" # # File: ../dialog_pause.c, line: 194 msgid "Drag vertices to eliminate crossed lines." msgstr "Faîtes glisser les points afin d'éradiquer les lignes qui" # # File: ../dialog_pause.c, line: 195 msgid "The objective may be a complete solution or" msgstr "se croisent. L'objectif peut être une solution complète" # # File: ../dialog_pause.c, line: 196 msgid "getting as close as possible to solving an" msgstr "ou, pour un puzzle insoluble, s'approcher d'aussi près" # # File: ../dialog_pause.c, line: 197 msgid "unsolvable puzzle. Work quickly and" msgstr "que possible d'une solution. Oeuvrez rapidement et" # # File: ../dialog_pause.c, line: 198 msgid "exceed the objective for bonus points!" msgstr "dépassez l'objectif afin d'obtenir des points bonus." # # File: ../dialog_pause.c, line: 207 msgid "gPlanarity written by Monty " msgstr "gPlanarity, écrit par Monty " # # File: ../dialog_pause.c, line: 208 msgid "as a demonstration of Gtk+/Cairo" msgstr "comme une démonstration de Gtk+/Cairo" # # File: ../dialog_pause.c, line: 210 msgid "Original Flash version of Planarity by" msgstr "Version originale en flash de Planarity par" # # File: ../dialog_pause.c, line: 211 msgid "John Tantalo " msgstr "John Tantalo " # # File: ../dialog_pause.c, line: 213 msgid "Original game concept by Mary Radcliffe" msgstr "Concept original du jeu par Mary Radcliffe" # # File: ../gameboard.c, line: 75 #, c-format msgid "" "\n" "\n" "ERROR: The windowmanager appears to be ignoring resize requests.\n" "This stands a pretty good chance of scrambling any saved board larger\n" "than the default window size.\n" "\n" msgstr "" "\n" "\n" "ERREUR: le gestionnaire de fenêtre semble ignorer les demandes d'ajustement\n" "de taille. Cela pourrait perturber la sauvegarde de n'importe quelle partie\n" "dont le plateau est plus grand que la taille de fenêtre par défaut.\n" "\n" # # File: ../gameboard.c, line: 78 # File: ../gameboard.c, line: 189 #, c-format msgid "" "Clipping and/or expanding this board to the current window size...\n" "\n" msgstr "" "Découper et/ou étendre l'espace de jeu sur la taille courante de la " "fenêtre...\n" "\n" # # File: ../gameboard.c, line: 184 #, c-format msgid "" "\n" "\n" "ERROR: The window size granted by the windowmanager is not the\n" "window size gPlanarity requested. If the windowmanager is\n" "configured to ignore application sizing requests, this stands\n" "a pretty good chance of scrambling saved boards later (and\n" "making everything look funny now).\n" "\n" msgstr "" "\n" "ERREUR: La taille de la fenêtre allouée par le gestionnaire de fenêtre\n" "n'est pas celle demandée par gPlanarity. Si le gestionnaire de fenêtre\n" "est configuré pour ignorer les demandes d'ajustement de taille, Cela\n" "pourrait perturber les prochaines sauvegarde des activités (et\n" "actuellement entraîner une drôle d'apparence).\n" " \n" # # File: ../gameboard_draw_intersection.c, line: 65 msgid "rather many, really" msgstr "en fait plutôt nombreux" # # File: ../gameboard_draw_main.c, line: 370 #, c-format msgid "ERROR: Could not load board icon \"%s\"\n" msgstr "ERREUR: Impossible de charger l'activité \"%s\"\n" # # File: ../gameboard_draw_main.c, line: 436 #, c-format msgid "ERROR: Could not save board icon \"%s\"\n" msgstr "ERREUR: Impossible de sauvegarder l'activité \"%s\"\n" # # File: ../gameboard_draw_score.c, line: 67 #, c-format msgid "Level %d: %s" msgstr "Niveau %d: %s" # # File: ../gameboard_draw_score.c, line: 68 #, c-format msgid "Score: %d" msgstr "Score: %d" # # File: ../gameboard_draw_score.c, line: 69 #, c-format msgid "%d%%" msgstr "%d%%" # # File: ../gameboard_draw_score.c, line: 70 #, c-format msgid "Intersections: %ld" msgstr "Intersections: %ld" # # File: ../gameboard_draw_score.c, line: 71 #, c-format msgid "Objective: %s" msgstr "Objectif: %s" # # File: ../gameboard_logic_buttonbar.c, line: 56 msgid "reset board" msgstr "réinitialiser le niveau" # # File: ../gameboard_logic_buttonbar.c, line: 57 msgid "pause" msgstr "pause" # # File: ../gameboard_logic_buttonbar.c, line: 58 msgid "help / about" msgstr "aide / à propos" # # File: ../gameboard_logic_buttonbar.c, line: 59 msgid "expand" msgstr "agrandir" # # File: ../gameboard_logic_buttonbar.c, line: 60 msgid "shrink" msgstr "réduire" # # File: ../gameboard_logic_buttonbar.c, line: 61 msgid "hide/show lines" msgstr "cacher/afficher les lignes" # # File: ../gameboard_logic_buttonbar.c, line: 62 msgid "mark intersections" msgstr "signaler les intersections" # # File: ../gameboard_logic_buttonbar.c, line: 63 msgid "click when finished!" msgstr "si vous avez terminé, cliquez!" # # File: ../gameboard_logic.c, line: 371 #, c-format msgid "" "ERROR: Could not save board state for \"%s\":\n" "\t%s\n" msgstr "" "ERREUR: Impossible de sauvegarder l'état de l'activité \"%s\":\n" "\t%s\n" # # File: ../gameboard_logic.c, line: 401 #, c-format msgid "" "ERROR: Could not read saved board state for \"%s\":\n" "\t%s\n" msgstr "" "ERREUR: Impossible de lire l'état de l'activité \"%s\":\n" "\t%s\n" # # File: ../graph.c, line: 923 #, c-format msgid "WARNING: edge references out of range vertex in save file\n" msgstr "" "AVERTISSEMENT: les références d'arêtes dépassent le sommet dans le fichier " "sauvegardé\n" # # File: ../graph_generate.c, line: 196 # File: ../graph_generate.c, line: 215 #, c-format msgid "Couldn't allocate memory for level name.\n" msgstr "Impossible d'allouer de la mémoire pour le nom du niveau.\n" # # File: ../graph_generate.c, line: 210 #, c-format msgid "Couldn't allocate memory for level description.\n" msgstr "Impossible d'allouer de la mémoire pour la description du niveau.\n" # # File: ../graph_region.c, line: 459 #, c-format msgid "" "region overlap adjustment failed in arc_arc_adj; \n" " This is an internal error that should never happen.\n" msgstr "" "L'adaptation de la zone de chevauchement a échoué dans arc_arc_adj; \n" " Ceci est une erreur interne qui ne devrait jamais se produire.\n" # # File: ../graph_score.c, line: 67 msgid "zero intersections" msgstr "zero intersection" # # File: ../graph_score.c, line: 70 msgid "1 intersection or fewer" msgstr "1 intersection ou moins" # # File: ../graph_score.c, line: 72 msgid "1 intersection" msgstr "1 intersection" # # File: ../graph_score.c, line: 75 #, c-format msgid "%d intersections%s" msgstr "%d intersections%s" # # File: ../graph_score.c, line: 77 msgid " or fewer" msgstr "ou moins" # # File: ../levelstate.c, line: 169 #, c-format msgid "" "ERROR: Could not save game state file \"%s\":\n" "\t%s\n" msgstr "" "ERREUR: Impossible de sauvegarder le fichier sur l'état d'avancement du jeu " "\"%s\":\n" "\t%s\n" # # File: ../levelstate.c, line: 216 #, c-format msgid "" "ERROR: Could not read game state file \"%s\":\n" "\t%s\n" msgstr "" "ERREUR : Impossible de lire le fichier sur l'état d'avancement du jeu \"%s" "\":\n" "\t%s\n" # # File: ../main.c, line: 73 #, c-format msgid "" "ERROR: Could not create directory (%s) to save game state:\n" "\t%s\n" msgstr "" "ERREUR: Impossible de créer le répertoire (%s) pour sauvegarder l'état " "d'avancement du jeu:\n" "\t%s\n" # # File: ../main.c, line: 93 #, c-format msgid "" "\n" "Trapped signal %d; saving state and exiting!\n" msgstr "" "\n" "Le signal %d est piégé; sauvegarde et quitte!\n" # # File: ../main.c, line: 146 #, c-format msgid "" "\n" "Unable to find any suitable %s fonts!\n" "Continuing, but the the results are likely to be poor.\n" "\n" msgstr "" "\n" "Incapable de trouver une police %s acceptable!\n" "Continuons, mais le résultat obtenu sera probablement pauvre.\n" "\n" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "bold italic" msgstr "police grasse" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "italic" msgstr "italique" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "bold" msgstr "gras" # # File: ../main.c, line: 149 # File: ../main.c, line: 167 msgid "medium" msgstr "moyen" # # File: ../main.c, line: 164 #, c-format msgid "" "\n" "Selected %s font \"%s\" is not scalable! This is almost as bad\n" "as not finding any font at all. Continuing, but this may look\n" "very poor indeed.\n" "\n" msgstr "" "\n" "L'échelle de la police %s sélectionnée \"%s\" est fixe! Ceci est presque\n" "aussi grave que de ne pas du tout trouver de police. Continuons, mais\n" "l'apparence pourrait être vraiment misérable.\n" "\n" # # File: ../main.c, line: 288 #, c-format msgid "" "No homedir environment variable set! gPlanarity will be\n" "unable to permanently save any progress or board state.\n" msgstr "" "La variable d'environnement homedir n'est pas définie! gPlanarity\n" "ne parviendra pas à sauvegarder les progrès ou l'état d'avancement de " "l'activité.\n" # # File: ../timer.c, line: 51 #, c-format msgid "%d:%02d:%02d" msgstr "%d:%02d:%02d" # # File: ../timer.c, line: 53 #, c-format msgid "%d:%02d" msgstr "%d:%02d" # # File: ../timer.c, line: 55 #, c-format msgid "%d seconds" msgstr "%d secondes" gplanarity-17906/po/Makefile0000644000175000017500000000127211543161637015701 0ustar vincentvincent#GT_DOMAIN:=gPlanarity SRC=../*.c ifeq ($(origin WANT_LINGUAS), undefined) PO=$(wildcard *.po) else PO=$(addsuffix .po,$(WANT_LINGUAS)) endif GMO=$(PO:.po=.gmo) HEADER=--msgid-bugs-address="Monty " all: $(GT_DOMAIN).pot $(GMO) $(GT_DOMAIN).pot: $(SRC) xgettext --strict $(HEADER) -d $(GT_DOMAIN) -o /dev/stdout \ -L C --keyword=_ $(SRC) | sed -f header.sed >$@ %.gmo: %.po $(GT_DOMAIN).pot msgmerge -o$ Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. gplanarity-17906/gameboard_draw_intersection.c0000644000175000017500000000611711543161637021516 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include "graph.h" #include "gameboard.h" #include "main.h" static void draw_intersection(cairo_t *c,double x, double y){ cairo_move_to(c,x-INTERSECTION_RADIUS,y); cairo_rel_line_to(c,INTERSECTION_RADIUS,-INTERSECTION_RADIUS); cairo_rel_line_to(c,INTERSECTION_RADIUS,INTERSECTION_RADIUS); cairo_rel_line_to(c,-INTERSECTION_RADIUS,INTERSECTION_RADIUS); cairo_close_path(c); } static void draw_many_intersection(Gameboard *g,cairo_t *c){ int x2 = g->g.width/2; int y2 = g->g.height/2; int r = INTERSECTION_RADIUS*10; cairo_set_source_rgba (c, INTERSECTION_COLOR); cairo_set_line_width(c, INTERSECTION_LINE_WIDTH*10); cairo_move_to(c,x2-r,y2-r/4); cairo_rel_line_to(c,r,-r); cairo_rel_line_to(c,r,r); cairo_rel_line_to(c,-r,r); cairo_close_path(c); cairo_stroke(c); set_font(c, 30., 34., 0,1); render_bordertext_centered(c,_("rather many, really"),x2,y2+r/4); } void draw_intersections(Gameboard *b, graph *g, cairo_t *c, int x,int y,int w,int h){ double xx=x-(INTERSECTION_LINE_WIDTH*.5 + INTERSECTION_RADIUS); double x2=w+x+(INTERSECTION_LINE_WIDTH + INTERSECTION_RADIUS*2); double yy=y-(INTERSECTION_LINE_WIDTH*.5 + INTERSECTION_RADIUS); double y2=h+y+(INTERSECTION_LINE_WIDTH + INTERSECTION_RADIUS*2); if(g->active_intersections > 1000){ // don't draw them all; potential for accidental CPU sink. draw_many_intersection(b,c); }else{ cairo_set_source_rgba (c, INTERSECTION_COLOR); cairo_set_line_width(c, INTERSECTION_LINE_WIDTH); // walk the intersection list of all edges; draw if paired is a higher pointer edge *e=g->edges; while(e){ intersection *i = e->i.next; while(i){ if(i->paired > i){ double ix=i->x, iy=i->y; if(ix >= xx && ix <= x2 && iy >= yy && iy <= y2) draw_intersection(c,ix,iy); } cairo_stroke(c); /* incremental stroke! It's easy to run the path longer than the X server allows. */ i=i->next; } e=e->next; } } } gplanarity-17906/graph_score.c0000644000175000017500000000456311543161637016271 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include #include "graph.h" #include "timer.h" #include "nls.h" static char objective_string[160]; int graphscore_get_raw_score(graph *g){ return (int)ceil((g->original_intersections- g->active_intersections)* g->intersection_mult); } int graphscore_get_multiplier_percent(graph *g){ float obj_multiplier = 100; if(g->objective_lessthan) if(g->objective > g->active_intersections) obj_multiplier += 100.f * g->objective_mult / g->objective * (g->objective - g->active_intersections); return ceil(obj_multiplier); } int graphscore_get_score(graph *g){ return graphscore_get_raw_score(g)*graphscore_get_multiplier_percent(g)/100; } int graphscore_get_bonus(graph *g){ int obj_multiplier = graphscore_get_multiplier_percent(g); if(get_timer()< g->original_intersections*g->intersection_mult) return ceil ((g->original_intersections*g->intersection_mult-get_timer()) * obj_multiplier / 100); return 0; } char *graphscore_objective_string(graph *g){ if(g->objective == 0) return _("zero intersections"); if(g->objective == 1){ if(g->objective_lessthan){ return _("1 intersection or fewer"); }else{ return _("1 intersection"); } }else{ snprintf(objective_string,160,_("%d intersections%s"), g->objective,(g->objective_lessthan? _(" or fewer"):"")); return objective_string; } } gplanarity-17906/gameboard_draw_curtain.c0000644000175000017500000000427111543161637020454 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include "graph.h" #include "gameboard.h" /* cache the curtain surface/pattern ******************************/ #define CW 4 void cache_curtain(Gameboard *g){ int x,y; cairo_t *wc = gdk_cairo_create(g->w.window); cairo_t *c; g->curtains= cairo_surface_create_similar (cairo_get_target (wc), CAIRO_CONTENT_COLOR_ALPHA, CW,CW); cairo_destroy(wc); c = cairo_create(g->curtains); cairo_save(c); cairo_set_operator(c,CAIRO_OPERATOR_CLEAR); cairo_set_source_rgba (c, 1,1,1,1); cairo_paint(c); cairo_restore(c); cairo_set_line_width(c,1); cairo_set_source_rgba (c, 0,0,0,.5); for(y=0;ycurtainp=cairo_pattern_create_for_surface (g->curtains); cairo_pattern_set_extend (g->curtainp, CAIRO_EXTEND_REPEAT); } void draw_curtain(Gameboard *g){ cairo_t *c = cairo_create(g->background); cairo_set_source (c, g->curtainp); cairo_paint(c); cairo_destroy(c); } gplanarity-17906/gameboard_draw_button.h0000644000175000017500000000506011543161637020324 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ extern void path_button_help(cairo_t *c, double x, double y); extern void path_button_back(cairo_t *c, double x, double y); extern void path_button_reset(cairo_t *c, double x, double y); extern void path_button_pause(cairo_t *c, double x, double y); extern void path_button_exit(cairo_t *c, double x, double y); extern void path_button_expand(cairo_t *c, double x, double y); extern void path_button_shrink(cairo_t *c, double x, double y); extern void path_button_lines(cairo_t *c, double x, double y); extern void path_button_int(cairo_t *c, double x, double y); extern void path_button_check(cairo_t *c, double x, double y); extern void path_button_play(cairo_t *c, double x, double y); #define BUTTON_QUIT_IDLE_FILL .7,.1,.1,.3 #define BUTTON_QUIT_IDLE_PATH .7,.1,.1,.6 #define BUTTON_QUIT_LIT_FILL .7,.1,.1,.5 #define BUTTON_QUIT_LIT_PATH .7,.1,.1,.6 #define BUTTON_IDLE_FILL .1,.1,.7,.3 #define BUTTON_IDLE_PATH .1,.1,.7,.6 #define BUTTON_LIT_FILL .1,.1,.7,.6 #define BUTTON_LIT_PATH .1,.1,.7,.6 #define BUTTON_CHECK_IDLE_FILL .1,.5,.1,.3 #define BUTTON_CHECK_IDLE_PATH .1,.5,.1,.6 #define BUTTON_CHECK_LIT_FILL .1,.5,.1,.6 #define BUTTON_CHECK_LIT_PATH .1,.5,.1,.6 #define BUTTON_RADIUS 14 #define BUTTON_Y_FROM_BOTTOM 25 #define BUTTON_LINE_WIDTH 1 #define BUTTON_TEXT_BORDER 15 #define BUTTON_TEXT_COLOR .1,.1,.7,.8 #define BUTTON_TEXT_SIZE 15.,18. #define BUTTON_ANIM_INTERVAL 15 #define BUTTON_LEFT 5 #define BUTTON_RIGHT 5 #define BUTTON_BORDER 35 #define BUTTON_SPACING 35 #define BUTTON_EXPOSE 50 #define DEPLOY_DELTA 6 #define SWEEP_DELTA 3 gplanarity-17906/dialog_pause.c0000644000175000017500000001424111543161637016423 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include #include #include "graph.h" #include "timer.h" #include "gameboard.h" #include "gameboard_draw_button.h" #include "dialog_pause.h" #include "main.h" static void unpause_post (Gameboard *g){ // back to buttonbar activity! pop_curtain(g); deploy_buttonbar(g); unpause_timer(); g->about_dialog_active=0; g->pause_dialog_active=0; } static void unpause_quit (Gameboard *g){ gtk_main_quit(); } static void local_unpause (Gameboard *g){ undeploy_buttons(g,unpause_post); } static void local_quit (Gameboard *g){ undeploy_buttons(g,unpause_quit); } /* initialize the rather weird little animation engine */ static void setup_pause_buttons(Gameboard *g,int bw, int bh){ int i; int w=g->g.width; int h=g->g.height; buttonstate *states=g->b.states; states[0].rollovertext=_("exit gPlanarity"); states[10].rollovertext=_("resume game!"); states[0].callback = local_quit; states[10].callback = local_unpause; for(i=0;ix = b->x_target = w/2 - bw/2 + PAUSE_BUTTON_BORDER; b->y_active = h/2 + bh/2 - PAUSE_BUTTON_Y; b->y = b->y_target = b->y_inactive = b->y_active + BUTTON_EXPOSE; b->sweepdeploy = 0; } { buttonstate *b=states+10; b->x = b->x_target = w/2 + bw/2 - PAUSE_BUTTON_BORDER; b->y_active = h/2 + bh/2 - PAUSE_BUTTON_Y; b->y = b->y_target = b->y_inactive = b->y_active + BUTTON_EXPOSE; b->sweepdeploy = SWEEP_DELTA; } for(i=0;ig.width; int h= g->g.height; cairo_t *c = cairo_create(g->background); borderbox_path(c, w/2 - PAUSEBOX_WIDTH/2, h/2 - PAUSEBOX_HEIGHT/2, PAUSEBOX_WIDTH, PAUSEBOX_HEIGHT); cairo_set_source_rgb(c,1,1,1); cairo_fill(c); centerbox(c, w/2 - PAUSEBOX_WIDTH/2, h/2 - PAUSEBOX_HEIGHT/2, PAUSEBOX_WIDTH, SCOREHEIGHT); centerbox(c, w/2 - PAUSEBOX_WIDTH/2 , h/2 + PAUSEBOX_HEIGHT/2 - SCOREHEIGHT, PAUSEBOX_WIDTH, SCOREHEIGHT); { char *time = get_timer_string(); set_font(c,18,18,0,1); cairo_set_source_rgba (c, TEXT_COLOR); render_text_centered(c,_("Game Paused"), w/2,h/2-PAUSEBOX_HEIGHT/2+SCOREHEIGHT/2); set_font(c,18,18,0,0); render_bordertext_centered(c,_("Time Elapsed:"), w/2,h/2-30); render_bordertext_centered(c,time, w/2,h/2); } cairo_destroy(c); } void pause_dialog(Gameboard *g){ g->pause_dialog_active=1; // set up new buttons setup_pause_buttons(g,PAUSEBOX_WIDTH, PAUSEBOX_HEIGHT); // draw pausebox push_curtain(g,draw_pausebox); // deploy new buttons deploy_buttons(g,0); } // the 'about' box is nearly identical, including the fact it pauses the game. // we just piggyback it here static void draw_aboutbox(Gameboard *g){ int w= g->g.width; int h= g->g.height; cairo_t *c = cairo_create(g->background); borderbox_path(c, w/2 - ABOUTBOX_WIDTH/2, h/2 - ABOUTBOX_HEIGHT/2, ABOUTBOX_WIDTH, ABOUTBOX_HEIGHT); cairo_set_source_rgb(c,1,1,1); cairo_fill(c); centerbox(c, w/2 - ABOUTBOX_WIDTH/2, h/2 - ABOUTBOX_HEIGHT/2, ABOUTBOX_WIDTH, SCOREHEIGHT); centerbox(c, w/2 - ABOUTBOX_WIDTH/2 , h/2 + ABOUTBOX_HEIGHT/2 - SCOREHEIGHT, ABOUTBOX_WIDTH, SCOREHEIGHT); { int y = h/2-ABOUTBOX_HEIGHT/2+SCOREHEIGHT/2; set_font(c,18,18,0,1); cairo_set_source_rgba (c, TEXT_COLOR); render_text_centered(c,_("gPlanarity"), w/2,y); set_font(c,18,18,0,0); y+=45; render_bordertext_centered(c,_("Untangle the mess!"), w/2,y); y+=30; set_font(c,13,13,0,0); render_bordertext_centered(c,_("Drag vertices to eliminate crossed lines."), w/2,y); y+=16; render_bordertext_centered(c,_("The objective may be a complete solution or"), w/2,y); y+=16; render_bordertext_centered(c,_("getting as close as possible to solving an"), w/2,y); y+=16; render_bordertext_centered(c,_("unsolvable puzzle. Work quickly and"), w/2,y); y+=16; render_bordertext_centered(c,_("exceed the objective for bonus points!"), w/2,y); y+=16; y+=16; cairo_move_to (c, w/2-100,y); cairo_line_to (c, w/2+100,y); cairo_stroke(c); y+=32; set_font(c,12,13,0,0); render_bordertext_centered(c,_("gPlanarity written by Monty "),w/2,y);y+=17; render_bordertext_centered(c,_("as a demonstration of Gtk+/Cairo"),w/2,y);y+=32; render_bordertext_centered(c,_("Original Flash version of Planarity by"),w/2,y);y+=17; render_bordertext_centered(c,_("John Tantalo "),w/2,y);y+=32; render_bordertext_centered(c,_("Original game concept by Mary Radcliffe"),w/2,y);y+=17; y = h/2+ABOUTBOX_HEIGHT/2-SCOREHEIGHT/2; set_font(c,10,11,0,1); render_text_centered(c,version, w/2,y); } cairo_destroy(c); } void about_dialog(Gameboard *g){ g->about_dialog_active=1; // set up new buttons setup_pause_buttons(g,ABOUTBOX_WIDTH,ABOUTBOX_HEIGHT); // draw about box push_curtain(g,draw_aboutbox); // deploy new buttons deploy_buttons(g,0); } gplanarity-17906/timer.h0000644000175000017500000000236411543161637015117 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include #include "nls.h" extern time_t get_timer(); extern char *get_timer_string(); extern void set_timer(time_t off); extern void pause_timer(); extern void unpause_timer(); extern int timer_paused_p(); gplanarity-17906/graph_region.c0000644000175000017500000004433611543161637016443 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include #include #include #include #include "graph.h" #include "graph_region.h" #include "nls.h" /* Regions are 'electric fences' for mesh building; used in mesh2 to make non-convex shapes */ typedef struct region_segment { int layout; /* 0 no layout, 1 left, 2 right, 3 layout-only */ int cont; /* is this continuous from last line? */ int split; /* are we splitting the graph into interntionally seperate regions here? */ float x1; float y1; float x2; float y2; // arc computation cache (if arc) float cx; float cy; float radius; float phi0; float phi1; float phi; float length; struct region_segment *next; } region_segment; typedef struct region{ int num; region_segment *l; int ox,oy,x,y; int layout; int cont; int split_next; } region; static region r; static region layout_adj; static region_segment *segpool=0; #define CHUNK 64 static region_segment *new_segment(region *r, int x1,int y1,int x2, int y2){ region_segment *ret; if(!segpool){ int i; segpool = calloc(CHUNK,sizeof(*segpool)); for(i=0;inext; memset(ret,0,sizeof(*ret)); ret->next = r->l; ret->layout=r->layout; ret->x1=x1; ret->y1=y1; ret->x2=x2; ret->y2=y2; ret->cont = r->cont; ret->split = r->split_next; r->l=ret; r->split_next=0; return ret; } /* angle convention: reversed y (1,-1 is first quadrant, ala X windows), range -PI to PI */ static int intersects_arc(edge *e, region_segment *r){ float Ax = e->A->x - r->cx; float Ay = e->A->y - r->cy; float Bx = e->B->x - r->cx; float By = e->B->y - r->cy; float dx = Bx - Ax; float dy = By - Ay; float dr2 = dx*dx + dy*dy; float D = Ax*By - Bx*Ay; float discriminant =(r->radius*r->radius)*dr2 - D*D; // does it even intersect the full circle? if(discriminant<=0)return 0; { float x1,y1,x2,y2; float sqrtd = sqrt(discriminant); float sign = (dy>0?1.f:-1.f); // finite precision required here else 0/inf slope lines will be // slighly off the secant x1 = rint((D*dy + sign*dx*sqrtd) / dr2); x2 = rint((D*dy - sign*dx*sqrtd) / dr2); y1 = rint((-D*dx + fabs(dy)*sqrtd) / dr2); y2 = rint((-D*dx - fabs(dy)*sqrtd) / dr2); Ax = rint(Ax); Ay = rint(Ay); Bx = rint(Bx); By = rint(By); // is x1,y1 actually on the segment? if( !(x1Ax && x1>Bx) && !(y1Ay && y1>By)){ // yes. it is in the angle range we care about? float ang = acos(x1 / r->radius); if(y1>0) ang = -ang; if(r->phi<0){ if(r->phi0 < r->phi1){ if(ang <= r->phi0 || ang >= r->phi1)return 1; }else{ if(ang <= r->phi0 && ang >= r->phi1)return 1; } }else{ if(r->phi0 < r->phi1){ if(ang >= r->phi0 && ang <= r->phi1)return 1; }else{ if(ang >= r->phi0 || ang <= r->phi1)return 1; } } } // is x2,y2 actually on the segment? // if so, it is in the arc range we care about? if( !(x2Ax && x2>Bx) && !(y2Ay && y2>By)){ // yes. it is in the angle range we care about? float ang = acos(x2 / r->radius); if(y2>0) ang = -ang; if(r->phi<0){ if(r->phi0 < r->phi1){ if(ang <= r->phi0 || ang >= r->phi1)return 1; }else{ if(ang <= r->phi0 && ang >= r->phi1)return 1; } }else{ if(r->phi0 < r->phi1){ if(ang >= r->phi0 && ang <= r->phi1)return 1; }else{ if(ang >= r->phi0 || ang <= r->phi1)return 1; } } } } return 0; } static float line_angle(float x1, float y1, float x2, float y2){ float xd = x2-x1; float yd = y2-y1; if(xd == 0){ if(yd>0) return -M_PI/2; else return M_PI/2; }else if(xd<0){ if(yd<0) return atan(-yd/xd)+M_PI; else return atan(-yd/xd)-M_PI; }else{ return atan(-yd/xd); } } static float line_mag(float x1, float y1, float x2, float y2){ float xd = x2-x1; float yd = y2-y1; return hypot(xd,yd); } static void compute_arc(region_segment *r,float phi){ float x1=r->x1; float y1=r->y1; float x2=r->x2; float y2=r->y2; float ar,br,cr; float cx,cy,a,c,d; float xd = x2-x1; float yd = y2-y1; if(phi<-M_PI){ ar = phi + M_PI*2; }else if (phi<0){ ar = -phi; }else if (phi0 && phicx=cx; r->cy=cy; r->radius=d; // have the center of the circle, have radius. Determine the // portion of the arc we want. r->phi0 = acos( (x1-cx) / d); r->phi1 = acos( (x2-cx) / d); if(y1>cy) r->phi0= -r->phi0; if(y2>cy) r->phi1= -r->phi1; r->phi=phi; } static region_segment *region_arc(region *re, int x1, int y1, int x2, int y2, float rad){ region_segment *n= new_segment(re,x1,y1,x2,y2); compute_arc(n,rad); return n; } static region_segment *region_line(region *re,int x1, int y1, int x2, int y2){ return new_segment(re,x1,y1,x2,y2); } /* The overall idea here is to massage the region segments and arcs slightly so that when we layout points based on a region, the layout is slightly inside or outside (as requested) the actual region. This also reverses the path when rebuilding into the new region, putting it in the order we actually need to evaluate it in. */ #define ADJ 2.f static void point_adj(float x1, float y1, float x2, float y2, float *Px, float *Py, int left){ float xd = x2-x1; float yd = y2-y1; float M = hypot(xd,yd); if(left){ *Px += yd/M*ADJ; *Py += -xd/M*ADJ; }else{ *Px += -yd/M*ADJ; *Py += xd/M*ADJ; } } static void line_adj(float *x1, float *y1, float *x2, float *y2, int left){ float xd = *x2-*x1; float yd = *y2-*y1; float M = hypot(xd,yd); if(left){ *x1 += yd/M*ADJ; *x2 += yd/M*ADJ; *y1 += -xd/M*ADJ; *y2 += -xd/M*ADJ; }else{ *x1 += -yd/M*ADJ; *x2 += -yd/M*ADJ; *y1 += xd/M*ADJ; *y2 += xd/M*ADJ; } // make sure there's an overlap! *x1-=xd/M*4.; *x2+=xd/M*4.; *y1-=yd/M*4.; *y2+=yd/M*4.; } static float tangent_distance_from_center(float x1, float y1, float x2, float y2, float cx, float cy){ float xd = x2 - x1; float yd = y2 - y1; return ((x2-x1)*(cy-y1) - (y2-y1)*(cx-x1)) / hypot(xd,yd); } static float radius_adjust(float r, float arc_phi, int left){ if(arc_phi<0){ if(left){ r+=ADJ; }else{ r-=ADJ; } }else{ if(left){ r-=ADJ; }else{ r+=ADJ; } } return r; } static void line_line_adj(region_segment *A, region_segment *B, float *new_x, float *new_y, int left){ double newd_x; double newd_y; float Ax1=A->x1; float Ay1=A->y1; float Ax2=A->x2; float Ay2=A->y2; float Bx1=B->x1; float By1=B->y1; float Bx2=B->x2; float By2=B->y2; line_adj(&Ax1, &Ay1, &Ax2, &Ay2, left); line_adj(&Bx1, &By1, &Bx2, &By2, left); // compute new intersection if(!intersects(Ax1,Ay1,Ax2,Ay2, Bx1,By1,Bx2,By2, &newd_x, &newd_y)){ // odd; do nothing rather than fail unpredictably *new_x=Ax2; *new_y=Ay2; }else{ *new_x=newd_x; *new_y=newd_y; } } static void line_arc_adj(float x1, float y1, float x2, float y2, float cx, float cy, float r, float arc_phi, float *new_x2, float *new_y2, int lleft, int aleft){ float xd = x2 - x1; float yd = y2 - y1; float c = tangent_distance_from_center(x1,y1,x2,y2,cx,cy); float a = sqrt(r*r - c*c),a2; float M = hypot(xd,yd); float ax = x2 + xd/M*a; float ay = y2 + yd/M*a; float ax1 = x2 - xd/M*a; float ay1 = y2 - yd/M*a; if(hypot(ax1-cx,ay1-cy) < hypot(ax-cx,ay-cy)){ ax=ax1; ay=ay1; } xd = ax-x2; yd = ay-y2; point_adj(x1, y1, x2, y2, &ax, &ay, lleft); r = radius_adjust(r,arc_phi,aleft); c = hypot(cx-ax,cy-ay); a2 = sqrt(r*r-c*c); *new_x2 = ax - xd/a*a2; *new_y2 = ay - yd/a*a2; } static void arc_arc_adj(region_segment *arc, region_segment *next, float *new_x2, float *new_y2, int left){ float x2 =arc->x2; float y2 =arc->y2; float cx1=arc->cx; float cy1=arc->cy; float r1 =arc->radius; float cx2=next->cx; float cy2=next->cy; float r2 =next->radius; float c; float xd = cx2-cx1; float yd = cy2-cy1; float d = hypot(xd,yd); float x = (d*d - r1*r1 + r2*r2) / (2*d); // is the old x2/y2 to the left or right of the line connecting the // circle centers? float angle_x2y2 = line_angle(cx1,cy1,x2,y2); float angle_c1c2 = line_angle(cx1,cy1,cx2,cy2); float angle = angle_x2y2 - angle_c1c2; if(angle < -M_PI)angle += M_PI*2.f; if(angle > M_PI)angle -= M_PI*2.f; r1=radius_adjust(r1,arc->phi,left); r2=radius_adjust(r2,arc->phi,left); if(r1+r2>=d){ // still have a valid solution x = (d*d - r1*r1 + r2*r2) / (2*d); c = sqrt(r2*r2 - x*x); if(angle>0){ // left of c1,c2 segment *new_x2 = cx1+xd/d*x + yd/d*c; *new_y2 = cy1+yd/d*x - xd/d*c; }else{ // right *new_x2 = cx1+xd/d*x - yd/d*c; *new_y2 = cy1+yd/d*x + xd/d*c; } }else{ // circles shrunk and no longer overlap. fprintf(stderr,_("region overlap adjustment failed in arc_arc_adj; \n" " This is an internal error that should never happen.\n")); } } static float phisub(float phi0, float phi1, float arcphi){ float phid = phi1-phi0; if(arcphi<0){ if(phid>0) phid -= M_PI*2.f; }else{ if(phid<0) phid += M_PI*2.f; } return phid; } static void radius_adj_xy(region_segment *s,float *x1,float *y1, int left){ float xd = *x1 - s->cx; float yd = *y1 - s->cy; float r = s->radius; float new_r = radius_adjust(r,s->phi,left); float delta = new_r/r; *x1 = s->cx + xd*delta; *y1 = s->cy + yd*delta; } static void adjust_layout(){ /* build adjustments from intersection region into layout region */ region_segment *s = r.l; region_segment *endpath = 0; region_segment *endpath_adj = 0; float x2=-1,y2=-1; // first, release previous layout region_segment *l=layout_adj.l; region_segment *le=l; while(le && le->next)le=le->next; if(le){ le->next=segpool; segpool=l; } memset(&layout_adj,0,sizeof(layout_adj)); while(s){ float x1=0,y1=0,phi=0,radius=0; if(s->cont){ if(!endpath){ endpath=s; endpath_adj=0; } } if(s->layout){ if(s->layout<3){ // the flags mark beginning and end of the path, but don't say // if it's closed. if(!s->cont && endpath_adj) if(endpath->x2 != s->x1 || endpath->y2 != s->y1) endpath_adj=0; /* first handle the lone-circle special case */ if(s->x1==s->x2 && s->y1==s->y2){ if(s->radius>0){ if(s->layout == 1) radius= s->radius+2; if(s->layout == 2) radius= s->radius-2; x1=x2=s->x1;y1=y2=s->y1; phi=s->phi; } }else{ region_segment *p = 0; if(s->cont) p = s->next; else if(endpath_adj) p = endpath; if(p){ if(s->radius){ if(x2==-1){ x2=s->x2; y2=s->y2; radius_adj_xy(s,&x2,&y2,s->layout==1); } if(p->radius){ // arc - arc case float phi0,phi1; arc_arc_adj(p,s,&x1,&y1,s->layout==1); phi0=line_angle(s->cx,s->cy,x1,y1); phi1=line_angle(s->cx,s->cy,x2,y2); phi=phisub(phi0,phi1,s->phi); }else{ // arc-line case float phi0,phi1; line_arc_adj(p->x1, p->y1, p->x2, p->y2, s->cx, s->cy, s->radius, s->phi, &x1, &y1, s->layout==1, s->layout==1); phi0=line_angle(s->cx,s->cy,x1,y1); phi1=line_angle(s->cx,s->cy,x2,y2); phi=phisub(phi0,phi1,s->phi); } }else{ if(x2==-1){ x2=s->x2; y2=s->y2; point_adj(s->x1, s->y1, s->x2, s->y2, &x2, &y2, s->layout==1); } if(p->radius){ // line-arc case line_arc_adj(s->x2, s->y2, s->x1, s->y1, p->cx, p->cy, p->radius, p->phi, &x1, &y1, s->layout==2, s->layout==1); }else{ // line-line case line_line_adj(p, s, &x1, &y1, s->layout==1); } } }else{ x1=s->x1; y1=s->y1; x2=s->x2; y2=s->y2; if(s->radius){ // lone arc case; alter radius radius_adj_xy(s,&x1,&y1,s->layout==1); radius_adj_xy(s,&x2,&y2,s->layout==1); phi=s->phi; }else{ // lone line segment case; offset point_adj(s->x1, s->y1, s->x2, s->y2, &x1, &y1, s->layout==1); point_adj(s->x1, s->y1, s->x2, s->y2, &x2, &y2, s->layout==1); } } } }else{ x1=s->x1; x2=s->x2; y1=s->y1; y2=s->y2; phi=s->phi; if(x1==x2 && y1==y2) radius = s->radius; } // push the region segment { region_segment *n=new_segment(&layout_adj,rint(x1),rint(y1),rint(x2),rint(y2)); n->layout=3; n->cont=(s->cont || endpath_adj); n->split = s->split; if(radius){ // circle; radius variable is treated as a flag n->cx=x1; n->cy=y1; n->radius=radius; n->phi0=-M_PI; n->phi1= M_PI; n->cont=1; }else if(s->radius){ // arc compute_arc(n,phi); } if(s->cont && !endpath_adj)endpath_adj=n; } if(endpath_adj && !s->cont){ // go back and clean up the endpath path member endpath_adj->x2 = rint(x1); endpath_adj->y2 = rint(y1); if(endpath->radius>0){ endpath_adj->phi1=line_angle(endpath->cx,endpath->cy,endpath_adj->x2,endpath_adj->y2); endpath_adj->phi=phisub(endpath_adj->phi0,endpath_adj->phi1,endpath_adj->phi); } } } if(!s->cont){ endpath_adj=0; endpath=0; x2=-1; y2=-1; }else{ x2=x1; y2=y1; } s=s->next; } } void region_init(){ // release any lines and arcs region_segment *l=r.l; region_segment *le=r.l; region_segment *a=layout_adj.l; region_segment *ae=layout_adj.l; while(le && le->next)le=le->next; while(ae && ae->next)ae=ae->next; if(le){ le->next=segpool; segpool=l; } if(ae){ ae->next=segpool; segpool=a; } memset(&r,0,sizeof(r)); memset(&layout_adj,0,sizeof(layout_adj)); } int region_layout(graph *g){ // count up the total length of the region segments used in layout float length=0,acc=0,ldel; int num_adj=g->vertex_num; int activenum=0; region_segment *l; vertex *v = g->verticies; adjust_layout(); l = layout_adj.l; while(l){ if(l->radius==0){ float xd=l->x2 - l->x1; float yd=l->y2 - l->y1; length += l->length = hypot(xd,yd); }else{ float diam = l->radius*2.f*M_PI; float del=phisub(l->phi0,l->phi1,l->phi); if(l->phi<0) del = -del; length += l->length = diam*del*(1.f/(M_PI*2.f)); } l=l->next; } // non-contiguous beginnings sink a single point segment per l = layout_adj.l; while(l){ if(!l->cont) num_adj--; l=l->next; } /* perform layout segment by segment */ l = layout_adj.l; ldel = (float)length/num_adj; while(l && v){ int i; int num_placed = l->cont ? rint((l->length-acc)/ldel) : rint((l->length-acc)/ldel)+1; float snap_del = l->cont ? l->length/num_placed : l->length/(num_placed-1); float snap_acc=l->cont?snap_del:0; if(l->split)activenum++; if(l->radius==0){ float x1 = l->x1; float y1 = l->y1; float x2 = l->x2; float y2 = l->y2; float xd=(x2-x1)/l->length; float yd=(y2-y1)/l->length; for(i=0;v && ix = rint(x1+xd*snap_acc); v->y = rint(y1+yd*snap_acc); if(snap_acc) acc+=ldel; snap_acc+=snap_del; v->active=activenum; v=v->next; } }else{ /* next is an arc */ float x = l->cx; float y = l->cy; float phid = phisub(l->phi0,l->phi1,l->phi); phid /= l->length; for(i=0;v && ix = rint( cos(l->phi0+phid*snap_acc)*(l->radius)+x); v->y = rint( -sin(l->phi0+phid*snap_acc)*(l->radius)+y); if(snap_acc) acc+=ldel; snap_acc+=snap_del; v->active=activenum; v=v->next; } } acc-=l->length; l=l->next; } return activenum; } void region_circle(int x,int y, float rad, int layout){ region_segment *a=new_segment(&r,0,0,0,0); a->cx=a->x1=a->x2=x; a->cy=a->y1=a->y2=y; a->radius=rad; a->phi0=-M_PI; a->phi1=M_PI; a->phi=M_PI*2.f; a->layout=layout; a->cont=0; // not really necessary, just consistent r.cont=0; } void region_new_area(int x, int y, int layout){ r.x=r.ox=x; r.y=r.oy=y; r.layout=layout; r.cont=0; } void region_line_to(int x,int y){ region_line(&r,r.x,r.y,x,y); r.x=x; r.y=y; r.cont=1; } void region_arc_to(int x,int y, float rad){ region_arc(&r,r.x,r.y,x,y,rad); r.x=x; r.y=y; r.cont=1; } void region_close_line(){ region_line(&r,r.x,r.y,r.ox,r.oy); r.x=r.ox; r.y=r.oy; r.cont=0; } void region_close_arc(float rad){ region_arc(&r,r.x,r.y,r.ox,r.oy,rad); r.x=r.ox; r.y=r.oy; r.cont=0; } void region_split_here(){ r.split_next=1; } int region_intersects(edge *e){ region_segment *s=r.l; while(s){ if(s->layout<3){ if(s->radius!=0){ if(intersects_arc(e,s))return 1; }else{ double xdummy,ydummy; if(intersects(e->A->x,e->A->y,e->B->x,e->B->y, s->x1,s->y1,s->x2,s->y2, &xdummy,&ydummy))return 1; } } s=s->next; } return 0; } int have_region(){ if(r.l)return 1; return 0; } gplanarity-17906/dialog_level.h0000644000175000017500000000267611543161637016433 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define LEVEL_BUTTON_BORDER 35 #define LEVEL_BUTTON_Y 25 #define LEVELBOX_WIDTH 560 #define LEVELBOX_HEIGHT 370 #define ICON_DELTA 20 extern void level_dialog(Gameboard *g,int advance); extern void render_level_icons(Gameboard *g, cairo_t *c, int ex,int ey, int ew, int eh); extern void level_icons_init(Gameboard *g); extern void level_mouse_motion(Gameboard *g, int x, int y); extern void level_mouse_press(Gameboard *g, int x, int y); extern void local_reset (Gameboard *g); gplanarity-17906/nls.h0000644000175000017500000000051611543161637014570 0ustar vincentvincent#ifdef ENABLE_NLS #include "gettext.h" #include #include #define GT_DOMAIN X_GT_DOMAIN(UGT_DOMAIN) #define X_GT_DOMAIN(x) XX_GT_DOMAIN(x) #define XX_GT_DOMAIN(x) #x #define GT_DIR X_GT_DIR(UGT_DIR) #define X_GT_DIR(x) XX_GT_DIR(x) #define XX_GT_DIR(x) #x #define _(x) gettext(x) #else #define _(x) x #endif gplanarity-17906/graph_generate.h0000644000175000017500000000315711543161637016753 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #include "nls.h" extern int generate_find_number(char *id); extern int generate_get_meta(int num, graphmeta *gm); extern void generate_board(graph *g,int num); extern void generate_simple(graph *g, int order); extern void generate_nasty(graph *g, int order); extern void generate_sparse(graph *g, int order); extern void generate_dense(graph *g, int order); extern void generate_rogue(graph *g, int order); extern void generate_embed(graph *g, int order); extern void generate_crest(graph *g, int order); extern void generate_data(graph *g, int order); extern void generate_freeform(graph *g, int order); extern void generate_shape(graph *g, int order); gplanarity-17906/levelstate.c0000644000175000017500000002164411543161637016144 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include #include #include #include "graph.h" #include "timer.h" #include "levelstate.h" #include "gameboard.h" #include "dialog_pause.h" #include "dialog_finish.h" #include "dialog_level.h" #include "main.h" #include "graph_generate.h" #define CHUNK 64 #define SAVENAME "levelstate" typedef struct levelstate{ struct levelstate *prev; struct levelstate *next; graphmeta gm; int in_progress; long highscore; } levelstate; static levelstate *head=0; static levelstate *tail=0; static levelstate *curr=0; static levelstate *pool=0; static int graph_dirty = 1; static int aboutflag = 0; static int pauseflag = 0; static int finishflag = 0; static int selectflag = 0; static int level_limit = 1; static levelstate *new_level(){ levelstate *ret; int num=0; if(pool==0){ int i; pool = calloc(CHUNK,sizeof(*pool)); for(i=0;inext points to nothing */ pool[i].next=pool+i+1; } ret=pool; if(tail) num=tail->gm.num+1; if(generate_get_meta(num, &ret->gm)) return 0; pool=ret->next; ret->next=0; ret->prev=tail; if(tail){ ret->prev->next=ret; }else{ head=ret; } tail=ret; ret->highscore=0; ret->in_progress=0; /* write out a 'fresh' board icon if it doesn't already exist */ if(!gameboard_icon_exists(ret->gm.id,"1")){ // generate a graph we can use to make the icon graph g; memset(&g,0,sizeof(g)); g.width=gameboard->g.orig_width; g.height=gameboard->g.orig_height; g.orig_width=gameboard->g.orig_width; g.orig_height=gameboard->g.orig_height; generate_board(&g,num); impress_location(&g); gameboard_write_icon(ret->gm.id,"1",gameboard,&g,1,1); // releases the temporary graph memory graph_release(&g); } return ret; } static levelstate *ensure_level_num(int level){ if(level<0)return 0; if(!tail)new_level(); if(level <= tail->gm.num){ // find it in the existing levels levelstate *l=tail; while(l){ if(level == l->gm.num) return l; l=l->prev; } return 0; }else{ // make new levels to fill while(tail->gm.numin_progress || gameboard->finish_dialog_active)){ gameboard_write(curr->gm.id,gameboard); gameboard_write_icon(curr->gm.id,"2",gameboard,&gameboard->g, !gameboard->hide_lines,gameboard->show_intersections); } f = fopen(name,"wb"); if(f==NULL){ fprintf(stderr,_("ERROR: Could not save game state file \"%s\":\n\t%s\n"), curr->gm.id,strerror(errno)); return errno; } fprintf(f,"current %d : %s\n",(int)strlen(curr->gm.id),curr->gm.id); { levelstate *l=head; while(l){ fprintf(f,"level %ld %d %d : %s\n", l->highscore,l->in_progress, (int)strlen(l->gm.id),l->gm.id); l=l->next; } } if(gameboard->about_dialog_active) fprintf(f,"about 1\n"); if(gameboard->pause_dialog_active) fprintf(f,"pause 1\n"); if(gameboard->finish_dialog_active) fprintf(f,"finish 1\n"); if(gameboard->level_dialog_active) fprintf(f,"select 1\n"); fclose(f); return 0; } // also functions as the levelstate init; always called once upon startup int levelstate_read(){ char *line=NULL; size_t n=0; FILE *f; char *name=alloca(strlen(statedir)+strlen(SAVENAME)+1); name[0]=0; strcat(name,statedir); strcat(name,SAVENAME); if(!head)new_level(); if(!curr)curr=head; f = fopen(name,"rb"); if(f==NULL){ if(errno!=ENOENT){ fprintf(stderr,_("ERROR: Could not read game state file \"%s\":\n\t%s\n"), curr->gm.id,strerror(errno)); } return errno; } // get all levels we've seen. while(getline(&line,&n,f)>0){ long l; int i; unsigned int j; if (sscanf(line,"level %ld %d %d : ",&l,&i,&j)==3){ char *name=strchr(line,':'); // guard against bad edits if(name && (strlen(line) - (name - line + 2) >= j)){ levelstate *le; name += 2; name[j]=0; le = ensure_level(name); if(le){ le->highscore=l; le->in_progress=i; if(le->highscore) if(le->gm.unlock_plus + le->gm.num > level_limit) level_limit = le->gm.unlock_plus + le->gm.num; } } } } rewind(f); // get current while(getline(&line,&n,f)>0){ int i; if (sscanf(line,"current %d : ",&i)==1){ char *name=strchr(line,':'); // guard against bad edits if(name && (strlen(line) - (name - line + 2) >= (unsigned)i)){ levelstate *le; name += 2; name[i]=0; le = ensure_level(name); if(le) curr=le; } } if(sscanf(line,"about %d",&i)==1) if(i==1) aboutflag=1; if(sscanf(line,"pause %d",&i)==1) if(i==1) pauseflag=1; if(sscanf(line,"finish %d",&i)==1) if(i==1) finishflag=1; if(sscanf(line,"select %d",&i)==1) if(i==1) selectflag=1; } while(curr->gm.num >= level_limit){ levelstate_prev(); } return 0; } void levelstate_resume(){ levelstate_go(); if(pauseflag){ prepare_reenter_game(gameboard); pause_dialog(gameboard); }else if (aboutflag){ prepare_reenter_game(gameboard); about_dialog(gameboard); }else if (finishflag){ prepare_reenter_game(gameboard); finish_level_dialog(gameboard); }else if (selectflag){ prepare_reenter_game(gameboard); level_dialog(gameboard,0); }else{ prepare_reenter_game(gameboard); reenter_game(gameboard); } aboutflag=0; pauseflag=0; finishflag=0; selectflag=0; } void set_in_progress(){ curr->in_progress=1; } long levelstate_total_hiscore(){ long score=0; levelstate *l=head; while(l){ score+=l->highscore; l=l->next; } return score; } long levelstate_get_hiscore(){ if(!curr)return 0; return curr->highscore; } int levelstate_next(){ if(!curr->next) new_level(); if(curr->next){ curr=curr->next; graph_dirty=1; return 1; } return 0; } int levelstate_prev(){ if(curr->prev){ curr=curr->prev; graph_dirty=1; return 1; } return 0; } int get_level_num(){ return curr->gm.num; } char *get_level_desc(){ return _(curr->gm.desc); } void levelstate_finish(){ int score = graphscore_get_score(&gameboard->g) + graphscore_get_bonus(&gameboard->g); curr->in_progress=0; if(score > curr->highscore) curr->highscore = score; if(curr->gm.unlock_plus + curr->gm.num > level_limit) level_limit = curr->gm.unlock_plus + curr->gm.num; } void levelstate_reset(){ curr->in_progress=0; graph_dirty=1; } int levelstate_in_progress(){ return curr->in_progress; } int levelstate_limit(){ return level_limit; } /* commit to the currently selected level and set the game state to readiness using it */ void levelstate_go(){ // we need to load the board if we're currently playing the board or sitting in the finish dialog right after if(curr->in_progress || finishflag){ if(gameboard_read(curr->gm.id,gameboard)){ /* not on disk or couldn't load it. clear level state flags and get a fresh version */ aboutflag=0; pauseflag=0; finishflag=0; selectflag=0; generate_board(&gameboard->g,curr->gm.num); activate_verticies(&gameboard->g); impress_location(&gameboard->g); set_timer(0); } }else{ /* no board in progress; fetch a new board */ generate_board(&gameboard->g,curr->gm.num); activate_verticies(&gameboard->g); impress_location(&gameboard->g); set_timer(0); } graph_dirty=0; } cairo_surface_t *levelstate_get_icon(int num){ levelstate *l=ensure_level_num(num); if(l==0)return 0; return gameboard_read_icon(l->gm.id,(l->in_progress?"2":"1"),gameboard); } gplanarity-17906/Makefile0000644000175000017500000000672711543161637015275 0ustar vincentvincent# Fuck Automake # Fuck the horse it rode in on # and Fuck its little dog Libtool too TARGET = gPlanarity CC = gcc LD = gcc export INSTALL = install PREFIX = /usr/local BINDIR = $(PREFIX)/bin ETCDIR = /etc/$(TARGET) MANDIR = $(PREFIX)/man #DISABLE_NLS = true # White space delimited list of locales you want to support. Defaults to all # available ones. #export WANT_LINGUAS := cs # All subdirs with Makefiles SUBDIRS = # By default, enable NLS ifeq ($(origin DISABLE_NLS), undefined) export GT_DOMAIN = $(TARGET) export GT_DIR = $(PREFIX)/share/locale ADD_DEF += -DUGT_DOMAIN="$(GT_DOMAIN)" -DUGT_DIR="$(GT_DIR)" -DENABLE_NLS SUBDIRS += po endif SRC = dialog_finish.c gameboard_logic.c dialog_pause.c gameboard_logic_button.c\ gameboard.c gameboard_logic_buttonbar.c gameboard_draw_box.c\ gameboard_logic_mouse.c gameboard_draw_button.c gameboard_logic_push.c\ gameboard_draw_buttonbar.c graph.c gameboard_draw_curtain.c\ graph_score.c graph_arrange.c gameboard_draw_edge.c graph_generate.c\ gameboard_draw_intersection.c graph_generate_mesh1.c gameboard_draw_main.c\ gameboard_draw_score.c main.c gameboard_draw_selection.c\ timer.c gameboard_draw_vertex.c levelstate.c dialog_level.c\ dialog_level_icons.c gameboard_draw_text.c random.c graph_generate_data.c\ gameboard_logic_fade.c graph_generate_mesh2.c graph_region.c OBJ = dialog_finish.o gameboard_logic.o dialog_pause.o gameboard_logic_button.o\ gameboard.o gameboard_logic_buttonbar.o gameboard_draw_box.o\ gameboard_logic_mouse.o gameboard_draw_button.o gameboard_logic_push.o\ gameboard_draw_buttonbar.o graph.o gameboard_draw_curtain.o\ graph_score.o graph_arrange.o gameboard_draw_edge.o graph_generate.o\ gameboard_draw_intersection.o graph_generate_mesh1.o gameboard_draw_main.o\ gameboard_draw_score.o main.o gameboard_draw_selection.o\ timer.o gameboard_draw_vertex.o levelstate.o dialog_level.o\ dialog_level_icons.o gameboard_draw_text.o random.o graph_generate_data.o\ gameboard_logic_fade.o graph_generate_mesh2.o graph_region.o CAIROVER = >= 1.0.0 GTKVER = >= 2.7.2 GCF = `pkg-config --cflags "gtk+-2.0 $(GTKVER) cairo $(CAIROVER) freetype2"` LDF = `pkg-config --libs "gtk+-2.0 $(GTKVER) cairo $(CAIROVER) freetype2"` all: all-local all-recursive all-local: pkg-config --cflags "gtk+-2.0 $(GTKVER) cairo $(CAIROVER) freetype2" 1>/dev/null $(MAKE) target CFLAGS='-O2 -ffast-math $(GCF) $(ADD_DEF)' all-recursive: for D in $(SUBDIRS); do make -C $$D || exit 1; done debug: pkg-config --cflags "gtk+-2.0 $(GTKVER) cairo $(CAIROVER) freetype2" 1>/dev/null $(MAKE) target CFLAGS='-g -Wall -W -Wno-unused-parameter -D__NO_MATH_INLINES $(GCF) $(ADD_DEF)' profile: pkg-config --cflags "gtk+-2.0 $(GTKVER) cairo $(CAIROVER) freetype2" 1>/dev/null $(MAKE) target CFLAGS='-pg -g -O2 -ffast-math $(GCF) $(ADD_DEF)" LIBS="$(LIBS) -lgprof-helper' clean: clean-local clean-recursive clean-local: rm -f $(OBJ) *.d *.d.* gmon.out $(TARGET) clean-recursive: for D in $(SUBDIRS); do make -C $$D clean || exit 1; done distclean: clean rm -f *~ %.d: %.c $(CC) -M $(CFLAGS) $< > $@.$$$$; sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; rm -f $@.$$$$ ifeq ($(MAKECMDGOALS),target) include $(SRC:.c=.d) endif target: $(OBJ) ./touch-version $(LD) $(OBJ) $(CFLAGS) -o $(TARGET) $(LIBS) $(LDF) install: install-local install-recursive install-local: target $(INSTALL) -d -m 0755 $(BINDIR) $(INSTALL) -m 0755 $(TARGET) $(BINDIR) install-recursive: for D in $(SUBDIRS); do make -C $$D install || exit 1; done gplanarity-17906/gameboard_logic_buttonbar.h0000644000175000017500000000257011543161637021154 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define BUTTONBAR_Y_FROM_BOTTOM 25 #define BUTTONBAR_LINE_WIDTH 1 #define BUTTONBAR_TEXT_BORDER 15 #define BUTTONBAR_TEXT_COLOR .1,.1,.7,.8 #define BUTTONBAR_TEXT_SIZE 15.,18. #define BUTTONBAR_ANIM_INTERVAL 15 #define BUTTONBAR_EXPOSE 50 #define BUTTONBAR_DELTA 3 #define BUTTONBAR_LEFT 5 #define BUTTONBAR_RIGHT 5 #define BUTTONBAR_BUTTONS 5 #define BUTTONBAR_BORDER 35 #define BUTTONBAR_SPACING 35 gplanarity-17906/gameboard_logic_push.c0000644000175000017500000000434211543161637020125 0ustar vincentvincent/* * * gPlanarity: * The geeky little puzzle game with a big noodly crunch! * * gPlanarity copyright (C) 2005 Monty * Original Flash game by John Tantalo * Original game concept by Mary Radcliffe * * gPlanarity is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * gPlanarity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Postfish; see the file COPYING. If not, write to the * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include "graph.h" #include "gameboard.h" void update_push(Gameboard *g, cairo_t *c){ if(g->pushed_curtain){ int w = g->g.width; int h = g->g.height; draw_foreground(g,c,0,0,w,h); // copy in the score and button surfaces cairo_set_source_surface(c,g->forescore,0,0); cairo_rectangle(c, 0,0,w, min(SCOREHEIGHT,h)); cairo_fill(c); cairo_set_source_surface(c,g->forebutton,0,h-SCOREHEIGHT); cairo_rectangle(c, 0,0,w,h); cairo_fill(c); if(g->show_intersections) draw_intersections(g,&g->g,c,0,0,w,h); cairo_set_source (c, g->curtainp); cairo_paint(c); if(g->redraw_callback)g->redraw_callback(g); } } void push_curtain(Gameboard *g,void(*redraw_callback)(Gameboard *g)){ if(!g->pushed_curtain){ cairo_t *c = cairo_create(g->background); g->pushed_curtain=1; g->redraw_callback=redraw_callback; update_push(g,c); cairo_destroy(c); expose_full(g); //gameboard_draw(g,0,0,w,h); } } void pop_curtain(Gameboard *g){ if(g->pushed_curtain){ g->pushed_curtain=0; update_full(g); } }