shithub: pse

Download patch

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)