Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
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;
}
Пример #4
0
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;
}