Show Posts

You can view here all posts made by this member. Note that you can only see posts made in areas to which you currently have access.

Topics - Snarky

Pages: [1] 2 3 ... 10
Engine Development / Winsetup scaling options again
« on: 26 Apr 2018, 21:36 »
I know this is Crimson Wizard's favorite topic, so I just had to bring it up again. (laugh)

In v3.4.1 I don't see the x2, x3, x4... options under windowed scale when I run winsetup. The only ones are "None (original game size)", "Max round multiplier", "Fill whole screen", and "Stretch, preserving aspect ratio" – IOW no scaling and three very slightly different variations on scale to full screen.

This is particularly a problem for me since I run AGS in a virtual machine on a high-resolution screen (2880x1800). This means that without scaling the window is tiny, but scaling e.g. a 320x200 game with max round multiplier ends up being x9, and the VM can't handle that (I'm not sure exactly where the the problem lies, but it freezes the VM).

However, even if this was not the case, I would want to be able to set intermediate scaling options. If I'm playing in Windowed mode I probably have other windows open, and I don't necessarily want thhe game window to fill most/all of my screen.

I want to be able to run games scaled bigger than the original resolution, but not necessarily to cover as much of the screen as mathematically possible. I want x2, x3, etc. back!

Modules & Plugins / ENGINE PLUGIN: Clipboard v0.4
« on: 30 Mar 2018, 14:09 »
By popular demand: a plugin to support copy/paste, integrating with the Windows clipboard!
This plugin allows you to copy text from other applications and paste it into an AGS game, or vice versa.

The plugin provides two methods:

Code: Adventure Game Studio
  1. bool Clipboard.CopyText(String copyString);
  2. String Clipboard.PasteText();

Calling Clipboard.CopyText(copyString) will put copyString on the Windows clipboard (returning true if successful), accessible to other applications. Calling Clipboard.PasteText() returns the current text content of the Windows clipboard as a String (or null if none) that you can use in-game. Pretty simple.

As with all AGS engine plugins, you have to place the .dll file in the AGS engine folder, then activate it in the IDE from the project tree before you can use the methods. It should be unnecessary to state, but for the record: the game must be designed and created to use the plugin, you can't just drop it into the folder of a finished game and expect it to do anything.

This is my first AGS plugin, and my first C++ project in many years. It works on my machine, but I'm not 100% sure it will work on every Windows machine – in particular on older Windows versions. If you could try the demo and let me know if you experience any problems, I'd appreciate it.

The code is available on Github. (In the demo game, the example of how to use it is in TextField.HandleKeyPress(), starting on line 538.)

Download Clipboard plugin
Download Clipboard demo

Change log:
-Initial release (untested except for on my own machine)

Modules & Plugins / MODULE: TextField v1.2.0
« on: 28 Mar 2018, 15:39 »
This is a quick little module I made for the AGS Awards client. It provides one-line text input fields, as a replacement for the AGS TextInput control.

Ways in which TextField is better than TextInput:
-It has a blinking text cursor
-You can position the cursor anywhere in the text (using mouse or arrow keys), and edit at that point
-It has a notion of focus, so that you can have multiple TextFields displayed without all the text being entered into all the fields
-You can define a max string length the field will accept
-You can make the border partially transparent
-You can add more advanced logic to it, e.g. to only accept certain character types, or to *** out the display of the text

Ways in which TextField is worse than TextInput:
-It's implemented in script, so on slow computers or in a resource-intensive game it could be less responsive than TextInput
-You have to do a little bit of setup to make it work
-You can't link the OnActivate event, so it's a little more complicated to respond when the player presses Return/Enter

The TextField module is available on Github.

Download TextField v1.2.0

You can also try it out in a demo game for the Clipboard plugin:

Download Clipboard Demo

- Fixes crash if TextField initialized with non-empty String
- Adds support for Clipboard plugin

- Initial release
- Fixes poor SHIFT-key detection

- Unreleased (used in AGS Awards 2017 client)

You can export all the files in a sprite folder, but is there some way to then reimport them again to replace the old sprites, after you've edited them in some external program, other than laboriously clicking "replace from file" on each and every sprite?

