adventuregamestudio / ags

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

Quest for infamy portraits 'blink' mid spoken line #761

Closed i30817 closed 5 years ago

i30817 commented 5 years ago

edit: Better way to reproduce in the post below.

This happens in both OGL and Software drivers, but i think it's more common in OGL.

Sadly the demo appears to be useless for this: it doesn't appear to happen there. But before you call it for a game bug (which it may be) this doesn't happen in wine. However i doubt wine is doing it well either, since there is a noticeable dialog portrait animation slowdown.

Sorry this issue is so useless, i even dowloaded the demo (here) to try to reproduce it without the game and it was a unpleasant surprise to see it didn't show the bug after 300mb of download.

i30817 commented 5 years ago

Much better way to reproduce. Start game, escape to skip sequence, talk to Udo but dont click mouse after greeting (the game waits by default). The Ego portrait will blink periodically (but only in the full game, the demo 'auto continues'). The demo is also using the ags_shell plugin but the full game doesn't appear to need or use it if that's a clue.

I've seen a games i forget with "speech_hold" property under mouse in the cfg, but this one doesn't appear to do anything in QFI. It may be the same engine alteration though.

edit: apparently "speech_hold" is a wadjet eye games thing and per game / dialog script. Technobabylon has it exposed on the options menu for instance.

edit2: apparently even putting in 'voice only' or 'text only' in the options for quest for infamy doesn't remove the portrait blinks. Can't win them all i guess.

i30817 commented 5 years ago

This also happens in Infamous Quest other game Order of the Thorne.

Maybe you'll have luck reproducing it on the demo on steam: https://store.steampowered.com/app/432810/The_Order_of_the_Thorne__The_Kings_Challenge_Demo/

Which i can't test by not having steam.

i30817 commented 5 years ago

This also happens - in a modified form, only the upper part of a portrait disappears, but still in both software an opengl modes) in a Crystal Shard game, Spaceship Quasar, were you can easily see it during the intro.

http://crystalshard.net/?g=15

ghost commented 5 years ago

I do not observe the issue (tested "Spaceship Quasar" on both Windows and Linux).

On another thought, may this be related to the CPU load problem? Like game fails to draw itself in time... just a random idea.

i30817 commented 5 years ago

That's unlikely considering that the original exec for quest for infamy and spaceship quasar didn't blink here (however in quest for infamy it was intolerably slow so i wouldn't use it anyway). I should try a bisect later.

ghost commented 5 years ago

That's unlikely considering that the original exec for quest for infamy and spaceship quasar didn't blink here

Okay, probably I missed something, could you elaborate what do you mean by this? You tried more than 1 version of a game? Or you mean running Windows executable?

I am referring to the 100% CPU load bug that was added to 3.5.0 engine very recently: #771

i30817 commented 5 years ago

Windows executable in wine. I'll try a compile of the version before that commit. It's strange that github doesn't have a easy way to see the previous commit from a commit, though i guess i'll try git checkout https://github.com/adventuregamestudio/ags/commit/f2ab428a596c67d950f2aed5fbd335f6ccc72e3f ~1 to see if that works.

i30817 commented 5 years ago

Ok bad news and good news; i checked and it was not https://github.com/adventuregamestudio/ags/commit/f2ab428a596c67d950f2aed5fbd335f6ccc72e3f but then i tried the version of the game (Spaceship Quasar) 3.3.0.1162 (actually slightly before the game because i screwed up i used v.3.3.0-final) , and the blinking didn't happen, though i had to regenerate the acsetup.cfg file and it says it's using the AGS: Created graphics driver: Allegro/DX5 which is clearly baloney since i'm on linux.

But anyway, i'm bisecting, with luck it'll be something small not a huge commit.

i30817 commented 5 years ago
05f970414e8df085af0d993db37ee155bdba0217 is the first bad commit
commit 05f970414e8df085af0d993db37ee155bdba0217
Author: Ivan Mogilko <ikm_spb@yahoo.com>
Date:   Sun Aug 23 22:25:06 2015 +0300

    Engine: alpha blend speech portrait if any part has alpha channel

    This corrects d9d04bada3a51765644d849f6eefb2913462a75b

:040000 040000 6e842bc2fc03086d6dab83b09fb8dd998f365308 5a509940cc20521655286c0bd68d5cfc5109939a M  Engine

Found it. Also tested going one commit back fixes quest for infamy. The portraits are slow but maybe that's just the game being slow because of these older versions defaulting to software and my computer being underclocked.

It's quite possible this is a case of 'hidden insufficient graphic card' because my computer is a pos portable designed on 2007, kept alive because of the linux mesa driver for radeons mobiles, so, opengl support might not the be best. Though on the other hand, the bug does occur with both the Software and OGL drivers so maybe not and it only shows on a especially slow computer instead.

ghost commented 5 years ago

Oh, iirc that commit fixed blinking animation frames with alpha channel not being drawn properly.

Hmm... when you said "blinking" did you mean portrait dissapearing, or character eyes blinking?

i30817 commented 5 years ago

In Quest for Infamy and Order of the Thorne they disappear, in Spaceship Quasar, only the part of the face that contains the eyes disappears (I think they're animating the eyes blink independently of the mouth-sync to appear more natural).

In quest for infamy and Spaceship Quasar, it appears to happen even if you don't progress the dialog (it doesn't progress automatically). Using wine to see what's happening i think they're putting a lip and eye movement on those moments of invisibility while not speaking because in wine the portraits do them and i never saw them native. If you just don't click after the greeting here, you'll see those zones disappear, which in QFI is the whole portrait but in SQ is just the 'eye+forehead' zone.

i30817 commented 5 years ago

What may be occurring is that the 'invisible zone' is actually supposed to be 'alpha transparent' and the mouth zone fixed or animated differently, like a overlay with some holes. But the transparent behaves differently here and instead of showing the 'speaking face' under, it shows the background. I don't know how speech is done in ags, but that's my suspicion of the evidence.

Though QFI whole portrait disappearing doesn't really jive with that idea, because no one wants to mark everything alpha zero in that situation.

ghost commented 5 years ago

In quest for infamy and Spaceship Quasar, it appears to happen even if you don't progress the dialog (it doesn't progress automatically).

