-
-
Notifications
You must be signed in to change notification settings - Fork 14
PicoC Basics
This page details the basics of beginning with picoC PKSM scripts.
This is not a guide to programming in C. If you need a primer (or refresher) on C, see C References below.
Here is the simplest skeleton of a picoC PKSM script
#include <pksm.h> // PKSM provided virtual header giving access to scripting API
#include <stdlib.h>
int main(int argc, char **argv)
{
// PKSM 7.0.1 and before
unsigned char *saveData = (unsigned char *)atoi(argv[0]);
// After PKSM 7.0.1
unsigned char *saveData = (unsigned char *)argv[0];
int saveLength = atoi(argv[1]);
unsigned char version = *argv[2];
// do work here...
return 0;
}
Feel free to remove any of the variable declarations you don't need, or use different names for the variables.
-
argc
is useless in scripts -- leave it in the parameters list formain
but otherwise ignore it -
argv
-
argv[0]
pointer to save data, as an integer, passed as text (PKSM 7.0.1 and before) -
argv[0]
pointer to save data (After PKSM 7.0.1) -
argv[1]
save data length (int passed as text) -
argv[2]
save's game version (game's index number as found in a Pokémon's source/origin game field)
-
Game | Version | argv[2] |
---|---|---|
Diamond | 10 | 10 |
Pearl | 11 | 10* |
Platinum | 12 | 12 |
HeartGold | 7 | 7 |
SoulSilver | 8 | 7* |
White | 20 | 20 |
Black | 21 | 21 |
White 2 | 22 | 22 |
Black 2 | 23 | 23 |
X | 24 | 24 |
Y | 25 | 25 |
Alpha Sapphire | 26 | 26 |
Omega Ruby | 27 | 27 |
Sun | 30 | 30 |
Moon | 31 | 31 |
Ultra Sun | 32 | 32 |
Ultra Moon | 33 | 33 |
Let's Go, Pikachu! | 42 | 42 |
Let's Go, Eevee! | 43 | 43 |
* - By content alone, Gen 4 saves from the same pair cannot be told apart from each other. This means that Pearl saves will have an argv[2]
equal to 10
(same as Diamond) and SoulSilver will have an argv[2]
equal to 7
(same as HeartGold).
PKSM provides a few enum
s and struct
s to scripts, most of which have a narrow scope of use and are detailed alongside the function(s) they pair with. Below are the multi-use ones
enum Generation {
GEN_FOUR,
GEN_FIVE,
GEN_SIX,
GEN_SEVEN,
GEN_LGPE
};
// example usage
int pokePick = gui_menu_6x5("Choose Honey Tree Pokémon", optNum, &treePokes[0], &pokes[0], GEN_FOUR);
When something depends on the generation being worked with (sprites, data structure, etc.), use one of these. The example usage code comes from the DPPT Honey Tree script, though there are other examples available in the repo.
enum Pouch {
NormalItem,
KeyItem,
TM,
Mail,
Medicine,
Berry,
Ball,
Battle,
Candy,
ZCrystals
};
Using API functions that work with the player's bag requires using one of these to specify which pouch to work with.
- Avoid allocating arrays based a size stored in a variable (for instance
char buffer[size];
). Use something along the lines ofchar* buffer = malloc(size);
instead and free the pointer after use.
This is more of a basic C concept, but I think it's important enough to demonstrate explicitly.
// 1 byte value
char val = saveData[offset];
saveData[offset] = val;
// 2 byte values
short val = *(short *)(saveData + offset);
*(short *)(saveData + offset) = val;
// 4 byte values
int val = *(int *)(saveData + offset);
*(int *)(saveData + offset) = val;
All data types in these examples are signed, but unsigned works just as well (and might be needed instead depending on the data you're working with)
Here is a list of references for C programming in general. Not all material will be applicable to PKSM scripts since picoC is a subset of C90.
Enjoy using PKSM? Consider supporting FlagBrew on Patreon