Port Requests


But werend the GTA3 and VC also leaks? I know i have Farcry as a DVD somewhere in my collection, and it was actually quite impressive back then.. but much too buggy on PC, i had the bug that the enemys got Noclip Cheat on, i was unable to harm them whit my guns..

And God Old Farcry didnt spam you whit this damm Farcry Arcade which kills the whole imension like on the part whit these religouse guys ... ^^
 
One of my failed attempt to port a game to the Pyra is Wipeout rewrite

wipeout-wasm.png


I have compiled it but during loading ends up always with Bus Error (with every backend i choose GL/Glx, GLES2, Software).
I compiled also on Pandora and there the loading went fine but is really slow, intro play but is not showed (only sound is fine) also game graphics is only in wireframe.

Plus there is a problem with the license as stated in readme the game is based on a leaked code from 2022.

Blog post about it https://phoboslab.org/log/2023/08/rewriting-wipeout
 
I just realized what PND’s are. Great! Package managers tend to make me nervous. Love the concept and the ethos is UNIX. Best community ever.
 
One of my failed attempt to port a game to the Pyra is Wipeout rewrite



I have compiled it but during loading ends up always with Bus Error (with every backend i choose GL/Glx, GLES2, Software).
I compiled also on Pandora and there the loading went fine but is really slow, intro play but is not showed (only sound is fine) also game graphics is only in wireframe.

Plus there is a problem with the license as stated in readme the game is based on a leaked code from 2022.

Blog post about it https://phoboslab.org/log/2023/08/rewriting-wipeout
BUSERROR is typical from this old software: memory were scarse, so all data were tightly packed. But ARMv7 have strict alignment constraint for everything float and double. Some helper, using memcpy or similar method, might be needed: run under gdb, what for the SEGBUS, look at the code (probably some float load/save from packed structure), use memcpy instead of simple copy, loop...
 
Last edited:
Tested also with -mno-unaligned-access but did change nothing.

I compiled a debug version and here is the result:
load cmp wipeout/textures/drfonts.cmp
load: wipeout/textures/speedo.tim
load: wipeout/textures/target2.tim
load cmp wipeout/common/wicons.cmp
load cmp wipeout/common/allsh.cmp
load: wipeout/common/allsh.prm

Thread 1 "wipegame" received signal SIGBUS, Bus error.
objects_load (name=0x437030 "wipeout/common/allsh.prm", tl=...)
at src/wipeout/object.c:59
59 object->origin.y = get_i32(bytes, &p);
(gdb) bt
#0 objects_load (name=0x437030 "wipeout/common/allsh.prm", tl=...)
at src/wipeout/object.c:59
#1 0x0041c11a in ships_load () at src/wipeout/ship.c:21
#2 0x0040ef9c in game_init () at src/wipeout/game.c:527
#3 0x0042eed8 in system_init () at src/system.c:20
#4 0x00432096 in main (argc=1, argv=0xbefff334) at src/platform_sdl.c:407
(gdb)
But i did not find any strange things...but maybe an expert eye.
Anyway this is not an old code is a rewrite using SDL2 based on the old code...
 
@Farox that's exactly what I was talking about:

Code:
at src/wipeout/object.c:59
59 object->origin.y = get_i32(bytes, &p);
that's were the SEGBUS is happening.

Not sure if get_i32 is a function or a macro, and what type is origin.y...
I can imagine maybe something like
Code:
int volatile tmp = get_i32(byte, &p);
object->origin.y = tmp;
might help (the volatile is here to ensure the compiler will not optimise out this intermediary step).
 
Well
get_i32 is defined as
C:
#define get_i8(BYTES, P) ((int8_t)get_u8(BYTES, P))
#define get_i16(BYTES, P) ((int16_t)get_u16(BYTES, P))
#define get_i16_le(BYTES, P) ((int16_t)get_u16_le(BYTES, P))
#define get_i32(BYTES, P) ((int32_t)get_u32(BYTES, P))
#define get_i32_le(BYTES, P) ((int32_t)get_u32_le(BYTES, P))

