Bemanitools v5.26 release
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config/resource.h"
|
||||
|
||||
#include "util/array.h"
|
||||
#include "util/log.h"
|
||||
#include "util/str.h"
|
||||
#include "util/winres.h"
|
||||
|
||||
struct usage {
|
||||
uint16_t id;
|
||||
char name[128];
|
||||
};
|
||||
|
||||
struct usage_page {
|
||||
uint16_t id;
|
||||
struct array usages;
|
||||
char wildcard[128];
|
||||
};
|
||||
|
||||
static struct array usages;
|
||||
|
||||
static bool usages_begin_page(const char *line, struct usage_page *page);
|
||||
static bool usages_read_usage(const char *line, struct usage_page *page);
|
||||
|
||||
void usages_init(HINSTANCE inst)
|
||||
{
|
||||
struct resource res;
|
||||
struct usage_page *cur_page;
|
||||
struct usage_page tmp_page;
|
||||
char line[512];
|
||||
size_t line_no;
|
||||
size_t nchars;
|
||||
|
||||
resource_open(&res, inst, "USAGES", IDR_USAGES);
|
||||
array_init(&usages);
|
||||
|
||||
cur_page = NULL;
|
||||
line_no = 0;
|
||||
|
||||
while (resource_fgets(&res, line, sizeof(line))) {
|
||||
line_no++;
|
||||
|
||||
nchars = strlen(line);
|
||||
|
||||
if (nchars == 0 || line[0] == '#'
|
||||
|| strspn(line, " \t\r\n") == nchars) {
|
||||
continue;
|
||||
}
|
||||
|
||||
str_trim(line);
|
||||
|
||||
if (!isspace(line[0])) {
|
||||
if (!usages_begin_page(line, &tmp_page)) {
|
||||
log_fatal("IDR_USAGES:%u: Invalid usage page",
|
||||
(unsigned int) line_no);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
cur_page = array_append(struct usage_page, &usages);
|
||||
memcpy(cur_page, &tmp_page, sizeof(tmp_page));
|
||||
} else {
|
||||
if (cur_page == NULL) {
|
||||
log_fatal("IDR_USAGES:%u: Usage before first page",
|
||||
(unsigned int) line_no);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!usages_read_usage(line, cur_page)) {
|
||||
log_fatal("IDR_USAGES:%u: Invalid usage",
|
||||
(unsigned int) line_no);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool usages_begin_page(const char *line, struct usage_page *page)
|
||||
{
|
||||
int id;
|
||||
|
||||
if (sscanf(line, "%i", &id) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
page->id = (uint16_t) id;
|
||||
array_init(&page->usages);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool usages_read_usage(const char *line, struct usage_page *page)
|
||||
{
|
||||
struct usage *usage;
|
||||
int id;
|
||||
int offset;
|
||||
char c;
|
||||
|
||||
if (sscanf(line, " %c %n", &c, &offset) == 1 && c == '*') {
|
||||
str_cpy(page->wildcard, sizeof(page->wildcard), &line[offset]);
|
||||
page->wildcard[sizeof(page->wildcard) - 1] = '\0';
|
||||
|
||||
return true;
|
||||
} else if (sscanf(line, " %i %n", &id, &offset) == 1) {
|
||||
usage = array_append(struct usage, &page->usages);
|
||||
|
||||
usage->id = (uint16_t) id;
|
||||
str_cpy(usage->name, sizeof(usage->name), &line[offset]);
|
||||
usage->name[sizeof(usage->name) - 1] = '\0';
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void usages_get(char *chars, size_t nchars, uint32_t usage_id)
|
||||
{
|
||||
const struct usage_page *page;
|
||||
const struct usage *usage;
|
||||
uint16_t hi;
|
||||
uint16_t lo;
|
||||
size_t i;
|
||||
size_t j;
|
||||
|
||||
hi = ((usage_id >> 16) & 0xFFFF);
|
||||
lo = ((usage_id >> 0) & 0xFFFF);
|
||||
|
||||
for (i = 0 ; i < usages.nitems ; i++) {
|
||||
page = array_item(struct usage_page, &usages, i);
|
||||
|
||||
if (page->id != hi) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0 ; j < page->usages.nitems ; j++) {
|
||||
usage = array_item(struct usage, &page->usages, j);
|
||||
|
||||
if (usage->id == lo) {
|
||||
str_cpy(chars, nchars, usage->name);
|
||||
chars[nchars - 1] = '\0';
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (page->wildcard[0]) {
|
||||
str_format(chars, nchars, page->wildcard, lo);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
str_format(chars, nchars, "%#08x", usage_id);
|
||||
}
|
||||
|
||||
void usages_fini(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0 ; i < usages.nitems ; i++) {
|
||||
array_fini(&array_item(struct usage_page, &usages, i)->usages);
|
||||
}
|
||||
|
||||
array_fini(&usages);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user