Marathon on PSP!

Questions about the content creation procedure go here, including using Forge, Anvil, or other editors, or operating emulators like Basilisk II.
aander91
Born on Board
Posts: 20
Joined: Mar 3rd '09, 02:06
Contact:

Please excuse the fact that this is a remake of an older thread. The other one is old and has been locked, and I would still like to support others attempting to use this and maybe even get some help on expanding it.

Both Marathon Duarandal and Marathon Infinity are available on PSPs operating on a custom firmware!

Created by Mk_Bs

Download

Instructions:
1. Download and extract above files.
2. Place both folders in GAME150.
3. Replace FONT(s) file from any Marathon game.
4. Run!

IF YOU ARE USING A SLIM PSP:
1. Download Dark_Alex's LEDA Legacy loader.
2. Run LEDA
1. Download and extract above files.
2. Place both folders in GAME150.
3. Replace FONT(s) file from any Marathon game.
4. Run!

Note: DON'T PRESS ANYTHING WHILE "LOADING COLLECTIONS..."

To toggle Hi-Res graphics, press R+L+TRIANGLE.

I'm currently trying to add the Shots Fired, Hi Res Landscapes, etc. I will upload them once I get them all working. :D

Enjoy!
User avatar
Ares Ex Machina
Mjolnir Mark IV
Posts: 614
Joined: Jan 23rd '08, 08:07
Contact:

That sounds pretty damn awesome. Too bad I can't try it. Is multiplayer functional?
aander91
Born on Board
Posts: 20
Joined: Mar 3rd '09, 02:06
Contact:

No, at the moment it is just campaign.
0xMk
Spazeroid
Posts: 4
Joined: Jun 30th '10, 00:42
Location: Rome
Contact:

