ref: 5e0dae801ca8b4d79a1fa08667b42f5457005e73
parent: cbdeb8387a30444a50f0f8561e0249cd0dc9b3cb
author: Jacob Moody <moody@posixcafe.org>
date: Wed May 17 23:05:30 EDT 2023
slight refactor, shiny check, game type parse
--- a/gen3.c
+++ b/gen3.c
@@ -3,6 +3,12 @@
#include "gen3dat.h"
#include "gen3.h"
+char *gen3gnametab[] = {
+ [GRS] "Ruby/Sapphire",
+ [GFRLG] "Fire Red/Leaf Green",
+ [GEM] "Emerald",
+};
+
int poketab[24][4] = {
{0, 12, 36, 24},
{0, 12, 24, 36},
@@ -54,10 +60,19 @@
memcpy(buf + t[1], src->data + 12, 12);
memcpy(buf + t[2], src->data + 24, 12);
memcpy(buf + t[3], src->data + 36, 12);
- cryptpokedat(buf, src->otid, src->personality);
+ cryptpokedat(buf, src->otid|(src->otsecretid<<16), src->personality);
assert(getpokedat(dst, buf) == sizeof buf);
}
+int
+gen3shiny(Pokemon *p)
+{
+ u16int v;
+
+ v = p->otid ^ p->otsecretid ^ (u16int)(p->personality>>16) ^ (u16int)(p->personality);
+ return v < 8;
+}
+
void
gen3pkstr(uchar *d, uchar *p, int n)
{
@@ -74,6 +89,19 @@
*d = 0;
}
+int
+gen3strfmt(Fmt *f)
+{
+ uchar *p;
+ long n;
+ uchar buf[32];
+
+ p = va_arg(f->args, uchar*);
+ n = va_arg(f->args, long);
+ gen3pkstr(buf, p, n);
+ return fmtprint(f, "%s", (char*)buf);
+}
+
void
getgen3iv(Gen3iv *dst, u32int src)
{
@@ -99,6 +127,7 @@
getgen3(int fd, Gen3 *save)
{
int i, j;
+ long off;
uchar buf[8192];
for(i = 0; i < 14; i++){
@@ -118,9 +147,30 @@
switch(save->active[i].id){
case STrainer:
gettrainer(&save->tr, save->active[i].data);
+ switch(save->tr.gamecode){
+ case 0:
+ save->type = GRS;
+ break;
+ case 1:
+ save->type = GFRLG;
+ break;
+ default:
+ save->type = GEM;
+ break;
+ }
break;
case SInvent:
- getinvent(&save->inv, save->active[i].data + 0x34);
+ switch(save->type){
+ default:
+ case GEM:
+ case GRS:
+ off = 0x234;
+ break;
+ case GFRLG:
+ off = 0x34;
+ break;
+ }
+ getinvent(&save->inv, save->active[i].data + off);
break;
case SState: case SMisc: case SRiv:
break;
--- a/gen3.h
+++ b/gen3.h
@@ -21,6 +21,8 @@
GEM,
};
+extern char* gen3gnametab[];
+
long getsection(Section*,uchar*);
long gettrainer(Trainer*,uchar*);
long getinvent(Invent*,uchar*);
@@ -53,7 +55,9 @@
};
void gen3pkstr(uchar *d, uchar *s, int n);
+int gen3strfmt(Fmt*);
void getgen3(int fd, Gen3 *save);
void decryptpokemon(Pokedat *dst, Pokemon *src);
void getgen3iv(Gen3iv *dst, u32int src);
int getgen3dex(u16int species);
+int gen3shiny(Pokemon*);
--- a/gen3dat.c
+++ b/gen3dat.c
@@ -347,8 +347,10 @@
n = 0;
ret->personality = GET4(data+n);
n += 4;
- ret->otid = GET4(data+n);
- n += 4;
+ ret->otid = GET2(data+n);
+ n += 2;
+ ret->otsecretid = GET2(data+n);
+ n += 2;
memcpy(ret->name, data+n, 10);
n += 10;
ret->lang = GET2(data+n);
@@ -374,8 +376,10 @@
n = 0;
PUT4(dst+n, src->personality);
n += 4;
- PUT4(dst+n, src->otid);
- n += 4;
+ PUT2(dst+n, src->otid);
+ n += 2;
+ PUT2(dst+n, src->otsecretid);
+ n += 2;
memcpy(dst+n, src->name, 10);
n += 10;
PUT2(dst+n, src->lang);
--- a/gen3dat.h
+++ b/gen3dat.h
@@ -87,7 +87,8 @@
struct Pokemon {
u32int personality;
- u32int otid;
+ u16int otid;
+ u16int otsecretid;
uchar name[10];
u16int lang;
uchar otname[7];
--- a/view.c
+++ b/view.c
@@ -11,18 +11,6 @@
Gen3 gen3;
-static void
-mklower(char *d, char *e, char *s)
-{
- assert(d <= e-1);
- for(; *s != 0 && d < e-1; s++){
- if(!isascii(*s))
- continue;
- *d++ = tolower(*s);
- }
- *d = 0;
-}
-
int currentbox = 0;
Pokemon *currentpk = nil;
Point spwd;
@@ -43,6 +31,19 @@
currentbox = 13;
}
+static int
+screenprint(Point p, char *format, ...)
+{
+ char buf[256];
+ va_list v;
+
+ va_start(v, format);
+ vsnprint(buf, sizeof buf, format, v);
+ va_end(v);
+ string(screen, p, display->black, ZP, display->defaultfont, buf);
+ return display->defaultfont->height;
+}
+
static void
redraw(void)
{
@@ -50,6 +51,7 @@
char path[128];
Image *image;
Rectangle r, r2;
+ Point p;
Pokedat pd;
Gen3iv iv;
int i;
@@ -60,33 +62,25 @@
r2 = r;
spwd = Pt(68*2, 56*2);
- gen3pkstr((uchar*)buf, gen3.tr.name, sizeof gen3.tr.name);
- snprint(path, sizeof path, "Name: %s ID: %d Secret ID: %d", buf, gen3.tr.id, gen3.tr.secretid);
- string(screen, r.min, display->black, ZP, display->defaultfont, path);
- r.min.y += display->defaultfont->height;
- snprint(path, sizeof path, "Time Played: %dhr %dmin", gen3.tr.hours, gen3.tr.min);
- string(screen, r.min, display->black, ZP, display->defaultfont, path);
- r.min.y += display->defaultfont->height;
- gen3pkstr((uchar*)buf, gen3.pc.name[currentbox].n, sizeof gen3.pc.name[currentbox].n);
- snprint(path, sizeof path, "Box %d: %s", currentbox+1, buf);
- string(screen, r.min, display->black, ZP, display->defaultfont, path);
- r.min.y += display->defaultfont->height;
+ r.min.y += screenprint(r.min, "Name: %G ID: %d Secret ID: %d", gen3.tr.name, sizeof gen3.tr.name, gen3.tr.id, gen3.tr.secretid);
+ r.min.y += screenprint(r.min, "Game: %s Time Played: %dhr %dmin", gen3gnametab[gen3.type], gen3.tr.hours, gen3.tr.min);
+ r.min.y += screenprint(r.min, "Box %d: %G", currentbox+1, gen3.pc.name[currentbox].n, sizeof gen3.pc.name[currentbox].n);
if(currentpk == nil)
currentpk = gen3.pc.box;
for(i = 0; i < 30; i++){
- if(gen3.pc.box[currentbox*30 + i].otid == 0)
- continue;
- decryptpokemon(&pd, gen3.pc.box + currentbox*30 + i);
- //fprint(2, "%d %s\n", pd.g.species, dexfiletab[pd.g.species]);
- snprint(path, sizeof path, "/sys/games/lib/pokesprite/regular/%s.png", dexfiletab[getgen3dex(pd.g.species)]);
r2.min.x = r.min.x + (i%6) * spwd.x;
r2.min.y = r.min.y + (i/6) * spwd.y;
r2.max.x = r2.min.x + spwd.x;
r2.max.y = r2.min.y + spwd.y;
-
if(gen3.pc.box + currentbox*30 + i == currentpk)
draw(screen, r2, light, nil, ZP);
+ if(gen3.pc.box[currentbox*30 + i].otid == 0)
+ continue;
+ decryptpokemon(&pd, gen3.pc.box + currentbox*30 + i);
+ if(pd.g.species > 411 || getgen3dex(pd.g.species) == -1)
+ continue;
+ snprint(path, sizeof path, "/sys/games/lib/pokesprite/regular/%s.png", dexfiletab[getgen3dex(pd.g.species)]);
image = spritecache[pd.g.species-1];
if(image == nil){
@@ -108,29 +102,16 @@
r = screen->r;
r.min.x += 6*spwd.x;
- snprint(path, sizeof path, "Species: %d", pd.g.species);
- string(screen, r.min, display->black, ZP, display->defaultfont, path);
- r.min.y += display->defaultfont->height;
- snprint(path, sizeof path, "Exp: %d", pd.g.exp);
- string(screen, r.min, display->black, ZP, display->defaultfont, path);
- r.min.y += display->defaultfont->height;
- snprint(path, sizeof path, "Move 1: %s Move 2: %s", movenametab[pd.a.move1], movenametab[pd.a.move2]);
- string(screen, r.min, display->black, ZP, display->defaultfont, path);
- r.min.y += display->defaultfont->height;
-
- snprint(path, sizeof path, "Move 3: %s Move 4: %s", movenametab[pd.a.move3], movenametab[pd.a.move4]);
- string(screen, r.min, display->black, ZP, display->defaultfont, path);
- r.min.y += display->defaultfont->height;
-
- snprint(path, sizeof path, "[EV] HP: %d Atk: %d Def: %d SpA: %d SpD: %d Spe: %d", pd.e.hp, pd.e.atk, pd.e.def, pd.e.spatk, pd.e.spdef, pd.e.spd);
- string(screen, r.min, display->black, ZP, display->defaultfont, path);
- r.min.y += display->defaultfont->height;
-
+ r.min.y += screenprint(r.min, "Name: %G", currentpk->name, sizeof currentpk->name);
+ r.min.y += screenprint(r.min, "OT Name: %G OT ID: %ud OT Secret ID: %d", currentpk->otname, sizeof currentpk->otname, currentpk->otid, currentpk->otsecretid);
+ r.min.y += screenprint(r.min, "National Dex: %d", getgen3dex(pd.g.species));
+ r.min.y += screenprint(r.min, "Shiny: %d", gen3shiny(currentpk));
+ r.min.y += screenprint(r.min, "Exp: %d", pd.g.exp);
+ r.min.y += screenprint(r.min, "Move 1: %s Move 2: %s", movenametab[pd.a.move1], movenametab[pd.a.move2]);
+ r.min.y += screenprint(r.min, "Move 3: %s Move 4: %s", movenametab[pd.a.move3], movenametab[pd.a.move4]);
+ r.min.y += screenprint(r.min, "[EV] HP: %d Atk: %d Def: %d SpA: %d SpD: %d Spe: %d", pd.e.hp, pd.e.atk, pd.e.def, pd.e.spatk, pd.e.spdef, pd.e.spd);
getgen3iv(&iv, pd.m.iv);
- snprint(path, sizeof path, "[IV] HP: %d Atk: %d Def: %d SpA: %d SpD: %d Spe: %d", iv.hp, iv.atk, iv.def, iv.spatk, iv.spdef, iv.spe);
- string(screen, r.min, display->black, ZP, display->defaultfont, path);
- r.min.y += display->defaultfont->height;
-
+ r.min.y += screenprint(r.min, "[IV] HP: %d Atk: %d Def: %d SpA: %d SpD: %d Spe: %d", iv.hp, iv.atk, iv.def, iv.spatk, iv.spdef, iv.spe);
flushimage(display, 1);
}
@@ -205,6 +186,7 @@
if(fd < 0)
sysfatal("open: %r");
+ fmtinstall('G', gen3strfmt);
getgen3(fd, &gen3);
if(initdraw(nil, nil, "pse") < 0)