and get_u32 is defined as...
C:
static inline uint32_t get_u32(uint8_t *bytes, uint32_t *p) {
    uint32_t v = 0;
    v |= bytes[(*p)++] << 24;
    v |= bytes[(*p)++] << 16;
    v |= bytes[(*p)++] <<  8;
    v |= bytes[(*p)++] <<  0;
    return v;
}

instead origin....
C:
typedef struct Object {
    char name[16];

    mat4_t mat;
    int16_t vertices_len; // Number of Vertices
    vec3_t *vertices; // Pointer to 3D Points

    int16_t normals_len; // Number of Normals
    vec3_t *normals; // Pointer to 3D Normals

    int16_t primitives_len; // Number of Primitives
    Primitive *primitives; // Pointer to Z Sort Primitives

    vec3_t origin;
    int32_t extent; // Flags for object characteristics
    int16_t flags; // Next object in list
    float radius;
    struct Object *next; // Next object in list
} Object;

and vec3_t ....
C:
typedef struct {
    float x, y, z;
} vec3_t;


and this is the function loading objects

Object *objects_load(char *name, texture_list_t tl) {
uint32_t length = 0;
uint8_t *bytes = platform_load_asset(name, &length);
if (!bytes) {
die("Failed to load file %s\n", name);
}
printf("load: %s\n", name);

Object *objectList = mem_mark();
Object *prevObject = NULL;
uint32_t p = 0;

while (p < length) {
Object *object = mem_bump(sizeof(Object));
if (prevObject) {
prevObject->next = object;
}
prevObject = object;

for (int i = 0; i < 16; i++) {
object->name = get_i8(bytes, &p);
}

object->mat = mat4_identity();
object->vertices_len = get_i16(bytes, &p); p += 2;
object->vertices = NULL; get_i32(bytes, &p);
object->normals_len = get_i16(bytes, &p); p += 2;
object->normals = NULL; get_i32(bytes, &p);
object->primitives_len = get_i16(bytes, &p); p += 2;
object->primitives = NULL; get_i32(bytes, &p);
get_i32(bytes, &p);
get_i32(bytes, &p);
get_i32(bytes, &p); // Skeleton ref
object->extent = get_i32(bytes, &p);
object->flags = get_i16(bytes, &p); p += 2;
object->next = NULL; get_i32(bytes, &p);

p += 3 * 3 * 2; // relative rot matrix
p += 2; // padding

object->origin.x = get_i32(bytes, &p);
object->origin.y = get_i32(bytes, &p);
object->origin.z = get_i32(bytes, &p);

p += 3 * 3 * 2; // absolute rot matrix
p += 2; // padding
p += 3 * 4; // absolute translation matrix
p += 2; // skeleton update flag
p += 2; // padding
p += 4; // skeleton super
p += 4; // skeleton sub
p += 4; // skeleton next

object->radius = 0;
object->vertices = mem_bump(object->vertices_len * sizeof(vec3_t));
for (int i = 0; i < object->vertices_len; i++) {
object->vertices.x = get_i16(bytes, &p);
object->vertices.y = get_i16(bytes, &p);
object->vertices.z = get_i16(bytes, &p);
p += 2; // padding

if (fabsf(object->vertices.x) > object->radius) {
object->radius = fabsf(object->vertices.x);
}
if (fabsf(object->vertices.y) > object->radius) {
object->radius = fabsf(object->vertices.y);
}
if (fabsf(object->vertices.z) > object->radius) {
object->radius = fabsf(object->vertices.z);
}
}



object->normals = mem_bump(object->normals_len * sizeof(vec3_t));
for (int i = 0; i < object->normals_len; i++) {
object->normals.x = get_i16(bytes, &p);
object->normals.y = get_i16(bytes, &p);
object->normals.z = get_i16(bytes, &p);
p += 2; // padding
}

object->primitives = mem_mark();
for (int i = 0; i < object->primitives_len; i++) {
Prm prm;
int16_t prm_type = get_i16(bytes, &p);
int16_t prm_flag = get_i16(bytes, &p);

switch (prm_type) {
case PRM_TYPE_F3:
prm.ptr = mem_bump(sizeof(F3));
prm.f3->coords[0] = get_i16(bytes, &p);
prm.f3->coords[1] = get_i16(bytes, &p);
prm.f3->coords[2] = get_i16(bytes, &p);
prm.f3->pad1 = get_i16(bytes, &p);
prm.f3->color = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_F4:
prm.ptr = mem_bump(sizeof(F4));
prm.f4->coords[0] = get_i16(bytes, &p);
prm.f4->coords[1] = get_i16(bytes, &p);
prm.f4->coords[2] = get_i16(bytes, &p);
prm.f4->coords[3] = get_i16(bytes, &p);
prm.f4->color = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_FT3:
prm.ptr = mem_bump(sizeof(FT3));
prm.ft3->coords[0] = get_i16(bytes, &p);
prm.ft3->coords[1] = get_i16(bytes, &p);
prm.ft3->coords[2] = get_i16(bytes, &p);

prm.ft3->texture = texture_from_list(tl, get_i16(bytes, &p));
prm.ft3->cba = get_i16(bytes, &p);
prm.ft3->tsb = get_i16(bytes, &p);
prm.ft3->u0 = get_i8(bytes, &p);
prm.ft3->v0 = get_i8(bytes, &p);
prm.ft3->u1 = get_i8(bytes, &p);
prm.ft3->v1 = get_i8(bytes, &p);
prm.ft3->u2 = get_i8(bytes, &p);
prm.ft3->v2 = get_i8(bytes, &p);

prm.ft3->pad1 = get_i16(bytes, &p);
prm.ft3->color = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_FT4:
prm.ptr = mem_bump(sizeof(FT4));
prm.ft4->coords[0] = get_i16(bytes, &p);
prm.ft4->coords[1] = get_i16(bytes, &p);
prm.ft4->coords[2] = get_i16(bytes, &p);
prm.ft4->coords[3] = get_i16(bytes, &p);

prm.ft4->texture = texture_from_list(tl, get_i16(bytes, &p));
prm.ft4->cba = get_i16(bytes, &p);
prm.ft4->tsb = get_i16(bytes, &p);
prm.ft4->u0 = get_i8(bytes, &p);
prm.ft4->v0 = get_i8(bytes, &p);
prm.ft4->u1 = get_i8(bytes, &p);
prm.ft4->v1 = get_i8(bytes, &p);
prm.ft4->u2 = get_i8(bytes, &p);
prm.ft4->v2 = get_i8(bytes, &p);
prm.ft4->u3 = get_i8(bytes, &p);
prm.ft4->v3 = get_i8(bytes, &p);
prm.ft4->pad1 = get_i16(bytes, &p);
prm.ft4->color = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_G3:
prm.ptr = mem_bump(sizeof(G3));
prm.g3->coords[0] = get_i16(bytes, &p);
prm.g3->coords[1] = get_i16(bytes, &p);
prm.g3->coords[2] = get_i16(bytes, &p);
prm.g3->pad1 = get_i16(bytes, &p);
prm.g3->color[0] = rgba_from_u32(get_u32(bytes, &p));
prm.g3->color[1] = rgba_from_u32(get_u32(bytes, &p));
prm.g3->color[2] = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_G4:
prm.ptr = mem_bump(sizeof(G4));
prm.g4->coords[0] = get_i16(bytes, &p);
prm.g4->coords[1] = get_i16(bytes, &p);
prm.g4->coords[2] = get_i16(bytes, &p);
prm.g4->coords[3] = get_i16(bytes, &p);
prm.g4->color[0] = rgba_from_u32(get_u32(bytes, &p));
prm.g4->color[1] = rgba_from_u32(get_u32(bytes, &p));
prm.g4->color[2] = rgba_from_u32(get_u32(bytes, &p));
prm.g4->color[3] = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_GT3:
prm.ptr = mem_bump(sizeof(GT3));
prm.gt3->coords[0] = get_i16(bytes, &p);
prm.gt3->coords[1] = get_i16(bytes, &p);
prm.gt3->coords[2] = get_i16(bytes, &p);

prm.gt3->texture = texture_from_list(tl, get_i16(bytes, &p));
prm.gt3->cba = get_i16(bytes, &p);
prm.gt3->tsb = get_i16(bytes, &p);
prm.gt3->u0 = get_i8(bytes, &p);
prm.gt3->v0 = get_i8(bytes, &p);
prm.gt3->u1 = get_i8(bytes, &p);
prm.gt3->v1 = get_i8(bytes, &p);
prm.gt3->u2 = get_i8(bytes, &p);
prm.gt3->v2 = get_i8(bytes, &p);
prm.gt3->pad1 = get_i16(bytes, &p);
prm.gt3->color[0] = rgba_from_u32(get_u32(bytes, &p));
prm.gt3->color[1] = rgba_from_u32(get_u32(bytes, &p));
prm.gt3->color[2] = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_GT4:
prm.ptr = mem_bump(sizeof(GT4));
prm.gt4->coords[0] = get_i16(bytes, &p);
prm.gt4->coords[1] = get_i16(bytes, &p);
prm.gt4->coords[2] = get_i16(bytes, &p);
prm.gt4->coords[3] = get_i16(bytes, &p);

prm.gt4->texture = texture_from_list(tl, get_i16(bytes, &p));
prm.gt4->cba = get_i16(bytes, &p);
prm.gt4->tsb = get_i16(bytes, &p);
prm.gt4->u0 = get_i8(bytes, &p);
prm.gt4->v0 = get_i8(bytes, &p);
prm.gt4->u1 = get_i8(bytes, &p);
prm.gt4->v1 = get_i8(bytes, &p);
prm.gt4->u2 = get_i8(bytes, &p);
prm.gt4->v2 = get_i8(bytes, &p);
prm.gt4->u3 = get_i8(bytes, &p);
prm.gt4->v3 = get_i8(bytes, &p);
prm.gt4->pad1 = get_i16(bytes, &p);
prm.gt4->color[0] = rgba_from_u32(get_u32(bytes, &p));
prm.gt4->color[1] = rgba_from_u32(get_u32(bytes, &p));
prm.gt4->color[2] = rgba_from_u32(get_u32(bytes, &p));
prm.gt4->color[3] = rgba_from_u32(get_u32(bytes, &p));
break;


case PRM_TYPE_LSF3:
prm.ptr = mem_bump(sizeof(LSF3));
prm.lsf3->coords[0] = get_i16(bytes, &p);
prm.lsf3->coords[1] = get_i16(bytes, &p);
prm.lsf3->coords[2] = get_i16(bytes, &p);
prm.lsf3->normal = get_i16(bytes, &p);
prm.lsf3->color = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_LSF4:
prm.ptr = mem_bump(sizeof(LSF4));
prm.lsf4->coords[0] = get_i16(bytes, &p);
prm.lsf4->coords[1] = get_i16(bytes, &p);
prm.lsf4->coords[2] = get_i16(bytes, &p);
prm.lsf4->coords[3] = get_i16(bytes, &p);
prm.lsf4->normal = get_i16(bytes, &p);
prm.lsf4->pad1 = get_i16(bytes, &p);
prm.lsf4->color = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_LSFT3:
prm.ptr = mem_bump(sizeof(LSFT3));
prm.lsft3->coords[0] = get_i16(bytes, &p);
prm.lsft3->coords[1] = get_i16(bytes, &p);
prm.lsft3->coords[2] = get_i16(bytes, &p);
prm.lsft3->normal = get_i16(bytes, &p);

prm.lsft3->texture = texture_from_list(tl, get_i16(bytes, &p));
prm.lsft3->cba = get_i16(bytes, &p);
prm.lsft3->tsb = get_i16(bytes, &p);
prm.lsft3->u0 = get_i8(bytes, &p);
prm.lsft3->v0 = get_i8(bytes, &p);
prm.lsft3->u1 = get_i8(bytes, &p);
prm.lsft3->v1 = get_i8(bytes, &p);
prm.lsft3->u2 = get_i8(bytes, &p);
prm.lsft3->v2 = get_i8(bytes, &p);
prm.lsft3->color = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_LSFT4:
prm.ptr = mem_bump(sizeof(LSFT4));
prm.lsft4->coords[0] = get_i16(bytes, &p);
prm.lsft4->coords[1] = get_i16(bytes, &p);
prm.lsft4->coords[2] = get_i16(bytes, &p);
prm.lsft4->coords[3] = get_i16(bytes, &p);
prm.lsft4->normal = get_i16(bytes, &p);

prm.lsft4->texture = texture_from_list(tl, get_i16(bytes, &p));
prm.lsft4->cba = get_i16(bytes, &p);
prm.lsft4->tsb = get_i16(bytes, &p);
prm.lsft4->u0 = get_i8(bytes, &p);
prm.lsft4->v0 = get_i8(bytes, &p);
prm.lsft4->u1 = get_i8(bytes, &p);
prm.lsft4->v1 = get_i8(bytes, &p);
prm.lsft4->u2 = get_i8(bytes, &p);
prm.lsft4->v2 = get_i8(bytes, &p);
prm.lsft4->u3 = get_i8(bytes, &p);
prm.lsft4->v3 = get_i8(bytes, &p);
prm.lsft4->color = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_LSG3:
prm.ptr = mem_bump(sizeof(LSG3));
prm.lsg3->coords[0] = get_i16(bytes, &p);
prm.lsg3->coords[1] = get_i16(bytes, &p);
prm.lsg3->coords[2] = get_i16(bytes, &p);
prm.lsg3->normals[0] = get_i16(bytes, &p);
prm.lsg3->normals[1] = get_i16(bytes, &p);
prm.lsg3->normals[2] = get_i16(bytes, &p);
prm.lsg3->color[0] = rgba_from_u32(get_u32(bytes, &p));
prm.lsg3->color[1] = rgba_from_u32(get_u32(bytes, &p));
prm.lsg3->color[2] = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_LSG4:
prm.ptr = mem_bump(sizeof(LSG4));
prm.lsg4->coords[0] = get_i16(bytes, &p);
prm.lsg4->coords[1] = get_i16(bytes, &p);
prm.lsg4->coords[2] = get_i16(bytes, &p);
prm.lsg4->coords[3] = get_i16(bytes, &p);
prm.lsg4->normals[0] = get_i16(bytes, &p);
prm.lsg4->normals[1] = get_i16(bytes, &p);
prm.lsg4->normals[2] = get_i16(bytes, &p);
prm.lsg4->normals[3] = get_i16(bytes, &p);
prm.lsg4->color[0] = rgba_from_u32(get_u32(bytes, &p));
prm.lsg4->color[1] = rgba_from_u32(get_u32(bytes, &p));
prm.lsg4->color[2] = rgba_from_u32(get_u32(bytes, &p));
prm.lsg4->color[3] = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_LSGT3:
prm.ptr = mem_bump(sizeof(LSGT3));
prm.lsgt3->coords[0] = get_i16(bytes, &p);
prm.lsgt3->coords[1] = get_i16(bytes, &p);
prm.lsgt3->coords[2] = get_i16(bytes, &p);
prm.lsgt3->normals[0] = get_i16(bytes, &p);
prm.lsgt3->normals[1] = get_i16(bytes, &p);
prm.lsgt3->normals[2] = get_i16(bytes, &p);

prm.lsgt3->texture = texture_from_list(tl, get_i16(bytes, &p));
prm.lsgt3->cba = get_i16(bytes, &p);
prm.lsgt3->tsb = get_i16(bytes, &p);
prm.lsgt3->u0 = get_i8(bytes, &p);
prm.lsgt3->v0 = get_i8(bytes, &p);
prm.lsgt3->u1 = get_i8(bytes, &p);
prm.lsgt3->v1 = get_i8(bytes, &p);
prm.lsgt3->u2 = get_i8(bytes, &p);
prm.lsgt3->v2 = get_i8(bytes, &p);
prm.lsgt3->color[0] = rgba_from_u32(get_u32(bytes, &p));
prm.lsgt3->color[1] = rgba_from_u32(get_u32(bytes, &p));
prm.lsgt3->color[2] = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_LSGT4:
prm.ptr = mem_bump(sizeof(LSGT4));
prm.lsgt4->coords[0] = get_i16(bytes, &p);
prm.lsgt4->coords[1] = get_i16(bytes, &p);
prm.lsgt4->coords[2] = get_i16(bytes, &p);
prm.lsgt4->coords[3] = get_i16(bytes, &p);
prm.lsgt4->normals[0] = get_i16(bytes, &p);
prm.lsgt4->normals[1] = get_i16(bytes, &p);
prm.lsgt4->normals[2] = get_i16(bytes, &p);
prm.lsgt4->normals[3] = get_i16(bytes, &p);

prm.lsgt4->texture = texture_from_list(tl, get_i16(bytes, &p));
prm.lsgt4->cba = get_i16(bytes, &p);
prm.lsgt4->tsb = get_i16(bytes, &p);
prm.lsgt4->u0 = get_i8(bytes, &p);
prm.lsgt4->v0 = get_i8(bytes, &p);
prm.lsgt4->u1 = get_i8(bytes, &p);
prm.lsgt4->v1 = get_i8(bytes, &p);
prm.lsgt4->u2 = get_i8(bytes, &p);
prm.lsgt4->v2 = get_i8(bytes, &p);
prm.lsgt4->pad1 = get_i16(bytes, &p);
prm.lsgt4->color[0] = rgba_from_u32(get_u32(bytes, &p));
prm.lsgt4->color[1] = rgba_from_u32(get_u32(bytes, &p));
prm.lsgt4->color[2] = rgba_from_u32(get_u32(bytes, &p));
prm.lsgt4->color[3] = rgba_from_u32(get_u32(bytes, &p));
break;


case PRM_TYPE_TSPR:
case PRM_TYPE_BSPR:
prm.ptr = mem_bump(sizeof(SPR));
prm.spr->coord = get_i16(bytes, &p);
prm.spr->width = get_i16(bytes, &p);
prm.spr->height = get_i16(bytes, &p);
prm.spr->texture = texture_from_list(tl, get_i16(bytes, &p));
prm.spr->color = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_SPLINE:
prm.ptr = mem_bump(sizeof(Spline));
prm.spline->control1.x = get_i32(bytes, &p);
prm.spline->control1.y = get_i32(bytes, &p);
prm.spline->control1.z = get_i32(bytes, &p);
p += 4; // padding
prm.spline->position.x = get_i32(bytes, &p);
prm.spline->position.y = get_i32(bytes, &p);
prm.spline->position.z = get_i32(bytes, &p);
p += 4; // padding
prm.spline->control2.x = get_i32(bytes, &p);
prm.spline->control2.y = get_i32(bytes, &p);
prm.spline->control2.z = get_i32(bytes, &p);
p += 4; // padding
prm.spline->color = rgba_from_u32(get_u32(bytes, &p));
break;

case PRM_TYPE_POINT_LIGHT:
prm.ptr = mem_bump(sizeof(PointLight));
prm.pointLight->position.x = get_i32(bytes, &p);
prm.pointLight->position.y = get_i32(bytes, &p);
prm.pointLight->position.z = get_i32(bytes, &p);
p += 4; // padding
prm.pointLight->color = rgba_from_u32(get_u32(bytes, &p));
prm.pointLight->startFalloff = get_i16(bytes, &p);
prm.pointLight->endFalloff = get_i16(bytes, &p);
break;

case PRM_TYPE_SPOT_LIGHT:
prm.ptr = mem_bump(sizeof(SpotLight));
prm.spotLight->position.x = get_i32(bytes, &p);
prm.spotLight->position.y = get_i32(bytes, &p);
prm.spotLight->position.z = get_i32(bytes, &p);
p += 4; // padding
prm.spotLight->direction.x = get_i16(bytes, &p);
prm.spotLight->direction.y = get_i16(bytes, &p);
prm.spotLight->direction.z = get_i16(bytes, &p);
p += 2; // padding
prm.spotLight->color = rgba_from_u32(get_u32(bytes, &p));
prm.spotLight->startFalloff = get_i16(bytes, &p);
prm.spotLight->endFalloff = get_i16(bytes, &p);
prm.spotLight->coneAngle = get_i16(bytes, &p);
prm.spotLight->spreadAngle = get_i16(bytes, &p);
break;

case PRM_TYPE_INFINITE_LIGHT:
prm.ptr = mem_bump(sizeof(InfiniteLight));
prm.infiniteLight->direction.x = get_i16(bytes, &p);
prm.infiniteLight->direction.y = get_i16(bytes, &p);
prm.infiniteLight->direction.z = get_i16(bytes, &p);
p += 2; // padding
prm.infiniteLight->color = rgba_from_u32(get_u32(bytes, &p));
break;


default:
die("bad primitive type %x \n", prm_type);
} // switch

prm.f3->type = prm_type;
prm.f3->flag = prm_flag;
} // each prim
} // each object

mem_temp_free(bytes);
return objectList;
}
 
