The Pandora Port Request Thread


@ptitSeb : I'd rather think a compiled engine would run faster than an interpreted one inside a JVM. I also expect EDuke32 to allow software rendering, in case GLES2 mode proved to be too slow on the Pandora, but I could be wrong though (e.g if the engine uses SDL2 for example...). On a side note, have you heard about Ion Fury ?

https://en.m.wikipedia.org/wiki/Ion_Fury

Runs on EDuke32 as far as I understand. I wonder whether it could be make to work on the Pandora ?

Cheers, Magic Sam
 
@ptitSeb : I'd rather think a compiled engine would run faster than an interpreted one inside a JVM. I also expect EDuke32 to allow software rendering, in case GLES2 mode proved to be too slow on the Pandora, but I could be wrong though (e.g if the engine uses SDL2 for example...).
Yes, could be. IIRC, there are 3 rendering mode with Eduke32: Software, Polymere and Polymost. The last two are hardware renderer, but one needs OpenGL 1.x and the other OpenGL 2.x (I don't remember which one is which). The issue with the OpenGL 2.x is that is uses Shaders with Textures 3D (among other things), that gl4es doesn't support yet (support is planned, but I haven't worked on that part yet). The OpenGL 1.x works, but can be slow on certains operations, so it's not always a win (it works fine with Duke Nukem 3D, it's a bit slow with the Sonic 3D remake that I forgot the name).

On a side note, have you heard about Ion Fury ?

https://en.m.wikipedia.org/wiki/Ion_Fury

Runs on EDuke32 as far as I understand. I wonder whether it could be make to work on the Pandora ?

Cheers, Magic Sam
Yeah, I heard of it. Looks nice. If it's vanilla EDuke32, than maybe (depending if it's tied to a specific renderer). If it's not vanilla Eduke32, well, Eduke32 seems to be GPL so I guess the changed sources must be found somewhere...
 
Hi all,

@ptitSeb : check your e-mail box ;)

Cheers, Magic Sam
Btw: indeed, Ion Fury sources are now inside eDuke32 (due to GPL 2.0 licence). To build you simply need a "make FURY=1". I tried to build on the Pandora. First, SDL1 backend doesn't work, only SDL2 do.
For now, I got it to work, but it's too slow to be playable. I think the scripts are using to much CPU. Also, it's a software build for now. I need to experiment more.
 
Last edited:
So I analysed a bit what is happening on Ion Fury on the Pandora: I rebuilt with debug info (and without LTO for now, for faster build), switched vorbis to tremor, reduce sound quality a bit (48kHz on 64 voices to 22kHz with 32 voices), but it's still to slow: the rendering is taking all the time
ionfury03.png
Code:
   PerfTop:    1005 irqs/sec  kernel: 4.3%  exact:  0.0% [1000Hz cycles],  (all, 1 CPU)
------------------------------------------------------------------------------------------------------------------------------------------------------------

    15.74%  fury                     [.] classicDrawSprite(int)
    11.43%  libgcc_s.so.1            [.] __udivmoddi4
     4.55%  fury                     [.] VM_Execute(bool)
     4.01%  fury                     [.] renderDrawRoomsQ16
     3.04%  libm.so.6                [.] __lrintf
     2.36%  libvorbisifile.so.1.0.3  [.] mdct_backward
     2.25%  fury                     [.] vlineasm4(int, char*)
     2.25%  fury                     [.] updatesectorz
     2.16%  fury                     [.] classicDrawBunches(int)
     2.10%  fury                     [.] _ZN9libdivideL26libdivide_128_div_64_to_64EyyyPy.constprop.0
     1.92%  fury                     [.] MV_Mix16BitStereo16(VoiceNode*, unsigned int)
     1.89%  fury                     [.] inside
     1.73%  fury                     [.] void softsurface_blitBufferInternal<unsigned short>(unsigned short*)
     1.62%  fury                     [.] owallmost(short*, int, long long)
     1.61%  fury                     [.] getzrange
     1.56%  fury                     [.] tvlineasm2(unsigned int, int, int, int, unsigned int, int)
     1.48%  fury                     [.] _ZL8prepwalliPK11uwalltypev7.isra.0
     1.42%  fury                     [.] hlineasm4(int, int, int, unsigned int, unsigned int, int)
     1.36%  libvorbisifile.so.1.0.3  [.] vorbis_book_decodev_add
     1.33%  fury                     [.] tabledivide64
     1.30%  fury                     [.] getzsofslopeptr
     1.25%  libc-2.9.so              [.] memcpy
     1.18%  fury                     [.] wallmost(short*, int, int, char)
     1.04%  [kernel]                 [k] __do_softirq
     0.98%  fury                     [.] Gv_GetVar(int)
     0.97%  fury                     [.] _ZL17classicScanSectors.part.0
     0.89%  fury                     [.] Gv_GetArrayOrStruct(int, int, int)
     0.86%  fury                     [.] grouscan(int, int, int, char)
     0.82%  [kernel]                 [k] ktime_get_ts
     0.81%  fury                     [.] libxmp_mix_stereo_8bit_spline(mixer_voice*, int*, int, int, int, int, int, int, int)
     0.80%  fury                     [.] S_Update
     0.72%  fury                     [.] thline(int, unsigned int, int, int, unsigned int, int)
     0.71%  fury                     [.] wallscan(int, int, short const*, short const*, int const*, int const*)
     0.69%  libasound.so.2.0.0       [.] 0x6554c
     0.66%  fury                     [.] _ZL17get_screen_coordsRK6vec2_tS1_PiS2_S2_S2_.isra.0
     0.66%  fury                     [.] G_DoSpriteAnimations
     0.59%  fury                     [.] MV_Mix16BitStereo16Stereo(VoiceNode*, unsigned int)
     0.53%  fury                     [.] renderDrawMasks
     0.47%  fury                     [.] wallfront
     0.44%  fury                     [.] vlineasm1(int, int, int, unsigned int, int, int)
     0.43%  libgcc_s.so.1            [.] __aeabi_uldivmod
     0.42%  libvorbisifile.so.1.0.3  [.] vorbis_synthesis_blockin
     0.39%  libvorbisifile.so.1.0.3  [.] floor1_inverse2
     0.38%  fury                     [.] Gv_GetVar(int, int, int)
     0.35%  fury                     [.] 0x1f858
     0.34%  fury                     [.] maskwallscan(int, int, int)
     0.34%  fury                     [.] mspritevline(int, int, int, int, int)
     0.31%  libogg.so.0.8.3          [.] oggpack_look
     0.30%  fury                     [.] A_Execute
     0.30%  libvorbisifile.so.1.0.3  [.] ov_read
     0.29%  fury                     [.] qinterpolatedown16short
     0.27%  fury                     [.] transmaskwallscan(int, int, int)
     0.26%  fury                     [.] ceilscan(int, int, int)
     0.25%  fury                     [.] mvlineasm4(int, char*)
     0.24%  libvorbisifile.so.1.0.3  [.] _01inverse
     0.24%  libgcc_s.so.1            [.] 0xcd5c
     0.23%  libvorbisifile.so.1.0.3  [.] _vorbis_apply_window
     0.22%  [kernel]                 [k] __schedule

I'll now try a "polymost" build (also, I noticed that Polymere build is disabled for Ion Fury...).
[doublepost=1568064675,1568053261][/doublepost]So, that polymost renderer is not easy to make work.

First, I got garbage on screen. After some analysis and debugging, I found I had an old issue in gl4es, but it was the first time it trigger as it needed to do some texture upload on a different Texture unit than the previous operation...

After that, I got mostly a black screen. This time, it's eduke32 source that I found strange, and I change the code, look in the spoiler:

Code:
    GLint prevVBO = 0;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vm->vboindex);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * 3 * 2 * vm->qcnt, index, GL_STATIC_DRAW);
    glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prevVBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prevVBO);
    prevVBO = 0;
    glBindBuffer(GL_ARRAY_BUFFER, vm->vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 5 * 4 * vm->qcnt, vertex, GL_STATIC_DRAW);
    glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prevVBO);
    glBindBuffer(GL_ARRAY_BUFFER, prevVBO);
    Xfree(vertex);
    Xfree(index);
