Skip to content

NESFab 1.8

Latest

Choose a tag to compare

@pubby pubby released this 19 Sep 05:01

This version contains several important bug fixes and a few new features. Please review the list of breaking changes. This release was a little rushed, so issues may arise.

9/22: hotfixes were done. Please download the hotfixed files.

NROM128 support

NESFab can now create 16KB NROM files.

I added this in case anyone wants to participate in the Game Genie Mini Jam.

Anonymous labels

asm fn and fn now accept anonymous labels.

Syntax:

label+amount
label-amount

Where +amount is a number referring to upcoming anonymous labels, and -amount is a number referring to previous anonymous labels.

Example:

label
    jmp label-1 // Jump to the previous label
    jmp label+1 // Jump to the next label 
    jmp label+2 // Jumps 2 labels ahead 
label
    nop
label

Arg-less [] and {}

The [] and {} operator can now be used without an index. In such cases, the index is treated as 0.

Example:

my_array[] = 10 // Equivalent to my_array[0] = 10

Index types: I and II.

There are two new types, I and II. These represent indexes into globally-defined arrays.

Syntax:

I.array
II.array

Where array is the name of a globally-defined array.

Values of I and II store indexes, just like U or UU. However, they also behave like pointers in that you can dereference them using [] or {}.

Example:

vars
    UU[10] some_array // Define a global array

fn example()
    I.some_array my_index = 5 // Create an index value pointing to the [5] position.
    my_index[] = 10           // Equivalent to some_array[5] = 10

Index types reduce the typing involved when working with arrays, but also come with some extra safety.

Feel free to ask in the Discord if you're confused by these.

Stronger type safety on [] and {} (breaking change)

The [] and {} operators now require their index to match type U and UU respectively. Before, implicit conversions were allowed, meaning {} could also accept U and Bool.

Weaker type safety on hardware writes

Hardware writes using the {}() syntax now cast the argument to U in more situations. This allows one to write S values, for example, without an explicit cast.

push / pop optional index argument

For Vec types, you can now push and pop into specific indexes, instead of only the last element.

Syntax:

push(vec, value, index)
pop(vec, index)

+inherit modifier

Adding the +inherit modifier to a struct field allows the owning struct to copy some of its behavior. Specifically, the parent struct will implicitly cast to the inherited field, and the inherited field's own fields will be accessible.

Example:

Struct Bar
    U member
struct Foo
    Bar bar : +inherit

fn example()
    Foo foo = Foo()
    Bar bar = foo // Implicit cast
    foo.member = 10 // Access Bar members

palette.fab rename: fade_out -> fade_out_custom (breaking change)

The fade_out / fade_in functions were intended to make it easy to define your own fade functions. The problem was, they took up the best names for these functions! Thus, they have been renamed.

lib/metasprite/metasprite.fab

I've added some extra functions to this library file, including ones that use U positions instead of SS.

lib/step_counter.fab

This tiny library file implements a common pattern: counting the number of times NMI was waited on. This is similar to checking nmi_counter, but does not increment on lag frames.

lib/uvec.fab

This library file contains ct functions for manipulating U{} values.