Hi there, I'm the developer of this port, I'm porting AlephOne to PSP again from scratch, using a different approach (I've learned from my mistakes!). The good news is that this one is more of a straight port (same user interface, file format, etc) and the whole trilogy seems to work fine, first Marathon included. The bad news is that I'm having a lot of unexpected issues, the biggest one being that loading collections now takes a HUGE amount of time, you have to wait something like 2 minutes before starting to play. Not the best user experience. I really don't know what's happening and this is really slowing down my progress with this port.
Anyway, I also wanted multiplayer to work very badly! I even ported SDL_net to PSP, but sadly I'm forced to work with an old version of AlephOne (20080721) because newer versions, adding support for shaders, seems to have broken the ability to disable OpenGL rendering when compiling and even if the PSP has limited support for OpenGL, most of the extensions AlephOne uses are not supported. For the reasons above I think that PSP<->PC multiplayer is not a possibility at the moment. PSP<->PSP multiplayer may still be possible though.
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

0xMk wrote:Anyway, I also wanted multiplayer to work very badly! I even ported SDL_net to PSP, but sadly I'm forced to work with an old version of AlephOne (20080721) because newer versions, adding support for shaders, seems to have broken the ability to disable OpenGL rendering when compiling and even if the PSP has limited support for OpenGL, most of the extensions AlephOne uses are not supported.
We have been a bit sloppy about this. Knowing someone depends on --disable-opengl, maybe we can be better about testing it before releases.

If there's anything I can do to help with this port (without actually being able to compile or test it) let me know!
aander91
Born on Board
Posts: 20
Joined: Mar 3rd '09, 02:06
Contact:

0xMk wrote:Hi there, I'm the developer of this port, I'm porting AlephOne to PSP again from scratch, using a different approach (I've learned from my mistakes!). The good news is that this one is more of a straight port (same user interface, file format, etc) and the whole trilogy seems to work fine, first Marathon included. The bad news is that I'm having a lot of unexpected issues, the biggest one being that loading collections now takes a HUGE amount of time, you have to wait something like 2 minutes before starting to play. Not the best user experience. I really don't know what's happening and this is really slowing down my progress with this port.
Anyway, I also wanted multiplayer to work very badly! I even ported SDL_net to PSP, but sadly I'm forced to work with an old version of AlephOne (20080721) because newer versions, adding support for shaders, seems to have broken the ability to disable OpenGL rendering when compiling and even if the PSP has limited support for OpenGL, most of the extensions AlephOne uses are not supported. For the reasons above I think that PSP<->PC multiplayer is not a possibility at the moment. PSP<->PSP multiplayer may still be possible though.
Excellent! I'm so glad you're still working on this. Have you tried bumping the processor up to 333 to get it to run faster? As always, I'll be available if you need to test it on the slim as well.
0xMk
Spazeroid
Posts: 4
Joined: Jun 30th '10, 00:42
Location: Rome
Contact:

aander91 wrote:Excellent! I'm so glad you're still working on this. Have you tried bumping the processor up to 333 to get it to run faster? As always, I'll be available if you need to test it on the slim as well.
I'm not sure, but if I remember correctly Sony enabled full speed on the Allegrex after firmware 3.50, but I'll have to check. Anyway that wouldn't probably make much of a difference because I'm quite sure that this is an I/O issue and not CPU speed related, but thanks for suggesting! As soon as I have something more usable, testing it on a Slim would be very helpful so I'll let you know... :)

Treellama wrote:We have been a bit sloppy about this. Knowing someone depends on --disable-opengl, maybe we can be better about testing it before releases.

If there's anything I can do to help with this port (without actually being able to compile or test it) let me know!
Thanks! Sadly I don't really know what's the issue right now, and the lack of a practical way to profile code on the PSP is not really helping me to acquire this knowledge. All that I understand is that the problem seems to lie somewhere in the load_bitmap function (shapes.cpp).
The strange thing about this is that in my older port, that used a very old version of Aleph One (PACKAGE_VERSION says 20051119), collections loaded in a few seconds. I've seen that the code for loading collections has been improved considerably by now, but such an increase in execution time makes me suspect of something on the PSP side, probably something memory or I/O related. If you can recall what were the changes for the collection loading code (load_bitmap in particular) since the old version I mentioned, anything that may have a bigger overhead on an embedded device comes to mind? Otherwise there's some place where I can get some info on how collections are loaded in Aleph One at the moment?

Thanks for your precious help!
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

0xMk wrote:Thanks! Sadly I don't really know what's the issue right now, and the lack of a practical way to profile code on the PSP is not really helping me to acquire this knowledge. All that I understand is that the problem seems to lie somewhere in the load_bitmap function (shapes.cpp).
The strange thing about this is that in my older port, that used a very old version of Aleph One (PACKAGE_VERSION says 20051119), collections loaded in a few seconds. I've seen that the code for loading collections has been improved considerably by now, but such an increase in execution time makes me suspect of something on the PSP side, probably something memory or I/O related. If you can recall what were the changes for the collection loading code (load_bitmap in particular) since the old version I mentioned, anything that may have a bigger overhead on an embedded device comes to mind? Otherwise there's some place where I can get some info on how collections are loaded in Aleph One at the moment?
Rather than loading each collection in one giant chunk, and setting pointers everywhere into that chunk, we now load the components of the collection into standard vectors. This is necessary to load shapes patches. Sequences and bitmaps, in particular, are stored in a std::vector<std::vector<uint8> >

So, this could increase overhead a little. I can't think what would cause a massive slowdown, though, unless there's some ridiculous penalty for memory allocations, which we do for each sequence and bitmap; or you were getting a weird cache benefit from the contiguous layout of the older collections.

The lack of adequate profiling tools makes things difficult. I assume this is due to the fact that you have to use homebrew firmware? You'll have to fall back on printfs and gettimeofday calls to figure out where the slowdown is. Yuck.

Another change to the collection loading code is that Aleph One scans the map for textures, scenery, etc. collections it needs to load, rather than just loading the one specified in the environment. It's easy to disable this if you want to see if that's affecting things, by commenting out the calls to mark_map_collections in marathon2.cpp.
Last edited by treellama on Jun 30th '10, 15:12, edited 1 time in total.
0xMk
Spazeroid
Posts: 4
Joined: Jun 30th '10, 00:42
Location: Rome
Contact:

Treellama wrote:The lack of adequate profiling tools makes things difficult. I assume this is due to the fact that you have to use homebrew firmware? You'll have to fall back on printfs and gettimeofday calls to figure out where the slowdown is. Yuck.
Yes, sadly. There was some kind of support for gprof but it doesn't work anymore on new firmwares so I'm out of luck.
I've managed to write a simple profiling class that outputs XML data. It's not very accurate because it uses SDL_GetTicks instead of clock cycles, but considering that we are definitely not talking about micro optimizations here it should help to shed some light on the matter.
I'll post back as soon as I get more info, thanks again for your help!
User avatar
Hopper
Mjolnir Mark IV
Posts: 585
Joined: May 10th '09, 17:02
Contact:

You may have already seen this, it was posted to Slashdot today:

http://blog.wolfire.com/2010/06/Aquaria-on-the-PSP

The issues discussed here seem very relevant to your current sticking point, touching on memory allocation woes (with STL, no less) and also on file-opening penalties.

Keep us posted, and I'll try to stop breaking --disable-opengl all over the place. [MErr]
Aleph One:  Download 1.2.1         Plugins:  Vasara  ·  more
User avatar
xilef
Cyborg
Posts: 186
Joined: Jul 6th '08, 22:30
Contact:

You're going to have to rewrite the loading into memory, I have cut down a loading time of 4 minutes to under a second after rewriting a texture loading algorithm, now I load textures first and scan them, don't ever scan from texture files, you want them in memory asap.
That's all I can say, just rewrite it to work on PSP specifically.
0xMk
Spazeroid
Posts: 4
Joined: Jun 30th '10, 00:42
Location: Rome
Contact:

Hopper wrote:You may have already seen this, it was posted to Slashdot today:

http://blog.wolfire.com/2010/06/Aquaria-on-the-PSP

The issues discussed here seem very relevant to your current sticking point, touching on memory allocation woes (with STL, no less) and also on file-opening penalties.
Thanks, I missed that and it proved to be quite an interesting reading. It think it's possible that the very same issues discussed on that article are the cause of my unidentified problem.
Anyway I took a chance to profile the code using the basic profiler I wrote and some interesting things came up. This is the parsed output of my profiler class:

Code: Select all

Analyzing file:  load_collections.xml
Function name                       Called     Avg. Time       Tot. Time      
----------------------------------- ---------- --------------- ---------------
load_collections                    1          1:42 s          1:42 s         
.load_collection                    11         3.23 s          1:39 s         
..load_clut                         11         3.2 ms          72.0 ms        
..load_low_level_shape              1171       1.94 ms         3.01 s         
..load_bitmap                       654        254.44 ms       1:33 s         
...load_bitmap-guess_row            654        84.29 ms        1:30 s         
....load_bitmap-guess_row-read_fl   33342      0.5 ms          23.9 s         
....load_bitmap-guess_row-seek      33342      1.11 ms         1:00 s      
..load_high_level_shape             163        2.2 ms          507.0 ms
As you can see, the problem lies in the load_bitmap function as I suspected. What's really unexpected is that the actual bitmap loading code is not the problem. What is really slowing down the whole thing seems to be the code fragment I labeled "guess_row" in the profiler, that corresponds to lines 609 to 634 of the shapes.cpp file. To be more precise, it seems that the real issue is with the SDL_RWseek call at line 624, that eats up a whole minute of the loading time!

At this point I think I'll do some beanchmarking on the SDL_RWseek function with the hope of understanding what's happening (maybe taking a look at how the function was implemented in the PSP's SDL port would be helpful). Given the profiler results it seems very likely to me that the issues with the uncached PSP's I/O operations mentioned in Jeffrey Rosen's post may be the cause of this unexplained SDL_RWseek behavior.

If you got any idea of what's going on, I'm listening!
Xilef wrote:You're going to have to rewrite the loading into memory, I have cut down a loading time of 4 minutes to under a second after rewriting a texture loading algorithm, now I load textures first and scan them, don't ever scan from texture files, you want them in memory asap.
That's all I can say, just rewrite it to work on PSP specifically.
I think that how Aleph One takes care of handling collections is pretty solid, even if the system was not designed with an embedded device in mind. Considering that developing a clean PSP-optimized solution to load collections and integrating it with the existing one is not a trivial task, I'd rather try to optimize the code that's already there. Not to mention that on my previous port of Aleph One for the PSP collections loaded in few seconds, and as far as improvements can go, a 2 minutes overhead sounds much more like a PSP specific issue than a problem with the code. But, anyway, thanks for suggesting!
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

0xMk wrote:At this point I think I'll do some beanchmarking on the SDL_RWseek function with the hope of understanding what's happening (maybe taking a look at how the function was implemented in the PSP's SDL port would be helpful). Given the profiler results it seems very likely to me that the issues with the uncached PSP's I/O operations mentioned in Jeffrey Rosen's post may be the cause of this unexplained SDL_RWseek behavior.
What stands out to me is the reverse seek on line 631. If I/O is really that broken on PSP, it's possible a reverse seek like that is implemented to read from the start of the file. Which will take forever.

If that's not it, or even if it is, uncached I/O is going to hurt you many places. Fortunately, it should be trivial to write a caching implementation of SDL_RWops.
PyroXfire
Born on Board
Posts: 8
Joined: Sep 21st '10, 17:49
Contact:

Hmm.. i donno about many people but id wait a few moments to play Marathon >_> but thats not the point lol Though i swear there where some type of debuging tools for the psp.. and i know if you use CWcheat you can take a look at whats going on in the running code. though its all in Assembly i belive . And what psp CFW are you aiming this for? other then that im going to go see if i cant dig up some debug tools for you. also for the sake of not confuseing i am the kid you emailed eariler ^^
User avatar
Sphting Distance
Born on Board
Posts: 51
Joined: May 30th '08, 16:07
Location: Pelham, New Hampshire
Contact:

Let me get this straight... You can't run this on your stock PSP, and need custom firmware? Is custom firmware easy to setup for the PSP, and where would I get it?
PyroXfire
Born on Board
Posts: 8
Joined: Sep 21st '10, 17:49
Contact:

S wrote:Let me get this straight... You can't run this on your stock PSP, and need custom firmware? Is custom firmware easy to setup for the PSP, and where would I get it?
Yes you need CFW and its easy once you know how to do it. Now getting to CFW all depends on what model psp you have and what Offical frimware you are running. if you want help you could give me an email at Afaryniak@gmail.com and id be more then happy to help you.
t3hm00kz
Born on Board
Posts: 12
Joined: Nov 25th '10, 00:40
Contact:

I love this concept.

I was actually planning on doing a Doom to Marathon mod just so I could have marathon on the go, but I haven't really kicked it off.. plus, I don't know if the doom engine could handle things like terminals and the like, and I'd have to improvise for stuff like bridges.

0xMk, are you planning on porting the engine itself to the PSP, for use of any third party mods? I'd love to be able to put RED into an eboot and play it on the go.

Also, I'm having problems starting the game. I've followed the instructions. Dragged and dropped the files into my game150 folder (When that didn't work I tried just the game folder) replaced the Fonts file, AND added it in and renamed it "Font." When I attempt to boot, I get the error "The game could not be started. (80020148)" I'm running cfw 5.00 M33-6 on a PSP fat (1000 series). Anything I could be doing wrong?

E:
Fixed that issue. Needed to install 1.50 kernal compatibility. Now the system shuts off when the game is "loading collections" when I hit new game... And yes, I have a fat. installed LEDA too just to see if it would work, and it doesn't.

Output:

Code: Select all

PSP AlephOne Crashed:

The offending routine may be identified with:

    psp-addr2line -e target.elf -f -C 0x89598e8 0xfff8833 0x895998c
PSP AlephOne Crashed:

The offending routine may be identified with:

    psp-addr2line -e target.elf -f -C 0x89598e8 0x0 0x895998c
PSP AlephOne Crashed:

The offending routine may be identified with:

    psp-addr2line -e target.elf -f -C 0x89598e8 0x0 0x895998c
Could this be an issue with the fonts file? If so, how would I go about obtaining a proper one? Even better, would anybody be able to upload a working folder for me?
Last edited by t3hm00kz on Nov 26th '10, 12:29, edited 1 time in total.
Nigel
Born on Board
Posts: 10
Joined: Dec 3rd '10, 01:21
Contact:

Hi,

Maybe my AlepOne for Dingux/Dingoo (MIPS32 based device) port might help with the PSP port. I've based mine on the 20091015 sources. While I could use the last source, pkg-config would give me *serious* headaches and there were no fixes as far as I could see to the software rendering part. Hence the choice stick with 20091015. 20100424 also introduced a vorbis crash bug on the Dingoo at least.


You can find it here, with sources: Dingoonity link for v3 and the v2 thread which has more screens.

Some features nice to porters:
- --disable-lua option restored, LUA can be excluded entirely saving quite some size in the binary and possibly avoiding compile errors on certain platforms (MIPS I, if anyone would want that)
- --disable-opengl restored. This was very easy, still is with the 2010 sources
- --disable-networking restored. There is no longer an sdl-net dependency

- Native 320x240. The hud, menu and game images use a smooth scaler. There's also a blocky scaler available and used for 8 bit support in AlephOne itself.
- Terminals also render and flow at 320x240, making for nice, readable text
- Software SDL_SetGammaRamp emulation for sceen flashes (damage, item pickup) and overlays (underwater). This only works on 16 bit (RGB565) but is easily done on 24/32 bit as well. Software gammaramp emulation only runs when it's needed unlike SDL_SetGammaRamp in AlephOne which is called every frame. Brightness options have been disabled to make sure it won't run all the time (anything other than dark loads a custom gamma table). It's fast.
- Fixes an engine rendering bug happening on the Dreamcast and GP2X ports as well, causing the liquid on the polygon next to the one you're standing on not to clip. I do not know where the bug itself is, just removed a swalpha related XOR which fixed it (all documented). Software alpha I've never gotten to work anyway. Perhaps it worked in 2001.
- Option to remap buttons when in automap mode added to shell.cpp. This was needed because this console (dingoo) didn't have enough buttons to map the map zoom keys too.
- Got some speed hacks and a lot of default prefs changed which you might want to undo on other platforms. Game runs at 30fps on the Dingoo, though it still has some drops to 20 sometimes. Thankfully the engine works very well under harsh conditions and with v3, those are hardly noticeable without fps counter anymore.
- Custom menu theme and a few dialog hacks to make it all fit nicely (including the keyboard setup and of course the load/save dialog) on 320x240 screens.
- More that you might or might not like

A few things that I remember that might be good to know:
- If SDL_Mixer is mixing in software/using something mixing in software, changing to 22KHz helps a lot. Do not change the DEFAULT_RATE define in the alephone source, it's used at one other place, to determine how quickly sounds should be repeated. However, this might be desired to halve or double the rate of, for example, assault rifle bullet sounds for performance or coolness.
- Having 50 monsters on the screen shooting each other, or big areas doesn't seem to be the speed bottleneck. Polygon complexity, however, is. Marathon Infinity's first level, or Tempus Irae's first back-to-earth level are great examples and tests. Animated textures like in the M1A1 Pathways intro (the red 'ghost'), appear to wreak havoc on performance. Thankfully the M1A1 intro is the only place you'll come across them in the main trilogy.
- AlephOne uses aroung 9-10 MB of RAM. Might be slightly less with LUA and network excluded.
- Compiling without vorbis (which is desired since Vorbis is @)$(* slow) causes the game to load an .ogg and play it back as raw data or so, giving quite a bit of noise that's even worse than the stuttering menu music you'd get with vorbis. Leave vorbis in instead (or fix it), and turn off menu music in pre-supplied Marathon 2 or Infinity prefs, or tell the user to convert the menu music .oggs to .mp3, editing files.mml to reflect this change. M1A1 does not have problems since it's using MP3 music in-game, which libmad decodes very quickly without noticeable hit in-game.
- The Boost headers are still required by the SDL interface. You need to change integer-traits.h for platforms it doesn't recognize (MIPS is one of those) and it isn't really built for cross compiling, but then again, you only need the headers not libboost (thank heaven). The original Marathon 2 Mac source will help a lot to have next to AlephOne to compare on trouble points. You can see what's changed, why it was changed and wether that C++ feature your compiler doesn't have is replaceable by something C/C++ universal (the original Mac source is written in C). The latter didn't apply to me, but might be if you're porting to something non-Linux with a simpler toolchain.


All source code changes are done using #ifdef HAVE_DINGOO <dingoo code> #else <orig code> #endif, so that they were easier to document and so that you can look at the official code at any time. This is my first C/C++ code attempt, so there's probably a lot you can improve. The dingoo also might not support stuff (yet) the PSP does (double buffering?). The PSP port will need a different scaler. This might be one of the few difficult things. Thankfully not difficult in code, that stuff just works with bitshifts, so C knowledge is not too important. Mine halves from 640 to 320, or the slower version used on every image, halves everything averaging out 4 pixels to 1 (box filter). You'd have to interpolate for the PSP's 480x272 or pick a close resolution for the HUD and images. Or, you could stay with 320x240 for HUD, terminal and scenario pics, and render the world (game window sans hud) and terminal at the full resolution. This might be the best looking (no interpolation noise) and fastest solution. Both the terminal and the game window just need a few tweaks to change to any resolution. The terminal code will reflow text automatically for you, and doesn't complain if the images would be a little smaller - though you will need to tweak positioning a bit. Very simple to hack around in that though.


You might also want to check out Pickle's GP32x port, on which the Dingoo port was based in its earliest versions. This port downscales the entire screen and contains the minimum changes required to 20091015 to compile without OpenGL, so the changes are way less daunting to newcomers. Without this port I wouldn't even have started since I did not know C/C++. Having something that compiles and does something definitely helps making you want to try and learn.

At last, you can also take a look at my source changes in alephone-dingoo v2, which only contains the native 320x240 res changes, box scaler and gamma emulation instead of changes all over the source and configure script for net and lua exclusion. It's therefore much easier to diff against a vanilla 20091015 source.



I hope I've made someone enthusiastic here, and that this code (mainly dirty hacks ;) and the things I found out will be of help to other hand-held porters. Have fun!


Cheers,

Nigel
Last edited by Nigel on Dec 3rd '10, 02:44, edited 1 time in total.
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

Some of your changes (SDL_GammaRamp) would be very useful to have in mainline. Any chance you kept changes in patch form rather than one big source? :)

Software alpha didn't work in 2001, I added that a few years ago. "Nice" is layout independent, so should work (slowly) on MIPS. "Fast" probably won't work unless you're little endian.

As for Vorbis, you could give Tremor a try ::shrug::

If this many console ports are active, it might make sense to restore --disable-lua/--disable-networking/--disable-opengl in the mainline.
Last edited by treellama on Dec 3rd '10, 03:20, edited 1 time in total.
Nigel
Born on Board
Posts: 10
Joined: Dec 3rd '10, 01:21
Contact:

Treellama wrote:Some of your changes (SDL_GammaRamp) would be very useful to have in mainline. Any chance you kept changes in patch form rather than one big source? :)
Uh... what's a patch? Those .diff things? Haven't touched anything related to C++/make/gcc before two months back so I'm still catching up :P. I could make those, but the code currently is tailored for RGB565/16 bit and totally not endian safe, so it needs a little work. Also, on 320x240 (or 320x160, I'm not including the HUD, only the world surface) it's fast but on, let's say, 1900x1200 it would probably be damn slow going through every single pixel.

[

Code: Select all

]
screen.cpp

/* [Line 100, somewhere at the top with the other defines:] */
#ifdef HAVE_DINGOO // Dingoo software gammaramp -- Nigel
void dingoo_swgammaramp(SDL_Surface *s);
uint8 gammatablered[32],  gammatablegreen[64], gammatableblue[32];
bool do_dingoogamma = false;
#endif // END dingoo hack


/* [in function update_screen] */
static void update_screen(SDL_Rect &source, SDL_Rect &destination, bool hi_rez)
{
#ifdef HAVE_DINGOO // Dingoo software gamma hack. For now, we won't do the whole screen but only the game world, this saves processing -- Nigel
	// Small update on that, processing takes not too much speed. Could be enabled full screen and in the menus too in the future.
	if (do_dingoogamma) {
		dingoo_swgammaramp(world_pixels);
	}
#endif
	if (hi_rez) {
/* [...] */

/* [hack to create tabes in animate_screen_clut] */
void animate_screen_clut(struct color_table *color_table, bool full_screen)
{
	if (bit_depth == 8) {
		SDL_Color colors[256];
		build_sdl_color_table(color_table, colors);
		SDL_SetPalette(main_surface, SDL_PHYSPAL, colors, 0, 256); // 8 bit flashes work -- Nigel
	} else if (!option_nogamma)
	{
#ifdef HAVE_DINGOO // Dingoo software gammaramp hack -- Nigel
	do_dingoogamma = false;	// Do not apply if no change (saves around 15% in no-screen-color-overlay areas, that's what the swgamma code takes away on the Dingoo).


	if (memcmp(color_table, uncorrected_color_table, sizeof(struct color_table)) != 0)
	{
		do_dingoogamma = true;
	}
/* Old way of checking
	for (int i=0; i < color_table->color_count; i+=32) { // Little cheating here, 8 loops max
		// You could use world_color_table here to get around having to disable gamma_correct_color_table but I'm afraid the other effects might receive the gamma correction and won't match :P
		if (	!(color_table->colors[i].red == default_gamma_r[i]) ||
				!(color_table->colors[i].green == default_gamma_g[i]) ||
				!(color_table->colors[i].blue == default_gamma_b[i]))
		{
			do_dingoogamma = true;
			break;
		}
	}
*/

	if (do_dingoogamma)
	{
		Uint8 c = 0; // We only need 32 out of 256
		// Red and blue are 5 bit instead of 16.
		for (int i=0; i < color_table->color_count; i+=8) {
			gammatablered[c] = (color_table->colors[i].red >> 11); // This should give a 5 bit number, sdl_setgammatable values are 16 bit (why? puzzles me too)
			gammatableblue[c] = (color_table->colors[i].blue >> 11);
			c++;
		}
		// Green, on the other hand, is 6 bit in RGB565/16 bit color.
		c=0;  // We only need 64 out of 256
		for (int i=0; i < color_table->color_count; i+=4) {
			gammatablegreen[c] = (color_table->colors[i].green >> 10); // And this 6 bit.
			c++;
		}
	}
#else
		uint16 red[256], green[256], blue[256];
		for (int i=0; i<color_table->color_count; i++) {
			red[i] = color_table->colors[i].red;
			green[i] = color_table->colors[i].green;
			blue[i] = color_table->colors[i].blue;
		}
		if (!option_nogamma)
			SDL_SetGammaRamp(red, green, blue);
#endif
	}
}


/* [finally, the function itself, which is likely not endian safe. I see now I could eliminate a shift, so it's not totally optimal either] */
#ifdef HAVE_DINGOO // START Dingoo gamma function: Apply software gammaramp to a 16 bit surface (no endianess check!). Assumes gammatables are already prepared. -- Nigel
void dingoo_swgammaramp(SDL_Surface *s)
{
	Uint32 pixelcount = s->w * s->h; // Total pixel count, will exceed 320x160 if HUD is disabled so 32 bit int is needed for full 320x240.

 	Uint16* Source = (Uint16 *)s->pixels;
	Uint16* Target = (Uint16 *)s->pixels;

	for (int curpixel = 0; curpixel < pixelcount; curpixel++)
	{
		*Target = (gammatablered[*Source >> 11 & 0x1F] << 11 | gammatablegreen[*Source >> 5 & 0x3F] << 5 | gammatableblue[*Source & 0x1F]);
		Source++; Target++;
	}
}
#endif

/* For any reader looking for this, consider this simple gammaramp emulation method (non-alephone code) public domain. It's not like you won't rewrite it anyway. */
[/[code]]

Code might look messy, but copy it to your C editor and I'm sure you'll see what it does right away. Although it took me a long while to figure that all out ('gamma' is just a color lookup table, gee), the result is ridiculously simple.

If you wish I can take this up myself - make something endian safe that does 32 bit too (I do have PPCs here). Do keep in mind that I'm new to this stuff and that I probably do everything that's considered forbidden in C land :D.





[quote]Software alpha didn't work in 2001, I added that a few years ago. "Nice" is layout independent, so should work (slowly) on MIPS. "Fast" probably won't work unless you're little endian.[/quote]Hm, I can't get it to work on the Windows version either, though apart from the setting I haven't searched/tried to see what the problem is. Software alpha blending has to do with transparency and liquids, no? If that's not something that's been broken for ages like I thought I definitely want to give it a shot on that device, slow or not. The dingoo is a MIPS clone, the linux that runs on it is mipsel, little endian - "fast" is an option then. And although I tried to go 1:1 with the original game, transparent liquids is something to make an exception for :).

Can't say I'm surprised little people are using software rendering on the main platforms though with the cool OpenGL glow effects and all in the latest versions. The drones with the red dots look especially cool in dark areas.





[quote]As for Vorbis, you could give Tremor a try ::shrug::[/quote]
Wow, I should suggest that to the Dingux guys. If I understand correctly it could just replace the normal lib, same calls? Something for them to figure out.


[quote]If this many console ports are active, it might make sense to restore --disable-lua/--disable-networking/--disable-opengl in the mainline.[/quote]
Would be cool, though it takes an hour or two to do it at the moment since most stuff is still nicely split up. Only a few if/thens and, well, if you do it like me and exclude the SDL network widgets and core game network support too a few minor function or array changes.

Excluding LUA and networking does not increase in-game speed by the way. Not in a way I noticed at least. Just shortens startup time to near-instant (slow reading SD card reader) and brings the mipsel binary from 5 MB back to 1,8 MB. That's why I took care to re-enable a configure flag for networking - if someone asks I can just compile that in again.


I think the hardest part of cross-compiling is fighting the configure script itself, it is a bit hard to edit if environment variables aren't enough to generate good makefiles. For me this was not a problem. Before deciding I wanted HAVE_DINGOO and exclude network support it configured right with just a --host and --prefix flag. The 2010 version, however, is using pkg-config. I didn't get that to work right and started patching the resulting config.status file instead before eating my fingers. A 'make' would then just regenerate the make files before building from the .status file (iirc, been a while).


Drat, I went on too long again. If you're using OS X, feel free to use the "Summarize" option on this post.
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

Nigel wrote:Uh... what's a patch? Those .diff things? Haven't touched anything related to C++/make/gcc before two months back so I'm still catching up :P.
Nice. Check out SVN or Mercurial. Either will let you create a local repository, and keep track of each change you make to your code. Very useful for if you screw everything up and just want to go back to the last time it worked. You can also generate .diff files between revisions easily.
Hm, I can't get it to work on the Windows version either, though apart from the setting I haven't searched/tried to see what the problem is. Software alpha blending has to do with transparency and liquids, no? If that's not something that's been broken for ages like I thought I definitely want to give it a shot on that device, slow or not. The dingoo is a MIPS clone, the linux that runs on it is mipsel, little endian - "fast" is an option then. And although I tried to go 1:1 with the original game, transparent liquids is something to make an exception for :).
It is transparent liquids, yes. You need to install Software_Transparent_Liquids.mml in your Scripts/ folder. "Fast" also depends on the exact pixel format SDL uses which may be different for your platform. Check out the "average" templates in low_level_textures.h if it gives you trouble.
Wow, I should suggest that to the Dingux guys. If I understand correctly it could just replace the normal lib, same calls? Something for them to figure out.
Not quite a drop-in replacement. You need to include ivorbisfile.h instead of vorbisfile.h, and, of course, functions like ov_time_total return int64s instead of doubles. For Aleph One's decoder, it should be drop in, just change the header file. For other stuff, not so much.

I killed --disable-lua when I switched to using embedded Lua rather than system Lua, because I knew I'd always have it. If it makes a big difference being able to compile without it, we can probably bring back --disable-lua. Lua is probably not very useful on console ports that are geared towards the original trilogy.
Nigel
Born on Board
Posts: 10
Joined: Dec 3rd '10, 01:21
Contact:

Sorry for the late reply.

Both 'fast' and 'nice' work on PPC. If I didn't know better I'd assume it was OpenGL, very nice. Didn't get it to work on Windows for some reason, even with the software mml there. Perhaps that's because I overwrote the other scripts with the ones that came with the M2 data there.

I'll attempt to restore the functionality on the Dingoo to see how big the performance impact is, however, disabling part of it in the source did solve the liquid clipping bug on the dingoo and possibly others. I was so happy that it was finally fixed that I didn't attempt to figure out if I was fixing the source cause or just working around it. Like "*omgyay it works!* not touching again"

FYI, poly-next-to-your-poly-doesn't-clip-sprites-through-media 'fix'.
Perhaps you immediately know what went/goes wrong or if it goes wrong here or not. I could shoot some screens or a video if you want to see that clipping bug in action (dingoo has composite tv-out).
Mind the #ifNdef:

Code: Select all

void RenderRasterizerClass::render_node_object(
    render_object_data *object,
    bool other_side_of_media)
{
    struct clipping_window_data *window;
    
    for (window= object->clipping_windows; window; window= window->next_window)
    {
        object->rectangle.clip_left= window->x0;
        object->rectangle.clip_right= window->x1;
        object->rectangle.clip_top= window->y0;
        object->rectangle.clip_bottom= window->y1;
        
        // Models will have their own liquid-surface clipping,
        // so don't edit their clip rects
        // This is bitwise XOR, but is presumably OK here
#ifndef HAVE_DINGOO // **THIS** is what caused the media clipping bug! Guess that XOR wasn't OK after all on MIPS, or perhaps the problem lies elsewhere. Removing the other side check solves it tho  -- Nigel
        if (view->under_media_boundary ^ other_side_of_media)
        {
            // Clipping: below a liquid surface
            if (object->rectangle.ModelPtr)
                object->rectangle.BelowLiquid = true;
            else
                object->rectangle.clip_top= MAX(object->rectangle.clip_top, object->ymedia);
        }
        else
        {
            // Clipping: above a liquid surface
            if (object->rectangle.ModelPtr)
                object->rectangle.BelowLiquid = false;
            else
                object->rectangle.clip_bottom= MIN(object->rectangle.clip_bottom, object->ymedia);
        }
#else
        if (view->under_media_boundary)
        {
            object->rectangle.clip_top= MAX(object->rectangle.clip_top, object->ymedia);
        }
        else
        {
            object->rectangle.clip_bottom= MIN(object->rectangle.clip_bottom, object->ymedia);
        }
#endif
        // LP: added OpenGL support
        // LP: using rasterizer object
        RasPtr->texture_rectangle(object->rectangle);
    }
}
EDIT: It's the ^ other_side_of_media, just noticed I removed more stuff but that's just because I've been experimenting with performance a bit and didn't need 3D models on the Dingoo (which I assumed ModelPtr was for).


As for development, any software you recommend? Reason I'm late is that Eclipse/Windows started complaining again about 'no JRE found' after a Java update and I couldn't be arsed to fix or even think about it again. It's not the first time this happened and I hate troubleshooting when I just want to get something done. Right now I'm about to just move stuff and use XCode/BBEdit/Coda on the Mac but if you know of something else I'm all ears.
Last edited by Nigel on Dec 8th '10, 04:38, edited 1 time in total.
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

Bitwise XOR on two booleans should be the same as a logical XOR, but maybe the MIPS compiler is buggy. Can you try this:

Code: Select all

if ((view->under_media_boundary ? 1 : 0) ^ (other_side_of_media ? 1 : 0))
Let me know if that works, I'll change the source.

As for development environments, I use emacs, gcc, and gdb in Linux myself. If you want an IDE, I guess Xcode is OK. So is Eclipse.
Last edited by treellama on Dec 8th '10, 14:07, edited 1 time in total.
Nigel
Born on Board
Posts: 10
Joined: Dec 3rd '10, 01:21
Contact:

Treellama wrote:Bitwise XOR on two booleans should be the same as a logical XOR, but maybe the MIPS compiler is buggy. Can you try this:

Code: Select all

if ((view->under_media_boundary ? 1 : 0) ^ (other_side_of_media ? 1 : 0))
Let me know if that works, I'll change the source.




As you can see that's a 'nope'. Seems the problem might lie in other_side_of_media then, perhaps in some overzealous OpenGL exclusion on my side, though the gp2x code did the same (then again, also OGL/OGL-XML tag exclusion). I'll put it on the list of 'things to figure out'.

It's not that important for the Dingoo version, the last version does everything correctly and runs fast so there's no rush for an update. If there's gonna be one transparent liquids is definitely something I'm going for though.

EDIT: Hm...
view->under_media_boundary ^ 0
view->under_media_boundary ^ 1
do the same thing as 'view->under_media_boundary ^ other_side_of_media' as in, clipping bug still there. Perhaps it is te xor? Nah, those are used elsewhere too.



EDIT 2: I am a fool.

Code: Select all

if (view->under_media_boundary ^ other_side_of_media)
        {
            // Clipping: below a liquid surface
//            if (object->rectangle.ModelPtr)
//                object->rectangle.BelowLiquid = true;
//            else
                object->rectangle.clip_top= MAX(object->rectangle.clip_top, object->ymedia);
        }
        else
        {
            // Clipping: above a liquid surface
//            if (object->rectangle.ModelPtr)
//                object->rectangle.BelowLiquid = false;
//            else
                object->rectangle.clip_bottom= MIN(object->rectangle.clip_bottom, object->ymedia);
        }
Working properly.
Guess I didn't try it without removing the ModelPtr stuff after all. Sorry!
Last edited by Nigel on Dec 8th '10, 15:08, edited 1 time in total.
Nigel
Born on Board
Posts: 10
Joined: Dec 3rd '10, 01:21
Contact:

Well, got everything setup. Started on implementing software gammaramp emulation and...

http://marathon.svn.sourceforge.net/viewvc...p;view=revision

... oh noes I'm beaten to it by 'jeremiahmorris'! Ouch... but maybe for the better, my implementation would've been less nice, to say the least.
Last edited by Nigel on Dec 9th '10, 02:58, edited 1 time in total.
Post Reply