to
Code:
    GLint prevVBO = 0;
    glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prevVBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vm->vboindex);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * 3 * 2 * vm->qcnt, index, GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prevVBO);
    prevVBO = 0;
    glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prevVBO);
    glBindBuffer(GL_ARRAY_BUFFER, vm->vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 5 * 4 * vm->qcnt, vertex, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, prevVBO);
    Xfree(vertex);
    Xfree(index);

But, stil no luck, still a black screen.I have done a PVR capture, but I still don't understand why it's black (at least, I can see the vertex coordinates are correct now). I'll continue to debug tomorow...

(also, the Polymost renderer is already a pretty advanced renderer. It's GL2.x only, and feature quite a lot of stuff, I'm not sure the rendering will be so fast in the end)
 
Hi all,

@ptitSeb : thanks for giving Ion Fury a try on the Pandora, that's really appreciated :) Let's hope it'll work fine eventually.

Cheers, Magic Sam
[doublepost=1568094184,1568092723][/doublepost]Hi again,

https://wiki.eduke32.com/wiki/Installation_and_configuration

Looks like there are many console and configuration file options available to tune the eye-candy down :)

Cheers, Magic Sam
 
For the curious, here is my current diff of the eduke32 sources:
Code:
-rwxr-xr-x 1 seb seb 15044300 Sep  9 23:46 fury
-rwxr-xr-x 1 seb seb 11039108 Sep  9 23:46 mapster32
/media/sda1/sources/svn/eduke32$ svn diff
Index: Common.mak
===================================================================
--- Common.mak  (revision 8090)
+++ Common.mak  (working copy)
@@ -52,7 +52,7 @@

 ifndef SUBPLATFORM
     SUBPLATFORM :=
