void InventoryScreen::Draw(Bitmap *ds) { color_t draw_color = ds->GetCompatibleColor(play.sierra_inv_color); ds->FillRect(Rect(0,0,windowwid,windowhit), draw_color); draw_color = ds->GetCompatibleColor(0); ds->FillRect(Rect(barxp,bartop, windowwid - 2,buttonyp-1), draw_color); for (int i = top_item; i < numitems; ++i) { if (i >= top_item + num_visible_items) break; Bitmap *spof=spriteset[dii[i].sprnum]; wputblock(ds, barxp+1+((i-top_item)%4)*widest+widest/2-spof->GetWidth()/2, bartop+1+((i-top_item)/4)*highest+highest/2-spof->GetHeight()/2,spof,1); } #define BUTTONWID Math::Max(1, game.SpriteInfos[btn_select_sprite].Width) // Draw select, look and OK buttons wputblock(ds, 2, buttonyp + 2, spriteset[btn_look_sprite], 1); wputblock(ds, 3+BUTTONWID, buttonyp + 2, spriteset[btn_select_sprite], 1); wputblock(ds, 4+BUTTONWID*2, buttonyp + 2, spriteset[btn_ok_sprite], 1); // Draw Up and Down buttons if required Bitmap *arrowblock = BitmapHelper::CreateTransparentBitmap (ARROWBUTTONWID, ARROWBUTTONWID); draw_color = arrowblock->GetCompatibleColor(0); if (play.sierra_inv_color == 0) draw_color = ds->GetCompatibleColor(14); arrowblock->DrawLine(Line(ARROWBUTTONWID/2, 2, ARROWBUTTONWID-2, 9), draw_color); arrowblock->DrawLine(Line(ARROWBUTTONWID/2, 2, 2, 9), draw_color); arrowblock->DrawLine(Line(2, 9, ARROWBUTTONWID-2, 9), draw_color); arrowblock->FloodFill(ARROWBUTTONWID/2, 4, draw_color); if (top_item > 0) wputblock(ds, windowwid-ARROWBUTTONWID, buttonyp + 2, arrowblock, 1); if (top_item + num_visible_items < numitems) arrowblock->FlipBlt(arrowblock, windowwid-ARROWBUTTONWID, buttonyp + 4 + ARROWBUTTONWID, Common::kBitmap_VFlip); delete arrowblock; }
int InventoryScreen::Redraw() { Bitmap *ds = GetVirtualScreen(); numitems=0; widest=0; highest=0; if (charextra[game.playercharacter].invorder_count < 0) update_invorder(); if (charextra[game.playercharacter].invorder_count == 0) { DisplayMessage(996); in_inv_screen--; return -1; } if (inv_screen_newroom >= 0) { in_inv_screen--; NewRoom(inv_screen_newroom); return -1; } for (int i = 0; i < charextra[game.playercharacter].invorder_count; ++i) { if (game.invinfo[charextra[game.playercharacter].invorder[i]].name[0]!=0) { dii[numitems].num = charextra[game.playercharacter].invorder[i]; dii[numitems].sprnum = game.invinfo[charextra[game.playercharacter].invorder[i]].pic; int snn=dii[numitems].sprnum; if (spritewidth[snn] > widest) widest=spritewidth[snn]; if (spriteheight[snn] > highest) highest=spriteheight[snn]; numitems++; } } if (numitems != charextra[game.playercharacter].invorder_count) quit("inconsistent inventory calculations"); widest += get_fixed_pixel_size(4); highest += get_fixed_pixel_size(4); num_visible_items = (MAX_ITEMAREA_HEIGHT / highest) * ICONSPERLINE; windowhit = highest * (numitems/ICONSPERLINE) + get_fixed_pixel_size(4); if ((numitems%ICONSPERLINE) !=0) windowhit+=highest; if (windowhit > MAX_ITEMAREA_HEIGHT) { windowhit = (MAX_ITEMAREA_HEIGHT / highest) * highest + get_fixed_pixel_size(4); } windowhit += BUTTONAREAHEIGHT; windowwid = widest*ICONSPERLINE + get_fixed_pixel_size(4); if (windowwid < get_fixed_pixel_size(105)) windowwid = get_fixed_pixel_size(105); windowxp=play.viewport.GetWidth()/2-windowwid/2; windowyp=play.viewport.GetHeight()/2-windowhit/2; buttonyp=windowyp+windowhit-BUTTONAREAHEIGHT; color_t draw_color = ds->GetCompatibleColor(play.sierra_inv_color); ds->FillRect(Rect(windowxp,windowyp,windowxp+windowwid,windowyp+windowhit), draw_color); draw_color = ds->GetCompatibleColor(0); bartop = windowyp + get_fixed_pixel_size(2); barxp = windowxp + get_fixed_pixel_size(2); ds->FillRect(Rect(barxp,bartop, windowxp + windowwid - get_fixed_pixel_size(2),buttonyp-1), draw_color); for (int i = top_item; i < numitems; ++i) { if (i >= top_item + num_visible_items) break; Bitmap *spof=spriteset[dii[i].sprnum]; wputblock(ds, barxp+1+((i-top_item)%4)*widest+widest/2-spof->GetWidth()/2, bartop+1+((i-top_item)/4)*highest+highest/2-spof->GetHeight()/2,spof,1); } #define BUTTONWID Math::Max(1, spritewidth[btn_select_sprite]) // Draw select, look and OK buttons wputblock(ds, windowxp+2, buttonyp + get_fixed_pixel_size(2), spriteset[btn_look_sprite], 1); wputblock(ds, windowxp+3+BUTTONWID, buttonyp + get_fixed_pixel_size(2), spriteset[btn_select_sprite], 1); wputblock(ds, windowxp+4+BUTTONWID*2, buttonyp + get_fixed_pixel_size(2), spriteset[btn_ok_sprite], 1); // Draw Up and Down buttons if required Bitmap *arrowblock = BitmapHelper::CreateTransparentBitmap (ARROWBUTTONWID, ARROWBUTTONWID); draw_color = arrowblock->GetCompatibleColor(0); if (play.sierra_inv_color == 0) draw_color = ds->GetCompatibleColor(14); arrowblock->DrawLine(Line(ARROWBUTTONWID/2, 2, ARROWBUTTONWID-2, 9), draw_color); arrowblock->DrawLine(Line(ARROWBUTTONWID/2, 2, 2, 9), draw_color); arrowblock->DrawLine(Line(2, 9, ARROWBUTTONWID-2, 9), draw_color); arrowblock->FloodFill(ARROWBUTTONWID/2, 4, draw_color); if (top_item > 0) wputblock(ds, windowxp+windowwid-ARROWBUTTONWID, buttonyp + get_fixed_pixel_size(2), arrowblock, 1); if (top_item + num_visible_items < numitems) arrowblock->FlipBlt(arrowblock, windowxp+windowwid-ARROWBUTTONWID, buttonyp + get_fixed_pixel_size(4) + ARROWBUTTONWID, Common::kBitmap_VFlip); delete arrowblock; //domouse(1); set_mouse_cursor(cmode); wasonitem=-1; prepare_gui_screen(windowxp, windowyp, windowwid, windowhit, true); return 0; }
int __actual_invscreen() { int BUTTONAREAHEIGHT = get_fixed_pixel_size(30); int cmode=CURS_ARROW, toret = -1; int top_item = 0, num_visible_items = 0; int MAX_ITEMAREA_HEIGHT = ((scrnhit - BUTTONAREAHEIGHT) - get_fixed_pixel_size(20)); in_inv_screen++; inv_screen_newroom = -1; Bitmap *ds = NULL; start_actinv: ds = SetVirtualScreen(virtual_screen); DisplayInvItem dii[MAX_INV]; int numitems=0,ww,widest=0,highest=0; if (charextra[game.playercharacter].invorder_count < 0) update_invorder(); if (charextra[game.playercharacter].invorder_count == 0) { DisplayMessage(996); in_inv_screen--; return -1; } if (inv_screen_newroom >= 0) { in_inv_screen--; NewRoom(inv_screen_newroom); return -1; } for (ww = 0; ww < charextra[game.playercharacter].invorder_count; ww++) { if (game.invinfo[charextra[game.playercharacter].invorder[ww]].name[0]!=0) { dii[numitems].num = charextra[game.playercharacter].invorder[ww]; dii[numitems].sprnum = game.invinfo[charextra[game.playercharacter].invorder[ww]].pic; int snn=dii[numitems].sprnum; if (spritewidth[snn] > widest) widest=spritewidth[snn]; if (spriteheight[snn] > highest) highest=spriteheight[snn]; numitems++; } } if (numitems != charextra[game.playercharacter].invorder_count) quit("inconsistent inventory calculations"); widest += get_fixed_pixel_size(4); highest += get_fixed_pixel_size(4); num_visible_items = (MAX_ITEMAREA_HEIGHT / highest) * ICONSPERLINE; int windowhit = highest * (numitems/ICONSPERLINE) + get_fixed_pixel_size(4); if ((numitems%ICONSPERLINE) !=0) windowhit+=highest; if (windowhit > MAX_ITEMAREA_HEIGHT) { windowhit = (MAX_ITEMAREA_HEIGHT / highest) * highest + get_fixed_pixel_size(4); } windowhit += BUTTONAREAHEIGHT; int windowwid = widest*ICONSPERLINE + get_fixed_pixel_size(4); if (windowwid < get_fixed_pixel_size(105)) windowwid = get_fixed_pixel_size(105); int windowxp=scrnwid/2-windowwid/2; int windowyp=scrnhit/2-windowhit/2; int buttonyp=windowyp+windowhit-BUTTONAREAHEIGHT; color_t draw_color = ds->GetCompatibleColor(play.sierra_inv_color); ds->FillRect(Rect(windowxp,windowyp,windowxp+windowwid,windowyp+windowhit), draw_color); draw_color = ds->GetCompatibleColor(0); int bartop = windowyp + get_fixed_pixel_size(2); int barxp = windowxp + get_fixed_pixel_size(2); ds->FillRect(Rect(barxp,bartop, windowxp + windowwid - get_fixed_pixel_size(2),buttonyp-1), draw_color); for (ww = top_item; ww < numitems; ww++) { if (ww >= top_item + num_visible_items) break; Bitmap *spof=spriteset[dii[ww].sprnum]; wputblock(ds, barxp+1+((ww-top_item)%4)*widest+widest/2-spof->GetWidth()/2, bartop+1+((ww-top_item)/4)*highest+highest/2-spof->GetHeight()/2,spof,1); } if ((spriteset[2041] == NULL) || (spriteset[2042] == NULL) || (spriteset[2043] == NULL)) quit("!InventoryScreen: one or more of the inventory screen graphics have been deleted"); #define BUTTONWID spritewidth[2042] // Draw select, look and OK buttons wputblock(ds, windowxp+2, buttonyp + get_fixed_pixel_size(2), spriteset[2041], 1); wputblock(ds, windowxp+3+BUTTONWID, buttonyp + get_fixed_pixel_size(2), spriteset[2042], 1); wputblock(ds, windowxp+4+BUTTONWID*2, buttonyp + get_fixed_pixel_size(2), spriteset[2043], 1); // Draw Up and Down buttons if required const int ARROWBUTTONWID = 11; Bitmap *arrowblock = BitmapHelper::CreateTransparentBitmap (ARROWBUTTONWID, ARROWBUTTONWID); draw_color = arrowblock->GetCompatibleColor(0); if (play.sierra_inv_color == 0) draw_color = ds->GetCompatibleColor(14); arrowblock->DrawLine(Line(ARROWBUTTONWID/2, 2, ARROWBUTTONWID-2, 9), draw_color); arrowblock->DrawLine(Line(ARROWBUTTONWID/2, 2, 2, 9), draw_color); arrowblock->DrawLine(Line(2, 9, ARROWBUTTONWID-2, 9), draw_color); arrowblock->FloodFill(ARROWBUTTONWID/2, 4, draw_color); if (top_item > 0) wputblock(ds, windowxp+windowwid-ARROWBUTTONWID, buttonyp + get_fixed_pixel_size(2), arrowblock, 1); if (top_item + num_visible_items < numitems) arrowblock->FlipBlt(arrowblock, windowxp+windowwid-ARROWBUTTONWID, buttonyp + get_fixed_pixel_size(4) + ARROWBUTTONWID, Common::kBitmap_VFlip); delete arrowblock; domouse(1); set_mouse_cursor(cmode); int wasonitem=-1; while (!kbhit()) { timerloop = 0; NEXT_ITERATION(); domouse(0); update_polled_stuff_and_crossfade(); write_screen(); int isonitem=((mousey-bartop)/highest)*ICONSPERLINE+(mousex-barxp)/widest; if (mousey<=bartop) isonitem=-1; else if (isonitem >= 0) isonitem += top_item; if ((isonitem<0) | (isonitem>=numitems) | (isonitem >= top_item + num_visible_items)) isonitem=-1; int mclick = mgetbutton(); if (mclick == LEFT) { if ((mousey<windowyp) | (mousey>windowyp+windowhit) | (mousex<windowxp) | (mousex>windowxp+windowwid)) continue; if (mousey<buttonyp) { int clickedon=isonitem; if (clickedon<0) continue; evblocknum=dii[clickedon].num; play.used_inv_on = dii[clickedon].num; if (cmode==MODE_LOOK) { domouse(2); run_event_block_inv(dii[clickedon].num, 0); // in case the script did anything to the screen, redraw it mainloop(); goto start_actinv; continue; } else if (cmode==MODE_USE) { // use objects on each other play.usedinv=toret; // set the activeinv so the script can check it int activeinvwas = playerchar->activeinv; playerchar->activeinv = toret; domouse(2); run_event_block_inv(dii[clickedon].num, 3); // if the script didn't change it, then put it back if (playerchar->activeinv == toret) playerchar->activeinv = activeinvwas; // in case the script did anything to the screen, redraw it mainloop(); // They used the active item and lost it if (playerchar->inv[toret] < 1) { cmode = CURS_ARROW; set_mouse_cursor(cmode); toret = -1; } goto start_actinv; // continue; } toret=dii[clickedon].num; // int plusng=play.using; play.using=toret; update_inv_cursor(toret); set_mouse_cursor(MODE_USE); cmode=MODE_USE; // play.using=plusng; // break; continue; } else { if (mousex >= windowxp+windowwid-ARROWBUTTONWID) { if (mousey < buttonyp + get_fixed_pixel_size(2) + ARROWBUTTONWID) { if (top_item > 0) { top_item -= ICONSPERLINE; domouse(2); goto start_actinv; } } else if ((mousey < buttonyp + get_fixed_pixel_size(4) + ARROWBUTTONWID*2) && (top_item + num_visible_items < numitems)) { top_item += ICONSPERLINE; domouse(2); goto start_actinv; } continue; } int buton=(mousex-windowxp)-2; if (buton<0) continue; buton/=BUTTONWID; if (buton>=3) continue; if (buton==0) { toret=-1; cmode=MODE_LOOK; } else if (buton==1) { cmode=CURS_ARROW; toret=-1; } else break; set_mouse_cursor(cmode); } } else if (mclick == RIGHT) { if (cmode == CURS_ARROW) cmode = MODE_LOOK; else cmode = CURS_ARROW; toret = -1; set_mouse_cursor(cmode); } else if (isonitem!=wasonitem) { domouse(2); int rectxp=barxp+1+(wasonitem%4)*widest; int rectyp=bartop+1+((wasonitem - top_item)/4)*highest; if (wasonitem>=0) { draw_color = ds->GetCompatibleColor(0); ds->DrawRect(Rect(rectxp,rectyp,rectxp+widest-1,rectyp+highest-1), draw_color); } if (isonitem>=0) { draw_color = ds->GetCompatibleColor(14);//opts.invrectcol); rectxp=barxp+1+(isonitem%4)*widest; rectyp=bartop+1+((isonitem - top_item)/4)*highest; ds->DrawRect(Rect(rectxp,rectyp,rectxp+widest-1,rectyp+highest-1), draw_color); } domouse(1); } wasonitem=isonitem; while (timerloop == 0) { update_polled_stuff_if_runtime(); platform->YieldCPU(); } } while (kbhit()) getch(); set_default_cursor(); domouse(2); construct_virtual_screen(true); in_inv_screen--; return toret; }
int is_route_possible(int fromx, int fromy, int tox, int toy, Bitmap *wss) { wallscreen = wss; suggestx = -1; // ensure it's a memory bitmap, so we can use direct access to line[] array if ((wss == NULL) || (!wss->IsMemoryBitmap()) || (wss->GetColorDepth() != 8)) quit("is_route_possible: invalid walkable areas bitmap supplied"); if (wallscreen->GetPixel(fromx, fromy) < 1) return 0; Bitmap *tempw = BitmapHelper::CreateBitmapCopy(wallscreen, 8); if (tempw == NULL) quit("no memory for route calculation"); if (!tempw->IsMemoryBitmap()) quit("tempw is not memory bitmap"); int dd, ff; // initialize array for finding widths of walkable areas int thisar, inarow = 0, lastarea = 0; int walk_area_times[MAX_WALK_AREAS + 1]; for (dd = 0; dd <= MAX_WALK_AREAS; dd++) { walk_area_times[dd] = 0; walk_area_granularity[dd] = 0; } for (ff = 0; ff < tempw->GetHeight(); ff++) { const uint8_t *tempw_scanline = tempw->GetScanLine(ff); for (dd = 0; dd < tempw->GetWidth(); dd++) { thisar = tempw_scanline[dd]; // count how high the area is at this point if ((thisar == lastarea) && (thisar > 0)) inarow++; else if (lastarea > MAX_WALK_AREAS) quit("!Calculate_Route: invalid colours in walkable area mask"); else if (lastarea != 0) { walk_area_granularity[lastarea] += inarow; walk_area_times[lastarea]++; inarow = 0; } lastarea = thisar; } } for (dd = 0; dd < tempw->GetWidth(); dd++) { for (ff = 0; ff < tempw->GetHeight(); ff++) { uint8_t *tempw_scanline = tempw->GetScanLineForWriting(ff); thisar = tempw_scanline[dd]; if (thisar > 0) tempw_scanline[dd] = 1; // count how high the area is at this point if ((thisar == lastarea) && (thisar > 0)) inarow++; else if (lastarea != 0) { walk_area_granularity[lastarea] += inarow; walk_area_times[lastarea]++; inarow = 0; } lastarea = thisar; } } // find the average "width" of a path in this walkable area for (dd = 1; dd <= MAX_WALK_AREAS; dd++) { if (walk_area_times[dd] == 0) { walk_area_granularity[dd] = MAX_GRANULARITY; continue; } walk_area_granularity[dd] /= walk_area_times[dd]; if (walk_area_granularity[dd] <= 4) walk_area_granularity[dd] = 2; else if (walk_area_granularity[dd] <= 15) walk_area_granularity[dd] = 3; else walk_area_granularity[dd] = MAX_GRANULARITY; /*char toprnt[200]; sprintf(toprnt,"area %d: Gran %d", dd, walk_area_granularity[dd]); winalert(toprnt); */ } walk_area_granularity[0] = MAX_GRANULARITY; tempw->FloodFill(fromx, fromy, 232); if (tempw->GetPixel(tox, toy) != 232) { // Destination pixel is not walkable // Try the 100x100 square around the target first at 3-pixel granularity int tryFirstX = tox - 50, tryToX = tox + 50; int tryFirstY = toy - 50, tryToY = toy + 50; if (!find_nearest_walkable_area(tempw, tryFirstX, tryFirstY, tryToX, tryToY, tox, toy, 3)) { // Nothing found, sweep the whole room at 5 pixel granularity find_nearest_walkable_area(tempw, 0, 0, tempw->GetWidth(), tempw->GetHeight(), tox, toy, 5); } delete tempw; return 0; } delete tempw; return 1; }