[EA] [WIP] A Guide To Inserting Everything Through EA

#Prologue - The Basics: Events

Now, I’m going to at least assume you’re used to using EA to make events, as well as general EA syntax. If not, you really should check out Arch’s eventing tutorial.

So I’m not going to tell you how to event chapters, but let’s talk about some necessary changes to the way you write chapters to be compatible with making a single file for everything.


#ifdef, #ifndef, #else, and #endif

If you’ve programmed in C, you should be familiar with these guys. If not, I’ll explain.

So, as you should know, you can #define things in EA. Here’s a quick example:

#define Eirika 0x1 //Define a constant
#define EndOfTable "BYTE 0xFF 0xFF 0xFF 0xFF" //Define a constant section of code; techncially same as above
#define EAFlag //Sets the state of "EAFlag" to defined
#define repointMyTable(newLoc) "ORG MyTableLoc; POIN newLoc" //Define a macro -- note that its definition uses MyTableLoc, which is assumed to be defined before.

Note that if you have defined something, you can remove it with #undef.

So what #ifdef does is that EA will assemble the events between the #ifdef and the #else or #endif ONLY IF the name you’re checking has been defined. To undefine a macro, you need to also provide its parameters. #ifndef is “if not defined” and acts the opposite way.

To bring this around, I will give three very practical examples of why this is useful:

Example 1
Recall that EA automatically defines _FE#_, where # is 6, 7, or 8 depending on which option you selected on the GUI. I don’t know about you, but I can forget to click the right button sometimes. So a good way to protect my ROM is like so:

#ifdef _FE8_
  //Things you want to assemble
#else
  ERROR "You're not assembling FE8 events!"
#endif

Example 2
This is a use very familiar to C programmers. Let’s say we have a definitions file for our hack, that we want to include in every other file, and it goes like so:

#define MyCruddySelfInsert 0x01
#define MyCruddyLoveInterest 0x02
#define MyCruddyAntagonist 0x03
#define ActuallyJustAnIronSwordReskin IronSword
//...

Well, if I tried to include this file in multiple files, each of which were included by one central file, well, I’d be defining everything multiple times. So one way to avoid this is to do

#ifndef MY_HACK_DEFINITIONS
#define MY_HACK_DEFINITIONS

#define MyCruddySelfInsert 0x01
#define MyCruddyLoveInterest 0x02
#define MyCruddyAntagonist 0x03
#define ActuallyJustAnIronSwordReskin IronSword
//...

#endif

That way, for all EA cares, I can do

#include "Hack Definitions.txt"
#include "Hack Definitions.txt"
#include "Hack Definitions.txt"
#include "Hack Definitions.txt"
#include "Hack Definitions.txt"

But it doesn’t matter; the variables will be defined only and exactly once.

Example 3
I mentioned previously that EA is great for memory management. Well, that’s kind of useless if you’re ORG-ing your chapter events to various locations. But it’s a bit dangerous to just completely remove that; or at least, I like the philosophy that each event file should be able to assemble on its own. But one way to get both benefits with no cost is like so:

#ifndef InlineEvents
  #define ChName_DefaultChapterOffset 0x01000000
  EventPointerTable(0x01, ChName_ThisChapter) //Note that this changes where EA is ORG'd, so if you do an in-place install, you need to have this command somewhere else.
  ORG ChName_DefaultChapterOffset
#endif
//Event Pointer Arrays go here

Then in your ROM Makefile, discussed in the next chapter, you can just #define InlineEvents.


Suggested Edits to the Eventing Template

There is one really relevant weakness to EA – you won’t be able to have the same name for two things; whether it’s #defined, or used as a label, or otherwise.

As a side note, it is possible to limit the scope of labels by surrounding the events (or in this case, an #include directive) with braces {}, but then we won’t be able to point to inside the braces from outside, which is something we might want to do with various hacks or map changes (if we have them with events).

So if you have in your prologue events

POIN TurnBasedEvents
POIN CharacterBasedEvents
POIN LocationBasedEvents
POIN MiscBasedEvents

etc. And in your Chapter 1 events you have the exact same

POIN TurnBasedEvents
POIN CharacterBasedEvents
POIN LocationBasedEvents
POIN MiscBasedEvents

Then you can see how you can run into problems when we try making one master file with all of these events.

So instead, I came up with this skeleton:
[spoiler=FE7]
TODO: Make this skeleton[/spoiler]
[spoiler=FE8]
//Made by CrazyColorz5 of Fire Emblem Universe
//Based off of Camtech75’s Skeleton
#include EAstdlib.event

#ifndef InlineEvents
  //Assume the Map is contained and documented elsewhere.
  #define ChName_DefaultChapterOffset 0x01000000
  #define ChName_ID 0x01 //TODO: Change this depending on what chapter you're making.
  
  EventPointerTable(ChName_ID, ChName_ThisChapter)
  ORG ChName_DefaultChapterOffset
#endif

ChName_ThisChapter:

POIN ChName_TurnBasedEvents
POIN ChName_CharacterBasedEvents
POIN ChName_LocationBasedEvents
POIN ChName_MiscBasedEvents
POIN ChName_Dunno ChName_Dunno ChName_Dunno
POIN ChName_Tutorial
POIN ChName_Ballista1 ChName_Ballista2
POIN ChName_Units1 ChName_Units1
POIN $0 $0 $0 $0 $0 $0
POIN ChName_BeginningScene ChName_EndingScene

ChName_TurnBasedEvents:
TURN

ChName_CharacterBasedEvents:
CHAR

ChName_LocationBasedEvents:
LOCA

ChName_MiscBasedEvents:
CauseGameOverIfLordDies
//Add Win Condition
AFEV

ChName_Dunno:
END_MAIN

ChName_Tutorial:
END_MAIN

ChName_Ballista1:
BLST

ChName_Ballista2:
BLST
ALIGN 4

ChName_Units1:
//Add Player Units
UNIT


ChName_BeginningScene:
FADU 0x8

ENDB


ChName_EndingScene:

MNCH 0x01 //TODO: Replace with proper code for next chapter.
ENDA


#ifndef InlineEvents
  MESSAGE Events end at offset currentOffset
#endif

[/spoiler]

When you make your chapter, find and replace ChName with a unique identifier for your chapter, such as Prologue, or ChOne, or something. Also follow this naming convention for labels, for events within the chapter. This way, you’ll never run into a naming conflict.