Beispiel #1
0
TbScreenMode switch_to_next_video_mode(void)
{
    TbScreenMode scrmode;
    scrmode = get_next_vidmode(lbDisplay.ScreenMode);
    if ( setup_screen_mode(scrmode) )
    {
        settings.video_scrnmode = scrmode;
    } else
    {
        SYNCLOG("Can't enter %s (mode %d), falling to failsafe mode",
            get_vidmode_name(scrmode),(int)scrmode);
        scrmode = get_failsafe_vidmode();
        if ( !setup_screen_mode(scrmode) )
        {
          FatalError = 1;
          exit_keeper = 1;
          return Lb_SCREEN_MODE_INVALID;
        }
        settings.video_scrnmode = scrmode;
    }
    SYNCLOG("Switched video to %s (mode %d)", get_vidmode_name(scrmode),(int)scrmode);
    save_settings();
    if (game.numfield_C & 0x20)
      setup_engine_window(status_panel_width, 0, MyScreenWidth, MyScreenHeight);
    else
      setup_engine_window(0, 0, MyScreenWidth, MyScreenHeight);
//    reinit_all_menus();
    return scrmode;
}
Beispiel #2
0
TbResult LbMouseChangeSpriteAndHotspot(struct TbSprite *pointerSprite, long hot_x, long hot_y)
{
#if (BFDEBUG_LEVEL > 18)
  if (pointerSprite == NULL)
    SYNCLOG("Setting to %s","NONE");
  else
    SYNCLOG("Setting to %dx%d, data at %p",(int)pointerSprite->SWidth,(int)pointerSprite->SHeight,pointerSprite);
#endif
  if (!lbMouseInstalled)
    return Lb_FAIL;
  if (!pointerHandler.SetMousePointerAndOffset(pointerSprite, hot_x, hot_y))
    return Lb_FAIL;
  return Lb_SUCCESS;
}
/**
 * Re-adds item to the amount available to be placed on map, if an empty trap gets destroyed.
 * @param owner
 * @param tngclass
 * @param tngmodel
 * @return
 * @note was named add_workshop_item()
 */
TbBool readd_workshop_item_to_amount_placeable_f(PlayerNumber plyr_idx, ThingClass tngclass, ThingModel tngmodel, const char *func_name)
{
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon_f(plyr_idx,func_name);
    if (dungeon_invalid(dungeon)) {
        ERRORLOG("%s: Can't add item; player %d has no dungeon.",func_name,(int)plyr_idx);
        return false;
    }
    switch (tngclass)
    {
    case TCls_Trap:
        SYNCDBG(8,"%s: Adding Trap %s",func_name,trap_code_name(tngmodel));
        dungeon->trap_amount_placeable[tngmodel]++;
        if (dungeon->trap_amount_placeable[tngmodel] > dungeon->trap_amount_stored[tngmodel]+dungeon->trap_amount_offmap[tngmodel]) {
            SYNCLOG("%s: Placeable %s traps amount for player %d was too large; fixed",func_name,trap_code_name(tngmodel),(int)plyr_idx);
            dungeon->trap_amount_placeable[tngmodel] = dungeon->trap_amount_stored[tngmodel]+dungeon->trap_amount_offmap[tngmodel];
        }
        if (dungeon->trap_amount_placeable[tngmodel] < dungeon->trap_amount_offmap[tngmodel]) {
            WARNLOG("%s: Placeable %s traps amount for player %d was too small; fixed",func_name,trap_code_name(tngmodel),(int)plyr_idx);
            dungeon->trap_amount_placeable[tngmodel] = dungeon->trap_amount_offmap[tngmodel];
        }
        break;
    case TCls_Door:
        SYNCDBG(8,"%s: Adding Door %s",func_name,door_code_name(tngmodel));
        dungeon->door_amount_placeable[tngmodel]++;
        // In case the placeable amount lost it, do a fix
        if (dungeon->door_amount_placeable[tngmodel] > dungeon->door_amount_stored[tngmodel]+dungeon->door_amount_offmap[tngmodel]) {
            SYNCLOG("%s: Placeable %s doors amount for player %d was too large; fixed",func_name,door_code_name(tngmodel),(int)plyr_idx);
            dungeon->door_amount_placeable[tngmodel] = dungeon->door_amount_stored[tngmodel]+dungeon->door_amount_offmap[tngmodel];
        }
        if (dungeon->door_amount_placeable[tngmodel] < dungeon->door_amount_offmap[tngmodel]) {
            WARNLOG("%s: Placeable %s doors amount for player %d was too small; fixed",func_name,door_code_name(tngmodel),(int)plyr_idx);
            dungeon->door_amount_placeable[tngmodel] = dungeon->door_amount_offmap[tngmodel];
        }
        break;
    default:
        ERRORLOG("%s: Can't add item; illegal item class %d",func_name,(int)tngclass);
        return false;
    }
    return true;
}
Beispiel #4
0
/**
 * Loads the language-specific strings data for game interface.
 */
