mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-03 04:18:09 +03:00
Implement DataFile HLL library
It provides access to data tables in *DA.ald, and is used in Big Bang Age. mt19937int.c is the first standard version of Mersenne Twister, downloaded from http://www.math.sci.hiroshima-u.ac.jp/m-mat/MT/VERSIONS/C-LANG/ver980409.html.
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
/* Copyright (C) 2021 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM4_MT19937INT_H
|
||||
#define SYSTEM4_MT19937INT_H
|
||||
|
||||
void sgenrand(unsigned long seed);
|
||||
unsigned long genrand(void);
|
||||
|
||||
#endif /* SYSTEM4_MT19937INT_H */
|
||||
@@ -137,6 +137,7 @@ extern struct static_library lib_AliceLogo;
|
||||
extern struct static_library lib_AliceLogo2;
|
||||
extern struct static_library lib_AliceLogo3;
|
||||
extern struct static_library lib_Confirm2;
|
||||
extern struct static_library lib_DataFile;
|
||||
extern struct static_library lib_DrawGraph;
|
||||
extern struct static_library lib_DrawPluginManager;
|
||||
extern struct static_library lib_File;
|
||||
@@ -158,6 +159,7 @@ static struct static_library *static_libraries[] = {
|
||||
&lib_AliceLogo2,
|
||||
&lib_AliceLogo3,
|
||||
&lib_Confirm2,
|
||||
&lib_DataFile,
|
||||
&lib_DrawGraph,
|
||||
&lib_DrawPluginManager,
|
||||
&lib_File,
|
||||
|
||||
@@ -0,0 +1,409 @@
|
||||
/* Copyright (C) 2021 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "system4/buffer.h"
|
||||
#include "system4/string.h"
|
||||
|
||||
#include "hll.h"
|
||||
#include "mt19937int.h"
|
||||
#include "xsystem4.h"
|
||||
|
||||
enum value_type {
|
||||
GDAT_INT = 0,
|
||||
GDAT_STRING = 2,
|
||||
GDAT_FLOAT = 3
|
||||
};
|
||||
|
||||
struct gdat_col {
|
||||
enum value_type type;
|
||||
uint32_t index;
|
||||
};
|
||||
|
||||
struct gdat_row {
|
||||
struct gdat_col *cols;
|
||||
uint32_t nr_cols;
|
||||
};
|
||||
|
||||
struct gdat_table {
|
||||
struct gdat_row *rows;
|
||||
uint32_t nr_rows;
|
||||
};
|
||||
|
||||
struct gdat {
|
||||
char **labels;
|
||||
uint32_t nr_labels;
|
||||
struct gdat_table *tables;
|
||||
uint32_t nr_tables;
|
||||
int32_t *ints;
|
||||
uint32_t nr_ints;
|
||||
float *floats;
|
||||
uint32_t nr_floats;
|
||||
struct string **strings;
|
||||
uint32_t nr_strings;
|
||||
};
|
||||
|
||||
static struct gdat *current_gdat;
|
||||
|
||||
static void gdat_free(struct gdat *dat)
|
||||
{
|
||||
if (!dat)
|
||||
return;
|
||||
if (dat->labels) {
|
||||
for (uint32_t i = 0; i < dat->nr_labels; i++)
|
||||
free(dat->labels[i]);
|
||||
free(dat->labels);
|
||||
}
|
||||
if (dat->tables) {
|
||||
for (uint32_t i = 0; i < dat->nr_tables; i++) {
|
||||
for (uint32_t j = 0; j < dat->tables[i].nr_rows; j++) {
|
||||
free(dat->tables[i].rows[j].cols);
|
||||
}
|
||||
free(dat->tables[i].rows);
|
||||
}
|
||||
free(dat->tables);
|
||||
}
|
||||
if (dat->ints)
|
||||
free(dat->ints);
|
||||
if (dat->floats)
|
||||
free(dat->floats);
|
||||
if (dat->strings) {
|
||||
for (uint32_t i = 0; i < dat->nr_strings; i++) {
|
||||
if (dat->strings[i])
|
||||
free_string(dat->strings[i]);
|
||||
}
|
||||
free(dat->strings);
|
||||
}
|
||||
free(dat);
|
||||
}
|
||||
|
||||
static struct gdat *gdat_read(struct buffer *r)
|
||||
{
|
||||
if (strncmp(buffer_strdata(r), "GDAT", 4)) {
|
||||
WARNING("Missing GDAT section marker");
|
||||
return NULL;
|
||||
}
|
||||
buffer_skip(r, 4);
|
||||
|
||||
int32_t version = buffer_read_int32(r);
|
||||
if (version != 1) {
|
||||
WARNING("Unknown GDAT version %d", version);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct gdat *dat = xcalloc(1, sizeof(struct gdat));
|
||||
|
||||
if (strncmp(buffer_strdata(r), "LABL", 4)) {
|
||||
WARNING("Missing LABL section marker");
|
||||
gdat_free(dat);
|
||||
return NULL;
|
||||
}
|
||||
buffer_skip(r, 4);
|
||||
|
||||
dat->nr_labels = buffer_read_int32(r);
|
||||
dat->labels = xcalloc(dat->nr_labels, sizeof(const char *));
|
||||
for (uint32_t i = 0; i < dat->nr_labels; i++) {
|
||||
dat->labels[i] = xstrdup(buffer_strdata(r));
|
||||
buffer_skip(r, strlen(dat->labels[i]) + 1);
|
||||
}
|
||||
|
||||
if (strncmp(buffer_strdata(r), "DATA", 4)) {
|
||||
WARNING("Missing DATA section marker");
|
||||
gdat_free(dat);
|
||||
return NULL;
|
||||
}
|
||||
buffer_skip(r, 4);
|
||||
|
||||
dat->nr_tables = buffer_read_int32(r);
|
||||
dat->tables = xcalloc(dat->nr_tables, sizeof(struct gdat_table));
|
||||
for (uint32_t i = 0; i < dat->nr_tables; i++) {
|
||||
struct gdat_table *tbl = &dat->tables[i];
|
||||
tbl->nr_rows = buffer_read_int32(r);
|
||||
tbl->rows = xcalloc(tbl->nr_rows, sizeof(struct gdat_row));
|
||||
for (uint32_t j = 0; j < tbl->nr_rows; j++) {
|
||||
struct gdat_row *row = &tbl->rows[j];
|
||||
row->nr_cols = buffer_read_int32(r);
|
||||
row->cols = xcalloc(row->nr_cols, sizeof(struct gdat_col));
|
||||
for (uint32_t k = 0; k < row->nr_cols; k++) {
|
||||
row->cols[k].type = buffer_read_int32(r);
|
||||
row->cols[k].index = buffer_read_int32(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strncmp(buffer_strdata(r), "INT_", 4) == 0) {
|
||||
buffer_skip(r, 4);
|
||||
dat->nr_ints = buffer_read_int32(r);
|
||||
dat->ints = xmalloc(dat->nr_ints * sizeof(int32_t));
|
||||
for (uint32_t i = 0; i < dat->nr_ints; i++)
|
||||
dat->ints[i] = buffer_read_int32(r);
|
||||
}
|
||||
|
||||
if (strncmp(buffer_strdata(r), "FLOT", 4) == 0) {
|
||||
buffer_skip(r, 4);
|
||||
dat->nr_floats = buffer_read_int32(r);
|
||||
dat->floats = xmalloc(dat->nr_floats * sizeof(float));
|
||||
for (uint32_t i = 0; i < dat->nr_floats; i++)
|
||||
dat->floats[i] = buffer_read_float(r);
|
||||
}
|
||||
|
||||
if (strncmp(buffer_strdata(r), "STRG", 4) == 0) {
|
||||
buffer_skip(r, 4);
|
||||
dat->nr_strings = buffer_read_int32(r);
|
||||
dat->strings = xcalloc(dat->nr_strings, sizeof(struct string*));
|
||||
for (uint32_t i = 0; i < dat->nr_strings; i++) {
|
||||
dat->strings[i] = cstr_to_string(buffer_strdata(r));
|
||||
buffer_skip(r, dat->strings[i]->size + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer_remaining(r)) {
|
||||
WARNING("Unknown GDAT section header");
|
||||
gdat_free(dat);
|
||||
return NULL;
|
||||
}
|
||||
return dat;
|
||||
}
|
||||
|
||||
static struct gdat_table *gdat_get_table(struct gdat *dat, int table)
|
||||
{
|
||||
if (!dat || table < 0 || table >= dat->nr_tables) {
|
||||
WARNING("Table index out of bounds: %d", table);
|
||||
return NULL;
|
||||
}
|
||||
return &dat->tables[table];
|
||||
}
|
||||
|
||||
static struct gdat_row *gdat_get_row(struct gdat *dat, int table, int row)
|
||||
{
|
||||
struct gdat_table *tbl = gdat_get_table(dat, table);
|
||||
if (!tbl)
|
||||
return NULL;
|
||||
if (row < 0 || row >= tbl->nr_rows) {
|
||||
WARNING("Row index out of bounds: %d", row);
|
||||
return NULL;
|
||||
}
|
||||
return &tbl->rows[row];
|
||||
}
|
||||
|
||||
static struct gdat_col *gdat_get_column(struct gdat *dat, int table, int row, int col)
|
||||
{
|
||||
struct gdat_row *r = gdat_get_row(dat, table, row);
|
||||
if (!r)
|
||||
return NULL;
|
||||
if (col < 0 || col >= r->nr_cols) {
|
||||
WARNING("Column index out of bounds: %d", col);
|
||||
return NULL;
|
||||
}
|
||||
return &r->cols[col];
|
||||
}
|
||||
|
||||
// for debug
|
||||
possibly_unused static void gdat_dump_as_json(struct gdat *dat, FILE *fp)
|
||||
{
|
||||
fputs("{\n", fp);
|
||||
for (uint32_t i = 0; i < dat->nr_tables; i++) {
|
||||
fprintf(fp, " \"%s\": [\n", dat->labels[i]);
|
||||
struct gdat_table *tbl = &dat->tables[i];
|
||||
for (uint32_t j = 0; j < tbl->nr_rows; j++) {
|
||||
fputs(" [", fp);
|
||||
struct gdat_row *row = &tbl->rows[j];
|
||||
for (uint32_t k = 0; k < row->nr_cols; k++) {
|
||||
struct gdat_col *col = &row->cols[k];
|
||||
switch (col->type) {
|
||||
case GDAT_INT:
|
||||
fprintf(fp, "%d", dat->ints[col->index]);
|
||||
break;
|
||||
case GDAT_FLOAT:
|
||||
fprintf(fp, "%f", dat->floats[col->index]);
|
||||
break;
|
||||
case GDAT_STRING:
|
||||
fprintf(fp, "\"%s\"", dat->strings[col->index]->text);
|
||||
break;
|
||||
}
|
||||
if (k < row->nr_cols - 1)
|
||||
fputs(", ", fp);
|
||||
}
|
||||
fprintf(fp, "]%s\n", j < tbl->nr_rows - 1 ? "," : "");
|
||||
}
|
||||
fprintf(fp, " ]%s\n", i < dat->nr_labels - 1 ? "," : "");
|
||||
}
|
||||
fputs("}\n", fp);
|
||||
}
|
||||
|
||||
static int DataFile_Open(int link)
|
||||
{
|
||||
struct archive_data *dfile = archive_get(ald[ALDFILE_DATA], link - 1);
|
||||
if (!dfile) {
|
||||
WARNING("Failed to load data file %d", link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct buffer r;
|
||||
buffer_init(&r, dfile->data, dfile->size);
|
||||
|
||||
if (strncmp(buffer_strdata(&r), "DD\x01\x01", 4)) {
|
||||
WARNING("Invalid data file");
|
||||
archive_free_data(dfile);
|
||||
return 0;
|
||||
}
|
||||
buffer_skip(&r, 4);
|
||||
|
||||
unsigned long uncompressed_size = buffer_read_int32(&r);
|
||||
uint32_t compressed_size = buffer_remaining(&r);
|
||||
|
||||
// decode compressed data
|
||||
uint8_t *compressed_data = xmalloc(compressed_size);
|
||||
buffer_read_bytes(&r, compressed_data, compressed_size);
|
||||
archive_free_data(dfile);
|
||||
sgenrand(4588163);
|
||||
for (size_t i = 0; i < compressed_size; i++)
|
||||
compressed_data[i] ^= genrand();
|
||||
|
||||
uint8_t *raw = xmalloc(uncompressed_size);
|
||||
int rv = uncompress(raw, &uncompressed_size, compressed_data, compressed_size);
|
||||
free(compressed_data);
|
||||
if (rv != Z_OK) {
|
||||
WARNING("Uncompress failed: %d", rv);
|
||||
free(raw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
buffer_init(&r, raw, uncompressed_size);
|
||||
gdat_free(current_gdat);
|
||||
current_gdat = gdat_read(&r);
|
||||
|
||||
free(raw);
|
||||
return current_gdat ? 1 : 0;
|
||||
}
|
||||
|
||||
static int DataFile_SarchLabel(struct string *label)
|
||||
{
|
||||
if (!current_gdat)
|
||||
return -1;
|
||||
for (uint32_t i = 0; i < current_gdat->nr_labels; i++) {
|
||||
if (!strcmp(current_gdat->labels[i], label->text))
|
||||
return i;
|
||||
}
|
||||
WARNING("Label '%s' not found", label->text);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int DataFile_GetNumofVertical(int label)
|
||||
{
|
||||
struct gdat_table *tbl = gdat_get_table(current_gdat, label);
|
||||
return tbl ? tbl->nr_rows : -1;
|
||||
}
|
||||
|
||||
static int DataFile_GetNumofHorizontal(int label, int vartical)
|
||||
{
|
||||
struct gdat_row *row = gdat_get_row(current_gdat, label, vartical);
|
||||
return row ? row->nr_cols : -1;
|
||||
}
|
||||
|
||||
static int DataFile_SarchString(int label, int horizontal, struct string *data)
|
||||
{
|
||||
struct gdat_table *tbl = gdat_get_table(current_gdat, label);
|
||||
if (!tbl)
|
||||
return -1;
|
||||
for (int i = 0; i < tbl->nr_rows; i++) {
|
||||
struct gdat_row *row = &tbl->rows[i];
|
||||
if (horizontal < row->nr_cols &&
|
||||
row->cols[horizontal].type == GDAT_STRING &&
|
||||
!strcmp(current_gdat->strings[row->cols[horizontal].index]->text, data->text))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int DataFile_SarchInt(int label, int horizontal, int data)
|
||||
{
|
||||
struct gdat_table *tbl = gdat_get_table(current_gdat, label);
|
||||
if (!tbl)
|
||||
return -1;
|
||||
for (int i = 0; i < tbl->nr_rows; i++) {
|
||||
struct gdat_row *row = &tbl->rows[i];
|
||||
if (horizontal < row->nr_cols &&
|
||||
row->cols[horizontal].type == GDAT_INT &&
|
||||
current_gdat->ints[row->cols[horizontal].index] == data)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int DataFile_GetInt(int label, int vartical, int horizontal)
|
||||
{
|
||||
struct gdat_col *col = gdat_get_column(current_gdat, label, vartical, horizontal);
|
||||
if (!col)
|
||||
return -1;
|
||||
|
||||
if (col->type != GDAT_INT) {
|
||||
WARNING("Value is not an int");
|
||||
return -1;
|
||||
}
|
||||
if (col->index >= current_gdat->nr_ints) {
|
||||
WARNING("Broken GDAT table; integer index %d out of bounds", col->index);
|
||||
return -1;
|
||||
}
|
||||
return current_gdat->ints[col->index];
|
||||
}
|
||||
|
||||
static float DataFile_GetFloat(int label, int vartical, int horizontal)
|
||||
{
|
||||
struct gdat_col *col = gdat_get_column(current_gdat, label, vartical, horizontal);
|
||||
if (!col)
|
||||
return -1.0;
|
||||
|
||||
if (col->type != GDAT_FLOAT) {
|
||||
WARNING("Value is not a float");
|
||||
return -1.0;
|
||||
}
|
||||
if (col->index >= current_gdat->nr_floats) {
|
||||
WARNING("Broken GDAT table; float index %d out of bounds", col->index);
|
||||
return -1.0;
|
||||
}
|
||||
return current_gdat->floats[col->index];
|
||||
}
|
||||
|
||||
static struct string *DataFile_GetString(int label, int vartical, int horizontal)
|
||||
{
|
||||
struct gdat_col *col = gdat_get_column(current_gdat, label, vartical, horizontal);
|
||||
if (!col)
|
||||
return string_ref(&EMPTY_STRING);
|
||||
|
||||
if (col->type != GDAT_STRING) {
|
||||
WARNING("Value is not a string");
|
||||
return string_ref(&EMPTY_STRING);
|
||||
}
|
||||
if (col->index >= current_gdat->nr_strings) {
|
||||
WARNING("Broken GDAT table; string index %d out of bounds", col->index);
|
||||
return string_ref(&EMPTY_STRING);
|
||||
}
|
||||
return string_ref(current_gdat->strings[col->index]);
|
||||
}
|
||||
|
||||
HLL_LIBRARY(DataFile,
|
||||
HLL_EXPORT(Open, DataFile_Open),
|
||||
HLL_EXPORT(SarchLabel, DataFile_SarchLabel),
|
||||
HLL_EXPORT(GetNumofVertical, DataFile_GetNumofVertical),
|
||||
HLL_EXPORT(GetNumofHorizontal, DataFile_GetNumofHorizontal),
|
||||
HLL_EXPORT(SarchString, DataFile_SarchString),
|
||||
HLL_EXPORT(SarchInt, DataFile_SarchInt),
|
||||
HLL_EXPORT(GetInt, DataFile_GetInt),
|
||||
HLL_EXPORT(GetFloat, DataFile_GetFloat),
|
||||
HLL_EXPORT(GetString, DataFile_GetString));
|
||||
@@ -8,6 +8,7 @@ xsystem4 = ['audio.c',
|
||||
'format.c',
|
||||
'heap.c',
|
||||
'input.c',
|
||||
'mt19937int.c',
|
||||
'page.c',
|
||||
'resume.c',
|
||||
'sact_graphics.c',
|
||||
@@ -22,6 +23,7 @@ xsystem4 = ['audio.c',
|
||||
'hll/AliceLogo2.c',
|
||||
'hll/AliceLogo3.c',
|
||||
'hll/Confirm2.c',
|
||||
'hll/DataFile.c',
|
||||
'hll/DrawGraph.c',
|
||||
'hll/DrawPluginManager.c',
|
||||
'hll/File.c',
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/* A C-program for MT19937: Integer version (1998/4/6) */
|
||||
/* genrand() generates one pseudorandom unsigned integer (32bit) */
|
||||
/* which is uniformly distributed among 0 to 2^32-1 for each */
|
||||
/* call. sgenrand(seed) set initial values to the working area */
|
||||
/* of 624 words. Before genrand(), sgenrand(seed) must be */
|
||||
/* called once. (seed is any 32-bit integer except for 0). */
|
||||
/* Coded by Takuji Nishimura, considering the suggestions by */
|
||||
/* Topher Cooper and Marc Rieffel in July-Aug. 1997. */
|
||||
|
||||
/* This library is free software; you can redistribute it and/or */
|
||||
/* modify it under the terms of the GNU Library General Public */
|
||||
/* License as published by the Free Software Foundation; either */
|
||||
/* version 2 of the License, or (at your option) any later */
|
||||
/* version. */
|
||||
/* This library is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */
|
||||
/* See the GNU Library General Public License for more details. */
|
||||
/* You should have received a copy of the GNU Library General */
|
||||
/* Public License along with this library; if not, write to the */
|
||||
/* Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */
|
||||
/* 02111-1307 USA */
|
||||
|
||||
/* Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. */
|
||||
/* When you use this, send an email to: matumoto@math.keio.ac.jp */
|
||||
/* with an appropriate reference to your work. */
|
||||
|
||||
/* REFERENCE */
|
||||
/* M. Matsumoto and T. Nishimura, */
|
||||
/* "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform */
|
||||
/* Pseudo-Random Number Generator", */
|
||||
/* ACM Transactions on Modeling and Computer Simulation, */
|
||||
/* Vol. 8, No. 1, January 1998, pp 3--30. */
|
||||
|
||||
#include<stdio.h>
|
||||
|
||||
#include "mt19937int.h"
|
||||
|
||||
/* Period parameters */
|
||||
#define N 624
|
||||
#define M 397
|
||||
#define MATRIX_A 0x9908b0df /* constant vector a */
|
||||
#define UPPER_MASK 0x80000000 /* most significant w-r bits */
|
||||
#define LOWER_MASK 0x7fffffff /* least significant r bits */
|
||||
|
||||
/* Tempering parameters */
|
||||
#define TEMPERING_MASK_B 0x9d2c5680
|
||||
#define TEMPERING_MASK_C 0xefc60000
|
||||
#define TEMPERING_SHIFT_U(y) (y >> 11)
|
||||
#define TEMPERING_SHIFT_S(y) (y << 7)
|
||||
#define TEMPERING_SHIFT_T(y) (y << 15)
|
||||
#define TEMPERING_SHIFT_L(y) (y >> 18)
|
||||
|
||||
static unsigned long mt[N]; /* the array for the state vector */
|
||||
static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
|
||||
|
||||
/* initializing the array with a NONZERO seed */
|
||||
void
|
||||
sgenrand(seed)
|
||||
unsigned long seed;
|
||||
{
|
||||
/* setting initial seeds to mt[N] using */
|
||||
/* the generator Line 25 of Table 1 in */
|
||||
/* [KNUTH 1981, The Art of Computer Programming */
|
||||
/* Vol. 2 (2nd Ed.), pp102] */
|
||||
mt[0]= seed & 0xffffffff;
|
||||
for (mti=1; mti<N; mti++)
|
||||
mt[mti] = (69069 * mt[mti-1]) & 0xffffffff;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
genrand()
|
||||
{
|
||||
unsigned long y;
|
||||
static unsigned long mag01[2]={0x0, MATRIX_A};
|
||||
/* mag01[x] = x * MATRIX_A for x=0,1 */
|
||||
|
||||
if (mti >= N) { /* generate N words at one time */
|
||||
int kk;
|
||||
|
||||
if (mti == N+1) /* if sgenrand() has not been called, */
|
||||
sgenrand(4357); /* a default initial seed is used */
|
||||
|
||||
for (kk=0;kk<N-M;kk++) {
|
||||
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
|
||||
mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
|
||||
}
|
||||
for (;kk<N-1;kk++) {
|
||||
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
|
||||
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
|
||||
}
|
||||
y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
|
||||
mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
|
||||
|
||||
mti = 0;
|
||||
}
|
||||
|
||||
y = mt[mti++];
|
||||
y ^= TEMPERING_SHIFT_U(y);
|
||||
y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
|
||||
y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
|
||||
y ^= TEMPERING_SHIFT_L(y);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* this main() outputs first 1000 generated numbers */
|
||||
main()
|
||||
{
|
||||
int j;
|
||||
|
||||
sgenrand(4357); /* any nonzero integer can be used as a seed */
|
||||
for (j=0; j<1000; j++) {
|
||||
printf("%10lu ", genrand());
|
||||
if (j%8==7) printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
@@ -205,6 +205,11 @@ static void init_gamedata_dir(const char *path)
|
||||
ald_filenames[ALDFILE_WAVE][dno] = strdup(filepath);
|
||||
ald_count[ALDFILE_WAVE] = max(ald_count[ALDFILE_WAVE], dno+1);
|
||||
break;
|
||||
case 'd':
|
||||
case 'D':
|
||||
ald_filenames[ALDFILE_DATA][dno] = strdup(filepath);
|
||||
ald_count[ALDFILE_DATA] = max(ald_count[ALDFILE_DATA], dno+1);
|
||||
break;
|
||||
default:
|
||||
WARNING("Unhandled ALD file: %s", d->d_name);
|
||||
break;
|
||||
@@ -231,6 +236,8 @@ static void init_gamedata_dir(const char *path)
|
||||
ald_init(ALDFILE_CG, ald_filenames[ALDFILE_CG], ald_count[ALDFILE_CG]);
|
||||
if (ald_count[ALDFILE_WAVE] > 0)
|
||||
ald_init(ALDFILE_WAVE, ald_filenames[ALDFILE_WAVE], ald_count[ALDFILE_WAVE]);
|
||||
if (ald_count[ALDFILE_DATA] > 0)
|
||||
ald_init(ALDFILE_DATA, ald_filenames[ALDFILE_DATA], ald_count[ALDFILE_DATA]);
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user