Developer Notes

From OHRRPGCE-Wiki
Revision as of 03:35, 20 December 2010 by The Mad Cacti (talk | contribs) (Important stuff I'm meant to remember but don't)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Notes for OHRRPGCE developers. This page is actually directed at the core developers as much as anyone else, as there are some pretty easy to forget gotchas when working on the engine.

FreeBASIC stuff

WITH

WITH is not just shorthand, it stores a pointer and uses that to access .members. Inside a 'WITH foo' block, be careful not to make the reference to 'foo' invalid, eg.:

WITH myarray(i)
 REDIM myarray(i + 10)
 'If you do this, PLACE A BIG WARNING ON THE NEXT LINE
 'Accessing myarray(i) members with .dot syntax will now likely segfault
END WITH

Bugs

There are several bugs in FB that affect us. A very incomplete list:

  • Implicitly declared strings (undeclared variables with $ suffix) are not freed! This leads to lots of memory leaks, which you're just going to have to ignore if using valgrind.
  • fbc just loves thowing branch crossing variable definition warnings randomly, especially the linux builds. Real branch crossing warning are bugs that need to be fixed, but unfortunately most of these warnings are completely imaginary (and their random nature suggests they are due to initialised memory in the compiler (as might be caused by a branch crossing a variable definition, actually)).
  • There's quite a few things (such as placement NEW) documented as being accessible from -lang fb only which we actually use from -lang deprecated.

Common

GOSUB

We don't use FreeBASIC's GOSUB, instead we use our own implementation. Use RETRACE instead of RETURN, this way we can use the normal meaning of RETURN. GOSUB must be the last statement on the line.

This uses scary macros containing assembly which push the current instruction pointer to the stack (see compat.bi; related details at FB stack internals). While I know of no way for these pointers to end up corrupted or interfere with other code, returning from a GOSUB block can causes problems. Jumping out of scopes is allowed, but you should not be allow to jump into a scope. It's disallowed in C, for example, and FB will throw a branch crossing warning normally, however it doesn't know that a GOSUB will later cause a RETRACE, so you'll get no warning or error.

GOSUB is not allowed inside a WITH, SCOPE (after variable definitions), FOR with a local counter or non-constant end or step, (and possibly other constructs I can't think of right now?).

WITH *blarg
 GOSUB foo
 .bar = 3   'BAD: WITH pointer may be corrupted
END WITH

FOR i as integer = 0 TO 4
 GOSUB foo  'BAD: i may be corrupted
NEXT

FOR i = 1 TO UBOUND(cmdline_args)
 GOSUB foo  'BAD: loop number may be corrupted
NEXT

FOR i = 0 TO 2
 GOSUB foo  'Allowable, but avoidance suggested
NEXT

On the other hand, FOR, WITH, SCOPE and DIM are allowed inside a GOSUB block.

Luckily illegal GOSUBs can be detected using the misc/gosub.el script (which TMC runs every year or two) which . There is also misc/with.el to place warnings after GOSUBs within WITH blocks. I can't remember whether this was necessary because misc/gosub.el won't detect these cases or not.

File functions

Use our alternatives to various FB file related functions. These add error checking and logging and work around FB bugs

  • findfiles or isfile or isdir instead of DIR (Note: isfile could be improved by using OS-specific functions, eg. stat() on Unix)
  • killdir instead of RMDIR
  • makedir instead of MKDIR
  • safekill instead of KILL (better to use safekill even if you're sure the file exists)

Platform

__FB_UNIX__ only exists in FB 0.21 or later (which is our requirement now anyway), however it's always defined (taking value 0 or -1), unlike __FB_LINUX__ and so on. I recommend always using our own __UNIX__ define instead, as it's much less confusing. Don't use __FB_LINUX__ except for truely Linux-specific stuff. Example (in compat.bi):

#ifdef __UNIX__
# define SLASH "/"
# define LINE_END !"\n"
#else
# define SLASH "\"
# define LINE_END !"\r\n"
#endif

Arrays

FB arrays are very limited. See FB Arrays Library for documentation of our custom arrays library.

Custom

ESC

PageUp+PageDown+Esc/Alt+F4/Cmd+Q/etc. work by setting keyval(-1), which causes setkeys to send a stream of ESC keypresses until clearkey(-1) is called. All menus in Custom should exit on a Esc keypress, except for those with unsaved state (eg. a modified help file and the Save/Save+Quit/Discard+Quit game menu). You need to call clearkey(-1) before querying the user whether to save if an Esc keypress will cancel the attempted exit.

See Also