Yes. Issue is that that origin.y is a float (origin is a vec3_t), and loading it directly with a get_i32, the compiler optimise all that by just reading an int from a pointer to a float, using VFPv3... But the address is unaligned... and so segbus. Chnage the line 59 by my block and try again, see, if you go farther or not...
 
for this first compilation i didn't used optimization (no VFPv3 ).
But i could try your changes. thanks
 
Unfortunately SIGBUS error still there after apply your changes and with and without -mno-unaligned-access.
my CFLAGS are -std=gnu99 -Wall -Wno-unused-variable -O1 -g -ggdb3
 
Unfortunately SIGBUS error still there after apply your changes and with and without -mno-unaligned-access.
my CFLAGS are -std=gnu99 -Wall -Wno-unused-variable -O1 -g -ggdb3
Yes, that expected, there will be more SIGBUS. But is still at the same code or is it farther?
 
At the same point in the code that i changed with your suggested..
int volatile tmp = get_i32(bytes, &p);
 
Yes. Issue is that that origin.y is a float (origin is a vec3_t), and loading it directly with a get_i32, the compiler optimise all that by just reading an int from a pointer to a float, using VFPv3... But the address is unaligned... and so segbus. Chnage the line 59 by my block and try again, see, if you go farther or not...
get_i32 if for reading big endian numbers so it won't get optimized to reading an int.

