Nametable Package¶
Submodules¶
Animator Module¶
- class AnimatedProtocol(*args, **kwargs)¶
Bases:
Protocol
A class that ensures that the animator dictates which frame is being shown for an animated object.
See also
- Attributes
- animator: The instance of the animator controlling the frame shown.
- animator: nametable.Animator.AnimatorProtocol¶
- class Animator(frame: int)¶
Bases:
object
A generic implementation of
AnimatorProtocol
that utilizes a simpledataclass()
.See also
- Attributes
- frame: int
The current frame that the
AnimatedProtocol
is on.
- class AnimatorProtocol(*args, **kwargs)¶
Bases:
Protocol
A class that handles the changing one an integer, representing the frame that the
AnimatedProtocol
is on.See also
- Attributes
- frame: The current frame that the :class:`~nametable.Animator.AnimatedProtocol` is on.
Block Module¶
- class Block(pattern_table: nametable.PatternTable.PatternTableProtocol, patterns: tuple[int, int, int, int])¶
Bases:
object
A generic implementation of
BlockProtocol
that utilizes a simpledataclass()
.- Raises
- BlockInvalidSizeException
Raised if the length of
patterns
is not equal to four.- PatternTableIndexException
Raise if any index inside
patterns
would result in anIndexError
.
Examples
To create an instance of a Block.
>>> Block( ... PatternTable( ... ( ... Pattern(PatternMeta ... ( ... bytes.fromhex("41 C2 44 48 10 20 40 80 01 02 04 08 16 21 42 87")) ... ), ... ) ... ), ... (0, 0, 0, 0,) ... ) Block(PatternTable((Pattern(PatternMeta(...)),)), (0, 0, 0, 0,))
- Attributes
- pattern_table: PatternTableProtocol
The instance of
PatternTableProtocol
to serve as the lookup table of instances ofPatternProtocol
.- patterns: tuple[int, int, int, int]
The indexes into
pattern_table
to create instances ofPatternProtocol
from.
- property numpy_array: numpy.ndarray[Any, numpy.dtype[numpy.uint8]]¶
Generates a two dimensional array with two bits per pixel, representing the respective instances of
PatternProtocol
numpy_array
concatenate together to form a 16 by 16 pixel grid. The order of they are shown is top left, top right, bottom left, bottom right, respectively.- Returns
- NDArray[ubyte]
This instance represented as an array.
See also
Examples
To create an instance of a Block.
>>> block = Block( ... PatternTable( ... ( ... Pattern(PatternMeta ... ( ... bytes.fromhex("41 C2 44 48 10 20 40 80 01 02 04 08 16 21 42 87")) ... ), ... ) ... ), ... (0, 0, 0, 0,) ... ) >>> block.numpy_array array( [ [0, 1, 0, 0, 0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 3], [1, 1, 0, 0, 0, 0, 3, 0, 1, 1, 0, 0, 0, 0, 3, 0], [0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0], [0, 1, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0], [0, 0, 0, 3, 0, 2, 2, 0, 0, 0, 0, 3, 0, 2, 2, 0], [0, 0, 3, 0, 0, 0, 0, 2, 0, 0, 3, 0, 0, 0, 0, 2], [0, 3, 0, 0, 0, 0, 2, 0, 0, 3, 0, 0, 0, 0, 2, 0], [3, 0, 0, 0, 0, 2, 2, 2, 3, 0, 0, 0, 0, 2, 2, 2], [0, 1, 0, 0, 0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 3], [1, 1, 0, 0, 0, 0, 3, 0, 1, 1, 0, 0, 0, 0, 3, 0], [0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0], [0, 1, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0], [0, 0, 0, 3, 0, 2, 2, 0, 0, 0, 0, 3, 0, 2, 2, 0], [0, 0, 3, 0, 0, 0, 0, 2, 0, 0, 3, 0, 0, 0, 0, 2], [0, 3, 0, 0, 0, 0, 2, 0, 0, 3, 0, 0, 0, 0, 2, 0], [3, 0, 0, 0, 0, 2, 2, 2, 3, 0, 0, 0, 0, 2, 2, 2], ], dtype=ubyte, )
- pattern_table: nametable.PatternTable.PatternTableProtocol¶
- exception BlockInvalidSizeException¶
Bases:
ValueError
Raised when the length of
patterns
is an invalid size for aBlockProtocol
.
- class BlockProtocol(*args, **kwargs)¶
Bases:
Protocol
A representation of a combination of four instances of
PatternProtocol
. Despite sounding unintuitive, this format was widely adopted throughout NES development due to limitations of the Picture Processing Unit: ‘PPU’ and memory space on the NES: The PPU attribute tables could only change the color attribute every 16 pixel in both dimensions, known as a ‘Block’. Similarly, to store each Pattern of each Block as a list in memory would take up the kilobytes of memory. By storing common sections of 2x2 Patterns, most programmers during this era found that memory required was dramatically reduced.See also
- Attributes
- pattern_table: PatternTableProtocol
The instance of
PatternTableProtocol
to serve as the lookup table of instances ofPatternProtocol
.- patterns: tuple[int, int, int, int]
The indexes into
pattern_table
to create instances ofPatternProtocol
from.
- property numpy_array: numpy.ndarray[Any, numpy.dtype[numpy.uint8]]¶
Generates a two dimensional array with two bits per pixel, representing the respective instances of
PatternProtocol
numpy_array
concatenate together to form a 16 by 16 pixel grid. The order of they are shown is top left, top right, bottom left, bottom right, respectively.- Returns
- NDArray[ubyte]
This instance represented as an array.
See also
- pattern_table: nametable.PatternTable.PatternTableProtocol¶
- exception PatternTableIndexException¶
Bases:
IndexError
Raised when the
int
insidepatterns
is an invalid index intopattern_array
ofpattern_table
.
Nametable Module¶
- class NametableProtocol(*args, **kwargs)¶
Bases:
Protocol
- blocks: tuple[nametable.Block.BlockProtocol, ...]¶
Pattern Module¶
- class Pattern(meta: nametable.PatternMeta.PatternMeta)¶
Bases:
object
A generic implementation of
PatternProtocol
.See also
- classmethod from_numpy_array(array: numpy.ndarray[Any, numpy.dtype[numpy.uint8]])¶
Wraps
from_numpy_array()
to create an instance directly.- Parameters
- arrayNDArray[ubyte]
The numpy array to be converted.
See also
- property meta: nametable.PatternMeta.PatternMeta¶
Provides the wrapped meta class that the instance is representing.
- Returns
- PatternMeta
The current
PatternMeta
that this instance is representing.
- property numpy_array: numpy.ndarray[Any, numpy.dtype[numpy.uint8]]¶
Provides a Numpy array that represents the pattern as a 2D matrix of the pixels of the pattern.
- Returns
- NDArray[ubyte]
The array is equivalent to the meta that the instance is representing.
Notes
The instance ensures that array provided is identical to the wrapped meta it represents.
This method is more efficient than the meta instance, with the results being cached, dramatically reducing math operations for large-scale operations.
The array provided should never be modified. If it is modified, this will interfere with the caching of the Pattern and may cause undesired artifacts.
Examples
When creating the instance, the class will check if the an equivalent instance of meta was already utilized to create this class. If one exists, it will return the instance of the already instantiated Pattern, otherwise it will create a new instance and cache it into a weak reference dictionary for future instantiations.
>>> meta = PatternMeta(bytes.fromhex("41 C2 44 48 10 20 40 80 01 02 04 08 16 21 42 87")) >>> pattern1 = Pattern(meta) >>> pattern2 = Pattern(meta) >>> pattern1 is pattern2 True
Likewise, when creating an array, the Pattern will cache the result after its first creation. The following code will only result in one execution of a numpy array.
>>> pattern1.numpy_array ... >>> pattern2.numpy_array ...
- class PatternProtocol(*args, **kwargs)¶
Bases:
Protocol
An Object Oriented wrapper around
PatternMeta
. This class enables easier extensions and edits onPatternMeta
without needing to understand the internals of the NES.- property meta: nametable.PatternMeta.PatternMeta¶
Provides the wrapped meta class that the instance is representing.
- Returns
- PatternMeta
The current
PatternMeta
that this instance is representing.
- property numpy_array: numpy.ndarray[Any, numpy.dtype[numpy.uint8]]¶
Provides a Numpy array that represents the pattern as a 2D matrix of the pixels of the pattern.
- Returns
- NDArray[ubyte]
The array is equivalent to the meta that the instance is representing.
See also
Notes
The purpose of extending the responsibility of creating an array to this instance is to provide additional ability to cache and utilize other techniques to improve performance.
PatternAnimated Module¶
- class PatternAnimated(stack: tuple[nametable.Pattern.PatternProtocol], animator: nametable.Animator.AnimatorProtocol)¶
Bases:
object
A generic implementation of
PatternAnimatedProtocol
that utilizes an instance ofAnimatorProtocol
to dictate thePatternMeta
meta for the instance from atuple
ofPatternProtocol
.Notes
The user must ensure that the
animator
must never have a frame greater than the length ofstack
.- Attributes
- stack: tuple[PatternProtocol]
A tuple of patterns that the instance’s animator selects from for a given frame.
- animator: AnimatorProtocol
The instance of the animator controlling the frame shown.
- animator: nametable.Animator.AnimatorProtocol¶
- property meta: nametable.PatternMeta.PatternMeta¶
Provides the meta the wrapped meta class that the pattern of the current
nametable.Pattern.PatternProtocol
insidestack
is representing.- Returns
- PatternMeta
The current
PatternMeta
that this instance is representing, dictated byanimator
.
See also
Examples
The animator can dynamically change the meta provided
>>> data = bytes.fromhex("41 C2 44 48 10 20 40 80 01 02 04 08 16 21 42 87") >>> pattern = PatternAnimated( ... (Pattern(PatternMeta(data)), Pattern(PatternMeta(data[::-1]))), ... Animator(0) ... ) >>> pattern.meta PatternMeta(data) >>> pattern.animator.frame = 1 >>> pattern.meta PatternMeta(data[::-1])
- property numpy_array: numpy.ndarray[Any, numpy.dtype[numpy.uint8]]¶
Provides an array that represents the pattern as a 2D matrix of the pixels of the pattern of the current
nametable.Pattern.PatternProtocol
insidestack
.- Returns
- NDArray[ubyte]
The array of the current
nametable.Pattern.PatternProtocol
dictated byanimator
.
See also
Examples
The animator can dynamically change the array provided
>>> data = bytes.fromhex("41 C2 44 48 10 20 40 80 01 02 04 08 16 21 42 87") >>> pattern = PatternAnimated( ... (Pattern(PatternMeta(data)), Pattern(PatternMeta(data[::-1]))), ... Animator(0) ... ) >>> pattern.numpy_array array( [ [0, 1, 0, 0, 0, 0, 0, 3], [1, 1, 0, 0, 0, 0, 3, 0], [0, 1, 0, 0, 0, 3, 0, 0], [0, 1, 0, 0, 3, 0, 0, 0], [0, 0, 0, 3, 0, 2, 2, 0], [0, 0, 3, 0, 0, 0, 0, 2], [0, 3, 0, 0, 0, 0, 2, 0], [3, 0, 0, 0, 0, 2, 2, 2], ], dtype=ubyte, ) >>> pattern.animator.frame = 1 >>> pattern.numpy_array array( [ [0, 0, 0, 3, 0, 1, 0, 0], [0, 0, 3, 0, 1, 1, 0, 0], [0, 3, 0, 0, 0, 1, 0, 0], [3, 0, 0, 0, 0, 1, 0, 0], [0, 2, 2, 0, 0, 0, 0, 3], [0, 0, 0, 2, 0, 0, 1, 2], [0, 0, 2, 0, 0, 1, 2, 0], [0, 2, 2, 2, 2, 1, 1, 0], ], dtype=ubyte, )
- class PatternAnimatedProtocol(*args, **kwargs)¶
Bases:
nametable.Pattern.PatternProtocol
,nametable.Animator.AnimatedProtocol
,Protocol
A
PatternProtocol
that determines thePatternMeta
that is represented by the frame insideAnimatorProtocol
.See also
- Attributes
- animator: AnimatorProtocol
The instance of the animator controlling the frame shown.
- animator: nametable.Animator.AnimatorProtocol¶
PatternMeta Module¶
- class PatternMeta(data: bytes)¶
Bases:
object
A wrapper around a fixed series of 16 bytes that represents an eight by eight square for a two bit image, typically associated with the Nintendo Entertainment System.
This format is derived from the Picture Processing Unit: ‘PPU’. The PPU functioned as a primitive graphics card for the NES, allowing a hard-wired implementation for graphics to be streamlined from the CPU onto the consumer’s television. This development enabled a great advance in the sophistication of graphics and hardware. Prior consoles, such as the Atari 2600 had to race the beam to render graphics onto the screen. With the fixed format of the PPU, much of the overhead that previously burdened the developer was reduced into a space in RAM devoted to a few flags and memory used for sprites and background graphics. The core element of this was the Tile, which is synonymous with Pattern. This class utilizes this format and fluffs the one dimensional byte array into a two dimensional array of bytes, which can easily be transposed into other picture formats for editing and viewing. Likewise, it can flatten these two dimensional arrays back down into the format utilized by the PPU.
See also
Notes
For large creation of patterns, it is recommended that
Pattern
should be used instead. Pattern will store multiple copies of the same pattern as one type, and enable more sophisticated use throughout the program. Specifically, it is easier to extend, due to not being immutable.Examples
To create a pattern, provide a series of 16 bytes.
>>> pattern = PatternMeta(bytes.fromhex("41 C2 44 48 10 20 40 80 01 02 04 08 16 21 42 87")) >>> pattern PatternMeta(b'...')
- HEIGHT = 8¶
- WIDTH = 8¶
- classmethod from_numpy_array(array: numpy.ndarray[Any, numpy.dtype[numpy.uint8]])¶
Flattens a two dimensional array into a fixed series of 16 bytes that represent a two bits per pixel pattern that was commonly used for the NES. Each byte inside the two dimensional array is expected to contain only two bits. If other bits are set, they will be strictly ignored, as the NES format does not enable such modifications.
- Parameters
- arrayNDArray[ubyte]
The numpy array to be converted.
Examples
Any two dimension array of type ubyte, with the representation of two bits and a size of (8, 8) can be transferred back to a pattern.
>>> pattern1 = PatternMeta(bytes.fromhex("41 C2 44 48 10 20 40 80 01 02 04 08 16 21 42 87")) >>> pattern2 = PatterMeta.from_numpy_array(pattern1.numpy_array) >>> pattern1 == pattern2 True
If more than two bits are represented inside an array, those bits will be truncated.
>>> modified_array = pattern1.numpy_array >>> modified_array[0][0] = 0b1111 >>> pattern3 = PatternMeta.from_numpy_array(modified_array) >>> pattern1 == pattern3 False
>>> modified_array[0][0] = 0b1100 >>> pattern4 = PatternMeta.from_numpy_array(modified_array) >>> pattern1 == pattern4 True
- property numpy_array: numpy.ndarray[Any, numpy.dtype[numpy.uint8]]¶
Fluffs the byte array into a two dimensional array with two bits per pixel, as specified in the pattern format.
- Returns
- NDArray[ubyte]
The PatternMeta represented as an array.
Notes
The format of a pattern is represented by two fixed series of eight bytes. The series represent the first and second bit of the palette index of the pattern, respectively. If the neither bit is set, the pixel is transparent.
In the diagram below, ‘.’ represents a transparent pixel. Numbers 1, 2, 3 represent the palette index for a given pattern.:
Bit Planes Pixel Pattern [0x0] = 0x41 = 0b01000001 [0x1] = 0xC2 = 0b11000010 [0x2] = 0x44 = 0b01000100 [0x3] = 0x48 = 0b01001000 [0x4] = 0x10 = 0b00010000 [0x5] = 0x20 = 0b00100000 .1.....3 [0x6] = 0x40 = 0b01000000 11....3. [0x7] = 0x80 = 0b10000000 ===== .1...3.. .1..3... [0x8] = 0x01 = 0b00000001 ===== ...3.22. [0x9] = 0x02 = 0b00000010 ..3....2 [0xA] = 0x04 = 0b00000100 .3....2. [0xB] = 0x08 = 0b00001000 3....222 [0xC] = 0x16 = 0b00010110 [0xD] = 0x21 = 0b00100001 [0xE] = 0x42 = 0b01000010 [0xF] = 0x87 = 0b10000111
Examples
Any pattern can be transferred to a 2 dimensional array.
>>> pattern = PatternMeta(bytes.fromhex("41 C2 44 48 10 20 40 80 01 02 04 08 16 21 42 87")) >>> pattern_array = pattern.numpy_array >>> pattern_array array( [ [0, 1, 0, 0, 0, 0, 0, 3], [1, 1, 0, 0, 0, 0, 3, 0], [0, 1, 0, 0, 0, 3, 0, 0], [0, 1, 0, 0, 3, 0, 0, 0], [0, 0, 0, 3, 0, 2, 2, 0], [0, 0, 3, 0, 0, 0, 0, 2], [0, 3, 0, 0, 0, 0, 2, 0], [3, 0, 0, 0, 0, 2, 2, 2], ], dtype=ubyte, )
PatternTable Module¶
- class PatternTable(pattern_array: tuple[nametable.Pattern.Pattern, ...])¶
Bases:
object
A generic implementation of
PatternTableProtocol
that utilizes a simpledataclass()
.See also
- Attributes
- pattern_array: tuple[Pattern, …]
A group of Patterns used for quickly indexing
BlockProtocol
.
- pattern_array: tuple[nametable.Pattern.Pattern, ...]¶
- class PatternTableProtocol(*args, **kwargs)¶
Bases:
Protocol
A wrapper around a
tuple
ofPattern
that represent the field of possible Patterns available on a given item. This enabled a byte to index the range of patterns on the PPU to formBlockProtocol
on the Picture Processing Unit:.See also
- Attributes
- pattern_array: tuple[Pattern, …]
A group of Patterns used for quickly indexing
BlockProtocol
.
- pattern_array: tuple[nametable.Pattern.Pattern, ...]¶
PatternTableAnimated Module¶
- class PatternTableAnimated(pattern_tables: tuple[nametable.PatternTable.PatternTableProtocol], animator: nametable.Animator.AnimatorProtocol)¶
Bases:
object
A generic implementation of
PatternTableAnimatedProtocol
that determines thepattern_tables
from theframe
specified insideAnimatorProtocol
.See also
- Attributes
- pattern_array: tuple[Pattern, …]
A group of Patterns used for quickly indexing
BlockProtocol
.- animator: AnimatorProtocol
The instance of the animator controlling the frame shown.
- animator: nametable.Animator.AnimatorProtocol¶
- property pattern_array: tuple[nametable.Pattern.Pattern, ...]¶
- pattern_tables: tuple[nametable.PatternTable.PatternTableProtocol]¶
- class PatternTableAnimatedProtocol(*args, **kwargs)¶
Bases:
nametable.PatternTable.PatternTableProtocol
,nametable.Animator.AnimatedProtocol
,Protocol
A
PatternTableProtocol
that determines thepattern_array
fromAnimatorProtocol
denoted byAnimatedProtocol
.See also
- Attributes
- pattern_array: tuple[Pattern, …]
A group of Patterns used for quickly indexing
BlockProtocol
.- animator: AnimatorProtocol
The instance of the animator controlling the frame shown.
- pattern_array: tuple[nametable.Pattern.Pattern, ...]¶