-    ifeq ($(PLATFORM),$(filter $(PLATFORM),LINUX DINGOO GCW CAANOO))
+    ifeq ($(PLATFORM),$(filter $(PLATFORM),LINUX DINGOO GCW CAANOO PANDORA))
         SUBPLATFORM := LINUX
     endif
 endif
@@ -364,7 +364,7 @@
 endif

 # Debugging/Build options
-FORCEDEBUG := 0
+FORCEDEBUG := 1
 KRANDDEBUG := 0
 PROFILER := 0
 # Make allocache() a wrapper around malloc()? Useful for debugging
@@ -405,6 +405,14 @@
     override NOASM := 1
 else ifeq ($(PLATFORM),$(filter $(PLATFORM),BEOS SKYOS))
     override NOASM := 1
+else ifeq ($(PLATFORM),PANDORA)
+    override USE_OPENGL := 1
+    override NETCODE := 0
+    override HAVE_GTK2 := 0
+    override HAVE_FLAC := 1
+    override NOASM := 1
+    override USE_LUAJIT_2_1 := 1
+    SDL_TARGET := 2
 endif

 ifneq (i386,$(strip $(IMPLICIT_ARCH)))
@@ -450,8 +458,8 @@

     LTO := 0
 else
-    OPTLEVEL := 2
-    LTO := 1
+    OPTLEVEL := 3
+    LTO := 0
 endif

 ifneq (0,$(CLANG))
@@ -576,6 +584,10 @@
     COMPILERFLAGS += -D__OPENDINGUX__
 else ifeq ($(PLATFORM),SKYOS)
     COMPILERFLAGS += -DUNDERSCORES
