From 90453f6a96cc10453cb54568f7ead8d87797cb73 Mon Sep 17 00:00:00 2001 From: Edward Cree Date: Sat, 23 May 2015 03:27:12 +0100 Subject: [PATCH] Use 64-bit cmids (instead of 32-bit acids) for crew IDs --- bits.c | 24 ++++++++++++++++++++++++ bits.h | 2 ++ gensave.py | 4 ++-- post_raid.c | 2 +- rand.c | 7 +++++++ rand.h | 1 + saving.c | 10 +++++----- types.h | 3 ++- 8 files changed, 44 insertions(+), 9 deletions(-) diff --git a/bits.c b/bits.c index fcdc901..8a61d4a 100644 --- a/bits.c +++ b/bits.c @@ -178,6 +178,30 @@ int gacid(const char from[8], acid *buf) return(0); } +void pcmid(cmid id, char buf[17]) +{ + for(size_t i=0;i<16;i++) + buf[i]=hex[(id>>(i<<2))&0xf]; + buf[16]=0; +} + +int gcmid(const char from[16], cmid *buf) +{ + if(!buf) return(1); + *buf=0; + unsigned int val; + char fbuf[2]={0, 0}; + for(size_t i=0;i<16;i++) + { + if(!from[i]) break; // Allow short strings. It's fine because we're little endian + if(!isxdigit(from[i])) return(1); + fbuf[0]=from[i]; + sscanf(fbuf, "%x", &val); + *buf|=((uint64_t)val)<<(i<<2); + } + return(0); +} + #ifdef WINDOWS /* doesn't have strndup, we need to implement one */ char *strndup(const char *s, size_t size) { diff --git a/bits.h b/bits.h index b4fb65b..cbfcc47 100644 --- a/bits.h +++ b/bits.h @@ -31,6 +31,8 @@ void free_string(string *s); // frees a string (is just free(s->buf); really) void pacid(acid id, char buf[9]); // print an a/c id as hex int gacid(const char from[8], acid *buf); // parse an a/c id from hex +void pcmid(cmid id, char buf[17]); // similar but for c/m ids +int gcmid(const char from[16], cmid *buf); #ifdef WINDOWS /* doesn't have strndup, we need to implement one */ char *strndup(const char *s, size_t size); diff --git a/gensave.py b/gensave.py index 4a3940c..eb9851a 100755 --- a/gensave.py +++ b/gensave.py @@ -47,9 +47,9 @@ def gencrews(line, i): lrate = poisson(ml) tops = random.randint(0, tops) if windows: - return "%s %c:%s,%u,%u,%u,%s"%(stat, cls, float_to_hex(skill), lrate, tops, ft, acid) + return "%s %c:%s,%u,%u,%u,00000000%s"%(stat, cls, float_to_hex(skill), lrate, tops, ft, acid) else: - return "%s %c:%u,%u,%u,%u,%s"%(stat, cls, skill, lrate, tops, ft, acid) + return "%s %c:%u,%u,%u,%u,00000000%s"%(stat, cls, skill, lrate, tops, ft, acid) windows = '--windows' in sys.argv diff --git a/post_raid.c b/post_raid.c index 448eea5..31a5966 100644 --- a/post_raid.c +++ b/post_raid.c @@ -542,7 +542,7 @@ void refill_students(game *state) } state->crews=new; for(unsigned int j=state->ncrews;jcrews[j]=(crewman){.id=rand_acid(), .class=i, .status=CSTATUS_STUDENT, .skill=0, .lrate=60+irandu(60), .tour_ops=0, .assignment=1}; + state->crews[j]=(crewman){.id=rand_cmid(), .class=i, .status=CSTATUS_STUDENT, .skill=0, .lrate=60+irandu(60), .tour_ops=0, .assignment=1}; state->ncrews=nc; } else if(scount>pool) diff --git a/rand.c b/rand.c index e08cb3b..e40defe 100644 --- a/rand.c +++ b/rand.c @@ -33,3 +33,10 @@ acid rand_acid(void) // but 0xffffffff is probably RAND_MAX anyway return(rand()&0xffffffff); } + +cmid rand_cmid(void) +{ + // and this is unbelievably corny + cmid l=rand_acid(), r=rand_acid(); + return((l<<32)|r); +} diff --git a/rand.h b/rand.h index cbfb793..1dd65be 100644 --- a/rand.h +++ b/rand.h @@ -13,3 +13,4 @@ int irandu(int n); // generate integer from U{0, 1, ... n-1} double drandu(double m); // generate real from U[0,m) bool brandp(double p); // generate Bern(p) acid rand_acid(void); // generate a/c ID +cmid rand_cmid(void); // generate c/m ID diff --git a/saving.c b/saving.c index f354c39..de8c674 100644 --- a/saving.c +++ b/saving.c @@ -355,8 +355,8 @@ int loadgame(const char *fn, game *state) char class; double skill; unsigned int lrate, tops, ft; - char p_id[9]; - f=sscanf(line, "%10s %c:%la,%u,%u,%u,%8s\n", status, &class, &skill, &lrate, &tops, &ft, p_id); + char p_id[17]; + f=sscanf(line, "%10s %c:%la,%u,%u,%u,%16s\n", status, &class, &skill, &lrate, &tops, &ft, p_id); if(f!=7) { fprintf(stderr, "1 Too few arguments to part %u of tag \"%s\"\n", i, tag); @@ -376,7 +376,7 @@ int loadgame(const char *fn, game *state) e|=32; break; } - if(gacid(p_id, &state->crews[i].id)) + if(gcmid(p_id, &state->crews[i].id)) { fprintf(stderr, "32 Invalid value \"%s\" for c/m ID in tag \"%s\"\n", p_id, tag); e|=32; @@ -761,7 +761,7 @@ int savegame(const char *fn, game state) perror("fopen"); return(1); } - char p_id[9]; + char p_id[17]; fprintf(fs, "HARR:%u.%u.%u\n", VER_MAJ, VER_MIN, VER_REV); fprintf(fs, "DATE:%02d-%02d-%04d\n", state.now.day, state.now.month, state.now.year); fprintf(fs, "DClasses:%u\n", DIFFICULTY_CLASSES); @@ -791,7 +791,7 @@ int savegame(const char *fn, game state) fprintf(fs, "Crews:%u\n", state.ncrews); for(unsigned int i=0;i