adventuregamestudio / ags

AGS editor and engine source code
Other
695 stars 159 forks source link

a path towards moving from Allegro to SDL #1096

Closed ericoporto closed 3 years ago

ericoporto commented 4 years ago

ags/wiki/SDL-Migration-proposition.md

The document is in the wiki so people can write in and clarify! If you are worried about losing your edit, do it using git, the document is SDL-Migration-proposition.md on the root directory.


I wrote above a document proposing a path toward migrating from Allegro, meaning, removing Allegro dependency completely, and using instead mostly SDL. It may turn out we need something else too.

Since last ags3-sdl2 port did not get merged, this tries to detail a plan, with ags4 in mind and focus on complete removal of Allegro.

Please comment , also accepting people to write the code. My central idea was to have code flowing towards this goal into AGS repo.

ivan-mogilko commented 4 years ago

I may be overreacting, but I don't like this sentence:

also accepting people to write the code. My central idea was to have code flowing towards this goal into AGS repo.

This is not the kind of task to be made by multiple contributors doing small changes, there must be a general plan and focused developer(s) to overwatch the process. It's better to have 1-2 people with good understanding of the engine code working on this to keep things organized. At most only truly distinct feature that could be done separately is audio.

ericoporto commented 4 years ago

I think a minimum of two people is required. I expressed badly, but writing code requires, other than the code: fix vcxproj files, fix makefiles, fix cmake files, testing and fixing initially in two (Windows and Linux?) , than three (MacOS), than 4 (Android), depending how libraries are inserted building or including these libraries (which means adding in the three dockerfiles), ... Even if is one for doing everything and the other to help testing.

I think it's important to decide if we are building statically or dynamically (should game.exe accompany a SDL.dll ?) and how SDL gets in AGS project (code in repo or reference). It's important to note SDL may also go into editor due to Native.dll.

Edit: switched ordering so it starts with audio, but a note that SDL doesn't support all audio features we have on allegro and will require additional libraries if those features are desired. I tried to briefly explain it in the wiki.

Edit2: just discovered the SDL sources include vcxproj files, so maybe someone can figure out a way to include them in the Engine solution in a way that both Common.lib and Engine picks it. This way we add the SDL source directly in our repo and just link it using CMake / Makefiles on Linux and MacOS builds.

Edit3: It almost builds on Windows, it fails at link with the AGS Engine, perhaps someone knows what is wrong in this: https://github.com/ericoporto/ags/commit/bbcc61d662b39acb5ae70498b2889b0305604ad2

JanetGilbert commented 4 years ago

Hi, this is interesting to me as Wadjet Eye is attempting to get our games ported to Switch. We started working with Nick Sonneveld but then the project went on hiatus for a year and now we are working with Eduardo Garcia. We are using the method of using Nick Sonneveld's SDL version of AGS combined with Ryan C. Gordon's port of SDL to Switch. I'm not sure how much we can share code as all the Switch stuff is under Nintendo's NDA so it can't be open source.

ericoporto commented 4 years ago

Hey @JanetGilbert , can you take a look at the path proposition and show to Eduardo Garcia too? The way the proposal diverges from @sonneveld approach is it prioritizes cutting ties from Allegro instead of relying in it's methods and reworking them in the backend. Sonneveld also changed other things that didn't make sense for me until you mentioned the Switch xD. I ommitted them here because I wanted the minimal things to move for SDL pure as fast as possible so other more interesting problems can be dealt with.

JanetGilbert commented 4 years ago

I'm not the techie on this project, AGS for SDL wouldn't compile for me! So Eduardo is handling the engine stuff, and I'm just going to be working on the scripting. I'm pretty sure it'd be easier to compile the less it depends on Allegro and associated libraries so I'm all for it. I've asked Eduardo to post here with his opinions.

Arcnor commented 4 years ago

Hi there. As @JanetGilbert mentions I'm working on porting AGS to the Switch. I started using Nick's port, although I've modified it a lot, which means my changes are far away both from AGS master & Nick's original changes :).

In any case, this is what I think it's best for a future version of AGS, in somewhat random order (sorry about that). I'm also assuming backwards compatibility is not desired, and if it is, separate tools can be written to deal with the migration. What I don't think should happen is maintaining support for both versions in the same engine, as there are certain things that cannot be reconciled (just my humble opinion, like everything I'm going to add here, please keep that in mind 😄 ):