+else ifeq ($(PLATFORM),PANDORA)
+    COMPILERFLAGS += -D__PANDORA__
+    COMMONFLAGS += -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -ffast-math -ftree-vectorize
+    LIBDIRS += -lrt
 endif
 ASFLAGS += -f $(ASFORMAT)

Index: GNUmakefile
===================================================================
--- GNUmakefile (revision 8090)
+++ GNUmakefile (working copy)
@@ -670,7 +670,11 @@
 endif

 ifeq ($(SUBPLATFORM),LINUX)
-    LIBS += -lFLAC -lvorbisfile -lvorbis -logg
+    ifeq ($(PLATFORM),PANDORA)
+        LIBS += -lFLAC -lvorbisifile
+    else
+        LIBS += -lFLAC -lvorbisfile -lvorbis -logg
+    endif
 endif

 ifeq ($(PLATFORM),BSD)
Index: source/build/src/tilepacker.cpp
===================================================================
--- source/build/src/tilepacker.cpp     (revision 8090)
+++ source/build/src/tilepacker.cpp     (working copy)
@@ -92,6 +92,7 @@

 static void maxheap_buildHeap()
 {
+    if(heapNodes<2) return;
     for (int i = (heapNodes-2)/2; i >= 0; --i)
     {
         maxheap_bubbleDown(i);
Index: source/build/src/voxmodel.cpp
===================================================================
--- source/build/src/voxmodel.cpp       (revision 8090)
+++ source/build/src/voxmodel.cpp       (working copy)
@@ -435,14 +435,14 @@
         index[(i*2+1)*3+2] = i*4+3;
     }
     GLint prevVBO = 0;
+    glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prevVBO);
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vm->vboindex);
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * 3 * 2 * vm->qcnt, index, GL_STATIC_DRAW);
-    glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prevVBO);
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prevVBO);
     prevVBO = 0;
+    glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prevVBO);
     glBindBuffer(GL_ARRAY_BUFFER, vm->vbo);
     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 5 * 4 * vm->qcnt, vertex, GL_STATIC_DRAW);
-    glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prevVBO);
     glBindBuffer(GL_ARRAY_BUFFER, prevVBO);
     Xfree(vertex);
     Xfree(index);
Index: source/duke3d/src/config.cpp
===================================================================
--- source/duke3d/src/config.cpp        (revision 8090)
+++ source/duke3d/src/config.cpp        (working copy)
@@ -227,11 +227,13 @@
     ud.config.MixRate = 44100;
 #elif defined __ANDROID__
     ud.config.MixRate = droidinfo.audio_sample_rate;
+#elif defined __PANDORA__
+    ud.config.MixRate = 22050;
 #else
     ud.config.MixRate = 48000;
 #endif

-#if defined GEKKO || defined __OPENDINGUX__
+#if defined GEKKO || defined __OPENDINGUX__ || defined __PANDORA__
     ud.config.NumVoices = 32;
     ud.camera_time = 11;
 #else

The added "if(heapNodes<2) return;" is a "funny" bug... "heapNodes" is an uint32_t. So when heapNodes is 0 (it happens on 2nd call), heapNodes-2 gives .... around 4 billions... So that function takes forever to run, freeing the games. I guess on x86 there are some implicit uint->int conversion? but not on ARM...
[doublepost=1568106130,1568096451][/doublepost]I think I have found the root cause of that last issue. It's an issue with varying and array optimisation:
the vertex shader of Ion Fury contains the following:
Code:
   gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
   gl_TexCoord[0] = mix(gl_TexCoord[0].xyzw, gl_TexCoord[0].yxzw, u_usePalette);

   gl_TexCoord[3] = gl_TextureMatrix[3] * gl_MultiTexCoord3;
   gl_TexCoord[4] = gl_TextureMatrix[4] * gl_MultiTexCoord4;

   gl_FogFragCoord = abs(eyeCoordPosition.z);