It does for me :/. Are there game settings that disable this? Also, do you play with voice-over on?

i30817 commented 5 years ago

I'm using this acsetup.cfg; though i doubt it matters:

//[override]
//os=win
[sound]
speechvol=50
musicvol=50
mastervol=100
digiid=AUTO
midiid=NONE
[graphics]
render_at_screenres=0
windowed=0
[language]
translation=
[mouse]
auto_lock=0
speech_hold=0
speed=2,000000

Yes, i play it with voices. Speech hold does nothing btw, i think it was option in the game .exe fork i originally copied this cfg from, since i know it's not a original ags option, i optimistically left it there to experiment on other games.

edit: checked wine, no diff. Sorry i've been misinforming you, i still have the older version of Quasar Deluxe Edition here, they might have introduced auto-incrementing dialog without clicks then and fixed that bug from the linux port. But it still exists in QFI which wasn't updated from 1.1.

i30817 commented 5 years ago

If you want to, i can introduce some debug code in any method you tell me to and write out what it says here when run on both (or the three) of those games. I'm going to sleep for about 5 hours now, so don't expect a immediate response thou.

i30817 commented 5 years ago

Here is a video of Quasar btw, QFI is similar except the whole portrait and name tag vanishes in the blinks. output

i30817 commented 5 years ago

If i replace face_has_alpha here with false, it blinks correctly, so the error is inside the function probably

https://github.com/adventuregamestudio/ags/blob/17422df84778e1f7add589c8628f2f4cb7a122e2/Engine/main/update.cpp#L452

To recap;

  1. the commit made it so that: 1.1. if face has alpha, draw it with alpha transparency 1.2. if either face or blinking frame has alpha, draw blinkframe on top of face with alpha. 1.3. if either face or blinking frame has alpha, call gfxDriver->UpdateDDBFromBitmap with alpha (whatever that is).

On Quasar, apparently, both the face and the blink frame have alpha, and the draw function then goes into the 'if alpha and game version >= 330' branch and when i forced face_has_alpha=false for that blinkframe draw that that forced the 'if not alpha' and it drew the blink frames.

Then i changed game version >= 330 to game version > 330 instead and tested both games and both games started drawing blink frames.

