Commit Graph
122 Commits
Author SHA1 Message Date
Walter Agazzi 6ee1a4978f AGS: Engine: expanded error messages for character being in wrong room
From upstream f1cdee7b689e6b12c14c593d1c540e2c13808554
2024-10-30 18:07:42 +02:00
Walter Agazzi 5ce015027f AGS: Add const_casts, comment out unneeded bindings 2024-10-30 18:07:42 +02:00
Walter Agazzi 8d468642cb AGS: Engine: implement add_waypoint_direct(), fix AddWaypoint's resolution
Completes 0b50067abb
2024-10-30 18:07:42 +02:00
Walter Agazzi 822842d038 AGS: Engine, Common: refactor guard using set_our_eip
Remove naked our_eip usages
From upstream 9f4371ab8c2fbc9ccf41b49f7b975ebe8bc5d1b8
2024-10-30 18:07:42 +02:00
Walter Agazzi 87c0bcdf7f AGS: Engine: fixed CharacterInfo breaking script compatibility again
This fixes a mistake introduced in commit 4be1556, which in turn followed b02814b

The problem is, that CCStaticArray does not work as intended, and seems won't (at
least not without some extra workarounds).

When the script compiler is told to get an Nth element of a global struct array, such
as character[n], it calculates the memory address as
    Character* ptr = (array address + sizeof(Character) * n).
If this address is used for the read/write operations, these ops can be intercepted by
interpreter and remapped into the real fields (see IScriptObject::ReadN, WriteN
interface).
But if this address is used IN POINTER COMPARISON BY VALUE, then we cannot do
anything. And if our real struct in the engine is stored on a different relative memory
offset than one expected by compiler, then this pointer comparison will fail.
This breaks script expressions like e.g.:
      if (player == character[n])
From upstream 97ed18e95b587544ae47497f0a5f1d1ba00a7e29
2024-10-30 18:07:42 +02:00
Walter Agazzi d0fe6fd80e AGS: Engine: remade writing of non-fixed Character name in game saves
Done for more consistency, so long as CharacterInfo and CharacterExtras are
separated structs.

WARNING: this breaks the saves made in 3.6.1.14 (Beta 15)...

Additionally, done so that legacy scriptnames are not loaded from current saves,
since these are supposed to stay fixed throughout the game (at least unless
characters are created dynamically, which they currently are not).
From upstream c15603adface26d3ea44519f07f4992c3201ad53
2024-10-30 18:07:42 +02:00
Walter Agazzi 419e2d7372 AGS: Engine: simplify display_at, and only call it for blocking messagebox
Because _displayspeech() was calling _display_at(), there happen two consecutive
calls to try_auto_play_speech().
If text contains more "&" characters that might lead to an unexpected scripting
error, or even an overriding voice-over.
Instead made _displayspeech() call display_main() directly, and simplified
display_at() to work strictly as a message box starter.
From upstream 1899fad4c4df0e2ddce7eb04699eb262e3638674
2024-10-30 18:07:42 +02:00
Walter Agazzi bdb34c01cc AGS: Engine: unrestricted scriptname and name in CharacterInfo
NOTE 1: we *must* keep the old fixed-sized fields for the time being,
 for compaibility with the plugin API. Would the plugin API be adjusted
  and have direct access to a character data struct removed, then these
   fields may be removed as well.

NOTE 2: we still read these old fields from game data, avoid changing the
 data format in the middle (in the sake of both backward and forward
 compatibility). These fixed-sized values are assigned to the character
  properties first. For unrestricted values we'll have to add a data extension,
   appended to the end of data format.
From upstream  b02814b8bb3bb7a2cd00110466e2bd3047e772d1
2024-10-30 18:07:42 +02:00
Walter Agazzi 80dcc60a78 AGS: ScriptAPI: added formatting support to a few text displaying functions
This refers to:
* DisplayAtY();
* DrawingSurface.DrawStringWrapped();
* Character.SayAt();
* Character.SayBackground();

From upstream e90f366b5abc2f7a89f16a40f24ccdc63fbe3601
2024-10-30 18:07:42 +02:00
Walter Agazzi c6e115e697 AGS: Script API: added readonly ScriptName property to all applicable types
From upstream a19c52bae9d8513bcb68924c0c4f11717dde90e7
2024-10-30 18:07:42 +02:00
Walter Agazzi 455b9609d0 AGS: Script API: implemented Type.GetByName() for all applicable types
From upstream 29602688ec766cdc0b8fb7aa761f73292365651b
2024-10-30 18:07:42 +02:00
Walter Agazzi b498b14ecc AGS: Engine: save global draw method args in DrawState struct
Avoid query gfxDriver's properties all the time, instead save them once in init_draw_method() and use saved values.

From upstream db535512af65119d50ae3d6fb06c221d56f42d85
2024-10-30 18:07:42 +02:00
Walter Agazzi e81c85c917 AGS: Engine: removed wrong cast to (char*)
From upstream e4fa97f8a7042b282a0a6ab504e731f1c32a7d93
2024-10-30 18:07:42 +02:00
Walter Agazzi f13f7cfac2 AGS: Engine: rem the distinction between static/dynamic objects in script VM
From upstream 04450b2a41f0e0f107a4ea85dab375f439b4ffae
2024-10-30 18:07:42 +02:00
Walter Agazzi 20706c475f AGS: Engine: Complete move to new API registering
This complements the previous commits related to the upstream commit
9221ea54c1a81b9f37829d7fafc90ac2806d4eb1:
Engine: replaced script API registration with cleaner array tables
The benefits are:
1. Cleaner registration view, an array initializer instead of myriads of function calls.
2. Implicit distinction between static and object member functions based on prototype
detection, no need to explicitly pass a parameter or call respective registration function.
3. Enforced function registration for plugins, now combined with the regular registration
in one table entry, so more difficult to skip plugin variant
2024-10-30 18:07:42 +02:00
Walter Agazzi 4799ff06d7 AGS: Engine: fixed silly typo in dataver condition in Character_SetSpeed()
From upstream 9ffaf228534fd305b8253ff2197f5c819ca49899
2024-10-30 18:07:42 +02:00
Walter Agazzi 56b3fd3299 AGS: Engine: converted MoveList::onpart to float
From upstream b0ba1ac225c0b4e5093e58ff70051cf0e297f06b
2024-10-30 18:07:42 +02:00
Walter Agazzi 7d2b747cae AGS: Engine: smooth transition when ordering to walk while walking
This is an attempt to keep character moving seamlessly when a new walking order
 is made while the character is already walking.

Historically, engine had a problem with this, because of how a walking step is calculated.
In short, a MoveList struct increments a number of "steps", but these "steps" may be less
than pixel, in which case it takes >1 frames to make a visual change.
When a new walking order is made, this step counter is reset. This means that if player,
for example, keeps clicking around, the character will be "stuttering".

In this commit we try following solution: if the character is already walking, then save
last value of a fraction of "unfinished" pixel step, and apply it to the new movelist as
a starting step counter.
This works pretty well for in case of manual orders.

I must note however, that still, due to the nature of this counter, there may be issues
if a new Walk order is assigned each game frame. This may be done e.g. in script.
In this case, depending on various factors (relation between x and y distance,
walking speed, linking to animation, etc) the character may visually walk in a "ladder"
instead of a straight line.
This is probably will not be noticed when commanded by a player, as players commonly
do not click that frequently.

At this point I'm uncertain whether fixing the above would be only a matter of changing
the types of variables (fixed -> float, in attempt to reduce conversion mistakes), or a matter
of changing the core movelist mechanics.

From upstream a56e62ba65f16628265244a2da217c591b2a1271
2024-10-30 18:07:42 +02:00
Walter Agazzi 2dc8b67350 AGS: Engine: in MoveList store steps as fractional values, for recalculation
Make MoveList::onpart a fixed point value too, allow more precise "current progress"
recalculation when the moving speed factor changes.
Possible TODO: on move update, the first step after recalculation should bring `onpart`
 the the nearest integer, to make the movement progress more consistent.

From upstream b28ca9f86b8b70a73e4f6fa6f1c72ce76f29ecf6
2024-10-30 18:07:42 +02:00
Walter Agazzi 99ca176e58 AGS: Engine: support changing walking speed during walk
Recalculate MoveList, substituting the walking speed factor.
From upstream ca0a4e94c35c4d365299fabc33576b7283f275bf
2024-10-30 18:07:42 +02:00
Walter Agazzi 56c790c838 AGS: Engine: tidy do_movelist_move() and MoveList further
From upstream 3292c4cf7ff549832fdd0249ac1ee6d805e91f93
2024-10-30 18:07:42 +02:00
Walter Agazzi 22cb981566 AGS: Engine: rewrote MoveList to avoid packed shorts
From upstream d463adac63817fd08eb757038f90c730726124d3
and 09203df6efb19cf0f2eafd098c798733bd85cfe0
2024-10-30 18:07:42 +02:00
Walter Agazzi 84f7493959 AGS: Engine: support scaling character sprite offsets after char's own zoom
Historically, neither Character.z (vertical offset), nor picture offsets (ones set by Character.LockViewAligned() and Character.LockViewOffset())
 were not scaled along with the character's sprite.
Although it seems like that would be a right thing to do in a majority of practical applications of these properties.

This change introduces a separate zoom factor for these parameters. It's done separately to be able to maintain backwards compatibility.
 In backwards mode this factor is always 100 (%), in the new mode it is always set equal to regular character's zoom (whether got from
  a manual property, or a walkable area scaling).
The switch between modes is controlled by OPT_SCALECHAROFFSETS. This supposed to be always set in the new games. But this is also
 a backup opportunity to disable this behavior, if a user finds it making it impossible to achieve a previously possible effect: in such case
  one may disable this when compiling a game, or call SetGameOption(OPT_SCALECHAROFFSETS, 0) in script.

Code-wise, I had to move get_effective_y() method to CharacterExtras class, which makes more sense, as that's a runtime character class,
 as opposed to CharacterInfo which is a game data serialization class, shared with the Editor.

There's still alot of potential for refactor and tidying the code, but I'd leave that for another task.

From upstream a2b0c88379f37fdaf44155e37f372b7de725db21
2024-10-30 18:07:42 +02:00
Walter Agazzi f866475b7f AGS: Engine: REALLY apply character's anim volume to portrait animation
+ process frame features for the first portrait frame too.
From upstream efc3941fe335d0cf4a34dbb65a75c012f8d6df40
2024-10-30 18:07:42 +02:00
Walter Agazzi 2ae4a1ebd8 AGS: Engine: some refactor + apply volume for character face animations
From upstream a31beb6b76243902e75a49e901165c9565e8553a
2024-10-30 18:07:42 +02:00
Walter Agazzi f35fe9b988 AGS: Script API: added Object.AnimationVolume, like in Character
Missed to add this in 3.6.0 (thought it is not necessary for some reason...)
From upstream 480a8de9d3c5dc36eaaa3e4be94a1edf00445d68
2024-10-30 18:07:42 +02:00
Walter Agazzi f9087ab378 AGS: Engine: optimized ScreenOverlays storage (vector variant)
Keep ScreenOverlays in std::vector, but do not erase elements
 in the middle and invalidate them instead. Record free indexes
 in a helper stack.
 When creating a new overlay, first check for the recorded free indexes.
Overlay's type now equals storage index.

This speeds up both creation/deletion of overlays, and their access.