This is just an extract, and it's Desktop GLSL. gl4es will transform that in GLES GLSL without issue:
Code:
   _gl4es_TexCoord[0] = _gl4es_TextureMatrix[0] * _gl4es_MultiTexCoord0;
   _gl4es_TexCoord[0] = mix(_gl4es_TexCoord[0].xyzw, _gl4es_TexCoord[0].yxzw, u_usePalette);

   _gl4es_TexCoord[3] = _gl4es_TextureMatrix[3] * _gl4es_MultiTexCoord3;
   _gl4es_TexCoord[4] = _gl4es_TextureMatrix[4] * _gl4es_MultiTexCoord4;

   _gl4es_FogFragCoord = abs(eyeCoordPosition.z);
All the "gl_" Desktop variable have to be emulated in GLES... And the gl_TexCoord[...] is also defined, in the "header" part of the converted vertex shader as
Code:
varying mediump vec4 _gl4es_TexCoord[5];

Then, in the original fragment shader, we have:
Code:
#ifdef POLYMOST1_EXTENDED
    vec4 detailColor = texture2D(s_detail, gl_TexCoord[3].xy);
    detailColor = mix(c_vec4_one, 2.0*detailColor, u_useDetailMapping*detailColor.a);
    color.rgb *= detailColor.rgb;
#endif

    color = mix(color, c_vec4_one, u_useColorOnly);

    // DEBUG
    //color = texture2D(s_palswap, gl_TexCoord[0].xy);
    //color = texture2D(s_palette, gl_TexCoord[0].xy);
    //color = texture2D(s_texture, gl_TexCoord[0].yx);

    color.rgb = mix(v_color.rgb*color.rgb, color.rgb, fullbright);

    float fogEnabled = mix(u_fogEnabled, c_zero, u_usePalette);
    fullbright = max(c_one-fogEnabled, fullbright);
    float fogFactor = clamp((gl_Fog.end-gl_FogFragCoord)*gl_Fog.scale, fullbright, c_one);
    //float fogFactor = clamp(gl_FogFragCoord, fullbright, c_one);
    color.rgb = mix(gl_Fog.color.rgb, color.rgb, fogFactor);

#ifdef POLYMOST1_EXTENDED
    vec4 glowColor = texture2D(s_glow, gl_TexCoord[4].xy);
    color.rgb = mix(color.rgb, glowColor.rgb, u_useGlowMapping*glowColor.a*(c_one-u_useColorOnly));
#endif
Again, it's just an extract... Note that, in the header "POLYMOST1_EXTENDED" is not defined.
gl4es tranform that part in:
Code:
    color = mix(color, c_vec4_one, u_useColorOnly);

   
   
   
   

    color.rgb = mix(v_color.rgb*color.rgb, color.rgb, fullbright);
So yeah, all comment and the #ifdef that could be evaluated simply are removed (the shader compiler will do the same anyway).
Of course, in the header of the fragment shader, I still get
Code:
varying mediump vec4 _gl4es_TexCoord[5];
As gl4es take care of having identical varying in both vertex and fragment shader, or the link would failed...

Still, in that case, the compiler is probably optimising that varying... It's defined as an Array of 5 vec4, but while in the vertex shader, elements 3 and 4 are writen, it's not the case in the fragment shader, where only the element 0 is writen. The _gl4es_TexCoord varying gets different "post optimize" difinition and ssems to more or less silently break the program.

If I change the vertex shader to remove the (here useless) 3 & 4 element change, it seems to work!
Also, if I force the use of discreet _gl4es_TexCoord instead of an array, it also seems to work.

I think I will change the vertex shader to also include the "#define POLYMOST1_EXTENDED" mecanism and change "polymost.cpp" to activate/deactivate that define in the vertex shader too (copypasta of the code for the fragment shader)...
 
The added "if(heapNodes<2) return;" is a "funny" bug... "heapNodes" is an uint32_t. So when heapNodes is 0 (it happens on 2nd call), heapNodes-2 gives .... around 4 billions... So that function takes forever to run, freeing the games. I guess on x86 there are some implicit uint->int conversion? but not on ARM...
It's "funny", because it's undefined behaviour in C standard, meaning that the compiler is free to do what it wants in this case. Which means that it works on x86 by accident and not by intent.
 
