⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 battery.c

📁 linux下的任天堂模拟器代码。供大家参考。
💻 C
字号:
/*Copyright (C) 1997-2007 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach )http://www.zsnes.comhttp://sourceforge.net/projects/zsneshttps://zsnes.bountysource.comThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseversion 2 as published by the Free Software Foundation.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "../gblhdr.h"/*Functions for battery probing on Linux by NachI believe Linux 2.4.x+ is needed for ACPI supportbut it'll compile fine for older versions tooSpecial thanks David Lee Lambert for most of the code here*/#ifdef linux#include <dirent.h>#include <math.h>int CheckBattery(){  int battery = -1; //No battery / Can't get info  const char *ac = "/proc/acpi/ac_adapter/";  //Check ac adapter  DIR *ac_dir = opendir(ac);  if (ac_dir)  {    char fnbuf[40]; // longer than len(ac)+len(HEXDIGIT*4)+len({state|info})    FILE *fp;    const char *pattern = " %39[^:]: %39[ -~]"; // for sscanf    char line[80], key[40], arg[40];    struct dirent *ent;    while ((ent = readdir(ac_dir)))    {      if (ent->d_name[0] == '.') { continue; }      snprintf(fnbuf, 40, "%s%s/state", ac, ent->d_name);      fp = fopen(fnbuf, "r");      if (fp)      {        while (fgets(line, 80, fp) && sscanf(line, pattern, key, arg) == 2)        {          if (!strcmp(key, "state"))          {            if (!strcmp(arg, "on-line"))            {              battery = 0;            }            else if (!strcmp(arg, "off-line"))            {              battery = 1;              break;            }          }        }        fclose(fp);      }    }    closedir(ac_dir);  }  return(battery);}static int BatteryLifeTime;static int BatteryLifePercent;static void update_battery_info(){  const char *batt = "/proc/acpi/battery/";  //Check batteries  DIR *batt_dir = opendir(batt);  if (batt_dir)  {    char fnbuf[40]; // longer than len(ac)+len(HEXDIGIT*4)+len({state|info})    FILE *fp;    const char *pattern = " %39[^:]: %39[ -~]"; // for sscanf    char line[80], key[40], arg[40];    float x, design_capacity = 0.0f, remaining_capacity = 0.0f, present_rate = 0.0f, full_capacity = 0.0f;    struct dirent *ent;    while ((ent = readdir(batt_dir)))    {      if (ent->d_name[0] == '.') { continue; }      snprintf(fnbuf, 40, "%s%s/info", batt, ent->d_name);      fp = fopen(fnbuf, "r");      if (fp)      {        while (fgets(line, 80, fp) && sscanf(line, pattern, key, arg) == 2)        {          if (!strcmp(key, "design capacity") && sscanf(arg, "%g", &x) == 1)          {            design_capacity += x;          }          else if (!strcmp(key, "last full capacity") && sscanf(arg, "%g", &x) == 1)          {            full_capacity += x;          }        }        fclose(fp);      }      snprintf(fnbuf, 40, "%s%s/state", batt, ent->d_name);      fp = fopen(fnbuf, "r");      if (fp)      {        int charging = 0;        while (fgets(line, 80, fp) && sscanf(line, pattern, key, arg) == 2)        {          if (!strcmp(key, "charging state"))          {            if (!strcmp(arg, "discharging"))            {              charging = -1;            }            else if (!strcmp(arg, "charging"))            {              charging = 1;            }          }          else if (!strcmp(key, "present rate") && sscanf(arg, "%g", &x) == 1)          {            present_rate += charging * x;            charging = 0;          }          else if (!strcmp(key, "remaining capacity") && sscanf(arg, "%g:", &x) == 1)          {            remaining_capacity += x;            charging = 0;          }        }        fclose(fp);      }    }    if (design_capacity > 0.0f)    {      BatteryLifePercent = (int)floorf(remaining_capacity / ((full_capacity > 0.0f) ? full_capacity : design_capacity) * 100.0);      if (BatteryLifePercent > 100) { BatteryLifePercent = 100; }      if (present_rate < 0.0f)      {        // Linux specifies rates in mWh or mAh        BatteryLifeTime = (int)floorf(remaining_capacity / (-present_rate) * 3600.0);      }    }    closedir(batt_dir);  }}int CheckBatteryTime(){  BatteryLifeTime = -1;  update_battery_info();  return(BatteryLifeTime);}int CheckBatteryPercent(){  BatteryLifePercent = -1;  update_battery_info();  return(BatteryLifePercent);}/*Functions for battery on FreeBSD/DragonFly by NachIf there's another FreeBSD based OS that doesn'tdefine one of these three, please let me know.*/#elif (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__))#include <sys/types.h>#include <sys/sysctl.h>int CheckBattery(){  int state;  size_t state_len = sizeof(state);  if (!sysctlbyname("hw.acpi.battery.state", &state, &state_len, 0, 0))  {    if ((state > -1) && (state < 7)) //7 == failure    {      if (!state || state&2)      {        return(0); //Plugged in      }      return(1); //Running off of battery    }  }  return(-1);}//Note that I have not yet gotten anyone to test if this function has correct info returnedint CheckBatteryTime(){  int batt_time;  size_t batt_time_len = sizeof(batt_time);  if (!sysctlbyname("hw.acpi.battery.time", &batt_time, &batt_time_len, 0, 0))  {    if (batt_time > -1)    {      return(batt_time * 60);    }  }  return(-1);}int CheckBatteryPercent(){  int life = -1;  size_t life_len = sizeof(life);  sysctlbyname("hw.acpi.battery.life", &life, &life_len, 0, 0);  return(life);}/*Functions for battery on NetBSD/OpenBSD by NachIf there's another NetBSD based OS that usesthe same API, please let me know.Note this was the least tested section for allthe battery specific code.*/#elif (defined(__NetBSD__) || defined(__OpenBSD__))#include <unistd.h>#include <fcntl.h>#include <sys/ioctl.h>#include <machine/apmvar.h>#ifndef APM_BATT_ABSENT#define APM_BATT_ABSENT APM_BATTERY_ABSENT#endifint CheckBattery(){  int fd = open("/dev/apm", O_RDONLY);  if (fd != -1)  {    struct apm_power_info info;    if (!ioctl(fd, APM_IOC_GETPOWER, &info) &&        (info.battery_state != APM_BATT_UNKNOWN) && (info.battery_state != APM_BATT_ABSENT))    {      close(fd);      if ((info.battery_state == APM_BATT_CHARGING) || (info.ac_state == APM_AC_ON)) { return(0); } //Plugged in      return(1); //Running off of battery    }    close(fd);  }  return(-1);}int CheckBatteryTime(){  int fd = open("/dev/apm", O_RDONLY);  if (fd != -1)  {    struct apm_power_info info;    if (!ioctl(fd, APM_IOC_GETPOWER, &info) && (info.minutes_left > 0) && (info.minutes_left < 0xFFFF))    {      close(fd);      return(info.minutes_left*60);    }    close(fd);  }  return(-1);}int CheckBatteryPercent(){  int fd = open("/dev/apm", O_RDONLY);  if (fd != -1)  {    struct apm_power_info info;    if (!ioctl(fd, APM_IOC_GETPOWER, &info))    {      close(fd);      return((info.battery_life == 255) ? 100 : info.battery_life);    }    close(fd);  }  return(-1);}/*Functions for battery on Mac OS X by drizztbsd, NachIf you have issues, please report.*/#elif defined(__APPLE__)#include <sys/types.h>#include <math.h>#include <CoreFoundation/CoreFoundation.h>#include <IOKit/ps/IOPowerSources.h>#include <IOKit/ps/IOPSkeys.h>static int stringsAreEqual(CFStringRef a, CFStringRef b){  if (!a || !b)  {    return(0);  }  return(CFStringCompare(a, b, 0) == kCFCompareEqualTo);}static int BatteryLifeTime;static int BatteryLifePercent;static int HasBattery;static void update_battery_info(){  CFTypeRef    powerBlob = IOPSCopyPowerSourcesInfo();  CFArrayRef   powerSourcesList = IOPSCopyPowerSourcesList(powerBlob);  unsigned int count = CFArrayGetCount(powerSourcesList);  unsigned int i;  unsigned int tmp;  char         ret;  int totalCurrentCapacity = 0, totalMaxCapacity = 0;  BatteryLifeTime = -1;  BatteryLifePercent = -1;  HasBattery = -1;  for (i = 0; i < count; ++i)  {    CFTypeRef       powerSource;    CFDictionaryRef description;    powerSource = CFArrayGetValueAtIndex(powerSourcesList, i);    description = IOPSGetPowerSourceDescription(powerBlob, powerSource);    //continue if one battery is not present    if (CFDictionaryGetValue(description, CFSTR(kIOPSIsPresentKey)) == kCFBooleanFalse)    {      continue;    }    if (stringsAreEqual(CFDictionaryGetValue(description, CFSTR(kIOPSTransportTypeKey)), CFSTR(kIOPSInternalType)))    {      int currentCapacity, maxCapacity;      CFStringRef currentState = CFDictionaryGetValue(description, CFSTR(kIOPSPowerSourceStateKey));      CFNumberRef timeToEmptyNum = CFDictionaryGetValue(description, CFSTR(kIOPSTimeToEmptyKey));      if (CFEqual(currentState, CFSTR(kIOPSACPowerValue)) && (HasBattery != 1))      {        HasBattery = 0;      }      else if (CFEqual(currentState, CFSTR(kIOPSBatteryPowerValue)))      {        CFNumberRef timeToEmptyNum = CFDictionaryGetValue(description, CFSTR(kIOPSTimeToEmptyKey));        if(CFNumberGetValue(timeToEmptyNum, kCFNumberIntType, &tmp))        {          if (BatteryLifeTime > -1)          {            BatteryLifeTime += tmp;          }          else          {            BatteryLifeTime = tmp;          }        }        HasBattery = 1;      }      CFNumberRef currentCapacityNum = CFDictionaryGetValue(description, CFSTR(kIOPSCurrentCapacityKey));      CFNumberRef maxCapacityNum = CFDictionaryGetValue(description, CFSTR(kIOPSMaxCapacityKey));      if (CFNumberGetValue(currentCapacityNum, kCFNumberIntType, &currentCapacity) && CFNumberGetValue(maxCapacityNum, kCFNumberIntType, &maxCapacity))      {        totalCurrentCapacity += currentCapacity;        totalMaxCapacity += maxCapacity;      }    }  }  CFRelease(powerSourcesList);  CFRelease(powerBlob);  if (totalCurrentCapacity && totalMaxCapacity)  {    BatteryLifePercent = (int)roundf((totalCurrentCapacity / (float)totalMaxCapacity) * 100.0f);  }}int CheckBattery(){  update_battery_info();  return(HasBattery);}int CheckBatteryTime(){  update_battery_info();  if (BatteryLifeTime > -1)  {    return(BatteryLifeTime * 60);  }  return(-1);}int CheckBatteryPercent(){  update_battery_info();  return(BatteryLifePercent);}#else //Not Linux, FreeBSD/DragonFlyBSD, NetBSD/OpenBSD, Mac OS Xint CheckBattery(){  return(-1);}int CheckBatteryTime(){  return(-1);}int CheckBatteryPercent(){  return(-1);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -