Initial NDS Universal-Core

This commit is contained in:
Pk11
2021-01-13 15:51:37 -06:00
commit 8a55d0e7cb
13 changed files with 2060 additions and 0 deletions
+156
View File
@@ -0,0 +1,156 @@
#ifndef FONT_HPP
#define FONT_HPP
#include "sprite.hpp"
#include <nds/ndstypes.h>
#include <string>
#include <string_view>
#include <vector>
#include "UNIVCORE_CONFIG.h"
enum class Alignment {
left,
center,
right,
};
class Font {
private:
#ifdef TEXT_BUFFERED
static u8 textBuf[2][256 * 192];
#endif
u8 tileWidth, tileHeight;
u16 tileSize;
u16 questionMark = 0;
std::vector<u8> fontTiles;
std::vector<u8> fontWidths;
std::vector<u16> fontMap;
u16 charIndex(char16_t c);
void print(std::u16string_view text, int x, int y, bool top, int layer, Alignment align, int maxWidth, int color, float scaleX, float scaleY, Sprite *sprite);
public:
/**
* @brief Converts a UTF-8 string to UCS-2
* @param text The string to convert
* @return The converted string
*/
static std::u16string utf8to16(std::string_view text);
/**
* @brief Text printing class
* @param paths The path to load the font from
*/
Font(const std::string &path) : Font(std::vector<std::string>({path})) {}
/**
* @brief Text printing class
* @param paths The paths to try load the font from, from highest to lowest priority
*/
Font(const std::vector<std::string> &paths);
Font() {}
~Font() {}
/**
* @brief The height of the font
* @return The font height
*/
u8 height(void) { return tileHeight; }
/**
* @brief Calculates the width of a given string of text
* @param text The text to calculate the width of
* @return The width of the given string
*/
int calcWidth(std::string_view text) { return calcWidth(utf8to16(text)); }
int calcWidth(std::u16string_view text);
/**
* @brief Prints an integer value to a background layer
* @param value The value to print
* @param x The X position to print at
* @param y The Y position to print at
* @param top Whether to print on the top or bottom screen
* @param layer (Optional) The layer to print on
* @param align (Optional) The alignment to use
* @param maxWidth (Optional) The maximum width of the string, set to 0 for no max width
* @param color (Optional) The color to print in
* @param scaleX (Optional) The scale on the X axis
* @param scaleY (Optional) The scale on the Y axis
*/
void print(int value, int x, int y, bool top, int layer = 2, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(utf8to16(std::to_string(value)), x, y, top, layer, align, maxWidth, scaleX, scaleY, color, nullptr); }
/**
* @brief Prints a string to a background layer
* @param text The string to print
* @param x The X position to print at
* @param y The Y position to print at
* @param top Whether to print on the top or bottom screen
* @param layer (Optional) The layer to print on
* @param align (Optional) The alignment to use
* @param maxWidth (Optional) The maximum width of the string, set to 0 for no max width
* @param scaleX (Optional) The scale on the X axis
* @param scaleY (Optional) The scale on the Y axis
* @param color (Optional) The color to print in
*/
void print(std::string_view text, int x, int y, bool top, int layer = 2, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(utf8to16(text), x, y, top, layer, align, maxWidth, color, scaleX, scaleY, nullptr); }
void print(std::u16string_view text, int x, int y, bool top, int layer = 2, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(text, x, y, top, layer, align, maxWidth, color, scaleX, scaleY, nullptr); }
/**
* @brief Prints an integer value to a sprite
* @param value The value to print
* @param x The X position to print at
* @param y The Y position to print at
* @param sprite The sprite to print to
* @param align (Optional) The alignment to use
* @param maxWidth (Optional) The maximum width of the string, set to 0 for no max width
* @param color (Optional) The color to print in
* @param scaleX (Optional) The scale on the X axis
* @param scaleY (Optional) The scale on the Y axis
*/
void print(int value, int x, int y, Sprite &sprite, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(utf8to16(std::to_string(value)), x, y, false, 0, align, maxWidth, color, scaleX, scaleY, nullptr); }
/**
* @brief Prints a string to a sprite
* @param text The string to print
* @param x The X position to print at
* @param y The Y position to print at
* @param sprite The sprite to print to
* @param align (Optional) The alignment to use
* @param maxWidth (Optional) The maximum width of the string, set to 0 for no max width
* @param color (Optional) The color to print in
* @param scaleX (Optional) The scale on the X axis
* @param scaleY (Optional) The scale on the Y axis
*/
void print(std::string_view text, int x, int y, Sprite &sprite, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(utf8to16(text), x, y, false, 0, align, maxWidth, color, scaleX, scaleY, &sprite); }
void print(std::u16string_view text, int x, int y, Sprite &sprite, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(text, x, y, false, 0, align, maxWidth, color, scaleX, scaleY, &sprite); }
#ifdef TEXT_BUFFERED
/**
* @brief Clears all text from both screens
*/
static void clear(void) { clear(true); clear(false); }
/**
* @brief Clears all text from the given screen
* @param Whether to clear the top or bottom screen
*/
static void clear(bool top);
/**
* @brief Copies all text on both screens from the buffer to actual screen
*/
static void update(void) { update(true); update(false); }
/**
* @brief Copies all text on the given screen from the buffer to actual screen
* @param top Whether to update the top or bottom screen
*/
static void update(bool top);
#endif
};
#endif
+62
View File
@@ -0,0 +1,62 @@
#ifndef GRAPHICS_HPP
#define GRAPHICS_HPP
#include "font.hpp"
#include "image.hpp"
#include "sprite.hpp"
#include <nds/ndstypes.h>
namespace Graphics {
extern int bg3Main, bg2Main, bg3Sub, bg2Sub;
extern bool wideScreen;
/**
* @brief Initializes the screens for drawing
*/
void init(void);
/**
* @brief Clears the given layer
*/
void clear(bool top, int layer);
/**
* @brief Draws a rectangle outline of a given size at a given position
* @param x The X position
* @param y The Y position
* @param w The Width
* @param h The Height
* @param color The index of the color to use
* @param top Whether to draw to the top or bottom screen
* @param layer The layer to draw to
*/
void drawOutline(int x, int y, int w, int h, u8 color, bool top, int layer);
/**
* @brief Draws a rectangle of a given size at a given position
* @param x The X position
* @param y The Y position
* @param w The Width
* @param h The Height
* @param color The index of the color to use
* @param top Whether to draw on the top or bottom screen
* @param layer The layer to draw to
*/
void drawRectangle(int x, int y, int w, int h, u8 color, bool top, bool layer);
/**
* @brief Draws a rectangle of a given size at a given position
* @param x The X position
* @param y The Y position
* @param w The Width
* @param h The Height
* @param color1 The index of the color to use for even rows
* @param color2 The index of the color to use for odd rows
* @param top Whether to draw on the top or bottom screen
* @param layer The layer to draw to
*/
void drawRectangle(int x, int y, int w, int h, u8 color1, u8 color2, bool top, bool layer);
}
#endif
+101
View File
@@ -0,0 +1,101 @@
#ifndef IMAGE_HPP
#define IMAGE_HPP
#include <nds/ndstypes.h>
#include <string>
#include <vector>
class Image {
private:
u16 _width;
u16 _height;
std::vector<u8> _bitmap;
std::vector<u16> _palette;
u16 _palOfs;
public:
/**
* Image drawing class
* @param path The path to load the image from
*/
Image(const std::vector<std::string> &paths);
/**
* @brief Text printing class
* @param paths The paths to try load the image from, from highest to lowest priority
*/
Image(const std::string &path) : Image(std::vector<std::string>({path})) {};
/**
* @brief Text printing class
* @param file The file to load the image from, seeked to the image magic
*/
Image(FILE *file);
Image() {};
~Image(void) {};
u16 width(void) const { return _width; }
u16 height(void) const { return _height; }
std::vector<u8> bitmap(void) const { return _bitmap; }
std::vector<u16> palette(void) const { return _palette; }
u16 palOfs(void) const { return _palOfs; }
/**
* @brief Draws the image to a background layer, faster but without alpha, scaling, or palette offsetting
* @param x The X position to draw at
* @param y The Y position to draw at
* @param top Whether to draw on teh top or bottom screen, not used for sprites
* @param layer (Optional) The layer to draw on, not used for sprites
* @param channel (Optional) The DMA channel to use
* @param copyPal (Optional) Whether to copy the image's palette into palette VRAM
*/
void draw(int x, int y, bool top, int layer = 3, int channel = 0, bool copyPal = true);
/**
* @brief Draws the image to a background layer, slower but can skip alpha, scale, and offset the palette
* @param x The X position to draw at
* @param y The Y position to draw at
* @param top Whether to draw on the top or bottom screen
* @param layer (Optional) Which background layer to draw on
* @param scaleX (Optional) The scale for the X axis
* @param scaleY (Optional) The scale for the Y axis
* @param paletteOffset (Optional) How much to offset the palette by
* @param copyPal (Optional) Whether to copy the image's palette into palette VRAM
*/
void drawSpecial(int x, int y, bool top, int layer = 3, float scaleX = 1.0f, float scaleY = 1.0f, int paletteOffset = 0, bool copyPal = true);
/**
* @brief Draws a segment of an image to a background layer, faster but overwrites alpha and no scaling or palette offsetting
* @param x The X position to draw at
* @param y The Y position to draw at
* @param imageX The X position in the image to draw from
* @param imageY The Y position in the image to draw from
* @param w The width to draw
* @param h The height to draw
* @param top Whether to draw on the top or bottom screen
* @param layer (Optional) Which background layer to draw on
* @param channel (Optional) The DMA channel to use
* @param copyPal (Optional) Whether to copy the image's palette into palette VRAM
*/
void drawSegment(int x, int y, int imageX, int imageY, int w, int h, bool top, int layer = 3, int channel = 0, bool copyPal = true);
/**
* @brief Draws a segment of an image to a background layer, slower but can skip alpha, scale, and offset the palette
* @param x The X position to draw at
* @param y The Y position to draw at
* @param imageX The X position in the image to draw from
* @param imageY The Y position in the image to draw from
* @param w The width to draw
* @param h The height to draw
* @param top Whether to draw on the top or bottom screen
* @param layer (Optional) Which background layer to draw on
* @param scaleX (Optional) The scale for the X axis
* @param scaleY (Optional) The scale for the Y axis
* @param paletteOffset (Optional) How much to offset the palette by
* @param copyPal (Optional) Whether to copy the image's palette into palette VRAM
*/
void drawSegmentSpecial(int x, int y, int imageX, int imageY, int w, int h, bool top, int layer = 3, float scaleX = 1.0f, float scaleY = 1.0f, int paletteOffset = 0, bool copyPal = true);
};
#endif
+175
View File
@@ -0,0 +1,175 @@
#ifndef SPRITE_HPP
#define SPRITE_HPP
#include "image.hpp"
#include <nds.h>
class Sprite {
private:
bool _top;
OamState *_oam;
SpriteSize _size;
SpriteColorFormat _format;
int _x, _y, _priority, _id, _rotationIndex, _paletteAlpha, _width, _height, _rotation;
float _scaleX, _scaleY;
bool _visibility;
u16* _gfx;
static bool _assigned[2][256];
public:
/**
* @brief A class for easier management of OAM sprites
*/
Sprite() {}
/**
* @brief A class for easier management of OAM sprites
* @param top Whether to make it on the top or bottom screen
* @param size The size of the sprite
* @param format The color format of the sprite
* @param (Optional) x The starting X position of the sprite
* @param (Optional) y The starting Y position of the sprite
* @param (Optional) priority The starting priority of the sprite, 0 - 3 with 0 on top
* @param (Optional) id The ID to use for the sprite, set to -1 to automatically use the first free one
* @param (Optional) paletteAlpha For paletted sprites, the pallete to use. For bitmap sprites, the alpha
* @param (Optional) rotationIndex The rotation index to use, set to -1 for no rotation
* @param (Optional) doubleSize Whether to double the size for rotation
* @param (Optional) visible Whether the sprite should start visible
* @param (Optional) vFlip Whether to start the sprite flipped vertically
* @param (Optional) hFlip Whether to start the sprite flipped horizontally
* @param (Optional) mosaic Whether to mosaic the sprite // TODO: What is this?
*/
Sprite(bool top, SpriteSize size, SpriteColorFormat format, int x = 0, int y = 0, int priority = 0, int id = -1, int paletteAlpha = 15, int rotationIndex = -1, bool doubleSize = false, bool visible = true, bool vFlip = false, bool hFlip = false, bool mosaic = false);
~Sprite(void);
u16* gfx(void) const { return _gfx; }
SpriteSize size(void) const { return _size; }
SpriteColorFormat format(void) const { return _format; }
bool visibility(void) const { return _visibility; }
int id(void) const { return _id; }
int rotationIndex(void) const { return _rotationIndex; }
int paletteAlpha(void) const { return _paletteAlpha; }
int x(void) const { return _x; }
int y(void) const { return _y; }
int width(void) const { return _width; }
int height(void) const { return _height; }
int rotation(void) const { return _rotation; }
float scaleX(void) const { return _scaleX; }
float scaleY(void) const { return _scaleY; }
/**
* @brief Sets the alpha of the sprite
* @param alpha The alpha, 0 - 15
*/
void alpha(int alpha) { oamSetAlpha(_oam, _id, alpha); }
/**
* @brief Sets the flip of the sprite
* @param hFlip The horizontal flip
* @param vFlip The vertical flip
*/
void flip(bool hFlip, bool vFlip) { oamSetFlip(_oam, _id, hFlip, vFlip); }
/**
* @brief Sets the position of the sprite
* @param x The X position
* @param y The Y position
*/
void position(int x, int y) { _x = x, _y = y; if(_visibility) oamSetXY(_oam, _id, _x, _y); }
/**
* @brief Sets the priority of the sprite
* @param priority The priority, 0 - 3 with 0 being on top
*/
void priority(int priority) { oamSetPriority(_oam, _id, priority); }
/**
* @brief Sets the scale of the sprite
* @param scaleX The scale on the X axis
* @param scaleY The scale on the Y axis
*/
void rotation(int rotation);
/**
* @brief Sets the scale of the sprite
* @param scaleX The scale on the X axis
* @param scaleY The scale on the Y axis
*/
void scale(float scaleX, float scaleY);
/**
* @brief Sets the visibility of the sprite
* @param show Whether to show the sprite or not, true to show
*/
void visibility(bool show);
/**
* @brief Clears the sprite
*/
void clear(void);
/**
* @brief Fills the sprite with a solid color
* @param color The color to fill with
*/
void fillColor(u16 color);
/**
* @brief Draws a solid color rectangle to the sprite
* @param x The X position to draw at
* @param y The Y position to draw at
* @param w The width of the rectangle
* @param h The height of the rectangle
* @param color The color of the rectangle
*/
void drawRectangle(int x, int y, int w, int h, u16 color) { drawRectangle(x, y, w, h, color, color); }
/**
* @brief Draws a solid color rectangle to the sprite
* @param x The X position to draw at
* @param y The Y position to draw at
* @param w The width of the rectangle
* @param h The height of the rectangle
* @param color The color of even rows
* @param color The color of odd rows
*/
void drawRectangle(int x, int y, int w, int h, u16 color1, u16 color2);
/**
* @brief Draws the image to a sprite, can skip alpha and scale the image
* @param x The X position to draw at
* @param y The Y position to draw at
* @param image The image to draw to the sprite
* @param scaleX (Optional) The scale for the X axis
* @param scaleY (Optional) The scale for the Y axis
*/
void drawImage(int x, int y, const Image &image, float scaleX = 1.0f, float scaleY = 1.0f);
/**
* @brief Draws a segment of an image to a sprite, faster but overwrites alpha and no scaling
* @param x The X position to draw at
* @param y The Y position to draw at
* @param imageX The X position in the image to draw from
* @param imageY The Y position in the image to draw from
* @param w The width to draw
* @param h The height to draw
* @param image The image to draw to the sprite
* @param scaleX (Optional) The scale for the X axis
* @param scaleY (Optional) The scale for the Y axis
*/
void drawImageSegment(int x, int y, int imageX, int imageY, int w, int h, const Image &image, float scaleX = 1.0f, float scaleY = 1.0f);
/**
* @brief Updates the OAM that this sprite is on, also updates all other sprites on that screen. Avoid calling this excessively, if changing a lot of sprites call it once when they're all done.
*/
void update(void) { oamUpdate(_oam); }
/**
* @brief Updates all sprites on the given screen. Avoid calling this excessively, if changing a lot of sprites call it once when they're all done.
* @param top Whether to update the top or bottom screen
*/
static void update(bool top) { oamUpdate(top ? &oamMain : &oamSub); }
};
#endif
+36
View File
@@ -0,0 +1,36 @@
//# Stuff you may not have yet.
#ifndef TONCCPY_H
#define TONCCPY_H
#ifdef __cplusplus
extern "C" {
#endif
#include <nds.h>
typedef unsigned int uint;
#define BIT_MASK(len) ((1<<(len))-1)
static inline u32 quad8(u32 x) { x |= x<<8; return x | x<<16; }
//# Declarations and inlines.
void tonccpy(void *dst, const void *src, uint size);
void __toncset(void *dst, u32 fill, uint size);
//! VRAM-safe memset, byte version. Size in bytes.
static inline void toncset(void *dst, u8 src, uint size) { __toncset(dst, quad8(src), size); }
//! VRAM-safe memset, halfword version. Size in hwords.
static inline void toncset16(void *dst, u16 src, uint size) { __toncset(dst, src|src<<16, size*2); }
//! VRAM-safe memset, word version. Size in words.
static inline void toncset32(void *dst, u32 src, uint size) { __toncset(dst, src, size*4); }
#ifdef __cplusplus
}
#endif
#endif