First of all, in general (and stuff I'm already doing) should be dropping support for the following:

About the wiki entries themselves: Path handling: Forget about using SDL or rolling your own, using dirent in Windows, etc, etc... There are many options in 2020 to deal with this as I mentioned before, and this is an excellent example of it. One of the best and most simple ones is just using PhysFS, which also happily works on consoles, and abstracts things like paths or even "containers" (you can have files inside a zip or in a directory, but in the end PhysFS abstracts all that). It's also by the main maintainer of SDL, so you know quality is at least as good.

SDL Library placement in Filesystem and CMakeLists.txt, Makefile, Vcxproj and SDL in the CI and Dockerfiles: This is a non issue, just use CMake for everything, SDL just works with it everywhere (I have it compiling for Linux, Windows, macOS and Switch on my own CI) and has its own CMakefile already. If you start juggling with different build systems you're going to have a bad day... Also, don't "ignore Android & iOS", it should work as well (I haven't added a build step for them, but I'm not expecting big issues with them, except maybe iOS for a bit, but it's a one time thing)

SDL Video and Window handling and graphics and SDL and Directx9 renderer: If you use the SDL Renderer API everything should just work everywhere (including consoles and smartphones), the only reason not to do it is in case you need special shaders or similar. The only shader I've seen cannot be replicated directly is lighting, but that might just mean there might be another way of getting the same or a similar result using the SDL Renderer API instead of having the exact 100% result that AGS3 does today, given that AGS4 is a clean break. It's also a good opportunity to drop the madness around transparency working in different ways depending if you have a value of 0, 1 to 250 or >250... Same for tinting, even if it doesn't match the AGS3 algorithm, just doing a simple color multiplication like the SDL Renderer API does should be enough...

All of that said, this is not the approach I'm going for, because the way in which AGS does rendering today doesn't match modern architectures (direct framebuffer access is not a thing anymore, anywhere) AND I need to keep compatibility with AGS3 because of Wadjet Eye's games, but the way I'm using is an even more extreme change so you might not want to do that for now, although I think it's the best option moving forward. As a summary, I'm not using SDL or its API for rendering, and also there is a lot of preprocessing of the data before it can be used with my fork of the engine, but it speeds up things tremendously, which is required for the Switch and maybe other platforms. I'll post more details if you're interested, although it's a work in progress and I'm a week or two away until I verify that everything works 100% like before.

But again, if you can use SDL Rendering and its limitations, it will work EVERYWHERE, which is work you don't need to do, as other people with way more experience is taking care of all the platform stuff for us.

Reduce Allegro BITMAPS part 1: Most of the mentioned libraries for antialiasing can just be dropped if the AA process is left to the driver (OpenGL, Metal, etc), but I guess you know this already, it's just not clear from the text.

For the rest I don't have any strong opinions yet, it's also a bit vague in many places like audio, so that's it for now.

morganwillcock commented 4 years ago

@Arcnor thank you for posting this here

the way I'm using is an even more extreme change so you might not want to do that for now, although I think it's the best option moving forward. As a summary, I'm not using SDL or its API for rendering, and also there is a lot of preprocessing of the data before it can be used with my fork of the engine, but it speeds up things tremendously, which is required for the Switch and maybe other platforms. I'll post more details if you're interested

I think we also looking to change the project data formats and the whole game/media build pipeline, since what exists now is too dependent on the editor and hampers user workflow in general. It would be very interesting to learn more when it is convenient to you.

Arcnor commented 4 years ago

@Arcnor thank you for posting this here

the way I'm using is an even more extreme change so you might not want to do that for now, although I think it's the best option moving forward. As a summary, I'm not using SDL or its API for rendering, and also there is a lot of preprocessing of the data before it can be used with my fork of the engine, but it speeds up things tremendously, which is required for the Switch and maybe other platforms. I'll post more details if you're interested

I think we also looking to change the project data formats and the whole game/media build pipeline, since what exists now is too dependent on the editor and hampers user workflow in general. It would be very interesting to learn more when it is convenient to you.

You're welcome @morganwillcock :). In any case, it looks like I misinterpreted what this ticket was about and there was a discussion about it here https://discordapp.com/channels/221047797292597249/221048199895449600/725838953147662358 so I'll let others comment on the best way to continue.

morganwillcock commented 4 years ago

@Arcnor Unfortunately I missed the conversation in-person, but I did read it earlier and was a little disheartened by the direction it went in... I guess we will see how things turn out, but it would be good to stay in touch.

ivan-mogilko commented 4 years ago

From that discussion it appeared to me that we do not have the same understanding even of the goals, or relevant problems.

Personally I believe that the above advices are good, even if we won't use all of them. And it's definitely will be useful to exchange ideas (so long as they may be disclosed and not part of private code etc).

However, my impression was that this ticket is meant strictly for the purpose of replacing one backend library with another, which is a good first step. After that further changes could be done.

The main purpose of this replacement is to have contemporary library underneath, and really not much else.

morganwillcock commented 4 years ago

I think the discussion was broader that what relates to this single ticket. I don't really see much logic to taking the branch that is decided to drop backwards compatibility and actually have significant modification, force yourself to port the graphics backend accommodating all the current features and issues, and then at the end of the process look at potentially removing some of those features and fixing some of those issues.

ivan-mogilko commented 4 years ago

Alright, then, maybe I don't understand the goals at all. Do I understand correctly that you suggest to first rewrite the engine's object logic and change backend only after?

ivan-mogilko commented 4 years ago

force yourself to port the graphics backend accommodating all the current features and issues, and then at the end of the process look at potentially removing some of those features and fixing some of those issues.

Another thing, tbh that's a bit abstract statement. The question is, what is ought to be removed, and whether porting introduces extra difficulties solving which may eventually come redundant. From what I understood (but did not check closely yet) that port keeps existing AGS renderers, only using SDL for drawing bitmaps (same way as allegro is used now). At the same time it provides more stable contemporary system support for window creation, input etc, which may at least give certain relief in these areas.

I think any concerns about SDL port need to be clarified and discussed, to make sure everyone's see the same picture.

ericoporto commented 4 years ago

https://github.com/adventuregamestudio/ags/compare/ags4...ericoporto:ags4--sdl2-sound-1

Above is a branch with Sonneveld's SDL2 sound implementation applied to AGS4 branch.

Sound turned out to be the biggest impact on the branch.

It includes the following:

As soon as threads are added for the sound to work well a lot of things will go crazy, if you run through a debugger it's pretty obvious that things are getting interrupted, you will step over/into and be met with a new context in the next step, in the case, the sound system will try to read something just before it's ready.

I imagine new strings and PhysFS was pushed into as a solution to this, the other alternative would be probably adding mutexes, but the new libraries work and reduce code.

This branch has only been built using CMake 3.16 (in CLion 2020.1) on Ubuntu 20.04. For Windows VS2019 with CMake it will clash when building allegro_main.cpp since both Allegro and SDL2 add a macro that redefines the main(argc,argv) on Windows. For this I need someone with Windows experience to help. For this reason the Editor is broken here - can't build AGS Native.dll.

Anyone with a Linux machine and a game compatible with ags4 (3.5.0.1-3.5.0.23 I think?), I highly recommend building this branch to listen to it as it sounds amazing.


Sorry for the confusion, this was a practical ticket of steps to get to SDL replacing Allegro. I didn't meant to diverge and discuss why.

ivan-mogilko commented 4 years ago

AGS Strings based on std::string, with additional nonstd::string_view added for script dicts. These are apparently needed for the multithreading (may not be if we use mutexes?);

I don't know how this is done in that branch, but in general sense they are not needed for multithreading, and mutexes would be required to protect std::string as well, as they are not protecting themselves.

C++ is kept at 11 but we can go 17 and just get the new features directly;

I would not do that right away unless critically needed (which I doubt it is). Every upgrade like this changes compiler requirement (and that's different on every platform) so this is something to be very careful about.

ericoporto commented 4 years ago

I don't know how this is done in that branch, but in general sense they are not needed for multithreading, and mutexes would be required to protect std::string as well, as they are not protecting themselves.

Makes sense. I was going from reading the comments, commits and discussions. Not actually the code, or documentation which I should have :/

I would not do that right away unless critically needed (which I doubt it is). Every upgrade like this changes compiler requirement (and that's different on every platform) so this is something to be very careful about.

Yes, makes sense.

Just to be clear, the branch doesn't actually upgrade the C++ to 17, I just mentioned it because I added some polyfill features from 14 and 17 to make the branch work (only string_view and make_unique), but these are coded there in C++11.


This is the same branch above (ags4 + MojoAL +SDL2 + SDL Sound), but it has the code before the std::string switch and PhysFS addition: https://github.com/ericoporto/ags/commits/ags4--sdl2-sound

The game will play in silence if you build for release, but if one build for debug it should crash when trying to access a buffer before the data is there. The thread method is on audiocore class.

Unfortunately I also only ran and built with CMake (through CLion 2020.1) and Ubuntu 20.04.

ivan-mogilko commented 3 years ago

Just a note to above branches, since I started investigating them, the commits there are real mess, with all due respect :-D: a single commit called "adds PhysFS support..." for example changes a whole lot of stuff at once, both related and not related to streams, moves code around etc. Need to try and split these in smaller changes to understand what's going on. Probably will try without extra libs, and without new utility classes (if possible) at first, as I want to know how all that is relevant to the multithread problems.

ivan-mogilko commented 3 years ago

As for the steps, I tend to agree that sound may be easiest to replace, because it's pretty much a separate thing.

I also learnt there is a way to use SDL in your program without SDL main and loop, which maybe will help to create intermediate builds, gradually replacing Allegro to SDL in various engine parts.

ericoporto commented 3 years ago

The commits are indeed a mess. Trying without extra libs is a good strategy! I am excited you are looking into this. :)

ivan-mogilko commented 3 years ago

I cloned the test branch and added few fixes to build on Windows: https://github.com/ivan-mogilko/ags-refactoring/tree/ags4--sdl2-sound-1

PhysFS appeared to be completely unnecessary, used in one class which may be disabled (there's few cases of unused new code overall, maybe prepared for the future).

I added SDL2 static lib from their website directly for this test. I don't know whether it's best option to have full SDL2 source in the repository, or why it was made so in the first place (for simplicity sake?).

EDIT: although it compiles, it does not really work though, when trying to play a sound it displays several assertions fail and then crashes; so I must investigate further.

rofl0r commented 3 years ago

I don't know whether it's best option to have full SDL2 source in the repository

this doesn't sound good at all, much less so "best"

ivan-mogilko commented 3 years ago

@ericoporto unfortunately the code as it is does not work at least for me.

I suspect that sound playback init has some actions in a wrong order.

Without going too much into details, what happens there is that ALSource is getting polled by the internal thread (mix_context in mojoal.c) earlier than it's initialized with actual data (call to alSourceQueueBuffers in our audio_core.cpp). Because of that sound gets discarded by mojoal and never really plays.

I'll have to research this further, because I had no experience with this sound library before.

ericoporto commented 3 years ago

image @ivan-mogilko I get the following error with VS2019's CMake when building your branch.

I haven't build my branch on Windows, as I note there, the only place I tested at the time was Ubuntu 20.04 and latest CMake there.

I suspect that sound playback init has some actions in a wrong order.

This is possible, my first approach used only the audio core and nothing else (I think basically no changes except on the media folder). At the time I got a "race condition" (not sure, the context switched and the audio data was gone in the next step) trying to access the vox package.

this is the branch: https://github.com/ericoporto/ags/commits/ags4--sdl2-sound

this is the significant commit: https://github.com/ericoporto/ags/commit/611b12c021663591ca78aa94bd95bf071d0655d4

But after I pulled more things from Sonnevelds branch (the branch you looked into) then it worked - so this is why I dismissed this at the time.

The game I used to test at the time was Tea for Two.

I'll have to research this further, because I had no experience with this sound library before.

This is valid. Overall I see Icculus libraries being used in most games I play but I find their documentation kinda... non-existent. So the source is probably where a lot of information is. But things do tend to work accross different systems.

ivan-mogilko commented 3 years ago

Ok, this is weird, but I think I found a bug in MojoAL source... (https://github.com/ivan-mogilko/ags-refactoring/commit/c23b596b91d600044583df729c41500ce06fc562#diff-baa934647843fd49d8f1863017135f30L4145)

The problem there was that alGenBuffers function that suppose to return fresh buffers to fill instead always returns first N buffer IDs regardless of whether they are currently free or not. Because of this our own list of buffers gets filled with same first 2 IDs, and engine tries to read into them while they still may be in use..... causing asserts in MojoAL in turn.

Idk, maybe I misunderstood something, but only after this change I can finally hear sound.

ivan-mogilko commented 3 years ago

Aha, apparently there was a bug, because newest library code has additional condition, compared to what we use: https://hg.icculus.org/icculus/mojoAL/file/tip/mojoal.c#l4290

EDIT: applied their patch instead, looks more correct

ericoporto commented 3 years ago

Weird question, but does it sound good? When listening, do you notice any stutter or something?

ivan-mogilko commented 3 years ago

This is a good question actually. I was testing one game ("Guard's Duty"), and on title screen I hear some noise on "strong" notes, like trembling. Original engine has this noise too, but for only a moment and then it goes away.

ericoporto commented 3 years ago

Yes, when I listened I felt it was different, like slightly louder, but not exactly. No problem with that, and not sure if something else influenced my perception at the time.

ivan-mogilko commented 3 years ago

After testing more, there's definitely something wrong, or unfinished in this branch, because not all sounds are playing. Maybe it cannot play multiple sounds simultaneously? For example in "Guard's Duty" intro sound fx are playing but background music is not.

Anyway, now when I see how it works in general, I'd like to make a step back and reapply only necessary code in clean way. Hopefully it will be easier to see what's wrong too.

ericoporto commented 3 years ago

My commits are throwaway code, feel completely free to do whatever with it :). It was just me trying to poke Sonneveld's code. My reading regarding what Sonneveld's code was and was doing:

ivan-mogilko commented 3 years ago

@ericoporto I made a new wip branch here: https://github.com/ivan-mogilko/ags-refactoring/tree/ags3--try-sdl2-sound

It has considerable less changes as I only pulled what was necessary to sound. Plus split decoder from audio_core.cpp because there was much code in it.

The library sources are still added to repo for simplicity sake, but we need to decide how to link them properly before actually merging this.

I did not add changes to CMake yet because I dont fully know how it works, so you'll have to do this if you want to build it with cmake.

EDIT: Note, I did not add any changes to strings, streams, etc yet, because I was not persuaded these are necessary for this particular changeset (as ags string class are not used within audio core thread at all). But I did not test this new branch alot yet, will do more tomorrow.

There were number of things in sonneveld's original branch that were likely added as placeholders or in expectation of further changes, or maybe just randomly... for example, SDL thread class is not even used in audio (as I expected at first), instead he's using std::thread explicitly (could be an oversight, might replace with our Thread class later if it's possible to adjust it's interface).

ericoporto commented 3 years ago

Hey, I will test this! It's cool, I can add the CMake part!

What do you think of a repository for all the source dependencies? The sources could be pulled from it either as a git submodule or through an event in the solution or a fetch script in the CMake.

Edit: I think the Windows build could copy the SDL2 dll in the build.

Edit2: this is weird, I get a script error when running Tea for Two (an invalid sprite slot!) :/

Edit3: there's something wrong with Drawing sprite in this build.

Edit4: sound appears to be working good, I need to try to build master later because I think something broke drawing sprites there. Tea for Two crashes and Dungeon Hands can't indicate cards that can't be selected. I tried some simpler games and sound was good, I looked the code changes and I don't think anything there touches the sprites. I reproduced the Windows build on my Windows 10, so once there's a decision on the dependencies, we can adjust the scripts.

ivan-mogilko commented 3 years ago

I pushed couple of more commits, mostly removing old allegro-based code, and a small fix. The problem which I experienced with previous branch, where simultaneous sounds were not playing, is not reproduced in the new branch. Don't know what's the reason is, but I also used most recent MojoAL version, which may also affect the result.

I will test your game on master separately first. UPDATE confirmed, happens in master, will be looking into this. UPDATE2 fixed DrawImage bug in master, and rebased sdl sound branch

ericoporto commented 3 years ago

Hey, the drawimage is fixed! With this working, I tested it with Future Flashback and the audio is perfect! Sometimes, in regular AGS 3.5.0, I had some audible stutters when saving game on Windows, but this did not occur when I tested the version on your sdl branch - I can see the frame briefly freezes but the music keeps going perfectly :D . I also did not notice any missing sound effects when playing. From using only the ears I could not pickup anything wrong.

Edit: on the sound playback, I read the TO-DOs:

It appears these are things that can be fixed later on. Not sure if any of them impacts backwards compatibility for ags3 - I don't know what slot id generation id is.

I am not sure where to go next, I imagine keeping Windows only as is and move to other Engine system (video, window, mouse, keyboard, ...) can make the implementation go faster.

I recently read this guide for SDL1.2 to SDL 2.0 and noticed some similarities between Allegro4 and SDL1.2.

ivan-mogilko commented 3 years ago

Sound caching only matters for slow reading systems, it was made for PSP (which is no longer supported); it may be still useful for console ports maybe. Creating a new one might be easy, mostly a matter of finding a good spot in code to keep engine architecture clean. Don't yet know what other points mean and whether they are important. For this TODO list I would add streaming mode, as right now it loads full sound clip at once. May not be a problem for shorter sounds, but will be if someone adds a 30 minute long playlist as one clip into a game :).

In terms of backward compatibility there are two main points of concern:

I'd like to create a proper branch in the main repository, forking from current master (ags3), and merge sound port there to have something persistent. What may still be necessary for this start?

rofl0r commented 3 years ago

how exactly OpenAL chooses what drivers to play sounds with. Maybe it also has a configuration?

http://web.archive.org/web/20130225015051/http://connect.creativelabs.com/openal/Documentation/OpenAL%201.1%20Specification.htm#_Toc199835899

ALCdevice * alcOpenDevice (const ALCchar *deviceSpecifier);

btw, there's also the excellent OpenALSoft implementation for linux.

may i ask why openal was chosen over SDL_sound, as the port was intended to use SDL?

I'd like to create a proper branch in the main repository

please, in case you already have binary stuff checked into your temporary branch the commits adding them need to be amended to remove it, otherwise the binary blob will forever stay in the repo's blob graveyard and everybody will have to download it.

Make a good decision on library sources;

should definitely stay outside the AGS repo, otherwise it will bloat up like a balloon. it would be preferable to have a git subproject, so people not needing the library sources (like linux users that have the libs installed systemwide) won't have to check the subproject out. but even better than this would be a buildscript for windows users that just downloads the sources from another repo hosted in the ags organisation.

ivan-mogilko commented 3 years ago

may i ask why openal was chosen over SDL_sound, as the port was intended to use SDL?

Both are used in this port variant, and MojoAL is a OpenAL implementation based on SDL. I still dont know much about these libs frankly, but from my current understanding, SDL_sound is used to read and decode file format, while MojoAL provides sound mixer and playback for raw wave data.

please, in case you already have binary stuff checked into your temporary branch the commits adding them need to be amended to remove it,

Yes, I marked these commits as [TEMP], and keep noting that these are to make preliminary testing faster.

rofl0r commented 3 years ago

MojoAL is a OpenAL implementation based on SDL.

oh i see, it's an API on top of an API! layers upon layers. i wonder who had that idea...

ivan-mogilko commented 3 years ago

What's the difference between that and OpenALSoft for instance?

We are using SDL anyway, why there's something bad in it?

ericoporto commented 3 years ago

OpenAL is just a specification. MojoAL is an implementation of the spec. I would rather not discuss that and move with the other things. I would actually prefer to just work with the Windows side of things before the rest of things actually... But if we are doing the vertical approach it's fine too. (I fear for rebase hell)

We could move everything from /libsrc to a repository ags-dependencies.

In the future if this turns out to be a pain - because of the many ags branches, we could just have things in. The idea of ags-dependencies would be being able to just get the source tar file from GH instead of caring for git cloning it. For CMake it could be fetch from there from CMake itself so it's part of the build process. I really would like source dependencies instead of binary ones - makes easier anytime it needs to be built for mobile or in the future, consoles.

I think SLN/Vcxproj also support fetching a source like this, like in a zip file, but I could not find anything on this, online? Also, not all libraries ship with vcxproj files, I think, so we would need to maintain the ones needed there - they should be fairly simple.

For commercially released games on Linux it's always better to pack all dependencies with the game, so it would be good to continue like this.

ivan-mogilko commented 3 years ago

From what I can see, OpenAL provides certain mixer and sound adjustment logic. So it depends on whether we need this layer of logic or not. If not, we could try using SDL sound directly, but then there's this concern: won't we end up writing similar logic ourselves?

rofl0r commented 3 years ago

What's the difference between that and OpenALSoft for instance?

openal is a library interface that wraps OS-specific sound driver libraries and provides an uniform, platform-indepent API to play sound. for example, on linux it would probably use libasound (alsa) or OSS behind the scenes.

openalsoft is an implementation of that API which sits on top of libasound.

SDL2's own sound functions https://wiki.libsdl.org/CategoryAudio do the same thing as OpenAL, they too provide such an interface.

now if you use an openal wrapper that sits on top of SDL, you end up with 2 layers of indirection: openal -> libSDL2 -> libasound. needless to say that each indirection has a certain cost.

however, the SDL2 sound interface is quite rudimentary and uses a callback driven design which is rather unpleasant to use, (and requires the user to unpack the audio manually, e.g. by using libogg) that's why many games prefer to use sdl_mixer: http://www.libsdl.org/projects/SDL_mixer/ .

interestingly, the SDL2 audio documentation itself recommends to use either openal or sdl_mixer: https://wiki.libsdl.org/SDL_MixAudioFormat

so maybe that is the reason mojoal is in use here.

rofl0r commented 3 years ago

I would rather not discuss that and move with the other things.

i think discussing it is fine, but i agree that since the sound stuff seems to work for the moment it would be more productive to continue with the port. whether direct use of libsdl's sound support is preferable can be evaluated when the rest works.

rofl0r commented 3 years ago

We could move everything from /libsrc to a repository ags-dependencies

at the moment libsrc only contains a few scripts to download the source anyway

edit: ah, then we have also Engine/libsrc. but since it's already in the repo removing it helps only for the case that a shallow clone or a "tarball from master" download is being done

sonneveld commented 3 years ago

G'day,

Sorry I have had little time to contribute lately (and in the future) but just wanted to document what I remember from my SDL2 port branch. I'm heartened to see that you're considering my code!

I was regularly rebasing the SDL branch on top of the latest of AGS. And then I was rebasing on top of that for the port. So the branch wasn't really intended to be merged in verbatim but to be cherry picked as we migrated various systems to use SDL.

So yeah, sorry for the "mess"! I was using individual commits for features where I could but ultimately it complicated rebasing as there were more commits where I had to invidually fix conflicts. I always intended to break out those large commits into something easier to review before creating pull requests.

The various libraries were deliberately commited to make it easier for me to make various patches. That's why I added libraries in multiple commits, one for the original pristine library code and then patch commits on top of that. This made it a lot easier for development but I didn't really intend for these to always live in the ags repo (with the exception of the allegro library since it would just be a shell around SDL)

Speaking of the allegro library, most the changes there were removing any allegro apis that we didn't use and implementing SDL "drivers" that spoke to sdl. That's all contained in a single src/sdl2/system.c for easy access.

With sound, I needed to be able to mix multiple sources and support the same audio formats that AGS needed. SDL_Sound is used for decoding but for mixing there were a few options:

1) Create an allegro sound driver using SDL. I believe Edward Rudd did this in the past for humble bundle linux ports. This might be a good first step but it relies on allegro doing all the audio mixing which didn't help if we ultimately wanted to remove allegro altogether 2) Use SDL. It doesn't provide a mixer so we would have had to write our own which I wanted avoid since we wouldn't be able to take advantage of any hardware mixing. 3) Use sdl_mixer. I investigated this but unfortunately it only provides a single "music" channel for streaming. It didn't really gel with the AGS audio api which lets you play streaming on any channel. Also, this may have changed, but it didn't really seem to be in heavy development, so we'd be swapping one unmaintained api for another. 3) Use OpenAL. This was supported natively on a few different platforms, allowed streaming from multiple sources and did mixing so it did feel like a good fit. For the platforms that don't natively support OpenAL (namely Windows), OpenALSoft is a pretty good implementation but it is GPL so we'd have to be careful how we include it. Fortunately Ryan C Gordon has created MojoAL which is a complete OpenAL layer on top of SDL and zlib licensed. It was still in development and was missing a couple of features like getting absolute position of playing sources (which may be implemented now) but it was a good fit if people didn't want to install OpenALSoft or the ancient creative openal drivers.

In regards to the physfs changes. This is unncessary for an initial sdl port, I just wanted to play around with ZIP file support and it seemed to fit in nicely. You could overlay multiple zip files to create a single pseduo file system. And it does create a clean api for accessing files on multiple platforms.

APEG should work okay. At least it worked last time I tested it. Although in the future it might be better to replace with something like ffmpeg. Unfortunately I found the ffmpeg api tricky to work with, so that would definitely be a future project if you wanted to go in that direction

In regards to the general changes to AGS for SDL support. The largest change was to use openal so we could avoid relying on allegro for mixing. Most of the other changes were related to input and changes to the various internal gameloops to ensure SDL can process events while waiting for mouse clicks or whatever. Otherwise it would look like the process had hung. There are a few places that I marked with AGS_DELETE_FOR_3_6 ifdefs, and they were mainly the older dirtyrect drawing code. I didn't think they would be necessary in a world where you only use OpenGL or Direct3D for rendering. But up to you I guess!

Anyway, hopefully that clears up some of my decisions.. and good luck!

ivan-mogilko commented 3 years ago

@rofl0r if I understand correctly, since OpenAL is an interface, we may simply switch implementation if current does not work out for some reason?

@sonneveld Hello, I was wondering what happened to you. Unfortunately, it took me a while to deal with other less important things and return to this task too.

I found and marked several of your old threads with different works (streams, strings, asset loader for switch iirc, and so on) and probably will be using them as a reference (if that's okay legal-wise). My branch mentioned in this discussion is made exactly by cherry picking your sound changes and tidying them up. Also I simply deleted relevant "AGS_DELETE_FOR_3_6" code because it seemed right doing so.

Something due mentioning, we were discussing trying to port without having allegro wrap over SDL. Could you elaborate, because I forgot, what were the reasons you went with allegro wrap, was that for simplicity sake, or something more serious?

PS

Unfortunately I found the ffmpeg api tricky to work with

By coincidence, all the last year I was working with ffmpeg on my office job, so I consider myself familiar with it now :) it's just that I am concerned that it may be an overkill to bring whole ffmpeg purely to play videos (while we still are using SDL_sound etc for sound).

rofl0r commented 3 years ago

@rofl0r if I understand correctly, since OpenAL is an interface, we may simply switch implementation if current does not work out for some reason?

indeed. one could for example use it with OpenALSoft, or the old reference implementation of creative labs.

it's just that I am concerned that it may be an overkill to bring whole ffmpeg purely to play videos

i suspect it should be possible to build ffmpeg only with support for the few videocodecs that are used by AGS (also in order to circumvent GPL'd codecs that may be built into libavcodec&friends). but that would probably involve yet another "fork". might be preferable to use the system-wide installed libraries via dynamic linking.

ericoporto commented 3 years ago

@ivan-mogilko for ags3.6 I think I would keep allegro even if only for the bitmap operations, while having mouse, keyboard, and window and others on SDL2. The bitmap usage can be replaced by something else (with some considerable code, with Pixman or with more human API, Cairo graphics), but the interfaces will require a lot of rewrite, and I think it may be easier to do in ags4 with potential feature dropping (like 16 bit colors). SDL has SDL_Surface that gives some functionality but it will need more things to have all the functionality in Allegro4.

rofl0r commented 3 years ago

The bitmap usage can be replaced by something else (with some considerable code, with Pixman or with more human API, Cairo graphics)

could you provide an overview of required functionality that you think is lacking in SDL2 ?

ericoporto commented 3 years ago

I could not figure out how to write Text or draw a line (or a circle, ...). But you are right, SDL_Surface with SDL pixels should get most things going, it just will require a lot of rewrite (even our wrapper classes have Allegro expectations), which is why I am afraid of working on it in 3.6 - we can get benefit from SDL interfaces quickly going, like multimonitor support, high pooling mouse, reliable keyboard handling, the sound, ...