Removed the gap between "fixed" overlay types and custom ones,
 to save space. If we ever need more special overlays, these could
 be created as custom and their ids saved in a variable (similar to
 how background speech works). Previously present special overlay
  types are left for backwards compatibility (and to simplify the transition).
  From upstream f7d2f162fa55aa1b6f37195d890ebe047a204154
2024-10-30 18:07:42 +02:00
Walter Agazzi d8d4a77724 AGS: Engine: hide "screenover" vector behind interface functions
From upstream 3b049092875293b0960013910586f3adb017c862
2024-10-30 18:07:42 +02:00
Walter Agazzi 90f94f74c0 AGS: Engine: reduced spriteset's [] operator use where possible
The spriteset's [] operator loads a sprite, but some operations may
 omit that and check the preloaded information instead.
This also makes it more certain where the actual sprite's bitmap is necessary.
From upstream df30fc1edd30d4f334addaf7883286e745dea2c3
2024-10-30 18:07:42 +02:00
Walter Agazzi 959d894606 AGS: Engine: fixed first Sierra speechline not accounting for disabled gui
From upstream 34957df168f27d6eeffc0f821f0d2632af404b89
2024-10-30 18:07:42 +02:00
Walter Agazzi ac85f7fc52 AGS: Engine: unified API assertions for view, loop and frame
From upstream 1fe83591970e6a87d1f97c8f4e2d752a3a35b301
2024-10-30 18:07:42 +02:00
Walter Agazzi a23bc88912 AGS: Engine: character and room object share function updating sprite scale
from upstream 54b689724c076e92e70decf9fe795ea76bec5f84
2024-10-30 18:07:42 +02:00
Walter Agazzi a90e5b7dd7 AGS: Engine: added missing exclusive variadic api impls for plugins
from upstream a61392135e734898b93d73db42942dc881250ef2
2024-10-30 18:07:42 +02:00
Walter Agazzi 09039ca805 AGS: Engine: brought multivariant script api functions to naming consistency
The idea is that the old variants have internal names with number
(signifying number of args), while the latest variant has a name without number.

Make sure there's a distinct function for each variant, and older vars are calling later ones in a sequence.
These calls likely to be inlined.
From upstream ca48926a37e848a1bcc162f77cc81e63ec7a1ca0
2024-10-30 18:07:42 +02:00
Walter Agazzi e0aab081f2 AGS: Engine: picked out view-loop-frame Animate params check, fixup sframe
from upstream db71d928a6f290172975209d36ba7b7e22881f57
2024-10-30 18:07:42 +02:00
Walter Agazzi c4f25a16ed AGS: Engine: ensure that all AnimateCharacter variants lead to the same impl
from upstream eb623b4557c91e353fe6fa1bbcfc109e614ceac2
2024-10-30 18:07:42 +02:00
Walter Agazzi f75a45d38d AGS: Engine: separated RoomObject's internal ANIM flags, fix ONCERESET arg
Separated internal RoomObject's storage values for ANIM_* types into OBJANIM_ constants.
Use common ANIM_* constants in shared code, such as ValidateViewAnimParams() and CycleViewAnim().
The internal storage values of objects, characters and buttons are converted from and to ANIM_ values
as necessary.
2024-10-30 18:07:42 +02:00
Walter Agazzi d5bf4fee8e AGS: Engine: tidied use of Character::animating and flags
from upstream 35b5cde74c166f98be62ab9de44b0bda02b80741
2024-10-30 18:07:42 +02:00
Walter Agazzi 3a5ccd4cba AGS: Engine: moved dynamic object management functions to a separate unit
From upstream 1a9df937e3ac9eba0c2f5b663507a52569d635e0
2024-10-30 18:07:42 +02:00
Le Philousophe 49b4c1b3c4 AGS: Revert to use std namespace
This allows to minimize changes from upstream
2024-07-08 21:37:28 +02:00
Paul Gilbert c2a476411c AGS: Move std namespace into common/std/ 2024-07-07 15:28:31 -07:00
Walter Agazzi 0b50067abb AGS: Engine: implement add_waypoint_direct(), fix AddWaypoint's resolution
This fixes Character.AddWaypoint not applying room<->mask resolution conversion,
which result in character's speed being different if room has non 1:1 mask resolution.