TbBool setup_gui_strings_data(void)
{
  char *strings_data_end;
  char *fname;
  short result;
  long filelen;
  long loaded_size;
  SYNCDBG(8,"Starting");

  fname = prepare_file_fmtpath(FGrp_FxData,"gtext_%s.dat",get_language_lwrstr(install_info.lang_id));
  filelen = LbFileLengthRnc(fname);
  if (filelen <= 0)
  {
    ERRORLOG("GUI Strings file does not exist or can't be opened");
    SYNCLOG("Strings file name is \"%s\"",fname);
    return false;
  }
  gui_strings_data = (char *)LbMemoryAlloc(filelen + 256);
  if (gui_strings_data == NULL)
  {
    ERRORLOG("Can't allocate memory for GUI Strings data");
    SYNCLOG("Strings file name is \"%s\"",fname);
    return false;
  }
  strings_data_end = gui_strings_data+filelen+255;
  loaded_size = LbFileLoadAt(fname, gui_strings_data);
  if (loaded_size < 16)
  {
    ERRORLOG("GUI Strings file couldn't be loaded or is too small");
    return false;
  }
  // Resetting all values to empty strings
  reset_strings(gui_strings);
  // Analyzing strings data and filling correct values
  result = create_strings_list(gui_strings, gui_strings_data, strings_data_end);
  // Updating strings inside the DLL
  LbMemoryCopy(_DK_strings, gui_strings, DK_STRINGS_MAX*sizeof(char *));
  SYNCDBG(19,"Finished");
  return result;
}
Beispiel #5
0
TbBool set_creature_assigned_job(struct Thing *thing, CreatureJob new_job)
{
    struct CreatureControl *cctrl;
    TRACE_THING(thing);
    cctrl = creature_control_get_from_thing(thing);
    if (creature_control_invalid(cctrl))
    {
        ERRORLOG("The %s index %d has invalid control",thing_model_name(thing),(int)thing->index);
        return false;
    }
    cctrl->job_assigned = new_job;
    SYNCLOG("Assigned job %s for %s index %d owner %d",creature_job_code_name(new_job),thing_model_name(thing),(int)thing->index,(int)thing->owner);
    return true;
}
Beispiel #6
0
/**
 * Changes mouse movement ratio.
 * Note that this function can be run even before mouse setup. Still, the factor
 *  will be reset during the installation - so use it after LbMouseSetup().
 *
 * @param ratio_x Movement ratio in X direction; 256 means unchanged ratio from OS.
 * @param ratio_y Movement ratio in Y direction; 256 means unchanged ratio from OS.
 * @return Lb_SUCCESS if the ratio values were of correct range and have been set.
 */
