Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,49 @@ jobs:
name: roller-${{ matrix.os }}-${{ matrix.arch }}
path: roller-${{ matrix.os }}-${{ matrix.arch }}.*
retention-days: 7

android:
name: Build Android APK
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
submodules: recursive

- name: Setup mise
uses: jdx/mise-action@v4
with:
install: true
experimental: true
cache: true

- name: Setup Java
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: "17"

- name: Setup Android SDK
uses: android-actions/setup-android@v3

- name: Install Android SDK packages
run: |
sdkmanager "platforms;android-36" "build-tools;36.0.0" "ndk;27.2.12479018"
echo "sdk.dir=$ANDROID_HOME" > android/local.properties

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-version: 8.7

- name: Build debug APK
run: gradle -p android assembleDebug --no-daemon

- name: Upload Android APK
uses: actions/upload-artifact@v7
with:
name: roller-android-debug
path: android/app/build/outputs/apk/debug/app-debug.apk
retention-days: 7
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,17 @@ fatdata
zig-out/
.zig-cache/

# Android build artifacts
.idea/
android/local.properties
android/.gradle/
android/build/
android/app/build/
android/app/src/main/jniLibs/
*.apk
*.ap_
*.aab

# Shadercross tool (build locally, not portable)
tools/shadercross/lib/
tools/shadercross/zig-out/
Expand Down
109 changes: 75 additions & 34 deletions PROJECTS/ROLLER/3d.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include "snapshot_scenes.h"
#include "rollerinput.h"
#include <SDL3/SDL.h>
#if defined(IS_ANDROID)
#include <SDL3/SDL_main.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
Expand Down Expand Up @@ -1625,27 +1628,48 @@ void race_update(void)
initsoundlag(0);
lagdone = -1;
}
if (screenready && !fadedin) // Start race timing only once the race view is visible
{
game_render_begin_fade(g_pGameRenderer, 1, 0);
fadedin = -1;
holdmusic = 0;
SDL_SetAtomicInt(&iTicksPending, 0);
if (w95) { // Start appropriate music track (title song for replay, game track for race)
if (!MusicCD && !winner_mode && !loading_replay) {
if (replaytype == 2)
iSong = titlesong;
else if (game_track == TRACK_LOAD_COMMUNITY && nummusictracks > 0)
iSong = rand() % nummusictracks + 1;
else
iSong = game_track;
startmusic(iSong);
}
}
}
updates = 0;
if (g_bSnapshotMode) {
// No SDL tick timer in snapshot mode: drive one logical tick per
// iteration with no wall-clock pacing, and zero scrbuf so any
// unredrawn region cannot leak from the previous frame.
SnapshotZeroScreen();
SnapshotAdvanceTick();
}
// Cap drained ticks per frame to prevent spiral-of-death: if a slow frame
// backs up iTicksPending, catching up burns main-thread time and starves
// the next render, which backs up more ticks, and so on.
int iDrained = 0;
while (iDrained < 4 && (iPendingTicks = SDL_GetAtomicInt(&iTicksPending)) != 0) {
// Claim one pending tick with CAS. The timer thread can enqueue between
// this read and update, so a plain read/add pair can race, especially
// when replay rewind changes the pending count's sign.
int iNextPendingTicks = iPendingTicks > 0 ? iPendingTicks - 1 : iPendingTicks + 1;
if (!SDL_CompareAndSwapAtomicInt(&iTicksPending, iPendingTicks, iNextPendingTicks))
continue;
game_tick_step();
++iDrained;
} else if (fadedin || replaytype == 2) {
// Cap drained ticks per frame to prevent spiral-of-death: if a slow frame
// backs up iTicksPending, catching up burns main-thread time and starves
// the next render, which backs up more ticks, and so on.
int iDrained = 0;
while (iDrained < 4 && (iPendingTicks = SDL_GetAtomicInt(&iTicksPending)) != 0) {
// Claim one pending tick with CAS. The timer thread can enqueue between
// this read and update, so a plain read/add pair can race, especially
// when replay rewind changes the pending count's sign.
int iNextPendingTicks = iPendingTicks > 0 ? iPendingTicks - 1 : iPendingTicks + 1;
if (!SDL_CompareAndSwapAtomicInt(&iTicksPending, iPendingTicks, iNextPendingTicks))
continue;
game_tick_step();
++iDrained;
}
} else {
SDL_SetAtomicInt(&iTicksPending, 0);
}
if (replaytype == 2 && !frontend_on && ticks != currentreplayframe)
game_tick_step();
Expand Down Expand Up @@ -1792,25 +1816,6 @@ void race_update(void)
} else if (forwarding) {
slowing = -1;
}
if (screenready) // Handle screen fade-in and music startup
{
if (!fadedin) {
game_render_begin_fade(g_pGameRenderer, 1, 0);
fadedin = -1;
holdmusic = 0;
if (w95) { // Start appropriate music track (title song for replay, game track for race)
if (!MusicCD && !winner_mode && !loading_replay) {
if (replaytype == 2)
iSong = titlesong;
else if (game_track == TRACK_LOAD_COMMUNITY && nummusictracks > 0)
iSong = rand() % nummusictracks + 1;
else
iSong = game_track;
startmusic(iSong);
}
}
}
}
//NOCD error disabled for ROLLER
//if (!intro && replaytype != 2) // Handle CD-ROM validation for copy protection
//{
Expand Down Expand Up @@ -2107,6 +2112,22 @@ void *trybuffer(uint32 uiSize)
return pBuf;
}

