1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-05-02 00:28:06 +02:00

gba render on tns

This commit is contained in:
XProger 2020-12-29 02:08:34 +03:00
parent 6d9304d96a
commit 0c0e2111b5
8 changed files with 406 additions and 97 deletions

View File

@ -249,7 +249,7 @@ namespace GAPI {
void resize() {
delete[] swDepth;
swDepth = new DepthSW[Core::width * Core::height];
//swDepth = new DepthSW[Core::width * Core::height];
}
inline mat4::ProjRange getProjRange() {

View File

@ -32,7 +32,7 @@ MUSIC :=
#---------------------------------------------------------------------------------
ARCH := -mthumb -mthumb-interwork
CFLAGS := -g -Wall -O3\
CFLAGS := -g -Wall -O3 -D__GBA__\
-mcpu=arm7tdmi -mtune=arm7tdmi\
-fomit-frame-pointer\
-ffast-math\

View File

@ -0,0 +1,49 @@
DEBUG = FALSE
GCC = nspire-gcc
AS = nspire-as
GXX = nspire-g++
LD = nspire-ld
GENZEHN = genzehn
GCCFLAGS = -marm -march=armv5te -mtune=arm926ej-s -std=c++11 -flto -ffast-math -fomit-frame-pointer -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections -D__TNS__ -I../../
LDFLAGS = -Wl,--gc-sections -Wl,--as-needed -flto -Wno-alloc-size-larger-than
ZEHNFLAGS = --name "OpenLara"
ifeq ($(DEBUG),FALSE)
GCCFLAGS += -Ofast
else
GCCFLAGS += -O0 -g
endif
OBJS = $(patsubst %.c, %.o, $(shell find . -name \*.c))
OBJS += $(patsubst %.cpp, %.o, $(shell find . -name \*.cpp))
OBJS += $(patsubst %.s, %.o, $(shell find . -name \*.s))
EXE = OpenLara
DISTDIR = .
vpath %.tns $(DISTDIR)
vpath %.elf $(DISTDIR)
all: $(EXE).prg.tns
%.o: %.c
$(GCC) $(GCCFLAGS) -c $<
%.o: %.cpp
$(GXX) $(GCCFLAGS) -c $<
%.o: %.s
$(AS) -c $<
$(EXE).elf: $(OBJS)
mkdir -p $(DISTDIR)
$(LD) $^ -o $(DISTDIR)/$@ $(LDFLAGS)
$(EXE).tns: $(EXE).elf
$(GENZEHN) --input $(DISTDIR)/$^ --output $(DISTDIR)/$@ $(ZEHNFLAGS)
$(EXE).prg.tns: $(EXE).tns
make-prg $(DISTDIR)/$^ $(DISTDIR)/$@
clean:
rm -f *.o $(DISTDIR)/$(EXE).tns $(DISTDIR)/$(EXE).elf $(DISTDIR)/$(EXE).prg.tns

View File

@ -1,19 +1,21 @@
#ifndef H_COMMON
#define H_COMMON
#ifdef _WIN32
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#else
#include <gba_console.h>
#include <gba_video.h>
#include <gba_timers.h>
#include <gba_interrupt.h>
#include <gba_systemcalls.h>
#include <gba_input.h>
#include <gba_dma.h>
#include <gba_affine.h>
#include <fade.h>
#if defined(_WIN32)
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#elif defined(__GBA__)
#include <gba_console.h>
#include <gba_video.h>
#include <gba_timers.h>
#include <gba_interrupt.h>
#include <gba_systemcalls.h>
#include <gba_input.h>
#include <gba_dma.h>
#include <gba_affine.h>
#include <fade.h>
#elif defined(__TNS__)
#include <os.h>
#endif
#include <stdio.h>
@ -22,29 +24,47 @@
#include <math.h>
#include <assert.h>
#define USE_MODE_5
//#define DEBUG_OVERDRAW
//#define DEBUG_FACES
//#define USE_MODE_5
//#define USE_MODE_4
#define SCALE 1
#ifdef USE_MODE_5
#define WIDTH 160
#define HEIGHT 128
#define FRAME_WIDTH 160
#define FRAME_HEIGHT 128
#define PIXEL_SIZE 1
#else // MODE_4
#define WIDTH 240
#define HEIGHT 160
#if defined(__TNS__)
#define WIDTH SCREEN_WIDTH
#define HEIGHT SCREEN_HEIGHT
#define FRAME_WIDTH (WIDTH/SCALE)
#define FRAME_HEIGHT (HEIGHT/SCALE)
#define PIXEL_SIZE 2
#define FOV_SHIFT 8
#else
#ifdef USE_MODE_5
#define WIDTH 160
#define HEIGHT 128
#define FRAME_WIDTH 160
#define FRAME_HEIGHT 128
#define FOV_SHIFT 7
#elif USE_MODE_4
#define WIDTH 240
#define HEIGHT 160
#define FRAME_WIDTH (WIDTH/SCALE)
#define FRAME_HEIGHT (HEIGHT/SCALE)
#define FOV_SHIFT 7
#else
#error
#endif
#endif
#ifdef _WIN32
#define INLINE inline
#ifdef USE_MODE_5
#define PIXEL_SIZE 1
#else
#define PIXEL_SIZE 2
#endif
#if defined(_WIN32)
#define INLINE inline
#elif defined(__GBA__) || defined(__TNS__)
#define INLINE __attribute__((always_inline)) inline
#endif
@ -63,13 +83,13 @@ typedef int16 Index;
#define DEG2RAD (PI / 180.0f)
#define RAD2DEG (180.0f / PI)
#ifdef _WIN32
#if defined(_WIN32)
#define IWRAM_CODE
#define EWRAM_DATA
#define dmaCopy(src,dst,size) memcpy(dst,src,size)
#define ALIGN4
#else
#elif defined(__GBA__)
#define ALIGN4 __attribute__ ((aligned (4)))
// TODO profiling
@ -91,6 +111,18 @@ typedef int16 Index;
REG_TM2CNT= 0;
return (REG_TM3D<<16)|REG_TM2D;
}
#elif defined(__TNS__)
#define IWRAM_CODE
#define EWRAM_DATA
#define dmaCopy(src,dst,size) memcpy(dst,src,size)
#define ALIGN4 __attribute__ ((aligned (4)))
void SetPalette(unsigned short* palette);
INLINE void profile_start() {}
INLINE uint32 profile_stop() { return 0; }
#endif
enum InputKey {
@ -289,7 +321,6 @@ struct Face {
};
#define FIXED_SHIFT 14
#define FOV_SHIFT (7 - (SCALE - 1))
#define MAX_MATRICES 8
#define MAX_MODELS 64
@ -339,4 +370,4 @@ void readLevel(const uint8 *data);
const Room::Sector* getSector(int32 roomIndex, int32 x, int32 z);
int32 getRoomIndex(int32 roomIndex, const vec3i &pos);
#endif
#endif

View File

@ -130,16 +130,22 @@ void readLevel(const uint8 *data) { // TODO non-hardcode level loader, added *_O
const uint8* p = f_palette;
for (int i = 0; i < 256; i++) {
for (int i = 0; i < 256; i++)
{
#if defined(_WIN32) || defined(__GBA__)
palette[i] = (p[0] >> 1) | ((p[1] >> 1) << 5) | ((p[2] >> 1) << 10);
#elif defined(__TNS__)
palette[i] = (p[2] >> 1) | ((p[1] >> 1) << 5) | ((p[0] >> 1) << 10);
#endif
p += 3;
}
#ifndef _WIN32
#if defined(__GBA__) || defined(__TNS__)
#ifndef USE_MODE_5
SetPalette(palette);
#endif
#endif
// prepare models
for (uint32 i = 0; i < modelsCount; i++) {
dmaCopy(modelsPtr, models + i, sizeof(Model)); // sizeof(Model) is faster than FILE_MODEL_SIZE

View File

@ -1,24 +1,10 @@
#ifndef _WIN32
#include <gba_console.h>
#include <gba_video.h>
#include <gba_timers.h>
#include <gba_interrupt.h>
#include <gba_systemcalls.h>
#include <gba_input.h>
#include <gba_dma.h>
#include <gba_affine.h>
#include <fade.h>
#include "LEVEL1_PHD.h"
#endif
//#define PROFILE
#include "common.h"
#include "level.h"
#include "camera.h"
#ifdef _WIN32
#if defined(_WIN32)
uint8* LEVEL1_PHD;
uint32 SCREEN[WIDTH * HEIGHT];
@ -26,8 +12,69 @@
extern uint8 fb[WIDTH * HEIGHT * 2];
#define WND_SCALE 4
#else
#elif defined(__GBA__)
#include "LEVEL1_PHD.h"
extern uint32 fb;
#elif defined(__TNS__)
uint8* LEVEL1_PHD;
extern uint8 fb[WIDTH * HEIGHT];
unsigned int osTime;
volatile unsigned int *timerBUS;
volatile unsigned int *timerCLK;
volatile unsigned int *timerCTR;
volatile unsigned int *timerDIV;
void timerInit()
{
timerBUS = (unsigned int*)0x900B0018;
timerCLK = (unsigned int*)0x900C0004;
timerCTR = (unsigned int*)0x900C0008;
timerDIV = (unsigned int*)0x900C0080;
*timerBUS &= ~(1 << 11);
*timerDIV = 0x0A;
*timerCTR = 0x82;
osTime = *timerCLK;
}
int GetTickCount()
{
return (osTime - *timerCLK) / 33;
}
void SetPalette(unsigned short* palette)
{
unsigned short *palReg = (unsigned short*)0xC0000200;
memcpy(palReg, palette, 256 * 2);
}
touchpad_info_t* touchInfo;
touchpad_report_t touchReport;
uint8 inputData[0x20];
void inputInit()
{
touchInfo = is_touchpad ? touchpad_getinfo() : NULL;
}
void inputUpdate()
{
if (touchInfo)
{
touchpad_scan(&touchReport);
}
memcpy(inputData, (void*)0x900E0000, 0x20);
}
bool keyDown(const t_key &key)
{
return (*(short*)(inputData + key.tpad_row)) & key.tpad_col;
}
#endif
bool keys[IK_MAX] = {};
@ -42,7 +89,7 @@ void update(int32 frames) {
}
}
#ifdef WIN32
#if defined(_WIN32)
extern Vertex gVertices[MAX_VERTICES];
INLINE int32 classify(const Vertex* v) {
@ -127,7 +174,7 @@ void render() {
drawNumber(fps, FRAME_WIDTH, 16);
}
#ifdef _WIN32
#if defined(_WIN32)
HDC hDC;
void blit() {
@ -187,9 +234,20 @@ void vblank() {
}
int main(void) {
#ifdef _WIN32
#if defined(_WIN32) || defined(__TNS__)
{
FILE *f = fopen("data/LEVEL1.PHD", "rb");
#if defined(_WIN32)
FILE *f = fopen("data/LEVEL1.PHD", "rb");
#elif defined(__TNS__)
FILE *f = fopen("/documents/OpenLara/LEVEL1.PHD.tns", "rb");
#else
#error
#endif
if (!f) {
return 0;
}
fseek(f, 0, SEEK_END);
int32 size = ftell(f);
fseek(f, 0, SEEK_SET);
@ -197,7 +255,7 @@ int main(void) {
fread(LEVEL1_PHD, 1, size, f);
fclose(f);
}
#else
#elif defined(__GBA__)
// set low latency mode via WAITCNT register (thanks to GValiente)
#define BIT_SET(y, flag) (y |= (flag))
#define REG_WAITCNT_NV *(u16*)(REG_BASE + 0x0204)
@ -209,7 +267,7 @@ int main(void) {
readLevel(LEVEL1_PHD);
#ifdef _WIN32
#if defined(_WIN32)
RECT r = { 0, 0, 240 * WND_SCALE, 160 * WND_SCALE };
AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, false);
@ -243,7 +301,7 @@ int main(void) {
}
} while (msg.message != WM_QUIT);
#else
#elif defined(__GBA__)
irqInit();
irqSet(IRQ_VBLANK, vblank);
irqEnable(IRQ_VBLANK);
@ -306,5 +364,67 @@ int main(void) {
}
}
#elif defined(__TNS__)
if (!has_colors)
return 0;
lcd_init(SCR_320x240_8);
timerInit();
inputInit();
int startTime = GetTickCount();
int lastTime = -15;
int fpsTime = startTime;
memset(keys, 0, sizeof(keys));
while (1)
{
inputUpdate();
if (keyDown(KEY_NSPIRE_ESC))
{
break;
}
if (touchInfo && touchReport.contact)
{
float tx = float(touchReport.x) / float(touchInfo->width) * 2.0f - 1.0f;
float ty = float(touchReport.y) / float(touchInfo->height) * 2.0f - 1.0f;
keys[IK_LEFT] = tx < -0.5f;
keys[IK_RIGHT] = tx > 0.5f;
keys[IK_UP] = ty > 0.5f;
keys[IK_DOWN] = ty < -0.5f;
} else {
keys[IK_LEFT] =
keys[IK_RIGHT] =
keys[IK_UP] =
keys[IK_DOWN] = false;
}
keys[IK_A] = keyDown(KEY_NSPIRE_2);
keys[IK_B] = keyDown(KEY_NSPIRE_3);
keys[IK_L] = keyDown(KEY_NSPIRE_7);
keys[IK_R] = keyDown(KEY_NSPIRE_9);
int time = GetTickCount() - startTime;
update((time - lastTime) / 16);
lastTime = time;
render();
lcd_blit(fb, SCR_320x240_8);
//msleep(16);
fpsCounter++;
if (lastTime - fpsTime >= 1000)
{
fps = fpsCounter;
fpsCounter = 0;
fpsTime = lastTime - ((lastTime - fpsTime) - 1000);
}
}
#endif
}

View File

@ -4,10 +4,12 @@
uint16 divTable[DIV_TABLE_SIZE];
#ifdef _WIN32
#if defined(_WIN32)
uint8 fb[WIDTH * HEIGHT * 2];
#else
#elif defined(__GBA__)
uint32 fb = VRAM;
#elif defined(__TNS__)
uint8 fb[WIDTH * HEIGHT];
#endif
#define FixedInvS(x) ((x < 0) ? -divTable[abs(x)] : divTable[x])
@ -194,7 +196,7 @@ Matrix& matrixGet() {
}
void matrixPush() {
#ifdef _WIN32
#if defined(_WIN32)
if (matrixStackIndex >= MAX_MATRICES - 1) {
DebugBreak();
return;
@ -206,7 +208,7 @@ void matrixPush() {
}
void matrixPop() {
#ifdef _WIN32
#if defined(_WIN32)
if (matrixStackIndex <= 0) {
DebugBreak();
return;
@ -292,7 +294,7 @@ INLINE int32 classify(const Vertex* v) {
}
void transform(const vec3s &v, int32 vg) {
#ifdef _WIN32
#if defined(_WIN32)
if (gVerticesCount >= MAX_VERTICES) {
DebugBreak();
return;
@ -326,12 +328,12 @@ void transform(const vec3s &v, int32 vg) {
z >>= FOV_SHIFT;
#if 1
#if 0
x >>= (10 + SCALE);
y >>= (10 + SCALE);
z >>= (10 + SCALE);
#ifdef WIN32
#if defined(_WIN32)
if (abs(z) >= DIV_TABLE_SIZE) {
DebugBreak();
}
@ -593,7 +595,7 @@ struct Edge {
};
INLINE void scanlineG(const uint8 *tile, uint16* buffer, int32 x1, int32 x2, uint8 palIndex, uint32 g, uint32 dgdx) {
#ifdef USE_MODE_5
#if defined(USE_MODE_5)
uint16* pixel = buffer + x1;
if (x1 & 1) {
@ -621,7 +623,7 @@ INLINE void scanlineG(const uint8 *tile, uint16* buffer, int32 x1, int32 x2, uin
if (x2 & 1) {
*pixel++ = FETCH_G_PAL(palIndex);
}
#else
#elif defined(USE_MODE_4)
if (x1 & 1)
{
uint16 &p = *(uint16*)((uint8*)buffer + x1 - 1);
@ -671,11 +673,60 @@ INLINE void scanlineG(const uint8 *tile, uint16* buffer, int32 x1, int32 x2, uin
{
*pixel = (*pixel & 0xFF00) | FETCH_G(palIndex);
}
#else
if (x1 & 1)
{
*((uint8*)buffer + x1) = FETCH_G(palIndex);
g += dgdx;
x1++;
}
int32 width = (x2 - x1) >> 1;
uint16* pixel = (uint16*)((uint8*)buffer + x1);
dgdx <<= 1;
if (width && (x1 & 3))
{
uint16 p = FETCH_G(palIndex);
*pixel++ = p | (FETCH_G(palIndex) << 8);
g += dgdx;
width--;
}
while (width-- > 0)
{
uint32 p = FETCH_G(palIndex);
p |= (FETCH_G(palIndex) << 8);
g += dgdx;
if (width-- > 0)
{
p |= (FETCH_G(palIndex) << 16);
p |= (FETCH_G(palIndex) << 24);
g += dgdx;
*(uint32*)pixel = p;
pixel += 2;
} else {
*(uint16*)pixel = p;
pixel += 1;
}
}
if (x2 & 1)
{
*((uint8*)pixel) = FETCH_G(palIndex);
}
#endif
}
INLINE void scanlineGT(const uint8 *tile, uint16* buffer, int32 x1, int32 x2, uint32 g, uint32 t, uint32 dgdx, uint32 dtdx) {
#ifdef USE_MODE_5
#if defined(USE_MODE_5)
uint16* pixel = buffer + x1;
if (x1 & 1) {
@ -708,7 +759,7 @@ INLINE void scanlineGT(const uint8 *tile, uint16* buffer, int32 x1, int32 x2, ui
*pixel++ = FETCH_GT_PAL();
}
#else
#elif defined(USE_MODE_4)
if (x1 & 1)
{
@ -766,6 +817,62 @@ INLINE void scanlineGT(const uint8 *tile, uint16* buffer, int32 x1, int32 x2, ui
{
*pixel = (*pixel & 0xFF00) | FETCH_GT();
}
#else
if (x1 & 1)
{
*((uint8*)buffer + x1) = FETCH_GT();
t += dtdx;
g += dgdx;
x1++;
}
int32 width = (x2 - x1) >> 1;
uint16* pixel = (uint16*)((uint8*)buffer + x1);
dgdx <<= 1;
if (width && (x1 & 3))
{
uint16 p = FETCH_GT();
t += dtdx;
*pixel++ = p | (FETCH_GT() << 8);
t += dtdx;
g += dgdx;
width--;
}
while (width-- > 0)
{
uint32 p = FETCH_GT();
t += dtdx;
p |= (FETCH_GT() << 8);
t += dtdx;
g += dgdx;
if (width-- > 0)
{
p |= (FETCH_GT() << 16);
t += dtdx;
p |= (FETCH_GT() << 24);
t += dtdx;
g += dgdx;
*(uint32*)pixel = p;
pixel += 2;
} else {
*(uint16*)pixel = p;
pixel += 1;
}
}
if (x2 & 1)
{
*((uint8*)pixel) = FETCH_GT();
}
#endif
}
@ -1066,7 +1173,7 @@ void drawGlyph(const Sprite *sprite, int32 x, int32 y) {
}
void faceAddQuad(uint16 flags, const Index* indices, int32 startVertex) {
#ifdef _WIN32
#if defined(_WIN32)
if (gFacesCount >= MAX_FACES) {
DebugBreak();
}
@ -1104,7 +1211,7 @@ void faceAddQuad(uint16 flags, const Index* indices, int32 startVertex) {
}
void faceAddTriangle(uint16 flags, const Index* indices, int32 startVertex) {
#ifdef _WIN32
#if defined(_WIN32)
if (gFacesCount >= MAX_FACES) {
DebugBreak();
}
@ -1227,9 +1334,9 @@ void initRender() {
}
void dmaClear(uint32 *dst, uint32 count) {
#ifdef WIN32
#if defined(_WIN32) || defined(__TNS__)
memset(dst, 0, count * 4);
#else
#elif defined(__GBA__)
vu32 value = 0;
REG_DMA3SAD = (vu32)&value;
REG_DMA3DAD = (vu32)dst;
@ -1238,9 +1345,5 @@ void dmaClear(uint32 *dst, uint32 count) {
}
void clear() {
#ifdef USE_MODE_5
dmaClear((uint32*)fb, (WIDTH * HEIGHT) >> PIXEL_SIZE);
#else
dmaClear((uint32*)fb, (WIDTH * HEIGHT) >> PIXEL_SIZE);
#endif
}
}

View File

@ -52,7 +52,7 @@ bool osJoyReady(int index)
void osJoyVibrate(int index, float L, float R) {}
void joyUpdate()
bool inputUpdate()
{
Input::setJoyPos(0, jkL, vec2(0.0f, 0.0f));
Input::setJoyPos(0, jkR, vec2(0.0f, 0.0f));
@ -70,21 +70,23 @@ void joyUpdate()
}
}
Input::setJoyDown(0, jkA, isKeyPressed(KEY_NSPIRE_2));
Input::setJoyDown(0, jkB, isKeyPressed(KEY_NSPIRE_3));
Input::setJoyDown(0, jkX, isKeyPressed(KEY_NSPIRE_5));
Input::setJoyDown(0, jkY, isKeyPressed(KEY_NSPIRE_6));
Input::setJoyDown(0, jkLB, isKeyPressed(KEY_NSPIRE_7));
Input::setJoyDown(0, jkRB, isKeyPressed(KEY_NSPIRE_9));
uint8 inputData[0x20];
memcpy(inputData, (void*)0x900E0000, 0x20);
#define IS_KEY_DOWN(key) ((*(short*)(inputData + key.tpad_row)) & key.tpad_col)
Input::setJoyDown(0, jkA, IS_KEY_DOWN(KEY_NSPIRE_2));
Input::setJoyDown(0, jkB, IS_KEY_DOWN(KEY_NSPIRE_3));
Input::setJoyDown(0, jkX, IS_KEY_DOWN(KEY_NSPIRE_5));
Input::setJoyDown(0, jkY, IS_KEY_DOWN(KEY_NSPIRE_6));
Input::setJoyDown(0, jkLB, IS_KEY_DOWN(KEY_NSPIRE_7));
Input::setJoyDown(0, jkRB, IS_KEY_DOWN(KEY_NSPIRE_9));
Input::setJoyDown(0, jkL, false);
Input::setJoyDown(0, jkR, false);
Input::setJoyDown(0, jkStart, isKeyPressed(KEY_NSPIRE_ENTER));
Input::setJoyDown(0, jkSelect, isKeyPressed(KEY_NSPIRE_MENU));
Input::setJoyDown(0, jkStart, IS_KEY_DOWN(KEY_NSPIRE_ENTER));
Input::setJoyDown(0, jkSelect, IS_KEY_DOWN(KEY_NSPIRE_MENU));
Input::setJoyDown(0, jkUp, isKeyPressed(KEY_NSPIRE_UP) || isKeyPressed(KEY_NSPIRE_LEFTUP) || isKeyPressed(KEY_NSPIRE_UPRIGHT));
Input::setJoyDown(0, jkDown, isKeyPressed(KEY_NSPIRE_DOWN) || isKeyPressed(KEY_NSPIRE_RIGHTDOWN) || isKeyPressed(KEY_NSPIRE_DOWNLEFT));
Input::setJoyDown(0, jkLeft, isKeyPressed(KEY_NSPIRE_LEFT) || isKeyPressed(KEY_NSPIRE_LEFTUP) || isKeyPressed(KEY_NSPIRE_DOWNLEFT));
Input::setJoyDown(0, jkRight, isKeyPressed(KEY_NSPIRE_RIGHT) || isKeyPressed(KEY_NSPIRE_RIGHTDOWN) || isKeyPressed(KEY_NSPIRE_UPRIGHT));
return !IS_KEY_DOWN(KEY_NSPIRE_ESC);
}
unsigned short* osPalette()
@ -113,7 +115,7 @@ int main(void)
Core::width = SCREEN_WIDTH;
Core::height = SCREEN_HEIGHT;
GAPI::swColor = new GAPI::ColorSW[SCREEN_WIDTH * SCREEN_HEIGHT];
GAPI::swColor = new GAPI::ColorSW[Core::width * Core::height];
GAPI::resize();
Sound::channelsCount = 0;
@ -122,7 +124,10 @@ int main(void)
while (!Core::isQuit)
{
joyUpdate();
if (!inputUpdate())
{
Core::quit();
}
if (Game::update())
{
@ -130,11 +135,6 @@ int main(void)
lcd_blit(GAPI::swColor, SCR_320x240_565);
}
if (isKeyPressed(KEY_NSPIRE_ESC))
{
Core::quit();
}
}
delete[] GAPI::swColor;