TbResult LbMouseChangeMoveRatio(long ratio_x, long ratio_y)
{
    if ((ratio_x < -8192) || (ratio_x > 8192) || (ratio_x == 0))
        return Lb_FAIL;
    if ((ratio_y < -8192) || (ratio_y > 8192) || (ratio_y == 0))
        return Lb_FAIL;
    SYNCLOG("New ratio %ldx%ld",ratio_x, ratio_y);
    // Currently we don't have two ratio factors, so let's store an average
    lbDisplay.MouseMoveRatio = (ratio_x + ratio_y)/2;
    //TODO INPUT Separate mouse ratios in X and Y direction when lbDisplay from DLL will no longer be used.
    //minfo.XMoveRatio = ratio_x;
    //minfo.YMoveRatio = ratio_y;
    return Lb_SUCCESS;
}
Beispiel #7
0
TbScreenMode reenter_video_mode(void)
{
 TbScreenMode scrmode;
 scrmode=validate_vidmode(settings.video_scrnmode);
 if ( setup_screen_mode(scrmode) )
  {
      settings.video_scrnmode = scrmode;
  } else
  {
      SYNCLOG("Can't enter %s (mode %d), falling to failsafe mode",
          get_vidmode_name(scrmode),(int)scrmode);
      scrmode=get_failsafe_vidmode();
      if ( !setup_screen_mode(scrmode) )
      {
        _DK_FatalError = 1;
        exit_keeper = 1;
        return Lb_SCREEN_MODE_INVALID;
      }
      settings.video_scrnmode = scrmode;
      save_settings();
  }
  SYNCLOG("Switched video to %s (mode %d)", get_vidmode_name(scrmode),(int)scrmode);
  return scrmode;
}
TbBool good_setup_wander_to_exit(struct Thing *creatng)
{
    struct Thing *gatetng;
    SYNCDBG(7,"Starting");
    gatetng = find_hero_door_hero_can_navigate_to(creatng);
    if (thing_is_invalid(gatetng))
    {
        SYNCLOG("Can't find any exit gate for hero %s.",thing_model_name(creatng));
        return false;
    }
    if (!setup_person_move_to_coord(creatng, &gatetng->mappos, NavRtF_Default))
    {
        WARNLOG("Hero %s index %d can't move to exit gate at (%d,%d).",thing_model_name(creatng),
            (int)gatetng->index, (int)gatetng->mappos.x.stl.num, (int)gatetng->mappos.y.stl.num);
        return false;
    }
    creatng->continue_state = CrSt_GoodLeaveThroughExitDoor;
    return true;
}
Beispiel #9
0
/**
 * Quick attack is just putting CTA spell on enemy room.

 * @param comp
 * @param check
 */