Hide calculate_move_stage() inside pathfinder, and expose add_waypoint_direct()
in the pathfinder interface instead.
From upstream 093354d78849dc3b4f13a244d4400c4e71f7d687
2024-03-28 12:01:52 +01:00
Walter Agazzi dacccc343e AGS: Engine: fix use of global "walkspeed" variables in the pathfinder
These variables had to be set using set_route_move_speed() call in order for
the find_route() and calculate_move_stage() work properly.
But it's not obvious, and easy to forget. So turn them into function arguments instead.

This fixes Character.AddWaypoint potentially using wrong walkspeed, if there are
multiple characters or objects moving simultaneously.
An example of a script that would cause a bug:

    cEgo.AddWaypoint(20, 20);
    oObject0.Move(0, 160, 1, eNoBlock, eAnywhere);
    cEgo.AddWaypoint(200, 200);

from upstream 9a00255a2699845bd0e53054d81c24e6955f663e
2024-03-28 12:01:52 +01:00
Walter Agazzi 092ef64fc6 AGS: Engine: fixed speech stuck in "post state" under some conditions
This fixes repeated post-state on/off switching, and as a consequence - endless loop
 in cause of a "..." sentence, that  is run until messagetime reaches -1 on its own,
  which did not happen because of repeated post-state.

NOTE: looks like an original bug introduced along with the DisplayPostTimeMs property.

From upstream 37360990b22a79380f2a5b34e686a2d2fbcf7de1
2024-03-28 12:00:55 +01:00
Walter Agazzi d18f7cac25 AGS: Engine: replaced another case of strncpy with snprintf
From upstream 73e49b44db8042aa307bff7fadf51f67156658be
2024-01-17 03:12:31 +01:00
Walter Agazzi c688b1d586 AGS: Engine: log warnings when Display or Say is called during fade-out
From upstream d7235fcef3c3ff042f9a4f9eed6ac0a250296927
2023-11-02 20:06:27 +01:00
Walter Agazzi 6166993f42 AGS: Engine: fixed WalkStraight() was resetting animation
if called again

This makes Character.WalkStraight() have the same animation
keeping logic as Character.Walk().
Also reduce code duplication by calling walk_or_move_character()
 which handles blocking movement already.
 From upstream c5b04eb0c8991026ebca593d6f3254dfe96fd290
2023-09-16 13:32:59 +02:00
Walter Agazzi 94a8518dd7 AGS: Engine: don't reset idle animation during speech with no speech view
This fixes idle animation getting reset to frame 0 at the blocking speech start
 if there's no speech view set. In such case the idle anim is expected to continue
 playing seamlessly.
 From upstream 7b399933a291a05e868cd9589b02d83d05f33314
2023-09-02 14:02:10 +02:00
Walter Agazzi 7cd860207d AGS: Engine: add object and char assertions in Get/SetProperty functions
Since older commit 5f3b8eb the properties are stored in vectors,
strictly resized to the number of characters and objects.
But the script functions that access these do not do any assertion
whether the object or char is valid, which could cause bad mem
access in case script loops over a array of objects of MAX_OBJECTS
size, or tries to access something using Object* pointer from another room.
From upstream 6ad4b220d75a32ea8df959e9a7b7f1ecb21d0c26
2023-09-02 13:23:59 +02:00
Walter Agazzi 4966d2a896 AGS: Engine: apply character's anim volume to portrait animation
+ process frame features for the first portrait frame too.
From upstream 59d4f740001b61af370ec0bca676a24d597f66b2
2023-08-13 10:58:26 +02:00