Skip to content

PicoC Basics

SpiredMoth edited this page Jan 21, 2021 · 12 revisions

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.

Getting Started

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)
{
    unsigned char version = *argv[0];

    // 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.

main Arguments

  • argc is useless in scripts -- leave it in the parameters list for main but otherwise ignore it
  • argv
    • *argv[0] save's game version (game's index number as found in a Pokémon's source/origin game field)
Game Version *argv[0]
Sapphire 1 1
Ruby 2 1*
Emerald 3 3
Fire Red 4 4
Leaf Green 5 4*
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
Sword 44 44
Shield 45 45

* - By content alone, Gen 3 and Gen 4 saves from the same pair cannot be told apart from each other. This means that Pearl saves will have an *argv[0] equal to 10 (same as Diamond) and SoulSilver will have an argv[2] equal to 7 (same as HeartGold). The same applies for Fire Red and Leaf Green, and Ruby and Sapphire.

General Enums and Structs

PKSM provides a few enums and structs 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

Generation

enum Generation {
    GEN_FOUR,
    GEN_FIVE,
    GEN_SIX,
    GEN_SEVEN,
    GEN_LGPE,
    GEN_EIGHT,
    GEN_THREE
};

// 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.

Pouch

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.

Tips and Tricks

  • Avoid allocating arrays based a size stored in a variable (for instance char buffer[size];). Use something along the lines of char* buffer = malloc(size); instead and free the pointer after use.

Accessing Save Values

// 1 byte value
char val = sav_get_byte(offset, 0);
sav_set_byte(val, offset, 0);

// 2 byte values
short val = sav_get_short(offset, 0);
sav_set_short(val, offset, 0);

// 4 byte values
int val = sav_get_int(offset, 0);
sav_set_int(val, offset, 0);

The utility functions above returned signed integers, but these are automatically converted to unsigned integers on assignment if you add the unsigned keyword to their type declarations. See Save Access Functions for how to specify offsets in different games.

C References

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.