long computer_check_for_quick_attack(struct Computer2 *comp, struct ComputerCheck * check)
{
    struct Dungeon *dungeon;
    SYNCDBG(8,"Starting");
    dungeon = comp->dungeon;
    int creatrs_num;
    creatrs_num = check->param1 * dungeon->num_active_creatrs / 100;
    if (check->param3 >= creatrs_num) {
        return CTaskRet_Unk4;
    }
    if (computer_able_to_use_magic(comp, PwrK_CALL2ARMS, 1, 3) != 1) {
        return CTaskRet_Unk4;
    }
    if ((check_call_to_arms(comp) != 1) || is_there_an_attack_task(comp)) {
        return CTaskRet_Unk4;
    }
    struct Room *room;
    room = get_hated_room_for_quick_attack(comp, check->param3);
    if (room_is_invalid(room)) {
        return CTaskRet_Unk4;
    }
    struct Coord3d pos;
    // TODO COMPUTER_PLAYER We should make sure the place of cast is accessible for creatures
    pos.x.val = subtile_coord_center(room->central_stl_x);
    pos.y.val = subtile_coord_center(room->central_stl_y);
    pos.z.val = subtile_coord(1,0);
    if (count_creatures_availiable_for_fight(comp, &pos) <= check->param3) {
        return CTaskRet_Unk4;
    }
    if (!create_task_magic_support_call_to_arms(comp, &pos, check->param2, 0, creatrs_num)) {
        return CTaskRet_Unk4;
    }
    SYNCLOG("Player %d decided to attack %s owned by player %d",(int)dungeon->owner,room_code_name(room->kind),(int)room->owner);
    output_message(SMsg_EnemyHarassments+ACTION_RANDOM(8), 500, 1);
    return CTaskRet_Unk1;
}
Beispiel #10
0
TbBool init_sound_heap_two_banks(unsigned char *heap_mem, long heap_size, char *snd_fname, char *spc_fname, long a5)
{
    long i;
    long buf_len;
    unsigned char *buf;
    SYNCDBG(8,"Starting");
    LbMemorySet(heap_mem, 0, heap_size);
    using_two_banks = 0;
    // Open first sound bank and prepare sample table
    if (sound_file != -1)
        close_sound_bank(0);
    samples_in_bank = 0;
    sound_file = _DK_LbFileOpen(snd_fname,Lb_FILE_MODE_READ_ONLY);
    if (sound_file == -1)
    {
        ERRORLOG("Couldn't open primary sound bank file \"%s\"",snd_fname);
        return false;
    }
    buf = heap_mem;
    buf_len = heap_size;
    i = parse_sound_file(sound_file, buf, &samples_in_bank, buf_len, a5);
    if (i == 0)
    {
        ERRORLOG("Couldn't parse sound bank file \"%s\"",snd_fname);
        close_sound_heap();
        return false;
    }
    sample_table = (struct SampleTable *)buf;
    buf_len -= i;
    buf += i;
    if (buf_len <= 0)
    {
        ERRORLOG("Sound bank buffer too short");
        close_sound_heap();
        return false;
    }
    // Open second sound bank and prepare sample table
    if (sound_file2 != -1)
        close_sound_bank(1);
    samples_in_bank2 = 0;
    sound_file2 = _DK_LbFileOpen(spc_fname,Lb_FILE_MODE_READ_ONLY);
    if (sound_file2 == -1)
    {
        ERRORLOG("Couldn't open secondary sound bank file \"%s\"",spc_fname);
        return false;
    }
    i = parse_sound_file(sound_file2, buf, &samples_in_bank2, buf_len, a5);
    if (i == 0)
    {
        ERRORLOG("Couldn't parse sound bank file \"%s\"",spc_fname);
        close_sound_heap();
        return false;
    }
    sample_table2 = (struct SampleTable *)buf;
    buf_len -= i;
    buf += i;
    if (buf_len <= 0)
    {
        ERRORLOG("Sound bank buffer too short");
        close_sound_heap();
        return false;
    }
    SYNCLOG("Got sound buffer of %ld bytes, samples in banks: %d,%d",buf_len,(int)samples_in_bank,(int)samples_in_bank2);
    sndheap = heapmgr_init(buf, buf_len, samples_in_bank2 + samples_in_bank);
    if (sndheap == NULL)
    {
        ERRORLOG("Sound heap manager init error");
        close_sound_heap();
        return false;
    }
    using_two_banks = 1;
    return true;
}
TbBool lights_stats_debug_dump(void)
{
    long lights[LIGHTS_COUNT];
    long lgh_things[THING_CLASSES_COUNT];
    long shadowcs[SHADOW_CACHE_COUNT];
    long shdc_used,shdc_linked,shdc_free;
    long lgh_used,lgh_free;
    long lgh_sttc,lgh_dynm;
    struct Thing * thing;
    struct Light *lgt;
    struct ShadowCache *shdc;
    long i,n;
    for (i=0; i < SHADOW_CACHE_COUNT; i++)
    {
        shdc = &game.lish.shadow_cache[i];
        if ((shdc->flags & ShCF_Allocated) != 0)
            shadowcs[i] = -1;
        else
            shadowcs[i] = 0;
    }
    lgh_sttc = 0;
    lgh_dynm = 0;
    for (i=0; i < LIGHTS_COUNT; i++)
    {
        lgt = &game.lish.lights[i];
        if ((lgt->flags & LgtF_Allocated) != 0)
        {
            lights[i] = -1;
            if ((lgt->flags & LgtF_Dynamic) != 0)
                lgh_dynm++;
            else
                lgh_sttc++;
            if ( (lgt->shadow_index > 0) && (lgt->shadow_index < SHADOW_CACHE_COUNT) )
            {
                if (shadowcs[lgt->shadow_index] == -1) {
                    shadowcs[lgt->shadow_index] = i;
                } else
                if (shadowcs[lgt->shadow_index] == 0) {
                    WARNLOG("Shadow Cache %d is not allocated, but used by light %d!",(int)lgt->shadow_index,(int)i);
                } else {
                    WARNLOG("Shadow Cache %d is double-allocated, for lights %d and %d!",(int)lgt->shadow_index,(int)shadowcs[lgt->shadow_index],(int)i);
                }
            } else
            if ((lgt->flags & LgtF_Dynamic) != 0)
            {
                WARNLOG("Dynamic light %d has bad Shadow Cache %d!",(int)i,(int)lgt->shadow_index);
            }
        } else {
            lights[i] = 0;
        }
    }
    for (i=1; i < THINGS_COUNT; i++)
    {
        thing = thing_get(i);
        if (thing_exists(thing))
        {
            if ((thing->light_id > 0) && (thing->light_id < LIGHTS_COUNT))
            {
                n = 1000+(long)thing->class_id;
                if (lights[thing->light_id] == -1) {
                    lights[thing->light_id] = n;
                } else
                if (lights[thing->light_id] == 0) {
                    WARNLOG("Light %d is not allocated, but used by %s!",(int)thing->light_id, thing_model_name(thing));
                } else {
                    WARNLOG("Light %d is double-allocated, for %d and %d!",(int)thing->light_id, (int)lights[thing->light_id], (int)n);
                }
            }

        }
    }
    lgh_used = 0;
    lgh_free = 0;
    for (i=0; i < THING_CLASSES_COUNT; i++)
        lgh_things[i] = 0;
    for (i=0; i < LIGHTS_COUNT; i++)
    {
        if (lights[i] != 0)
        {
            lgh_used++;
            if ((lights[i] > 1000) && (lights[i] < 1000+THING_CLASSES_COUNT))
                lgh_things[lights[i]-1000]++;
        } else
        {
            lgh_free++;
        }
    }
    shdc_free = 0;
    shdc_used = 0;
    shdc_linked = 0;
    for (i=0; i < SHADOW_CACHE_COUNT; i++)
    {
        if (shadowcs[i] != 0)
        {
            shdc_used++;
            if (shadowcs[i] > 0)
                shdc_linked++;
        } else {
            shdc_free++;
        }
    }
    SYNCLOG("Lights: %ld free, %ld used; %ld static, %ld dynamic; for things:%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld",lgh_free,lgh_used,lgh_sttc,lgh_dynm,lgh_things[1],lgh_things[2],lgh_things[3],lgh_things[4],lgh_things[5],lgh_things[6],lgh_things[7],lgh_things[8],lgh_things[9],lgh_things[10],lgh_things[11],lgh_things[12],lgh_things[13]);
    if ((shdc_used != shdc_linked) || (shdc_used != lgh_dynm))
    {
        WARNLOG("Amount of shadow cache mismatches: %ld free, %ld used, %ld linked to lights, %d dyn. lights.",shdc_free,shdc_used,shdc_linked,light_total_dynamic_lights);
    }
    if (lgh_sttc != light_total_stat_lights)
    {
        WARNLOG("Wrong global lights counter: %ld static lights and counter says %ld.",lgh_sttc,light_total_stat_lights);
    }
    if (lgh_dynm != light_total_dynamic_lights)
    {
        WARNLOG("Wrong global lights counter: %ld dynamic lights and counter says %ld.",lgh_dynm,light_total_dynamic_lights);
    }
    return false;
}