It's "funny", because it's undefined behaviour in C standard
The wrap-around is well-defined for unsigned integers, it's only undefined behaviour if the variable is a signed integer.

The integer promotion rules that determine the final data type used for the calculation are rather wonky, though - they changed over the standard versions and compilers usually implement their own idea of how to do it. It's usually a good idea to always mark your constants as unsigned where applicable to keep things in order.
 
Last edited:
The issue was this line:
Code:
for (int i = (heapNodes-2)/2; i >= 0; --i) {
 ...
with heapNodes a uint32_t, and the issue is when heapNodes is 0, then (heapNodes-2)/2 is computed as uint32_t, and gives 2 billions, and a compatible value for an "int promotion" in the for loop initialization.
 
then (heapNodes-2)/2 is computed as uint32_t
If I remember correctly the C standard strictly prefers signed integers unless the value is too large to fit in (while compilers apparently prefer to preserve the unsignedness), which leads to the mentioned undefined behaviour due to a signed overflow. Such undefined behaviour is a very popular point for aggressive optimizations, the compiler may just decide to insert that check itself to skip the loop for values that cause undefined behaviour, because "things that don't exist in the standard don't exist at all".

GCC has a fairly long record of doing these kind of "destructive" optimizations, which caused quite a lot of security holes due to sanity checks being removed that unintentionally exploited undefined behaviour.
 
So, I have made the changes, and now IonFury start with Polymost renderer on the Pandora. Unfortunatly, the SGX just can't cope with it, and it's even slower than software renderer.

For the curious, here the complete set of changes:
Code:
Index: Common.mak
===================================================================
--- Common.mak  (revision 8090)
+++ Common.mak  (working copy)
@@ -52,7 +52,7 @@

 ifndef SUBPLATFORM
     SUBPLATFORM :=
-    ifeq ($(PLATFORM),$(filter $(PLATFORM),LINUX DINGOO GCW CAANOO))
+    ifeq ($(PLATFORM),$(filter $(PLATFORM),LINUX DINGOO GCW CAANOO PANDORA))
         SUBPLATFORM := LINUX
     endif
 endif
@@ -364,7 +364,7 @@
 endif

 # Debugging/Build options
-FORCEDEBUG := 0
+FORCEDEBUG := 1
 KRANDDEBUG := 0
 PROFILER := 0
 # Make allocache() a wrapper around malloc()? Useful for debugging
@@ -405,6 +405,14 @@
     override NOASM := 1
 else ifeq ($(PLATFORM),$(filter $(PLATFORM),BEOS SKYOS))
     override NOASM := 1
+else ifeq ($(PLATFORM),PANDORA)
+    override USE_OPENGL := 1
+    override NETCODE := 0
+    override HAVE_GTK2 := 0
+    override HAVE_FLAC := 1
+    override NOASM := 1
+    override USE_LUAJIT_2_1 := 1
+    SDL_TARGET := 2
 endif

 ifneq (i386,$(strip $(IMPLICIT_ARCH)))
@@ -450,8 +458,8 @@

     LTO := 0
 else
-    OPTLEVEL := 2
-    LTO := 1
+    OPTLEVEL := 3
+    LTO := 0
 endif

 ifneq (0,$(CLANG))
@@ -576,6 +584,10 @@
     COMPILERFLAGS += -D__OPENDINGUX__
 else ifeq ($(PLATFORM),SKYOS)
     COMPILERFLAGS += -DUNDERSCORES
+else ifeq ($(PLATFORM),PANDORA)
+    COMPILERFLAGS += -D__PANDORA__
+    COMMONFLAGS += -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -ffast-math -ftree-vectorize
+    LIBDIRS += -lrt
 endif
 ASFLAGS += -f $(ASFORMAT)

Index: GNUmakefile
===================================================================
--- GNUmakefile (revision 8090)
+++ GNUmakefile (working copy)
@@ -670,7 +670,11 @@
 endif

 ifeq ($(SUBPLATFORM),LINUX)
-    LIBS += -lFLAC -lvorbisfile -lvorbis -logg
+    ifeq ($(PLATFORM),PANDORA)
+        LIBS += -lFLAC -lvorbisifile
+    else
+        LIBS += -lFLAC -lvorbisfile -lvorbis -logg
+    endif
 endif

 ifeq ($(PLATFORM),BSD)
Index: source/build/src/polymost.cpp
===================================================================
--- source/build/src/polymost.cpp       (revision 8090)
+++ source/build/src/polymost.cpp       (working copy)
@@ -1128,10 +1128,21 @@
     fogRangeLoc = glGetUniformLocation(polymost2BasicShaderProgramID, "u_fogRange");
     fogColorLoc = glGetUniformLocation(polymost2BasicShaderProgramID, "u_fogColor");

+    int polymost1BasicVertLen = strlen(polymost1Vert);
+    char* polymost1BasicVert = (char*) malloc(polymost1BasicVertLen);
+    memcpy(polymost1BasicVert, polymost1Vert, polymost1BasicVertLen);
+    char* extDefineSubstr = strstr(polymost1BasicVert, " #define POLYMOST1_EXTENDED");
+    if (extDefineSubstr)
+    {
+        //Disable extensions for basic fragment shader
+        extDefineSubstr[0] = '/';
+        extDefineSubstr[1] = '/';
+    }
     polymost1ExtendedShaderProgramID = glCreateProgram();
-    GLuint polymost1BasicVertexShaderID = polymost2_compileShader(GL_VERTEX_SHADER, polymost1Vert);
+    GLuint polymost1BasicVertexShaderID = polymost2_compileShader(GL_VERTEX_SHADER, polymost1BasicVert, polymost1BasicVertLen);
+    GLuint polymost1ExtendedVertexShaderID = polymost2_compileShader(GL_VERTEX_SHADER, polymost1Vert);
     GLuint polymost1ExtendedFragmentShaderID = polymost2_compileShader(GL_FRAGMENT_SHADER, polymost1Frag);
-    glAttachShader(polymost1ExtendedShaderProgramID, polymost1BasicVertexShaderID);
+    glAttachShader(polymost1ExtendedShaderProgramID, polymost1ExtendedVertexShaderID);
     glAttachShader(polymost1ExtendedShaderProgramID, polymost1ExtendedFragmentShaderID);
     glLinkProgram(polymost1ExtendedShaderProgramID);

@@ -1138,7 +1149,7 @@
     int polymost1BasicFragLen = strlen(polymost1Frag);
     char* polymost1BasicFrag = (char*) malloc(polymost1BasicFragLen);
     memcpy(polymost1BasicFrag, polymost1Frag, polymost1BasicFragLen);
-    char* extDefineSubstr = strstr(polymost1BasicFrag, " #define POLYMOST1_EXTENDED");
+    extDefineSubstr = strstr(polymost1BasicFrag, " #define POLYMOST1_EXTENDED");
     if (extDefineSubstr)
     {
         //Disable extensions for basic fragment shader
@@ -1152,7 +1163,10 @@
     glLinkProgram(polymost1BasicShaderProgramID);
     free(polymost1BasicFrag);
     polymost1BasicFrag = 0;
+    free(polymost1BasicVert);
+    polymost1BasicVert = 0;

+
     // set defaults
     polymost_setCurrentShaderProgram(polymost1ExtendedShaderProgramID);
     glUniform1i(polymost1TexSamplerLoc, 0);
Index: source/build/src/polymost1Vert.glsl
===================================================================
--- source/build/src/polymost1Vert.glsl (revision 8090)
+++ source/build/src/polymost1Vert.glsl (working copy)
@@ -1,5 +1,8 @@
 #version 110

+//include an additional space here so that we can programmatically search for and disable this preprocessor definition easily
+ #define POLYMOST1_EXTENDED
+
 varying vec4 v_color;
 varying float v_distance;

@@ -21,10 +24,10 @@

    gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
    gl_TexCoord[0] = mix(gl_TexCoord[0].xyzw, gl_TexCoord[0].yxzw, u_usePalette);
-
+#ifdef POLYMOST1_EXTENDED
    gl_TexCoord[3] = gl_TextureMatrix[3] * gl_MultiTexCoord3;
    gl_TexCoord[4] = gl_TextureMatrix[4] * gl_MultiTexCoord4;
-
+#endif
    gl_FogFragCoord = abs(eyeCoordPosition.z);
    //gl_FogFragCoord = clamp((gl_Fog.end-abs(eyeCoordPosition.z))*gl_Fog.scale, c_zero, c_one);

Index: source/build/src/tilepacker.cpp
===================================================================
--- source/build/src/tilepacker.cpp     (revision 8090)
+++ source/build/src/tilepacker.cpp     (working copy)
@@ -92,6 +92,7 @@

 static void maxheap_buildHeap()
 {
+    if(heapNodes<2) return;
     for (int i = (heapNodes-2)/2; i >= 0; --i)
     {
         maxheap_bubbleDown(i);
Index: source/build/src/voxmodel.cpp
===================================================================
--- source/build/src/voxmodel.cpp       (revision 8090)
+++ source/build/src/voxmodel.cpp       (working copy)
@@ -435,14 +435,14 @@
         index[(i*2+1)*3+2] = i*4+3;
     }
     GLint prevVBO = 0;
+    glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prevVBO);
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vm->vboindex);
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * 3 * 2 * vm->qcnt, index, GL_STATIC_DRAW);
-    glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prevVBO);
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prevVBO);
     prevVBO = 0;