This version of Quasar had Compiled with: 3.3.0.1162, kGameVersion_330 was 43 and loaded_game_file_version was 43 And QFI had Compiled with: 3.3.2.0, kGameVersion_330 was 43, loaded_game_file_version was 43

So i have a hypothesis; are you sure you meant >= 330 there and not >? And you probably have a later Quasar version so you don't see the problem.

I'm not sure this is right either, this 'solution' would force these game with loaded_game_file_version == 43 to load the else branch on all sprite draws (i assume).

Would there be a quality loss? Dunno.

kGameVersion_330 is only used in another place at global audio here: https://github.com/adventuregamestudio/ags/blob/17422df84778e1f7add589c8628f2f4cb7a122e2/Engine/ac/global_audio.cpp#L314

with '<' so it's probably 'all the versions before 43 have a min volume of 0 instead of a complex per room adjustment', which is probably unrelated.

ghost commented 5 years ago

I'd also need to remember if I added this as a new feature, or as a fix for some existing game.

i30817 commented 5 years ago

I'm also curious about why the behavior is so disastrous with these games for the blinking frame if it takes the if branch and not for the 'face', in at least this version of Quasar

I mean i could understand if the blinking frame had alpha completely 0 by accident, but shouldn't it draw the normal face frame on the 'hole' instead of obliterating everything, if it draws normally? Confusing to me, but i'm not exactly a graphical programmer, i just have the naive idea that 'alpha == transparency' and drawing things on top of eachother would show the bottom if the top was transparent and the bottom wasn't, not disappear both.

ghost commented 5 years ago

So i have a hypothesis; are you sure you meant >= 330 there and not >? And you probably have a later Quasar version so you don't see the problem.

Same condition is used in another place related to drawing sprites: see draw_gui_sprite_v330 function.

I mean i could understand if the blinking frame had alpha completely 0 by accident, but shouldn't it draw the normal face frame on the 'hole' instead of obliterating everything, if it draws normally?

Probably has something to do with how Allegro's alpha blending operation works. I don't remember that in detail right now.

i30817 commented 5 years ago

Yeah, i missed that one on the grep, sorry about that.

ghost commented 5 years ago

@i30817 I still cannot reproduce this issue in my copy of Qasar (I hacked the engine to force it not skip speech until user input). Is there any place I could get the old version you are using? Alternatively, can you send me the game files? I believe only "exe" and "001" files are necessary.

PS. Going to try https://store.steampowered.com/app/432810/The_Order_of_the_Thorne__The_Kings_Challenge_Demo/ now

ghost commented 5 years ago

Alright, I was actually able to see the portrait "blinking" in "The Order of the Thorne" demo. Not sure if it's completely same issue as in Qasar, since eye blinking animation seem to display correctly, but maybe it's a part of regular speech animation, and there's also separate blinking animation... anyway, will investigate now.

ghost commented 5 years ago

Hmm, I am beginning to remember/understand what's going on. Old games used slightly different rules of blending sprites with alpha channel together and to compensate there's a game switch OPT_SPRITEALPHA which these particular games do not set, apparently.

This old blending rule used Allegro's built-in blending function, which had pretty specific uses, in the resulting bitmap the alpha channel was stripped. There's a comment I wrote years ago: https://github.com/adventuregamestudio/ags/blob/master/Engine/gfx/blender.h#L23 so normally it should be used only when result is to be treated as "opaque" bitmap.

So this is exactly what is happening, it combines two images (main speech frame + blinking frame) properly but resulting bitmap does not have alpha channel anymore. So when engine tries to draw it as if it has one (gfxDriver->UpdateDDBFromBitmap(screenover[face_talking].bmp, screenover[face_talking].pic, face_has_alpha);) then it is rendered completely invisible (alpha = 0 in every pixel).

PS. Now need to figure out of possibly most logical way to fix this. It could be that the blinking frame is not supposed to be drawn with alpha blending for these older games without OPT_SPRITEALPHA at all.

ghost commented 5 years ago

...I spent more time thinking this over than actually fixing. Ended up with stricter condition under which alpha blending is done with portrait frames: only if developers have explicitly set they want to use correct sprite blending mode in the game. Because it makes no sense otherwise.

870d5d8c68fa976255f14a2db1196d4bf4f3eb4a

i30817 commented 5 years ago

Fixed here.