static void PG_UpdateRects(_THIS, int numrects, SDL_Rect *rects) { int i; for (i = 0; i < numrects; i++) { if (rects[i].w <= 0 || rects[i].h <= 0) continue; /* Schedule an incremental update for this rectangle, using * the canvas gropnodes we've loaded beforehand. */ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_FINDGROP, 1, 0); pgWriteCmd(this->hidden->wCanvas, PGCANVAS_MOVEGROP, 4, rects[i].x, rects[i].y, rects[i].w, rects[i].h); pgWriteCmd(this->hidden->wCanvas, PGCANVAS_FINDGROP, 1, 1); pgWriteCmd(this->hidden->wCanvas, PGCANVAS_MOVEGROP, 4, rects[i].x, rects[i].y, rects[i].w, rects[i].h); /* Go perform the update */ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_INCREMENTAL, 0); pgSubUpdate(this->hidden->wCanvas); } }
void set_vfd_text(pghandle vfd,const char *text) { /* Use the lower level canvas commands to change the VFD's text. * The display's previous text is stored as its payload so we can * delete it, and we set the new text by changing the text gropnode's * parameter */ pghandle h; pgDelete(pgGetPayload(vfd)); h = pgNewString(text); pgWriteCmd(vfd,PGCANVAS_SETGROP,1,h); pgWriteCmd(vfd,PGCANVAS_REDRAW,0); pgSetPayload(vfd,h); }
/* Start a new level */ void startLevel(int newlev) { int i,j,x; light *p = board; /* Set up variables */ moves = 0; level = newlev; memset(board,0,boardsize); memset(solution,0,boardsize); /* Make random moves */ for (x=level;x;x--) { i = random() % boardwidth; j = random() % boardheight; invertLightNoupdate(i,j); invertLightNoupdate(i-1,j); invertLightNoupdate(i+1,j); invertLightNoupdate(i,j-1); invertLightNoupdate(i,j+1); SOLUTION(i,j) ^= 1; } /* Set the gropnode states */ for (j=0;j<boardheight;j++) for (i=0;i<boardwidth;i++) setLight(i,j,*(p++)); pgWriteCmd(wCanvas,PGCANVAS_INCREMENTAL,0); /* Update the status message and run pgUpdate() */ updateStatus(); }
/* Clickski! */ int evtMouseDown(struct pgEvent *evt) { int lx,ly; light *p; int i; /* What light was it in? */ lx = (evt->e.pntr.x - bx) / lightw; ly = (evt->e.pntr.y - by) / lighth; if (evt->e.pntr.x < bx || lx >= boardwidth || evt->e.pntr.y < by || ly >= boardwidth) return 0; invertLight(lx,ly); invertLight(lx-1,ly); invertLight(lx+1,ly); invertLight(lx,ly-1); invertLight(lx,ly+1); SOLUTION(lx,ly) ^= 1; /* Update the screen */ pgWriteCmd(evt->from,PGCANVAS_INCREMENTAL,0); moves++; updateStatus(); /* A win condition? */ for (i=boardsize,p=board;i;i--,p++) if (*p) return 0; /* Nope. */ /* Yep! */ pgMessageDialogFmt("Blackout!",0, "You completed level %d!\n\n" "Moves: %d",level,moves); startLevel(level+1); return 0; }
static int redraw_world(int zone) { ENTER("redraw_world(int zone)"); int must_update = 0; /* draw the world */ pgSetLgop(gfx_context, PG_LGOP_NONE); pgWriteCmd(main_window, PGCANVAS_GROP, 6, PG_GROP_BITMAP, 0, 0, width, height, world_bitmap); /* draw a zone */ if(zone>=0) { set_color(0x505050); pgSetLgop(gfx_context, PG_LGOP_ADD); draw_zone(zone); pgSetLgop(gfx_context, PG_LGOP_NONE); must_update = 1; } LEAVE; return must_update; }
/* Redraw the game board */ int evtDrawBoard(struct pgEvent *evt) { int x,y,i,j; light *p = board; /* Extra space on the sides or top and bottom? */ if (evt->e.size.w < evt->e.size.h) bs = evt->e.size.w-4; else bs = evt->e.size.h-4; bx = (evt->e.size.w - bs)>>1; by = (evt->e.size.h - bs)>>1; lightw = bs/boardwidth; lighth = bs/boardheight; /* Get rid of remainder */ bs = boardwidth*lightw; /* Clear the groplist, by default store color with each grop */ pgWriteCmd(evt->from,PGCANVAS_NUKE,0); pgWriteCmd(evt->from,PGCANVAS_DEFAULTFLAGS,1,PG_GROPF_COLORED); /* Black game board background */ pgWriteCmd(evt->from,PGCANVAS_GROP,6,PG_GROP_RECT,0,0, evt->e.size.w,evt->e.size.h,0x000000); /* Game board frame */ pgWriteCmd(evt->from,PGCANVAS_GROP,6,PG_GROP_FRAME, bx-1,by-1,bs+3,bs+3,0x808080); /* Light gropnodes */ for (j=boardheight,y=by;j;j--,y+=lighth) for (i=boardwidth,x=bx;i;i--,x+=lightw) { pgWriteCmd(evt->from,PGCANVAS_GROP,6,PG_GROP_RECT, x+1,y+1,lightw-1,lighth-1,(*(p++)) ? ON_COLOR : OFF_COLOR); } /* Draw it */ pgWriteCmd(evt->from,PGCANVAS_REDRAW,0); pgUpdate(); return 0; }
SDL_Surface *PG_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { if ( this->hidden->bitmap ) { /* Free old bitmap */ if (current->pixels) { shmdt(current->pixels); current->pixels = NULL; } pgDelete(this->hidden->bitmap); } /* Allocate the new pixel format for the screen */ if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) { SDL_SetError("Couldn't allocate new pixel format for requested mode"); return(NULL); } /* Create a new picogui bitmap */ this->hidden->bitmap = pgCreateBitmap(width,height); this->hidden->shm = *pgMakeSHMBitmap(this->hidden->bitmap); current->pixels = shmat(shmget(this->hidden->shm.shm_key, this->hidden->shm.shm_length,0),NULL,0); /* Reset the canvas, and draw persistent and incremental grops. * Use mapping and offsets to center it. */ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_NUKE, 0); /* 0. Set the source position during incremental rendering */ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_GROP, 5, PG_GROP_SETSRC,0,0,0,0); pgWriteCmd(this->hidden->wCanvas, PGCANVAS_GROPFLAGS, 1, PG_GROPF_INCREMENTAL); /* 1. Incremental bitmap rendering */ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_GROP, 6, PG_GROP_BITMAP, 0,0,0,0,this->hidden->bitmap); pgWriteCmd(this->hidden->wCanvas, PGCANVAS_GROPFLAGS, 1, PG_GROPF_INCREMENTAL); /* 2. Normal bitmap rendering */ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_GROP, 6, PG_GROP_BITMAP, 0,0,this->hidden->shm.width,this->hidden->shm.height,this->hidden->bitmap); /* Set up the new mode framebuffer */ current->flags = 0; current->w = this->hidden->shm.width; current->h = this->hidden->shm.height; current->pitch = this->hidden->shm.pitch; /* Set up pixel format */ current->format->BitsPerPixel = this->hidden->shm.bpp; current->format->BytesPerPixel = this->hidden->shm.bpp >> 3; if (this->hidden->shm.bpp & 7) current->format->BytesPerPixel++; current->format->palette = NULL; current->format->Rmask = this->hidden->shm.red_mask; current->format->Gmask = this->hidden->shm.green_mask; current->format->Bmask = this->hidden->shm.blue_mask; current->format->Amask = this->hidden->shm.alpha_mask; current->format->Rshift = this->hidden->shm.red_shift; current->format->Gshift = this->hidden->shm.green_shift; current->format->Bshift = this->hidden->shm.blue_shift; current->format->Ashift = this->hidden->shm.alpha_shift; current->format->Rloss = 8 - this->hidden->shm.red_length; current->format->Gloss = 8 - this->hidden->shm.green_length; current->format->Bloss = 8 - this->hidden->shm.blue_length; current->format->Aloss = 8 - this->hidden->shm.alpha_length; /* Draw the app */ pgUpdate(); /* We're done */ return(current); }
/* Set the state of the specified light gropnode */ void setLight(int lx,int ly,light l) { pgWriteCmd(wCanvas,PGCANVAS_FINDGROP,1,LIGHTGROP(lx,ly)); pgWriteCmd(wCanvas,PGCANVAS_SETGROP,1,l ? ON_COLOR : OFF_COLOR); pgWriteCmd(wCanvas,PGCANVAS_GROPFLAGS,1,PG_GROPF_PSEUDOINCREMENTAL | PG_GROPF_COLORED); }
int main(int argc, char** argv) { pgcolor color; struct pgmodeinfo mi; int i; pghandle ttl_box; /* init PicoGUI client */ pgInit(argc,argv); pgRegisterApp(PG_APP_NORMAL, argv[0], 0); /* create the title */ ttl_box = pgNewWidget(PG_WIDGET_BOX,0,0); ttl_text = pgNewWidget(PG_WIDGET_LABEL, PG_DERIVE_INSIDE, ttl_box); pgSetWidget (PGDEFAULT, PG_WP_TEXT, pgNewString("wclock"), 0); pgNewWidget(PG_WIDGET_BUTTON, PG_DERIVE_INSIDE, ttl_box); pgSetWidget (PGDEFAULT, PG_WP_SIDE, PG_S_RIGHT, PG_WP_TEXT, pgNewString("?"), PG_WP_EXTDEVENTS, PG_EXEV_PNTR_DOWN, 0); pgBind (PGDEFAULT, PG_WE_PNTR_DOWN, &btn_handler, (void*)btnid_set); pgNewWidget(PG_WIDGET_BUTTON, PG_DERIVE_INSIDE, ttl_box); pgSetWidget (PGDEFAULT, PG_WP_SIDE, PG_S_LEFT, PG_WP_TEXT, pgNewString(">"), PG_WP_EXTDEVENTS, PG_EXEV_PNTR_DOWN, 0); pgBind (PGDEFAULT, PG_WE_PNTR_DOWN, &btn_handler, (void*)btnid_right); pgNewWidget(PG_WIDGET_BUTTON, PG_DERIVE_INSIDE, ttl_box); pgSetWidget (PGDEFAULT, PG_WP_SIDE, PG_S_LEFT, PG_WP_TEXT, pgNewString("<"), PG_WP_EXTDEVENTS, PG_EXEV_PNTR_DOWN, 0); pgBind (PGDEFAULT, PG_WE_PNTR_DOWN, &btn_handler, (void*)btnid_left); /* create the main context */ main_window = pgNewWidget(PG_WIDGET_CANVAS, PG_DERIVE_AFTER, ttl_box); pgBind(PGDEFAULT, PGBIND_ANY, &canvas_handler, NULL); /* init time zones */ init_zones(); /* activate mouse move, keyboard and focus events */ pgSetWidget(main_window, PG_WP_TRIGGERMASK, pgGetWidget(main_window, PG_WP_TRIGGERMASK) | PG_TRIGGER_MOVE | PG_TRIGGER_CHAR | PG_TRIGGER_KEYDOWN | PG_TRIGGER_KEYUP /* | PG_TRIGGER_ACTIVATE | PG_TRIGGER_DEACTIVATE */, 0); mi = *pgGetVideoMode(); width = mi.lxres; height = mi.lyres; /* Make a backbuffer bitmap */ world_bitmap = create_world_bitmap(); width = get_world_width(); height = get_world_height(); /* Set the clipping rectangle */ pgWriteCmd(main_window, PGCANVAS_GROP, 5, PG_GROP_SETCLIP, 0, 0, width, height + TIMEBAR_HEIGHT); /* Set to be always rendered */ pgWriteCmd(main_window, PGCANVAS_GROPFLAGS, 1, PG_GROPF_UNIVERSAL); /* Create contexts for the canvas itself and the back-buffer */ gfx_context = pgNewCanvasContext(main_window, PGFX_IMMEDIATE ); /* run all */ DPRINTF(">>> entering loop\n"); pgEventLoop(); return 0; }