+    glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prevVBO);
     glBindBuffer(GL_ARRAY_BUFFER, vm->vbo);
     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 5 * 4 * vm->qcnt, vertex, GL_STATIC_DRAW);
-    glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prevVBO);
     glBindBuffer(GL_ARRAY_BUFFER, prevVBO);
     Xfree(vertex);
     Xfree(index);
Index: source/duke3d/src/config.cpp
===================================================================
--- source/duke3d/src/config.cpp        (revision 8090)
+++ source/duke3d/src/config.cpp        (working copy)
@@ -227,11 +227,13 @@
     ud.config.MixRate = 44100;
 #elif defined __ANDROID__
     ud.config.MixRate = droidinfo.audio_sample_rate;
+#elif defined __PANDORA__
+    ud.config.MixRate = 22050;
 #else
     ud.config.MixRate = 48000;
 #endif

-#if defined GEKKO || defined __OPENDINGUX__
+#if defined GEKKO || defined __OPENDINGUX__ || defined __PANDORA__
     ud.config.NumVoices = 32;
     ud.camera_time = 11;
 #else

I'll switch back to software renderer, and will try to add the missing function to have an SDL1 build. I could then try to have it runs at 400x240 with hardware upscaling...
 
Please, would anybody be able to port a current version of Emacs? I've tried to ask Lukas who did the version 24, in repo comment with no response.
I'm willing to donate say 50 EUR via PayPal to successful porter to give at least a small reward for effort. Thanks in advance to anyone who makes an attempt!
 
Oh ... thanks for the heads up, I didn't know there's emacs bundled with Codeblocks beta (didn't update Codeblocks in years).

It's version 25.1.2 which is not the most up to date but the best on Pandora so far, awesome! Please, PM me your PayPal address so I can send you 25 EUR already.

It seems I can live with v25 but there are some emacs packages that require 26+ so if you would be so kind to pack separate PND (for convenience) with emacs 26+, I'll be happy to send another 25 in your direction. Thanks again for your restless effort! (not just with emacs)
 
Back
Top