It's a really simple thing that causes endless frustration working with AGS: if open an "add sprite" (to a view or GUI control) dialog while the sprite tab is open, it collapses any folders you have expanded in that tab.

This makes it very tedious to perform tasks that involve checking the contents of certain sprite folders and adding them to different things. If someone could fix it, I'm sure it'd save endless wasted hours in total for all AGS devs.

It's time to start working on the client for the 2017 AGS Awards! 8-0

I plan to handle the coding side of things again, but I could really use some help with the resources. Some of them are starting to show their age, and the update last year was a bit of a rush job, with ugly placeholder elements.

Add spoiler tag for Hidden:

Notice the use of three different button styles, unstyled listboxes, and the crude red arrow highlighting your character.
A list of things I have in mind (for overall reference, the client is 1280x720 in 32-bit):

  • New buttons and GUI elements. I intend to redesign the GUI quite a bit, moving away from the black screens that currently cover up the entire background. I'm leaning towards a tabbed interface. I also want to make all the buttons consistent, and make it so they fade out unless you move the cursor close. The chat history window also needs to be fixed. This task might involve collaborating on the UI redesign, or just making a template for the button/slider styles or drawing graphics for the button symbols.
  • Related to that: Perhaps a new cursor (not sure I like the current one), and definitely a new "character highlighter". Currently it's just a crude red arrow; I was thinking an animated glowing ball oscillating up and down over your head. (Might want this in two colors: one for you and one for highlighting other characters.)
  • Trophies! It would be really cool if winners could receive an actual trophy. There was a trophy in SSH's non-online Awards ceremony games, but I don't think the graphic style really fits:
    Add spoiler tag for Hidden:
  • Graphics and animations for the on-stage screen (320x240 canvas, with the top partially obscured):
    • New animated "interstitial" screens: some kind of AGS logo, or saying "2017 AGS Awards" or something like that, with some sort of calm (looping) animation livening it up. (The 2015 client had one of these, but I don't have access to it.)
    • Screens announcing the various categories (Best Backgrounds, Best Voice Acting, etc.): Probably some kind of logo or drawing symbolizing that category.
    • New "animated gif" meme-style reactions, ideally taken from AGS games or at least adventure games.
    • Surprises and other fun things to put up on the screen.
    • And if any graphically gifted AGSers have good ideas for how to format the presentations of nominees and winners in each category (particularly for things like Best Character, Best Animations, Best Character art), I'm all ears.
  • New DJ characters/platform (updating or replacing the pixel Daft Punk).
  • Also, new music for the DJs to play! A range of tunes, from catchy party music to calm background audio. New/alternative music cues for the ceremony would also be interesting.
  • There was some complaint last year that the font was difficult to read. If anyone has any suggestion for fonts to use for the chat window or above characters' heads (or other things), let me know. (We should be able to do proper rendering and outlining of antialiased text now, so don't feel limited to pixel fonts.)

Also, Noa's performance of "Troll Song" from the 2014 ceremony was one of my favorite parts of that event, and it would be cool if anyone wants to do something like that (or has some other idea to enrich the show):