//-------------------------------------------------------------------------------------------------
//00010890 helper
uint32 getbuffer_size(void *pData)
{
int iMemBlocksIdx;

if (!pData)
return 0;

iMemBlocksIdx = find_mem_block(pData);
if (iMemBlocksIdx < 0)
return 0;

return mem_blocks[iMemBlocksIdx].uiSize;
}

//-------------------------------------------------------------------------------------------------
//000109F0
void fre(void **ppData)
Expand Down Expand Up @@ -2607,6 +2628,14 @@ void draw_road(uint8 *pScrPtr, int iCarIdx, unsigned int uiViewMode, int iCopyIm

//-------------------------------------------------------------------------------------------------
//00011930
#if defined(IS_ANDROID)
int main(int argc, const char **argv, const char **envp);
int SDL_main(int argc, char *argv[])
{
return main(argc, (const char **)argv, NULL);
}
#endif

int main(int argc, const char **argv, const char **envp)
{
int consumed = 0;
Expand Down Expand Up @@ -2749,6 +2778,18 @@ int main(int argc, const char **argv, const char **envp)
i += consumed;
}

#if defined(IS_ANDROID)
if (!whiplash_root[0]) {
const char *szExt = SDL_GetAndroidExternalStoragePath();
if (!szExt) {
ErrorBoxExit("External storage is not available. Cannot locate game data.");
return 1;
}
strncpy(whiplash_root, szExt, sizeof(whiplash_root) - 1);
whiplash_root[sizeof(whiplash_root) - 1] = '\0';
}
#endif

if (g_bSnapshotMode) {
if (g_SnapshotConfig.eKind == SNAPSHOT_KIND_REPLAY && g_SnapshotConfig.szReplayName[0] == '\0') {
cli_fprintf(stderr, "ERROR: '--snapshot' requires a replay filename\n");
Expand Down Expand Up @@ -2777,7 +2818,7 @@ int main(int argc, const char **argv, const char **envp)
}

if (iCrashHandlerEnabled)
InitCrashHandler();
InitCrashHandler(whiplash_root);

if (InitSDL(whiplash_root, midi_root) != 0) {
return 1;
Expand Down
1 change: 1 addition & 0 deletions PROJECTS/ROLLER/3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ void copypic(uint8 *pSrc, uint8 *pDest);
void init_screen();
void init();
void *getbuffer(uint32 uiSize);
uint32 getbuffer_size(void *pData);
void *trybuffer(uint32 uiSize);
void fre(void **ppData);
void doexit();
Expand Down
5 changes: 5 additions & 0 deletions PROJECTS/ROLLER/control.c
Original file line number Diff line number Diff line change
Expand Up @@ -2236,6 +2236,11 @@ void updatecar2(tCar *pCar)
fAbsoluteSpeed = 0.0;
fSpeedOverflow = 0.0;
}
if (!race_started && iControlTypeCheck == 3) {
fAbsoluteSpeed = 0.0f;
fSpeedOverflow = 0.0f;
pCar->fBaseSpeed = 0.0f;
}
dAbsoluteSpeed = fAbsoluteSpeed;
pCar->fFinalSpeed = fAbsoluteSpeed;
fAbsoluteSpeed = (float)fabs(dAbsoluteSpeed);
Expand Down
Loading
Loading