I suspect the problem is in function mem_bump (in mem.c) - it can return unaligned pointers, if previous allocation size wasn't divisible by 4.

Try aligning the size to 8 bytes (the same as in function mem_temp_alloc). Change
Code:
void *mem_bump(uint32_t size) {
    error_if(bump_len + temp_len + size >= MEM_HUNK_BYTES, "Failed to allocate %d bytes in hunk mem", size);
to:
Code:
void *mem_bump(uint32_t size) {
    size = ((size + 7) >> 3) << 3; // allign to 8 bytes
    error_if(bump_len + temp_len + size >= MEM_HUNK_BYTES, "Failed to allocate %d bytes in hunk mem", size);
 
Check the kernel log for the source of the SIGBUS signal, if this is really a misaligned access it should've caused a data abort exception.

If origin was allocated misaligned, shouldn't the exception already happen earlier, like when writing origin.x? I'm pretty sure this shouldn't get reordered by the compiler due to the dependence on p.

You could also try to disable optimizations entirely ( -O0 ), maybe this makes things more obvious.
 
Thanks @M-HT now loading is going a bit forward...but it stops at:

Code:
load cmp wipeout/textures/drfonts.cmp
load: wipeout/textures/speedo.tim
load: wipeout/textures/target2.tim
load cmp wipeout/common/wicons.cmp
load cmp wipeout/common/allsh.cmp
load: wipeout/common/allsh.prm
load cmp wipeout/common/alcol.cmp
load: wipeout/common/alcol.prm
Abort at "src/wipeout/ship.c" line 353: cone.c::InitCone:Bad primitive type 0
 
Try aligning the size to 4 bytes instead of 7 bytes (in function mem_bump in mem.c).
Change:
Code:
void *mem_bump(uint32_t size) {
    size = ((size + 7) >> 3) << 3; // allign to 8 bytes
to
Code:
void *mem_bump(uint32_t size) {
    size = ((size + 3) >> 2) << 2; // allign to 4 bytes
 
Back
Top