Finally, I hope to improve the dynamic applause system, and make a similar system for dynamic laughter. (I'm also considering adding "crowd noise".) To make that happen, I need a pool of audio clips to use.

Add spoiler tag for Hidden:
For the applause, I currently have six levels of intensity, depending on how many people are clapping (single person clapping, scattered applause, modest applause, general applause, enthusiastic applause, ecstatic applause), each with short and long clips (short clips are played during presentations, long clips when the floor is open). For some levels there are a couple of different clips of each type, picked at random. All in all, there are 20 different clips of people clapping (some of which aren't that great, and should be replaced). Something similar would be nice for laughter. Tracking down and editing the clips is quite time-consuming, so if someone wants to help out with that I'd appreciate it. (Also, the clips should be properly licensed, giving us the right to use them.)
Oh, and like every year, AGS character avatars are much appreciated! Send me your chars!

Exactly how we're going to do this depends a bit on your interest and feedback. For some things we might run a contest or workshop thread. Mostly it'll probably be discussions over PMs.

I can't guarantee the inclusion of what you make in the ceremony, so if you're thinking of doing something that would be a lot of effort, maybe run it by me first (e.g. if 20 different people each want to do some sort of performance, that's probably a bit much – we might have to arrange a separate AGS Talent Night instead).

PC Gamer is running an interview by Richard Cobbett with Eugene Sandulenko ("Sev"), the ScummVM project lead, on the occasion of the release of ScummVM v2.0 (hooray!)

He has this to say about AGS (not hooray!):

The most notable omission though has to be AGS—Adventure Game Studio. This is the software behind 99 percent of freeware and indie adventures this side of the millennium, ranging from the Chzo Mythos and Larry Vales to the Blackwell series and next year’s Unavowed. Early versions are a pain, to put it mildly, as anyone who’s ever tried getting something like Quest For Glory IV 1/2: So You Thought You Were A Hero to run can attest. (Top tip: don’t!) The audience and features seem perfect for ScummVM. Yet still, no support.

"AGS is... unfortunate for us," admits Sandulenko. "Once the original author published the source code, we were pretty excited and we started working on it. We really had high hopes. But then when we mentioned it in the AGS forums, where the game authors are, there was a huge uproar. They didn't want it. They disliked the idea. They jumped on our poor developer so hard that they left in disgust, not wanting to touch it any more. I don't know why there was such opposition. We wanted to do it in the proper way, in the ScummVM spirit, and keep it updated as AGS was upgraded and improved over time. Later there was some talk of 'letting' us handle old game compatibility and so on, but... well, yeah... thanks? That’s not really in the spirit of our project."

Most of the debate he's referring to is in this thread. I would say his summary mischaracterizes the events a great deal.

Christmas! It's the most wonderful time of the year, according to some. I'm a total sucker for all the sappy, romanticized Christmas kitsch, and I'm sitting here looking at the snow falling outside, about to bake some lussekatter (saffron buns).

So, in the spirit of the season, what are some good Christmas-y adventure games?

I'm having a weird issue with Speech.SkipStyle. When it is set to eSkipTime (which is 2), it reports its value as -1 instead:

Code: Adventure Game Studio
  1.   Speech.SkipStyle = eSkipTime;
  2.   Display("Speech.Skipstyle is %d. eSkipTime is %d", Speech.SkipStyle, eSkipTime);

This displays "Speech.Skipstyle is -1. eSkipTime is 2"

Other than that, it appears to work OK. Speech behaves correctly: it times out but cannot be dismissed with mouse or keyboard.

If I try to actively set Speech.SkipStyle to -1, the game crashes, with an error message saying I used an illegal value.

This code is part of the SpeechBubble module I just posted, but since it has more general-purpose application, I thought it deserved its own post.

Displaying text with a TrueType (.ttf) font in AGS has some well-known limitations:

  • If you place anti-aliased text on a semi-transparent background (e.g. as a label on a semi-transparent GUI), the anti-aliasing "pokes holes" in the background. This looks terrible.
  • With anti-aliased text, the AGS auto-outline feature often does not work very well, with gaps and other artifacts.
  • The auto-outline can only be one pixel wide.
  • The outline can only be black. (You can set it to a different color using game.text_shadow_color, but it will affect ALL the text on the screen.)

Here are two functions to work around those issues. They take advantage of the fact that DrawingSurface.DrawImage() does correct alpha-blending. You can use this to draw an anti-aliased string onto any DrawingSurface without artifacts. And by "stamping" multiple copies of the string in a pattern of 1-pixel displacements, you can also create an arbitrarily wide outline of any color you like.

The drawback is that it is slower, particularly if you want to draw a very wide outline (a 5-pixel outline will do something like 20 DrawImage() operations). However, I've found that in practice it runs fast enough to not be a problem for typical uses. (There are also some optimizations still possible in this code, particularly if you don't need the ability to draw the text at <100% opacity.)

Code: Adventure Game Studio
  1. /// The shape of a text outline
  2. enum TextOutlineStyle
  3. {
  4.   /// A circular, rounded outline
  5.   eTextOutlineRounded = 0,
  6.   /// A square "block" outline
  7.   eTextOutlineSquare
  8. };
  10. // To work around the AGS bug where antialiasing "pokes holes" in semi-transparent canvases
  11. void drawStringWrappedAA(this DrawingSurface*, int x, int y, int width, FontType font, Alignment alignment, String message, int transparency)
  12. {
  13.   DynamicSprite* textSprite = DynamicSprite.Create(this.Width, this.Height, true);
  14.   DrawingSurface* textSurface = textSprite.GetDrawingSurface();
  15.   textSurface.DrawingColor = this.DrawingColor;
  16.   textSurface.DrawStringWrapped(x, y, width, font, alignment, message);
  17.   textSurface.Release();
  18.   this.DrawImage(0, 0, textSprite.Graphic, transparency);
  19.   textSprite.Delete();
  20. }
  22. // Draw a string with outline (make sure the canvas has at least outlineWidth pixels on each side of the string)
  23. void drawStringWrappedOutline(this DrawingSurface*, int x, int y, int width, TextOutlineStyle outlineStyle, FontType font,  Alignment alignment, String message, int transparency, int outlineColor, int outlineWidth)
  24. {
  25.   // This is what we draw on (because we might need to copy with transparency)
  26.   DynamicSprite* outlineSprite = DynamicSprite.Create(this.Width, this.Height, true);
  27.   DrawingSurface* outlineSurface = outlineSprite.GetDrawingSurface();
  29.   // This holds multiple horizontal copies of the text
  30.   // We copy it multiple times (shifted vertically) onto the outlineSprite to create the outline
  31.   DynamicSprite* outlineStripSprite = DynamicSprite.Create(this.Width, this.Height, true);
  32.   DrawingSurface* outlineStripSurface = outlineStripSprite.GetDrawingSurface();
  34.   // This is our "text stamp" that we use to draw the outline, we copy it onto outlineStripSprite
  35.   DynamicSprite* textSprite = DynamicSprite.Create(this.Width, this.Height, true);
  36.   DrawingSurface* textSurface = textSprite.GetDrawingSurface();
  38.   // Draw our text stamp
  39.   textSurface.DrawingColor = outlineColor;
  40.   textSurface.DrawStringWrapped(x, y, width, font, alignment, message);
  41.   textSurface.Release();
  43.   switch(outlineStyle)
  44.   {
  45.     case eTextOutlineRounded:
  46.     {
  47.       // Draw Circular outline
  48.       int maxSquare = outlineWidth*outlineWidth+1; // Add 1 for rounding purposes, to avoid "pointy corners"
  49.       int maxWidth = 0;
  50.       outlineStripSurface.DrawImage(0, 0, textSprite.Graphic);
  51.       // We loop from top and bottom to the middle, making the outline wider and wider, to form circular outline
  52.       for(int i = outlineWidth; i > 0; i--)
  53.       {
  54.         // Here's the circular calculation...
  55.         while(i*i + maxWidth*maxWidth <= maxSquare)
  56.         {
  57.           // Increase width of the outline if necessary
  58.           maxWidth++;
  59.           outlineStripSurface.DrawImage(-maxWidth, 0, textSprite.Graphic);
  60.           outlineStripSurface.DrawImage(maxWidth, 0, textSprite.Graphic);
  61.           outlineStripSurface.Release();
  62.           outlineStripSurface = outlineStripSprite.GetDrawingSurface();
  63.         }
  64.         // Draw outline strip above and below
  65.         outlineSurface.DrawImage(0, -i, outlineStripSprite.Graphic);
  66.         outlineSurface.DrawImage(0, i, outlineStripSprite.Graphic);
  67.       }
  68.       // Finally the middle strip
  69.       outlineSurface.DrawImage(0, 0, outlineStripSprite.Graphic);
  70.       break;
  71.     }
  72.     case eTextOutlineSquare:
  73.     {
  74.       // Draw square block outline
  75.       // Just draw the full outline width onto the strip
  76.       for(int i = -outlineWidth; i <= outlineWidth; i++)
  77.         outlineStripSurface.DrawImage(i, 0, textSprite.Graphic);
  78.       outlineStripSurface.Release();
  79.       // Draw the full outline height
  80.       for(int j = -outlineWidth; j <= outlineWidth; j++)
  81.         outlineSurface.DrawImage(0, j, outlineStripSprite.Graphic);
  82.       break;
  83.     }
  84.   }
  85.   textSprite.Delete();
  86.   outlineStripSurface.Release();
  87.   outlineStripSprite.Delete();
  89.   /// Now draw the text itself on top of the outline
  90.   outlineSurface.DrawingColor = this.DrawingColor;
  91.   outlineSurface.drawStringWrappedAA(x, y, width, font, alignment, message, 0);
  92.   outlineSurface.Release();
  93.   // ... And copy it onto our canvas
  94.   this.DrawImage(0, 0, outlineSprite.Graphic, transparency);
  95.   outlineSprite.Delete();
  96. }

Modules & Plugins / MODULE: SpeechBubble v0.8.0
« on: 03 Dec 2017, 11:28 »
Here's a module to do comic book-style speech bubbles. It's an alternative to Phylactere, because the older module doesn't work properly with 32-bit color. This module requires AGS 3.4, and for now it only works in 32-bit mode (or rather, transparency only works in 32-bit mode).

Initial development of this module was paid for by bx83, who agreed to allow it to be open-sourced.

To use, you call Character.SayBubble():

Code: Adventure Game Studio
  1.   player.SayBubble("This line will be said in a speech bubble.");

To configure, you set the SpeechBubble properties:

Code: Adventure Game Studio
  1.   SpeechBubble.BorderColor = Game.GetColorFromRGB(0,128,0);
  2.   SpeechBubble.BackgroundColor = Game.GetColorFromRGB(128,255,128);
  3.   SpeechBubble.BackgroundTransparency = 33;
  4.   SpeechBubble.PaddingTop = 5;
  5.   SpeechBubble.PaddingBottom = 5;
  6.   SpeechBubble.PaddingLeft = 15;
  7.   SpeechBubble.PaddingRight = 15;

(You should probably do this in game_start() in GlobalScript.)

This module is still under development, and is currently missing some functionality (in particular support for background speech). Please report any bugs you experience.

The module is available on GitHub.

Download SpeechBubble v0.8.0

Change Log:
-Implemented Character.SayBackgroundBubble()
-Added SpeechBubble.DefaultGui property
-Fixed crash with characters that don't have a speech view set

-Fixed an issue with lines with speech clips in text-only mode

-Initial pre-release

I want to block indefinitely until a mouse or key is pressed. AGS only offers timed blocks in WaitKey() and WaitMouseKey(), but if the timing is long enough that's probably fine. So I want to put in as big a number as I can when calling these functions.

The int maxvalue is 2,147,483,647 (according to the manual). But trying to Wait() or WaitKey() for that length of time (or 1 less, in case it has to be able to go above it) doesn't work: it just gets ignored. What's the biggest number you can provide as an argument to the Wait...() functions?

(Though since there's no WaitMouse(), I'll probably have to build my own solution anyway, with Wait(1); in a loop, and flag that gets set on the keyboard/mouse events.)

Is there some way to find out from within AGS how long a certain speech clip is, without playing it?

Here's why I'm asking:

When you call Character.Say() with a voice clip (e.g. player.Say("&14 This line has voice-over");), the speech lasts as long as the clip, logically enough. (Depending on your Speech.SkipStyle setting the text may stay on screen longer, but the character won't do the Talk animation.)

However, if you set your Speech.VoiceMode to eSpeechTextOnly, the voice clip is ignored, and it seems the game falls back to using the standard AGS formula for how long to display the text, based on the string length and  Game.TextReadingSpeed.

I want to be able to maintain the same timing whether or not speech is turned on. If I could get the length of the speech clip I could do that (writing my own little function to manually do the Talk animation and time it correctly).

I have a question for the engine experts. In 32-bit, AGS allows you to set the transparency of various things and drawing operations as a percentage (0-100). However, 32-bit color actually uses an 8-bit alpha channel internally (0-255). Do you know how this is mapped?

For example, if I set the transparency of a GUI to 3%, am I really setting it to the closest alpha value, 8? (8/255 = 0.03137..., or about 3.14%). Is this calculated as (in AGS syntax) int alpha = FloatToInt( IntToFloat(percentage)*255.0/100.0, eRoundNearest), or some other way?

Pages: [1] 2 3 ... 10