1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-01-29 10:38:04 +01:00

TI-Nspire port

This commit is contained in:
XProger 2020-12-27 18:00:36 +03:00
parent 8a3126a7c3
commit 6d9304d96a
11 changed files with 278 additions and 33 deletions

View File

@ -150,9 +150,15 @@
#elif _X360
#define _OS_X360 1
// TODO
#elif __NDLESS__
#define _OS_TNS 1
#define _GAPI_SW 1
#include <os.h>
#undef OS_PTHREAD_MT
#endif
#ifndef _OS_PSP
#if !defined(_OS_PSP) && !defined(_OS_TNS)
#define USE_INFLATE
#endif

View File

@ -3233,7 +3233,9 @@ namespace TR {
case VER_TR2_PSX : loadTR2_PSX (stream); break;
case VER_TR3_PC : loadTR3_PC (stream); break;
case VER_TR3_PSX : loadTR3_PSX (stream); break;
#ifdef USE_INFLATE
case VER_TR4_PC : loadTR4_PC (stream); break;
#endif
case VER_TR4_PSX : loadTR4_PSX (stream); break;
case VER_TR4_SDC : loadTR4_SDC (stream); break;
case VER_TR5_PC : loadTR5_PC (stream); break;
@ -3609,6 +3611,7 @@ namespace TR {
readCameraFrames(stream);
}
#ifdef USE_INFLATE
void loadTR4_PC (Stream &stream) {
uint16 roomTilesCount, objTilesCount, bumpTilesCount;
uint32 sizeD, sizeC, sizeR;
@ -3686,6 +3689,7 @@ namespace TR {
soundDataSize += sizeC;
}
}
#endif
void loadTR4_PSX (Stream &stream) {
@ -5895,10 +5899,13 @@ namespace TR {
break;
}
case VER_TR3_PSX : {
mesh.tCount = 0;
mesh.rCount = 0;
mesh.fCount = 0;
if (!mesh.vCount) {
mesh.vertices = NULL;
mesh.faces = NULL;
mesh.tCount = mesh.rCount = mesh.fCount = 0;
break;
}

View File

@ -1087,7 +1087,7 @@ namespace TR {
id == LVL_TR2_CUT_4 || id == LVL_TR2_XIAN || id == LVL_TR2_HOUSE) {
char buf[64];
strcpy(buf, LEVEL_INFO[id].name);
String::toLower(buf);
StrUtils::toLower(buf);
sprintf(dst, "DATA/%s.TR2", buf);
} else if (id == LVL_TR2_TITLE) {
sprintf(dst, "DATA/%s.tr2", LEVEL_INFO[id].name);
@ -1098,7 +1098,7 @@ namespace TR {
}
if (Stream::existsContent(dst)) break;
strcpy(dst, LEVEL_INFO[id].name);
String::toLower(dst);
StrUtils::toLower(dst);
strcat(dst, ".TR2");
break;
}

View File

@ -7,12 +7,14 @@
#define PROFILE_LABEL(id, name, label)
#define PROFILE_TIMING(time)
#ifdef _OS_LINUX
//#define DITHER_FILTER
#if defined(_OS_LINUX) || defined(_OS_TNS)
#define COLOR_16
#endif
#ifdef COLOR_16
#ifdef _OS_LINUX
#if defined(_OS_LINUX) || defined(_OS_TNS)
#define COLOR_FMT_565
#define CONV_COLOR(r,g,b) (((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3))
#else
@ -290,7 +292,7 @@ namespace GAPI {
}
if (depth) {
memset(swDepth, 0xFF, Core::width * Core::height * sizeof(DepthSW));
//memset(swDepth, 0xFF, Core::width * Core::height * sizeof(DepthSW));
}
}
@ -396,18 +398,25 @@ namespace GAPI {
int32 i = y * Core::width;
#ifdef DITHER_FILTER
const int *dithY = uvDither + ((y & 1) * 4);
#endif
for (int x = i + x1; x < i + x2; x++) {
S.z += dS.z;
DepthSW z = DepthSW(uint32(S.z) >> 16);
if (swDepth[x] >= z) {
{//if (swDepth[x] >= z) {
#ifdef DITHER_FILTER
const int *dithX = dithY + (x & 1);
uint32 u = uint32(S.u + dithX[0]) >> 16;
uint32 v = uint32(S.v + dithX[2]) >> 16;
#else
uint32 u = uint32(S.u) >> 16;
uint32 v = uint32(S.v) >> 16;
#endif
uint8 index = curTile->index[(v << 8) + u];
@ -415,7 +424,7 @@ namespace GAPI {
index = swLightmap[((S.l >> (16 + 3)) << 8) + index];
swColor[x] = swPalette[index];
swDepth[x] = z;
//swDepth[x] = z;
}
}
@ -580,8 +589,8 @@ namespace GAPI {
}
void applyLighting(VertexSW &result, const Vertex &vertex, float depth) {
vec3 coord = vec3(vertex.coord);
vec3 normal = vec3(vertex.normal).normal();
vec3 coord = vec3(float(vertex.coord.x), float(vertex.coord.y), float(vertex.coord.z));
vec3 normal = vec3(float(vertex.normal.x), float(vertex.normal.y), float(vertex.normal.z)).normal();
float lighting = 0.0f;
for (int i = 0; i < lightsCount; i++) {
LightSW &light = lightsRel[i];

View File

@ -153,9 +153,9 @@ struct Flame : Sprite {
Controller *owner;
int32 jointIndex;
float sleep;
float sleepTime;
Flame(IGame *game, int entity) : Sprite(game, entity, false, Sprite::FRAME_ANIMATED), owner(NULL), jointIndex(0), sleep(0.0f) {
Flame(IGame *game, int entity) : Sprite(game, entity, false, Sprite::FRAME_ANIMATED), owner(NULL), jointIndex(0), sleepTime(0.0f) {
time = randf() * 3.0f;
activate();
}
@ -186,15 +186,15 @@ struct Flame : Sprite {
lara->hit(FLAME_BURN_DAMAGE * Core::deltaTime, this);
} else
if (lara->health > 0.0f) {
if (sleep > 0.0f)
sleep = max(0.0f, sleep - Core::deltaTime);
if (sleepTime > 0.0f)
sleepTime = max(0.0f, sleepTime - Core::deltaTime);
if (sleep == 0.0f && !lara->burn && lara->collide(Sphere(pos, 600.0f))) {
if (sleepTime == 0.0f && !lara->burn && lara->collide(Sphere(pos, 600.0f))) {
lara->hit(FLAME_HEAT_DAMAGE * Core::deltaTime, this);
if (lara->collide(Sphere(pos, 300.0f))) {
Flame::add(game, lara, 0);
sleep = 3.0f; // stay inactive for 3 seconds
sleepTime = 3.0f; // stay inactive for 3 seconds
}
}
}
@ -1838,4 +1838,4 @@ struct Bullet : Controller {
}
};
#endif
#endif

49
src/platform/tns/Makefile Normal file
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 -fomit-frame-pointer -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections -D__NDLESS__ -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

145
src/platform/tns/main.cpp Normal file
View File

@ -0,0 +1,145 @@
#include <sys/time.h>
#include <game.h>
// multi-threading (no sound - no problem)
void* osMutexInit() { return NULL; }
void osMutexFree(void *obj) {}
void osMutexLock(void *obj) {}
void osMutexUnlock(void *obj) {}
// timing
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 osGetTimeMS()
{
return (osTime - *timerCLK) / 33;
}
// input
touchpad_info_t* touchInfo;
touchpad_report_t touchReport;
void touchInit()
{
touchInfo = is_touchpad ? touchpad_getinfo() : NULL;
}
bool osJoyReady(int index)
{
return (index == 0);
}
void osJoyVibrate(int index, float L, float R) {}
void joyUpdate()
{
Input::setJoyPos(0, jkL, vec2(0.0f, 0.0f));
Input::setJoyPos(0, jkR, vec2(0.0f, 0.0f));
Input::setJoyPos(0, jkLT, vec2(0.0f, 0.0f));
Input::setJoyPos(0, jkRT, vec2(0.0f, 0.0f));
if (touchInfo)
{
touchpad_scan(&touchReport);
if (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;
Input::setJoyPos(0, jkL, vec2(tx, -ty));
}
}
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));
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, 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));
}
unsigned short* osPalette()
{
return (unsigned short*)0xC0000200;
}
int main(void)
{
if (!has_colors)
return 0;
lcd_init(SCR_320x240_565);
timerInit();
touchInit();
contentDir[0] = saveDir[0] = cacheDir[0] = 0;
strcpy(contentDir, "/documents/Games/OpenLara/");
strcpy(saveDir, contentDir);
strcpy(cacheDir, contentDir);
Stream::addPack("content.tns");
Core::width = SCREEN_WIDTH;
Core::height = SCREEN_HEIGHT;
GAPI::swColor = new GAPI::ColorSW[SCREEN_WIDTH * SCREEN_HEIGHT];
GAPI::resize();
Sound::channelsCount = 0;
Game::init("DATA/LEVEL1.PHD");
while (!Core::isQuit)
{
joyUpdate();
if (Game::update())
{
Game::render();
lcd_blit(GAPI::swColor, SCR_320x240_565);
}
if (isKeyPressed(KEY_NSPIRE_ESC))
{
Core::quit();
}
}
delete[] GAPI::swColor;
//Game::deinit();
return 0;
}

View File

@ -1,15 +1,20 @@
#ifndef H_SOUND
#define H_SOUND
#define DECODE_ADPCM
#define DECODE_IMA
#define DECODE_VAG
#define DECODE_XA
#ifdef _OS_TNS
#define NO_SOUND
#endif
#define DECODE_OGG
#ifndef NO_SOUND
#define DECODE_ADPCM
#define DECODE_IMA
#define DECODE_VAG
#define DECODE_XA
#define DECODE_OGG
#if !defined(_OS_PSP) && !defined(_OS_WEB) && !defined(_OS_PSV) && !defined(_OS_3DS) && !defined(_OS_XBOX) && !defined(_OS_XB1)
#define DECODE_MP3
#if !defined(_OS_PSP) && !defined(_OS_WEB) && !defined(_OS_PSV) && !defined(_OS_3DS) && !defined(_OS_XBOX) && !defined(_OS_XB1)
#define DECODE_MP3
#endif
#endif
#include "utils.h"
@ -846,7 +851,8 @@ namespace Sound {
Sample(Stream *stream, const vec3 *pos, float volume, float pitch, int flags, int id) : uniquePtr(pos), decoder(NULL), volume(volume), volumeTarget(volume), volumeDelta(0.0f), pitch(pitch), flags(flags), id(id) {
this->pos = pos ? *pos : vec3(0.0f);
#ifndef NO_SOUND
uint32 fourcc;
stream->read(fourcc);
if (fourcc == FOURCC("RIFF")) { // wav
@ -898,6 +904,7 @@ namespace Sound {
decoder = new VAG(stream);
#endif
}
#endif
if (!decoder)
delete stream;
@ -1171,6 +1178,7 @@ namespace Sound {
}
Sample* play(Stream *stream, const vec3 *pos = NULL, float volume = 1.0f, float pitch = 0.0f, int flags = 0, int id = - 1) {
#ifndef NO_SOUND
OS_LOCK(lock);
ASSERT(pitch >= 0.0f);
@ -1207,6 +1215,7 @@ namespace Sound {
LOG("! no free channels\n");
}
#endif
delete stream;
return NULL;
}

View File

@ -9,7 +9,7 @@
#define SUBTITLES_SPEED 0.1f
#define TEXT_LINE_HEIGHT 18
#ifdef _OS_PSV
#if defined(_OS_PSV) || defined(_OS_TNS)
#define UI_SHOW_FPS
#endif

View File

@ -1532,7 +1532,7 @@ struct CLUT {
ColorCLUT color[16];
};
namespace String {
namespace StrUtils {
void toLower(char *str) {
if (!str) return;
@ -1868,7 +1868,7 @@ private:
public:
Stream(const char *name, const void *data, int size, Callback *callback = NULL, void *userData = NULL) : callback(callback), userData(userData), f(NULL), data((char*)data), name(NULL), size(size), pos(0), buffer(NULL) {
this->name = String::copy(name);
this->name = StrUtils::copy(name);
}
Stream(const char *name, Callback *callback = NULL, void *userData = NULL) : callback(callback), userData(userData), f(NULL), data(NULL), name(NULL), size(-1), pos(0), buffer(NULL), buffering(true), baseOffset(0) {
@ -1912,13 +1912,13 @@ public:
fpos = 0;
bufferIndex = -1;
this->name = String::copy(name);
this->name = StrUtils::copy(name);
if (callback) callback(this, userData);
return;
}
}
this->name = String::copy(name);
this->name = StrUtils::copy(name);
#ifdef _OS_3DS /* TODO
if (callback) {
@ -1964,14 +1964,14 @@ public:
break;
}
int32 len = utf16_to_utf8((uint8*)buf + pathLen, entry.name, String::length(entry.name));
int32 len = utf16_to_utf8((uint8*)buf + pathLen, entry.name, StrUtils::length(entry.name));
buf[pathLen + len] = 0;
if (entry.attributes & FS_ATTRIBUTE_DIRECTORY) {
strcat(buf, "/");
readDirectory(archive, buf);
} else {
fileList.push(String::copy(buf));
fileList.push(StrUtils::copy(buf));
}
}

View File

@ -5,6 +5,10 @@
#include "texture.h"
#include "sound.h"
#ifdef _OS_TNS
#define NO_VIDEO
#endif
struct AC_ENTRY {
uint8 code;
uint8 skip;
@ -264,6 +268,9 @@ struct Video {
nextChunk(0, 0);
#ifdef NO_SOUND
audioDecoder = NULL;
#else
if (sfmt == 1)
audioDecoder = new Sound::PCM(NULL, channels, rate, 0x7FFFFF, bps); // TR2
else if (sfmt == 101) {
@ -272,6 +279,7 @@ struct Video {
else
audioDecoder = new Sound::IMA(NULL, channels, rate); // TR3
}
#endif
}
virtual ~Escape() {
@ -678,6 +686,9 @@ struct Video {
}
virtual int decode(Sound::Frame *frames, int count) {
#ifdef NO_VIDEO
return 0;
#else
if (!audioDecoder) return 0;
if (bps != 4 && abs(curAudioChunk - curVideoChunk) > 1) { // sync with video chunk, doesn't work for IMA
@ -718,6 +729,7 @@ struct Video {
}
return count;
#endif
}
};
@ -838,7 +850,11 @@ struct Video {
channels = 2;
freq = 37800;
#ifdef NO_SOUND
audioDecoder = NULL;
#else
audioDecoder = new Sound::XA(NULL);
#endif
}
virtual ~STR() {
@ -1077,6 +1093,9 @@ struct Video {
}
virtual int decode(Sound::Frame *frames, int count) {
#ifdef NO_VIDEO
return 0;
#else
if (!audioDecoder) return 0;
Sound::XA *xa = (Sound::XA*)audioDecoder;
@ -1104,6 +1123,7 @@ struct Video {
}
return count;
#endif
}
};