ref: b492d42e2545b8c414c917f7544bdd4b92e406e8
dir: /colo.c/
#include <u.h>
#include <libc.h>
#include <mp.h>
#include <libsec.h>
#include "colodat.h"
#include "gen3dat.h"
#include "pse.h"
#define GET2(p) (u16int)(p)[1] | (u16int)(p)[0]<<8
#define GET4(p) (u32int)(p)[3] | (u32int)(p)[2]<<8 | (u32int)(p)[1]<<16 | (u32int)(p)[0]<<24
static void
dodecrypt(uchar *dst, uchar *src)
{
uchar d1[SHA1dlen];
uchar d2[SHA1dlen];
uchar *s, *e, *dot;
int i;
memcpy(d2, src + Slotszcolo - SHA1dlen, SHA1dlen);
for(i = 0; i < SHA1dlen; i++)
d2[i] = ~d2[i];
s = src + 0x18;
dst += 0x18;
e = src + Slotszcolo - (2*SHA1dlen);
while(s < e){
dot = s + SHA1dlen;
if(dot > e)
dot = e;
sha1(s, dot - s, d1, nil);
for(i = 0; i < dot - s; i++)
*dst++ = s[i] ^ d2[i];
memmove(d2, d1, dot - s);
s = dot;
}
}
void
getcolo(int fd, Colo *dst)
{
uchar buf[0x6000];
int i;
uchar *dd;
u32int max = 0;
if(readn(fd, dst->gcihdr, sizeof dst->gcihdr) != sizeof dst->gcihdr)
sysfatal("read: %r");
if(readn(fd, buf, sizeof buf) != sizeof buf)
sysfatal("read: %r");
for(i = 0; i < nelem(dst->slots); i++)
if(readn(fd, dst->slots[i], sizeof dst->slots[i]) != sizeof dst->slots[i])
sysfatal("read: %r");
for(i = 0; i < nelem(dst->index); i++){
dst->index[i] = GET4(&dst->slots[i][4]);
if(dst->index[i] > max)
dst->active = dst->slots[i];
}
dodecrypt(dst->decrypted, dst->active);
gettrainercolo(&dst->tr, dst->decrypted+0x78);
dst->money = GET4(dst->decrypted+0xAFC);
dst->coupons = GET4(dst->decrypted+0xB00);
dd = dst->decrypted + 0x00B90;
for(i = 0; i < 30*3; i++){
getpokemoncolo(dst->pc+i, dd + ((i/30 + 1) * 0x14));
dd += 312;
}
}
#pragma varargck type "L" uchar*
/* colo strings are UTF16 but the game predates surrogate pairs */
static int
colostrfmt(Fmt *f)
{
uchar *p;
Rune r;
int n;
p = va_arg(f->args, uchar*);
for(n = 0;; p +=2){
r = GET2(p);
if(r == 0)
break;
n += fmtprint(f, "%C", r);
}
return n;
}
static void
vinit(void)
{
fmtinstall('L', colostrfmt);
}
extern int gen3speciestab[];
extern char *dexfiletab[];
extern char *movenametab[];
static int
vdex(void *v)
{
Pokemoncolo *p;
p = v;
if(p->species == 0)
return -1;
return gen3speciestab[p->species]-1;
}
static int
vhdr(char *dst, char *e, void *v, int box)
{
Colo *s;
s = v;
dst = seprint(dst, e, "Name: %L ID: %d Secret ID: %d\n", s->tr.name, s->tr.id, s->tr.secretid);
dst = seprint(dst, e, "Game: Colosseum Money: %ud Coupons: %ud\n", s->money, s->coupons);
seprint(dst, e, "Box %d: %L\n", box+1, s->decrypted + 0x00B90 + box*0x24a4);
return 0;
}
static int
vbody(char *dst, char *e, void *v)
{
Pokemoncolo *p;
p = v;
dst = seprint(dst, e, "Name: %L\n", p->name);
dst = seprint(dst, e, "OT Name: %L OT ID: %ud OT Secret ID: %d\n", p->otname, p->otid, p->otsecretid);
dst = seprint(dst, e, "National Dex: %d\n", gen3speciestab[p->species]-1);
dst = seprint(dst, e, "Exp: %d\n", p->exp);
dst = seprint(dst, e, "Move 1: %s Move 2: %s\n", movenametab[p->moves[0].id], movenametab[p->moves[1].id]);
dst = seprint(dst, e, "Move 3: %s Move 4: %s\n", movenametab[p->moves[2].id], movenametab[p->moves[3].id]);
dst = seprint(dst, e, "[EV] HP: %d Atk: %d Def: %d SpA: %d SpD: %d Spe: %d\n", p->ev.hp, p->ev.atk, p->ev.def, p->ev.spa, p->ev.spd, p->ev.spe);
seprint(dst, e, "[IV] HP: %d Atk: %d Def: %d SpA: %d SpD: %d Spe: %d\n", p->iv.hp, p->iv.atk, p->iv.def, p->iv.spa, p->iv.spd, p->iv.spe);
return 0;
}
static void*
vbox(int box, int i, void *v)
{
Colo *c;
c = v;
return c->pc + box*30 + i;
}
View vcolo = {
vinit,
vhdr,
vdex,
vbody,
vbox,
};