diff --git a/src/fixed/common.h b/src/fixed/common.h index af49687..699ba71 100644 --- a/src/fixed/common.h +++ b/src/fixed/common.h @@ -149,7 +149,7 @@ #define ALIGN16 __declspec(align(16)) #elif defined(__WATCOMC__) || defined(__3DO__) #define X_INLINE inline - #define X_NOINLINE __declspec(noinline) + #define X_NOINLINE #define ALIGN4 #define ALIGN16 #else @@ -2050,7 +2050,7 @@ struct IMA_STATE int32 idx; }; -#if defined(MODEHW) +#if defined(MODEHW) || defined(MODE13) #define PROJ_SHIFT 4 #define PERSPECTIVE_DZ(z) (z >> PROJ_SHIFT) @@ -2062,14 +2062,6 @@ struct IMA_STATE x = (x * d) >> (16 - PROJ_SHIFT);\ y = (y * d) >> (16 - PROJ_SHIFT);\ } -#elif defined(MODE13) - #define PERSPECTIVE(x, y, z) {\ - int32 dz = (z >> (FIXED_SHIFT + FOV_SHIFT - 1)) / 3;\ - if (dz >= DIV_TABLE_SIZE) dz = DIV_TABLE_SIZE - 1;\ - int32 d = FixedInvU(dz);\ - x = d * (x >> 14) >> 12;\ - y = d * (y >> 14) >> 12;\ - } #elif defined(MODE4) #define PERSPECTIVE_DZ(z) ((z >> 4) + (z >> 6)) diff --git a/src/platform/dos/DOS4GW.exe b/src/platform/dos/DOS4GW.exe new file mode 100644 index 0000000..79f04ac Binary files /dev/null and b/src/platform/dos/DOS4GW.exe differ diff --git a/src/platform/dos/deploy.bat b/src/platform/dos/deploy.bat new file mode 100644 index 0000000..c7f3f32 --- /dev/null +++ b/src/platform/dos/deploy.bat @@ -0,0 +1,4 @@ +rm *.obj *.err +copy ..\gba\render.iwram.cpp render.cpp /Y +wcl386.exe *.cpp ..\..\fixed\*.cpp -fe=OpenLara.exe -i="C:\WATCOM/h" -i="..\..\fixed" -wcd726 -w4 -e25 -zq -ox -d2 -6r -bt=dos -fo=.obj -zmf -xd -l=pmodew +C:\Dosbox\dosbox -conf dosbox.conf OpenLara.exe \ No newline at end of file diff --git a/src/platform/dos/dosbox.conf b/src/platform/dos/dosbox.conf new file mode 100644 index 0000000..2f6596d --- /dev/null +++ b/src/platform/dos/dosbox.conf @@ -0,0 +1,10 @@ +[autoexec] +@echo off +mount c: C:\Projects\OpenLara\src\platform\dos +c: + +[cpu] +cycles=fixed 26800 + +[serial] +serial1=directserial realport:COM3 \ No newline at end of file diff --git a/src/platform/dos/main.cpp b/src/platform/dos/main.cpp new file mode 100644 index 0000000..e182127 --- /dev/null +++ b/src/platform/dos/main.cpp @@ -0,0 +1,267 @@ +#include "game.h" + +EWRAM_DATA int32 fps; +EWRAM_DATA int32 frameIndex = 0; +EWRAM_DATA int32 fpsCounter = 0; +EWRAM_DATA uint32 curSoundBuffer = 0; + +const void* TRACKS_IMA; +const void* TITLE_SCR; +const void* levelData; + +#define KB_ESC 1 +#define KB_A 30 +#define KB_S 31 +#define KB_Z 44 +#define KB_X 45 +#define KB_UP 72 +#define KB_LEFT 75 +#define KB_RIGHT 77 +#define KB_DOWN 80 +#define KB_ENTER 20 +#define KB_TAB 15 + +#define DOS_ISR __interrupt __far + +#define PIT_TIMER 0x08 +#define PIT_KEYBOARD 0x09 + + +void (DOS_ISR *old_timerISR)(); +void (DOS_ISR *old_keyISR)(); + +bool keyState[128]; + +void setVideoMode(); +#pragma aux setVideoMode = \ + "mov ax,13h" \ + "int 10h"; + +void setTextMode(); +#pragma aux setTextMode = \ + "mov ax,03h" \ + "int 10h"; + +void osSetPalette(const uint16* palette) +{ + outp(0x03C8, 0); + for (int32 i = 0; i < 256; i++) + { + uint16 c = *palette++; + outp(0x03C9, (c & 0x1F) << 1); + outp(0x03C9, ((c >> 5) & 0x1F) << 1); + outp(0x03C9, ((c >> 10) & 0x1F) << 1); + } +} + +void DOS_ISR timerISR() +{ + frameIndex++; + + outp(0x20, 0x20); +} + +void videoAcquire() +{ + setVideoMode(); + + old_timerISR = _dos_getvect(PIT_TIMER); + _dos_setvect(PIT_TIMER, timerISR); + + uint32 divisor = 1193182 / 60; + outp(0x43, 0x36); + outp(0x40, divisor & 0xFF); + outp(0x40, divisor >> 8); +} + +void videoRelease() +{ + _dos_setvect(PIT_TIMER, old_timerISR); + setTextMode(); +} + +void waitVBlank() +{ + while ((inp(0x03DA) & 0x08)); + while (!(inp(0x03DA) & 0x08)); +} + +void blit() +{ + memcpy((uint8*)0xA0000, fb, VRAM_WIDTH * FRAME_HEIGHT * 2); +} + +void DOS_ISR keyISR() +{ + uint32 scancode = inp(0x60); + + if (scancode != 0xE0) { + keyState[scancode & 0x7F] = ((scancode & 0x80) == 0); + } + + outp(0x20, 0x20); +} + +void inputAcquire() +{ + old_keyISR = _dos_getvect(PIT_KEYBOARD); + _dos_setvect(PIT_KEYBOARD, keyISR); +} + +void inputRelease() +{ + _dos_setvect(PIT_KEYBOARD, old_keyISR); +} + +void inputUpdate() +{ + keys = 0; + if (keyState[KB_UP]) keys |= IK_UP; + if (keyState[KB_RIGHT]) keys |= IK_RIGHT; + if (keyState[KB_DOWN]) keys |= IK_DOWN; + if (keyState[KB_LEFT]) keys |= IK_LEFT; + if (keyState[KB_X]) keys |= IK_A; + if (keyState[KB_Z]) keys |= IK_B; + if (keyState[KB_A]) keys |= IK_L; + if (keyState[KB_S]) keys |= IK_R; + if (keyState[KB_ENTER]) keys |= IK_START; + if (keyState[KB_TAB]) keys |= IK_SELECT; +} + +int32 osGetSystemTimeMS() +{ + return 0; +} + +bool osSaveSettings() +{ + return false; +} + +bool osLoadSettings() +{ + return false; +} + +bool osCheckSave() +{ + return false; +} + +bool osSaveGame() +{ + return false; +} + +bool osLoadGame() +{ + return false; +} + +void osJoyVibrate(int32 index, int32 L, int32 R) {} + +void* osLoadLevel(const char* name) +{ + sndStop(); + +// level1 + char buf[32]; + + delete[] levelData; + + sprintf(buf, "data/%s.PKD", name); + + FILE *f = fopen(buf, "rb"); + + if (!f) + return NULL; + + { + fseek(f, 0, SEEK_END); + int32 size = ftell(f); + fseek(f, 0, SEEK_SET); + uint8* data = new uint8[size]; + fread(data, 1, size, f); + fclose(f); + + levelData = data; + } + +// tracks + if (!TRACKS_IMA) + { + FILE *f = fopen("data/TRACKS.IMA", "rb"); + if (!f) + return NULL; + + fseek(f, 0, SEEK_END); + int32 size = ftell(f); + fseek(f, 0, SEEK_SET); + uint8* data = new uint8[size]; + fread(data, 1, size, f); + fclose(f); + + TRACKS_IMA = data; + } + + if (!TITLE_SCR) + { + FILE *f = fopen("data/TITLE.SCR", "rb"); + if (!f) + return NULL; + + fseek(f, 0, SEEK_END); + int32 size = ftell(f); + fseek(f, 0, SEEK_SET); + uint8* data = new uint8[size]; + fread(data, 1, size, f); + fclose(f); + + TITLE_SCR = data; + } + + return (void*)levelData; +} + +int main(void) +{ + videoAcquire(); + inputAcquire(); + + gameInit(gLevelInfo[gLevelID].name); + + int32 lastFrameIndex = -1; + + //int extraFrame = 0; + + while (1) + { + inputUpdate(); + + if (keyState[KB_ESC]) + break; + + int32 frame = frameIndex / 2; + gameUpdate(frame - lastFrameIndex); + lastFrameIndex = frame; + + gameRender(); + + fpsCounter++; + if (frameIndex >= 60) { + frameIndex -= 60; + lastFrameIndex -= 30; + + fps = fpsCounter; + + fpsCounter = 0; + } + + blit(); + } + + inputRelease(); + videoRelease(); + + return 0; +} diff --git a/src/platform/gba/rasterizer_mode13.h b/src/platform/dos/rasterizer.h similarity index 97% rename from src/platform/gba/rasterizer_mode13.h rename to src/platform/dos/rasterizer.h index dc8e054..e83d07f 100644 --- a/src/platform/gba/rasterizer_mode13.h +++ b/src/platform/dos/rasterizer.h @@ -14,6 +14,9 @@ extern const uint8* tile; #define rasterizeFTA rasterizeFTA_c #define rasterizeGTA rasterizeGTA_c #define rasterizeSprite rasterizeSprite_c +#define rasterizeLineH rasterizeLineH_c +#define rasterizeLineV rasterizeLineV_c +#define rasterizeFillS rasterizeFillS_c void rasterizeS_c(uint16* pixel, const VertexLink* L, const VertexLink* R) { @@ -123,9 +126,9 @@ void rasterizeS_c(uint16* pixel, const VertexLink* L, const VertexLink* R) } } -void rasterizeF_c(uint16* pixel, const VertexLink* L, const VertexLink* R, int32 index) +void rasterizeF_c(uint16* pixel, const VertexLink* L, const VertexLink* R) { - uint16 color = lightmap[(L->v.g << 8) | index]; + uint16 color = lightmap[(L->v.g << 8) | L->t.t]; color |= (color << 8); int32 Lh = 0; @@ -228,13 +231,13 @@ void rasterizeF_c(uint16* pixel, const VertexLink* L, const VertexLink* R, int32 } } -void rasterizeG_c(uint16* pixel, const VertexLink* L, const VertexLink* R, int32 index) +void rasterizeG_c(uint16* pixel, const VertexLink* L, const VertexLink* R) { int32 Lh = 0, Rh = 0; int32 Lx, Rx, Ldx = 0, Rdx = 0; int32 Lg, Rg, Ldg = 0, Rdg = 0; - const uint8* ft_lightmap = lightmap + index; + const uint8* ft_lightmap = lightmap + L->t.t; while (1) { @@ -794,4 +797,19 @@ void rasterizeSprite_c(uint16* pixel, const VertexLink* L, const VertexLink* R) // TODO } +void rasterizeLineH_c(uint16* pixel, const VertexLink* L, const VertexLink* R) +{ + // TODO +} + +void rasterizeLineV_c(uint16* pixel, const VertexLink* L, const VertexLink* R) +{ + // TODO +} + +void rasterizeFillS_c(uint16* pixel, const VertexLink* L, const VertexLink* R) +{ + // TODO +} + #endif diff --git a/src/platform/dos/sound.cpp b/src/platform/dos/sound.cpp new file mode 100644 index 0000000..2512df5 --- /dev/null +++ b/src/platform/dos/sound.cpp @@ -0,0 +1,51 @@ +#include "common.h" + +void sndInit() +{ + // TODO +} + +void sndInitSamples() +{ + // TODO +} + +void sndFreeSamples() +{ + // TODO +} + +void* sndPlaySample(int32 index, int32 volume, int32 pitch, int32 mode) +{ + return NULL; // TODO +} + +void sndPlayTrack(int32 track) +{ + // TODO +} + +void sndStopTrack() +{ + // TODO +} + +bool sndTrackIsPlaying() +{ + return false; // TODO +} + +void sndStopSample(int32 index) +{ + // TODO +} + +void sndStop() +{ + // TODO +} + +void sndFill(uint8* buffer, int32 count) +{ + // TODO +} diff --git a/src/platform/gba/IMGS/O/P/OPLA.bmp b/src/platform/gba/IMGS/O/P/OPLA.bmp new file mode 100644 index 0000000..732c4a2 Binary files /dev/null and b/src/platform/gba/IMGS/O/P/OPLA.bmp differ diff --git a/src/platform/gba/Makefile b/src/platform/gba/Makefile index 7e3b792..1d9aa9b 100644 --- a/src/platform/gba/Makefile +++ b/src/platform/gba/Makefile @@ -22,7 +22,7 @@ include $(DEVKITARM)/gba_rules #--------------------------------------------------------------------------------- TARGET := OpenLara BUILD := build -SOURCES := ../../fixed . +SOURCES := ../../fixed . asm INCLUDES := include . ../../fixed DATA := data MUSIC := @@ -120,6 +120,7 @@ export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) $(BUILD): @[ -d $@ ] || mkdir -p $@ @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + gbafix $(TARGET).gba -tOpenLara -cOPLA #--------------------------------------------------------------------------------- clean: diff --git a/src/platform/gba/Makefile_tns b/src/platform/gba/Makefile_tns deleted file mode 100644 index e60cf91..0000000 --- a/src/platform/gba/Makefile_tns +++ /dev/null @@ -1,49 +0,0 @@ -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 diff --git a/src/platform/gba/OpenLara.vcxproj b/src/platform/gba/OpenLara.vcxproj index f304485..26297ce 100644 --- a/src/platform/gba/OpenLara.vcxproj +++ b/src/platform/gba/OpenLara.vcxproj @@ -38,8 +38,7 @@ - - + 15.0 diff --git a/src/platform/gba/boxIsVisible.s b/src/platform/gba/asm/boxIsVisible.s similarity index 100% rename from src/platform/gba/boxIsVisible.s rename to src/platform/gba/asm/boxIsVisible.s diff --git a/src/platform/gba/boxRotateYQ.s b/src/platform/gba/asm/boxRotateYQ.s similarity index 100% rename from src/platform/gba/boxRotateYQ.s rename to src/platform/gba/asm/boxRotateYQ.s diff --git a/src/platform/gba/boxTranslate.s b/src/platform/gba/asm/boxTranslate.s similarity index 100% rename from src/platform/gba/boxTranslate.s rename to src/platform/gba/asm/boxTranslate.s diff --git a/src/platform/gba/common_asm.inc b/src/platform/gba/asm/common_asm.inc similarity index 100% rename from src/platform/gba/common_asm.inc rename to src/platform/gba/asm/common_asm.inc diff --git a/src/platform/gba/faceAddMeshQuads.s b/src/platform/gba/asm/faceAddMeshQuads.s similarity index 100% rename from src/platform/gba/faceAddMeshQuads.s rename to src/platform/gba/asm/faceAddMeshQuads.s diff --git a/src/platform/gba/faceAddMeshTriangles.s b/src/platform/gba/asm/faceAddMeshTriangles.s similarity index 100% rename from src/platform/gba/faceAddMeshTriangles.s rename to src/platform/gba/asm/faceAddMeshTriangles.s diff --git a/src/platform/gba/faceAddRoomQuads.s b/src/platform/gba/asm/faceAddRoomQuads.s similarity index 100% rename from src/platform/gba/faceAddRoomQuads.s rename to src/platform/gba/asm/faceAddRoomQuads.s diff --git a/src/platform/gba/faceAddRoomTriangles.s b/src/platform/gba/asm/faceAddRoomTriangles.s similarity index 100% rename from src/platform/gba/faceAddRoomTriangles.s rename to src/platform/gba/asm/faceAddRoomTriangles.s diff --git a/src/platform/gba/matrixLerp.s b/src/platform/gba/asm/matrixLerp.s similarity index 100% rename from src/platform/gba/matrixLerp.s rename to src/platform/gba/asm/matrixLerp.s diff --git a/src/platform/gba/matrixPush.s b/src/platform/gba/asm/matrixPush.s similarity index 100% rename from src/platform/gba/matrixPush.s rename to src/platform/gba/asm/matrixPush.s diff --git a/src/platform/gba/matrixRotate.s b/src/platform/gba/asm/matrixRotate.s similarity index 100% rename from src/platform/gba/matrixRotate.s rename to src/platform/gba/asm/matrixRotate.s diff --git a/src/platform/gba/matrixSetBasis.s b/src/platform/gba/asm/matrixSetBasis.s similarity index 100% rename from src/platform/gba/matrixSetBasis.s rename to src/platform/gba/asm/matrixSetBasis.s diff --git a/src/platform/gba/matrixSetIdentity.s b/src/platform/gba/asm/matrixSetIdentity.s similarity index 100% rename from src/platform/gba/matrixSetIdentity.s rename to src/platform/gba/asm/matrixSetIdentity.s diff --git a/src/platform/gba/matrixTranslate.s b/src/platform/gba/asm/matrixTranslate.s similarity index 100% rename from src/platform/gba/matrixTranslate.s rename to src/platform/gba/asm/matrixTranslate.s diff --git a/src/platform/gba/rasterizeF.s b/src/platform/gba/asm/rasterizeF.s similarity index 100% rename from src/platform/gba/rasterizeF.s rename to src/platform/gba/asm/rasterizeF.s diff --git a/src/platform/gba/rasterizeFT.s b/src/platform/gba/asm/rasterizeFT.s similarity index 100% rename from src/platform/gba/rasterizeFT.s rename to src/platform/gba/asm/rasterizeFT.s diff --git a/src/platform/gba/rasterizeFTA.s b/src/platform/gba/asm/rasterizeFTA.s similarity index 100% rename from src/platform/gba/rasterizeFTA.s rename to src/platform/gba/asm/rasterizeFTA.s diff --git a/src/platform/gba/rasterizeFillS.s b/src/platform/gba/asm/rasterizeFillS.s similarity index 100% rename from src/platform/gba/rasterizeFillS.s rename to src/platform/gba/asm/rasterizeFillS.s diff --git a/src/platform/gba/rasterizeGT.s b/src/platform/gba/asm/rasterizeGT.s similarity index 100% rename from src/platform/gba/rasterizeGT.s rename to src/platform/gba/asm/rasterizeGT.s diff --git a/src/platform/gba/rasterizeGTA.s b/src/platform/gba/asm/rasterizeGTA.s similarity index 100% rename from src/platform/gba/rasterizeGTA.s rename to src/platform/gba/asm/rasterizeGTA.s diff --git a/src/platform/gba/rasterizeLineH.s b/src/platform/gba/asm/rasterizeLineH.s similarity index 98% rename from src/platform/gba/rasterizeLineH.s rename to src/platform/gba/asm/rasterizeLineH.s index fab7a0f..667b708 100644 --- a/src/platform/gba/rasterizeLineH.s +++ b/src/platform/gba/asm/rasterizeLineH.s @@ -24,7 +24,7 @@ rasterizeLineH_asm: strh tmp, [pixel], #2 subs width, #1 beq .scanline_end - + mov pc, lr .align_right: tst width, #1 beq .scanline_block_2px diff --git a/src/platform/gba/rasterizeLineV.s b/src/platform/gba/asm/rasterizeLineV.s similarity index 100% rename from src/platform/gba/rasterizeLineV.s rename to src/platform/gba/asm/rasterizeLineV.s diff --git a/src/platform/gba/rasterizeS.s b/src/platform/gba/asm/rasterizeS.s similarity index 100% rename from src/platform/gba/rasterizeS.s rename to src/platform/gba/asm/rasterizeS.s diff --git a/src/platform/gba/rasterize_dummy.s b/src/platform/gba/asm/rasterize_dummy.s similarity index 100% rename from src/platform/gba/rasterize_dummy.s rename to src/platform/gba/asm/rasterize_dummy.s diff --git a/src/platform/gba/sdiv32.s b/src/platform/gba/asm/sdiv32.s similarity index 100% rename from src/platform/gba/sdiv32.s rename to src/platform/gba/asm/sdiv32.s diff --git a/src/platform/gba/sndIMA.s b/src/platform/gba/asm/sndIMA.s similarity index 100% rename from src/platform/gba/sndIMA.s rename to src/platform/gba/asm/sndIMA.s diff --git a/src/platform/gba/sndPCM.s b/src/platform/gba/asm/sndPCM.s similarity index 100% rename from src/platform/gba/sndPCM.s rename to src/platform/gba/asm/sndPCM.s diff --git a/src/platform/gba/sndWrite.s b/src/platform/gba/asm/sndWrite.s similarity index 100% rename from src/platform/gba/sndWrite.s rename to src/platform/gba/asm/sndWrite.s diff --git a/src/platform/gba/sphereIsVisible.s b/src/platform/gba/asm/sphereIsVisible.s similarity index 100% rename from src/platform/gba/sphereIsVisible.s rename to src/platform/gba/asm/sphereIsVisible.s diff --git a/src/platform/gba/transformMesh.s b/src/platform/gba/asm/transformMesh.s similarity index 100% rename from src/platform/gba/transformMesh.s rename to src/platform/gba/asm/transformMesh.s diff --git a/src/platform/gba/transformRoom.s b/src/platform/gba/asm/transformRoom.s similarity index 100% rename from src/platform/gba/transformRoom.s rename to src/platform/gba/asm/transformRoom.s diff --git a/src/platform/gba/transformRoomUW.s b/src/platform/gba/asm/transformRoomUW.s similarity index 100% rename from src/platform/gba/transformRoomUW.s rename to src/platform/gba/asm/transformRoomUW.s diff --git a/src/platform/gba/udiv32.s b/src/platform/gba/asm/udiv32.s similarity index 100% rename from src/platform/gba/udiv32.s rename to src/platform/gba/asm/udiv32.s diff --git a/src/platform/gba/deploy_dos.bat b/src/platform/gba/deploy_dos.bat deleted file mode 100644 index e6a87f0..0000000 --- a/src/platform/gba/deploy_dos.bat +++ /dev/null @@ -1,3 +0,0 @@ -rm *.obj -wcl386.exe *.cpp -fe=OpenLara.exe -i="C:\WATCOM/h" -wcd726 -w4 -e25 -zq -ox -d2 -6r -bt=dos -fo=.obj -zmf -xd -l=pmodew -C:\Dosbox\dosbox -conf dosbox.conf OpenLara.exe \ No newline at end of file diff --git a/src/platform/gba/main.cpp b/src/platform/gba/main.cpp index 18f79fd..9aaea30 100644 --- a/src/platform/gba/main.cpp +++ b/src/platform/gba/main.cpp @@ -1,513 +1,100 @@ -#if defined(_WIN32) || defined(__DOS__) - const void* TRACKS_IMA; - const void* TITLE_SCR; - const void* levelData; -#endif - #include "game.h" EWRAM_DATA int32 fps; EWRAM_DATA int32 frameIndex = 0; EWRAM_DATA int32 fpsCounter = 0; - -#if defined(_WIN32) - uint32 SCREEN[FRAME_WIDTH * FRAME_HEIGHT]; - - HWND hWnd; - - LARGE_INTEGER g_timer; - LARGE_INTEGER g_current; - - #define WND_WIDTH 240*4 - #define WND_HEIGHT 160*4 - - uint16 MEM_PAL_BG[256]; - - void osSetPalette(const uint16* palette) - { - memcpy(MEM_PAL_BG, palette, 256 * 2); - } - - int32 osGetSystemTimeMS() - { - return GetTickCount(); - } - - bool osSaveSettings() - { - FILE* f = fopen("settings.dat", "wb"); - if (!f) return false; - fwrite(&gSettings, sizeof(gSettings), 1, f); - fclose(f); - return true; - } - - bool osLoadSettings() - { - FILE* f = fopen("settings.dat", "rb"); - if (!f) return false; - uint8 version; - fread(&version, 1, 1, f); - if (version != gSettings.version) { - fclose(f); - return false; - } - fread((uint8*)&gSettings + 1, sizeof(gSettings) - 1, 1, f); - fclose(f); - return true; - } - - bool osCheckSave() - { - FILE* f = fopen("savegame.dat", "rb"); - if (!f) return false; - fclose(f); - return true; - } - - bool osSaveGame() - { - FILE* f = fopen("savegame.dat", "wb"); - if (!f) return false; - fwrite(&gSaveGame, sizeof(gSaveGame), 1, f); - fwrite(&gSaveData, gSaveGame.dataSize, 1, f); - fclose(f); - return true; - } - - bool osLoadGame() - { - FILE* f = fopen("savegame.dat", "rb"); - if (!f) return false; - - uint32 version; - fread(&version, sizeof(version), 1, f); - - if (SAVEGAME_VER != version) - { - fclose(f); - return false; - } - - fread(&gSaveGame.dataSize, sizeof(gSaveGame) - sizeof(version), 1, f); - fread(&gSaveData, gSaveGame.dataSize, 1, f); - fclose(f); - return true; - } - - void osJoyVibrate(int32 index, int32 L, int32 R) {} - -#elif defined(__GBA__) - void osSetPalette(const uint16* palette) - { - memcpy((uint16*)MEM_PAL_BG, palette, 256 * 2); - } - - int32 osGetSystemTimeMS() - { - return 0; // TODO - } - - const uint8 SRAM_MAGIC[4] = { 14, 02, 19, 68 }; - - int32 byteCopy(volatile uint8* dst, const volatile uint8* src, uint32 count) - { - for (uint32 i = 0; i < count; i++) - { - *dst++ = *src++; - } - return count; - } - - bool checkSRAM(volatile uint8* src) - { - for (uint32 i = 0; i < sizeof(SRAM_MAGIC); i++) - { - if (SRAM_MAGIC[i] != *src++) - return false; - } - return true; - } - - bool osSaveSettings() - { - volatile uint8* ptr = (uint8*)MEM_SRAM; - - byteCopy(ptr, SRAM_MAGIC, 4); - if (!checkSRAM(ptr)) - return false; - ptr += 4; - - volatile uint8* data = (uint8*)&gSettings; - byteCopy(ptr, data, sizeof(gSettings)); - - return true; - } - - bool osLoadSettings() - { - volatile uint8* ptr = (uint8*)MEM_SRAM; - - if (!checkSRAM(ptr)) - return false; - ptr += 4; - - if (SETTINGS_VER != *ptr) - return false; - - volatile uint8* data = (uint8*)&gSettings; - byteCopy(data, ptr, sizeof(gSettings)); - - return true; - } - - bool osCheckSave() - { - volatile uint8* ptr = (uint8*)MEM_SRAM + SETTINGS_SIZE; - - if (!checkSRAM(ptr)) - return false; - ptr += 4; - - uint32 version; - byteCopy((uint8*)&version, ptr, sizeof(version)); - - return (SAVEGAME_VER == version); - } - - bool osSaveGame() - { - volatile uint8* ptr = (uint8*)MEM_SRAM + SETTINGS_SIZE; - - byteCopy(ptr, SRAM_MAGIC, 4); - if (!checkSRAM(ptr)) - return false; - - ptr += 4; - ptr += byteCopy(ptr, (uint8*)&gSaveGame, sizeof(gSaveGame)); - byteCopy(ptr, (uint8*)&gSaveData, gSaveGame.dataSize); - return true; - } - - bool osLoadGame() - { - if (!osCheckSave()) - return false; - - volatile uint8* ptr = (uint8*)MEM_SRAM + SETTINGS_SIZE + 4; // skip magic - - ptr += byteCopy((uint8*)&gSaveGame, ptr, sizeof(gSaveGame)); - byteCopy((uint8*)&gSaveData, ptr, gSaveGame.dataSize); - - return true; - } - - #define GPIO_RUMBLE_DATA (*(vu16*)0x80000C4) - #define GPIO_RUMBLE_DIRECTION (*(vu16*)0x80000C6) - #define GPIO_RUMBLE_CONTROL (*(vu16*)0x80000C8) - #define GPIO_RUMBLE_MASK (1 << 3) - - #define CART_RUMBLE_TICKS 6 - - EWRAM_DATA int32 cartRumbleTick = 0; - - void rumbleInit() - { - GPIO_RUMBLE_DIRECTION = GPIO_RUMBLE_MASK; - GPIO_RUMBLE_CONTROL = 1; - } - - void rumbleSet(bool enable) - { - if (enable) { - GPIO_RUMBLE_DATA |= GPIO_RUMBLE_MASK; - cartRumbleTick = CART_RUMBLE_TICKS; - } else { - GPIO_RUMBLE_DATA &= ~GPIO_RUMBLE_MASK; - cartRumbleTick = 0; - } - } - - void rumbleUpdate(int32 frames) - { - if (!cartRumbleTick) - return; - - cartRumbleTick -= frames; - - if (cartRumbleTick <= 0) { - rumbleSet(false); - } - } - - void osJoyVibrate(int32 index, int32 L, int32 R) - { - if (!gSettings.controls_vibration) - return; - rumbleSet(X_MAX(L, R) > 0); - } -#elif defined(__TNS__) - 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; - } - - int32 GetTickCount() - { - return (osTime - *timerCLK) / 33; - } - - int32 osGetSystemTimeMS() - { - return *timerCLK / 33; - } - - bool osSaveSettings() - { - return false; - } - - bool osLoadSettings() - { - return false; - } - - bool osCheckSave() - { - return false; - } - - bool osSaveGame() - { - return false; - } - - bool osLoadGame() - { - return false; - } - - void osJoyVibrate(int32 index, int32 L, int32 R) {} - - void osSetPalette(const uint16* palette) - { - memcpy((uint16*)0xC0000200, palette, 256 * 2); - } - - touchpad_info_t* touchInfo; - touchpad_report_t touchReport; - uint8 inputData[0x20]; - - bool keyDown(const t_key &key) - { - return (*(short*)(inputData + key.tpad_row)) & key.tpad_col; - } - - void inputInit() - { - touchInfo = is_touchpad ? touchpad_getinfo() : NULL; - } - - void inputUpdate() - { - keys = 0; - - if (touchInfo) - { - touchpad_scan(&touchReport); - } - - memcpy(inputData, (void*)0x900E0000, 0x20); - - 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; - - if (tx < -0.5f) keys |= IK_LEFT; - if (tx > 0.5f) keys |= IK_RIGHT; - if (ty > 0.5f) keys |= IK_UP; - if (ty < -0.5f) keys |= IK_DOWN]; - } - - if (keyDown(KEY_NSPIRE_2)) keys |= IK_A; - if (keyDown(KEY_NSPIRE_3)) keys |= IK_B; - if (keyDown(KEY_NSPIRE_7)) keys |= IK_L; - if (keyDown(KEY_NSPIRE_9)) keys |= IK_R; - if (keyDown(KEY_NSPIRE_ENTER)) keys |= IK_START; - if (keyDown(KEY_NSPIRE_SPACE)) keys |= IK_SELECT; - } -#elif defined(__DOS__) - #define KB_ESC 1 - #define KB_A 30 - #define KB_S 31 - #define KB_Z 44 - #define KB_X 45 - #define KB_UP 72 - #define KB_LEFT 75 - #define KB_RIGHT 77 - #define KB_DOWN 80 - #define KB_ENTER 20 - #define KB_TAB 15 - - #define DOS_ISR __interrupt __far - - #define PIT_TIMER 0x08 - #define PIT_KEYBOARD 0x09 - - - void (DOS_ISR *old_timerISR)(); - void (DOS_ISR *old_keyISR)(); - - bool keyState[128]; - - void setVideoMode(); - #pragma aux setVideoMode = \ - "mov ax,13h" \ - "int 10h"; - - void setTextMode(); - #pragma aux setTextMode = \ - "mov ax,03h" \ - "int 10h"; - - void osSetPalette(const uint16* palette) - { - outp(0x03C8, 0); - for (int32 i = 0; i < 256; i++) - { - uint16 c = *palette++; - outp(0x03C9, (c & 0x1F) << 1); - outp(0x03C9, ((c >> 5) & 0x1F) << 1); - outp(0x03C9, ((c >> 10) & 0x1F) << 1); - } - } - - void DOS_ISR timerISR() - { - frameIndex++; - - outp(0x20, 0x20); - } - - void videoAcquire() - { - setVideoMode(); - - old_timerISR = _dos_getvect(PIT_TIMER); - _dos_setvect(PIT_TIMER, timerISR); - - uint32 divisor = 1193182 / 60; - outp(0x43, 0x36); - outp(0x40, divisor & 0xFF); - outp(0x40, divisor >> 8); - } - - void videoRelease() - { - _dos_setvect(PIT_TIMER, old_timerISR); - setTextMode(); - } - - void waitVBlank() - { - while ((inp(0x03DA) & 0x08)); - while (!(inp(0x03DA) & 0x08)); - } - - void blit() - { - memcpy((uint8*)0xA0000, fb, VRAM_WIDTH * FRAME_HEIGHT * 2); - } - - void DOS_ISR keyISR() - { - uint32 scancode = inp(0x60); - - if (scancode != 0xE0) { - keyState[scancode & 0x7F] = ((scancode & 0x80) == 0); - } - - outp(0x20, 0x20); - } - - void inputAcquire() - { - old_keyISR = _dos_getvect(PIT_KEYBOARD); - _dos_setvect(PIT_KEYBOARD, keyISR); - } - - void inputRelease() - { - _dos_setvect(PIT_KEYBOARD, old_keyISR); - } - - void inputUpdate() - { - keys = 0; - if (keyState[KB_UP]) keys |= IK_UP; - if (keyState[KB_RIGHT]) keys |= IK_RIGHT; - if (keyState[KB_DOWN]) keys |= IK_DOWN; - if (keyState[KB_LEFT]) keys |= IK_LEFT; - if (keyState[KB_X]) keys |= IK_A; - if (keyState[KB_Z]) keys |= IK_B; - if (keyState[KB_A]) keys |= IK_L; - if (keyState[KB_S]) keys |= IK_R; - if (keyState[KB_ENTER]) keys |= IK_START; - if (keyState[KB_TAB]) keys |= IK_SELECT; - } - - int32 osGetSystemTimeMS() - { - return 0; - } - - bool osSaveSettings() - { - return false; - } - - bool osLoadSettings() - { - return false; - } - - bool osCheckSave() - { - return false; - } - - bool osSaveGame() - { - return false; - } - - bool osLoadGame() - { - return false; - } - - void osJoyVibrate(int32 index, int32 L, int32 R) {} -#endif - EWRAM_DATA uint32 curSoundBuffer = 0; -#if defined(_WIN32) +#ifdef _WIN32 +const void* TRACKS_IMA; +const void* TITLE_SCR; +const void* levelData; + +HWND hWnd; + +LARGE_INTEGER g_timer; +LARGE_INTEGER g_current; + +#define WND_WIDTH 240*4 +#define WND_HEIGHT 160*4 + +uint16 MEM_PAL_BG[256]; +uint32 SCREEN[FRAME_WIDTH * FRAME_HEIGHT]; + +void osSetPalette(const uint16* palette) +{ + memcpy(MEM_PAL_BG, palette, 256 * 2); +} + +int32 osGetSystemTimeMS() +{ + return GetTickCount(); +} + +bool osSaveSettings() +{ + FILE* f = fopen("settings.dat", "wb"); + if (!f) return false; + fwrite(&gSettings, sizeof(gSettings), 1, f); + fclose(f); + return true; +} + +bool osLoadSettings() +{ + FILE* f = fopen("settings.dat", "rb"); + if (!f) return false; + uint8 version; + fread(&version, 1, 1, f); + if (version != gSettings.version) { + fclose(f); + return false; + } + fread((uint8*)&gSettings + 1, sizeof(gSettings) - 1, 1, f); + fclose(f); + return true; +} + +bool osCheckSave() +{ + FILE* f = fopen("savegame.dat", "rb"); + if (!f) return false; + fclose(f); + return true; +} + +bool osSaveGame() +{ + FILE* f = fopen("savegame.dat", "wb"); + if (!f) return false; + fwrite(&gSaveGame, sizeof(gSaveGame), 1, f); + fwrite(&gSaveData, gSaveGame.dataSize, 1, f); + fclose(f); + return true; +} + +bool osLoadGame() +{ + FILE* f = fopen("savegame.dat", "rb"); + if (!f) return false; + + uint32 version; + fread(&version, sizeof(version), 1, f); + + if (SAVEGAME_VER != version) + { + fclose(f); + return false; + } + + fread(&gSaveGame.dataSize, sizeof(gSaveGame) - sizeof(version), 1, f); + fread(&gSaveData, gSaveGame.dataSize, 1, f); + fclose(f); + return true; +} + +void osJoyVibrate(int32 index, int32 L, int32 R) {} + extern uint8 soundBuffer[2 * SND_SAMPLES + 32]; // 32 bytes of silence for DMA overrun while interrupt HWAVEOUT waveOut; @@ -541,34 +128,7 @@ void soundFill() waveOutWrite(waveOut, waveHdr, sizeof(WAVEHDR)); curSoundBuffer ^= 1; } -#elif defined(__GBA__) -extern uint8* soundBuffer; -void soundInit() -{ - sndInit(); - - REG_SOUNDCNT_X = SSTAT_ENABLE; - REG_SOUNDCNT_H = SDS_ATMR0 | SDS_AL | SDS_AR | SDS_ARESET | SDS_A100; - REG_TM0D = 65536 - (16777216 / SND_OUTPUT_FREQ); - REG_TM0CNT = TM_ENABLE; - REG_DMA1DAD = (u32)®_FIFO_A; -} - -void soundFill() -{ - if (curSoundBuffer == 1) { - REG_DMA1CNT = 0; - REG_DMA1SAD = (u32)soundBuffer; - REG_DMA1CNT = DMA_DST_FIXED | DMA_REPEAT | DMA_16 | DMA_AT_FIFO | DMA_ENABLE; - } - - sndFill(soundBuffer + curSoundBuffer * SND_SAMPLES, SND_SAMPLES); - curSoundBuffer ^= 1; -} -#endif - -#if defined(_WIN32) HDC hDC; void blit() @@ -642,9 +202,304 @@ LRESULT CALLBACK wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) return 0; } -#elif defined(__GBA__) +void* osLoadLevel(const char* name) +{ + // level1 + char buf[32]; -void vblank() { + delete[] levelData; + + sprintf(buf, "data/%s.PKD", name); + + FILE *f = fopen(buf, "rb"); + + if (!f) + return NULL; + + { + fseek(f, 0, SEEK_END); + int32 size = ftell(f); + fseek(f, 0, SEEK_SET); + uint8* data = new uint8[size]; + fread(data, 1, size, f); + fclose(f); + + levelData = data; + } + +// tracks + if (!TRACKS_IMA) + { + FILE *f = fopen("data/TRACKS.IMA", "rb"); + if (!f) + return NULL; + + fseek(f, 0, SEEK_END); + int32 size = ftell(f); + fseek(f, 0, SEEK_SET); + uint8* data = new uint8[size]; + fread(data, 1, size, f); + fclose(f); + + TRACKS_IMA = data; + } + + if (!TITLE_SCR) + { + FILE *f = fopen("data/TITLE.SCR", "rb"); + if (!f) + return NULL; + + fseek(f, 0, SEEK_END); + int32 size = ftell(f); + fseek(f, 0, SEEK_SET); + uint8* data = new uint8[size]; + fread(data, 1, size, f); + fclose(f); + + TITLE_SCR = data; + } + + return (void*)levelData; +} + +int main(void) +{ + RECT r = { 0, 0, WND_WIDTH, WND_HEIGHT }; + + AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, false); + int wx = (GetSystemMetrics(SM_CXSCREEN) - (r.right - r.left)) / 2; + int wy = (GetSystemMetrics(SM_CYSCREEN) - (r.bottom - r.top)) / 2; + + hWnd = CreateWindow("static", "OpenLara GBA", WS_OVERLAPPEDWINDOW, wx + r.left, wy + r.top, r.right - r.left, r.bottom - r.top, 0, 0, 0, 0); + hDC = GetDC(hWnd); + + SetWindowLong(hWnd, GWL_WNDPROC, (LONG)&wndProc); + ShowWindow(hWnd, SW_SHOWDEFAULT); + + soundInit(); + + gameInit(gLevelInfo[gLevelID].name); + + MSG msg; + + int32 startTime = GetTickCount() - 33; + int32 lastFrame = 0; + + do { + if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } else { + int32 frame = (GetTickCount() - startTime) / 33; + if (GetAsyncKeyState('R')) frame /= 10; + + int32 count = frame - lastFrame; + if (GetAsyncKeyState('T')) count *= 10; + gameUpdate(count); + lastFrame = frame; + + gameRender(); + + blit(); + } + } while (msg.message != WM_QUIT); + + return 0; +} +#else +void osSetPalette(const uint16* palette) +{ + memcpy((uint16*)MEM_PAL_BG, palette, 256 * 2); +} + +int32 osGetSystemTimeMS() +{ + return 0; // TODO +} + +const uint8 SRAM_MAGIC[4] = { 14, 02, 19, 68 }; + +int32 byteCopy(volatile uint8* dst, const volatile uint8* src, uint32 count) +{ + for (uint32 i = 0; i < count; i++) + { + *dst++ = *src++; + } + return count; +} + +bool checkSRAM(volatile uint8* src) +{ + for (uint32 i = 0; i < sizeof(SRAM_MAGIC); i++) + { + if (SRAM_MAGIC[i] != *src++) + return false; + } + return true; +} + +bool osSaveSettings() +{ + volatile uint8* ptr = (uint8*)MEM_SRAM; + + byteCopy(ptr, SRAM_MAGIC, 4); + if (!checkSRAM(ptr)) + return false; + ptr += 4; + + volatile uint8* data = (uint8*)&gSettings; + byteCopy(ptr, data, sizeof(gSettings)); + + return true; +} + +bool osLoadSettings() +{ + volatile uint8* ptr = (uint8*)MEM_SRAM; + + if (!checkSRAM(ptr)) + return false; + ptr += 4; + + if (SETTINGS_VER != *ptr) + return false; + + volatile uint8* data = (uint8*)&gSettings; + byteCopy(data, ptr, sizeof(gSettings)); + + return true; +} + +bool osCheckSave() +{ + volatile uint8* ptr = (uint8*)MEM_SRAM + SETTINGS_SIZE; + + if (!checkSRAM(ptr)) + return false; + ptr += 4; + + uint32 version; + byteCopy((uint8*)&version, ptr, sizeof(version)); + + return (SAVEGAME_VER == version); +} + +bool osSaveGame() +{ + volatile uint8* ptr = (uint8*)MEM_SRAM + SETTINGS_SIZE; + + byteCopy(ptr, SRAM_MAGIC, 4); + if (!checkSRAM(ptr)) + return false; + + ptr += 4; + ptr += byteCopy(ptr, (uint8*)&gSaveGame, sizeof(gSaveGame)); + byteCopy(ptr, (uint8*)&gSaveData, gSaveGame.dataSize); + return true; +} + +bool osLoadGame() +{ + if (!osCheckSave()) + return false; + + volatile uint8* ptr = (uint8*)MEM_SRAM + SETTINGS_SIZE + 4; // skip magic + + ptr += byteCopy((uint8*)&gSaveGame, ptr, sizeof(gSaveGame)); + byteCopy((uint8*)&gSaveData, ptr, gSaveGame.dataSize); + + return true; +} + +#define GPIO_RUMBLE_DATA (*(vu16*)0x80000C4) +#define GPIO_RUMBLE_DIRECTION (*(vu16*)0x80000C6) +#define GPIO_RUMBLE_CONTROL (*(vu16*)0x80000C8) +#define GPIO_RUMBLE_MASK (1 << 3) + +#define CART_RUMBLE_TICKS 6 + +EWRAM_DATA int32 cartRumbleTick = 0; + +void rumbleInit() +{ + GPIO_RUMBLE_DIRECTION = GPIO_RUMBLE_MASK; + GPIO_RUMBLE_CONTROL = 1; +} + +void rumbleSet(bool enable) +{ + if (enable) { + GPIO_RUMBLE_DATA |= GPIO_RUMBLE_MASK; + cartRumbleTick = CART_RUMBLE_TICKS; + } else { + GPIO_RUMBLE_DATA &= ~GPIO_RUMBLE_MASK; + cartRumbleTick = 0; + } +} + +void rumbleUpdate(int32 frames) +{ + if (!cartRumbleTick) + return; + + cartRumbleTick -= frames; + + if (cartRumbleTick <= 0) { + rumbleSet(false); + } +} + +void osJoyVibrate(int32 index, int32 L, int32 R) +{ + if (!gSettings.controls_vibration) + return; + rumbleSet(X_MAX(L, R) > 0); +} + +void updateInput() +{ + keys = 0; + key_poll(); + if (key_is_down(KEY_UP)) keys |= IK_UP; + if (key_is_down(KEY_RIGHT)) keys |= IK_RIGHT; + if (key_is_down(KEY_DOWN)) keys |= IK_DOWN; + if (key_is_down(KEY_LEFT)) keys |= IK_LEFT; + if (key_is_down(KEY_A)) keys |= IK_A; + if (key_is_down(KEY_B)) keys |= IK_B; + if (key_is_down(KEY_L)) keys |= IK_L; + if (key_is_down(KEY_R)) keys |= IK_R; + if (key_is_down(KEY_START)) keys |= IK_START; + if (key_is_down(KEY_SELECT)) keys |= IK_SELECT; +} + +extern uint8* soundBuffer; + +void soundInit() +{ + sndInit(); + + REG_SOUNDCNT_X = SSTAT_ENABLE; + REG_SOUNDCNT_H = SDS_ATMR0 | SDS_AL | SDS_AR | SDS_ARESET | SDS_A100; + REG_TM0D = 65536 - (16777216 / SND_OUTPUT_FREQ); + REG_TM0CNT = TM_ENABLE; + REG_DMA1DAD = (u32)®_FIFO_A; +} + +void soundFill() +{ + if (curSoundBuffer == 1) { + REG_DMA1CNT = 0; + REG_DMA1SAD = (u32)soundBuffer; + REG_DMA1CNT = DMA_DST_FIXED | DMA_REPEAT | DMA_16 | DMA_AT_FIFO | DMA_ENABLE; + } + + sndFill(soundBuffer + curSoundBuffer * SND_SAMPLES, SND_SAMPLES); + curSoundBuffer ^= 1; +} + +void vblank() +{ frameIndex++; soundFill(); } @@ -691,81 +546,8 @@ void boostEWRAM() } } -#endif - void* osLoadLevel(const char* name) { - sndStop(); - -#if defined(_WIN32) || defined(__TNS__) || defined(__DOS__) - { - // level1 - char buf[32]; - - delete[] levelData; - - #if defined(_WIN32) || defined(__DOS__) - sprintf(buf, "data/%s.PKD", name); - #elif defined(__TNS__) - sprintf(buf, "/documents/OpenLara/%s.PKD.tns", name); - #else - #error - #endif - - FILE *f = fopen(buf, "rb"); - - if (!f) - return NULL; - - { - fseek(f, 0, SEEK_END); - int32 size = ftell(f); - fseek(f, 0, SEEK_SET); - uint8* data = new uint8[size]; - fread(data, 1, size, f); - fclose(f); - - levelData = data; - } - - // track 13 - #if defined(_WIN32) || defined(__DOS__) - if (!TRACKS_IMA) - { - FILE *f = fopen("data/TRACKS.IMA", "rb"); - if (!f) - return NULL; - - fseek(f, 0, SEEK_END); - int32 size = ftell(f); - fseek(f, 0, SEEK_SET); - uint8* data = new uint8[size]; - fread(data, 1, size, f); - fclose(f); - - TRACKS_IMA = data; - } - - if (!TITLE_SCR) - { - FILE *f = fopen("data/TITLE.SCR", "rb"); - if (!f) - return NULL; - - fseek(f, 0, SEEK_END); - int32 size = ftell(f); - fseek(f, 0, SEEK_SET); - uint8* data = new uint8[size]; - fread(data, 1, size, f); - fclose(f); - - TITLE_SCR = data; - } - #endif - } - - return (void*)levelData; -#elif defined(__GBA__) for (int32 i = 0; i < LVL_MAX; i++) { if (strcmp(name, gLevelInfo[i].name) == 0) @@ -774,52 +556,10 @@ void* osLoadLevel(const char* name) gLevelID = LVL_TR1_TITLE; return (void*)gLevelInfo[gLevelID].data; -#endif } -int main(void) { -#if defined(_WIN32) - RECT r = { 0, 0, WND_WIDTH, WND_HEIGHT }; - - AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, false); - int wx = (GetSystemMetrics(SM_CXSCREEN) - (r.right - r.left)) / 2; - int wy = (GetSystemMetrics(SM_CYSCREEN) - (r.bottom - r.top)) / 2; - - hWnd = CreateWindow("static", "OpenLara GBA", WS_OVERLAPPEDWINDOW, wx + r.left, wy + r.top, r.right - r.left, r.bottom - r.top, 0, 0, 0, 0); - hDC = GetDC(hWnd); - - SetWindowLong(hWnd, GWL_WNDPROC, (LONG)&wndProc); - ShowWindow(hWnd, SW_SHOWDEFAULT); - - soundInit(); - - gameInit(gLevelInfo[gLevelID].name); - - MSG msg; - - int32 startTime = GetTickCount() - 33; - int32 lastFrame = 0; - - do { - if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } else { - int32 frame = (GetTickCount() - startTime) / 33; - if (GetAsyncKeyState('R')) frame /= 10; - - int32 count = frame - lastFrame; - if (GetAsyncKeyState('T')) count *= 10; - gameUpdate(count); - lastFrame = frame; - - gameRender(); - - blit(); - } - } while (msg.message != WM_QUIT); - -#elif defined(__GBA__) +int main(void) +{ if (intptr_t(divTable) != MEM_EWRAM) return 0; if (intptr_t(lightmap) != MEM_IWRAM) return 0; @@ -841,33 +581,17 @@ int main(void) { while (1) { - { // input - keys = 0; - key_poll(); - if (key_is_down(KEY_UP)) keys |= IK_UP; - if (key_is_down(KEY_RIGHT)) keys |= IK_RIGHT; - if (key_is_down(KEY_DOWN)) keys |= IK_DOWN; - if (key_is_down(KEY_LEFT)) keys |= IK_LEFT; - if (key_is_down(KEY_A)) keys |= IK_A; - if (key_is_down(KEY_B)) keys |= IK_B; - if (key_is_down(KEY_L)) keys |= IK_L; - if (key_is_down(KEY_R)) keys |= IK_R; - if (key_is_down(KEY_START)) keys |= IK_START; - if (key_is_down(KEY_SELECT)) keys |= IK_SELECT; - } - + updateInput(); int32 frame = frameIndex / 2; int32 delta = frame - lastFrameIndex; - if (!delta) { + if (!delta) continue; - } + lastFrameIndex = frame; rumbleUpdate(delta); - lastFrameIndex = frame; - gameUpdate(delta); #ifdef PROFILING @@ -879,7 +603,8 @@ int main(void) { gameRender(); fpsCounter++; - if (frameIndex >= 60) { + if (frameIndex >= 60) + { frameIndex -= 60; lastFrameIndex -= 30; @@ -888,85 +613,7 @@ int main(void) { fpsCounter = 0; } } -#elif defined(__TNS__) - if (!has_colors) - return 0; - lcd_init(SCR_320x240_8); - - timerInit(); - inputInit(); - - gameInit(gLevelInfo[gLevelID].name); - - int startTime = GetTickCount(); - int lastTime = -16; - int fpsTime = startTime; - - while (1) - { - inputUpdate(); - - if (keyDown(KEY_NSPIRE_ESC)) - { - break; - } - - int time = GetTickCount() - startTime; - gameUpdate((time - lastTime) / 16); - lastTime = time; - - gameRender(); - - lcd_blit(fb, SCR_320x240_8); - //msleep(16); - - fpsCounter++; - if (lastTime - fpsTime >= 1000) - { - fps = fpsCounter; - fpsCounter = 0; - fpsTime = lastTime - ((lastTime - fpsTime) - 1000); - } - } -#elif defined(__DOS__) - videoAcquire(); - inputAcquire(); - - gameInit(gLevelInfo[gLevelID].name); - - int32 lastFrameIndex = -1; - - //int extraFrame = 0; - - while (1) - { - inputUpdate(); - - if (keyState[KB_ESC]) - break; - - int32 frame = frameIndex / 2; - gameUpdate(frame - lastFrameIndex); - lastFrameIndex = frame; - - gameRender(); - - fpsCounter++; - if (frameIndex >= 60) { - frameIndex -= 60; - lastFrameIndex -= 30; - - fps = fpsCounter; - - fpsCounter = 0; - } - - blit(); - } - - inputRelease(); - videoRelease(); -#endif return 0; } +#endif diff --git a/src/platform/gba/rasterizer_mode4.h b/src/platform/gba/rasterizer.h similarity index 100% rename from src/platform/gba/rasterizer_mode4.h rename to src/platform/gba/rasterizer.h diff --git a/src/platform/gba/render.iwram.cpp b/src/platform/gba/render.iwram.cpp index dd4b9eb..719cbd2 100644 --- a/src/platform/gba/render.iwram.cpp +++ b/src/platform/gba/render.iwram.cpp @@ -60,13 +60,7 @@ enum FaceType { #define ALIGNED_LIGHTMAP #endif -#if defined(MODE4) - #include "rasterizer_mode4.h" -#elif defined(MODE13) - #include "rasterizer_mode13.h" -#else - #error no supported video mode set -#endif +#include "rasterizer.h" extern uint8 lightmap[256 * 32]; extern Level level; @@ -507,16 +501,15 @@ bool transformBoxRect(const AABBs* box, RectMinMax* rect) if ((m.e23 < VIEW_MIN_F) || (m.e23 >= VIEW_MAX_F)) return false; - const vec3i v[8] = { - _vec3i( box->minX, box->minY, box->minZ ), - _vec3i( box->maxX, box->minY, box->minZ ), - _vec3i( box->minX, box->maxY, box->minZ ), - _vec3i( box->maxX, box->maxY, box->minZ ), - _vec3i( box->minX, box->minY, box->maxZ ), - _vec3i( box->maxX, box->minY, box->maxZ ), - _vec3i( box->minX, box->maxY, box->maxZ ), - _vec3i( box->maxX, box->maxY, box->maxZ ) - }; + vec3i v[8]; + v[0] = _vec3i( box->minX, box->minY, box->minZ ), + v[1] = _vec3i( box->maxX, box->minY, box->minZ ), + v[2] = _vec3i( box->minX, box->maxY, box->minZ ), + v[3] = _vec3i( box->maxX, box->maxY, box->minZ ), + v[4] = _vec3i( box->minX, box->minY, box->maxZ ), + v[5] = _vec3i( box->maxX, box->minY, box->maxZ ), + v[6] = _vec3i( box->minX, box->maxY, box->maxZ ), + v[7] = _vec3i( box->maxX, box->maxY, box->maxZ ); *rect = RectMinMax( INT_MAX, INT_MAX, INT_MIN, INT_MIN ); @@ -1112,6 +1105,8 @@ X_NOINLINE void renderLine(int32 x, int32 y, int32 width, int32 height, int32 in } ASSERT(width == 1 || height == 1); + ASSERT(width > 0); + ASSERT(height > 0); gVerticesBase[0].x = x; gVerticesBase[0].y = y; @@ -1120,10 +1115,12 @@ X_NOINLINE void renderLine(int32 x, int32 y, int32 width, int32 height, int32 in gVerticesBase[1].x = width; gVerticesBase[1].y = height; + int32 idx = gVerticesBase - gVertices; + Face* f = faceAdd(z); f->flags = (height == 1) ? (FACE_TYPE_LINE_H << FACE_TYPE_SHIFT) : (FACE_TYPE_LINE_V << FACE_TYPE_SHIFT); - f->indices[0] = gVerticesBase - gVertices; - f->indices[1] = f->indices[0] + 1; + f->indices[0] = idx; + f->indices[1] = idx + 1; gVerticesBase += 2; } @@ -1294,9 +1291,12 @@ void renderBar(int32 x, int32 y, int32 width, int32 value, BarType type) int32 iy = y + 2; int32 w = value * width >> 8; - for (int32 i = 0; i < 5; i++) + if (w > 0) { - renderLine(ix, iy++, w, 1, BAR_COLORS[type][i], 0); + for (int32 i = 0; i < 5; i++) + { + renderLine(ix, iy++, w, 1, BAR_COLORS[type][i], 0); + } } renderBorder(x, y, width + 4, BAR_HEIGHT + 4, 27, 19, 17, 0); diff --git a/src/platform/tns/Makefile b/src/platform/tns/Makefile index b4b9d14..df8aa6f 100644 --- a/src/platform/tns/Makefile +++ b/src/platform/tns/Makefile @@ -6,7 +6,7 @@ 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../../ +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" @@ -18,7 +18,7 @@ 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)) +OBJS += $(patsubst %.s, %.o, $(shell find . -name \*.s)) EXE = OpenLara DISTDIR = . vpath %.tns $(DISTDIR) @@ -32,10 +32,11 @@ all: $(EXE).prg.tns %.o: %.cpp $(GXX) $(GCCFLAGS) -c $< -%.o: %.S +%.o: %.s $(AS) -c $< $(EXE).elf: $(OBJS) + copy ../gba/render.iwram.cpp render.cpp /Y mkdir -p $(DISTDIR) $(LD) $^ -o $(DISTDIR)/$@ $(LDFLAGS) diff --git a/src/platform/tns/main.cpp b/src/platform/tns/main.cpp index 61fa789..879b66e 100644 --- a/src/platform/tns/main.cpp +++ b/src/platform/tns/main.cpp @@ -1,15 +1,16 @@ -#include +#if defined(_WIN32) || defined(__DOS__) + const void* TRACKS_IMA; + const void* TITLE_SCR; + const void* levelData; +#endif -#include +#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) {} +int32 fps; +int32 frameIndex = 0; +int32 fpsCounter = 0; +uint32 curSoundBuffer = 0; - -// timing unsigned int osTime; volatile unsigned int *timerBUS; volatile unsigned int *timerCLK; @@ -22,76 +23,126 @@ void timerInit() timerCLK = (unsigned int*)0x900C0004; timerCTR = (unsigned int*)0x900C0008; timerDIV = (unsigned int*)0x900C0080; - + *timerBUS &= ~(1 << 11); *timerDIV = 0x0A; *timerCTR = 0x82; - + osTime = *timerCLK; } -int osGetTimeMS() +int32 GetTickCount() { return (osTime - *timerCLK) / 33; } +int32 osGetSystemTimeMS() +{ + return *timerCLK / 33; +} + +bool osSaveSettings() +{ + return false; +} + +bool osLoadSettings() +{ + return false; +} + +bool osCheckSave() +{ + return false; +} + +bool osSaveGame() +{ + return false; +} + +bool osLoadGame() +{ + return false; +} + +void osJoyVibrate(int32 index, int32 L, int32 R) {} + +void osSetPalette(const uint16* palette) +{ + memcpy((uint16*)0xC0000200, palette, 256 * 2); +} -// input touchpad_info_t* touchInfo; touchpad_report_t touchReport; +uint8 inputData[0x20]; -void touchInit() +bool keyDown(const t_key &key) +{ + return (*(short*)(inputData + key.tpad_row)) & key.tpad_col; +} + +void inputInit() { touchInfo = is_touchpad ? touchpad_getinfo() : NULL; } -bool osJoyReady(int index) +void inputUpdate() { - return (index == 0); -} + keys = 0; -void osJoyVibrate(int index, float L, float R) {} - -bool inputUpdate() -{ - 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)); - } } - - uint8 inputData[0x20]; + memcpy(inputData, (void*)0x900E0000, 0x20); - #define IS_KEY_DOWN(key) ((*(short*)(inputData + key.tpad_row)) & key.tpad_col) + 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; - 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, IS_KEY_DOWN(KEY_NSPIRE_ENTER)); - Input::setJoyDown(0, jkSelect, IS_KEY_DOWN(KEY_NSPIRE_MENU)); + if (tx < -0.5f) keys |= IK_LEFT; + if (tx > 0.5f) keys |= IK_RIGHT; + if (ty > 0.5f) keys |= IK_UP; + if (ty < -0.5f) keys |= IK_DOWN]; + } - return !IS_KEY_DOWN(KEY_NSPIRE_ESC); + if (keyDown(KEY_NSPIRE_2)) keys |= IK_A; + if (keyDown(KEY_NSPIRE_3)) keys |= IK_B; + if (keyDown(KEY_NSPIRE_7)) keys |= IK_L; + if (keyDown(KEY_NSPIRE_9)) keys |= IK_R; + if (keyDown(KEY_NSPIRE_ENTER)) keys |= IK_START; + if (keyDown(KEY_NSPIRE_SPACE)) keys |= IK_SELECT; } -unsigned short* osPalette() +void* osLoadLevel(const char* name) { - return (unsigned short*)0xC0000200; +// level1 + char buf[32]; + + delete[] levelData; + + sprintf(buf, "/documents/OpenLara/%s.PKD.tns", name); + + FILE *f = fopen(buf, "rb"); + + if (!f) + return NULL; + + { + fseek(f, 0, SEEK_END); + int32 size = ftell(f); + fseek(f, 0, SEEK_SET); + uint8* data = new uint8[size]; + fread(data, 1, size, f); + fclose(f); + + levelData = data; + } + + return (void*)levelData; } int main(void) @@ -99,47 +150,43 @@ int main(void) if (!has_colors) return 0; - lcd_init(SCR_320x240_565); + lcd_init(SCR_320x240_8); timerInit(); - touchInit(); + inputInit(); - contentDir[0] = saveDir[0] = cacheDir[0] = 0; + gameInit(gLevelInfo[gLevelID].name); - strcpy(contentDir, "/documents/Games/OpenLara/"); - strcpy(saveDir, contentDir); - strcpy(cacheDir, contentDir); + int startTime = GetTickCount(); + int lastTime = -16; + int fpsTime = startTime; - Stream::addPack("content.tns"); - - Core::width = SCREEN_WIDTH; - Core::height = SCREEN_HEIGHT; - - GAPI::swColor = new GAPI::ColorSW[Core::width * Core::height]; - GAPI::resize(); - - Sound::channelsCount = 0; - - Game::init("DATA/LEVEL1.PHD"); - - while (!Core::isQuit) + while (1) { - if (!inputUpdate()) + inputUpdate(); + + if (keyDown(KEY_NSPIRE_ESC)) { - Core::quit(); + break; } - if (Game::update()) + int time = GetTickCount() - startTime; + gameUpdate((time - lastTime) / 16); + lastTime = time; + + gameRender(); + + lcd_blit(fb, SCR_320x240_8); + //msleep(16); + + fpsCounter++; + if (lastTime - fpsTime >= 1000) { - Game::render(); - - lcd_blit(GAPI::swColor, SCR_320x240_565); + fps = fpsCounter; + fpsCounter = 0; + fpsTime = lastTime - ((lastTime - fpsTime) - 1000); } } - delete[] GAPI::swColor; - - //Game::deinit(); - return 0; } diff --git a/src/platform/tns/sound.cpp b/src/platform/tns/sound.cpp new file mode 100644 index 0000000..2512df5 --- /dev/null +++ b/src/platform/tns/sound.cpp @@ -0,0 +1,51 @@ +#include "common.h" + +void sndInit() +{ + // TODO +} + +void sndInitSamples() +{ + // TODO +} + +void sndFreeSamples() +{ + // TODO +} + +void* sndPlaySample(int32 index, int32 volume, int32 pitch, int32 mode) +{ + return NULL; // TODO +} + +void sndPlayTrack(int32 track) +{ + // TODO +} + +void sndStopTrack() +{ + // TODO +} + +bool sndTrackIsPlaying() +{ + return false; // TODO +} + +void sndStopSample(int32 index) +{ + // TODO +} + +void sndStop() +{ + // TODO +} + +void sndFill(uint8* buffer, int32 count) +{ + // TODO +}