[Scummvm-git-logs] scummvm master -> 6cba76e056a71ecc8f7e396f5459206c51377289
sev-
noreply at scummvm.org
Wed Nov 12 15:08:35 UTC 2025
This automated email contains information about 908 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
ca1d031be4 VIDEO: add Surface::getRect
9dd0e041d2 AGDS: added minimal engine and detection of black mirror
4e6ee6b12a AGDS: read config file, log path entries
7d41c7ee03 AGDS: added resource manager and grp file scanning
c99f585dff AGDS: Implemented ResourceManager::getResource
aa3ece6cb4 AGDS: changed decrypt signature and scope, allowing external usage
d75dff1104 AGDS: implemented adb file scanning/loading
ded41b2b3a AGDS: fixed include guard
e424791da8 AGDS: fixed data offset in database
54677250a5 AGDS: added object code loading and simple process execution loop
90cfa82602 AGDS: implemented first few opcodes
2a6248bdae AGDS: added resource table parsing
353ad3b35d AGDS: added pop instruction
122bf85e03 AGDS: moved resource string table initialisation to object, made it lazy
85c03f9e83 AGDS: implemented setSpecialVariable stub
7c539a21c0 AGDS: renamed special to system
070c2b0eeb AGDS: introduced popString()
aeb5012b1d AGDS: pass engine pointer to process instance
bbb72808df AGDS: implemented shared storage and append to shared storage opcode
5dd9e6569c AGDS: implemented process suspension and loadScreenObject
3feccb436c AGDS: implemented simple nested scheduler stub
d7d1f298a3 AGDS: moved opcode related code to process_opcodes.cpp, added more stubs, fixed process activation
c66d23d4d1 AGDS: added clearScreen stub, moved all the rest of opcodes to separate header
626cd9e6b3 AGDS: added 4 new instructions
d6aaf89733 AGDS: added name to object, output it in unknown opcode exception
9eed06fe14 AGDS: fixed stub 140 implementation
bec1a83eaa AGDS: implemented playFilm, GetGlobalImm8
ff1f162257 AGDS: added stub206
0521108147 AGDS: added kExitScreen opcode
60268178ae AGDS: return empty string from getString(-1), as it's always the case so far
3f310e8689 AGDS: added suspendProcess, and findObjectInMouseArea stubs
2877c1461d AGDS: added 16 new instructions
b80765dd96 AGDS: implemented region stub, do not take ownership of stream
33a6cac27c AGDS: added arithmetic stubs, added setScreenHeight
f089f28026 AGDS: removed noisy resource block logs, port it to debug channels later
be1582ef13 AGDS: do not restart process for loaded objects
4c70bcc6a3 AGDS: load object from stub165
cc1f301ce3 AGDS: load object and region from findObjectInMouseArea
63215e1333 AGDS: added a few more stubs
7a850fd007 AGDS: removed execution of object code in findObject
16e254dd4a AGDS: fixed copy-pasted typo in getRegionHeight
d7557d72da AGDS: added extended region data parsing
a8b7bc027c AGDS: resume after suspend
7c8966c64a AGDS: added fadeObject, jumpImm16 and a few stubs
6ca4b1c969 AGDS: added incrementGlobal + dumping unary/binary ops results
f97ddb713e AGDS: push(opcode) instead of stub 0
a7fd9f3e08 AGDS: copy-paste ninja was here
2b410cce9f AGDS: added Process:top()
d42b925057 AGDS: fixed increment/decrement global opcodes
4c75dc5b20 AGDS: added incrementGlobalByTop instruction
b505fbd4b0 AGDS: reimplemented stub140, output process number in wakeup log line
c50d20f009 AGDS: kStub98 is kDisableUser
4d30a6c6ca AGDS: added Process::debug and output additional script info there (object:ip)
737ba5b67c AGDS: fixed logs in changeScreenPatch
7b92339fd1 AGDS: output file offset in ip
881f892062 AGDS: remodelled scheduler, round-robin processes, logic there is still to be determined
57689289fa AGDS: output starting ip of instruction
9cccdc1188 AGDS: return false from screen patch routine
da7728283e AGDS: renamed stub165 to moveScreenObject
91671530f3 AGDS: removed trailing colon from debug format string
c23eb525c9 AGDS: load first object argument to stub188
0cfc14f1c8 AGDS: check done flag and purge finished processes
fc7cf0c19a AGDS: more logs in case of failures
3e073892a9 AGDS: added stubs for opcodes 155, 156, 166
698204dc36 AGDS: output 2 bytes from object on load
e91a53166c AGDS: output field 3 from extended region entry only if it was initialised
816238f8f2 AGDS: added Process::popFilename, and Engine::loadFilename for resource convenience
2ada111d5f AGDS: added graphics initialisation
355d78b972 AGDS: renamed setCounter to setTimer, added active() and main loop
8dc86d7c42 AGDS: added simple mjpg player and playFim support
e5f10f773e AGDS: removed comment
510b520a24 AGDS: use 25 fps as a base
5cf5782b35 AGDS: renamed stub182 to kSetGlyphSize
9ab8d008f4 AGDS: made resources case-insensitive
bfc1b4be5a AGDS: added ResourceManager::loadPicture
603a825512 AGDS: added picture to object
47faa4ce2b AGDS: replaced resource string table with array
7c36c29b4a AGDS: convert video frame, use lockScreen instead of copying raw pixel data
e0662c6056 AGDS: fixed assertion in intro stream
fb5b2cbfdc AGDS: reworked surface loading (fixed ownership problem by converting to display format), added implementation of surfac
a7b3a165df AGDS: implement object move opcode
6773542b44 AGDS: removed colon between name and ip for better readability
5c3d7044c2 AGDS: implemented basic screen container
e16e1c28c2 AGDS: removed _nextScreen, cleaned up screen handling
a81447479f AGDS: return control to main loop on process suspend
853c43a3be AGDS: properly crop out-of-screen rects
874aaad489 AGDS: added getters for object x/y
2eded2059e AGDS: added mouse move event handling
7582419ef2 AGDS: added FLC mouse pointer loading and rendering support
9f56d51f5f AGDS: pick up pixel format supported by transparent surface
60ffd747f6 AGDS: added TransparentSurface support, convert colorkeyed surfaces to surfaces with alpha
fc226e4ce6 AGDS: fixed invalid clipping rect for movies
352ceeee43 AGDS: improved region support
4969a1184c AGDS: added region to object, allowed searching object in scene
a79203fdc8 AGDS: implemented mouse enter/leave events
1400c042a0 AGDS: split loadObject and runObject, run objects from loadScreenObject/loadScreen opcodes for now
1360b04f0b AGDS: added click handler for object
8a4b5f54fe AGDS: implemented resetGlobal, stub235 and quit opcodes
c5e64237d3 AGDS: added pcx format support
7f578912a1 AGDS: generalised Process::suspend(), implemented opcode 80 and fixed relative offset in callimm16
fb7304cc62 AGDS: added stubs 173/174, post decrement of global and generate region stub
7087e7ee21 AGDS: added more opcodes and extra argument to loadObject/runObject - prototype, simplified suspend() code
0e4fbad0cc AGDS: more opcodes and stubs
b8ddde5508 AGDS: cleanup mouse area for opcode 80
26c9e5dbf5 AGDS: added navigating previous screen support (buggy)
5c42ca702b AGDS: added more stubs to run new game
a178bbc447 AGDS: Fix warnings
c3265484bc AGDS: renamed loadObjectAs to cloneObject
4dfe665d4d AGDS: added loadText, removed local decryption code from engine
262bc0cd06 AGDS: added system variables support
674ce7b09f AGDS: added stubs 172/194
372e78479f AGDS: fixed non-transparent surfaces in objects
899d647239 AGDS: more stubs, implemented dup()
4348bf36f7 AGDS: added exitProcessCreatePatch stub
86ef95ea53 AGDS: return -1 when global was not declared
f566272553 AGDS: implemented enough opcodes/stubs to run new game
c5d0af1a14 AGDS: implemented proper fps limiter
8117f90d29 AGDS: implemented fadeObject
007ad05b96 AGDS: clip input alpha to 0..100 boundaries
1f7952101a AGDS: reworked mouse area handling, figured out what op 206 does, removed mouse area clearing hacks
dce6d14e42 AGDS: added logs from jump instructions
3a3140470d AGDS: renamed resetGlobal to resetPhaseVar
47cb65f9f3 AGDS: renamed phase var opcodes, store current phase var
0c8d094d1c AGDS: added SoundManager class
ca88990e7c AGDS: ported resource loading to scummvm's Archive/File
6b4c0f9954 AGDS: implemented playSound (only scummvm part)
7a11b0fe26 AGDS: implemented sound list, reset phase var to zero for now
8e00b9f3a7 AGDS: removed useless fillScreen(0) in run()
7c921190f7 AGDS: improved process suspend logging
18a1b63f6c AGDS: process all processes in one tick
a840773ffd AGDS: renamed loadFilename to loadText
ab9d0a76e4 AGDS: more stubs, mostly for inventory
f8155280b6 AGDS: implemented inventory
0a72f980d5 AGDS: not inventory size, but free space in inventory, fixed
798fb215b6 AGDS: do not double-load text from loadTextFromObject
d975093144 AGDS: added more stubs, new game starts now
bc551f2891 AGDS: updated mouse area log
ae310a0ac5 AGDS: stub191 is disableMouseAreas
3e43a55b49 AGDS: destroy process on error condition
3ae2964c70 AGDS: do not run processes outside of current screen
ee51f03978 AGDS: made enabled flag counter
b227a5a7ef AGDS: suspend after call
64d0eb4364 AGDS: implemented runProcess closer to original, run object code once, push all processes once per tick after suspend
e8550ebde2 AGDS: exitScreen seems to be disableInventory
80a01d37f9 AGDS: implemented simple animation support, ported mouse cursor to it, properly resolve current cursor from current obje
73970dedc9 AGDS: Fix warnings
1a01e9df56 AGDS: marked all known handlers with [handlers] word
a6dba7e1a4 AGDS: return empty string for empty value
b183cf056d AGDS: do not output noisy 'last char' log
c36248cfc3 AGDS: feeble attempt to pass reference rewriting and fixing previous screen handling
a29fe16c16 AGDS: non-existing global returned as zero (see opcode 21 and others)
a689f2f860 AGDS: fixed formatting
91e29f1b02 AGDS: implemented init_resources var handling
6b905c4813 AGDS: more code in createPatch stub, call done_resources object first, clear inventory, and then init_resource
42096ea884 AGDS: renamed stub188 to setObjectText
f86cb6acd5 AGDS: added few character stubs
c5b0dcb203 AGDS: fixed previous screen support, opcode 80 stores current screen name in history before load
2c1ad059cf AGDS: added stub216
260657c9ff AGDS: put runObject(string) to definition file
612d77ca7c AGDS: extra logs for getglobalimm8 instruction
b4d4cb9027 AGDS: call onleave before destroying, check that current area is not in use
d709366cea AGDS: original engine uses intrusive list to accumulate mouse areas and then link them to newly loaded screen.
f529e85415 AGDS: do not destroy process on resource initialisation, reworked destroy flag
ca09fc8213 AGDS: skip mouse area modification with negative index, it's intentional and present in original code
b664ca593b AGDS: more stubs, first locations are clickable
f0282f0a3d AGDS: removed screen storage, it's not needed
8583ace529 AGDS: added object animation support
f46667b67e AGDS: fixed previous screen name, and do not compare screen pointers, as they may differ
0471073d50 AGDS: added stub83
014226c2fd AGDS: added key handling support
ab76a35cd7 AGDS: added skipFilm by space/escape key
2cf522a3a7 AGDS: added fastmode hotkey (ctrl-f)
ede26f4c2e AGDS: reverted old behaviour, new process spawns first (engine uses single global current_pid)
a9be4fb591 AGDS: do not process key handlers if user flag is disabled
fdca7c1135 AGDS: implemented loadPicture and picture cache
5cb9d608d1 AGDS: store text assosiated with the object as member
e275b26927 AGDS: added setObjectText implementation
951f66628a AGDS: added preliminary text rendering support and Font class
1a832b9dbc AGDS: added negate op and stub233
9f099904c2 AGDS: skip resulting zeroes at the end of the string
0fbd894299 AGDS: scan glyphs and determine their actual width
8714aa1d59 AGDS: change region centerX/Y type to Point, render object name using region center for now
58e24f6412 AGDS: fixed fallthrough in F key handling
b1d418755b AGDS: fixed stub166
14ff04f7be AGDS: renamed stub176 to cloneName
81a6574862 AGDS: output stack size in debug()
22148b73f7 AGDS: marked stub194 as possible mute
980fc16761 AGDS: do not suspend process in moveCharacter
5171327a90 AGDS: renamed stubs 71/74
9042cfb3a2 AGDS: added another variant of moveCharacter (usermove: 0)
7991092b2d AGDS: more stubs regarding character animation
a89103474f AGDS: implemented cloneName
07e17e5573 AGDS: more globals arithmetics
d2636a0713 AGDS: added stub231
f4d72e7940 AGDS: implemented getCloneVar
7961f35673 AGDS: created Character stub and added simple animation phase support
b119f9edb5 AGDS: found proper names/opcodes for set delay/random/cycles
c829a08cbb AGDS: make Screen::remove return bool and output warning if nothing was found
3e4b7c62dc AGDS: implemented modifyMouseRegion
560b13050a AGDS: fixed lifetime of the objects, removed global object cache
544d7ee1db AGDS: added opcodes 102 and 220
c3d2142d9e AGDS: implemented InventoryHasObject and some inventory related stub
f37e82e099 AGDS: implemented stub 202
7d83dc0953 AGDS: support FLIC as surface resources (tab hints)
2d1d999afd AGDS: implement stub 233 as unload picture
e6a818006f AGDS: added stub160
7f14576fd1 AGDS: removed 'leak' comments
7514908664 AGDS: renamed arguments for addMouseArea
d6005a9c44 AGDS: fixed current screen handling while navigating back in history
b0f7896470 AGDS: read text from resource for fogOnCharacter
992ae7a242 AGDS: fixed memory leaks reported by valgrind
0fec63ea15 AGDS: minor cleanups, almost every location in chapter 1 is accessible
613016458e AGDS: implement Process::error(), skip stack overflows and terminate process
3f9bb3fb7e AGDS: provide additional info for stub63, it looks like it's inventory presence flag
ae0143bee1 AGDS: documented changeScreenPatch logic
cc265633a0 AGDS: implement changeScreenPatch
af3d96f5f7 AGDS: implement proper animation phase logic for characters
7ecd56aca7 AGDS: add some text stubs
c5bf06c730 AGDS: implement runDialog stub with defs parsing
a49b59ede4 AGDS: uncommented extended region entries
a00bbf0ee6 AGDS: timer is per-process, not per-engine
997fe75abc AGDS: added some magic dialog_var values, handle end of the dialog
58803d9d52 AGDS: schedule dialog process after dialog finished
ec68759c69 AGDS: removed dialog from logs
9541e4aaf2 AGDS: more dialog state transitions
0d5e00c3d7 AGDS: animation frames start from 1 and goes to N (inclusive)
39efed2053 AGDS: implemented stubs 154/155
47d4efa7b3 AGDS: log dialog object
9d34468e01 AGDS: added enableUser from fadescreen
f6087e9a23 AGDS: removed mouse area code, it's already handled in changeMouseArea
25fcdf3f39 AGDS: added inventory enable/disable implementation + tick stub
6462aa84b1 AGDS: removed `stub` word from getCharacterPhase
66326e76e7 AGDS: added missing pop() in stub200
ca316c6beb AGDS: assorted fixes of inventory related opcodes
2b91921808 AGDS: cleaned up mouse area handling
d4856c57d5 AGDS: cleaned up sounds a bit, added support for text voice over
f8dbabbc3b AGDS: cleaned up phase vars a bit, started investigating animations
d54b5d3b20 AGDS: fixed typo
d23092e968 AGDS: fix animation phase control, implement loop, cycle
06cafe66c2 AGDS: add name and object to Character
76f330a8c5 AGDS: implement opcode 236: userEnabled
bc0accc92a AGDS: added WARNING prefix for Process::error()
74034f4c92 AGDS: implement on-screen animation
c423e2d375 AGDS: implemented opcode 119: animation paused
d052d761dd AGDS: chain character animations, partially implement stopCharacter
1df655ae58 AGDS: do not run anything in parallel while dialog plays
147aab490d AGDS: partially implement setCharacter
6e370f6f2f AGDS: fixed animation timings
f7c35d51c4 AGDS: added experimental examine handler, reworked animation frames/cycle/loop counters
502e4c67c8 AGDS: implemented register use object handler opcode 63
660087b015 AGDS: improved logic in changeScreenPatch
5e4f7f2b19 AGDS: fixed obvious typos, added missing logs
59335f1690 AGDS: added hex output for data size in object
cd268d02a9 AGDS: remove runObject from setCharacter for now
56e17c162c AGDS: properly implement call
1cd04ef15d AGDS: set global to zero before animation actually started playing (fixes some infinite loops)
c279f45d44 AGDS: do not fail on invalid string id, resolve it later
8b7bf44307 AGDS: added inventory region handling
5a62f1feb3 AGDS: rename glyph size to tile size
d0ba885b01 AGDS: better inventory enable/disable condition
4ec20caa0e AGDS: renamed stub200 to SetTileIndex
caeebc5b80 AGDS: better picture caching, allow name -> id lookup and picture reuse
e7dbd9cd5c AGDS: implement SetObjectTile (184) stub
9875a417ef AGDS: added missing ~Object
83d341772e AGDS: implemented setObjectTile, copy tile data from cache
aa2333b577 AGDS: rename stub190 to SetObjectScale
254311b2a3 AGDS: remove 152/153 offset in stubs
c07b92e228 AGDS: check mouse area disabled flag when checking inventory
4a611bbd66 AGDS: add region generation stub
769d3c789f AGDS: fixed SetObjectZ
08505a590e AGDS: implemented z-order (animations have to be fixed too)
358084b4ba AGDS: sorted animation by z, implemented global and local z-order
557e529d28 AGDS: implemented generateRegion
b403f1fe91 AGDS: added rclick handler
2561dcfd9d AGDS: add region to screen object
efed59d26d AGDS: add Region::toString
9b69df80ec AGDS: convert region pointer to shared pointer, removed _regions
8645932416 AGDS: renamed Object::move to Object::moveTo
98a64b9c0e AGDS: remove loadObject from inventoryAdd
be5ddfa478 AGDS: skip movies in fast mode
18b2366f68 AGDS: add Region::move
1fadd916fd AGDS: rename stack arguments
d834fd88d4 AGDS: added getEngineId
83bfb88b55 AGDS: fix typo
10c806386e AGDS: add double-add warning
ddfacea58a AGDS: change z to 10 (seems to be game's default)
4ef0bfa0bd AGDS: destroy processes owned by different screen
20cb24ea43 AGDS: speculative fix for z order, assume default z of 1000, instead of 10.
98a8946b43 AGDS: enable scummvm-based save/load dialogs
02b818057d AGDS: reformat with clang-format --style=file
b4185bc1c7 AGDS: remove virtual, add metadata feature to metaengine
2db39bd7df AGDS: add override
37b4af34bd AGDS: implemented opcode 160, kLoadSaveSlotNamePicture
d1168cd946 AGDS: sync position and region.
36278f97ad AGDS: add kLoadGame opcode
3053385a56 AGDS: allow streams to be used for database
d806c435b8 AGDS: implemented loadGame stub
132e5a0312 AGDS: parse character file
28a2d8c21e AGDS: cleaning up saves, allow save_slot (-x)
99084ff065 AGDS: load system vars from save
dc7c01d0a0 AGDS: call loadCharacter from loadGameState
5a4614e876 AGDS: run inventory object code when loading objects
4efede434a AGDS: add readString(stream, size)
5165e84a64 AGDS: load engine state parts in original order
365f8674f0 AGDS: call init_resources after loading save state
001a7d0f0c AGDS: remove ugly Common::Array<char>
15cd0d6e30 AGDS: remove warning about double-adding object
27ebd9ce70 AGDS: fix all known z order issues, restored engine's default z of 10
f458e28582 AGDS: comment out debug in paint
971f691a75 AGDS: rename stub154/155 to getObjectSurfaceX/Y
b6fbb7abbd AGDS: replace _pos with dst (typo)
0fc72c41f6 AGDS: do not assume returned object was not null
c3b94ea7d7 AGDS: simplify region loading
7d3cbde881 AGDS: scan default picture offset (tranparent left/top parts)
09b89fd05b AGDS: implement stub152/153 (get base picture offset x/y)
ab94cefa99 AGDS: Add russian version of Nibiru: Age of Secrets to detection tables
d6191ac566 AGDS: parse videomode from config
27ec2f449f AGDS: set default size for readString()
b12e7de6e8 AGDS: implement patches
dacf2ad6d0 AGDS: add russian language detection (steam version)
43833892db AGDS: allow previousScreenName to be used
6a146d750f AGDS: handle object patches
7774d6c632 AGDS: process objects specified in patch
d549134665 AGDS: debug logs in patch
f52cdfc583 AGDS: actually push object to patch
fbea702a40 AGDS: implemented exitprocesscreatepatch (actually reinitialisation of the game)
e2a8a0bb99 AGDS: move mousemap/region code to separate files
ed05d0cd0b AGDS: clear mouse map and call done if exists
1ea7540714 AGDS: fix mouse area leftovers
b7ab93bf71 AGDS: remove override for now
1cbaa5f126 AGDS: fix opcode 166 (changeScreenPatch), return patch status instead of process status
1b698ff9e1 AGDS: reworked mouse map, remove it from screen
757c20f5cc AGDS: reimplement scheduler
c4eed516ce AGDS: call loadScreen outside of scheduler
d648d65c82 AGDS: Remove previous screen
1311d4825b AGDS: simplified logic for exit-and-load
60b977ad8c AGDS: return bool from Screen::add()
7a77b10570 AGDS: remove invalid assumption that mouse id could not be 0
26cd420332 AGDS: add any running object to screen
ccc2483b2b AGDS: hide current mouse area before resetting screen
16f9b2c9e0 AGDS: remove Process::activate
046ac3c719 AGDS: move exit code handling to Process
f24362c172 AGDS: rewrite process handling to match original engine
6bfb0f46b5 AGDS: more stubs
ed4a10465f AGDS: implement getting mouse position
00c4df9add AGDS: add comment regarding stub174
41089e0e6d AGDS: moved patch load/save to Screen
f659cefeda AGDS: use inScene flag to add/remove objects from/to scene
5e05840a07 AGDS: save/load default mouse cursor in patch
23f737aa9f AGDS: remove debug(OFFSET)
6cb6c5d9ba AGDS: fix id
eb56d3fbf0 AGDS: solved mistery with region extended entries, allow multiple regions per Region instance
c6b6f371cd AGDS: save opcode 209 (user use?) handler
c6a35102bd AGDS: fix constant reloading of inventory region
d10f369c95 AGDS: rip dialog off the engine
0bb1d7ff14 AGDS: kick processes when dialog is active
970c7137d2 AGDS: add two notification opcodes
016d59a62f AGDS: run dialog object
12117fb65f AGDS: implement dialog notification stubs
02678b219d AGDS: support sound id
8634ac1d31 AGDS: replace stub133 with setPanAndVolume
c1d8a003a5 AGDS: initial tell support
4c7f566078 AGDS: add text output to engine
949c876e8b AGDS: implement text layout to handle multiline aligned layouts
40016b9cdf AGDS: add flag for resetting text after sync sound stops
9292639980 AGDS: move text notification code to TextLayout, it used for both texts/dialogs
90c5654150 AGDS: implement explicit activation, do not automatically activate any suspended process
07d37e9eae AGDS: process next screen name from tick (as per original)
f764ee0eb3 AGDS: add Screen::applyingPatch() for check patch routine
67379575f7 AGDS: instantly restart process for some exit codes
69b1d69868 AGDS: remove old Objects typedef
04dc57b49d AGDS: cleaned up screen changed
19fedd20db AGDS: implement process reactivation on sound (if no phase var)
121dbfb2d0 AGDS: pass process to animation to reactivate if no phase var
081b3f664f AGDS: reworked phase vars
32a25cde57 AGDS: move some ObjectPtr usage to cpp file
37d8b491e3 AGDS: add debug console with run command
9c506b19a9 AGDS: add unpack-db and unpack-grp scripts
f7fcf18de9 AGDS: add reactivate command, export vars to debugger
e8e290412d AGDS: reactivate sound processes and update phasevar
58d4e1c0e7 AGDS: remove all processes before loading screen
f57cc4c7a4 AGDS: implement mod opcode
08a882a111 AGDS: signal animation frame and wake up process
80817d72c1 AGDS: implemented GetCharacterX/Y
86ac100902 AGDS: generate switch/header declaration of the single source, AGDS_OPCODE_LIST
3bf682b479 AGDS: clear animation from loadScreen
bd6b4efeb1 AGDS: add screen patch comment
bde8923b23 AGDS: add console info command stub + accessor for processes
530df0343e AGDS: remove noisy logs
50138cde1a AGDS: delete flic instance before load
63d0c0c022 AGDS: add 'info' command for console debugger
1807939469 AGDS: activate process after new game exit code
cad0050e1e AGDS: remodel phase update code in sound manager
e7177aba3a AGDS: slightly changed animation log
7ec64636dc AGDS: fix more phase var logic
326b6d74a4 AGDS: more opcodes implemented: pan/volume, restart/stop sample
894f08a8f7 AGDS: modelled timers after original logic
f2794385ea AGDS: add decription for remove mouse cursor stub, add more of fadeScreen stub (global var update)
1e391b094b AGDS: run the latest process if idle
56261ca41e AGDS: do not run processes instantly (fixme: original engine does it)
43d6863b70 AGDS: cleaning up process reactivation
c765a94eaf AGDS: log name for enter/leave processes
8fa9c76a08 AGDS: implement object recovering logic
eddc35d982 AGDS: suspend and close inventory does not modify process status, fixing this
4190bf7d4e AGDS: log if animation stopped via script
33bb105e24 AGDS: list animations in console info commands
080c3faf01 AGDS: implement more animation logic
a461816525 AGDS: implemented user/sysuser disable/enable
088f6748f5 AGDS: signal dialog text with dialog_var == -3
0071129f80 AGDS: allow empty text resource
c662822a68 AGDS: allow ncpSayNoSound and signal npc var
ffd187b684 AGDS: implement getTextDelay()
2db918d071 AGDS: add support for default text (which is actually used by dialog only)
7d57964a8a AGDS: add delay/random values for animation
8fd4f9e439 AGDS: finally fixed pause/resume
a3cd0c088b AGDS: animation refactoring
8f1086dc2e AGDS: implement rolling sample index for dialog sounds
5aa9dc2986 AGDS: revised sound manager phase var/activations
993680807a AGDS: reactivate process when text layout resets
b84fcf5e74 AGDS: move common animation code to Process::setupAnimation()
b1399e3ad7 AGDS: decode/show first frame
236af478df AGDS: rename _animationPaused to _phaseVarControlled
5243e004f1 AGDS: skip phaseVarControlled animations with no frame, allow resume
fda9eda54a AGDS: use (phase-var) instead of (paused)
a3073ceb47 AGDS: fix typo
a65a19b081 AGDS: do not ++i twice in animation tick loop
bcbc9bc887 AGDS: fix animation so intro sequence partially works now
a344c0e05c AGDS: implement opcodes 120, 125
afb6c85b91 AGDS: implement opcode 96, setCharacterDirection
eebc96ece6 AGDS: port engine to the new API
8725304774 AGDS: initial refactoring of character
c79b114327 AGDS: implement Character::moveTo stub
8399f0e186 AGDS: implement animateCharacter
6455ea2705 AGDS: enable character by default
509becef2e AGDS: do not add all animations to screen
da4c7622fa AGDS: implement show/hideCharacter (+opcode for hide), set x,y,dir from savegame
beb72eb9a0 AGDS: fix wrong move coordinates
0d80e505e3 AGDS: clear _nextScreenName in loadScreen
9d08a34cc3 AGDS: use ProcessPtr instead of Process
2283af4938 AGDS: implement process table to mimic original behaviour + fix lifetime issues
5642d2add5 AGDS: output unknown header fields of CHR file
c973a81a8f AGDS: add _movementDirection
25519ff10d AGDS: add Character::getDirectionForMovement
a0ce0dd3cf AGDS: better resume/restart handling
20e3b2dfc3 AGDS: add Screen::setCharacterZNearFar
0810dd5777 AGDS: implement z-scaling for character
4a32865afc AGDS: implement animation speed
e42dbeb750 AGDS: ignore case while checking prefix for dialog sounds
f7c2755047 AGDS: output proper sample name to logs
111c4a567b AGDS: implement direction notification
dd9ec5827d AGDS: load jokes.chr/animateCharacter
79404a0b45 AGDS: add _animationPos and fix zeroing of character position
f02d4a0478 AGDS: implement direction check for default jokes animation
b6cc6bb870 AGDS: remove loop flags from character animation
f71af6692f AGDS: calculate max frames for jokes based on speed
45641716ce AGDS: do not reset character direction
12ece6aa19 AGDS: implement setPeriodic semi-stub
27c1e079b4 AGDS: remove rewind() from decodeNextFrame
f519975c02 VIDEO: add VideoDecoder::getCurFrameDelay()
a62cd54473 AGDS: readd runNow flag for reactivate()
3670df0bb2 AGDS: another feeble attempt to rewrite animation
98c3f4bf84 AGDS: use local dialog_var
08ec0de6e1 AGDS: add play jokes animation fallback
0951633562 AGDS: fix multiline dialog lines parsing
f0090c9a88 AGDS: restored old inScene() flag behaviour
8bb0bc2e5a AGDS: fix animation position
5194a0971e AGDS: improve character positioning
a307270a7a AGDS: fix animation loop
69ddaa1c9d AGDS: pass Common::Point as an argument to getDirectionForMovement
310b0a4dd3 AGDS: change argument to move character to direction
9e23f423ae AGDS: add set command
e82ebae3cf AGDS: fix stop phase value
01c2dddfc8 AGDS: add Screen::remove(Animation)
2efb19eed0 AGDS: implement z-sorting for char/child/animation
24a24ea8c4 AGDS: add 'load' console command (load + run)
b0c185ce02 AGDS: clear mouse map before calling resource init (fixes top-level menu and global mouse areas)
8b872b794b AGDS: rename stub138
1f7a145ab6 AGDS: add Process::disassemble stub
1dab8c2102 AGDS: rename change/checkscreenpatch
fbe7aecac3 AGDS: clean process at the end of the dialog
856889e914 AGDS: add AGDSEngine::stopProcess()
be583ebaf4 AGDS: fix crash in console (allow empty process slots)
3f016d4028 AGDS: activate parent dialog process at the end of the dialog
72bde4f34d AGDS: small animation/direction fix
3de298d1f2 AGDS: treat @ as a comment
17b5498b0d AGDS: remove botched move
d0b1210437 AGDS: implement opcode 139 (remove object and save patch)
6d86768fcc AGDS: use proper font for object texts
4105384d27 AGDS: separate texts and titles, so objtext is displayed separately
f6b0fe9cd6 AGDS: implement hint mode (left ctrl for now)
5d28aec9b0 AGDS: add Object::scale/_scale
38cd1299f7 AGDS: add Object::pointIn()
fe276118f1 AGDS: pass engine to screen objects
ae849797b2 AGDS: stop all sounds before loading game state
ce1806f3d6 AGDS: slightly fixed logs in runObject(object)
50a26b6d6e AGDS: return object from runObject(name), use it while loading game
4034228dbe AGDS: output handler ips in hex
73586595de AGDS: return object position adjusted with offset
a66bf2c7f6 AGDS: remove inScene check if looking up objects by name
40a7cdb94a AGDS: use runObject instead of loadObject when adding inventory object
8ac1bf6ac1 AGDS: add Inventory::find() and current object inventory querying
c81f277c50 AGDS: add reAddInventory(), readd all objects on screen change
87dafd429b AGDS: move reactivate to process API
4efc1a95c7 AGDS: implement removing from inventory
d98b5d08b4 AGDS: implement current object support and call 'use object with' handlers
b2e504092c AGDS: use skipFilm on film eos
3822839c46 AGDS: play audio for films
1eb8f936e4 AGDS: implement subtitles for films
41214d4175 AGDS: implement proper video synchronisation
6707b3d40e AGDS: better frame delta (single getMillis call per frame)
48844cae19 AGDS: add support for newline character in subtitles
54f726adff AGDS: wrap long subtitle lines
e3140c3113 AGDS: fix audio disappearance on scene change
db6654f057 AGDS: remove comment
1525da8bf5 AGDS: fixed object restart
7e9982cb83 AGDS: do not return removed objects from Screen::find()
110a79c0cb AGDS: split log to avoid confusion
c346a72047 AGDS: load/store character position/direction in patch
932aed9d7b AGDS: fully implemented checkScreenPatch opcode
cecb756efb AGDS: do not save inventory/cloned objects
cd6b209e9a AGDS: do not execute call if object was recovered
206e02a9e2 AGDS: call outputs dst address, not offset now
5adcf6647b AGDS: fix moveObject and implement stub166
281c29161c AGDS: remove runtime load/save because it's not supported
4857d17858 AGDS: reset save name picture if no save found
53e4403ad7 AGDS: add missing else
9c8094936e AGDS: add createPatch()
c25798e03c AGDS: implement incref/decref for screen patches
eee67d1310 AGDS: add stub197
e9ec21aa9b AGDS: implement opcode 151, compareScreenName
16b8e8416f AGDS: implement save game stubs
9adfd5794e AGDS: add writeString()
683e88903f AGDS: add Patch::save
bf5bf1ed45 AGDS: use tell_close_inv in AGDSEngine::tell
ad70e0a1de AGDS: do not play samples with given phaseVar more than once
41098938e9 AGDS: reset object position when picture loads
8d2efc2045 AGDS: return multiple objects from Screen::find(pos)
0529cffb65 AGDS: store engine to animation object
cd32cff2b1 AGDS: implement opcode 109
9292af434c AGDS: fix animation ids
811693fd3e AGDS: read color key, min/max shadow color from config, rename stub 223
fc8863f291 AGDS: implement colorkeying and shadow effect
141bf240b1 AGDS: use proper name of setObjectZtoDisplayHeight op
17fc1ac85d AGDS: slightly fix inventory load object logic
c25609bda5 AGDS: do not allow calls for screens with patch
5e2cd379aa AGDS: rename stub 193 to removeGapsFromInventory
1906451c39 AGDS: show _lastIp without +7
88c6820d85 AGDS: move Process::next to cpp file
962211b537 AGDS: add debug if jumpz didn't take conditional branch
0b96df7dda AGDS: rename stub 194 to samplePaused
07cbf16b38 AGDS: store only currently present objects in patch
07a7abe52d AGDS: loadScreen only loads patches object
6c32395823 AGDS: remove noisy char z log
14f86e95e8 AGDS: do not start all objects from the patch
bafd9576fa AGDS: optimised colorKey/shadow (no multiplications inside loop)
879c57bb3a AGDS: remove returnToPreviousScreen hack
e094bd6372 AGDS: loadScreen should load patches immediately only if returning to previous screen
dd714dffb1 AGDS: implemented hasPreviousScreenName flag
bd10b2c9e9 AGDS: disallow calls only if patch present
a008e8795e AGDS: disable calls for object restored from screen->load(patch)
c30a001191 AGDS: fix character z
3ef1a1f68b AGDS: port to the newest upstream
0ef9aeff34 AGDS: use getValOrDefault()
2a866351da AGDS: add opcodes for throw/use-on handlers
170d7267c6 AGDS: rename opcode197 to setRotation
06b3100a89 AGDS: add Region::empty()
165c2a7428 AGDS: rename stub201/202
d30cda07ff AGDS: use throw handler if use didn't work, use UseOn as a fallback for UseOn(object)
3c56994e9a AGDS: sync mouse position when process starts
819836dc24 AGDS: add debug log when mouse animation is empty (removal)
4f0a255cf0 AGDS: remove region when object goes off screen
a2ccb432f2 AGDS: add Object::getRect()
9ffa1968f6 AGDS: add throw/useOn handlers
0eec5e26bf AGDS: implement mouse cursor removal
096218f87c AGDS: fix increment/decrement global by top instructions
c0c77888ab AGDS: correct pointIn for object with animation
437876fc4a AGDS: add _rotatePicture
82e916a9be AGDS: implement rotation
4067dd5cb7 AGDS: correct text position by region offset
b6cb6addd3 AGDS: implement opcode 167 - return current inventory object
af84f21406 AGDS: fix findInventoryObjectByName, add hasInventoryObjectByName
fa7c684bf3 AGDS: rotate current rotated picture
745c9b077e AGDS: minor log cleanup, add setGlobal log
440fb93070 AGDS: handler logic finding cleanup and better logs
1c97aedf3c AGDS: massage lines a bit
e7468ac655 AGDS: free rotate picture cache in case of loading static mouse cursor
c670440fa0 AGDS: center current inventory object
3e8c72a784 AGDS: do not save patch if loadScreen called from loadGameStream
7106b380a6 AGDS: rename inScene to alive
89fc87bb47 AGDS: use original engine removal logic (current -> alive = false)
8c2a79b669 AGDS: share logic for loading patch object
dbbf27c5ab AGDS: console.run removes object from screen or it won't start
26d1a8b66c AGDS: simplify getGlobal
306a0a44e9 AGDS: pass allowCalls to load/runObject, don't allow calls for object loaded from patch
2487e42637 AGDS: remove doPatch logic for now
8cedbffc5c AGDS: solved long-time mystery, "call" is actually initialisation handler
e3848970f8 AGDS: fixed object lifetime cycle
85e3447006 AGDS: add Object::generateRegion(rect)
bff7da3c3e AGDS: generate transparent surface for empty saves
fd2cb6545b AGDS: remove stub from saveGame
68f99e2c44 AGDS: return false for all metaengine/engine features
f44df99cef AGDS: output warning if save has failed
4492f784d4 AGDS: overload load/saveGameState
430d682201 AGDS: add getDataOffset method
19b0c61049 AGDS: lowered stream interface requirements to ReadStream/WriteStream
8a01d5e4b8 AGDS: implement Database::write and save stub
c0f851fcdc AGDS: load game state cleanups, volume/type discovered
b93cc1aa55 AGDS: add ambient sound flag
1e6202f51f AGDS: reimplemented Database::write
e11ee7b579 AGDS: add Character::load/saveState
48f23dbb36 AGDS: save char id/resource name/object name in engine to save it later
124c5817c0 AGDS: move inventory load/save to inventory class
c9c22ece82 AGDS: disable autosave
42a1f6d320 AGDS: made Character::saveState const
c2883b2883 AGDS: implement/load object patch
e7513b5c51 AGDS: patch object if there's a patch for it
469f9b6353 AGDS: rename stub172 to setSampleType
1f6cffbf6f AGDS: add ambient sample implementation + SoundManager::find(id)
b07003b437 AGDS: implement game saving
922e3caaa7 AGDS: pass sample resource to playSound to properly save/restore it later
75192c15df AGDS: revisited previous/next handling
33dda54d18 AGDS: save screen patch before saving
38a8d32eac AGDS: fix crash when user interaction was enabled, but no mouse cursor
22e76f838e AGDS: add loadNextScreen
ca13c06fcc AGDS: improve screen history support, add support for loading type flag
1e4cccf7cd AGDS: add shl/shr
9917dda3fd AGDS: implement object patching
98e5241213 AGDS: add missing return
1ae8612b37 AGDS: moar logs
a7f2078819 AGDS: do not load patch for save/load type of the screens
b1839522b6 AGDS: pass final direction to stopCharacter()
c47532dded AGDS: reactivate process started by animate/move/dialog
4bf629106d AGDS: store text resource in patch, not text itself
88d1daa8c0 AGDS: fixed animation rewinding
bb18f9e001 AGDS: remove spam from char tick
87e7853566 AGDS: screen.add skips null
dae8d57630 AGDS: initialise Inventory::_visible in ctor
71443b8d4e AGDS: save process on stack, so loadScreen doesn't destroy current process
e2d8c7ba9c AGDS: constify Object/Animation::paint
45f48d4aec AGDS: split tick/paint for Character (made paint immutable)
8c7975d3ee AGDS: fix enable/disable inventory flags
736940aab9 AGDS: reverse z in Screen::find, so click will pick the top-level object
89539b472f AGDS: rearrange inventory/local handlers to fix their priority
530fa0bb48 AGDS: log allowInitialise
e6b8cd9be4 AGDS: adjust x coordinate of character animation
2880b8ff8e AGDS: re-enable inventory after text ends
578c21bff5 Revert "AGDS: adjust x coordinate of character animation"
52c3a740bf AGDS: store current animation description in character object
af809cb53c AGDS: initialise scale member with 100
d45d91d79c AGDS: support large screens
5e113b3237 AGDS: implement Character::associate
41ff8986e0 AGDS: character direction is signed
62b23893c9 AGDS: implement dual animation support for character
5711ef40a7 AGDS: stop all object processes when it's getting removed from screen, lock object in exit handler
ac944fb1c8 AGDS: reactivate animation process on each frame
f8ce56edec AGDS: add console 'stop' command
c1e25ef708 AGDS: fix the latest dialog definition
26ffdbd9d3 AGDS: handle @vybervariantyX and @varianta properly, keep current sample index
c6afd32df2 AGDS: do not signal character var when npc say finishes
4b0c0916f6 AGDS: remove stub from scale op
e9ea67c120 AGDS: make Screen::paint const
c7474cbac7 AGDS: do not use phaseVar for sync sounds
224712583f AGDS: change process status to passive from text layout, do not reactivate
4d0ff689e0 AGDS: add animation name to animation object
9cbf76e9c0 AGDS: add getRandomNumber function for engine
93e295b4fc AGDS: reorganised animation tick to be closer to engine's
c05ed093aa AGDS: activate dialog callbacks synchronously
c441007f64 AGDS: remove animation cache
1cbad8d43a AGDS: moved opcodes switch and processing to process.cpp
edf0e7a957 AGDS: implement process stopping from removeScreenObject
19a1d0c2fa AGDS: smooth rewinding (do not free frame), fix looped animations
2a3e3e167b AGDS: fix scrolling pos in Screen::find
80a4947f7f AGDS: pass allowInitialise to loadObject (in loadScreen)
837b10e8ce AGDS: more logs in patch
874732a98b AGDS: fix screen patch check
1f8b5fa897 AGDS: fix loading of screen patch preallocated by incref/decref
4b15dfb321 AGDS: remove animate call from setDirection
7f92d1c04c AGDS: stop ambient sound before adding new one
f9e203c45e AGDS: rename animationPaused to setPhaseVarControlledFlag
bb9346e536 AGDS: do not start non-ambient samples by default
00ad4c047e AGDS: log runNow flag in reactivate()
890a5da625 AGDS: do not return from dialog tick as we can miss dialog end signal, split directive processing into functions
5a585b7fee AGDS: implement screen region patching
74c2aa8699 AGDS: do not stop inventory onbjects removed from screen
68c1d6ad10 AGDS: rename new game opcode
a597eb30f6 AGDS: reworked process activation code, remove status dependency (original engine does not check it too)
0bb2119560 AGDS: allow lclick with current object attached
eeb7469d4a AGDS: remove readd inventory code
a85edad9f6 AGDS: add logs in engine resource ctor/dtor
e340f04a82 AGDS: fix crash if inventory object has no picture
26bd1c420a AGDS: remove noisy log
0bb38022f0 AGDS: implement setGlobalWithTop
93cb0540f6 AGDS: implement signal animation end
60e4ee929f AGDS: implement character trap handler stub
61a3cb2770 AGDS: properly implemented engine restart
fba946698a AGDS: slightly fixed indent madness
dc981e8f20 AGDS: implement trap handler
8c811fbdc0 AGDS: skip spaces in sound directive
b5736b72bc start playing if phase var is empty
f13b3a2edb AGDS: do not expect space at the beginning of each dialog line (RE mistake)
985d165b13 AGDS: do not reset syncSoundId in tell()
46a58b8e02 AGDS: implement gaps removing from inventory, call it on open and from specific remove gaps opcode
057e2e25ee AGDS: implement animation next frame opcode
b4528c07e2 AGDS: fix missing Surface::free
8987f8a1d8 AGDS: ported to the latest upstream
dfc40d4af6 AGDS: remove old hack and fix alpha
c05b136fed AGDS: do not call screen tick when dialog is active
f1321f5005 AGDS: add missing parameters
aacf784f83 COMMON: fix invalid right/bottom margins used in getBlitRect
6ef34bdde3 AGDS: render objects on top of animations
11fd3043da AGDS: fix active sound checking logic (fix brick puzzle and many other sounds)
f6dc22f43b AGDS: explicitly show character from loadScreen and loadSave
e221ad5ae4 AGDS: do not skip engine tick if dialog is active
220437221a AGDS: improve tick logic, run processes after animation was expired
09a84303d6 AGDS: minor mjpg cleanup
b8c8a1fc05 AGDS: log text layout reset
668283641d AGDS: activate character process only when animation finishes, not on any tick
36a1c6bd37 AGDS: log character description filename
43bfc37006 AGDS: add "add" command to debug console
1f73ffd98c AGDS: implement stopCharacter and fix freeze in chapter V
4e96bc3f70 AGDS: remove irrelevant comments, reactivate process before it
b7ceb1da6b AGDS: disable autosave (breaks any puzzle)
95e9b40088 AGDS: better logging from SoundManager::play(), start non-phase controlled samples
069f22d15b AGDS: accomodate volume/pan for samples
91bb27cb78 AGDS: add enableSystemUser correction
e3b3152f71 AGDS: cleanup exit codes handling a bit, fix a few deactivate/activate mismatches
ef407d757f AGDS: fix tile object opcode used with no resource
39d08f1afd AGDS: move character to the click point, skip respawning handlers, fix trap handler in chapter 2 (Vick)
51ccf7af58 AGDS: port to new engine detection API
3abde97b89 AGDS: port to the new API
edf5696423 AGDS: fix inventory at top left corner
febed22dfb AGDS: fix log string
5ee012f110 AGDS: separately handled animation frame and its on-screen status
3e7c1406b0 AGDS: clean character visibility up
b900d1843b AGDS: Fix font surface leak
a700e5bd8b AGDS: implement fog stub
263f253357 AGDS: remove _stopped check in active, do not touch visible
ea83311759 AGDS: implement blending with "fog"
2c36f3f9b4 AGDS: cache scaled surface/rescale animation
75c98d3311 AGDS: scan for visible height, properly calculate character base
82601a2d78 AGDS: move character only when any other handler failed
728d817609 AGDS: add background object logic
118af99fbd AGDS: use background object to calculate bottom margin for z/scale
827cb7d39b AGDS: return const ref to region
0720b1845f AGDS: implement set character direction opcode
94a93008eb AGDS: return constant ref from region()
f346ce5947 AGDS: reset character visibility on each loadScreen
f262642784 AGDS: add Inventory::add(String) to skip duplicate adds
ec89f79e35 AGDS: fix object finding logic, so we don't have to return array of matches, just the top one
0d4e7976c7 AGDS: implement ignore region opcode
96def13fb7 AGDS: fix duplicate process finding logic
c953aa0381 Revert "AGDS: fix object finding logic, so we don't have to return array of matches, just the top one"
0225963bbb AGDS: fix background
51db21ebf1 AGDS: read signed direction from save file
fe84e73be1 AGDS: do not skip cutscenes in fast mode
72c8270cd1 AGDS: remove background from z scale code
f84eb9ef3d AGDS: fix horizontal character alignment
d92af6f074 AGDS: ignore direction animation when jokes animation is active
fa10c451bc AGDS: animate/restore latest direction
1fe0a98461 AGDS: rename stub233 to objectRemovePictureAndAnimation
6b406dcdd9 AGDS: render inventory object mouse cursor first
d6bcd5f78a AGDS: back off mouse cursor change
2849af1646 AGDS: proper implement screen object protection
908853a043 AGDS: reimplelementing current object infrastructure
34653187dc AGDS: remove various inventory visibility hacks
bec9c565b8 AGDS: some objects have return to inventory code into their use-on(object) handlers - call it
b4c7b8bb87 AGDS: remove gaps only if no selected object present
261a064c81 AGDS: fix log line for use handler
30b4723256 AGDS: do not call simple handlers in a current object presense
857196f9b7 AGDS: silently add object to inventory after removal
ff9f6e63c8 AGDS: move character only on left click
0c7f924c92 AGDS: add reactivation reason
c3a3f6e118 AGDS: remove reactivation from dialog (not present in the original engine)
21effbad63 AGDS: restore suspension of main "tell" process lost in refactoring
3df3f973c7 AGDS: do not patch current screen (original engine)
606171f6e4 AGDS: fix missing argument to setRainDensity
9b2471bc54 AGDS: remove reactivation from character (breaks morgue scene)
2eed4ea3b7 AGDS: do not rewind if animation ended from restartAnimation
1a33419955 AGDS: do not return inventory object by default
5f31414b08 AGDS: clean old sounds without phase vars
bded747b1b AGDS: add fixme
2455561e74 AGDS: allow lclick to click on inventory arrows while holding object (for using objects on each other)
ec91f7db7c Revert "AGDS: do not patch current screen (original engine)"
83dfd6775e AGDS: do not lose the last message in dialog
a3ef27574a AGDS: non destructive dialog reactivation
7940da1215 AGDS: output warning if process finished with values on stack
358610258d AGDS: display only top-level object description
1a578f1905 AGDS: remove tickCharacter, call trap handler only from move
7d29040751 AGDS: remove all sounds and stop processes for removed objects
991db7ab77 AGDS: reset direction only if jokes was played
e9b264f8a3 AGDS: remove hack with single frame tick for non-jokes animations (now animations are loading its first frame at load())
e1349a7843 AGDS: remove double-tick for Character, reactivate process from tick
264d069dab AGDS: make stop/leave/move suspend process and change process name in character object
0a9f1ce86a AGDS: do not reactivate character process if there's text layout
ee7f9ac1dc AGDS: add Inventory::has (do not create object)
0b7fbe5c0d AGDS: add a warning about replacing current inventory object
2e9e9d9145 AGDS: remove dialog parent process/runDialog shortcut
fe38854f23 AGDS: add x,y from description to animation
d13e9a0fe0 AGDS: add missing cleanup after destroy
5162f7e06f AGDS: add missing suspend() in returnCurrentInventoryObject
be7d8f3e58 AGDS: clear object patches if new game started
78ed711023 AGDS: pass ambient flag to sound manager, restart ambient streams automatically
25bd4b7cd5 AGDS: remove bogus log level
cfc7e27dac AGDS: do not set sound process for ambient sounds
88980cdaa0 AGDS: implement "curtain" timer
669bbd5e8a AGDS: deactivate/activate process before/after move
9227d2425f AGDS: allow string to reactivate
2569cd3ec3 AGDS: suspend process that plays sync sound without phase var
f3a68676ef AGDS: reenabled attached object animation
d62609c9cb AGDS: implement bidirectional fading
f69cf0995e AGDS: do not run processes started by other screens
12e1d652a7 AGDS: better phase boundaries check
026f2345c8 AGDS: better handling of character stopped flag, handle direction == -1 case
a4973624e7 AGDS: only suspend parent process if animation started
cf4a99e155 AGDS: promote patch-related failures to warnings
41ca1b0e09 AGDS: remove _loadingScreen flag
4b8df38eab AGDS: do not store screen object in patch, so it won't be double-loaded
91ac0ee844 AGDS: processes which require reactivation put in a queue
b2ed2db310 AGDS: reset current screen before loading object
20b0c62dbe AGDS: match mouse area management/id allocation to original engine
77b0a19d8f AGDS: save before suspend
8c3939c505 AGDS: implement new APIs in ArchiveMember
79e5409cd4 AGDS: do not blit empty glyphs
fb859b6fef AGDS: rewrite mouse area handling to be closer to the original engine
b97c811d0b AGDS: add stub191 implementation
447944f6dc remove system user enable from leaveCharacter
8ea8ae9adf AGDS: disable user before hiding mouse areas
1ac39ee45e AGDS: fix order of the mouse area deactivation
d05700bd87 AGDS: return from hideInactive only if mouse area was really activated
4dbdc55cd3 AGDS: restore inventory region check
9c57c1ec6f AGDS: handle "keepGraphics" flag of attachInventoryObjectToMouse
72017c64a6 AGDS: add rotation support to animation, fix inventory object rotation
9664a574c5 AGDS: remove log when object name is pushed to the pool of strings
e838c471e3 AGDS: mark inventory object as non-persistent and don't save them to patches
ee12099926 AGDS: remove invalid comment
3e8dd751f9 AGDS: when cutscene is playing, act as a user was disabled
9e222ee6f9 AGDS: add safe animation removal - the real array resizing will happen in Screen::tick
cc03f5ee08 AGDS: fix initialisation order
e7efed7bae AGDS: remove process-level animation when process exits
295310c173 AGDS: use SharedPtr for animations, do not leak them
6efc59e6e9 AGDS: ArchiveMember fixup
15c858eb28 AGDS: replace TransparentSurface with ManagedSurface
39f297b476 AGDS: do not log jumps
869a0a5a2f AGDS: safer animation removal - keep AnimationDesc in screen/mark as removed
6f6546acae AGDS: follow upstream canLoad/canSave methods signatures
d15bda69a2 AGDS: rebase, adopt some string â path changes
823e4cae9a AGDS: call removeScreenObject from screenObjectPatchDecRef
43c9ad7b07 AGDS: remove process animation from stopProcess(name)
ffa788860d AGDS: add suspendIfPassive() and use it when needed
f291793de0 AGDS: clean up process deactivation/waking up in character code, better pointTo stub
c7a05a27da AGDS: do not use click handler with inventory object attached
65a83cb694 AGDS: print ip of each handler in log
44aa1f7190 AGDS: split visible/shown as visible character may be removed from the screen
c335e81f1b AGDS: reset character animation on screen change
73f0fd8391 AGDS: store BD/C1 handlers in object
320fe5ce86 AGDS: remove _stopped flag from character
be9ee673e1 AGDS: name opcodes 43 and 44
8ba083dd94 AGDS: perform object removal when the last process exits, call removeProcessAnimation from remove object, not from proce
bb5f249b74 AGDS: reimplement stopped flag
e04f2d42ac AGDS: do not mutate character state if animation wasn't found
2cd4683ccc AGDS: remove stop(process)
a818755956 AGDS: renamed getPhase to phase(), add setter phase(phase)
9d5bc80bd3 AGDS: do not reset direction in setCharacter
4cf6f7f05e AGDS: move does not work on invisible character
ff99fc0a09 AGDS: remove animation skip hack
c754e2709d AGDS: generalise stop flag check
1c6e8538b1 AGDS: create a patch for decref
21ba09d2ef AGDS: add patch screen [object flag] command
1e162cf681 AGDS: do not output OP, use just NAME
fd6fb513f1 AGDS: fix case phase var == -1, this means nextAnimationFrame will restart the animation
967b15fff8 AGDS: fix reactivation of character process (point seems to reactivate it - stub)
770936f4c3 AGDS: return character object to use with anything
50aea89071 AGDS: animation end sets phase var to -1
f0a3df0873 AGDS: implement video scaling
a3d407c21d AGDS: update scummvm
c453c89748 AGDS: new managed surface api
775629ae62 AGDS: add missing override
ab049d542e AGDS: just initialise with desired pixel format
db60595722 AGDS: replace stream pointers with refs
9d4add9a0c AGDS: use ScopedPtr everywhere
a9caa34479 AGDS: replace typedefs with using
efca2860d8 VIDEO: Add missing override keywords
a626fa98bc AGDS: Fix struct/class forward declaration mismatches
4c85210750 AGDS: Update license to GPLv3
56d8df154f AGDS: Disable engine by default
7e49e66454 JANITORIAL: Fix code formatting
70a94a7adb AGDS: mark nibiru as unsupported
86684398ce AGDS: fix nibiru initialisation
6c1195bdc3 AGDS: map v2 to v1 opcodes, fix v2 object loading
aa9b5e551b JANITORIAL: use pre-commit to format agds files
21067ffaa5 AGDS: add more v2 opcores
cf0ba514d9 AGDS: add IsBMP
12edcfbf9f AGDS: align load order with original engine
4f52bc970d AGDS: add missing detection.h file
f5266f60f5 AGDS: more stubs and general mapping from v2 to v1
944b06125e AGDS: add v2 loadTTF stub
57e4588cc7 AGDS: enough stubs to run NiBiRu intro
8b0b73414a AGDS: mark nibiru as unstable (it's possible to get to the start of the intro)
081c77cc60 AGDS: add all v2 stubs for intro
72612d5558 AGDS: remove tools
d03c032e04 AGDS: try removing namespace from metaengine
10a8a876dc AGDS: fix header guards
e6355a9b20 AGDS: support TTF fonts
4f70a87d64 AGDS: include plugins.h in metaengine.cpp
0ede9e7d0f AGDS: add credits.pl
a465cf6afd AGDS: correct engine.configure - only two games are known
4c9d89b311 AGDS: reorder module.mk to match skeleton
6cba76e056 AGDS: janitorial - remove AGDS prefix
Commit: ca1d031be4f89fb6268e973c05bc82046cec362a
https://github.com/scummvm/scummvm/commit/ca1d031be4f89fb6268e973c05bc82046cec362a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:44+01:00
Commit Message:
VIDEO: add Surface::getRect
Changed paths:
graphics/surface.cpp
graphics/surface.h
diff --git a/graphics/surface.cpp b/graphics/surface.cpp
index 540fa4dbf79..9908d3100c0 100644
--- a/graphics/surface.cpp
+++ b/graphics/surface.cpp
@@ -137,6 +137,10 @@ void Surface::drawEllipse(int x0, int y0, int x1, int y1, uint32 color, bool fil
error("Surface::drawEllipse: bytesPerPixel must be 1, 2, or 4, got %d", format.bytesPerPixel);
}
+Common::Rect Surface::getRect() const {
+ return Common::Rect(w, h);
+}
+
// see backends/graphics/atari/atari-surface.cpp
#ifndef ATARI
void Surface::create(int16 width, int16 height, const PixelFormat &f) {
diff --git a/graphics/surface.h b/graphics/surface.h
index 58d726d711e..0d9b32d47a7 100644
--- a/graphics/surface.h
+++ b/graphics/surface.h
@@ -100,6 +100,8 @@ public:
Surface() : w(0), h(0), pitch(0), pixels(0), format() {
}
+ Common::Rect getRect() const;
+
/**
* Return a pointer to the pixel data.
*
Commit: 9dd0e041d20e5302f7b9770bd51424a74dff8dd4
https://github.com/scummvm/scummvm/commit/9dd0e041d20e5302f7b9770bd51424a74dff8dd4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:44+01:00
Commit Message:
AGDS: added minimal engine and detection of black mirror
Changed paths:
A engines/agds/agds.cpp
A engines/agds/agds.h
A engines/agds/configure.engine
A engines/agds/detection.cpp
A engines/agds/detection_tables.h
A engines/agds/module.mk
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
new file mode 100644
index 00000000000..8d705bd7477
--- /dev/null
+++ b/engines/agds/agds.cpp
@@ -0,0 +1,40 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/agds.h"
+#include "common/error.h"
+
+namespace AGDS {
+
+AGDSEngine::AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
+ _gameDescription(gameDesc) {
+
+}
+
+AGDSEngine::~AGDSEngine() {
+}
+
+Common::Error AGDSEngine::run() {
+ return Common::kNoError;
+}
+
+} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
new file mode 100644
index 00000000000..e85c4389e26
--- /dev/null
+++ b/engines/agds/agds.h
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_AGDS_H
+#define AGDS_AGDS_H
+
+#include "common/scummsys.h"
+#include "engines/advancedDetector.h"
+
+/**
+ * This is the namespace of the AGDS engine.
+ *
+ * Status of this engine: In Progress
+ *
+ * Games using this engine:
+ * - Black Mirror (Windows)
+ */
+namespace AGDS {
+
+class AGDSEngine : public Engine {
+public:
+ AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc);
+ ~AGDSEngine();
+
+ Common::Error run();
+private:
+ const ADGameDescription *_gameDescription;
+};
+
+
+} // End of namespace AGDS
+
+#endif /* AGDS_AGDS_H */
diff --git a/engines/agds/configure.engine b/engines/agds/configure.engine
new file mode 100644
index 00000000000..f16d163e116
--- /dev/null
+++ b/engines/agds/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine agds "AGDS (Black Mirror and others)" yes
diff --git a/engines/agds/detection.cpp b/engines/agds/detection.cpp
new file mode 100644
index 00000000000..8abe49cd8c0
--- /dev/null
+++ b/engines/agds/detection.cpp
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/agds.h"
+
+#include "engines/advancedDetector.h"
+
+static const PlainGameDescriptor agdsGames[] = {
+ { "black-mirror", "Black Mirror" },
+ { 0, 0 }
+};
+
+#include "agds/detection_tables.h"
+
+class AGDSMetaEngine : public AdvancedMetaEngine {
+public:
+ AGDSMetaEngine() : AdvancedMetaEngine(AGDS::gameDescriptions, sizeof(ADGameDescription), agdsGames) {
+ _maxScanDepth = 3;
+ }
+
+ virtual const char *getName() const {
+ return "AGDS Engine";
+ }
+
+ virtual const char *getOriginalCopyright() const {
+ return "AGDS (C) Future Games";
+ }
+
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+};
+
+bool AGDSMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ if (desc) {
+ *engine = new AGDS::AGDSEngine(syst, desc);
+ }
+ return *engine;
+}
+
+#if PLUGIN_ENABLED_DYNAMIC(AGDS)
+ REGISTER_PLUGIN_DYNAMIC(AGDS, PLUGIN_TYPE_ENGINE, AGDSMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(AGDS, PLUGIN_TYPE_ENGINE, AGDSMetaEngine);
+#endif
diff --git a/engines/agds/detection_tables.h b/engines/agds/detection_tables.h
new file mode 100644
index 00000000000..3d3e0db2172
--- /dev/null
+++ b/engines/agds/detection_tables.h
@@ -0,0 +1,41 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+namespace AGDS {
+
+static const ADGameDescription gameDescriptions[] = {
+
+ // Black Mirror Windows
+ {
+ "black-mirror",
+ 0,
+ AD_ENTRY1s("gfx1.grp", "6665ce103cf12a362fd55f863d1ec9e6", 907820240),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_DROPPLATFORM,
+ GUIO1(GUIO_NONE)
+ },
+
+ AD_TABLE_END_MARKER
+};
+
+} // End of namespace AGDS
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
new file mode 100644
index 00000000000..bd0715e8379
--- /dev/null
+++ b/engines/agds/module.mk
@@ -0,0 +1,13 @@
+MODULE := engines/agds
+
+MODULE_OBJS := \
+ agds.o \
+ detection.o
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_AGDS), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
Commit: 4e6ee6b12ae9906acb1b509a2b215b17ca20e088
https://github.com/scummvm/scummvm/commit/4e6ee6b12ae9906acb1b509a2b215b17ca20e088
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:44+01:00
Commit Message:
AGDS: read config file, log path entries
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 8d705bd7477..488dbb73602 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -22,18 +22,42 @@
#include "agds/agds.h"
#include "common/error.h"
+#include "common/ini-file.h"
+#include "common/file.h"
+#include "common/debug.h"
namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
_gameDescription(gameDesc) {
-
}
AGDSEngine::~AGDSEngine() {
}
+bool AGDSEngine::load() {
+ Common::INIFile config;
+ Common::File configFile;
+ if (!configFile.open("agds.cfg"))
+ return false;
+
+ configFile.readLine(); //skip first line
+ config.setDefaultSectionName("core");
+ if (!config.loadFromStream(configFile))
+ return false;
+
+ Common::INIFile::SectionKeyList values = config.getKeys("core");
+ for(Common::INIFile::SectionKeyList::iterator i = values.begin(); i != values.end(); ++i) {
+ if (i->key == "path")
+ debug("found path %s", i->value.c_str());
+ }
+
+ return true;
+}
+
Common::Error AGDSEngine::run() {
+ if (!load())
+ return Common::kNoGameDataFoundError;
return Common::kNoError;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index e85c4389e26..3130054718b 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -42,6 +42,10 @@ public:
~AGDSEngine();
Common::Error run();
+
+private:
+ bool load();
+
private:
const ADGameDescription *_gameDescription;
};
Commit: 7d41c7ee03af9ab1c8d81e1c555c130d71deb408
https://github.com/scummvm/scummvm/commit/7d41c7ee03af9ab1c8d81e1c555c130d71deb408
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:44+01:00
Commit Message:
AGDS: added resource manager and grp file scanning
Changed paths:
A engines/agds/resourceManager.cpp
A engines/agds/resourceManager.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/module.mk
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 488dbb73602..b91accdad18 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -49,7 +49,8 @@ bool AGDSEngine::load() {
Common::INIFile::SectionKeyList values = config.getKeys("core");
for(Common::INIFile::SectionKeyList::iterator i = values.begin(); i != values.end(); ++i) {
if (i->key == "path")
- debug("found path %s", i->value.c_str());
+ if (!_resourceManager.addPath(i->value))
+ return false;
}
return true;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 3130054718b..d9e14f96869 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "engines/advancedDetector.h"
+#include "agds/resourceManager.h"
/**
* This is the namespace of the AGDS engine.
@@ -47,7 +48,8 @@ private:
bool load();
private:
- const ADGameDescription *_gameDescription;
+ const ADGameDescription * _gameDescription;
+ ResourceManager _resourceManager;
};
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index bd0715e8379..de81d0ce32a 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -2,7 +2,8 @@ MODULE := engines/agds
MODULE_OBJS := \
agds.o \
- detection.o
+ detection.o \
+ resourceManager.o
# This module can be built as a plugin
ifeq ($(ENABLE_AGDS), DYNAMIC_PLUGIN)
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
new file mode 100644
index 00000000000..699c6ce2273
--- /dev/null
+++ b/engines/agds/resourceManager.cpp
@@ -0,0 +1,126 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/resourceManager.h"
+#include "common/debug.h"
+#include "common/file.h"
+#include "common/memstream.h"
+#include "common/algorithm.h"
+
+namespace AGDS {
+ ResourceManager::ResourceManager()
+ { }
+
+ ResourceManager::~ResourceManager()
+ { }
+
+ template<typename T>
+ void ResourceManager::decrypt(T * data, unsigned size) {
+ static const char * kKey = "Vyvojovy tym AGDS varuje: Hackerovani skodi obchodu!";
+ const char *ptr = kKey;
+ while(size--) {
+ *data++ ^= 0xff ^ *ptr++;
+ if (*ptr == 0)
+ ptr = kKey;
+ }
+ }
+
+ bool ResourceManager::addPath(const Common::String &grpFilename) {
+ static const char * kSignature = "AGDS group file\x1a";
+ static const uint32 kMagic = 0x1a03c9e6;
+ static const uint32 kVersion1 = 44;
+ static const uint32 kVersion2 = 2;
+
+ debug("adding path %s", grpFilename.c_str());
+ Common::File grp;
+ if (!grp.open(grpFilename)) {
+ error("failing opening grp file %s", grpFilename.c_str());
+ return false;
+ }
+ uint8 header[0x2c];
+ if (grp.read(header, sizeof(header)) != sizeof(header))
+ return false;
+
+ decrypt(header, 0x10);
+ if (strncmp(reinterpret_cast<const char*>(header), kSignature, 0x10) != 0)
+ return false;
+
+ Common::MemoryReadStreamEndian reader(header + 0x10, sizeof(header) - 0x10, false);
+ uint32 version1 = reader.readUint32();
+ if (version1 != kVersion1) {
+ error("invalid version 1 (%d)", version1);
+ return false;
+ }
+
+ uint32 magic = reader.readUint32();
+ if (magic != kMagic) {
+ error("invalid magic (0x%08x)", magic);
+ return false;
+ }
+
+ uint32 version2 = reader.readUint32();
+ if (version2 != kVersion2) {
+ error("invalid version 2 (%d)", version2);
+ return false;
+ }
+
+ unsigned dirCount = reader.readUint32();
+ if (!reader.skip(3 * 4))
+ return false;
+
+ GrpFilePtr grpFile(new GrpFile(grpFilename));
+
+ debug("+%u files in index", dirCount);
+ while(dirCount--) {
+ uint8 dirData[0x31];
+ uint8 * dirDataEnd = dirData + sizeof(dirData);
+
+ if (grp.read(dirData, sizeof(dirData)) != sizeof(dirData)) {
+ error("short read, corrupted file");
+ return false;
+ }
+
+ uint8 *nameEnd = Common::find(dirData, dirDataEnd, 0);
+ if (nameEnd == dirDataEnd) {
+ error("corrupted entry at %d", (int)grp.pos() - 0x31);
+ continue;
+ }
+
+ unsigned nameLength = nameEnd - dirData;
+ decrypt(dirData, nameLength);
+ Common::String name(reinterpret_cast<char *>(dirData), nameLength);
+
+ Common::MemoryReadStreamEndian dirReader(dirData + 0x21, 8, false);
+
+ uint32 offset = dirReader.readSint32();
+ uint32 size = dirReader.readSint32();
+ //debug("\t\tfile %s %u %u", name.c_str(), offset, size);
+ ResourcePtr resource(new Resource(grpFile, offset, size));
+ _resources.setVal(name, resource);
+ }
+
+ debug("\t%u files in index", _resources.size());
+ return true;
+ }
+
+
+} // End of namespace AGDS
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
new file mode 100644
index 00000000000..4e8cf9fe5f7
--- /dev/null
+++ b/engines/agds/resourceManager.h
@@ -0,0 +1,72 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_RESOURCE_MANAGER_H
+#define AGDS_RESOURCE_MANAGER_H
+
+#include "common/scummsys.h"
+#include "common/str.h"
+#include "common/ptr.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+
+namespace AGDS {
+
+class ResourceManager {
+private:
+ struct GrpFile
+ {
+ Common::String filename;
+
+ GrpFile(const Common::String &fname): filename(fname) {
+ }
+ };
+ typedef Common::SharedPtr<GrpFile> GrpFilePtr;
+
+ struct Resource
+ {
+ GrpFilePtr grp;
+ uint32 offset;
+ uint32 size;
+ Resource(const GrpFilePtr &g, uint32 o, uint32 s):
+ grp(g), offset(o), size(s) {
+ }
+ };
+ typedef Common::SharedPtr<Resource> ResourcePtr;
+
+ typedef Common::HashMap<Common::String, ResourcePtr> ResourcesType;
+ ResourcesType _resources;
+
+ template<typename T>
+ static void decrypt(T * data, unsigned size);
+
+public:
+ ResourceManager();
+ ~ResourceManager();
+
+ bool addPath(const Common::String &grpFilename);
+};
+
+
+} // End of namespace AGDS
+
+#endif /* AGDS_RESOURCE_MANAGER_H */
Commit: c99f585dff6ee6d9ed7f29a987cc3997728c2b01
https://github.com/scummvm/scummvm/commit/c99f585dff6ee6d9ed7f29a987cc3997728c2b01
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:44+01:00
Commit Message:
AGDS: Implemented ResourceManager::getResource
Changed paths:
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 699c6ce2273..073e921c881 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -25,6 +25,7 @@
#include "common/file.h"
#include "common/memstream.h"
#include "common/algorithm.h"
+#include "common/ptr.h"
namespace AGDS {
ResourceManager::ResourceManager()
@@ -122,5 +123,27 @@ namespace AGDS {
return true;
}
+ Common::SeekableReadStream * ResourceManager::getResource(const Common::String &name) const
+ {
+ ResourcesType::const_iterator i = _resources.find(name);
+ if (i == _resources.end()) {
+ error("no resource %s could be found", name.c_str());
+ return NULL;
+ }
+
+ const ResourcePtr & resource = i->_value;
+ assert(resource);
+
+ const Common::String & filename = resource->grp->filename;
+ Common::File grp;
+ if (!grp.open(filename)) {
+ error("could not open group file %s", filename.c_str());
+ return NULL;
+ }
+
+ grp.seek(resource->offset);
+ return grp.readStream(resource->size);
+ }
+
} // End of namespace AGDS
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 4e8cf9fe5f7..9f85a50ffa9 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/str.h"
+#include "common/stream.h"
#include "common/ptr.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
@@ -48,7 +49,7 @@ private:
uint32 offset;
uint32 size;
Resource(const GrpFilePtr &g, uint32 o, uint32 s):
- grp(g), offset(o), size(s) {
+ grp(g), offset(o), size(s) {
}
};
typedef Common::SharedPtr<Resource> ResourcePtr;
@@ -64,6 +65,8 @@ public:
~ResourceManager();
bool addPath(const Common::String &grpFilename);
+
+ Common::SeekableReadStream * getResource(const Common::String &name) const;
};
Commit: aa3ece6cb4a9f02e3f607d92dc13205482a1af93
https://github.com/scummvm/scummvm/commit/aa3ece6cb4a9f02e3f607d92dc13205482a1af93
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:44+01:00
Commit Message:
AGDS: changed decrypt signature and scope, allowing external usage
Changed paths:
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 073e921c881..d19843f3957 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -34,8 +34,7 @@ namespace AGDS {
ResourceManager::~ResourceManager()
{ }
- template<typename T>
- void ResourceManager::decrypt(T * data, unsigned size) {
+ void ResourceManager::decrypt(uint8 * data, unsigned size) {
static const char * kKey = "Vyvojovy tym AGDS varuje: Hackerovani skodi obchodu!";
const char *ptr = kKey;
while(size--) {
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 9f85a50ffa9..7c08f1e4594 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -57,13 +57,12 @@ private:
typedef Common::HashMap<Common::String, ResourcePtr> ResourcesType;
ResourcesType _resources;
- template<typename T>
- static void decrypt(T * data, unsigned size);
-
public:
ResourceManager();
~ResourceManager();
+ static void decrypt(uint8 * data, unsigned size);
+
bool addPath(const Common::String &grpFilename);
Common::SeekableReadStream * getResource(const Common::String &name) const;
Commit: d75dff1104009cf2a03d3c2e42a3ccd00f5ac97c
https://github.com/scummvm/scummvm/commit/d75dff1104009cf2a03d3c2e42a3ccd00f5ac97c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:44+01:00
Commit Message:
AGDS: implemented adb file scanning/loading
Changed paths:
A engines/agds/database.cpp
A engines/agds/database.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/module.mk
engines/agds/resourceManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index b91accdad18..85c694d36cf 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -52,6 +52,10 @@ bool AGDSEngine::load() {
if (!_resourceManager.addPath(i->value))
return false;
}
+ if (!_data.open("data.adb"))
+ return false;
+
+ _patch.open("patch.adb"); //it's ok
return true;
}
@@ -59,6 +63,12 @@ bool AGDSEngine::load() {
Common::Error AGDSEngine::run() {
if (!load())
return Common::kNoGameDataFoundError;
+
+ Common::SeekableReadStream * main = _data.getEntry("main");
+ debug("loaded main: %p\n", static_cast<void *>(main));
+ if (!main)
+ return Common::kNoGameDataFoundError;
+
return Common::kNoError;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index d9e14f96869..017d54c4581 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "engines/advancedDetector.h"
#include "agds/resourceManager.h"
+#include "agds/database.h"
/**
* This is the namespace of the AGDS engine.
@@ -50,6 +51,7 @@ private:
private:
const ADGameDescription * _gameDescription;
ResourceManager _resourceManager;
+ Database _data, _patch; //data and patch databases
};
diff --git a/engines/agds/database.cpp b/engines/agds/database.cpp
new file mode 100644
index 00000000000..867eb501933
--- /dev/null
+++ b/engines/agds/database.cpp
@@ -0,0 +1,83 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/database.h"
+#include "common/debug.h"
+#include "common/file.h"
+#include "common/algorithm.h"
+
+namespace AGDS {
+
+ bool Database::open(const Common::String& filename) {
+ static const uint32 kMagic = 666;
+
+ _filename = filename;
+ Common::File file;
+ if (!file.open(filename))
+ return false;
+ uint32 magic = file.readUint32LE();
+ if (magic != kMagic) {
+ debug("invalid magic for database %s", filename.c_str());
+ return false;
+ }
+ _writeable = file.readUint32LE();
+ _totalEntries = file.readUint32LE();
+ _usedEntries = file.readUint32LE();
+ _maxNameSize = file.readUint32LE();
+ if (_maxNameSize == 0) {
+ debug("invalid max name record size");
+ return false;
+ }
+
+ static const uint32 kHeaderFieldSize = 9;
+
+ uint32 dataOffset = (_maxNameSize + kHeaderFieldSize) * _totalEntries;
+ Common::Array<char> nameBuffer(_maxNameSize + 1);
+ for(uint32 i = 0; i < _usedEntries; ++i) {
+ uint32 offset = file.readUint32LE();
+ file.read(nameBuffer.data(), nameBuffer.size());
+ char *z = Common::find(nameBuffer.begin(), nameBuffer.end(), 0);
+ Common::String name(nameBuffer.data(), z - nameBuffer.begin());
+ uint32 size = file.readUint32LE();
+ //debug("adb entry: %s, offset %08x, size: %u", name.c_str(), offset, size);
+ _entries.setVal(name, Entry(dataOffset + offset, size));
+ }
+
+ return true;
+ }
+
+ Common::SeekableReadStream * Database::getEntry(const Common::String &name) const
+ {
+ EntriesType::const_iterator i = _entries.find(name);
+ if (i == _entries.end())
+ return NULL;
+
+ Common::File file;
+ if (!file.open(_filename)) {
+ error("could not open database file %s", _filename.c_str()); //previously available, but now disappeared or no fd, error
+ return NULL;
+ }
+ const Entry &entry = i->_value;
+ file.seek(entry.offset);
+ return file.readStream(entry.size);
+ }
+}
diff --git a/engines/agds/database.h b/engines/agds/database.h
new file mode 100644
index 00000000000..dc694954edf
--- /dev/null
+++ b/engines/agds/database.h
@@ -0,0 +1,63 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_DATABASE_H
+#define AGDS_DATABASE_H
+
+#include "common/scummsys.h"
+#include "common/str.h"
+#include "common/stream.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+
+namespace AGDS {
+
+class Database {
+private:
+ struct Entry
+ {
+ uint32 offset;
+ uint32 size;
+
+ Entry(): offset(), size() { }
+ Entry(uint32 o, uint32 s): offset(o), size(s) { }
+ };
+
+ typedef Common::HashMap<Common::String, Entry> EntriesType;
+
+ Common::String _filename;
+ bool _writeable;
+ uint32 _totalEntries;
+ uint32 _usedEntries;
+ uint32 _maxNameSize;
+
+ EntriesType _entries;
+
+public:
+ bool open(const Common::String &filename);
+ Common::SeekableReadStream * getEntry(const Common::String &name) const;
+};
+
+
+} // End of namespace AGDS
+
+#endif /* AGDS_RESOURCE_MANAGER_H */
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index de81d0ce32a..96ad1c4187a 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/agds
MODULE_OBJS := \
agds.o \
+ database.o \
detection.o \
resourceManager.o
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 7c08f1e4594..ab057a58749 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -34,6 +34,8 @@ namespace AGDS {
class ResourceManager {
private:
+
+ //fixme: port to Archive
struct GrpFile
{
Common::String filename;
Commit: ded41b2b3ad293ce817b80ed2e56060eb143022f
https://github.com/scummvm/scummvm/commit/ded41b2b3ad293ce817b80ed2e56060eb143022f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:44+01:00
Commit Message:
AGDS: fixed include guard
Changed paths:
engines/agds/database.h
diff --git a/engines/agds/database.h b/engines/agds/database.h
index dc694954edf..24582b1cd27 100644
--- a/engines/agds/database.h
+++ b/engines/agds/database.h
@@ -60,4 +60,4 @@ public:
} // End of namespace AGDS
-#endif /* AGDS_RESOURCE_MANAGER_H */
+#endif /* AGDS_DATABASE_H */
Commit: e424791da812a5a8289587f6311c680b2b64285b
https://github.com/scummvm/scummvm/commit/e424791da812a5a8289587f6311c680b2b64285b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:45+01:00
Commit Message:
AGDS: fixed data offset in database
Changed paths:
engines/agds/database.cpp
diff --git a/engines/agds/database.cpp b/engines/agds/database.cpp
index 867eb501933..02ad3ad04be 100644
--- a/engines/agds/database.cpp
+++ b/engines/agds/database.cpp
@@ -48,9 +48,10 @@ namespace AGDS {
return false;
}
- static const uint32 kHeaderFieldSize = 9;
+ static const uint32 kHeaderFieldSize = 0x09;
+ static const uint32 kHeaderSize = 0x14;
- uint32 dataOffset = (_maxNameSize + kHeaderFieldSize) * _totalEntries;
+ uint32 dataOffset = kHeaderSize + (_maxNameSize + kHeaderFieldSize) * _totalEntries;
Common::Array<char> nameBuffer(_maxNameSize + 1);
for(uint32 i = 0; i < _usedEntries; ++i) {
uint32 offset = file.readUint32LE();
Commit: 54677250a575f2c266847d411b72532ea64204ff
https://github.com/scummvm/scummvm/commit/54677250a575f2c266847d411b72532ea64204ff
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:45+01:00
Commit Message:
AGDS: added object code loading and simple process execution loop
Changed paths:
A engines/agds/object.cpp
A engines/agds/object.h
A engines/agds/process.cpp
A engines/agds/process.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/module.mk
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 85c694d36cf..e79fa570210 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -21,6 +21,8 @@
*/
#include "agds/agds.h"
+#include "agds/object.h"
+#include "agds/process.h"
#include "common/error.h"
#include "common/ini-file.h"
#include "common/file.h"
@@ -56,18 +58,35 @@ bool AGDSEngine::load() {
return false;
_patch.open("patch.adb"); //it's ok
-
+ _nextScreen = "main";
+
return true;
}
+void AGDSEngine::loadObject(Common::String & name) {
+ debug("loading object %s", name.c_str());
+ Common::SeekableReadStream * stream = _data.getEntry(name);
+ if (!stream)
+ error("no database entry for %s\n", name.c_str());
+ ObjectsType::iterator i = _objects.find(name);
+ Object *object = i != _objects.end()? i->_value: NULL;
+ if (!object)
+ _objects.setVal(name, object = new Object(stream));
+
+ _processes.push_back(Process(object));
+ _processes.back().execute();
+}
+
Common::Error AGDSEngine::run() {
if (!load())
return Common::kNoGameDataFoundError;
-
- Common::SeekableReadStream * main = _data.getEntry("main");
- debug("loaded main: %p\n", static_cast<void *>(main));
- if (!main)
- return Common::kNoGameDataFoundError;
+ if (!_nextScreen.empty()) {
+ debug("loading screen %s", _nextScreen.c_str());
+ Common::String nextScreen;
+ nextScreen = _nextScreen;
+ _nextScreen.clear();
+ loadObject(nextScreen);
+ }
return Common::kNoError;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 017d54c4581..e494b493556 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -24,6 +24,7 @@
#define AGDS_AGDS_H
#include "common/scummsys.h"
+#include "common/hashmap.h"
#include "engines/advancedDetector.h"
#include "agds/resourceManager.h"
#include "agds/database.h"
@@ -38,6 +39,9 @@
*/
namespace AGDS {
+class Object;
+class Process;
+
class AGDSEngine : public Engine {
public:
AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc);
@@ -47,11 +51,18 @@ public:
private:
bool load();
+ void loadObject(Common::String & name);
private:
+ typedef Common::HashMap<Common::String, Object *> ObjectsType;
+ typedef Common::List<Process> ProcessListType;
+
const ADGameDescription * _gameDescription;
ResourceManager _resourceManager;
Database _data, _patch; //data and patch databases
+ ObjectsType _objects;
+ ProcessListType _processes;
+ Common::String _nextScreen;
};
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index 96ad1c4187a..14e54d98507 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -4,6 +4,8 @@ MODULE_OBJS := \
agds.o \
database.o \
detection.o \
+ object.o \
+ process.o \
resourceManager.o
# This module can be built as a plugin
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
new file mode 100644
index 00000000000..972b379c728
--- /dev/null
+++ b/engines/agds/object.cpp
@@ -0,0 +1,44 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/object.h"
+#include "common/debug.h"
+
+namespace AGDS {
+
+Object::Object(Common::SeekableReadStream * stream) {
+ stream->skip(2);
+ uint16 dataSize = stream->readUint16LE();
+ if (dataSize != 0)
+ error("implement me: object with data (%u)", dataSize);
+ uint16 codeSize = stream->readUint16LE();
+ uint8 flags = stream->readByte();
+ if (flags != 1)
+ error("implement me: no flags handling yet");
+
+ debug("object code size %u", codeSize);
+ _code.resize(codeSize);
+ stream->read(_code.data(), _code.size());
+ delete stream;
+}
+
+}
diff --git a/engines/agds/object.h b/engines/agds/object.h
new file mode 100644
index 00000000000..593c17daed3
--- /dev/null
+++ b/engines/agds/object.h
@@ -0,0 +1,50 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_OBJECT_H
+#define AGDS_OBJECT_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/stream.h"
+
+namespace AGDS {
+
+class Object {
+public:
+ typedef Common::Array<uint8> CodeType;
+
+private:
+ CodeType _code;
+
+public:
+ Object(Common::SeekableReadStream * stream);
+
+ const CodeType & getCode() const {
+ return _code;
+ }
+};
+
+
+} // End of namespace AGDS
+
+#endif /* AGDS_OBJECT_H */
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
new file mode 100644
index 00000000000..a473e67a72e
--- /dev/null
+++ b/engines/agds/process.cpp
@@ -0,0 +1,43 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/process.h"
+#include "common/debug.h"
+
+namespace AGDS {
+
+Process::Process(Object* object) : _object(object), _ip(0), _failed(false) { }
+
+void Process::execute() {
+ const Object::CodeType &code = _object->getCode();
+ while(!_failed && _ip < code.size()) {
+ uint8 op = next();
+ switch(op) {
+ default:
+ debug("%08x: unknown opcode %02x", _ip - 1, (unsigned)op);
+ _failed = true;
+ break;
+ }
+ }
+}
+
+}
diff --git a/engines/agds/process.h b/engines/agds/process.h
new file mode 100644
index 00000000000..a46b3bc0af6
--- /dev/null
+++ b/engines/agds/process.h
@@ -0,0 +1,61 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_PROCESS_H
+#define AGDS_PROCESS_H
+
+#include "agds/object.h"
+#include "common/scummsys.h"
+#include "common/stack.h"
+
+namespace AGDS {
+
+class Process {
+private:
+ typedef Common::Stack<uint32> StackType;
+
+ Object * _object;
+ StackType _stack;
+ unsigned _ip;
+ bool _failed; //fixme: add status
+
+private:
+ uint8 next() {
+ const Object::CodeType & code = _object->getCode();
+ if (_ip < code.size()) {
+ return code[_ip++];
+ } else {
+ _failed = true;
+ return 0;
+ }
+ }
+
+public:
+ Process(Object *object);
+
+ void execute();
+};
+
+
+} // End of namespace AGDS
+
+#endif /* AGDS_PROCESS_H */
Commit: 90cfa82602e3a8d22528c1e0a77217f4c8bdeb98
https://github.com/scummvm/scummvm/commit/90cfa82602e3a8d22528c1e0a77217f4c8bdeb98
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:45+01:00
Commit Message:
AGDS: implemented first few opcodes
Changed paths:
A engines/agds/process_opcodes.cpp
engines/agds/module.mk
engines/agds/process.cpp
engines/agds/process.h
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index 14e54d98507..cd0f95ee11f 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS := \
detection.o \
object.o \
process.o \
+ process_opcodes.o \
resourceManager.o
# This module can be built as a plugin
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index a473e67a72e..0d687e20784 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -25,15 +25,54 @@
namespace AGDS {
+enum Opcode {
+ kEnter = 5,
+ kPushImm8 = 18,
+ kOp142 = 142,
+ kLoadPicture = 198,
+ kMax = 248
+};
+
+
+//fixme: add trace here
+#define OP(NAME, METHOD) \
+ case NAME: METHOD (); break
+
+#define OP_C(NAME, METHOD) \
+ case NAME: { int8 arg = next(); METHOD (arg); } break
+
+#define OP_B(NAME, METHOD) \
+ case NAME: { uint8 arg = next(); METHOD (arg); } break
+
+#define OP_U(NAME, METHOD) \
+ case NAME: { uint16 arg = next16(); METHOD (arg); } break
+
+#define OP_UU(NAME, METHOD) \
+ case NAME: { uint16 arg1 = next16(); uint16 arg2 = next16(); METHOD (arg1, arg2); } break
+
Process::Process(Object* object) : _object(object), _ip(0), _failed(false) { }
+void Process::push(int32 value) {
+ _stack.push(value);
+}
+
+int32 Process::pop() {
+ if (_stack.empty())
+ error("stack underflow, ip: %08x", _ip);
+ return _stack.pop();
+}
+
void Process::execute() {
const Object::CodeType &code = _object->getCode();
while(!_failed && _ip < code.size()) {
uint8 op = next();
switch(op) {
+ OP_UU (kEnter, enter);
+ OP_C (kPushImm8, push);
+ OP (kLoadPicture, loadPicture);
+ OP (kOp142, stub142);
default:
- debug("%08x: unknown opcode %02x", _ip - 1, (unsigned)op);
+ debug("%08x: unknown opcode 0x%02x (%u)", _ip - 1, (unsigned)op, (unsigned)op);
_failed = true;
break;
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index a46b3bc0af6..fff31b853c5 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -31,7 +31,7 @@ namespace AGDS {
class Process {
private:
- typedef Common::Stack<uint32> StackType;
+ typedef Common::Stack<int32> StackType;
Object * _object;
StackType _stack;
@@ -49,6 +49,19 @@ private:
}
}
+ uint16 next16() {
+ uint8 l = next();
+ uint16 h = next();
+ return (h << 8) | l;
+ }
+
+ void push(int32 value);
+ int32 pop();
+
+ void enter(int16 dead, int16 jump);
+ void stub142();
+ void loadPicture();
+
public:
Process(Object *object);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
new file mode 100644
index 00000000000..396457e47e3
--- /dev/null
+++ b/engines/agds/process_opcodes.cpp
@@ -0,0 +1,44 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/process.h"
+#include "common/debug.h"
+
+namespace AGDS {
+
+void Process::enter(int16 dead, int16 jump) {
+ _ip += jump;
+}
+
+void Process::stub142() {
+ int arg1 = pop();
+ int arg2 = pop();
+ debug("stub142: %d, %d", arg1, arg2);
+}
+
+void Process::loadPicture() {
+ int32 id = pop();
+ debug("loadPicture stub %d", id);
+ push(100500); //dummy
+}
+
+}
Commit: 2a6248bdae247545053c039def1f83d6ed210241
https://github.com/scummvm/scummvm/commit/2a6248bdae247545053c039def1f83d6ed210241
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:45+01:00
Commit Message:
AGDS: added resource table parsing
Changed paths:
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.h b/engines/agds/process.h
index fff31b853c5..1eacc4b25cd 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -58,7 +58,7 @@ private:
void push(int32 value);
int32 pop();
- void enter(int16 dead, int16 jump);
+ void enter(uint16 magic, uint16 size);
void stub142();
void loadPicture();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 396457e47e3..3c5e0ebc844 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -22,11 +22,45 @@
#include "agds/process.h"
#include "common/debug.h"
+#include "common/memstream.h"
namespace AGDS {
-void Process::enter(int16 dead, int16 jump) {
- _ip += jump;
+void Process::enter(uint16 magic, uint16 size) {
+ if (magic != 0xdead || size != 0x0c)
+ error("invalid enter() magic: 0x%04x or size: %u", magic, size);
+ uint16 unk1 = next16();
+ uint16 unk2 = next16();
+ uint16 unk3 = next16();
+ unsigned resOffset = next16();
+ uint16 resCount = next16();
+ uint16 unk4 = next16();
+
+ debug("resource block %04x %04x %04x %04x, resources table with %u entries", unk1, unk2, unk3, unk4, resCount);
+
+ const Object::CodeType &code = _object->getCode();
+ resOffset += 5 /*instruction*/ + 0x11 /*another header*/;
+ if (resOffset >= code.size())
+ error("invalid resource table offset");
+
+ debug("resource table at %08x", resOffset);
+ Common::MemoryReadStream stream(code.data() + resOffset, code.size() - resOffset);
+ for(uint16 i = 0; i < resCount; ++i) {
+ uint16 offset = stream.readUint16LE();
+ uint16 flags = stream.readUint16LE();
+
+ unsigned nameOffset = resOffset + offset;
+ if (nameOffset > code.size())
+ error("invalid resource name offset");
+
+ const char * nameBegin = reinterpret_cast<const char *>(code.data() + nameOffset);
+ const char * codeEnd = reinterpret_cast<const char *>(code.data() + code.size());
+ const char * nameEnd = Common::find(nameBegin, codeEnd, 0);
+
+ Common::String name(nameBegin, nameEnd - nameBegin);
+
+ debug("resource table 1[%04u]: 0x%04x %s", i, flags, name.c_str());
+ }
}
void Process::stub142() {
Commit: 353ad3b35dcbd7df99be90027288b17152b7b3e2
https://github.com/scummvm/scummvm/commit/353ad3b35dcbd7df99be90027288b17152b7b3e2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:45+01:00
Commit Message:
AGDS: added pop instruction
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 0d687e20784..9a47676d6b7 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -27,6 +27,7 @@ namespace AGDS {
enum Opcode {
kEnter = 5,
+ kPop = 10,
kPushImm8 = 18,
kOp142 = 142,
kLoadPicture = 198,
@@ -68,6 +69,7 @@ void Process::execute() {
uint8 op = next();
switch(op) {
OP_UU (kEnter, enter);
+ OP (kPop, pop);
OP_C (kPushImm8, push);
OP (kLoadPicture, loadPicture);
OP (kOp142, stub142);
Commit: 122bf85e0301fcaf196d6907364fc887d7e264a1
https://github.com/scummvm/scummvm/commit/122bf85e0301fcaf196d6907364fc887d7e264a1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:45+01:00
Commit Message:
AGDS: moved resource string table initialisation to object, made it lazy
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 972b379c728..48fba3cfc25 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -22,10 +22,11 @@
#include "agds/object.h"
#include "common/debug.h"
+#include "common/memstream.h"
namespace AGDS {
-Object::Object(Common::SeekableReadStream * stream) {
+Object::Object(Common::SeekableReadStream * stream) : _stringTableLoaded(false) {
stream->skip(2);
uint16 dataSize = stream->readUint16LE();
if (dataSize != 0)
@@ -41,4 +42,45 @@ Object::Object(Common::SeekableReadStream * stream) {
delete stream;
}
+void Object::readStringTable(unsigned resOffset, uint16 resCount) {
+ if (_stringTableLoaded)
+ return;
+
+ resOffset += 5 /*instruction*/ + 0x11 /*another header*/;
+ if (resOffset >= _code.size())
+ error("invalid resource table offset");
+
+ debug("resource table at %08x", resOffset);
+ Common::MemoryReadStream stream(_code.data() + resOffset, _code.size() - resOffset);
+ for(uint16 i = 0; i < resCount; ++i) {
+ uint16 offset = stream.readUint16LE();
+ uint16 flags = stream.readUint16LE();
+
+ unsigned nameOffset = resOffset + offset;
+ if (nameOffset > _code.size())
+ error("invalid resource name offset");
+
+ const char * nameBegin = reinterpret_cast<const char *>(_code.data() + nameOffset);
+ const char * codeEnd = reinterpret_cast<const char *>(_code.data() + _code.size());
+ const char * nameEnd = Common::find(nameBegin, codeEnd, 0);
+
+ Common::String name(nameBegin, nameEnd - nameBegin);
+
+ debug("resource table 1[%04u]: 0x%04x %s", i, flags, name.c_str());
+ _stringTable[i] = StringEntry(name, flags);
+ }
+ _stringTableLoaded = true;
+}
+
+const Object::StringEntry & Object::getString(uint16 index) const {
+ if (!_stringTableLoaded)
+ error("no string table loaded");
+
+ StringTableType::const_iterator i = _stringTable.find(index);
+ if (i == _stringTable.end())
+ error("no resource name with id %u", index);
+
+ return i->_value;
+}
+
}
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 593c17daed3..27220c6f5bc 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/array.h"
#include "common/stream.h"
+#include "common/hashmap.h"
namespace AGDS {
@@ -33,12 +34,29 @@ class Object {
public:
typedef Common::Array<uint8> CodeType;
+ struct StringEntry
+ {
+ Common::String string;
+ uint16 flags;
+
+ StringEntry(): string(), flags() { }
+ StringEntry(const Common::String &s, uint16 f): string(s), flags(f) { }
+ };
+
private:
- CodeType _code;
+ typedef Common::HashMap<uint16, StringEntry, Common::Hash<uint16> > StringTableType;
+
+ CodeType _code;
+ StringTableType _stringTable;
+ bool _stringTableLoaded;
+
public:
Object(Common::SeekableReadStream * stream);
+ void readStringTable(unsigned resOffset, uint16 resCount);
+ const StringEntry & getString(uint16 index) const;
+
const CodeType & getCode() const {
return _code;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3c5e0ebc844..497439c5c50 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -22,7 +22,6 @@
#include "agds/process.h"
#include "common/debug.h"
-#include "common/memstream.h"
namespace AGDS {
@@ -35,27 +34,11 @@ void Process::enter(uint16 magic, uint16 size) {
unsigned resOffset = next16();
uint16 resCount = next16();
uint16 unk4 = next16();
+ debug("resource block %04x %04x %04x %04x,"
+ " resources table with %u entries", unk1, unk2, unk3, unk4, resCount);
- debug("resource block %04x %04x %04x %04x, resources table with %u entries", unk1, unk2, unk3, unk4, resCount);
-
- const Object::CodeType &code = _object->getCode();
- resOffset += 5 /*instruction*/ + 0x11 /*another header*/;
- if (resOffset >= code.size())
- error("invalid resource table offset");
-
- debug("resource table at %08x", resOffset);
- Common::MemoryReadStream stream(code.data() + resOffset, code.size() - resOffset);
- for(uint16 i = 0; i < resCount; ++i) {
- uint16 offset = stream.readUint16LE();
- uint16 flags = stream.readUint16LE();
-
- unsigned nameOffset = resOffset + offset;
- if (nameOffset > code.size())
- error("invalid resource name offset");
-
- const char * nameBegin = reinterpret_cast<const char *>(code.data() + nameOffset);
- const char * codeEnd = reinterpret_cast<const char *>(code.data() + code.size());
- const char * nameEnd = Common::find(nameBegin, codeEnd, 0);
+ _object->readStringTable(resOffset, resCount);
+}
Common::String name(nameBegin, nameEnd - nameBegin);
Commit: 85c03f9e83707d82e113baa13a2553d068899102
https://github.com/scummvm/scummvm/commit/85c03f9e83707d82e113baa13a2553d068899102
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:45+01:00
Commit Message:
AGDS: implemented setSpecialVariable stub
Changed paths:
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 9a47676d6b7..9b9d1e2c79f 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -29,7 +29,9 @@ enum Opcode {
kEnter = 5,
kPop = 10,
kPushImm8 = 18,
- kOp142 = 142,
+ kSetSpecialVariable = 142,
+ kGetRegionWidth = 146,
+ kGetRegionHeight = 147,
kLoadPicture = 198,
kMax = 248
};
@@ -72,7 +74,7 @@ void Process::execute() {
OP (kPop, pop);
OP_C (kPushImm8, push);
OP (kLoadPicture, loadPicture);
- OP (kOp142, stub142);
+ OP (kSetSpecialVariable, setSpecialVariable);
default:
debug("%08x: unknown opcode 0x%02x (%u)", _ip - 1, (unsigned)op, (unsigned)op);
_failed = true;
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 1eacc4b25cd..4ea8bb30bd8 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -59,7 +59,7 @@ private:
int32 pop();
void enter(uint16 magic, uint16 size);
- void stub142();
+ void setSpecialVariable();
void loadPicture();
public:
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 497439c5c50..4c58c5d2266 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -40,18 +40,19 @@ void Process::enter(uint16 magic, uint16 size) {
_object->readStringTable(resOffset, resCount);
}
- Common::String name(nameBegin, nameEnd - nameBegin);
-
- debug("resource table 1[%04u]: 0x%04x %s", i, flags, name.c_str());
+void Process::setSpecialVariable() {
+ int16 valueIndex = pop();
+ int16 nameIndex = pop();
+
+ const Object::StringEntry &name = _object->getString(nameIndex);
+ if (valueIndex != -1) {
+ const Object::StringEntry &value = _object->getString(valueIndex);
+ debug("setSpecialVariable: %s[%d] to %s[%d]", name.string.c_str(), nameIndex, value.string.c_str(), valueIndex);
+ } else {
+ debug("resetSpecialVariable: %s[%d]", name.string.c_str(), nameIndex);
}
}
-void Process::stub142() {
- int arg1 = pop();
- int arg2 = pop();
- debug("stub142: %d, %d", arg1, arg2);
-}
-
void Process::loadPicture() {
int32 id = pop();
debug("loadPicture stub %d", id);
Commit: 7c539a21c006d08d3195e169699621f483cd2799
https://github.com/scummvm/scummvm/commit/7c539a21c006d08d3195e169699621f483cd2799
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:45+01:00
Commit Message:
AGDS: renamed special to system
Changed paths:
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 9b9d1e2c79f..6ecfd6d68f9 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -29,7 +29,7 @@ enum Opcode {
kEnter = 5,
kPop = 10,
kPushImm8 = 18,
- kSetSpecialVariable = 142,
+ kSetSystemVariable = 142,
kGetRegionWidth = 146,
kGetRegionHeight = 147,
kLoadPicture = 198,
@@ -74,7 +74,7 @@ void Process::execute() {
OP (kPop, pop);
OP_C (kPushImm8, push);
OP (kLoadPicture, loadPicture);
- OP (kSetSpecialVariable, setSpecialVariable);
+ OP (kSetSystemVariable, setSystemVariable);
default:
debug("%08x: unknown opcode 0x%02x (%u)", _ip - 1, (unsigned)op, (unsigned)op);
_failed = true;
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 4ea8bb30bd8..4c1065f67f7 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -59,7 +59,7 @@ private:
int32 pop();
void enter(uint16 magic, uint16 size);
- void setSpecialVariable();
+ void setSystemVariable();
void loadPicture();
public:
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4c58c5d2266..b8c600b3be0 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -40,16 +40,16 @@ void Process::enter(uint16 magic, uint16 size) {
_object->readStringTable(resOffset, resCount);
}
-void Process::setSpecialVariable() {
+void Process::setSystemVariable() {
int16 valueIndex = pop();
int16 nameIndex = pop();
const Object::StringEntry &name = _object->getString(nameIndex);
if (valueIndex != -1) {
const Object::StringEntry &value = _object->getString(valueIndex);
- debug("setSpecialVariable: %s[%d] to %s[%d]", name.string.c_str(), nameIndex, value.string.c_str(), valueIndex);
+ debug("setSystemVariable: %s[%d] to %s[%d]", name.string.c_str(), nameIndex, value.string.c_str(), valueIndex);
} else {
- debug("resetSpecialVariable: %s[%d]", name.string.c_str(), nameIndex);
+ debug("resetSystemVariable: %s[%d]", name.string.c_str(), nameIndex);
}
}
Commit: 070c2b0eeb3cb832b2ddd2105337c37f858cf5b7
https://github.com/scummvm/scummvm/commit/070c2b0eeb3cb832b2ddd2105337c37f858cf5b7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:45+01:00
Commit Message:
AGDS: introduced popString()
Changed paths:
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 6ecfd6d68f9..01941ef9243 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -53,7 +53,9 @@ enum Opcode {
#define OP_UU(NAME, METHOD) \
case NAME: { uint16 arg1 = next16(); uint16 arg2 = next16(); METHOD (arg1, arg2); } break
-Process::Process(Object* object) : _object(object), _ip(0), _failed(false) { }
+Process::Process(Object* object) :
+ _object(object), _ip(0), _failed(false) {
+}
void Process::push(int32 value) {
_stack.push(value);
@@ -65,6 +67,10 @@ int32 Process::pop() {
return _stack.pop();
}
+const Object::StringEntry & Process::popString() {
+ return _object->getString(pop());
+}
+
void Process::execute() {
const Object::CodeType &code = _object->getCode();
while(!_failed && _ip < code.size()) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 4c1065f67f7..4b5db2101ae 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -57,6 +57,7 @@ private:
void push(int32 value);
int32 pop();
+ const Object::StringEntry & popString();
void enter(uint16 magic, uint16 size);
void setSystemVariable();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b8c600b3be0..d80c8fe20fe 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -42,20 +42,19 @@ void Process::enter(uint16 magic, uint16 size) {
void Process::setSystemVariable() {
int16 valueIndex = pop();
- int16 nameIndex = pop();
+ const Object::StringEntry &name = popString();
- const Object::StringEntry &name = _object->getString(nameIndex);
if (valueIndex != -1) {
const Object::StringEntry &value = _object->getString(valueIndex);
- debug("setSystemVariable: %s[%d] to %s[%d]", name.string.c_str(), nameIndex, value.string.c_str(), valueIndex);
+ debug("setSystemVariable %s to %s", name.string.c_str(), value.string.c_str());
} else {
- debug("resetSystemVariable: %s[%d]", name.string.c_str(), nameIndex);
+ debug("resetSystemVariable %s", name.string.c_str());
}
}
void Process::loadPicture() {
- int32 id = pop();
- debug("loadPicture stub %d", id);
+ const Object::StringEntry &name = popString();
+ debug("loadPicture stub %s", name.string.c_str());
push(100500); //dummy
}
Commit: aeb5012b1d6188a6d5077bbcbf077f8f59d697a2
https://github.com/scummvm/scummvm/commit/aeb5012b1d6188a6d5077bbcbf077f8f59d697a2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:45+01:00
Commit Message:
AGDS: pass engine pointer to process instance
Changed paths:
engines/agds/agds.cpp
engines/agds/process.cpp
engines/agds/process.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index e79fa570210..127dcb0b1d1 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -73,7 +73,7 @@ void AGDSEngine::loadObject(Common::String & name) {
if (!object)
_objects.setVal(name, object = new Object(stream));
- _processes.push_back(Process(object));
+ _processes.push_back(Process(this, object));
_processes.back().execute();
}
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 01941ef9243..8d7983970d7 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -53,8 +53,8 @@ enum Opcode {
#define OP_UU(NAME, METHOD) \
case NAME: { uint16 arg1 = next16(); uint16 arg2 = next16(); METHOD (arg1, arg2); } break
-Process::Process(Object* object) :
- _object(object), _ip(0), _failed(false) {
+Process::Process(AGDSEngine *engine, Object* object) :
+ _engine(engine), _object(object), _ip(0), _failed(false) {
}
void Process::push(int32 value) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 4b5db2101ae..5be9127431b 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -29,10 +29,12 @@
namespace AGDS {
+class AGDSEngine;
class Process {
private:
typedef Common::Stack<int32> StackType;
+ AGDSEngine * _engine;
Object * _object;
StackType _stack;
unsigned _ip;
@@ -64,7 +66,7 @@ private:
void loadPicture();
public:
- Process(Object *object);
+ Process(AGDSEngine *engine, Object *object);
void execute();
};
Commit: bbb72808df4ecd0d73f38afe430af08d0e3b6ab4
https://github.com/scummvm/scummvm/commit/bbb72808df4ecd0d73f38afe430af08d0e3b6ab4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:46+01:00
Commit Message:
AGDS: implemented shared storage and append to shared storage opcode
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 127dcb0b1d1..a54cdc00c30 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -31,7 +31,7 @@
namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
- _gameDescription(gameDesc) {
+ _gameDescription(gameDesc), _sharedStorageIndex(-2) {
}
AGDSEngine::~AGDSEngine() {
@@ -91,4 +91,13 @@ Common::Error AGDSEngine::run() {
return Common::kNoError;
}
+int AGDSEngine::appendToSharedStorage(const Common::String &value) {
+ int index = _sharedStorageIndex;
+ _sharedStorage[-2 - (_sharedStorageIndex--)] = value;
+ if (_sharedStorageIndex <= -12)
+ _sharedStorageIndex = -2;
+ return index;
+}
+
+
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index e494b493556..25627529bd3 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -43,6 +43,8 @@ class Object;
class Process;
class AGDSEngine : public Engine {
+ friend class Process;
+
public:
AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc);
~AGDSEngine();
@@ -52,6 +54,7 @@ public:
private:
bool load();
void loadObject(Common::String & name);
+ int appendToSharedStorage(const Common::String &value);
private:
typedef Common::HashMap<Common::String, Object *> ObjectsType;
@@ -63,6 +66,8 @@ private:
ObjectsType _objects;
ProcessListType _processes;
Common::String _nextScreen;
+ int _sharedStorageIndex;
+ Common::String _sharedStorage[10];
};
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 8d7983970d7..6d8d89dd0ad 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -32,6 +32,7 @@ enum Opcode {
kSetSystemVariable = 142,
kGetRegionWidth = 146,
kGetRegionHeight = 147,
+ kAppendToSharedStorage = 175,
kLoadPicture = 198,
kMax = 248
};
@@ -79,8 +80,9 @@ void Process::execute() {
OP_UU (kEnter, enter);
OP (kPop, pop);
OP_C (kPushImm8, push);
- OP (kLoadPicture, loadPicture);
OP (kSetSystemVariable, setSystemVariable);
+ OP (kAppendToSharedStorage, appendToSharedStorage);
+ OP (kLoadPicture, loadPicture);
default:
debug("%08x: unknown opcode 0x%02x (%u)", _ip - 1, (unsigned)op, (unsigned)op);
_failed = true;
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 5be9127431b..ebe886ffd33 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -64,6 +64,7 @@ private:
void enter(uint16 magic, uint16 size);
void setSystemVariable();
void loadPicture();
+ void appendToSharedStorage();
public:
Process(AGDSEngine *engine, Object *object);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d80c8fe20fe..3a10a3bf133 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -21,6 +21,7 @@
*/
#include "agds/process.h"
+#include "agds/agds.h"
#include "common/debug.h"
namespace AGDS {
@@ -58,4 +59,12 @@ void Process::loadPicture() {
push(100500); //dummy
}
+void Process::appendToSharedStorage() {
+ const Object::StringEntry &value = popString();
+ int index = _engine->appendToSharedStorage(value.string);
+ debug("appendToSharedStorage %s -> %d", value.string.c_str(), index);
+ push(index);
+}
+
+
}
Commit: 5dd9e6569c5ff1706ed916269896fc789596e373
https://github.com/scummvm/scummvm/commit/5dd9e6569c5ff1706ed916269896fc789596e373
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:46+01:00
Commit Message:
AGDS: implemented process suspension and loadScreenObject
Changed paths:
A engines/agds/processExitCode.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index a54cdc00c30..45ec04fbcb9 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -63,7 +63,7 @@ bool AGDSEngine::load() {
return true;
}
-void AGDSEngine::loadObject(Common::String & name) {
+ProcessExitCode AGDSEngine::loadObject(Common::String & name) {
debug("loading object %s", name.c_str());
Common::SeekableReadStream * stream = _data.getEntry(name);
if (!stream)
@@ -74,7 +74,7 @@ void AGDSEngine::loadObject(Common::String & name) {
_objects.setVal(name, object = new Object(stream));
_processes.push_back(Process(this, object));
- _processes.back().execute();
+ return _processes.back().execute();
}
Common::Error AGDSEngine::run() {
@@ -99,5 +99,12 @@ int AGDSEngine::appendToSharedStorage(const Common::String &value) {
return index;
}
+const Common::String & AGDSEngine::getSharedStorage(int id) const {
+ int index = -2 - id;
+ if (index < 0 || index >= 10)
+ error("shared storage id is out of range");
+ return _sharedStorage[index];
+}
+
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 25627529bd3..3b6f1fd70fc 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -26,8 +26,9 @@
#include "common/scummsys.h"
#include "common/hashmap.h"
#include "engines/advancedDetector.h"
-#include "agds/resourceManager.h"
#include "agds/database.h"
+#include "agds/processExitCode.h"
+#include "agds/resourceManager.h"
/**
* This is the namespace of the AGDS engine.
@@ -53,8 +54,9 @@ public:
private:
bool load();
- void loadObject(Common::String & name);
+ ProcessExitCode loadObject(Common::String & name);
int appendToSharedStorage(const Common::String &value);
+ const Common::String & getSharedStorage(int id) const;
private:
typedef Common::HashMap<Common::String, Object *> ObjectsType;
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 6d8d89dd0ad..f4abf252e5b 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -21,20 +21,22 @@
*/
#include "agds/process.h"
+#include "agds/agds.h"
#include "common/debug.h"
namespace AGDS {
enum Opcode {
- kEnter = 5,
- kPop = 10,
- kPushImm8 = 18,
- kSetSystemVariable = 142,
- kGetRegionWidth = 146,
- kGetRegionHeight = 147,
+ kEnter = 5,
+ kPop = 10,
+ kPushImm8 = 18,
+ kScreenLoadObject = 76,
+ kSetSystemVariable = 142,
+ kGetRegionWidth = 146,
+ kGetRegionHeight = 147,
kAppendToSharedStorage = 175,
- kLoadPicture = 198,
- kMax = 248
+ kLoadPicture = 198,
+ kMax = 248
};
@@ -55,7 +57,7 @@ enum Opcode {
case NAME: { uint16 arg1 = next16(); uint16 arg2 = next16(); METHOD (arg1, arg2); } break
Process::Process(AGDSEngine *engine, Object* object) :
- _engine(engine), _object(object), _ip(0), _failed(false) {
+ _engine(engine), _object(object), _ip(0), _status(kStatusActive), _exitCode(kExitCodeDestroy) {
}
void Process::push(int32 value) {
@@ -68,27 +70,36 @@ int32 Process::pop() {
return _stack.pop();
}
-const Object::StringEntry & Process::popString() {
- return _object->getString(pop());
+Common::String Process::getString(int id) {
+ if (id <= -2 && id > -12)
+ return _engine->getSharedStorage(id);
+ else
+ return _object->getString(id).string;
}
-void Process::execute() {
+
+ProcessExitCode Process::execute() {
+ _exitCode = kExitCodeDestroy;
+
const Object::CodeType &code = _object->getCode();
- while(!_failed && _ip < code.size()) {
+ while(_status == kStatusActive && _ip < code.size()) {
uint8 op = next();
switch(op) {
OP_UU (kEnter, enter);
OP (kPop, pop);
OP_C (kPushImm8, push);
+ OP (kScreenLoadObject, loadScreenObject);
OP (kSetSystemVariable, setSystemVariable);
OP (kAppendToSharedStorage, appendToSharedStorage);
OP (kLoadPicture, loadPicture);
default:
debug("%08x: unknown opcode 0x%02x (%u)", _ip - 1, (unsigned)op, (unsigned)op);
- _failed = true;
+ _status = kStatusError;
break;
}
}
+
+ return _exitCode;
}
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index ebe886ffd33..2c9b763a670 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -24,6 +24,7 @@
#define AGDS_PROCESS_H
#include "agds/object.h"
+#include "agds/processExitCode.h"
#include "common/scummsys.h"
#include "common/stack.h"
@@ -31,6 +32,9 @@ namespace AGDS {
class AGDSEngine;
class Process {
+public:
+ enum Status { kStatusActive, kStatusPassive, kStatusDone, kStatusError };
+
private:
typedef Common::Stack<int32> StackType;
@@ -38,7 +42,9 @@ private:
Object * _object;
StackType _stack;
unsigned _ip;
- bool _failed; //fixme: add status
+ Status _status;
+ Common::String _exitValue;
+ ProcessExitCode _exitCode;
private:
uint8 next() {
@@ -46,7 +52,7 @@ private:
if (_ip < code.size()) {
return code[_ip++];
} else {
- _failed = true;
+ _status = kStatusError;
return 0;
}
}
@@ -59,17 +65,36 @@ private:
void push(int32 value);
int32 pop();
- const Object::StringEntry & popString();
+
+ Common::String getString(int id);
+ Common::String popString() {
+ return getString(pop());
+ }
void enter(uint16 magic, uint16 size);
void setSystemVariable();
void loadPicture();
void appendToSharedStorage();
+ void loadScreenObject();
+
+ void suspend(ProcessExitCode exitCode) {
+ if (_status == kStatusActive)
+ _status = kStatusPassive;
+ _exitCode = exitCode;
+ }
public:
Process(AGDSEngine *engine, Object *object);
- void execute();
+ ProcessExitCode execute();
+
+ ProcessExitCode getExitCode() const {
+ return _exitCode;
+ }
+
+ const Common::String & getExitValue() const {
+ return _exitValue;
+ }
};
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
new file mode 100644
index 00000000000..691001b89e4
--- /dev/null
+++ b/engines/agds/processExitCode.h
@@ -0,0 +1,13 @@
+#ifndef AGDS_PROCESS_EXIT_CODE_H
+#define AGDS_PROCESS_EXIT_CODE_H
+
+namespace AGDS {
+
+ enum ProcessExitCode {
+ kExitCodeDestroy = 2,
+ kExitCodeLoadScreenObject = 8
+ };
+
+}
+
+#endif
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3a10a3bf133..b0aa3a6edb7 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -43,26 +43,33 @@ void Process::enter(uint16 magic, uint16 size) {
void Process::setSystemVariable() {
int16 valueIndex = pop();
- const Object::StringEntry &name = popString();
+ Common::String name = popString();
if (valueIndex != -1) {
- const Object::StringEntry &value = _object->getString(valueIndex);
- debug("setSystemVariable %s to %s", name.string.c_str(), value.string.c_str());
+ Common::String value = getString(valueIndex);
+ debug("setSystemVariable %s to %s", name.c_str(), value.c_str());
} else {
- debug("resetSystemVariable %s", name.string.c_str());
+ debug("resetSystemVariable %s", name.c_str());
}
}
void Process::loadPicture() {
- const Object::StringEntry &name = popString();
- debug("loadPicture stub %s", name.string.c_str());
+ Common::String name = popString();
+ debug("loadPicture stub %s", name.c_str());
push(100500); //dummy
}
+void Process::loadScreenObject() {
+ Common::String value = popString();
+ debug("loadObjectToCurrentScreen: %s", value.c_str());
+ _exitValue = value;
+ suspend(kExitCodeLoadScreenObject);
+}
+
void Process::appendToSharedStorage() {
- const Object::StringEntry &value = popString();
- int index = _engine->appendToSharedStorage(value.string);
- debug("appendToSharedStorage %s -> %d", value.string.c_str(), index);
+ Common::String value = popString();
+ int index = _engine->appendToSharedStorage(value);
+ debug("appendToSharedStorage %s -> %d", value.c_str(), index);
push(index);
}
Commit: 3feccb436c2021c425e5b03f5c05fec225ab763d
https://github.com/scummvm/scummvm/commit/3feccb436c2021c425e5b03f5c05fec225ab763d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:46+01:00
Commit Message:
AGDS: implemented simple nested scheduler stub
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 45ec04fbcb9..0c48a74e3c3 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -63,7 +63,7 @@ bool AGDSEngine::load() {
return true;
}
-ProcessExitCode AGDSEngine::loadObject(Common::String & name) {
+ProcessExitCode AGDSEngine::loadObject(const Common::String & name) {
debug("loading object %s", name.c_str());
Common::SeekableReadStream * stream = _data.getEntry(name);
if (!stream)
@@ -74,7 +74,22 @@ ProcessExitCode AGDSEngine::loadObject(Common::String & name) {
_objects.setVal(name, object = new Object(stream));
_processes.push_back(Process(this, object));
- return _processes.back().execute();
+
+ ProcessExitCode code = kExitCodeDestroy;
+ while(!_processes.empty()) {
+ Process & process = _processes.back();
+ code = process.execute();
+ switch(code) {
+ case kExitCodeLoadScreenObject:
+ debug("loading screen object...");
+ code = loadObject(process.getExitValue());
+ break;
+ default:
+ debug("destroying process...");
+ _processes.pop_back();
+ }
+ }
+ return code;
}
Common::Error AGDSEngine::run() {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 3b6f1fd70fc..ac349e7fb7c 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -54,7 +54,7 @@ public:
private:
bool load();
- ProcessExitCode loadObject(Common::String & name);
+ ProcessExitCode loadObject(const Common::String & name);
int appendToSharedStorage(const Common::String &value);
const Common::String & getSharedStorage(int id) const;
Commit: d7d1f298a3b2bada4a24a431b78afd7bb8a54207
https://github.com/scummvm/scummvm/commit/d7d1f298a3b2bada4a24a431b78afd7bb8a54207
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:46+01:00
Commit Message:
AGDS: moved opcode related code to process_opcodes.cpp, added more stubs, fixed process activation
Changed paths:
engines/agds/agds.cpp
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 0c48a74e3c3..c84aa6d04ed 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -78,6 +78,7 @@ ProcessExitCode AGDSEngine::loadObject(const Common::String & name) {
ProcessExitCode code = kExitCodeDestroy;
while(!_processes.empty()) {
Process & process = _processes.back();
+ process.activate();
code = process.execute();
switch(code) {
case kExitCodeLoadScreenObject:
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index f4abf252e5b..22ddbd56570 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -26,36 +26,6 @@
namespace AGDS {
-enum Opcode {
- kEnter = 5,
- kPop = 10,
- kPushImm8 = 18,
- kScreenLoadObject = 76,
- kSetSystemVariable = 142,
- kGetRegionWidth = 146,
- kGetRegionHeight = 147,
- kAppendToSharedStorage = 175,
- kLoadPicture = 198,
- kMax = 248
-};
-
-
-//fixme: add trace here
-#define OP(NAME, METHOD) \
- case NAME: METHOD (); break
-
-#define OP_C(NAME, METHOD) \
- case NAME: { int8 arg = next(); METHOD (arg); } break
-
-#define OP_B(NAME, METHOD) \
- case NAME: { uint8 arg = next(); METHOD (arg); } break
-
-#define OP_U(NAME, METHOD) \
- case NAME: { uint16 arg = next16(); METHOD (arg); } break
-
-#define OP_UU(NAME, METHOD) \
- case NAME: { uint16 arg1 = next16(); uint16 arg2 = next16(); METHOD (arg1, arg2); } break
-
Process::Process(AGDSEngine *engine, Object* object) :
_engine(engine), _object(object), _ip(0), _status(kStatusActive), _exitCode(kExitCodeDestroy) {
}
@@ -77,29 +47,17 @@ Common::String Process::getString(int id) {
return _object->getString(id).string;
}
-
-ProcessExitCode Process::execute() {
- _exitCode = kExitCodeDestroy;
-
- const Object::CodeType &code = _object->getCode();
- while(_status == kStatusActive && _ip < code.size()) {
- uint8 op = next();
- switch(op) {
- OP_UU (kEnter, enter);
- OP (kPop, pop);
- OP_C (kPushImm8, push);
- OP (kScreenLoadObject, loadScreenObject);
- OP (kSetSystemVariable, setSystemVariable);
- OP (kAppendToSharedStorage, appendToSharedStorage);
- OP (kLoadPicture, loadPicture);
- default:
- debug("%08x: unknown opcode 0x%02x (%u)", _ip - 1, (unsigned)op, (unsigned)op);
- _status = kStatusError;
+void Process::activate() {
+ switch(_status)
+ {
+ case kStatusActive:
break;
- }
+ case kStatusPassive:
+ _status = kStatusActive;
+ break;
+ default:
+ error("process in invalid state");
}
-
- return _exitCode;
}
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 2c9b763a670..1fefe7ac21b 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -74,8 +74,15 @@ private:
void enter(uint16 magic, uint16 size);
void setSystemVariable();
void loadPicture();
+ void loadMouse();
void appendToSharedStorage();
void loadScreenObject();
+ void removeScreenObject();
+ void loadFont();
+ void stub128();
+ void stub182();
+ void setIntegerVariable();
+ void exitProcess();
void suspend(ProcessExitCode exitCode) {
if (_status == kStatusActive)
@@ -86,6 +93,8 @@ private:
public:
Process(AGDSEngine *engine, Object *object);
+ void activate();
+
ProcessExitCode execute();
ProcessExitCode getExitCode() const {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b0aa3a6edb7..d1375a8f427 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -60,12 +60,34 @@ void Process::loadPicture() {
}
void Process::loadScreenObject() {
- Common::String value = popString();
- debug("loadObjectToCurrentScreen: %s", value.c_str());
- _exitValue = value;
+ Common::String name = popString();
+ debug("loadScreenObject: %s", name.c_str());
+ _exitValue = name;
suspend(kExitCodeLoadScreenObject);
}
+void Process::removeScreenObject() {
+ Common::String name = popString();
+ debug("removeScreenObject: %s", name.c_str());
+}
+
+void Process::loadFont() {
+ Common::String name = popString();
+ int id = pop();
+ debug("loadFont %s %d stub", name.c_str(), id);
+}
+
+void Process::loadMouse() {
+ Common::String name = popString();
+ debug("loadMouse %s", name.c_str());
+}
+
+void Process::setIntegerVariable() {
+ int value = pop();
+ Common::String name = popString();
+ debug("setIntegerVariable stub: %s -> %d", name.c_str(), value);
+}
+
void Process::appendToSharedStorage() {
Common::String value = popString();
int index = _engine->appendToSharedStorage(value);
@@ -73,5 +95,99 @@ void Process::appendToSharedStorage() {
push(index);
}
+void Process::stub128() {
+ debug("ProcessCleanupStub128");
+}
+void Process::stub182() {
+ int arg2 = pop();
+ int arg1 = pop();
+ debug("Stub182 %d %d", arg1, arg2);
+}
+
+void Process::exitProcess() {
+ debug("exit");
+ _status = kStatusDone;
+ _exitCode = kExitCodeDestroy;
+}
+
+//fixme: add trace here
+#define OP(NAME, METHOD) \
+ case NAME: METHOD (); break
+
+#define OP_C(NAME, METHOD) \
+ case NAME: { int8 arg = next(); METHOD (arg); } break
+
+#define OP_B(NAME, METHOD) \
+ case NAME: { uint8 arg = next(); METHOD (arg); } break
+
+#define OP_W(NAME, METHOD) \
+ case NAME: { int16 arg = next16(); METHOD (arg); } break
+
+#define OP_U(NAME, METHOD) \
+ case NAME: { uint16 arg = next16(); METHOD (arg); } break
+
+#define OP_UU(NAME, METHOD) \
+ case NAME: { uint16 arg1 = next16(); uint16 arg2 = next16(); METHOD (arg1, arg2); } break
+
+enum Opcode {
+ kEnter = 5,
+ kPop = 10,
+ kExitProcess = 12,
+ kPushImm16 = 15,
+ kPushImm8 = 16,
+ kPushImm16_2 = 17,
+ kPushImm8_2 = 18,
+ kScreenLoadObject = 76,
+ kScreenRemoveObject = 78,
+ kLoadMouse = 108,
+ kProcessCleanupStub128 = 128,
+ kSetSystemVariable = 142,
+ kSetIntegerVariable = 143,
+ kGetRegionWidth = 146,
+ kGetRegionHeight = 147,
+ kAppendToSharedStorage = 175,
+ kStub182 = 182,
+ kLoadPicture = 198,
+ kLoadFont = 227,
+ kMax = 248
+};
+
+ProcessExitCode Process::execute() {
+ _exitCode = kExitCodeDestroy;
+
+ const Object::CodeType &code = _object->getCode();
+ while(_status == kStatusActive && _ip < code.size()) {
+ uint8 op = next();
+ switch(op) {
+ OP_UU (kEnter, enter);
+ OP (kPop, pop);
+ OP (kExitProcess, exitProcess);
+ OP_C (kPushImm8, push);
+ OP_W (kPushImm16, push);
+ OP_C (kPushImm8_2, push);
+ OP_W (kPushImm16_2, push);
+ OP (kLoadMouse, loadMouse);
+ OP (kScreenLoadObject, loadScreenObject);
+ OP (kScreenRemoveObject, removeScreenObject);
+ OP (kSetSystemVariable, setSystemVariable);
+ OP (kSetIntegerVariable, setIntegerVariable);
+ OP (kAppendToSharedStorage, appendToSharedStorage);
+ OP (kLoadPicture, loadPicture);
+ OP (kProcessCleanupStub128, stub128);
+ OP (kStub182, stub182);
+ OP (kLoadFont, loadFont);
+ default:
+ debug("%08x: unknown opcode 0x%02x (%u)", _ip - 1, (unsigned)op, (unsigned)op);
+ _status = kStatusError;
+ break;
+ }
+ }
+
+ if (_status == kStatusActive) {
+ debug("code ended, exiting...");
+ }
+
+ return _exitCode;
+}
}
Commit: c66d23d4d1c2c4cf02ad257dcb382d38f3ddfb94
https://github.com/scummvm/scummvm/commit/c66d23d4d1c2c4cf02ad257dcb382d38f3ddfb94
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:46+01:00
Commit Message:
AGDS: added clearScreen stub, moved all the rest of opcodes to separate header
Changed paths:
A engines/agds/opcode.h
engines/agds/process.h
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
new file mode 100644
index 00000000000..54916e4e5bd
--- /dev/null
+++ b/engines/agds/opcode.h
@@ -0,0 +1,272 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_OPCODE_H
+#define AGDS_OPCODE_H
+
+namespace AGDS {
+
+enum Opcode {
+ kEnter = 5,
+ kStub8 = 8,
+ kStub9 = 9,
+ kPop = 10,
+ kStub11 = 11,
+ kExitProcess = 12,
+ kStub13 = 13,
+ kStub14 = 14,
+ kPushImm16 = 15,
+ kPushImm8 = 16,
+ kPushImm16_2 = 17,
+ kPushImm8_2 = 18,
+ kStub19 = 19,
+ kStub20 = 20,
+ kStub21 = 21,
+ kStub22 = 22,
+ kStub23 = 23,
+ kStub24 = 24,
+ kStub25 = 25,
+ kStub26 = 26,
+ kStub27 = 27,
+ kStub28 = 28,
+ kStub29 = 29,
+ kStub30 = 30,
+ kStub31 = 31,
+ kStub32 = 32,
+ kStub33 = 33,
+ kStub34 = 34,
+ kStub35 = 35,
+ kStub36 = 36,
+ kStub37 = 37,
+ kStub38 = 38,
+ kStub39 = 39,
+ kStub40 = 40,
+ kStub41 = 41,
+ kStub42 = 42,
+ kStub43 = 43,
+ kStub44 = 44,
+ kStub45 = 45,
+ kStub46 = 46,
+ kStub47 = 47,
+ kStub48 = 48,
+ kStub49 = 49,
+ kStub50 = 50,
+ kStub51 = 51,
+ kStub52 = 52,
+ kStub53 = 53,
+ kStub54 = 54,
+ kStub55 = 55,
+ kStub56 = 56,
+ kStub57 = 57,
+ kStub58 = 58,
+ kStub59 = 59,
+ kStub60 = 60,
+ kStub61 = 61,
+ kStub62 = 62,
+ kStub63 = 63,
+ kStub64 = 64,
+ kStub65 = 65,
+ kStub66 = 66,
+ kStub68 = 68,
+ kStub69 = 69,
+ kStub70 = 70,
+ kStub71 = 71,
+ kStub72 = 72,
+ kStub73 = 73,
+ kStub74 = 74,
+ kStub75 = 75,
+ kScreenLoadObject = 76,
+ kStub77 = 77,
+ kScreenRemoveObject = 78,
+ kStub79 = 79,
+ kStub80 = 80,
+ kStub82 = 82,
+ kStub83 = 83,
+ kStub84 = 84,
+ kStub85 = 85,
+ kStub86 = 86,
+ kStub87 = 87,
+ kStub88 = 88,
+ kStub89 = 89,
+ kStub90 = 90,
+ kStub91 = 91,
+ kStub92 = 92,
+ kStub93 = 93,
+ kStub94 = 94,
+ kStub95 = 95,
+ kStub96 = 96,
+ kStub97 = 97,
+ kStub98 = 98,
+ kStub99 = 99,
+ kStub100 = 100,
+ kStub101 = 101,
+ kStub102 = 102,
+ kStub103 = 103,
+ kStub104 = 104,
+ kClearScreen = 105,
+ kStub106 = 106,
+ kStub107 = 107,
+ kLoadMouse = 108,
+ kStub109 = 109,
+ kStub110 = 110,
+ kStub111 = 111,
+ kStub112 = 112,
+ kStub113 = 113,
+ kStub114 = 114,
+ kStub115 = 115,
+ kStub116 = 116,
+ kStub117 = 117,
+ kStub118 = 118,
+ kStub119 = 119,
+ kStub120 = 120,
+ kStub121 = 121,
+ kStub122 = 122,
+ kStub123 = 123,
+ kStub124 = 124,
+ kStub125 = 125,
+ kStub126 = 126,
+ kStub127 = 127,
+ kProcessCleanupStub128 = 128,
+ kStub129 = 129,
+ kStub130 = 130,
+ kStub131 = 131,
+ kStub132 = 132,
+ kStub133 = 133,
+ kStub134 = 134,
+ kStub135 = 135,
+ kStub136 = 136,
+ kStub137 = 137,
+ kStub138 = 138,
+ kStub139 = 139,
+ kStub140 = 140,
+ kStub141 = 141,
+ kSetSystemVariable = 142,
+ kSetIntegerVariable = 143,
+ kStub144 = 144,
+ kStub145 = 145,
+ kGetRegionWidth = 146,
+ kGetRegionHeight = 147,
+ kStub148 = 148,
+ kStub149 = 149,
+ kStub150 = 150,
+ kStub151 = 151,
+ kStub152 = 152,
+ kStub153 = 153,
+ kStub154 = 154,
+ kStub155 = 155,
+ kStub156 = 156,
+ kStub157 = 157,
+ kStub158 = 158,
+ kStub159 = 159,
+ kStub160 = 160,
+ kStub161 = 161,
+ kStub162 = 162,
+ kStub163 = 163,
+ kStub164 = 164,
+ kStub165 = 165,
+ kStub166 = 166,
+ kStub167 = 167,
+ kStub168 = 168,
+ kStub169 = 169,
+ kStub170 = 170,
+ kStub171 = 171,
+ kStub172 = 172,
+ kStub173 = 173,
+ kStub174 = 174,
+ kAppendToSharedStorage = 175,
+ kStub176 = 176,
+ kStub177 = 177,
+ kStub178 = 178,
+ kStub179 = 179,
+ kStub180 = 180,
+ kStub181 = 181,
+ kStub182 = 182,
+ kStub183 = 183,
+ kStub184 = 184,
+ kStub185 = 185,
+ kStub186 = 186,
+ kStub187 = 187,
+ kStub188 = 188,
+ kStub189 = 189,
+ kStub190 = 190,
+ kStub191 = 191,
+ kStub192 = 192,
+ kStub193 = 193,
+ kStub194 = 194,
+ kStub195 = 195,
+ kStub196 = 196,
+ kStub197 = 197,
+ kLoadPicture = 198,
+ kStub199 = 199,
+ kStub200 = 200,
+ kStub201 = 201,
+ kStub202 = 202,
+ kStub203 = 203,
+ kStub204 = 204,
+ kStub205 = 205,
+ kStub206 = 206,
+ kStub207 = 207,
+ kStub208 = 208,
+ kStub209 = 209,
+ kStub210 = 210,
+ kStub211 = 211,
+ kStub212 = 212,
+ kStub213 = 213,
+ kStub214 = 214,
+ kStub215 = 215,
+ kStub216 = 216,
+ kStub217 = 217,
+ kStub218 = 218,
+ kStub219 = 219,
+ kStub220 = 220,
+ kStub221 = 221,
+ kStub222 = 222,
+ kStub223 = 223,
+ kStub224 = 224,
+ kStub225 = 225,
+ kStub226 = 226,
+ kLoadFont = 227,
+ kStub228 = 228,
+ kStub229 = 229,
+ kStub230 = 230,
+ kStub231 = 231,
+ kStub232 = 232,
+ kStub233 = 233,
+ kStub234 = 234,
+ kStub235 = 235,
+ kStub236 = 236,
+ kStub237 = 237,
+ kStub238 = 238,
+ kStub239 = 239,
+ kStub240 = 240,
+ kStub241 = 241,
+ kStub242 = 242,
+ kStub243 = 243,
+ kStub244 = 244,
+ kStub245 = 245,
+ kStub246 = 246,
+ kStub247 = 247
+};
+
+}
+
+#endif
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 1fefe7ac21b..e44d1a20739 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -72,6 +72,7 @@ private:
}
void enter(uint16 magic, uint16 size);
+ void clearScreen();
void setSystemVariable();
void loadPicture();
void loadMouse();
@@ -79,11 +80,13 @@ private:
void loadScreenObject();
void removeScreenObject();
void loadFont();
- void stub128();
- void stub182();
void setIntegerVariable();
void exitProcess();
+ void stub98();
+ void stub128();
+ void stub182();
+
void suspend(ProcessExitCode exitCode) {
if (_status == kStatusActive)
_status = kStatusPassive;
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index 691001b89e4..2c68b61fc56 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -1,3 +1,25 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
#ifndef AGDS_PROCESS_EXIT_CODE_H
#define AGDS_PROCESS_EXIT_CODE_H
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d1375a8f427..6236b663514 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -22,6 +22,7 @@
#include "agds/process.h"
#include "agds/agds.h"
+#include "agds/opcode.h"
#include "common/debug.h"
namespace AGDS {
@@ -110,6 +111,10 @@ void Process::exitProcess() {
_exitCode = kExitCodeDestroy;
}
+void Process::clearScreen() {
+ debug("clearScreen");
+}
+
//fixme: add trace here
#define OP(NAME, METHOD) \
case NAME: METHOD (); break
@@ -129,29 +134,6 @@ void Process::exitProcess() {
#define OP_UU(NAME, METHOD) \
case NAME: { uint16 arg1 = next16(); uint16 arg2 = next16(); METHOD (arg1, arg2); } break
-enum Opcode {
- kEnter = 5,
- kPop = 10,
- kExitProcess = 12,
- kPushImm16 = 15,
- kPushImm8 = 16,
- kPushImm16_2 = 17,
- kPushImm8_2 = 18,
- kScreenLoadObject = 76,
- kScreenRemoveObject = 78,
- kLoadMouse = 108,
- kProcessCleanupStub128 = 128,
- kSetSystemVariable = 142,
- kSetIntegerVariable = 143,
- kGetRegionWidth = 146,
- kGetRegionHeight = 147,
- kAppendToSharedStorage = 175,
- kStub182 = 182,
- kLoadPicture = 198,
- kLoadFont = 227,
- kMax = 248
-};
-
ProcessExitCode Process::execute() {
_exitCode = kExitCodeDestroy;
@@ -166,6 +148,7 @@ ProcessExitCode Process::execute() {
OP_W (kPushImm16, push);
OP_C (kPushImm8_2, push);
OP_W (kPushImm16_2, push);
+ OP (kClearScreen, clearScreen);
OP (kLoadMouse, loadMouse);
OP (kScreenLoadObject, loadScreenObject);
OP (kScreenRemoveObject, removeScreenObject);
Commit: 626cd9e6b379baf67e8a6d403a4051f696957243
https://github.com/scummvm/scummvm/commit/626cd9e6b379baf67e8a6d403a4051f696957243
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:46+01:00
Commit Message:
AGDS: added 4 new instructions
Changed paths:
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index ac349e7fb7c..6464de21b71 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -56,11 +56,14 @@ private:
bool load();
ProcessExitCode loadObject(const Common::String & name);
int appendToSharedStorage(const Common::String &value);
+ void setGlobal(const Common::String &name, int value)
+ { _globals.setVal(name, value); }
const Common::String & getSharedStorage(int id) const;
private:
- typedef Common::HashMap<Common::String, Object *> ObjectsType;
+ typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
typedef Common::List<Process> ProcessListType;
+ typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
const ADGameDescription * _gameDescription;
ResourceManager _resourceManager;
@@ -70,6 +73,7 @@ private:
Common::String _nextScreen;
int _sharedStorageIndex;
Common::String _sharedStorage[10];
+ GlobalsType _globals;
};
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 54916e4e5bd..574df74d6d0 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -27,12 +27,12 @@ namespace AGDS {
enum Opcode {
kEnter = 5,
- kStub8 = 8,
+ kJumpZImm16 = 8,
kStub9 = 9,
kPop = 10,
kStub11 = 11,
kExitProcess = 12,
- kStub13 = 13,
+ kExitProcess5 = 13,
kStub14 = 14,
kPushImm16 = 15,
kPushImm8 = 16,
@@ -67,7 +67,7 @@ enum Opcode {
kStub45 = 45,
kStub46 = 46,
kStub47 = 47,
- kStub48 = 48,
+ kSetGlobal = 48,
kStub49 = 49,
kStub50 = 50,
kStub51 = 51,
@@ -246,7 +246,7 @@ enum Opcode {
kStub226 = 226,
kLoadFont = 227,
kStub228 = 228,
- kStub229 = 229,
+ kOnKey = 229,
kStub230 = 230,
kStub231 = 231,
kStub232 = 232,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index e44d1a20739..06ba21e1501 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -66,6 +66,16 @@ private:
void push(int32 value);
int32 pop();
+ void jump(int delta)
+ { _ip += delta; }
+
+ void jumpz(int delta)
+ {
+ int value = pop();
+ if (value == 0)
+ jump(delta);
+ }
+
Common::String getString(int id);
Common::String popString() {
return getString(pop());
@@ -74,6 +84,7 @@ private:
void enter(uint16 magic, uint16 size);
void clearScreen();
void setSystemVariable();
+ void setGlobal();
void loadPicture();
void loadMouse();
void appendToSharedStorage();
@@ -82,9 +93,11 @@ private:
void loadFont();
void setIntegerVariable();
void exitProcess();
+ void onKey(unsigned size);
void stub98();
void stub128();
+ void stub140();
void stub182();
void suspend(ProcessExitCode exitCode) {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 6236b663514..1e9fd40ad0b 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -89,6 +89,13 @@ void Process::setIntegerVariable() {
debug("setIntegerVariable stub: %s -> %d", name.c_str(), value);
}
+void Process::setGlobal() {
+ Common::String name = popString();
+ int value = pop();
+ debug("setting global %s -> %d", name.c_str(), value);
+ _engine->setGlobal(name, value);
+}
+
void Process::appendToSharedStorage() {
Common::String value = popString();
int index = _engine->appendToSharedStorage(value);
@@ -96,13 +103,27 @@ void Process::appendToSharedStorage() {
push(index);
}
+void Process::stub98() {
+ debug("stub98");
+}
+
+void Process::stub140() {
+ Common::String res2 = popString();
+ Common::String res1;
+ int index = pop();
+ if (index != -1)
+ res1 = getString(index);
+ debug("stub140: %d '%s' '%s'", index, res1.c_str(), res2.c_str());
+}
+
void Process::stub128() {
- debug("ProcessCleanupStub128");
+ debug("processCleanupStub128");
}
+
void Process::stub182() {
int arg2 = pop();
int arg1 = pop();
- debug("Stub182 %d %d", arg1, arg2);
+ debug("stub182 %d %d", arg1, arg2);
}
void Process::exitProcess() {
@@ -115,6 +136,13 @@ void Process::clearScreen() {
debug("clearScreen");
}
+void Process::onKey(unsigned size) {
+ Common::String key = popString();
+ debug("onKey %s handler, %u instructions", key.c_str(), size);
+ _ip += size;
+}
+
+
//fixme: add trace here
#define OP(NAME, METHOD) \
case NAME: METHOD (); break
@@ -142,16 +170,20 @@ ProcessExitCode Process::execute() {
uint8 op = next();
switch(op) {
OP_UU (kEnter, enter);
+ OP_W (kJumpZImm16, jumpz);
OP (kPop, pop);
OP (kExitProcess, exitProcess);
OP_C (kPushImm8, push);
OP_W (kPushImm16, push);
OP_C (kPushImm8_2, push);
OP_W (kPushImm16_2, push);
+ OP (kSetGlobal, setGlobal);
+ OP (kStub98, stub98);
OP (kClearScreen, clearScreen);
OP (kLoadMouse, loadMouse);
OP (kScreenLoadObject, loadScreenObject);
OP (kScreenRemoveObject, removeScreenObject);
+ OP (kStub140, stub140);
OP (kSetSystemVariable, setSystemVariable);
OP (kSetIntegerVariable, setIntegerVariable);
OP (kAppendToSharedStorage, appendToSharedStorage);
@@ -159,6 +191,7 @@ ProcessExitCode Process::execute() {
OP (kProcessCleanupStub128, stub128);
OP (kStub182, stub182);
OP (kLoadFont, loadFont);
+ OP_U (kOnKey, onKey);
default:
debug("%08x: unknown opcode 0x%02x (%u)", _ip - 1, (unsigned)op, (unsigned)op);
_status = kStatusError;
Commit: d6aaf8973314e4ec661a7258baa87911a0c474af
https://github.com/scummvm/scummvm/commit/d6aaf8973314e4ec661a7258baa87911a0c474af
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:46+01:00
Commit Message:
AGDS: added name to object, output it in unknown opcode exception
Changed paths:
engines/agds/agds.cpp
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c84aa6d04ed..ccfd17dfdd0 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -71,7 +71,7 @@ ProcessExitCode AGDSEngine::loadObject(const Common::String & name) {
ObjectsType::iterator i = _objects.find(name);
Object *object = i != _objects.end()? i->_value: NULL;
if (!object)
- _objects.setVal(name, object = new Object(stream));
+ _objects.setVal(name, object = new Object(name, stream));
_processes.push_back(Process(this, object));
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 48fba3cfc25..9c51b2ab6c6 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -26,7 +26,7 @@
namespace AGDS {
-Object::Object(Common::SeekableReadStream * stream) : _stringTableLoaded(false) {
+Object::Object(const Common::String &name, Common::SeekableReadStream * stream) : _name(name), _stringTableLoaded(false) {
stream->skip(2);
uint16 dataSize = stream->readUint16LE();
if (dataSize != 0)
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 27220c6f5bc..2fa4d621714 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -46,16 +46,19 @@ public:
private:
typedef Common::HashMap<uint16, StringEntry, Common::Hash<uint16> > StringTableType;
+ Common::String _name;
CodeType _code;
StringTableType _stringTable;
bool _stringTableLoaded;
public:
- Object(Common::SeekableReadStream * stream);
+ Object(const Common::String &name, Common::SeekableReadStream * stream);
void readStringTable(unsigned resOffset, uint16 resCount);
const StringEntry & getString(uint16 index) const;
+ const Common::String & getName() const
+ { return _name; }
const CodeType & getCode() const {
return _code;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 1e9fd40ad0b..4418cdb0955 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -193,7 +193,7 @@ ProcessExitCode Process::execute() {
OP (kLoadFont, loadFont);
OP_U (kOnKey, onKey);
default:
- debug("%08x: unknown opcode 0x%02x (%u)", _ip - 1, (unsigned)op, (unsigned)op);
+ debug("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _ip - 1, (unsigned)op, (unsigned)op);
_status = kStatusError;
break;
}
Commit: 9eed06fe14c4040f0ccda78c65d2b53ff2842c57
https://github.com/scummvm/scummvm/commit/9eed06fe14c4040f0ccda78c65d2b53ff2842c57
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:46+01:00
Commit Message:
AGDS: fixed stub 140 implementation
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 574df74d6d0..3d0c951c1a3 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -157,7 +157,7 @@ enum Opcode {
kStub137 = 137,
kStub138 = 138,
kStub139 = 139,
- kStub140 = 140,
+ kScreenChangeScreenPatch = 140,
kStub141 = 141,
kSetSystemVariable = 142,
kSetIntegerVariable = 143,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 06ba21e1501..8bb5fe9ff2f 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -97,7 +97,7 @@ private:
void stub98();
void stub128();
- void stub140();
+ void changeScreenPatch();
void stub182();
void suspend(ProcessExitCode exitCode) {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4418cdb0955..63c231c1d6b 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -107,13 +107,15 @@ void Process::stub98() {
debug("stub98");
}
-void Process::stub140() {
+void Process::changeScreenPatch() {
Common::String res2 = popString();
Common::String res1;
int index = pop();
if (index != -1)
res1 = getString(index);
+ //change screen patch
debug("stub140: %d '%s' '%s'", index, res1.c_str(), res2.c_str());
+ push(0);
}
void Process::stub128() {
@@ -183,7 +185,7 @@ ProcessExitCode Process::execute() {
OP (kLoadMouse, loadMouse);
OP (kScreenLoadObject, loadScreenObject);
OP (kScreenRemoveObject, removeScreenObject);
- OP (kStub140, stub140);
+ OP (kScreenChangeScreenPatch, changeScreenPatch);
OP (kSetSystemVariable, setSystemVariable);
OP (kSetIntegerVariable, setIntegerVariable);
OP (kAppendToSharedStorage, appendToSharedStorage);
Commit: bec1a83eaa2d792df8647b10092cfa2eebaac432
https://github.com/scummvm/scummvm/commit/bec1a83eaa2d792df8647b10092cfa2eebaac432
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:46+01:00
Commit Message:
AGDS: implemented playFilm, GetGlobalImm8
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ccfd17dfdd0..274ad59f792 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -122,5 +122,16 @@ const Common::String & AGDSEngine::getSharedStorage(int id) const {
return _sharedStorage[index];
}
+int AGDSEngine::getGlobal(const Common::String &name) const {
+ GlobalsType::const_iterator i = _globals.find(name);
+ if (i != _globals.end())
+ return i->_value;
+ else {
+ debug("global %s was not declared, returning 0", name.c_str());
+ return 0;
+ }
+}
+
+
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 6464de21b71..415b6d2a535 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -56,9 +56,11 @@ private:
bool load();
ProcessExitCode loadObject(const Common::String & name);
int appendToSharedStorage(const Common::String &value);
+ const Common::String & getSharedStorage(int id) const;
+
void setGlobal(const Common::String &name, int value)
{ _globals.setVal(name, value); }
- const Common::String & getSharedStorage(int id) const;
+ int getGlobal(const Common::String &name) const;
private:
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 3d0c951c1a3..194055d03c6 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -40,7 +40,7 @@ enum Opcode {
kPushImm8_2 = 18,
kStub19 = 19,
kStub20 = 20,
- kStub21 = 21,
+ kGetGlobalImm8 = 21,
kStub22 = 22,
kStub23 = 23,
kStub24 = 24,
@@ -116,7 +116,7 @@ enum Opcode {
kStub96 = 96,
kStub97 = 97,
kStub98 = 98,
- kStub99 = 99,
+ kEnableUser = 99,
kStub100 = 100,
kStub101 = 101,
kStub102 = 102,
@@ -219,8 +219,8 @@ enum Opcode {
kStub199 = 199,
kStub200 = 200,
kStub201 = 201,
- kStub202 = 202,
- kStub203 = 203,
+ kStub202ScreenHandler = 202,
+ kPlayFilm = 203,
kStub204 = 204,
kStub205 = 205,
kStub206 = 206,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 8bb5fe9ff2f..ee48abe0579 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -84,6 +84,7 @@ private:
void enter(uint16 magic, uint16 size);
void clearScreen();
void setSystemVariable();
+ void getGlobal(unsigned index);
void setGlobal();
void loadPicture();
void loadMouse();
@@ -99,6 +100,9 @@ private:
void stub128();
void changeScreenPatch();
void stub182();
+ void stub202(unsigned size);
+ void stub203();
+ void enableUser();
void suspend(ProcessExitCode exitCode) {
if (_status == kStatusActive)
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 63c231c1d6b..e6159a24a32 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -96,6 +96,14 @@ void Process::setGlobal() {
_engine->setGlobal(name, value);
}
+void Process::getGlobal(unsigned index) {
+ const Common::String & name = _object->getString(index).string;
+ int value = _engine->getGlobal(name);
+ debug("get global %s -> %d", name.c_str(), value);
+ push(value);
+}
+
+
void Process::appendToSharedStorage() {
Common::String value = popString();
int index = _engine->appendToSharedStorage(value);
@@ -138,12 +146,32 @@ void Process::clearScreen() {
debug("clearScreen");
}
+void Process::stub202(unsigned size) {
+ debug("stub203, %u instructions", size);
+ _ip += size;
+}
+
+void Process::stub203() {
+ //arg3 is optional and stored in process struct, offset 0x210
+ Common::String audio = popString();
+ Common::String video = popString();
+
+ debug("playFilm %s %s", video.c_str(), audio.c_str());
+}
+
+
void Process::onKey(unsigned size) {
Common::String key = popString();
debug("onKey %s handler, %u instructions", key.c_str(), size);
_ip += size;
}
+void Process::enableUser() {
+ //screen loading block user interaction until this instruction
+ debug("enableUser");
+}
+
+
//fixme: add trace here
#define OP(NAME, METHOD) \
@@ -179,8 +207,10 @@ ProcessExitCode Process::execute() {
OP_W (kPushImm16, push);
OP_C (kPushImm8_2, push);
OP_W (kPushImm16_2, push);
+ OP_B (kGetGlobalImm8, getGlobal);
OP (kSetGlobal, setGlobal);
OP (kStub98, stub98);
+ OP (kEnableUser, enableUser);
OP (kClearScreen, clearScreen);
OP (kLoadMouse, loadMouse);
OP (kScreenLoadObject, loadScreenObject);
@@ -193,6 +223,8 @@ ProcessExitCode Process::execute() {
OP (kProcessCleanupStub128, stub128);
OP (kStub182, stub182);
OP (kLoadFont, loadFont);
+ OP_U (kStub202ScreenHandler, stub202);
+ OP (kPlayFilm, stub203);
OP_U (kOnKey, onKey);
default:
debug("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _ip - 1, (unsigned)op, (unsigned)op);
Commit: ff1f162257de2af19f641f2dde9a8535de4eac5d
https://github.com/scummvm/scummvm/commit/ff1f162257de2af19f641f2dde9a8535de4eac5d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:46+01:00
Commit Message:
AGDS: added stub206
Changed paths:
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.h b/engines/agds/process.h
index ee48abe0579..cbf107c2f8f 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -102,6 +102,7 @@ private:
void stub182();
void stub202(unsigned size);
void stub203();
+ void stub206();
void enableUser();
void suspend(ProcessExitCode exitCode) {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index e6159a24a32..a1efba82de6 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -159,6 +159,13 @@ void Process::stub203() {
debug("playFilm %s %s", video.c_str(), audio.c_str());
}
+void Process::stub206() {
+ int arg2 = pop();
+ int arg1 = pop();
+ debug("stub206 (mouse?) %d %d", arg1, arg2);
+}
+
+
void Process::onKey(unsigned size) {
Common::String key = popString();
@@ -225,6 +232,7 @@ ProcessExitCode Process::execute() {
OP (kLoadFont, loadFont);
OP_U (kStub202ScreenHandler, stub202);
OP (kPlayFilm, stub203);
+ OP (kStub206, stub206);
OP_U (kOnKey, onKey);
default:
debug("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _ip - 1, (unsigned)op, (unsigned)op);
Commit: 0521108147c3b2e29305e2acc95ce8fed9bd8ca4
https://github.com/scummvm/scummvm/commit/0521108147c3b2e29305e2acc95ce8fed9bd8ca4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:47+01:00
Commit Message:
AGDS: added kExitScreen opcode
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 194055d03c6..f3ab4971bba 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -179,7 +179,7 @@ enum Opcode {
kStub159 = 159,
kStub160 = 160,
kStub161 = 161,
- kStub162 = 162,
+ kExitScreen = 162,
kStub163 = 163,
kStub164 = 164,
kStub165 = 165,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index cbf107c2f8f..54f26e55307 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -104,6 +104,7 @@ private:
void stub203();
void stub206();
void enableUser();
+ void exitScreen();
void suspend(ProcessExitCode exitCode) {
if (_status == kStatusActive)
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index 2c68b61fc56..545d74cc27e 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -27,7 +27,8 @@ namespace AGDS {
enum ProcessExitCode {
kExitCodeDestroy = 2,
- kExitCodeLoadScreenObject = 8
+ kExitCodeLoadScreenObject = 8,
+ kExitCodeExitScreen = 15
};
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index a1efba82de6..cc592b700dc 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -165,7 +165,12 @@ void Process::stub206() {
debug("stub206 (mouse?) %d %d", arg1, arg2);
}
-
+void Process::exitScreen()
+{
+ debug("stubExit15");
+ _status = kStatusDone;
+ _exitCode = kExitCodeExitScreen;
+}
void Process::onKey(unsigned size) {
Common::String key = popString();
@@ -228,6 +233,7 @@ ProcessExitCode Process::execute() {
OP (kAppendToSharedStorage, appendToSharedStorage);
OP (kLoadPicture, loadPicture);
OP (kProcessCleanupStub128, stub128);
+ OP (kExitScreen, exitScreen);
OP (kStub182, stub182);
OP (kLoadFont, loadFont);
OP_U (kStub202ScreenHandler, stub202);
Commit: 60268178ae6c2844e8a41a70738ee6dc51a14f3e
https://github.com/scummvm/scummvm/commit/60268178ae6c2844e8a41a70738ee6dc51a14f3e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:47+01:00
Commit Message:
AGDS: return empty string from getString(-1), as it's always the case so far
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 22ddbd56570..32d56c437ef 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -41,7 +41,9 @@ int32 Process::pop() {
}
Common::String Process::getString(int id) {
- if (id <= -2 && id > -12)
+ if (id == -1)
+ return Common::String();
+ else if (id <= -2 && id > -12)
return _engine->getSharedStorage(id);
else
return _object->getString(id).string;
Commit: 3f310e8689a9a631de116baee53c483f98fb4266
https://github.com/scummvm/scummvm/commit/3f310e8689a9a631de116baee53c483f98fb4266
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:47+01:00
Commit Message:
AGDS: added suspendProcess, and findObjectInMouseArea stubs
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index f3ab4971bba..ce70a46d37d 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -32,7 +32,7 @@ enum Opcode {
kPop = 10,
kStub11 = 11,
kExitProcess = 12,
- kExitProcess5 = 13,
+ kSuspendProcess = 13,
kStub14 = 14,
kPushImm16 = 15,
kPushImm8 = 16,
@@ -222,7 +222,7 @@ enum Opcode {
kStub202ScreenHandler = 202,
kPlayFilm = 203,
kStub204 = 204,
- kStub205 = 205,
+ kFindObjectInMouseArea = 205,
kStub206 = 206,
kStub207 = 207,
kStub208 = 208,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 54f26e55307..addecea01fa 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -82,29 +82,35 @@ private:
}
void enter(uint16 magic, uint16 size);
+ void exitProcess();
+ void suspendProcess();
+ void exitScreen();
+
void clearScreen();
- void setSystemVariable();
- void getGlobal(unsigned index);
- void setGlobal();
void loadPicture();
void loadMouse();
- void appendToSharedStorage();
void loadScreenObject();
- void removeScreenObject();
void loadFont();
+ void removeScreenObject();
+ void changeScreenPatch();
+
+ void setSystemVariable();
void setIntegerVariable();
- void exitProcess();
+ void getGlobal(unsigned index);
+ void setGlobal();
+ void appendToSharedStorage();
+ void findObjectInMouseArea();
+
+ void enableUser();
void onKey(unsigned size);
void stub98();
void stub128();
- void changeScreenPatch();
void stub182();
void stub202(unsigned size);
void stub203();
void stub206();
- void enableUser();
- void exitScreen();
+
void suspend(ProcessExitCode exitCode) {
if (_status == kStatusActive)
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index 545d74cc27e..ad612f1cece 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -26,9 +26,10 @@
namespace AGDS {
enum ProcessExitCode {
- kExitCodeDestroy = 2,
- kExitCodeLoadScreenObject = 8,
- kExitCodeExitScreen = 15
+ kExitCodeDestroy = 2,
+ kExitCodeSuspend = 5,
+ kExitCodeLoadScreenObject = 8,
+ kExitCodeExitScreen = 15
};
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index cc592b700dc..b67ecd013f8 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -172,6 +172,13 @@ void Process::exitScreen()
_exitCode = kExitCodeExitScreen;
}
+void Process::suspendProcess()
+{
+ debug("suspendProcess");
+ _status = kStatusPassive;
+ _exitCode = kExitCodeSuspend;
+}
+
void Process::onKey(unsigned size) {
Common::String key = popString();
debug("onKey %s handler, %u instructions", key.c_str(), size);
@@ -183,7 +190,14 @@ void Process::enableUser() {
debug("enableUser");
}
+void Process::findObjectInMouseArea() {
+ Common::String arg3 = popString();
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("findObjectInMouseArea %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
+ push(0);
+}
//fixme: add trace here
#define OP(NAME, METHOD) \
@@ -215,6 +229,7 @@ ProcessExitCode Process::execute() {
OP_W (kJumpZImm16, jumpz);
OP (kPop, pop);
OP (kExitProcess, exitProcess);
+ OP (kSuspendProcess, suspendProcess);
OP_C (kPushImm8, push);
OP_W (kPushImm16, push);
OP_C (kPushImm8_2, push);
@@ -238,10 +253,11 @@ ProcessExitCode Process::execute() {
OP (kLoadFont, loadFont);
OP_U (kStub202ScreenHandler, stub202);
OP (kPlayFilm, stub203);
+ OP (kFindObjectInMouseArea, findObjectInMouseArea);
OP (kStub206, stub206);
OP_U (kOnKey, onKey);
default:
- debug("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _ip - 1, (unsigned)op, (unsigned)op);
+ error("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _ip - 1, (unsigned)op, (unsigned)op);
_status = kStatusError;
break;
}
Commit: 2877c1461dc8d6cb1d4884819604abd28a9f54de
https://github.com/scummvm/scummvm/commit/2877c1461dc8d6cb1d4884819604abd28a9f54de
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:47+01:00
Commit Message:
AGDS: added 16 new instructions
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 274ad59f792..7924c851372 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -82,6 +82,7 @@ ProcessExitCode AGDSEngine::loadObject(const Common::String & name) {
code = process.execute();
switch(code) {
case kExitCodeLoadScreenObject:
+ case kExitCodeDestroyProcessSetNextScreen:
debug("loading screen object...");
code = loadObject(process.getExitValue());
break;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 415b6d2a535..b7a9f960bfc 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -61,6 +61,8 @@ private:
void setGlobal(const Common::String &name, int value)
{ _globals.setVal(name, value); }
int getGlobal(const Common::String &name) const;
+ bool hasGlobal(const Common::String &name) const
+ { return _globals.find(name) != _globals.end(); }
private:
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index ce70a46d37d..7246d97e60e 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -41,8 +41,8 @@ enum Opcode {
kStub19 = 19,
kStub20 = 20,
kGetGlobalImm8 = 21,
- kStub22 = 22,
- kStub23 = 23,
+ kEquals = 22,
+ kNotEquals = 23,
kStub24 = 24,
kStub25 = 25,
kStub26 = 26,
@@ -55,12 +55,12 @@ enum Opcode {
kStub33 = 33,
kStub34 = 34,
kStub35 = 35,
- kStub36 = 36,
+ kNot = 36,
kStub37 = 37,
kStub38 = 38,
- kStub39 = 39,
- kStub40 = 40,
- kStub41 = 41,
+ kBoolAnd = 39,
+ kBoolOr = 40,
+ kBoolNot = 41,
kStub42 = 42,
kStub43 = 43,
kStub44 = 44,
@@ -78,7 +78,7 @@ enum Opcode {
kStub56 = 56,
kStub57 = 57,
kStub58 = 58,
- kStub59 = 59,
+ kCall = 59,
kStub60 = 60,
kStub61 = 61,
kStub62 = 62,
@@ -87,17 +87,17 @@ enum Opcode {
kStub65 = 65,
kStub66 = 66,
kStub68 = 68,
- kStub69 = 69,
- kStub70 = 70,
+ kLoadPictureFromObject = 69,
+ kLoadAnimationFromObject = 70,
kStub71 = 71,
- kStub72 = 72,
+ kUpdateScreenHeightToDisplay = 72,
kStub73 = 73,
kStub74 = 74,
kStub75 = 75,
kScreenLoadObject = 76,
kStub77 = 77,
kScreenRemoveObject = 78,
- kStub79 = 79,
+ kExitProcessSetNextScreen = 79,
kStub80 = 80,
kStub82 = 82,
kStub83 = 83,
@@ -134,8 +134,8 @@ enum Opcode {
kStub114 = 114,
kStub115 = 115,
kStub116 = 116,
- kStub117 = 117,
- kStub118 = 118,
+ kLoadAnimation = 117,
+ kLoadSample = 118,
kStub119 = 119,
kStub120 = 120,
kStub121 = 121,
@@ -144,7 +144,7 @@ enum Opcode {
kStub124 = 124,
kStub125 = 125,
kStub126 = 126,
- kStub127 = 127,
+ kSetCounter = 127,
kProcessCleanupStub128 = 128,
kStub129 = 129,
kStub130 = 130,
@@ -186,7 +186,7 @@ enum Opcode {
kStub166 = 166,
kStub167 = 167,
kStub168 = 168,
- kStub169 = 169,
+ kGetIntegerSystemVariable = 169,
kStub170 = 170,
kStub171 = 171,
kStub172 = 172,
@@ -259,7 +259,7 @@ enum Opcode {
kStub239 = 239,
kStub240 = 240,
kStub241 = 241,
- kStub242 = 242,
+ kHasGlobal = 242,
kStub243 = 243,
kStub244 = 244,
kStub245 = 245,
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 32d56c437ef..b35a4fd4da6 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -26,8 +26,8 @@
namespace AGDS {
-Process::Process(AGDSEngine *engine, Object* object) :
- _engine(engine), _object(object), _ip(0), _status(kStatusActive), _exitCode(kExitCodeDestroy) {
+Process::Process(AGDSEngine *engine, Object* object, unsigned ip) :
+ _engine(engine), _object(object), _ip(ip), _status(kStatusActive), _exitCode(kExitCodeDestroy) {
}
void Process::push(int32 value) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index addecea01fa..62e14e51fe7 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -85,6 +85,7 @@ private:
void exitProcess();
void suspendProcess();
void exitScreen();
+ void call(uint16 addr);
void clearScreen();
void loadPicture();
@@ -93,23 +94,51 @@ private:
void loadFont();
void removeScreenObject();
void changeScreenPatch();
+ void updateScreenHeightToDisplay();
+ void findObjectInMouseArea();
+ void loadPictureFromObject();
+ void loadAnimationFromObject();
+ void loadAnimation();
+ void loadSample();
+ void setCounter();
void setSystemVariable();
+ void getIntegerSystemVariable();
void setIntegerVariable();
void getGlobal(unsigned index);
void setGlobal();
+ void hasGlobal();
void appendToSharedStorage();
- void findObjectInMouseArea();
void enableUser();
void onKey(unsigned size);
void stub98();
void stub128();
+ void stub129();
+ void stub130();
+ void stub133();
+ void stub134();
+ void stub136();
void stub182();
+ void stub188();
void stub202(unsigned size);
void stub203();
void stub206();
+ void exitProcessSetNextScreen();
+
+ void boolNot()
+ { push(!pop()); }
+ void boolOr()
+ { int arg2 = pop(); int arg1 = pop(); push(arg1 || arg2); }
+ void boolAnd()
+ { int arg2 = pop(); int arg1 = pop(); push(arg1 && arg2); }
+ void bitNot()
+ { push(~pop()); }
+ void equals()
+ { push(pop() == pop()); }
+ void notEquals()
+ { push(pop() != pop()); }
void suspend(ProcessExitCode exitCode) {
@@ -119,7 +148,7 @@ private:
}
public:
- Process(AGDSEngine *engine, Object *object);
+ Process(AGDSEngine *engine, Object *object, unsigned ip = 0);
void activate();
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index ad612f1cece..98a61eb0731 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -26,10 +26,11 @@
namespace AGDS {
enum ProcessExitCode {
- kExitCodeDestroy = 2,
- kExitCodeSuspend = 5,
- kExitCodeLoadScreenObject = 8,
- kExitCodeExitScreen = 15
+ kExitCodeDestroy = 2,
+ kExitCodeSuspend = 5,
+ kExitCodeDestroyProcessSetNextScreen = 6,
+ kExitCodeLoadScreenObject = 8,
+ kExitCodeExitScreen = 15
};
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b67ecd013f8..005d7234d99 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -54,12 +54,30 @@ void Process::setSystemVariable() {
}
}
+void Process::getIntegerSystemVariable() {
+ Common::String name = popString();
+ int value = 0;
+ debug("getIntegerSystemVariable: %s -> %d", name.c_str(), value);
+ push(value);
+}
+
+
void Process::loadPicture() {
Common::String name = popString();
debug("loadPicture stub %s", name.c_str());
push(100500); //dummy
}
+void Process::loadAnimation() {
+ Common::String name = popString();
+ debug("loadAnimation %s", name.c_str());
+}
+
+void Process::loadSample() {
+ Common::String name = popString();
+ debug("loadSample %s", name.c_str());
+}
+
void Process::loadScreenObject() {
Common::String name = popString();
debug("loadScreenObject: %s", name.c_str());
@@ -103,6 +121,12 @@ void Process::getGlobal(unsigned index) {
push(value);
}
+void Process::hasGlobal() {
+ Common::String name = popString();
+ int result = _engine->hasGlobal(name)? 1: 0;
+ debug("hasGlobal %s %d", name.c_str(), result);
+ push(result);
+}
void Process::appendToSharedStorage() {
Common::String value = popString();
@@ -130,12 +154,45 @@ void Process::stub128() {
debug("processCleanupStub128");
}
+void Process::stub129() {
+ int value = pop();
+ debug("stub129 %d", value);
+}
+
+void Process::stub130() {
+ int value = pop();
+ debug("stub130 %d", value);
+}
+void Process::stub133() {
+ int pan = pop();
+ int volume = pop();
+ debug("stub133: pan? %d volume? %d", pan, volume);
+}
+
+void Process::stub134() {
+ int arg2 = pop();
+ int arg1 = pop();
+ debug("stub134, font related %d %d", arg1, arg2);
+}
+
+void Process::stub136() {
+ debug("stub136 sets value of stub130 to 1000000000");
+}
+
void Process::stub182() {
int arg2 = pop();
int arg1 = pop();
debug("stub182 %d %d", arg1, arg2);
}
+void Process::stub188() {
+ int arg3 = pop();
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("stub188 %s %s %d", arg1.c_str(), arg2.c_str(), arg3);
+}
+
+
void Process::exitProcess() {
debug("exit");
_status = kStatusDone;
@@ -165,20 +222,39 @@ void Process::stub206() {
debug("stub206 (mouse?) %d %d", arg1, arg2);
}
+void Process::exitProcessSetNextScreen() {
+ _exitValue = popString();
+ _exitCode = kExitCodeDestroyProcessSetNextScreen;
+ _status = kStatusPassive;
+}
+
void Process::exitScreen()
{
- debug("stubExit15");
- _status = kStatusDone;
- _exitCode = kExitCodeExitScreen;
+ debug("exitScreen? reactivating process...");
+ if (_status != kStatusDone)
+ _status = kStatusActive;
}
-void Process::suspendProcess()
-{
+void Process::updateScreenHeightToDisplay() {
+ debug("updateScreenHeightToDisplay");
+}
+
+
+void Process::suspendProcess() {
debug("suspendProcess");
_status = kStatusPassive;
_exitCode = kExitCodeSuspend;
}
+void Process::call(uint16 addr) {
+ debug("call %04x", addr);
+ //original engine just create new process, save exit code in screen object
+ //and on stack, then just ignore return code, fixme?
+ Process callee(_engine, _object, addr);
+ ProcessExitCode code = callee.execute();
+ debug("call returned %d", code);
+}
+
void Process::onKey(unsigned size) {
Common::String key = popString();
debug("onKey %s handler, %u instructions", key.c_str(), size);
@@ -199,6 +275,23 @@ void Process::findObjectInMouseArea() {
push(0);
}
+void Process::loadPictureFromObject() {
+ Common::String name = popString();
+ debug("loadPictureFromObject %s", name.c_str());
+}
+
+void Process::loadAnimationFromObject() {
+ Common::String name = popString();
+ debug("loadAnimationFromObject %s", name.c_str());
+}
+
+void Process::setCounter() {
+ int value = pop();
+ debug("setCounter127 %d", value);
+}
+
+
+
//fixme: add trace here
#define OP(NAME, METHOD) \
case NAME: METHOD (); break
@@ -235,27 +328,49 @@ ProcessExitCode Process::execute() {
OP_C (kPushImm8_2, push);
OP_W (kPushImm16_2, push);
OP_B (kGetGlobalImm8, getGlobal);
+ OP (kEquals, equals);
+ OP (kNotEquals, notEquals);
OP (kSetGlobal, setGlobal);
+ OP (kBoolOr, boolOr);
+ OP (kBoolAnd, boolAnd);
+ OP (kNot, bitNot);
+ OP (kBoolNot, boolNot);
+ OP_U (kCall, call);
+ OP (kLoadPictureFromObject, loadPictureFromObject);
+ OP (kLoadAnimationFromObject, loadAnimationFromObject);
OP (kStub98, stub98);
OP (kEnableUser, enableUser);
OP (kClearScreen, clearScreen);
OP (kLoadMouse, loadMouse);
+ OP (kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay);
OP (kScreenLoadObject, loadScreenObject);
+ OP (kExitProcessSetNextScreen, exitProcessSetNextScreen);
OP (kScreenRemoveObject, removeScreenObject);
+ OP (kLoadAnimation, loadAnimation);
+ OP (kLoadSample, loadSample);
+ OP (kSetCounter, setCounter);
+ OP (kProcessCleanupStub128, stub128);
+ OP (kStub129, stub129);
+ OP (kStub130, stub130);
+ OP (kStub133, stub133);
+ OP (kStub134, stub134);
+ OP (kStub136, stub136);
OP (kScreenChangeScreenPatch, changeScreenPatch);
OP (kSetSystemVariable, setSystemVariable);
OP (kSetIntegerVariable, setIntegerVariable);
+ OP (kGetIntegerSystemVariable, getIntegerSystemVariable);
OP (kAppendToSharedStorage, appendToSharedStorage);
- OP (kLoadPicture, loadPicture);
- OP (kProcessCleanupStub128, stub128);
OP (kExitScreen, exitScreen);
OP (kStub182, stub182);
+ OP (kStub188, stub188);
+ OP (kLoadPicture, loadPicture);
OP (kLoadFont, loadFont);
OP_U (kStub202ScreenHandler, stub202);
OP (kPlayFilm, stub203);
OP (kFindObjectInMouseArea, findObjectInMouseArea);
OP (kStub206, stub206);
OP_U (kOnKey, onKey);
+ OP (kHasGlobal, hasGlobal);
default:
error("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _ip - 1, (unsigned)op, (unsigned)op);
_status = kStatusError;
Commit: b80765dd966cab1c485ba9ba42fe66d70e38f2da
https://github.com/scummvm/scummvm/commit/b80765dd966cab1c485ba9ba42fe66d70e38f2da
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:47+01:00
Commit Message:
AGDS: implemented region stub, do not take ownership of stream
Changed paths:
A engines/agds/region.cpp
A engines/agds/region.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/module.mk
engines/agds/object.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 7924c851372..deaf0dccb4b 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -23,6 +23,7 @@
#include "agds/agds.h"
#include "agds/object.h"
#include "agds/process.h"
+#include "agds/region.h"
#include "common/error.h"
#include "common/ini-file.h"
#include "common/file.h"
@@ -63,6 +64,14 @@ bool AGDSEngine::load() {
return true;
}
+Region * AGDSEngine::loadRegion(const Common::String &name) {
+ debug("loading region %s", name.c_str());
+ Common::SeekableReadStream * stream = _data.getEntry(name);
+ if (!stream)
+ error("no database entry for %s\n", name.c_str());
+ return new Region(name, stream);
+}
+
ProcessExitCode AGDSEngine::loadObject(const Common::String & name) {
debug("loading object %s", name.c_str());
Common::SeekableReadStream * stream = _data.getEntry(name);
@@ -73,6 +82,8 @@ ProcessExitCode AGDSEngine::loadObject(const Common::String & name) {
if (!object)
_objects.setVal(name, object = new Object(name, stream));
+ delete stream;
+
_processes.push_back(Process(this, object));
ProcessExitCode code = kExitCodeDestroy;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index b7a9f960bfc..019ed9ec0f1 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -42,6 +42,7 @@ namespace AGDS {
class Object;
class Process;
+class Region;
class AGDSEngine : public Engine {
friend class Process;
@@ -55,6 +56,8 @@ public:
private:
bool load();
ProcessExitCode loadObject(const Common::String & name);
+ Region * loadRegion(const Common::String &name);
+
int appendToSharedStorage(const Common::String &value);
const Common::String & getSharedStorage(int id) const;
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index cd0f95ee11f..1bd3eca9bd5 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS := \
object.o \
process.o \
process_opcodes.o \
+ region.o \
resourceManager.o
# This module can be built as a plugin
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 9c51b2ab6c6..fa989999d6f 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -39,7 +39,6 @@ Object::Object(const Common::String &name, Common::SeekableReadStream * stream)
debug("object code size %u", codeSize);
_code.resize(codeSize);
stream->read(_code.data(), _code.size());
- delete stream;
}
void Object::readStringTable(unsigned resOffset, uint16 resCount) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 62e14e51fe7..d3c32f538c7 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -101,6 +101,8 @@ private:
void loadAnimation();
void loadSample();
void setCounter();
+ void getRegionWidth();
+ void getRegionHeight();
void setSystemVariable();
void getIntegerSystemVariable();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 005d7234d99..6625c7f950b 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -23,6 +23,7 @@
#include "agds/process.h"
#include "agds/agds.h"
#include "agds/opcode.h"
+#include "agds/region.h"
#include "common/debug.h"
namespace AGDS {
@@ -61,6 +62,24 @@ void Process::getIntegerSystemVariable() {
push(value);
}
+void Process::getRegionWidth() {
+ Common::String name = popString();
+ Region *reg = _engine->loadRegion(name);
+ int value = reg->width;
+ push(value);
+ delete reg;
+ debug("getRegionWidth %s -> %d", name.c_str(), value);
+}
+
+void Process::getRegionHeight() {
+ Common::String name = popString();
+ Region *reg = _engine->loadRegion(name);
+ int value = reg->width;
+ push(value);
+ delete reg;
+ debug("getRegionHeight %s -> %d", name.c_str(), value);
+}
+
void Process::loadPicture() {
Common::String name = popString();
@@ -358,6 +377,8 @@ ProcessExitCode Process::execute() {
OP (kScreenChangeScreenPatch, changeScreenPatch);
OP (kSetSystemVariable, setSystemVariable);
OP (kSetIntegerVariable, setIntegerVariable);
+ OP (kGetRegionWidth, getRegionWidth);
+ OP (kGetRegionHeight, getRegionHeight);
OP (kGetIntegerSystemVariable, getIntegerSystemVariable);
OP (kAppendToSharedStorage, appendToSharedStorage);
OP (kExitScreen, exitScreen);
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
new file mode 100644
index 00000000000..c23982783c6
--- /dev/null
+++ b/engines/agds/region.cpp
@@ -0,0 +1,50 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/region.h"
+#include "common/debug.h"
+#include "common/textconsole.h"
+#include "common/algorithm.h"
+#include "common/endian.h"
+
+namespace AGDS {
+
+Region::Region(const Common::String &resourceName, Common::SeekableReadStream * stream) {
+ static const int kRegionHeaderSize = 0x26;
+ static const int kRegionHeaderWidthOffset = 0x20;
+ static const int kRegionHeaderHeightOffset = 0x22;
+ static const int kRegionHeaderFlagsOffset = 0x24;
+
+ int size = stream->size();
+ debug("region size %d, data %d", size, size - kRegionHeaderSize);
+ byte header[kRegionHeaderSize];
+ if (stream->read(header, kRegionHeaderSize) != kRegionHeaderSize)
+ error("invalid region %s", resourceName.c_str());
+ byte * nameEnd = Common::find(header, header + 0x20, 0);
+ name = Common::String(reinterpret_cast<char *>(header), nameEnd - header);
+ width = READ_UINT16(header + kRegionHeaderWidthOffset);
+ height = READ_UINT16(header + kRegionHeaderHeightOffset);
+ flags = READ_UINT16(header + kRegionHeaderFlagsOffset);
+ debug("region %s %dx%d %04x", name.c_str(), width, height, flags);
+}
+
+}
diff --git a/engines/agds/region.h b/engines/agds/region.h
new file mode 100644
index 00000000000..d1b9a5d4146
--- /dev/null
+++ b/engines/agds/region.h
@@ -0,0 +1,42 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_REGION_H
+#define AGDS_REGION_H
+
+#include "common/scummsys.h"
+#include "common/stream.h"
+
+namespace AGDS {
+
+struct Region {
+ Common::String name;
+ uint16 width;
+ uint16 height;
+ uint16 flags;
+ Region(const Common::String &resourceName, Common::SeekableReadStream * stream);
+};
+
+
+} // End of namespace AGDS
+
+#endif /* AGDS_OBJECT_H */
Commit: 33a6cac27cc601398f1860c66f2af1aea301ed06
https://github.com/scummvm/scummvm/commit/33a6cac27cc601398f1860c66f2af1aea301ed06
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:47+01:00
Commit Message:
AGDS: added arithmetic stubs, added setScreenHeight
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 7246d97e60e..433725d2232 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -43,14 +43,14 @@ enum Opcode {
kGetGlobalImm8 = 21,
kEquals = 22,
kNotEquals = 23,
- kStub24 = 24,
- kStub25 = 25,
- kStub26 = 26,
- kStub27 = 27,
- kStub28 = 28,
- kStub29 = 29,
- kStub30 = 30,
- kStub31 = 31,
+ kGreater = 24,
+ kLess = 25,
+ kGreaterOrEquals = 26,
+ kLessOrEquals = 27,
+ kAdd = 28,
+ kSub = 29,
+ kMul = 30,
+ kDiv = 31,
kStub32 = 32,
kStub33 = 33,
kStub34 = 34,
@@ -89,7 +89,7 @@ enum Opcode {
kStub68 = 68,
kLoadPictureFromObject = 69,
kLoadAnimationFromObject = 70,
- kStub71 = 71,
+ kSetScreenHeight = 71,
kUpdateScreenHeightToDisplay = 72,
kStub73 = 73,
kStub74 = 74,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index d3c32f538c7..5d38d5eee20 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -94,6 +94,7 @@ private:
void loadFont();
void removeScreenObject();
void changeScreenPatch();
+ void setScreenHeight();
void updateScreenHeightToDisplay();
void findObjectInMouseArea();
void loadPictureFromObject();
@@ -122,6 +123,7 @@ private:
void stub133();
void stub134();
void stub136();
+ void stub165();
void stub182();
void stub188();
void stub202(unsigned size);
@@ -129,18 +131,26 @@ private:
void stub206();
void exitProcessSetNextScreen();
- void boolNot()
- { push(!pop()); }
- void boolOr()
- { int arg2 = pop(); int arg1 = pop(); push(arg1 || arg2); }
- void boolAnd()
- { int arg2 = pop(); int arg1 = pop(); push(arg1 && arg2); }
- void bitNot()
- { push(~pop()); }
- void equals()
- { push(pop() == pop()); }
- void notEquals()
- { push(pop() != pop()); }
+#define UNARY_OP(NAME, OP) void NAME () { push( OP pop() ); }
+#define BINARY_OP(NAME, OP) void NAME () { int arg2 = pop(); int arg1 = pop(); push(arg1 OP arg2); }
+
+ UNARY_OP(boolNot, !)
+ UNARY_OP(bitNot, ~)
+ BINARY_OP(boolOr, ||)
+ BINARY_OP(boolAnd, &&)
+ BINARY_OP(equals, ==)
+ BINARY_OP(notEquals, !=)
+ BINARY_OP(greater, >)
+ BINARY_OP(greaterOrEquals, >=)
+ BINARY_OP(less, <)
+ BINARY_OP(lessOrEquals, <=)
+ BINARY_OP(add, +)
+ BINARY_OP(sub, +)
+ BINARY_OP(mul, *)
+ BINARY_OP(div, /)
+
+#undef UNARY_OP
+#undef BINARY_OP
void suspend(ProcessExitCode exitCode) {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 6625c7f950b..08d9674e960 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -222,6 +222,14 @@ void Process::clearScreen() {
debug("clearScreen");
}
+void Process::stub165() {
+ int arg3 = pop();
+ int arg2 = pop();
+ Common::String arg1 = popString();
+ debug("stub165 %s %d %d", arg1.c_str(), arg2, arg3);
+}
+
+
void Process::stub202(unsigned size) {
debug("stub203, %u instructions", size);
_ip += size;
@@ -254,6 +262,11 @@ void Process::exitScreen()
_status = kStatusActive;
}
+void Process::setScreenHeight() {
+ int height = pop();
+ debug("setScreenHeight %d", height);
+}
+
void Process::updateScreenHeightToDisplay() {
debug("updateScreenHeightToDisplay");
}
@@ -349,6 +362,14 @@ ProcessExitCode Process::execute() {
OP_B (kGetGlobalImm8, getGlobal);
OP (kEquals, equals);
OP (kNotEquals, notEquals);
+ OP (kGreater, greater);
+ OP (kLess, less);
+ OP (kGreaterOrEquals, greaterOrEquals);
+ OP (kLessOrEquals, lessOrEquals);
+ OP (kAdd, add);
+ OP (kSub, sub);
+ OP (kMul, mul);
+ OP (kDiv, div);
OP (kSetGlobal, setGlobal);
OP (kBoolOr, boolOr);
OP (kBoolAnd, boolAnd);
@@ -361,6 +382,7 @@ ProcessExitCode Process::execute() {
OP (kEnableUser, enableUser);
OP (kClearScreen, clearScreen);
OP (kLoadMouse, loadMouse);
+ OP (kSetScreenHeight, setScreenHeight);
OP (kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay);
OP (kScreenLoadObject, loadScreenObject);
OP (kExitProcessSetNextScreen, exitProcessSetNextScreen);
@@ -382,6 +404,7 @@ ProcessExitCode Process::execute() {
OP (kGetIntegerSystemVariable, getIntegerSystemVariable);
OP (kAppendToSharedStorage, appendToSharedStorage);
OP (kExitScreen, exitScreen);
+ OP (kStub165, stub165);
OP (kStub182, stub182);
OP (kStub188, stub188);
OP (kLoadPicture, loadPicture);
Commit: f089f28026f114a5ee7b561561201a7e315a07bf
https://github.com/scummvm/scummvm/commit/f089f28026f114a5ee7b561561201a7e315a07bf
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:47+01:00
Commit Message:
AGDS: removed noisy resource block logs, port it to debug channels later
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index fa989999d6f..c8b22a20a83 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -49,7 +49,7 @@ void Object::readStringTable(unsigned resOffset, uint16 resCount) {
if (resOffset >= _code.size())
error("invalid resource table offset");
- debug("resource table at %08x", resOffset);
+ //debug("resource table at %08x", resOffset);
Common::MemoryReadStream stream(_code.data() + resOffset, _code.size() - resOffset);
for(uint16 i = 0; i < resCount; ++i) {
uint16 offset = stream.readUint16LE();
@@ -65,7 +65,7 @@ void Object::readStringTable(unsigned resOffset, uint16 resCount) {
Common::String name(nameBegin, nameEnd - nameBegin);
- debug("resource table 1[%04u]: 0x%04x %s", i, flags, name.c_str());
+ //debug("resource table 1[%04u]: 0x%04x %s", i, flags, name.c_str());
_stringTable[i] = StringEntry(name, flags);
}
_stringTableLoaded = true;
Commit: be1582ef1386883374ba733e99c633e0a9782f44
https://github.com/scummvm/scummvm/commit/be1582ef1386883374ba733e99c633e0a9782f44
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:47+01:00
Commit Message:
AGDS: do not restart process for loaded objects
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index deaf0dccb4b..7e46b892d0e 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -81,6 +81,8 @@ ProcessExitCode AGDSEngine::loadObject(const Common::String & name) {
Object *object = i != _objects.end()? i->_value: NULL;
if (!object)
_objects.setVal(name, object = new Object(name, stream));
+ else
+ return kExitCodeDestroy;
delete stream;
Commit: 4c70bcc6a3dcb6e4886ac028f66da7fa9fb91ca4
https://github.com/scummvm/scummvm/commit/4c70bcc6a3dcb6e4886ac028f66da7fa9fb91ca4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:47+01:00
Commit Message:
AGDS: load object from stub165
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 08d9674e960..ecad2a0a319 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -227,6 +227,7 @@ void Process::stub165() {
int arg2 = pop();
Common::String arg1 = popString();
debug("stub165 %s %d %d", arg1.c_str(), arg2, arg3);
+ _engine->loadObject(arg1);
}
Commit: cc1f301ce3feff8177e14398e501859343383a1d
https://github.com/scummvm/scummvm/commit/cc1f301ce3feff8177e14398e501859343383a1d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:48+01:00
Commit Message:
AGDS: load object and region from findObjectInMouseArea
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index ecad2a0a319..d53689b0ff9 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -305,6 +305,9 @@ void Process::findObjectInMouseArea() {
Common::String arg1 = popString();
debug("findObjectInMouseArea %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
+ _engine->loadRegion(arg1);
+ _engine->loadObject(arg2);
+ _engine->loadObject(arg3);
push(0);
}
Commit: 63215e133330ce3c0c02bdb83d4f5f7011c4ea04
https://github.com/scummvm/scummvm/commit/63215e133330ce3c0c02bdb83d4f5f7011c4ea04
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:48+01:00
Commit Message:
AGDS: added a few more stubs
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 433725d2232..d668e6b3035 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -78,15 +78,15 @@ enum Opcode {
kStub56 = 56,
kStub57 = 57,
kStub58 = 58,
- kCall = 59,
+ kCallImm16 = 59,
kStub60 = 60,
- kStub61 = 61,
+ kObjectRegisterUseHandler = 61,
kStub62 = 62,
kStub63 = 63,
kStub64 = 64,
kStub65 = 65,
kStub66 = 66,
- kStub68 = 68,
+ kLoadRegionFromObject = 68,
kLoadPictureFromObject = 69,
kLoadAnimationFromObject = 70,
kSetScreenHeight = 71,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 5d38d5eee20..01d922fcad4 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -97,6 +97,7 @@ private:
void setScreenHeight();
void updateScreenHeightToDisplay();
void findObjectInMouseArea();
+ void loadRegionFromObject();
void loadPictureFromObject();
void loadAnimationFromObject();
void loadAnimation();
@@ -115,7 +116,9 @@ private:
void enableUser();
void onKey(unsigned size);
+ void onUse(unsigned size);
+ void loadMouseStub66();
void stub98();
void stub128();
void stub129();
@@ -126,6 +129,7 @@ private:
void stub165();
void stub182();
void stub188();
+ void stub190();
void stub202(unsigned size);
void stub203();
void stub206();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d53689b0ff9..8c9f11d1833 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -169,6 +169,12 @@ void Process::changeScreenPatch() {
push(0);
}
+void Process::loadMouseStub66() {
+ Common::String name = popString();
+ debug("loadMouseStub66 %s", name.c_str());
+}
+
+
void Process::stub128() {
debug("processCleanupStub128");
}
@@ -230,6 +236,10 @@ void Process::stub165() {
_engine->loadObject(arg1);
}
+void Process::stub190() {
+ int value = pop();
+ debug("stub190 %d", value);
+}
void Process::stub202(unsigned size) {
debug("stub203, %u instructions", size);
@@ -294,6 +304,12 @@ void Process::onKey(unsigned size) {
_ip += size;
}
+void Process::onUse(unsigned size) {
+ debug("use? handler, %u instructions", size);
+ _ip += size;
+}
+
+
void Process::enableUser() {
//screen loading block user interaction until this instruction
debug("enableUser");
@@ -305,12 +321,21 @@ void Process::findObjectInMouseArea() {
Common::String arg1 = popString();
debug("findObjectInMouseArea %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
- _engine->loadRegion(arg1);
+ Region *reg = _engine->loadRegion(arg1);
_engine->loadObject(arg2);
_engine->loadObject(arg3);
+ delete reg;
push(0);
}
+void Process::loadRegionFromObject() {
+ Common::String name = popString();
+ debug("loadRegionFromObject %s", name.c_str());
+ Region *reg = _engine->loadRegion(name);
+ delete reg;
+}
+
+
void Process::loadPictureFromObject() {
Common::String name = popString();
debug("loadPictureFromObject %s", name.c_str());
@@ -379,7 +404,10 @@ ProcessExitCode Process::execute() {
OP (kBoolAnd, boolAnd);
OP (kNot, bitNot);
OP (kBoolNot, boolNot);
- OP_U (kCall, call);
+ OP_U (kCallImm16, call);
+ OP_U (kObjectRegisterUseHandler, onUse);
+ OP (kStub66, loadMouseStub66);
+ OP (kLoadRegionFromObject, loadRegionFromObject);
OP (kLoadPictureFromObject, loadPictureFromObject);
OP (kLoadAnimationFromObject, loadAnimationFromObject);
OP (kStub98, stub98);
@@ -411,6 +439,7 @@ ProcessExitCode Process::execute() {
OP (kStub165, stub165);
OP (kStub182, stub182);
OP (kStub188, stub188);
+ OP (kStub190, stub190);
OP (kLoadPicture, loadPicture);
OP (kLoadFont, loadFont);
OP_U (kStub202ScreenHandler, stub202);
Commit: 7a850fd007146e46d426c447774ca322824b140f
https://github.com/scummvm/scummvm/commit/7a850fd007146e46d426c447774ca322824b140f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:48+01:00
Commit Message:
AGDS: removed execution of object code in findObject
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 8c9f11d1833..cb5645d167d 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -322,8 +322,8 @@ void Process::findObjectInMouseArea() {
debug("findObjectInMouseArea %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
Region *reg = _engine->loadRegion(arg1);
- _engine->loadObject(arg2);
- _engine->loadObject(arg3);
+ //_engine->loadObject(arg2);
+ //_engine->loadObject(arg3);
delete reg;
push(0);
}
Commit: 16e254dd4a75a94130b0988aa70e7f7c09e850a1
https://github.com/scummvm/scummvm/commit/16e254dd4a75a94130b0988aa70e7f7c09e850a1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:48+01:00
Commit Message:
AGDS: fixed copy-pasted typo in getRegionHeight
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index cb5645d167d..936b019223f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -74,7 +74,7 @@ void Process::getRegionWidth() {
void Process::getRegionHeight() {
Common::String name = popString();
Region *reg = _engine->loadRegion(name);
- int value = reg->width;
+ int value = reg->height;
push(value);
delete reg;
debug("getRegionHeight %s -> %d", name.c_str(), value);
Commit: d7557d72da18a72669ec3fea30b8965c25a3f4ec
https://github.com/scummvm/scummvm/commit/d7557d72da18a72669ec3fea30b8965c25a3f4ec
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:48+01:00
Commit Message:
AGDS: added extended region data parsing
Changed paths:
engines/agds/region.cpp
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index c23982783c6..8adcfb9e824 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -45,6 +45,18 @@ Region::Region(const Common::String &resourceName, Common::SeekableReadStream *
height = READ_UINT16(header + kRegionHeaderHeightOffset);
flags = READ_UINT16(header + kRegionHeaderFlagsOffset);
debug("region %s %dx%d %04x", name.c_str(), width, height, flags);
+ if (size > kRegionHeaderSize) {
+ uint16 ext = stream->readUint16LE();
+ debug("extended entries %u", ext);
+ while(ext--) {
+ int16 a = stream->readSint16LE();
+ int16 b = stream->readSint16LE();
+ uint16 c = stream->readUint16LE();
+ debug("extended entry: %d %d %04x", a, b, c);
+ }
+ if (stream->pos() != size)
+ debug("region data left: %u", size - stream->pos());
+ }
}
}
Commit: a8b7bc027c40b2483f8fd258b3f84b3fbf3f9f6f
https://github.com/scummvm/scummvm/commit/a8b7bc027c40b2483f8fd258b3f84b3fbf3f9f6f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:48+01:00
Commit Message:
AGDS: resume after suspend
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 7e46b892d0e..15d4e72f7d4 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -99,6 +99,9 @@ ProcessExitCode AGDSEngine::loadObject(const Common::String & name) {
debug("loading screen object...");
code = loadObject(process.getExitValue());
break;
+ case kExitCodeSuspend:
+ debug("nop, waking up");
+ break;
default:
debug("destroying process...");
_processes.pop_back();
Commit: 7c8966c64ad37e1e8f11e8f7fdba3fe9b0b1c484
https://github.com/scummvm/scummvm/commit/7c8966c64ad37e1e8f11e8f7fdba3fe9b0b1c484
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:48+01:00
Commit Message:
AGDS: added fadeObject, jumpImm16 and a few stubs
Changed paths:
engines/agds/object.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 2fa4d621714..315b5242550 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -57,6 +57,9 @@ public:
void readStringTable(unsigned resOffset, uint16 resCount);
const StringEntry & getString(uint16 index) const;
+ uint getStringTableSize() const
+ { return _stringTable.size(); }
+
const Common::String & getName() const
{ return _name; }
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index d668e6b3035..c082bace3f3 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -28,7 +28,7 @@ namespace AGDS {
enum Opcode {
kEnter = 5,
kJumpZImm16 = 8,
- kStub9 = 9,
+ kJumpImm16 = 9,
kPop = 10,
kStub11 = 11,
kExitProcess = 12,
@@ -69,7 +69,7 @@ enum Opcode {
kStub47 = 47,
kSetGlobal = 48,
kStub49 = 49,
- kStub50 = 50,
+ kIncrementGlobal = 50,
kStub51 = 51,
kStub52 = 52,
kStub53 = 53,
@@ -243,7 +243,7 @@ enum Opcode {
kStub223 = 223,
kStub224 = 224,
kStub225 = 225,
- kStub226 = 226,
+ kFadeObject = 226,
kLoadFont = 227,
kStub228 = 228,
kOnKey = 229,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 01d922fcad4..123053aa301 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -105,6 +105,7 @@ private:
void setCounter();
void getRegionWidth();
void getRegionHeight();
+ void fadeObject();
void setSystemVariable();
void getIntegerSystemVariable();
@@ -112,6 +113,7 @@ private:
void getGlobal(unsigned index);
void setGlobal();
void hasGlobal();
+ void incrementGlobal();
void appendToSharedStorage();
void enableUser();
@@ -130,6 +132,8 @@ private:
void stub182();
void stub188();
void stub190();
+ void stub195();
+ void stub196();
void stub202(unsigned size);
void stub203();
void stub206();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 936b019223f..c1aa5f544eb 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -147,6 +147,12 @@ void Process::hasGlobal() {
push(result);
}
+void Process::incrementGlobal() {
+ Common::String name = popString();
+ debug("increment global %s", name.c_str());
+ _engine->setGlobal(name, _engine->getGlobal(name) + 1);
+}
+
void Process::appendToSharedStorage() {
Common::String value = popString();
int index = _engine->appendToSharedStorage(value);
@@ -174,6 +180,12 @@ void Process::loadMouseStub66() {
debug("loadMouseStub66 %s", name.c_str());
}
+void Process::fadeObject() {
+ int arg = pop();
+ Common::String name = popString();
+ debug("fadeObject %s %d", name.c_str(), arg);
+}
+
void Process::stub128() {
debug("processCleanupStub128");
@@ -241,6 +253,20 @@ void Process::stub190() {
debug("stub190 %d", value);
}
+void Process::stub195() {
+ Common::String value = popString();
+ debug("stub195 %s", value.c_str());
+ _engine->loadObject(value);
+ push(195);
+}
+
+void Process::stub196() {
+ Common::String value = popString();
+ debug("stub196 %s", value.c_str());
+ _engine->loadObject(value);
+ push(196);
+}
+
void Process::stub202(unsigned size) {
debug("stub203, %u instructions", size);
_ip += size;
@@ -381,6 +407,7 @@ ProcessExitCode Process::execute() {
switch(op) {
OP_UU (kEnter, enter);
OP_W (kJumpZImm16, jumpz);
+ OP_W (kJumpImm16, jump);
OP (kPop, pop);
OP (kExitProcess, exitProcess);
OP (kSuspendProcess, suspendProcess);
@@ -389,6 +416,7 @@ ProcessExitCode Process::execute() {
OP_C (kPushImm8_2, push);
OP_W (kPushImm16_2, push);
OP_B (kGetGlobalImm8, getGlobal);
+ OP (kIncrementGlobal, incrementGlobal);
OP (kEquals, equals);
OP (kNotEquals, notEquals);
OP (kGreater, greater);
@@ -440,7 +468,10 @@ ProcessExitCode Process::execute() {
OP (kStub182, stub182);
OP (kStub188, stub188);
OP (kStub190, stub190);
+ OP (kStub195, stub195);
+ OP (kStub196, stub196);
OP (kLoadPicture, loadPicture);
+ OP (kFadeObject, fadeObject);
OP (kLoadFont, loadFont);
OP_U (kStub202ScreenHandler, stub202);
OP (kPlayFilm, stub203);
Commit: 6ca4b1c969d858e724e508917d62e64508bc2bba
https://github.com/scummvm/scummvm/commit/6ca4b1c969d858e724e508917d62e64508bc2bba
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:48+01:00
Commit Message:
AGDS: added incrementGlobal + dumping unary/binary ops results
Changed paths:
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 123053aa301..bcf45020641 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -27,6 +27,7 @@
#include "agds/processExitCode.h"
#include "common/scummsys.h"
#include "common/stack.h"
+#include "common/debug.h"
namespace AGDS {
@@ -139,8 +140,8 @@ private:
void stub206();
void exitProcessSetNextScreen();
-#define UNARY_OP(NAME, OP) void NAME () { push( OP pop() ); }
-#define BINARY_OP(NAME, OP) void NAME () { int arg2 = pop(); int arg1 = pop(); push(arg1 OP arg2); }
+#define UNARY_OP(NAME, OP) void NAME () { int arg = pop(); debug(#NAME " %d", arg); push( OP arg ); }
+#define BINARY_OP(NAME, OP) void NAME () { int arg2 = pop(); int arg1 = pop(); debug(#NAME " %d " #OP " %d", arg1, arg2); push(arg1 OP arg2); }
UNARY_OP(boolNot, !)
UNARY_OP(bitNot, ~)
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c1aa5f544eb..935c18dcf45 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -149,8 +149,10 @@ void Process::hasGlobal() {
void Process::incrementGlobal() {
Common::String name = popString();
- debug("increment global %s", name.c_str());
- _engine->setGlobal(name, _engine->getGlobal(name) + 1);
+ int value = _engine->getGlobal(name);
+ debug("increment global %s %d", name.c_str(), value);
+ push(value);
+ _engine->setGlobal(name, value + 1);
}
void Process::appendToSharedStorage() {
Commit: f97ddb713e6334fcf829f8d3df5c41d9177f16cf
https://github.com/scummvm/scummvm/commit/f97ddb713e6334fcf829f8d3df5c41d9177f16cf
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:48+01:00
Commit Message:
AGDS: push(opcode) instead of stub 0
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 935c18dcf45..91d99aef087 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -174,7 +174,7 @@ void Process::changeScreenPatch() {
res1 = getString(index);
//change screen patch
debug("stub140: %d '%s' '%s'", index, res1.c_str(), res2.c_str());
- push(0);
+ push(140);
}
void Process::loadMouseStub66() {
@@ -353,7 +353,7 @@ void Process::findObjectInMouseArea() {
//_engine->loadObject(arg2);
//_engine->loadObject(arg3);
delete reg;
- push(0);
+ push(205);
}
void Process::loadRegionFromObject() {
Commit: a7fd9f3e08ca805a4b6d960238a008fb73b90316
https://github.com/scummvm/scummvm/commit/a7fd9f3e08ca805a4b6d960238a008fb73b90316
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:48+01:00
Commit Message:
AGDS: copy-paste ninja was here
Changed paths:
engines/agds/process.h
diff --git a/engines/agds/process.h b/engines/agds/process.h
index bcf45020641..0cec4454354 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -154,7 +154,7 @@ private:
BINARY_OP(less, <)
BINARY_OP(lessOrEquals, <=)
BINARY_OP(add, +)
- BINARY_OP(sub, +)
+ BINARY_OP(sub, -)
BINARY_OP(mul, *)
BINARY_OP(div, /)
Commit: 2b410cce9fafe5c5ab01f6b89f053fb7cacdd16d
https://github.com/scummvm/scummvm/commit/2b410cce9fafe5c5ab01f6b89f053fb7cacdd16d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:49+01:00
Commit Message:
AGDS: added Process:top()
Changed paths:
engines/agds/process.cpp
engines/agds/process.h
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index b35a4fd4da6..5b746bb437e 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -40,6 +40,12 @@ int32 Process::pop() {
return _stack.pop();
}
+int32 Process::top() {
+ if (_stack.empty())
+ error("stack underflow, ip: %08x", _ip);
+ return _stack.top();
+}
+
Common::String Process::getString(int id) {
if (id == -1)
return Common::String();
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 0cec4454354..628551d4c38 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -66,6 +66,7 @@ private:
void push(int32 value);
int32 pop();
+ int32 top();
void jump(int delta)
{ _ip += delta; }
Commit: d42b92505768d61b1232bef77d572d2b5b7b2660
https://github.com/scummvm/scummvm/commit/d42b92505768d61b1232bef77d572d2b5b7b2660
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:49+01:00
Commit Message:
AGDS: fixed increment/decrement global opcodes
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index c082bace3f3..cc0bd030e7f 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -64,12 +64,12 @@ enum Opcode {
kStub42 = 42,
kStub43 = 43,
kStub44 = 44,
- kStub45 = 45,
+ kPostIncrementGlobal = 45,
kStub46 = 46,
kStub47 = 47,
kSetGlobal = 48,
kStub49 = 49,
- kIncrementGlobal = 50,
+ kDecrementGlobalByTop = 50,
kStub51 = 51,
kStub52 = 52,
kStub53 = 53,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 628551d4c38..708b92e7921 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -115,7 +115,9 @@ private:
void getGlobal(unsigned index);
void setGlobal();
void hasGlobal();
- void incrementGlobal();
+ void postIncrementGlobal();
+ void decrementGlobal(int value);
+ void decrementGlobalByTop() { decrementGlobal(top()); }
void appendToSharedStorage();
void enableUser();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 91d99aef087..109d2ac2210 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -147,7 +147,7 @@ void Process::hasGlobal() {
push(result);
}
-void Process::incrementGlobal() {
+void Process::postIncrementGlobal() {
Common::String name = popString();
int value = _engine->getGlobal(name);
debug("increment global %s %d", name.c_str(), value);
@@ -155,6 +155,14 @@ void Process::incrementGlobal() {
_engine->setGlobal(name, value + 1);
}
+void Process::decrementGlobal(int dec) {
+ Common::String name = popString();
+ int value = _engine->getGlobal(name);
+ debug("increment global %s %d", name.c_str(), value);
+ _engine->setGlobal(name, value - dec);
+}
+
+
void Process::appendToSharedStorage() {
Common::String value = popString();
int index = _engine->appendToSharedStorage(value);
@@ -257,14 +265,14 @@ void Process::stub190() {
void Process::stub195() {
Common::String value = popString();
- debug("stub195 %s", value.c_str());
+ debug("stub195(getPictureWidth) %s", value.c_str());
_engine->loadObject(value);
push(195);
}
void Process::stub196() {
Common::String value = popString();
- debug("stub196 %s", value.c_str());
+ debug("stub196(getPictureHeight) %s", value.c_str());
_engine->loadObject(value);
push(196);
}
@@ -418,7 +426,8 @@ ProcessExitCode Process::execute() {
OP_C (kPushImm8_2, push);
OP_W (kPushImm16_2, push);
OP_B (kGetGlobalImm8, getGlobal);
- OP (kIncrementGlobal, incrementGlobal);
+ OP (kPostIncrementGlobal, postIncrementGlobal);
+ OP (kDecrementGlobalByTop, decrementGlobalByTop);
OP (kEquals, equals);
OP (kNotEquals, notEquals);
OP (kGreater, greater);
Commit: 4c75dc5b20fabc44d510c3959d7a3b70d2a4707c
https://github.com/scummvm/scummvm/commit/4c75dc5b20fabc44d510c3959d7a3b70d2a4707c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:49+01:00
Commit Message:
AGDS: added incrementGlobalByTop instruction
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index cc0bd030e7f..8e906aa1261 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -68,7 +68,7 @@ enum Opcode {
kStub46 = 46,
kStub47 = 47,
kSetGlobal = 48,
- kStub49 = 49,
+ kIncrementGlobalByTop = 49,
kDecrementGlobalByTop = 50,
kStub51 = 51,
kStub52 = 52,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 708b92e7921..660350b988d 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -116,6 +116,8 @@ private:
void setGlobal();
void hasGlobal();
void postIncrementGlobal();
+ void incrementGlobal(int value);
+ void incrementGlobalByTop() { incrementGlobal(top()); }
void decrementGlobal(int value);
void decrementGlobalByTop() { decrementGlobal(top()); }
void appendToSharedStorage();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 109d2ac2210..0db1e81195e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -155,13 +155,19 @@ void Process::postIncrementGlobal() {
_engine->setGlobal(name, value + 1);
}
-void Process::decrementGlobal(int dec) {
+void Process::incrementGlobal(int inc) {
Common::String name = popString();
int value = _engine->getGlobal(name);
debug("increment global %s %d", name.c_str(), value);
- _engine->setGlobal(name, value - dec);
+ _engine->setGlobal(name, value + inc);
}
+void Process::decrementGlobal(int dec) {
+ Common::String name = popString();
+ int value = _engine->getGlobal(name);
+ debug("decrement global %s %d", name.c_str(), value);
+ _engine->setGlobal(name, value - dec);
+}
void Process::appendToSharedStorage() {
Common::String value = popString();
@@ -427,6 +433,7 @@ ProcessExitCode Process::execute() {
OP_W (kPushImm16_2, push);
OP_B (kGetGlobalImm8, getGlobal);
OP (kPostIncrementGlobal, postIncrementGlobal);
+ OP (kIncrementGlobalByTop, incrementGlobalByTop);
OP (kDecrementGlobalByTop, decrementGlobalByTop);
OP (kEquals, equals);
OP (kNotEquals, notEquals);
Commit: b505fbd4b03635e6b0086c4fb134dd0d8f9219e3
https://github.com/scummvm/scummvm/commit/b505fbd4b03635e6b0086c4fb134dd0d8f9219e3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:49+01:00
Commit Message:
AGDS: reimplemented stub140, output process number in wakeup log line
Changed paths:
engines/agds/agds.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 15d4e72f7d4..5e98ef1f16f 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -100,7 +100,7 @@ ProcessExitCode AGDSEngine::loadObject(const Common::String & name) {
code = loadObject(process.getExitValue());
break;
case kExitCodeSuspend:
- debug("nop, waking up");
+ debug("nop, waking up, %u processes", _processes.size());
break;
default:
debug("destroying process...");
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 0db1e81195e..e744c5f7272 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -182,12 +182,9 @@ void Process::stub98() {
void Process::changeScreenPatch() {
Common::String res2 = popString();
- Common::String res1;
- int index = pop();
- if (index != -1)
- res1 = getString(index);
+ Common::String res1 = popString();
//change screen patch
- debug("stub140: %d '%s' '%s'", index, res1.c_str(), res2.c_str());
+ debug("stub140: '%s' '%s'", res1.c_str(), res2.c_str());
push(140);
}
Commit: c50d20f00954f009c88e2ede64df7b9f680df78f
https://github.com/scummvm/scummvm/commit/c50d20f00954f009c88e2ede64df7b9f680df78f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:49+01:00
Commit Message:
AGDS: kStub98 is kDisableUser
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 8e906aa1261..c04eeba9e54 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -115,7 +115,7 @@ enum Opcode {
kStub95 = 95,
kStub96 = 96,
kStub97 = 97,
- kStub98 = 98,
+ kDisableUser = 98,
kEnableUser = 99,
kStub100 = 100,
kStub101 = 101,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 660350b988d..a55b3583583 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -122,12 +122,12 @@ private:
void decrementGlobalByTop() { decrementGlobal(top()); }
void appendToSharedStorage();
+ void disableUser();
void enableUser();
void onKey(unsigned size);
void onUse(unsigned size);
void loadMouseStub66();
- void stub98();
void stub128();
void stub129();
void stub130();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index e744c5f7272..e73004a13e3 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -176,8 +176,8 @@ void Process::appendToSharedStorage() {
push(index);
}
-void Process::stub98() {
- debug("stub98");
+void Process::disableUser() {
+ debug("disableUser");
}
void Process::changeScreenPatch() {
@@ -453,7 +453,7 @@ ProcessExitCode Process::execute() {
OP (kLoadRegionFromObject, loadRegionFromObject);
OP (kLoadPictureFromObject, loadPictureFromObject);
OP (kLoadAnimationFromObject, loadAnimationFromObject);
- OP (kStub98, stub98);
+ OP (kDisableUser, disableUser);
OP (kEnableUser, enableUser);
OP (kClearScreen, clearScreen);
OP (kLoadMouse, loadMouse);
Commit: 4d30a6c6ca58056910ea95dfe615baebe02d3809
https://github.com/scummvm/scummvm/commit/4d30a6c6ca58056910ea95dfe615baebe02d3809
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:49+01:00
Commit Message:
AGDS: added Process::debug and output additional script info there (object:ip)
Changed paths:
engines/agds/process.cpp
engines/agds/process.h
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 5b746bb437e..e8b6b64a78d 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -23,12 +23,27 @@
#include "agds/process.h"
#include "agds/agds.h"
#include "common/debug.h"
+#include "common/system.h"
namespace AGDS {
Process::Process(AGDSEngine *engine, Object* object, unsigned ip) :
_engine(engine), _object(object), _ip(ip), _status(kStatusActive), _exitCode(kExitCodeDestroy) {
}
+void Process::debug(const char *str, ...) {
+ va_list va;
+ va_start(va, str);
+
+ Common::String format = Common::String::format("%s:%04x: %s: ", _object->getName().c_str(), _ip, str);
+ Common::String buf = Common::String::vformat(format.c_str(), va);
+
+ buf += '\n';
+
+ if (g_system)
+ g_system->logMessage(LogMessageType::kDebug, buf.c_str());
+
+ va_end(va);
+}
void Process::push(int32 value) {
_stack.push(value);
diff --git a/engines/agds/process.h b/engines/agds/process.h
index a55b3583583..bbd43382aad 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -144,6 +144,7 @@ private:
void stub203();
void stub206();
void exitProcessSetNextScreen();
+ void debug(const char *str, ...);
#define UNARY_OP(NAME, OP) void NAME () { int arg = pop(); debug(#NAME " %d", arg); push( OP arg ); }
#define BINARY_OP(NAME, OP) void NAME () { int arg2 = pop(); int arg1 = pop(); debug(#NAME " %d " #OP " %d", arg1, arg2); push(arg1 OP arg2); }
Commit: 737ba5b67c01fd82e214c473376c16fc9df9699d
https://github.com/scummvm/scummvm/commit/737ba5b67c01fd82e214c473376c16fc9df9699d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:49+01:00
Commit Message:
AGDS: fixed logs in changeScreenPatch
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index e73004a13e3..3494b9001c3 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -184,7 +184,7 @@ void Process::changeScreenPatch() {
Common::String res2 = popString();
Common::String res1 = popString();
//change screen patch
- debug("stub140: '%s' '%s'", res1.c_str(), res2.c_str());
+ debug("changeScreenPatch: '%s' '%s'", res1.c_str(), res2.c_str());
push(140);
}
Commit: 7b92339fd10fe3cdfe72da54eee58347957d28c0
https://github.com/scummvm/scummvm/commit/7b92339fd10fe3cdfe72da54eee58347957d28c0
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:49+01:00
Commit Message:
AGDS: output file offset in ip
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index e8b6b64a78d..ef8891ff45d 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -34,7 +34,7 @@ void Process::debug(const char *str, ...) {
va_list va;
va_start(va, str);
- Common::String format = Common::String::format("%s:%04x: %s: ", _object->getName().c_str(), _ip, str);
+ Common::String format = Common::String::format("%s:%04x: %s: ", _object->getName().c_str(), _ip + 7, str);
Common::String buf = Common::String::vformat(format.c_str(), va);
buf += '\n';
Commit: 881f89206216534933cf758b5a7db4a3e4303857
https://github.com/scummvm/scummvm/commit/881f89206216534933cf758b5a7db4a3e4303857
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:49+01:00
Commit Message:
AGDS: remodelled scheduler, round-robin processes, logic there is still to be determined
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 5e98ef1f16f..e4230442517 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -86,25 +86,29 @@ ProcessExitCode AGDSEngine::loadObject(const Common::String & name) {
delete stream;
- _processes.push_back(Process(this, object));
+ _processes.push_front(Process(this, object));
ProcessExitCode code = kExitCodeDestroy;
while(!_processes.empty()) {
- Process & process = _processes.back();
- process.activate();
- code = process.execute();
- switch(code) {
- case kExitCodeLoadScreenObject:
- case kExitCodeDestroyProcessSetNextScreen:
- debug("loading screen object...");
- code = loadObject(process.getExitValue());
+ for(ProcessListType::iterator p = _processes.begin(); p != _processes.end(); ) {
+ Process & process = *p;
+ process.activate();
+ code = process.execute();
+ switch(code) {
+ case kExitCodeLoadScreenObject:
+ case kExitCodeDestroyProcessSetNextScreen:
+ debug("loading screen object...");
+ code = loadObject(process.getExitValue());
+ break;
+ case kExitCodeSuspend:
+ debug("nop, waking up, next process");
+ break;
+ default:
+ debug("destroying process...");
+ p = _processes.erase(p);
+ continue;
+ }
break;
- case kExitCodeSuspend:
- debug("nop, waking up, %u processes", _processes.size());
- break;
- default:
- debug("destroying process...");
- _processes.pop_back();
}
}
return code;
Commit: 57689289fa1450c814abbbe23eb8c3b77f33ee1f
https://github.com/scummvm/scummvm/commit/57689289fa1450c814abbbe23eb8c3b77f33ee1f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:49+01:00
Commit Message:
AGDS: output starting ip of instruction
Changed paths:
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index ef8891ff45d..1c35ed7986c 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -34,7 +34,7 @@ void Process::debug(const char *str, ...) {
va_list va;
va_start(va, str);
- Common::String format = Common::String::format("%s:%04x: %s: ", _object->getName().c_str(), _ip + 7, str);
+ Common::String format = Common::String::format("%s:%04x: %s: ", _object->getName().c_str(), _lastIp + 7, str);
Common::String buf = Common::String::vformat(format.c_str(), va);
buf += '\n';
diff --git a/engines/agds/process.h b/engines/agds/process.h
index bbd43382aad..143cb8a3a1d 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -42,7 +42,7 @@ private:
AGDSEngine * _engine;
Object * _object;
StackType _stack;
- unsigned _ip;
+ unsigned _ip, _lastIp;
Status _status;
Common::String _exitValue;
ProcessExitCode _exitCode;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3494b9001c3..3b7a2f28d4e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -416,6 +416,7 @@ ProcessExitCode Process::execute() {
const Object::CodeType &code = _object->getCode();
while(_status == kStatusActive && _ip < code.size()) {
+ _lastIp = _ip;
uint8 op = next();
switch(op) {
OP_UU (kEnter, enter);
Commit: 9cccdc11888ecb986ad66d2525e9bb9962099fd7
https://github.com/scummvm/scummvm/commit/9cccdc11888ecb986ad66d2525e9bb9962099fd7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:50+01:00
Commit Message:
AGDS: return false from screen patch routine
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3b7a2f28d4e..d9ba710d52b 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -185,7 +185,7 @@ void Process::changeScreenPatch() {
Common::String res1 = popString();
//change screen patch
debug("changeScreenPatch: '%s' '%s'", res1.c_str(), res2.c_str());
- push(140);
+ push(0);
}
void Process::loadMouseStub66() {
Commit: da7728283e7eae7f5a55f41cc8f39376acb9a5ee
https://github.com/scummvm/scummvm/commit/da7728283e7eae7f5a55f41cc8f39376acb9a5ee
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:50+01:00
Commit Message:
AGDS: renamed stub165 to moveScreenObject
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index c04eeba9e54..23c9a7487f7 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -182,7 +182,7 @@ enum Opcode {
kExitScreen = 162,
kStub163 = 163,
kStub164 = 164,
- kStub165 = 165,
+ kMoveScreenObject = 165,
kStub166 = 166,
kStub167 = 167,
kStub168 = 168,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 143cb8a3a1d..ed67d9022bb 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -108,6 +108,7 @@ private:
void getRegionWidth();
void getRegionHeight();
void fadeObject();
+ void moveScreenObject();
void setSystemVariable();
void getIntegerSystemVariable();
@@ -134,7 +135,6 @@ private:
void stub133();
void stub134();
void stub136();
- void stub165();
void stub182();
void stub188();
void stub190();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d9ba710d52b..e0c1f78c4bc 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -253,11 +253,11 @@ void Process::clearScreen() {
debug("clearScreen");
}
-void Process::stub165() {
+void Process::moveScreenObject() {
int arg3 = pop();
int arg2 = pop();
Common::String arg1 = popString();
- debug("stub165 %s %d %d", arg1.c_str(), arg2, arg3);
+ debug("moveScreenObject %s %d %d", arg1.c_str(), arg2, arg3);
_engine->loadObject(arg1);
}
@@ -480,7 +480,7 @@ ProcessExitCode Process::execute() {
OP (kGetIntegerSystemVariable, getIntegerSystemVariable);
OP (kAppendToSharedStorage, appendToSharedStorage);
OP (kExitScreen, exitScreen);
- OP (kStub165, stub165);
+ OP (kMoveScreenObject, moveScreenObject);
OP (kStub182, stub182);
OP (kStub188, stub188);
OP (kStub190, stub190);
Commit: 91671530f3cc0789ade673d4e336ab4425249469
https://github.com/scummvm/scummvm/commit/91671530f3cc0789ade673d4e336ab4425249469
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:50+01:00
Commit Message:
AGDS: removed trailing colon from debug format string
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 1c35ed7986c..22a7e5f9b7a 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -34,7 +34,7 @@ void Process::debug(const char *str, ...) {
va_list va;
va_start(va, str);
- Common::String format = Common::String::format("%s:%04x: %s: ", _object->getName().c_str(), _lastIp + 7, str);
+ Common::String format = Common::String::format("%s:%04x: %s", _object->getName().c_str(), _lastIp + 7, str);
Common::String buf = Common::String::vformat(format.c_str(), va);
buf += '\n';
Commit: c23eb525c97f1ea76af0bd08cc6d691a3ab0c10b
https://github.com/scummvm/scummvm/commit/c23eb525c97f1ea76af0bd08cc6d691a3ab0c10b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:50+01:00
Commit Message:
AGDS: load first object argument to stub188
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index e0c1f78c4bc..cad711cee77 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -240,6 +240,7 @@ void Process::stub188() {
Common::String arg2 = popString();
Common::String arg1 = popString();
debug("stub188 %s %s %d", arg1.c_str(), arg2.c_str(), arg3);
+ _engine->loadObject(arg1);
}
Commit: 0cfc14f1c8d607a2e9bb009c816abdbd1e7ebaf9
https://github.com/scummvm/scummvm/commit/0cfc14f1c8d607a2e9bb009c816abdbd1e7ebaf9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:50+01:00
Commit Message:
AGDS: check done flag and purge finished processes
Changed paths:
engines/agds/agds.cpp
engines/agds/process.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index e4230442517..1244ad86c8b 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -92,6 +92,10 @@ ProcessExitCode AGDSEngine::loadObject(const Common::String & name) {
while(!_processes.empty()) {
for(ProcessListType::iterator p = _processes.begin(); p != _processes.end(); ) {
Process & process = *p;
+ if (process.getStatus() == Process::kStatusDone) {
+ p = _processes.erase(p);
+ continue;
+ }
process.activate();
code = process.execute();
switch(code) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index ed67d9022bb..76788755d72 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -177,6 +177,10 @@ private:
public:
Process(AGDSEngine *engine, Object *object, unsigned ip = 0);
+ Status getStatus() const {
+ return _status;
+ }
+
void activate();
ProcessExitCode execute();
Commit: fc7cf0c19aa602e24cb1cf8d7597777dda75e00a
https://github.com/scummvm/scummvm/commit/fc7cf0c19aa602e24cb1cf8d7597777dda75e00a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:50+01:00
Commit Message:
AGDS: more logs in case of failures
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 22a7e5f9b7a..0827559a8f0 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -51,13 +51,13 @@ void Process::push(int32 value) {
int32 Process::pop() {
if (_stack.empty())
- error("stack underflow, ip: %08x", _ip);
+ error("stack underflow at %s:%04x", _object->getName().c_str(), _lastIp + 7);
return _stack.pop();
}
int32 Process::top() {
if (_stack.empty())
- error("stack underflow, ip: %08x", _ip);
+ error("stack underflow, %s:%04x", _object->getName().c_str(), _lastIp + 7);
return _stack.top();
}
@@ -79,7 +79,7 @@ void Process::activate() {
_status = kStatusActive;
break;
default:
- error("process in invalid state");
+ error("process in invalid state %d", _status);
}
}
Commit: 3e073892a9409c85825f24130d246224120889ab
https://github.com/scummvm/scummvm/commit/3e073892a9409c85825f24130d246224120889ab
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:50+01:00
Commit Message:
AGDS: added stubs for opcodes 155, 156, 166
Changed paths:
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 76788755d72..97576c740c8 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -135,6 +135,9 @@ private:
void stub133();
void stub134();
void stub136();
+ void stub154();
+ void stub155();
+ void stub166();
void stub182();
void stub188();
void stub190();
@@ -167,7 +170,6 @@ private:
#undef UNARY_OP
#undef BINARY_OP
-
void suspend(ProcessExitCode exitCode) {
if (_status == kStatusActive)
_status = kStatusPassive;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index cad711cee77..307fe9db9e2 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -229,6 +229,24 @@ void Process::stub136() {
debug("stub136 sets value of stub130 to 1000000000");
}
+void Process::stub154() {
+ Common::String name = popString();
+ debug("stub154(getSomeX): %s", name.c_str());
+ push(154);
+}
+
+void Process::stub155() {
+ Common::String name = popString();
+ debug("stub154(getSomeY): %s", name.c_str());
+ push(155);
+}
+
+void Process::stub166() {
+ int arg2 = pop();
+ int arg1 = pop();
+ debug("stub166 %d %d", arg1, arg2);
+}
+
void Process::stub182() {
int arg2 = pop();
int arg1 = pop();
@@ -362,10 +380,11 @@ void Process::findObjectInMouseArea() {
debug("findObjectInMouseArea %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
Region *reg = _engine->loadRegion(arg1);
- //_engine->loadObject(arg2);
- //_engine->loadObject(arg3);
delete reg;
push(205);
+
+ _engine->loadObject(arg2);
+ _engine->loadObject(arg3);
}
void Process::loadRegionFromObject() {
@@ -480,6 +499,9 @@ ProcessExitCode Process::execute() {
OP (kGetRegionHeight, getRegionHeight);
OP (kGetIntegerSystemVariable, getIntegerSystemVariable);
OP (kAppendToSharedStorage, appendToSharedStorage);
+ OP (kStub154, stub154);
+ OP (kStub155, stub155);
+ OP (kStub166, stub166);
OP (kExitScreen, exitScreen);
OP (kMoveScreenObject, moveScreenObject);
OP (kStub182, stub182);
Commit: 698204dc36654e076b7513946f3087d7e39bd9bb
https://github.com/scummvm/scummvm/commit/698204dc36654e076b7513946f3087d7e39bd9bb
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:50+01:00
Commit Message:
AGDS: output 2 bytes from object on load
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index c8b22a20a83..e06ef3d8217 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -27,7 +27,10 @@
namespace AGDS {
Object::Object(const Common::String &name, Common::SeekableReadStream * stream) : _name(name), _stringTableLoaded(false) {
- stream->skip(2);
+ byte id = stream->readByte();
+ byte flag = stream->readByte();
+ debug("id: 0x%02x %u, flag: %u", id, id, flag);
+
uint16 dataSize = stream->readUint16LE();
if (dataSize != 0)
error("implement me: object with data (%u)", dataSize);
Commit: e91a53166ca4ed4fccc1d1395dee729c86ce23e2
https://github.com/scummvm/scummvm/commit/e91a53166ca4ed4fccc1d1395dee729c86ce23e2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:50+01:00
Commit Message:
AGDS: output field 3 from extended region entry only if it was initialised
Changed paths:
engines/agds/region.cpp
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index 8adcfb9e824..f5b0a82de8e 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -51,8 +51,11 @@ Region::Region(const Common::String &resourceName, Common::SeekableReadStream *
while(ext--) {
int16 a = stream->readSint16LE();
int16 b = stream->readSint16LE();
- uint16 c = stream->readUint16LE();
- debug("extended entry: %d %d %04x", a, b, c);
+ int16 c = stream->readUint16LE();
+ if (c != -12851) //0xcdcd
+ debug("extended entry: %d %d %d", a, b, c);
+ else
+ debug("extended entry: %d %d", a, b);
}
if (stream->pos() != size)
debug("region data left: %u", size - stream->pos());
Commit: 816238f8f2fa16582535c2b19fb1f04444fdeea0
https://github.com/scummvm/scummvm/commit/816238f8f2fa16582535c2b19fb1f04444fdeea0
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:50+01:00
Commit Message:
AGDS: added Process::popFilename, and Engine::loadFilename for resource convenience
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 1244ad86c8b..04447e85b1d 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -72,6 +72,22 @@ Region * AGDSEngine::loadRegion(const Common::String &name) {
return new Region(name, stream);
}
+Common::String AGDSEngine::loadFilename(const Common::String &entryName) {
+ Common::SeekableReadStream * stream = _data.getEntry(entryName);
+ if (!stream)
+ error("no database entry for %s\n", entryName.c_str());
+
+ byte name[32];
+ int end = stream->read(name, sizeof(name));
+ byte *nameEnd = Common::find(name, name + end, 0);
+ unsigned size = nameEnd - name;
+ ResourceManager::decrypt(name, size);
+
+ delete stream;
+ return Common::String(reinterpret_cast<const char *>(name), size);
+}
+
+
ProcessExitCode AGDSEngine::loadObject(const Common::String & name) {
debug("loading object %s", name.c_str());
Common::SeekableReadStream * stream = _data.getEntry(name);
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 019ed9ec0f1..ebc95ee6f9c 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -57,6 +57,7 @@ private:
bool load();
ProcessExitCode loadObject(const Common::String & name);
Region * loadRegion(const Common::String &name);
+ Common::String loadFilename(const Common::String &name);
int appendToSharedStorage(const Common::String &value);
const Common::String & getSharedStorage(int id) const;
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 0827559a8f0..7ace274d295 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -70,6 +70,10 @@ Common::String Process::getString(int id) {
return _object->getString(id).string;
}
+Common::String Process::popFilename() {
+ return _engine->loadFilename(popString());
+}
+
void Process::activate() {
switch(_status)
{
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 97576c740c8..545bb95f8c3 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -82,6 +82,7 @@ private:
Common::String popString() {
return getString(pop());
}
+ Common::String popFilename();
void enter(uint16 magic, uint16 size);
void exitProcess();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 307fe9db9e2..9e82898f093 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -82,18 +82,18 @@ void Process::getRegionHeight() {
void Process::loadPicture() {
- Common::String name = popString();
+ Common::String name = popFilename();
debug("loadPicture stub %s", name.c_str());
push(100500); //dummy
}
void Process::loadAnimation() {
- Common::String name = popString();
+ Common::String name = popFilename();
debug("loadAnimation %s", name.c_str());
}
void Process::loadSample() {
- Common::String name = popString();
+ Common::String name = popFilename();
debug("loadSample %s", name.c_str());
}
@@ -110,13 +110,13 @@ void Process::removeScreenObject() {
}
void Process::loadFont() {
- Common::String name = popString();
+ Common::String name = popFilename();
int id = pop();
debug("loadFont %s %d stub", name.c_str(), id);
}
void Process::loadMouse() {
- Common::String name = popString();
+ Common::String name = popFilename();
debug("loadMouse %s", name.c_str());
}
@@ -189,7 +189,7 @@ void Process::changeScreenPatch() {
}
void Process::loadMouseStub66() {
- Common::String name = popString();
+ Common::String name = popFilename();
debug("loadMouseStub66 %s", name.c_str());
}
@@ -396,12 +396,12 @@ void Process::loadRegionFromObject() {
void Process::loadPictureFromObject() {
- Common::String name = popString();
+ Common::String name = popFilename();
debug("loadPictureFromObject %s", name.c_str());
}
void Process::loadAnimationFromObject() {
- Common::String name = popString();
+ Common::String name = popFilename();
debug("loadAnimationFromObject %s", name.c_str());
}
Commit: 2ada111d5fbe4fffcfbee4430bc7a2074d0a2dc5
https://github.com/scummvm/scummvm/commit/2ada111d5fbe4fffcfbee4430bc7a2074d0a2dc5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:51+01:00
Commit Message:
AGDS: added graphics initialisation
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 04447e85b1d..d1a30d47d1a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -28,6 +28,8 @@
#include "common/ini-file.h"
#include "common/file.h"
#include "common/debug.h"
+#include "common/system.h"
+#include "engines/util.h"
namespace AGDS {
@@ -38,6 +40,23 @@ AGDSEngine::AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engin
AGDSEngine::~AGDSEngine() {
}
+bool AGDSEngine::initGraphics() {
+ //fixme: get mode from config?
+ typedef Common::List<Graphics::PixelFormat> FormatsType;
+ FormatsType formats = _system->getSupportedFormats();
+
+ FormatsType::iterator fi;
+ for(fi = formats.begin(); fi != formats.end(); ++fi) {
+ if (fi->bytesPerPixel == 4) {
+ debug("found mode %s", fi->toString().c_str());
+ ::initGraphics(800, 600, &*fi);
+ return true;
+ }
+ }
+ error("nope");
+ return false;
+}
+
bool AGDSEngine::load() {
Common::INIFile config;
Common::File configFile;
@@ -49,6 +68,9 @@ bool AGDSEngine::load() {
if (!config.loadFromStream(configFile))
return false;
+ if (!initGraphics())
+ error("no video mode found");
+
Common::INIFile::SectionKeyList values = config.getKeys("core");
for(Common::INIFile::SectionKeyList::iterator i = values.begin(); i != values.end(); ++i) {
if (i->key == "path")
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index ebc95ee6f9c..8f793c0eb51 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -54,6 +54,7 @@ public:
Common::Error run();
private:
+ bool initGraphics();
bool load();
ProcessExitCode loadObject(const Common::String & name);
Region * loadRegion(const Common::String &name);
Commit: 355d78b972a225fcb695d49d3852f1d0f3769a20
https://github.com/scummvm/scummvm/commit/355d78b972a225fcb695d49d3852f1d0f3769a20
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:51+01:00
Commit Message:
AGDS: renamed setCounter to setTimer, added active() and main loop
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index d1a30d47d1a..abf0c63d41c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -25,6 +25,7 @@
#include "agds/process.h"
#include "agds/region.h"
#include "common/error.h"
+#include "common/events.h"
#include "common/ini-file.h"
#include "common/file.h"
#include "common/debug.h"
@@ -34,7 +35,7 @@
namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
- _gameDescription(gameDesc), _sharedStorageIndex(-2) {
+ _gameDescription(gameDesc), _sharedStorageIndex(-2), _timer(0) {
}
AGDSEngine::~AGDSEngine() {
@@ -110,7 +111,7 @@ Common::String AGDSEngine::loadFilename(const Common::String &entryName) {
}
-ProcessExitCode AGDSEngine::loadObject(const Common::String & name) {
+void AGDSEngine::loadObject(const Common::String & name) {
debug("loading object %s", name.c_str());
Common::SeekableReadStream * stream = _data.getEntry(name);
if (!stream)
@@ -120,51 +121,69 @@ ProcessExitCode AGDSEngine::loadObject(const Common::String & name) {
if (!object)
_objects.setVal(name, object = new Object(name, stream));
else
- return kExitCodeDestroy;
+ return;
delete stream;
_processes.push_front(Process(this, object));
+}
- ProcessExitCode code = kExitCodeDestroy;
- while(!_processes.empty()) {
- for(ProcessListType::iterator p = _processes.begin(); p != _processes.end(); ) {
- Process & process = *p;
- if (process.getStatus() == Process::kStatusDone) {
- p = _processes.erase(p);
- continue;
- }
- process.activate();
- code = process.execute();
- switch(code) {
- case kExitCodeLoadScreenObject:
- case kExitCodeDestroyProcessSetNextScreen:
- debug("loading screen object...");
- code = loadObject(process.getExitValue());
- break;
- case kExitCodeSuspend:
- debug("nop, waking up, next process");
- break;
- default:
- debug("destroying process...");
- p = _processes.erase(p);
- continue;
- }
+void AGDSEngine::runProcess() {
+ for(ProcessListType::iterator p = _processes.begin(); active() && p != _processes.end(); ) {
+ Process & process = *p;
+ if (process.getStatus() == Process::kStatusDone) {
+ p = _processes.erase(p);
+ continue;
+ }
+ process.activate();
+ ProcessExitCode code = process.execute();
+ switch(code) {
+ case kExitCodeLoadScreenObject:
+ case kExitCodeDestroyProcessSetNextScreen:
+ debug("loading screen object...");
+ loadObject(process.getExitValue());
+ break;
+ case kExitCodeSuspend:
+ debug("nop, waking up, next process");
break;
+ default:
+ debug("destroying process...");
+ p = _processes.erase(p);
+ continue;
}
+ break;
}
- return code;
}
+
Common::Error AGDSEngine::run() {
if (!load())
return Common::kNoGameDataFoundError;
- if (!_nextScreen.empty()) {
- debug("loading screen %s", _nextScreen.c_str());
- Common::String nextScreen;
- nextScreen = _nextScreen;
- _nextScreen.clear();
- loadObject(nextScreen);
+
+ Common::EventManager *eventManager = _system->getEventManager();
+ _system->fillScreen(0);
+
+ while(!shouldQuit()) {
+ if (!_nextScreen.empty()) {
+ debug("loading screen %s", _nextScreen.c_str());
+ Common::String nextScreen;
+ nextScreen = _nextScreen;
+ _nextScreen.clear();
+ loadObject(nextScreen);
+ }
+
+ if (active()) {
+ while(active() && !_processes.empty())
+ runProcess();
+ }
+ else
+ --_timer;
+
+ Common::Event event;
+ while(eventManager->pollEvent(event)) {
+ }
+ _system->updateScreen();
+ _system->delayMillis(20);
}
return Common::kNoError;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 8f793c0eb51..df75a33af9d 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -56,18 +56,28 @@ public:
private:
bool initGraphics();
bool load();
- ProcessExitCode loadObject(const Common::String & name);
+ void runProcess();
+
+ void loadObject(const Common::String & name);
Region * loadRegion(const Common::String &name);
Common::String loadFilename(const Common::String &name);
int appendToSharedStorage(const Common::String &value);
const Common::String & getSharedStorage(int id) const;
- void setGlobal(const Common::String &name, int value)
- { _globals.setVal(name, value); }
+ void setGlobal(const Common::String &name, int value) {
+ _globals.setVal(name, value);
+ }
+ bool hasGlobal(const Common::String &name) const {
+ return _globals.find(name) != _globals.end();
+ }
int getGlobal(const Common::String &name) const;
- bool hasGlobal(const Common::String &name) const
- { return _globals.find(name) != _globals.end(); }
+
+ void setTimer(int timer) {
+ _timer = timer;
+ }
+
+ bool active() const { return _timer <= 0; }
private:
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
@@ -83,6 +93,7 @@ private:
int _sharedStorageIndex;
Common::String _sharedStorage[10];
GlobalsType _globals;
+ int _timer;
};
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 23c9a7487f7..0f7f180152c 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -144,7 +144,7 @@ enum Opcode {
kStub124 = 124,
kStub125 = 125,
kStub126 = 126,
- kSetCounter = 127,
+ kSetTimer = 127,
kProcessCleanupStub128 = 128,
kStub129 = 129,
kStub130 = 130,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 545bb95f8c3..ac47c839ceb 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -105,7 +105,7 @@ private:
void loadAnimationFromObject();
void loadAnimation();
void loadSample();
- void setCounter();
+ void setTimer();
void getRegionWidth();
void getRegionHeight();
void fadeObject();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 9e82898f093..c3a648c3c45 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -405,9 +405,12 @@ void Process::loadAnimationFromObject() {
debug("loadAnimationFromObject %s", name.c_str());
}
-void Process::setCounter() {
+void Process::setTimer() {
int value = pop();
- debug("setCounter127 %d", value);
+ debug("setTimer %d", value);
+ _engine->setTimer(value);
+ _status = kStatusPassive;
+ _exitCode = kExitCodeSuspend;
}
@@ -485,7 +488,7 @@ ProcessExitCode Process::execute() {
OP (kScreenRemoveObject, removeScreenObject);
OP (kLoadAnimation, loadAnimation);
OP (kLoadSample, loadSample);
- OP (kSetCounter, setCounter);
+ OP (kSetTimer, setTimer);
OP (kProcessCleanupStub128, stub128);
OP (kStub129, stub129);
OP (kStub130, stub130);
Commit: 8dc86d7c422f5fdc029a2b9d37c6db48c6996df4
https://github.com/scummvm/scummvm/commit/8dc86d7c422f5fdc029a2b9d37c6db48c6996df4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:51+01:00
Commit Message:
AGDS: added simple mjpg player and playFim support
Changed paths:
A engines/agds/mjpgPlayer.cpp
A engines/agds/mjpgPlayer.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/module.mk
engines/agds/process.h
engines/agds/process_opcodes.cpp
engines/agds/region.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index abf0c63d41c..5285f0a5f59 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -21,6 +21,7 @@
*/
#include "agds/agds.h"
+#include "agds/mjpgPlayer.h"
#include "agds/object.h"
#include "agds/process.h"
#include "agds/region.h"
@@ -35,7 +36,7 @@
namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
- _gameDescription(gameDesc), _sharedStorageIndex(-2), _timer(0) {
+ _gameDescription(gameDesc), _sharedStorageIndex(-2), _timer(0), _mjpgPlayer(NULL) {
}
AGDSEngine::~AGDSEngine() {
@@ -144,7 +145,7 @@ void AGDSEngine::runProcess() {
loadObject(process.getExitValue());
break;
case kExitCodeSuspend:
- debug("nop, waking up, next process");
+ debug("process suspended");
break;
default:
debug("destroying process...");
@@ -164,6 +165,9 @@ Common::Error AGDSEngine::run() {
_system->fillScreen(0);
while(!shouldQuit()) {
+ if (_timer > 0)
+ --_timer;
+
if (!_nextScreen.empty()) {
debug("loading screen %s", _nextScreen.c_str());
Common::String nextScreen;
@@ -172,12 +176,20 @@ Common::Error AGDSEngine::run() {
loadObject(nextScreen);
}
- if (active()) {
- while(active() && !_processes.empty())
- runProcess();
+ while(active() && !_processes.empty())
+ runProcess();
+
+ if (_mjpgPlayer) {
+ const Graphics::Surface *surface = _mjpgPlayer->decodeFrame();
+
+ if (surface)
+ _system->copyRectToScreen(surface->getPixels(), surface->pitch, 0, 0, surface->w, surface->h);
+
+ if (_mjpgPlayer->eos()) {
+ delete _mjpgPlayer;
+ _mjpgPlayer = NULL;
+ }
}
- else
- --_timer;
Common::Event event;
while(eventManager->pollEvent(event)) {
@@ -189,6 +201,12 @@ Common::Error AGDSEngine::run() {
return Common::kNoError;
}
+void AGDSEngine::playFilm(const Common::String &video, const Common::String &audio) {
+ delete _mjpgPlayer;
+ _mjpgPlayer = new MJPGPlayer(_resourceManager.getResource(video));
+}
+
+
int AGDSEngine::appendToSharedStorage(const Common::String &value) {
int index = _sharedStorageIndex;
_sharedStorage[-2 - (_sharedStorageIndex--)] = value;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index df75a33af9d..e89cbc3eb07 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -43,6 +43,7 @@ namespace AGDS {
class Object;
class Process;
class Region;
+class MJPGPlayer;
class AGDSEngine : public Engine {
friend class Process;
@@ -77,7 +78,8 @@ private:
_timer = timer;
}
- bool active() const { return _timer <= 0; }
+ bool active() const { return _timer <= 0 && !_mjpgPlayer; }
+ void playFilm(const Common::String &video, const Common::String &audio);
private:
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
@@ -94,6 +96,7 @@ private:
Common::String _sharedStorage[10];
GlobalsType _globals;
int _timer;
+ MJPGPlayer * _mjpgPlayer;
};
diff --git a/engines/agds/mjpgPlayer.cpp b/engines/agds/mjpgPlayer.cpp
new file mode 100644
index 00000000000..bf36546bc83
--- /dev/null
+++ b/engines/agds/mjpgPlayer.cpp
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/mjpgPlayer.h"
+#include "common/debug.h"
+
+namespace AGDS {
+
+MJPGPlayer::MJPGPlayer(Common::SeekableReadStream * stream): _stream(stream), _firstFramePos(_stream->pos()) {
+}
+
+MJPGPlayer::~MJPGPlayer() {
+ delete _stream;
+}
+
+void MJPGPlayer::rewind() {
+ _stream->seek(_firstFramePos);
+}
+
+const Graphics::Surface *MJPGPlayer::decodeFrame() {
+ if (_stream->eos())
+ return NULL;
+
+ uint32 size = _stream->readSint32LE();
+ if (size == 0)
+ return NULL;
+
+ Common::SeekableReadStream *stream = _stream->readStream(size);
+ const Graphics::Surface *surface = _decoder.decodeFrame(*stream);
+ delete stream;
+ return surface;
+}
+
+
+}
diff --git a/engines/agds/mjpgPlayer.h b/engines/agds/mjpgPlayer.h
new file mode 100644
index 00000000000..4869e66e049
--- /dev/null
+++ b/engines/agds/mjpgPlayer.h
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_MJPG_PLAYER_H
+#define AGDS_MJPG_PLAYER_H
+
+#include "common/scummsys.h"
+#include "common/stream.h"
+#include "graphics/surface.h"
+#include "image/jpeg.h"
+
+namespace AGDS {
+
+class MJPGPlayer {
+ Common::SeekableReadStream * _stream;
+ int32 _firstFramePos;
+ Image::JPEGDecoder _decoder;
+
+public:
+ MJPGPlayer(Common::SeekableReadStream * stream);
+ ~MJPGPlayer();
+
+ bool eos() {
+ return _stream->eos();
+ }
+
+ void rewind();
+ const Graphics::Surface *decodeFrame();
+};
+
+
+} // End of namespace AGDS
+
+#endif /* AGDS_MJPG_PLAYER_H */
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index 1bd3eca9bd5..f36bb13e7f9 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -4,6 +4,7 @@ MODULE_OBJS := \
agds.o \
database.o \
detection.o \
+ mjpgPlayer.o \
object.o \
process.o \
process_opcodes.o \
diff --git a/engines/agds/process.h b/engines/agds/process.h
index ac47c839ceb..98af83429dc 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -145,7 +145,7 @@ private:
void stub195();
void stub196();
void stub202(unsigned size);
- void stub203();
+ void playFilm();
void stub206();
void exitProcessSetNextScreen();
void debug(const char *str, ...);
@@ -171,7 +171,7 @@ private:
#undef UNARY_OP
#undef BINARY_OP
- void suspend(ProcessExitCode exitCode) {
+ void suspend(ProcessExitCode exitCode = kExitCodeSuspend) {
if (_status == kStatusActive)
_status = kStatusPassive;
_exitCode = exitCode;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c3a648c3c45..b94ee99c6fa 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -304,12 +304,14 @@ void Process::stub202(unsigned size) {
_ip += size;
}
-void Process::stub203() {
+void Process::playFilm() {
//arg3 is optional and stored in process struct, offset 0x210
- Common::String audio = popString();
- Common::String video = popString();
+ Common::String audio = popFilename();
+ Common::String video = popFilename();
debug("playFilm %s %s", video.c_str(), audio.c_str());
+ _engine->playFilm(video, audio);
+ suspend();
}
void Process::stub206() {
@@ -409,8 +411,7 @@ void Process::setTimer() {
int value = pop();
debug("setTimer %d", value);
_engine->setTimer(value);
- _status = kStatusPassive;
- _exitCode = kExitCodeSuspend;
+ suspend();
}
@@ -516,7 +517,7 @@ ProcessExitCode Process::execute() {
OP (kFadeObject, fadeObject);
OP (kLoadFont, loadFont);
OP_U (kStub202ScreenHandler, stub202);
- OP (kPlayFilm, stub203);
+ OP (kPlayFilm, playFilm);
OP (kFindObjectInMouseArea, findObjectInMouseArea);
OP (kStub206, stub206);
OP_U (kOnKey, onKey);
diff --git a/engines/agds/region.h b/engines/agds/region.h
index d1b9a5d4146..1503dea814e 100644
--- a/engines/agds/region.h
+++ b/engines/agds/region.h
@@ -39,4 +39,4 @@ struct Region {
} // End of namespace AGDS
-#endif /* AGDS_OBJECT_H */
+#endif /* AGDS_REGION_H */
Commit: e5f10f773eb9657faf2e9a6fdb63c7e200fc5d84
https://github.com/scummvm/scummvm/commit/e5f10f773eb9657faf2e9a6fdb63c7e200fc5d84
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:51+01:00
Commit Message:
AGDS: removed comment
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b94ee99c6fa..02dbb9a988a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -305,7 +305,6 @@ void Process::stub202(unsigned size) {
}
void Process::playFilm() {
- //arg3 is optional and stored in process struct, offset 0x210
Common::String audio = popFilename();
Common::String video = popFilename();
Commit: 510b520a2460597bf9fcc591ab91e8f74aac1d26
https://github.com/scummvm/scummvm/commit/510b520a2460597bf9fcc591ab91e8f74aac1d26
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:51+01:00
Commit Message:
AGDS: use 25 fps as a base
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 5285f0a5f59..52b8eebf965 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -195,7 +195,7 @@ Common::Error AGDSEngine::run() {
while(eventManager->pollEvent(event)) {
}
_system->updateScreen();
- _system->delayMillis(20);
+ _system->delayMillis(40);
}
return Common::kNoError;
Commit: 5cf5782b3583220ef6c6d96bc08d2a64725c2b55
https://github.com/scummvm/scummvm/commit/5cf5782b3583220ef6c6d96bc08d2a64725c2b55
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:51+01:00
Commit Message:
AGDS: renamed stub182 to kSetGlyphSize
Changed paths:
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 0f7f180152c..772fa54606f 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -199,7 +199,7 @@ enum Opcode {
kStub179 = 179,
kStub180 = 180,
kStub181 = 181,
- kStub182 = 182,
+ kSetGlyphSize = 182,
kStub183 = 183,
kStub184 = 184,
kStub185 = 185,
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 7ace274d295..e4d98ecac1e 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -28,8 +28,10 @@
namespace AGDS {
Process::Process(AGDSEngine *engine, Object* object, unsigned ip) :
- _engine(engine), _object(object), _ip(ip), _status(kStatusActive), _exitCode(kExitCodeDestroy) {
+ _engine(engine), _object(object), _ip(ip), _status(kStatusActive), _exitCode(kExitCodeDestroy),
+ _glyphWidth(16), _glyphHeight(16) {
}
+
void Process::debug(const char *str, ...) {
va_list va;
va_start(va, str);
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 98af83429dc..0918c0dcfeb 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -46,6 +46,7 @@ private:
Status _status;
Common::String _exitValue;
ProcessExitCode _exitCode;
+ int _glyphWidth, _glyphHeight;
private:
uint8 next() {
@@ -139,7 +140,7 @@ private:
void stub154();
void stub155();
void stub166();
- void stub182();
+ void setFontGlyphSize();
void stub188();
void stub190();
void stub195();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 02dbb9a988a..ff0d9d69428 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -247,10 +247,10 @@ void Process::stub166() {
debug("stub166 %d %d", arg1, arg2);
}
-void Process::stub182() {
- int arg2 = pop();
- int arg1 = pop();
- debug("stub182 %d %d", arg1, arg2);
+void Process::setFontGlyphSize() {
+ _glyphHeight = pop();
+ _glyphWidth = pop();
+ debug("setFontGlyphSize %d %d", _glyphWidth, _glyphHeight);
}
void Process::stub188() {
@@ -507,7 +507,7 @@ ProcessExitCode Process::execute() {
OP (kStub166, stub166);
OP (kExitScreen, exitScreen);
OP (kMoveScreenObject, moveScreenObject);
- OP (kStub182, stub182);
+ OP (kSetGlyphSize, setFontGlyphSize);
OP (kStub188, stub188);
OP (kStub190, stub190);
OP (kStub195, stub195);
Commit: 9ab8d008f4e2018176e5aeb124918ea1f03f4e85
https://github.com/scummvm/scummvm/commit/9ab8d008f4e2018176e5aeb124918ea1f03f4e85
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:51+01:00
Commit Message:
AGDS: made resources case-insensitive
Changed paths:
engines/agds/resourceManager.h
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index ab057a58749..46a3e099369 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -56,7 +56,7 @@ private:
};
typedef Common::SharedPtr<Resource> ResourcePtr;
- typedef Common::HashMap<Common::String, ResourcePtr> ResourcesType;
+ typedef Common::HashMap<Common::String, ResourcePtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ResourcesType;
ResourcesType _resources;
public:
Commit: bfc1b4be5a2875e543e7c60e19cb64ac6c7ed039
https://github.com/scummvm/scummvm/commit/bfc1b4be5a2875e543e7c60e19cb64ac6c7ed039
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:51+01:00
Commit Message:
AGDS: added ResourceManager::loadPicture
Changed paths:
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index d19843f3957..156dba8034b 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -26,6 +26,7 @@
#include "common/memstream.h"
#include "common/algorithm.h"
#include "common/ptr.h"
+#include "image/bmp.h"
namespace AGDS {
ResourceManager::ResourceManager()
@@ -144,5 +145,14 @@ namespace AGDS {
return grp.readStream(resource->size);
}
+ const Graphics::Surface * ResourceManager::loadPicture(const Common::String & name) {
+ Common::SeekableReadStream *stream = getResource(name);
+ if (!stream)
+ return NULL;
+
+ Image::BitmapDecoder bmp;
+ return bmp.loadStream(*stream)? bmp.getSurface(): NULL;
+ }
+
} // End of namespace AGDS
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 46a3e099369..5a2a8a26110 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -30,6 +30,8 @@
#include "common/hashmap.h"
#include "common/hash-str.h"
+namespace Graphics { class Surface; }
+
namespace AGDS {
class ResourceManager {
@@ -68,6 +70,7 @@ public:
bool addPath(const Common::String &grpFilename);
Common::SeekableReadStream * getResource(const Common::String &name) const;
+ const Graphics::Surface * loadPicture(const Common::String & name);
};
Commit: 603a8255124053b425f53a1652328aa6cfde5328
https://github.com/scummvm/scummvm/commit/603a8255124053b425f53a1652328aa6cfde5328
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:51+01:00
Commit Message:
AGDS: added picture to object
Changed paths:
engines/agds/agds.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index e89cbc3eb07..e24fa351c39 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -81,6 +81,10 @@ private:
bool active() const { return _timer <= 0 && !_mjpgPlayer; }
void playFilm(const Common::String &video, const Common::String &audio);
+ ResourceManager & resourceManager() {
+ return _resourceManager;
+ }
+
private:
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
typedef Common::List<Process> ProcessListType;
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index e06ef3d8217..0cd378beaac 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -26,7 +26,7 @@
namespace AGDS {
-Object::Object(const Common::String &name, Common::SeekableReadStream * stream) : _name(name), _stringTableLoaded(false) {
+Object::Object(const Common::String &name, Common::SeekableReadStream * stream) : _name(name), _stringTableLoaded(false), _picture(), _x(), _y() {
byte id = stream->readByte();
byte flag = stream->readByte();
debug("id: 0x%02x %u, flag: %u", id, id, flag);
@@ -85,4 +85,9 @@ const Object::StringEntry & Object::getString(uint16 index) const {
return i->_value;
}
+void Object::setPicture(const Graphics::Surface *surface) {
+ delete _picture;
+ _picture = surface;
+}
+
}
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 315b5242550..19d67f07980 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -27,6 +27,7 @@
#include "common/array.h"
#include "common/stream.h"
#include "common/hashmap.h"
+#include "graphics/surface.h"
namespace AGDS {
@@ -46,10 +47,12 @@ public:
private:
typedef Common::HashMap<uint16, StringEntry, Common::Hash<uint16> > StringTableType;
- Common::String _name;
- CodeType _code;
- StringTableType _stringTable;
- bool _stringTableLoaded;
+ Common::String _name;
+ CodeType _code;
+ StringTableType _stringTable;
+ bool _stringTableLoaded;
+ const Graphics::Surface * _picture;
+ int _x, _y;
public:
@@ -66,6 +69,12 @@ public:
const CodeType & getCode() const {
return _code;
}
+
+ void setPicture(const Graphics::Surface *);
+
+ const Graphics::Surface *getPicture() const {
+ return _picture;
+ }
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index ff0d9d69428..8c11b383ee6 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -399,6 +399,7 @@ void Process::loadRegionFromObject() {
void Process::loadPictureFromObject() {
Common::String name = popFilename();
debug("loadPictureFromObject %s", name.c_str());
+ _object->setPicture(_engine->resourceManager().loadPicture(name));
}
void Process::loadAnimationFromObject() {
Commit: 47faa4ce2bdcc1ed4495d8405de1d17f3d8b09be
https://github.com/scummvm/scummvm/commit/47faa4ce2bdcc1ed4495d8405de1d17f3d8b09be
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:51+01:00
Commit Message:
AGDS: replaced resource string table with array
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 0cd378beaac..50ceb274262 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -54,6 +54,7 @@ void Object::readStringTable(unsigned resOffset, uint16 resCount) {
//debug("resource table at %08x", resOffset);
Common::MemoryReadStream stream(_code.data() + resOffset, _code.size() - resOffset);
+ _stringTable.resize(resCount);
for(uint16 i = 0; i < resCount; ++i) {
uint16 offset = stream.readUint16LE();
uint16 flags = stream.readUint16LE();
@@ -78,11 +79,10 @@ const Object::StringEntry & Object::getString(uint16 index) const {
if (!_stringTableLoaded)
error("no string table loaded");
- StringTableType::const_iterator i = _stringTable.find(index);
- if (i == _stringTable.end())
+ if (index >= _stringTable.size())
error("no resource name with id %u", index);
- return i->_value;
+ return _stringTable[index];
}
void Object::setPicture(const Graphics::Surface *surface) {
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 19d67f07980..baad0e55a92 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -26,7 +26,6 @@
#include "common/scummsys.h"
#include "common/array.h"
#include "common/stream.h"
-#include "common/hashmap.h"
#include "graphics/surface.h"
namespace AGDS {
@@ -45,7 +44,7 @@ public:
};
private:
- typedef Common::HashMap<uint16, StringEntry, Common::Hash<uint16> > StringTableType;
+ typedef Common::Array<StringEntry> StringTableType;
Common::String _name;
CodeType _code;
Commit: 7c36c29b4a6040e585a4746c7e695cc10d8ecf30
https://github.com/scummvm/scummvm/commit/7c36c29b4a6040e585a4746c7e695cc10d8ecf30
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:52+01:00
Commit Message:
AGDS: convert video frame, use lockScreen instead of copying raw pixel data
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 52b8eebf965..ffe901154fc 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -179,11 +179,18 @@ Common::Error AGDSEngine::run() {
while(active() && !_processes.empty())
runProcess();
+ Graphics::Surface *backbuffer = _system->lockScreen();
+
if (_mjpgPlayer) {
const Graphics::Surface *surface = _mjpgPlayer->decodeFrame();
- if (surface)
- _system->copyRectToScreen(surface->getPixels(), surface->pitch, 0, 0, surface->w, surface->h);
+ if (surface) {
+ Graphics::Surface * converted = surface->convertTo(backbuffer->format);
+ int x = (backbuffer->w - converted->w) / 2;
+ int y = (backbuffer->h - converted->h) / 2;
+ backbuffer->copyRectToSurface(*converted, x, y, Common::Rect(0, 0, converted->w, converted->h));
+ delete converted;
+ }
if (_mjpgPlayer->eos()) {
delete _mjpgPlayer;
@@ -194,6 +201,7 @@ Common::Error AGDSEngine::run() {
Common::Event event;
while(eventManager->pollEvent(event)) {
}
+ _system->unlockScreen();
_system->updateScreen();
_system->delayMillis(40);
}
Commit: e0662c60569ef1b849807bb2c9eefdec486ce155
https://github.com/scummvm/scummvm/commit/e0662c60569ef1b849807bb2c9eefdec486ce155
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:52+01:00
Commit Message:
AGDS: fixed assertion in intro stream
Changed paths:
engines/agds/mjpgPlayer.cpp
diff --git a/engines/agds/mjpgPlayer.cpp b/engines/agds/mjpgPlayer.cpp
index bf36546bc83..2a696b92d5f 100644
--- a/engines/agds/mjpgPlayer.cpp
+++ b/engines/agds/mjpgPlayer.cpp
@@ -44,6 +44,8 @@ const Graphics::Surface *MJPGPlayer::decodeFrame() {
if (size == 0)
return NULL;
+ if (_stream->eos())
+ return NULL;
Common::SeekableReadStream *stream = _stream->readStream(size);
const Graphics::Surface *surface = _decoder.decodeFrame(*stream);
delete stream;
Commit: fb5b2cbfdc64b8f298fd9d32f79504a3618e2707
https://github.com/scummvm/scummvm/commit/fb5b2cbfdc64b8f298fd9d32f79504a3618e2707
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:52+01:00
Commit Message:
AGDS: reworked surface loading (fixed ownership problem by converting to display format), added implementation of surface width/height opcodes
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/object.cpp
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ffe901154fc..d4ccfede2d4 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -36,7 +36,8 @@
namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
- _gameDescription(gameDesc), _sharedStorageIndex(-2), _timer(0), _mjpgPlayer(NULL) {
+ _gameDescription(gameDesc), _sharedStorageIndex(-2), _timer(0),
+ _mjpgPlayer(NULL), _currentScreen(NULL) {
}
AGDSEngine::~AGDSEngine() {
@@ -51,7 +52,8 @@ bool AGDSEngine::initGraphics() {
for(fi = formats.begin(); fi != formats.end(); ++fi) {
if (fi->bytesPerPixel == 4) {
debug("found mode %s", fi->toString().c_str());
- ::initGraphics(800, 600, &*fi);
+ _pixelFormat = *fi;
+ ::initGraphics(800, 600, &_pixelFormat);
return true;
}
}
@@ -112,21 +114,23 @@ Common::String AGDSEngine::loadFilename(const Common::String &entryName) {
}
-void AGDSEngine::loadObject(const Common::String & name) {
- debug("loading object %s", name.c_str());
+Object *AGDSEngine::loadObject(const Common::String & name) {
+ ObjectsType::iterator i = _objects.find(name);
+ Object *object = i != _objects.end()? i->_value: NULL;
+ if (object)
+ return object;
+
Common::SeekableReadStream * stream = _data.getEntry(name);
if (!stream)
error("no database entry for %s\n", name.c_str());
- ObjectsType::iterator i = _objects.find(name);
- Object *object = i != _objects.end()? i->_value: NULL;
- if (!object)
- _objects.setVal(name, object = new Object(name, stream));
- else
- return;
+
+ object = new Object(name, stream);
+ _objects.setVal(name, object);
delete stream;
_processes.push_front(Process(this, object));
+ return object;
}
void AGDSEngine::runProcess() {
@@ -140,9 +144,11 @@ void AGDSEngine::runProcess() {
ProcessExitCode code = process.execute();
switch(code) {
case kExitCodeLoadScreenObject:
- case kExitCodeDestroyProcessSetNextScreen:
- debug("loading screen object...");
- loadObject(process.getExitValue());
+ case kExitCodeDestroyProcessSetNextScreen: {
+ Common::String screen = process.getExitValue();
+ debug("loading screen object %s", screen.c_str());
+ _currentScreen = loadObject(screen);
+ }
break;
case kExitCodeSuspend:
debug("process suspended");
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index e24fa351c39..5ba99eeb541 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -29,6 +29,7 @@
#include "agds/database.h"
#include "agds/processExitCode.h"
#include "agds/resourceManager.h"
+#include "graphics/pixelformat.h"
/**
* This is the namespace of the AGDS engine.
@@ -59,7 +60,8 @@ private:
bool load();
void runProcess();
- void loadObject(const Common::String & name);
+ Object * loadObject(const Common::String & name);
+
Region * loadRegion(const Common::String &name);
Common::String loadFilename(const Common::String &name);
@@ -85,6 +87,9 @@ private:
return _resourceManager;
}
+ const Graphics::Surface * loadPicture(const Common::String &name)
+ { return _resourceManager.loadPicture(name, _pixelFormat); }
+
private:
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
typedef Common::List<Process> ProcessListType;
@@ -100,7 +105,9 @@ private:
Common::String _sharedStorage[10];
GlobalsType _globals;
int _timer;
+ Graphics::PixelFormat _pixelFormat;
MJPGPlayer * _mjpgPlayer;
+ Object * _currentScreen;
};
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 50ceb274262..016dcab57d3 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -85,9 +85,9 @@ const Object::StringEntry & Object::getString(uint16 index) const {
return _stringTable[index];
}
-void Object::setPicture(const Graphics::Surface *surface) {
+void Object::setPicture(const Graphics::Surface *picture) {
delete _picture;
- _picture = surface;
+ _picture = picture;
}
}
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 772fa54606f..ff58df68ebf 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -212,8 +212,8 @@ enum Opcode {
kStub192 = 192,
kStub193 = 193,
kStub194 = 194,
- kStub195 = 195,
- kStub196 = 196,
+ kGetObjectPictureWidth = 195,
+ kGetObjectPictureHeight = 196,
kStub197 = 197,
kLoadPicture = 198,
kStub199 = 199,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 0918c0dcfeb..87b69ceb051 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -143,8 +143,8 @@ private:
void setFontGlyphSize();
void stub188();
void stub190();
- void stub195();
- void stub196();
+ void getObjectPictureWidth();
+ void getObjectPictureHeight();
void stub202(unsigned size);
void playFilm();
void stub206();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 8c11b383ee6..07d4d8f1db8 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -285,18 +285,24 @@ void Process::stub190() {
debug("stub190 %d", value);
}
-void Process::stub195() {
- Common::String value = popString();
- debug("stub195(getPictureWidth) %s", value.c_str());
- _engine->loadObject(value);
- push(195);
+void Process::getObjectPictureWidth() {
+ Common::String name = popString();
+ debug("getObjectPictureWidth %s", name.c_str());
+ Object *object = _engine->loadObject(name);
+ const Graphics::Surface *picture = object->getPicture();
+ int value = picture? picture->w: 0;
+ debug("\t->%d", value);
+ push(value);
}
-void Process::stub196() {
- Common::String value = popString();
- debug("stub196(getPictureHeight) %s", value.c_str());
- _engine->loadObject(value);
- push(196);
+void Process::getObjectPictureHeight() {
+ Common::String name = popString();
+ debug("getObjectPictureHeight %s", name.c_str());
+ Object *object = _engine->loadObject(name);
+ const Graphics::Surface *picture = object->getPicture();
+ int value = picture? picture->h: 0;
+ debug("\t->%d", value);
+ push(value);
}
void Process::stub202(unsigned size) {
@@ -399,7 +405,7 @@ void Process::loadRegionFromObject() {
void Process::loadPictureFromObject() {
Common::String name = popFilename();
debug("loadPictureFromObject %s", name.c_str());
- _object->setPicture(_engine->resourceManager().loadPicture(name));
+ _object->setPicture(_engine->loadPicture(name));
}
void Process::loadAnimationFromObject() {
@@ -511,8 +517,8 @@ ProcessExitCode Process::execute() {
OP (kSetGlyphSize, setFontGlyphSize);
OP (kStub188, stub188);
OP (kStub190, stub190);
- OP (kStub195, stub195);
- OP (kStub196, stub196);
+ OP (kGetObjectPictureWidth, getObjectPictureWidth);
+ OP (kGetObjectPictureHeight, getObjectPictureHeight);
OP (kLoadPicture, loadPicture);
OP (kFadeObject, fadeObject);
OP (kLoadFont, loadFont);
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 156dba8034b..7954b876466 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -27,6 +27,7 @@
#include "common/algorithm.h"
#include "common/ptr.h"
#include "image/bmp.h"
+#include "graphics/surface.h"
namespace AGDS {
ResourceManager::ResourceManager()
@@ -145,13 +146,14 @@ namespace AGDS {
return grp.readStream(resource->size);
}
- const Graphics::Surface * ResourceManager::loadPicture(const Common::String & name) {
+ const Graphics::Surface * ResourceManager::loadPicture(const Common::String & name, const Graphics::PixelFormat &format) {
Common::SeekableReadStream *stream = getResource(name);
if (!stream)
return NULL;
Image::BitmapDecoder bmp;
- return bmp.loadStream(*stream)? bmp.getSurface(): NULL;
+ const Graphics::Surface * surface = bmp.loadStream(*stream)? bmp.getSurface()->convertTo(format): NULL;
+ return surface;
}
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 5a2a8a26110..0f83d6a8276 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -30,7 +30,7 @@
#include "common/hashmap.h"
#include "common/hash-str.h"
-namespace Graphics { class Surface; }
+namespace Graphics { class Surface; class PixelFormat; }
namespace AGDS {
@@ -70,7 +70,7 @@ public:
bool addPath(const Common::String &grpFilename);
Common::SeekableReadStream * getResource(const Common::String &name) const;
- const Graphics::Surface * loadPicture(const Common::String & name);
+ const Graphics::Surface * loadPicture(const Common::String & name, const Graphics::PixelFormat &format);
};
Commit: a7b3a165df001970ed8b8dc4ae48c3acadc2ce58
https://github.com/scummvm/scummvm/commit/a7b3a165df001970ed8b8dc4ae48c3acadc2ce58
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:52+01:00
Commit Message:
AGDS: implement object move opcode
Changed paths:
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.h b/engines/agds/object.h
index baad0e55a92..60adb858a02 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -74,6 +74,10 @@ public:
const Graphics::Surface *getPicture() const {
return _picture;
}
+
+ void move(int x, int y) {
+ _x = x; _y = y;
+ }
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 07d4d8f1db8..68a3eb82e12 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -277,7 +277,8 @@ void Process::moveScreenObject() {
int arg2 = pop();
Common::String arg1 = popString();
debug("moveScreenObject %s %d %d", arg1.c_str(), arg2, arg3);
- _engine->loadObject(arg1);
+ Object *object = _engine->loadObject(arg1);
+ object->move(arg2, arg3);
}
void Process::stub190() {
Commit: 6773542b440b3386e027063adf84f413561ce55f
https://github.com/scummvm/scummvm/commit/6773542b440b3386e027063adf84f413561ce55f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:52+01:00
Commit Message:
AGDS: removed colon between name and ip for better readability
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index e4d98ecac1e..d19e6cc5f7e 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -36,7 +36,7 @@ void Process::debug(const char *str, ...) {
va_list va;
va_start(va, str);
- Common::String format = Common::String::format("%s:%04x: %s", _object->getName().c_str(), _lastIp + 7, str);
+ Common::String format = Common::String::format("%s %04x: %s", _object->getName().c_str(), _lastIp + 7, str);
Common::String buf = Common::String::vformat(format.c_str(), va);
buf += '\n';
Commit: 5c3d7044c294bdf41a447319c97e9680565ee39f
https://github.com/scummvm/scummvm/commit/5c3d7044c294bdf41a447319c97e9680565ee39f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:52+01:00
Commit Message:
AGDS: implemented basic screen container
Changed paths:
A engines/agds/screen.cpp
A engines/agds/screen.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/module.mk
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index d4ccfede2d4..f9be84f47c3 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -25,6 +25,7 @@
#include "agds/object.h"
#include "agds/process.h"
#include "agds/region.h"
+#include "agds/screen.h"
#include "common/error.h"
#include "common/events.h"
#include "common/ini-file.h"
@@ -130,6 +131,8 @@ Object *AGDSEngine::loadObject(const Common::String & name) {
delete stream;
_processes.push_front(Process(this, object));
+ if (_currentScreen)
+ _currentScreen->add(object);
return object;
}
@@ -147,7 +150,9 @@ void AGDSEngine::runProcess() {
case kExitCodeDestroyProcessSetNextScreen: {
Common::String screen = process.getExitValue();
debug("loading screen object %s", screen.c_str());
- _currentScreen = loadObject(screen);
+ _currentScreen = new Screen(loadObject(screen));
+ delete _screens[screen];
+ _screens[screen] = _currentScreen;
}
break;
case kExitCodeSuspend:
@@ -186,6 +191,7 @@ Common::Error AGDSEngine::run() {
runProcess();
Graphics::Surface *backbuffer = _system->lockScreen();
+ backbuffer->fillRect(Common::Rect(0, 0, backbuffer->w, backbuffer->h), 0);
if (_mjpgPlayer) {
const Graphics::Surface *surface = _mjpgPlayer->decodeFrame();
@@ -202,6 +208,8 @@ Common::Error AGDSEngine::run() {
delete _mjpgPlayer;
_mjpgPlayer = NULL;
}
+ } else {
+ _currentScreen->paint(*backbuffer);
}
Common::Event event;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 5ba99eeb541..dfb36f1653f 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -45,6 +45,7 @@ class Object;
class Process;
class Region;
class MJPGPlayer;
+class Screen;
class AGDSEngine : public Engine {
friend class Process;
@@ -87,11 +88,16 @@ private:
return _resourceManager;
}
+ Screen *currentScreen() {
+ return _currentScreen;
+ }
+
const Graphics::Surface * loadPicture(const Common::String &name)
{ return _resourceManager.loadPicture(name, _pixelFormat); }
private:
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
+ typedef Common::HashMap<Common::String, Screen *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ScreensType;
typedef Common::List<Process> ProcessListType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
@@ -99,6 +105,7 @@ private:
ResourceManager _resourceManager;
Database _data, _patch; //data and patch databases
ObjectsType _objects;
+ ScreensType _screens;
ProcessListType _processes;
Common::String _nextScreen;
int _sharedStorageIndex;
@@ -107,7 +114,7 @@ private:
int _timer;
Graphics::PixelFormat _pixelFormat;
MJPGPlayer * _mjpgPlayer;
- Object * _currentScreen;
+ Screen * _currentScreen;
};
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index f36bb13e7f9..cd9ebd7aaf7 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -9,7 +9,8 @@ MODULE_OBJS := \
process.o \
process_opcodes.o \
region.o \
- resourceManager.o
+ resourceManager.o \
+ screen.o
# This module can be built as a plugin
ifeq ($(ENABLE_AGDS), DYNAMIC_PLUGIN)
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 016dcab57d3..3ff3a5988ef 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -23,6 +23,8 @@
#include "agds/object.h"
#include "common/debug.h"
#include "common/memstream.h"
+#include "common/rect.h"
+#include "graphics/surface.h"
namespace AGDS {
@@ -90,4 +92,10 @@ void Object::setPicture(const Graphics::Surface *picture) {
_picture = picture;
}
+void Object::paint(Graphics::Surface &backbuffer) {
+ if (_picture)
+ backbuffer.copyRectToSurface(*_picture, _x, _y, Common::Rect(0, 0, _picture->w, _picture->h));
+}
+
+
}
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 60adb858a02..84ebe5fac1b 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -75,6 +75,8 @@ public:
return _picture;
}
+ void paint(Graphics::Surface &backbuffer);
+
void move(int x, int y) {
_x = x; _y = y;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 68a3eb82e12..dcf058e7fa8 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -327,6 +327,7 @@ void Process::stub206() {
}
void Process::exitProcessSetNextScreen() {
+ debug("exitProcessSetNextScreen");
_exitValue = popString();
_exitCode = kExitCodeDestroyProcessSetNextScreen;
_status = kStatusPassive;
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
new file mode 100644
index 00000000000..434ebff5ad5
--- /dev/null
+++ b/engines/agds/screen.cpp
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/screen.h"
+#include "agds/object.h"
+
+namespace AGDS {
+
+Screen::Screen(Object *object) {
+ add(object);
+}
+
+void Screen::add(Object *object) {
+ _children.push_back(object);
+}
+
+void Screen::remove(const Common::String &name) {
+ for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ) {
+ if ((*i)->getName() == name)
+ i = _children.erase(i);
+ else
+ ++i;
+ }
+}
+
+
+void Screen::paint(Graphics::Surface &backbuffer) {
+ for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
+ (*i)->paint(backbuffer);
+ }
+}
+
+
+}
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
new file mode 100644
index 00000000000..7d15d46d013
--- /dev/null
+++ b/engines/agds/screen.h
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_SCREEN_H
+#define AGDS_SCREEN_H
+
+#include "common/scummsys.h"
+#include "common/list.h"
+#include "common/str.h"
+
+namespace Graphics {
+ class Surface;
+}
+
+namespace AGDS {
+
+class Object;
+
+class Screen {
+ typedef Common::List<Object *> ChildrenType;
+ ChildrenType _children;
+
+public:
+ Screen(Object *object);
+ void add(Object *object);
+ void remove(const Common::String &name);
+ void paint(Graphics::Surface &backbuffer);
+};
+
+
+} // End of namespace AGDS
+
+#endif /* AGDS_SCREEN_H */
Commit: e16e1c28c223368e2fd6ea7d1eba965ca19e1315
https://github.com/scummvm/scummvm/commit/e16e1c28c223368e2fd6ea7d1eba965ca19e1315
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:52+01:00
Commit Message:
AGDS: removed _nextScreen, cleaned up screen handling
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index f9be84f47c3..6c9ac2149a6 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -86,7 +86,7 @@ bool AGDSEngine::load() {
return false;
_patch.open("patch.adb"); //it's ok
- _nextScreen = "main";
+ _currentScreen = loadScreen("main");
return true;
}
@@ -136,6 +136,17 @@ Object *AGDSEngine::loadObject(const Common::String & name) {
return object;
}
+Screen *AGDSEngine::loadScreen(const Common::String & name) {
+ ScreensType::iterator i = _screens.find(name);
+ if (i != _screens.end())
+ return i->_value;
+
+ debug("loadScreen %s", name.c_str());
+ Screen *screen = new Screen(loadObject(name));
+ _screens[name] = screen;
+ return screen;
+}
+
void AGDSEngine::runProcess() {
for(ProcessListType::iterator p = _processes.begin(); active() && p != _processes.end(); ) {
Process & process = *p;
@@ -147,13 +158,10 @@ void AGDSEngine::runProcess() {
ProcessExitCode code = process.execute();
switch(code) {
case kExitCodeLoadScreenObject:
- case kExitCodeDestroyProcessSetNextScreen: {
- Common::String screen = process.getExitValue();
- debug("loading screen object %s", screen.c_str());
- _currentScreen = new Screen(loadObject(screen));
- delete _screens[screen];
- _screens[screen] = _currentScreen;
- }
+ loadObject(process.getExitValue());
+ break;
+ case kExitCodeDestroyProcessSetNextScreen:
+ _currentScreen = loadScreen(process.getExitValue());
break;
case kExitCodeSuspend:
debug("process suspended");
@@ -179,14 +187,6 @@ Common::Error AGDSEngine::run() {
if (_timer > 0)
--_timer;
- if (!_nextScreen.empty()) {
- debug("loading screen %s", _nextScreen.c_str());
- Common::String nextScreen;
- nextScreen = _nextScreen;
- _nextScreen.clear();
- loadObject(nextScreen);
- }
-
while(active() && !_processes.empty())
runProcess();
@@ -208,7 +208,7 @@ Common::Error AGDSEngine::run() {
delete _mjpgPlayer;
_mjpgPlayer = NULL;
}
- } else {
+ } else if (_currentScreen) {
_currentScreen->paint(*backbuffer);
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index dfb36f1653f..067a97465f7 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -62,6 +62,7 @@ private:
void runProcess();
Object * loadObject(const Common::String & name);
+ Screen * loadScreen(const Common::String & name);
Region * loadRegion(const Common::String &name);
Common::String loadFilename(const Common::String &name);
@@ -107,7 +108,6 @@ private:
ObjectsType _objects;
ScreensType _screens;
ProcessListType _processes;
- Common::String _nextScreen;
int _sharedStorageIndex;
Common::String _sharedStorage[10];
GlobalsType _globals;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index dcf058e7fa8..1b2d51d8d85 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -24,6 +24,7 @@
#include "agds/agds.h"
#include "agds/opcode.h"
#include "agds/region.h"
+#include "agds/screen.h"
#include "common/debug.h"
namespace AGDS {
@@ -107,6 +108,9 @@ void Process::loadScreenObject() {
void Process::removeScreenObject() {
Common::String name = popString();
debug("removeScreenObject: %s", name.c_str());
+ Screen *screen = _engine->currentScreen();
+ if (screen)
+ screen->remove(name);
}
void Process::loadFont() {
Commit: a81447479fb37acf145f1f89a7324695d4314403
https://github.com/scummvm/scummvm/commit/a81447479fb37acf145f1f89a7324695d4314403
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:52+01:00
Commit Message:
AGDS: return control to main loop on process suspend
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 6c9ac2149a6..f2f3b092abb 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -165,7 +165,7 @@ void AGDSEngine::runProcess() {
break;
case kExitCodeSuspend:
debug("process suspended");
- break;
+ return;
default:
debug("destroying process...");
p = _processes.erase(p);
@@ -187,7 +187,7 @@ Common::Error AGDSEngine::run() {
if (_timer > 0)
--_timer;
- while(active() && !_processes.empty())
+ if (active())
runProcess();
Graphics::Surface *backbuffer = _system->lockScreen();
Commit: 853c43a3becf279fdd2f8dc61ff3439c042b216f
https://github.com/scummvm/scummvm/commit/853c43a3becf279fdd2f8dc61ff3439c042b216f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:52+01:00
Commit Message:
AGDS: properly crop out-of-screen rects
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 3ff3a5988ef..87e2395a5d6 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -93,8 +93,20 @@ void Object::setPicture(const Graphics::Surface *picture) {
}
void Object::paint(Graphics::Surface &backbuffer) {
- if (_picture)
- backbuffer.copyRectToSurface(*_picture, _x, _y, Common::Rect(0, 0, _picture->w, _picture->h));
+ if (_picture) {
+ Common::Rect srcRect(0, 0, _picture->w, _picture->h);
+ int x = _x, y = _y;
+ if (x < 0) {
+ srcRect.left += -x;
+ x = 0;
+ }
+ if (y < 0) {
+ srcRect.top += -y;
+ y = 0;
+ }
+ if (!srcRect.isEmpty())
+ backbuffer.copyRectToSurface(*_picture, x, y, srcRect);
+ }
}
Commit: 874aaad489cc5daa4e0dee976a922512157108f3
https://github.com/scummvm/scummvm/commit/874aaad489cc5daa4e0dee976a922512157108f3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:52+01:00
Commit Message:
AGDS: added getters for object x/y
Changed paths:
engines/agds/object.h
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 84ebe5fac1b..a6e4ba540f1 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -80,6 +80,12 @@ public:
void move(int x, int y) {
_x = x; _y = y;
}
+ int getX() const {
+ return _x;
+ }
+ int getY() const {
+ return _y;
+ }
};
Commit: 2eded2059ee32178eff5295551ccc1aebf90eab2
https://github.com/scummvm/scummvm/commit/2eded2059ee32178eff5295551ccc1aebf90eab2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:53+01:00
Commit Message:
AGDS: added mouse move event handling
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index f2f3b092abb..70ec2c7ad28 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -38,7 +38,8 @@ namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
_gameDescription(gameDesc), _sharedStorageIndex(-2), _timer(0),
- _mjpgPlayer(NULL), _currentScreen(NULL) {
+ _mjpgPlayer(NULL), _currentScreen(NULL),
+ _mouse(400, 300) {
}
AGDSEngine::~AGDSEngine() {
@@ -187,6 +188,17 @@ Common::Error AGDSEngine::run() {
if (_timer > 0)
--_timer;
+ Common::Event event;
+ while(eventManager->pollEvent(event)) {
+ switch(event.type) {
+ case Common::EVENT_MOUSEMOVE:
+ _mouse = event.mouse;
+ break;
+ default:
+ break;
+ }
+ }
+
if (active())
runProcess();
@@ -212,9 +224,6 @@ Common::Error AGDSEngine::run() {
_currentScreen->paint(*backbuffer);
}
- Common::Event event;
- while(eventManager->pollEvent(event)) {
- }
_system->unlockScreen();
_system->updateScreen();
_system->delayMillis(40);
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 067a97465f7..48f7a861cff 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/hashmap.h"
+#include "common/rect.h"
#include "engines/advancedDetector.h"
#include "agds/database.h"
#include "agds/processExitCode.h"
@@ -115,6 +116,7 @@ private:
Graphics::PixelFormat _pixelFormat;
MJPGPlayer * _mjpgPlayer;
Screen * _currentScreen;
+ Common::Point _mouse;
};
Commit: 7582419ef2bd05e9a60db5b3000774309bd54545
https://github.com/scummvm/scummvm/commit/7582419ef2bd05e9a60db5b3000774309bd54545
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:53+01:00
Commit Message:
AGDS: added FLC mouse pointer loading and rendering support
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 70ec2c7ad28..56d60cb3c2f 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -38,8 +38,8 @@ namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
_gameDescription(gameDesc), _sharedStorageIndex(-2), _timer(0),
- _mjpgPlayer(NULL), _currentScreen(NULL),
- _mouse(400, 300) {
+ _mjpgPlayer(NULL), _currentScreen(NULL), _mouseCursor(NULL),
+ _mouse(400, 300), _userEnabled(false) {
}
AGDSEngine::~AGDSEngine() {
@@ -203,7 +203,7 @@ Common::Error AGDSEngine::run() {
runProcess();
Graphics::Surface *backbuffer = _system->lockScreen();
- backbuffer->fillRect(Common::Rect(0, 0, backbuffer->w, backbuffer->h), 0);
+ backbuffer->fillRect(backbuffer->getRect(), 0);
if (_mjpgPlayer) {
const Graphics::Surface *surface = _mjpgPlayer->decodeFrame();
@@ -212,7 +212,7 @@ Common::Error AGDSEngine::run() {
Graphics::Surface * converted = surface->convertTo(backbuffer->format);
int x = (backbuffer->w - converted->w) / 2;
int y = (backbuffer->h - converted->h) / 2;
- backbuffer->copyRectToSurface(*converted, x, y, Common::Rect(0, 0, converted->w, converted->h));
+ backbuffer->copyRectToSurface(*converted, x, y, converted->getRect());
delete converted;
}
@@ -224,6 +224,20 @@ Common::Error AGDSEngine::run() {
_currentScreen->paint(*backbuffer);
}
+ if (_userEnabled && _mouseCursor) {
+ const Graphics::Surface * frame = _mouseCursor->decodeNextFrame();
+ if (!frame) {
+ _mouseCursor->rewind();
+ frame = _mouseCursor->decodeNextFrame();
+ }
+ Graphics::Surface * c = frame->convertTo(_pixelFormat, _mouseCursor->getPalette());
+ Common::Point dst = _mouse;
+ Common::Rect srcRect = c->getRect();
+ if (Common::Rect::getBlitRect(dst, srcRect, backbuffer->getRect()))
+ backbuffer->copyRectToSurface(*c, dst.x, dst.y, srcRect);
+ delete c;
+ }
+
_system->unlockScreen();
_system->updateScreen();
_system->delayMillis(40);
@@ -263,6 +277,14 @@ int AGDSEngine::getGlobal(const Common::String &name) const {
}
}
+void AGDSEngine::loadCursor(const Common::String &name, unsigned index) {
+ Video::FlicDecoder * cursor = new Video::FlicDecoder;
+ if (cursor->loadStream(_resourceManager.getResource(name))) {
+ delete _mouseCursor;
+ _mouseCursor = cursor;
+ } else
+ delete cursor;
+}
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 48f7a861cff..df5ce6a222d 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -31,6 +31,7 @@
#include "agds/processExitCode.h"
#include "agds/resourceManager.h"
#include "graphics/pixelformat.h"
+#include "video/flic_decoder.h"
/**
* This is the namespace of the AGDS engine.
@@ -97,6 +98,11 @@ private:
const Graphics::Surface * loadPicture(const Common::String &name)
{ return _resourceManager.loadPicture(name, _pixelFormat); }
+ void loadCursor(const Common::String &name, unsigned index = 0);
+ void enableUser(bool enabled) {
+ _userEnabled = enabled;
+ }
+
private:
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
typedef Common::HashMap<Common::String, Screen *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ScreensType;
@@ -116,7 +122,9 @@ private:
Graphics::PixelFormat _pixelFormat;
MJPGPlayer * _mjpgPlayer;
Screen * _currentScreen;
+ Video::FlicDecoder * _mouseCursor;
Common::Point _mouse;
+ bool _userEnabled;
};
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 87e2395a5d6..a765537e3e9 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -28,7 +28,7 @@
namespace AGDS {
-Object::Object(const Common::String &name, Common::SeekableReadStream * stream) : _name(name), _stringTableLoaded(false), _picture(), _x(), _y() {
+Object::Object(const Common::String &name, Common::SeekableReadStream * stream) : _name(name), _stringTableLoaded(false), _picture(), _pos() {
byte id = stream->readByte();
byte flag = stream->readByte();
debug("id: 0x%02x %u, flag: %u", id, id, flag);
@@ -94,18 +94,10 @@ void Object::setPicture(const Graphics::Surface *picture) {
void Object::paint(Graphics::Surface &backbuffer) {
if (_picture) {
- Common::Rect srcRect(0, 0, _picture->w, _picture->h);
- int x = _x, y = _y;
- if (x < 0) {
- srcRect.left += -x;
- x = 0;
- }
- if (y < 0) {
- srcRect.top += -y;
- y = 0;
- }
- if (!srcRect.isEmpty())
- backbuffer.copyRectToSurface(*_picture, x, y, srcRect);
+ Common::Point dst = _pos;
+ Common::Rect srcRect = _picture->getRect();
+ if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
+ backbuffer.copyRectToSurface(*_picture, dst.x, dst.y, srcRect);
}
}
diff --git a/engines/agds/object.h b/engines/agds/object.h
index a6e4ba540f1..7f96436fa3b 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -51,7 +51,7 @@ private:
StringTableType _stringTable;
bool _stringTableLoaded;
const Graphics::Surface * _picture;
- int _x, _y;
+ Common::Point _pos;
public:
@@ -77,14 +77,15 @@ public:
void paint(Graphics::Surface &backbuffer);
- void move(int x, int y) {
- _x = x; _y = y;
+ void move(Common::Point pos) {
+ _pos = pos;
}
+
int getX() const {
- return _x;
+ return _pos.x;
}
int getY() const {
- return _y;
+ return _pos.y;
}
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 1b2d51d8d85..b57705f092e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -182,6 +182,7 @@ void Process::appendToSharedStorage() {
void Process::disableUser() {
debug("disableUser");
+ _engine->enableUser(false);
}
void Process::changeScreenPatch() {
@@ -195,6 +196,7 @@ void Process::changeScreenPatch() {
void Process::loadMouseStub66() {
Common::String name = popFilename();
debug("loadMouseStub66 %s", name.c_str());
+ _engine->loadCursor(name);
}
void Process::fadeObject() {
@@ -282,7 +284,7 @@ void Process::moveScreenObject() {
Common::String arg1 = popString();
debug("moveScreenObject %s %d %d", arg1.c_str(), arg2, arg3);
Object *object = _engine->loadObject(arg1);
- object->move(arg2, arg3);
+ object->move(Common::Point(arg2, arg3));
}
void Process::stub190() {
@@ -384,6 +386,7 @@ void Process::onUse(unsigned size) {
void Process::enableUser() {
//screen loading block user interaction until this instruction
debug("enableUser");
+ _engine->enableUser(true);
}
void Process::findObjectInMouseArea() {
Commit: 9f56d51f5f3dfb5d5194f33a780933694b453896
https://github.com/scummvm/scummvm/commit/9f56d51f5f3dfb5d5194f33a780933694b453896
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:53+01:00
Commit Message:
AGDS: pick up pixel format supported by transparent surface
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 56d60cb3c2f..11565d64874 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -33,6 +33,7 @@
#include "common/debug.h"
#include "common/system.h"
#include "engines/util.h"
+#include "graphics/transparent_surface.h"
namespace AGDS {
@@ -50,16 +51,16 @@ bool AGDSEngine::initGraphics() {
typedef Common::List<Graphics::PixelFormat> FormatsType;
FormatsType formats = _system->getSupportedFormats();
- FormatsType::iterator fi;
- for(fi = formats.begin(); fi != formats.end(); ++fi) {
- if (fi->bytesPerPixel == 4) {
- debug("found mode %s", fi->toString().c_str());
- _pixelFormat = *fi;
+ for(FormatsType::iterator fi = formats.begin(); fi != formats.end(); ++fi) {
+ const Graphics::PixelFormat & format = *fi;
+ if (fi->bytesPerPixel == 4 && format == Graphics::TransparentSurface::getSupportedPixelFormat()) {
+ debug("found mode %s", format.toString().c_str());
+ _pixelFormat = format;
::initGraphics(800, 600, &_pixelFormat);
return true;
}
}
- error("nope");
+ error("no supported video format found");
return false;
}
Commit: 60ffd747f693a5aeb683b8bc0739f64e10ea0ff5
https://github.com/scummvm/scummvm/commit/60ffd747f693a5aeb683b8bc0739f64e10ea0ff5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:53+01:00
Commit Message:
AGDS: added TransparentSurface support, convert colorkeyed surfaces to surfaces with alpha
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/resourceManager.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 11565d64874..737a2abcc74 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -210,10 +210,11 @@ Common::Error AGDSEngine::run() {
const Graphics::Surface *surface = _mjpgPlayer->decodeFrame();
if (surface) {
- Graphics::Surface * converted = surface->convertTo(backbuffer->format);
- int x = (backbuffer->w - converted->w) / 2;
- int y = (backbuffer->h - converted->h) / 2;
- backbuffer->copyRectToSurface(*converted, x, y, converted->getRect());
+ Graphics::Surface * converted = surface->convertTo(_pixelFormat);
+ Common::Point dst((backbuffer->w - converted->w) / 2, (backbuffer->h - converted->h) / 2);
+ Common::Rect srcRect(converted->getRect());
+ if (Common::Rect::getBlitRect(dst, srcRect, converted->getRect()))
+ backbuffer->copyRectToSurface(*converted, dst.x, dst.y, srcRect);
delete converted;
}
@@ -231,11 +232,11 @@ Common::Error AGDSEngine::run() {
_mouseCursor->rewind();
frame = _mouseCursor->decodeNextFrame();
}
- Graphics::Surface * c = frame->convertTo(_pixelFormat, _mouseCursor->getPalette());
+ Graphics::TransparentSurface * c = convertToTransparent(frame->convertTo(_pixelFormat, _mouseCursor->getPalette()));
Common::Point dst = _mouse;
Common::Rect srcRect = c->getRect();
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer->getRect()))
- backbuffer->copyRectToSurface(*c, dst.x, dst.y, srcRect);
+ c->blit(*backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
delete c;
}
@@ -287,5 +288,16 @@ void AGDSEngine::loadCursor(const Common::String &name, unsigned index) {
delete cursor;
}
+const Graphics::Surface * AGDSEngine::loadPicture(const Common::String &name)
+{ return convertToTransparent(_resourceManager.loadPicture(name, _pixelFormat)); }
+
+Graphics::TransparentSurface *AGDSEngine::convertToTransparent(const Graphics::Surface *surface) {
+ if (!surface)
+ return NULL;
+ Graphics::TransparentSurface * t = new Graphics::TransparentSurface(*surface, true);
+ t->applyColorKey(0xff, 0, 0xff, true);
+ delete surface;
+ return t;
+}
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index df5ce6a222d..de750b75459 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -41,6 +41,9 @@
* Games using this engine:
* - Black Mirror (Windows)
*/
+
+namespace Graphics { class TransparentSurface; }
+
namespace AGDS {
class Object;
@@ -95,8 +98,8 @@ private:
return _currentScreen;
}
- const Graphics::Surface * loadPicture(const Common::String &name)
- { return _resourceManager.loadPicture(name, _pixelFormat); }
+ const Graphics::Surface * loadPicture(const Common::String &name);
+ Graphics::TransparentSurface *convertToTransparent(const Graphics::Surface *surface); //destroys surface!
void loadCursor(const Common::String &name, unsigned index = 0);
void enableUser(bool enabled) {
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 7954b876466..50976f6e268 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -152,8 +152,7 @@ namespace AGDS {
return NULL;
Image::BitmapDecoder bmp;
- const Graphics::Surface * surface = bmp.loadStream(*stream)? bmp.getSurface()->convertTo(format): NULL;
- return surface;
+ return bmp.loadStream(*stream)? bmp.getSurface()->convertTo(format): NULL;
}
Commit: fc226e4ce603b90c4e8709fd3e1b6bae0cc4ec5b
https://github.com/scummvm/scummvm/commit/fc226e4ce603b90c4e8709fd3e1b6bae0cc4ec5b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:53+01:00
Commit Message:
AGDS: fixed invalid clipping rect for movies
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 737a2abcc74..2570ca56518 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -213,7 +213,7 @@ Common::Error AGDSEngine::run() {
Graphics::Surface * converted = surface->convertTo(_pixelFormat);
Common::Point dst((backbuffer->w - converted->w) / 2, (backbuffer->h - converted->h) / 2);
Common::Rect srcRect(converted->getRect());
- if (Common::Rect::getBlitRect(dst, srcRect, converted->getRect()))
+ if (Common::Rect::getBlitRect(dst, srcRect, backbuffer->getRect()))
backbuffer->copyRectToSurface(*converted, dst.x, dst.y, srcRect);
delete converted;
}
Commit: 352ceeee43457e88fae86a6948e12cec33c60366
https://github.com/scummvm/scummvm/commit/352ceeee43457e88fae86a6948e12cec33c60366
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:53+01:00
Commit Message:
AGDS: improved region support
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
engines/agds/region.cpp
engines/agds/region.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 2570ca56518..e2b0b65b388 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -94,11 +94,20 @@ bool AGDSEngine::load() {
}
Region * AGDSEngine::loadRegion(const Common::String &name) {
+ RegionsType::iterator i = _regions.find(name);
+ if (i != _regions.end())
+ return i->_value;
+
debug("loading region %s", name.c_str());
Common::SeekableReadStream * stream = _data.getEntry(name);
if (!stream)
error("no database entry for %s\n", name.c_str());
- return new Region(name, stream);
+
+ Region *region = new Region(name, stream);
+ delete stream;
+
+ _regions[name] = region;
+ return region;
}
Common::String AGDSEngine::loadFilename(const Common::String &entryName) {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index de750b75459..30ebfc0ca50 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -109,6 +109,7 @@ private:
private:
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
typedef Common::HashMap<Common::String, Screen *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ScreensType;
+ typedef Common::HashMap<Common::String, Region *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> RegionsType;
typedef Common::List<Process> ProcessListType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
@@ -117,6 +118,7 @@ private:
Database _data, _patch; //data and patch databases
ObjectsType _objects;
ScreensType _screens;
+ RegionsType _regions;
ProcessListType _processes;
int _sharedStorageIndex;
Common::String _sharedStorage[10];
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index ff58df68ebf..135db3fb233 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -163,8 +163,8 @@ enum Opcode {
kSetIntegerVariable = 143,
kStub144 = 144,
kStub145 = 145,
- kGetRegionWidth = 146,
- kGetRegionHeight = 147,
+ kGetRegionCenterX = 146,
+ kGetRegionCenterY = 147,
kStub148 = 148,
kStub149 = 149,
kStub150 = 150,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 87b69ceb051..e85888ba46a 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -107,8 +107,8 @@ private:
void loadAnimation();
void loadSample();
void setTimer();
- void getRegionWidth();
- void getRegionHeight();
+ void getRegionCenterX();
+ void getRegionCenterY();
void fadeObject();
void moveScreenObject();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b57705f092e..198885c8670 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -63,22 +63,20 @@ void Process::getIntegerSystemVariable() {
push(value);
}
-void Process::getRegionWidth() {
+void Process::getRegionCenterX() {
Common::String name = popString();
Region *reg = _engine->loadRegion(name);
- int value = reg->width;
+ int value = reg->centerX;
push(value);
- delete reg;
- debug("getRegionWidth %s -> %d", name.c_str(), value);
+ debug("getRegionCenterX %s -> %d", name.c_str(), value);
}
-void Process::getRegionHeight() {
+void Process::getRegionCenterY() {
Common::String name = popString();
Region *reg = _engine->loadRegion(name);
- int value = reg->height;
+ int value = reg->centerY;
push(value);
- delete reg;
- debug("getRegionHeight %s -> %d", name.c_str(), value);
+ debug("getRegionCenterY %s -> %d", name.c_str(), value);
}
@@ -396,7 +394,6 @@ void Process::findObjectInMouseArea() {
debug("findObjectInMouseArea %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
Region *reg = _engine->loadRegion(arg1);
- delete reg;
push(205);
_engine->loadObject(arg2);
@@ -514,8 +511,8 @@ ProcessExitCode Process::execute() {
OP (kScreenChangeScreenPatch, changeScreenPatch);
OP (kSetSystemVariable, setSystemVariable);
OP (kSetIntegerVariable, setIntegerVariable);
- OP (kGetRegionWidth, getRegionWidth);
- OP (kGetRegionHeight, getRegionHeight);
+ OP (kGetRegionCenterX, getRegionCenterX);
+ OP (kGetRegionCenterY, getRegionCenterY);
OP (kGetIntegerSystemVariable, getIntegerSystemVariable);
OP (kAppendToSharedStorage, appendToSharedStorage);
OP (kStub154, stub154);
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index f5b0a82de8e..e764bc68e72 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -41,25 +41,30 @@ Region::Region(const Common::String &resourceName, Common::SeekableReadStream *
error("invalid region %s", resourceName.c_str());
byte * nameEnd = Common::find(header, header + 0x20, 0);
name = Common::String(reinterpret_cast<char *>(header), nameEnd - header);
- width = READ_UINT16(header + kRegionHeaderWidthOffset);
- height = READ_UINT16(header + kRegionHeaderHeightOffset);
+ centerX = READ_UINT16(header + kRegionHeaderWidthOffset);
+ centerY = READ_UINT16(header + kRegionHeaderHeightOffset);
flags = READ_UINT16(header + kRegionHeaderFlagsOffset);
- debug("region %s %dx%d %04x", name.c_str(), width, height, flags);
+ debug("region %s at (%d,%d) %04x", name.c_str(), centerX, centerY, flags);
if (size > kRegionHeaderSize) {
uint16 ext = stream->readUint16LE();
- debug("extended entries %u", ext);
+ //debug("extended entries %u", ext);
while(ext--) {
int16 a = stream->readSint16LE();
int16 b = stream->readSint16LE();
- int16 c = stream->readUint16LE();
- if (c != -12851) //0xcdcd
- debug("extended entry: %d %d %d", a, b, c);
- else
- debug("extended entry: %d %d", a, b);
+ /* int16 c = */ stream->readUint16LE();
+// if (c != -12851) //0xcdcd
+// debug("extended entry: %d %d %d", a, b, c);
+// else
+// debug("extended entry: %d %d", a, b);
+ points.push_back(Common::Point(a, b));
}
if (stream->pos() != size)
- debug("region data left: %u", size - stream->pos());
+ warning("region data left: %u", size - stream->pos());
}
}
+bool Region::pointIn(Common::Point point) const {
+ return false;
+}
+
}
diff --git a/engines/agds/region.h b/engines/agds/region.h
index 1503dea814e..a0c7d508fd3 100644
--- a/engines/agds/region.h
+++ b/engines/agds/region.h
@@ -24,16 +24,24 @@
#define AGDS_REGION_H
#include "common/scummsys.h"
+#include "common/array.h"
#include "common/stream.h"
+#include "common/rect.h"
namespace AGDS {
struct Region {
+ typedef Common::Array<Common::Point> PointsType;
+
Common::String name;
- uint16 width;
- uint16 height;
+ uint16 centerX;
+ uint16 centerY;
uint16 flags;
+ PointsType points;
+
Region(const Common::String &resourceName, Common::SeekableReadStream * stream);
+
+ bool pointIn(Common::Point point) const;
};
Commit: 4969a1184c4ec15da9212ae1b118370f919a973e
https://github.com/scummvm/scummvm/commit/4969a1184c4ec15da9212ae1b118370f919a973e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:53+01:00
Commit Message:
AGDS: added region to object, allowed searching object in scene
Changed paths:
engines/agds/agds.cpp
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
engines/agds/region.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index e2b0b65b388..afcc34c1270 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -204,6 +204,14 @@ Common::Error AGDSEngine::run() {
case Common::EVENT_MOUSEMOVE:
_mouse = event.mouse;
break;
+ case Common::EVENT_LBUTTONDOWN:
+ _mouse = event.mouse;
+ if (_userEnabled && _currentScreen) {
+ debug("lclick %d, %d", _mouse.x, _mouse.y);
+ Object *object = _currentScreen->find(_mouse);
+ debug("found object %p", (void *)object);
+ }
+ break;
default:
break;
}
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index a765537e3e9..be1f2afe8df 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -28,7 +28,7 @@
namespace AGDS {
-Object::Object(const Common::String &name, Common::SeekableReadStream * stream) : _name(name), _stringTableLoaded(false), _picture(), _pos() {
+Object::Object(const Common::String &name, Common::SeekableReadStream * stream) : _name(name), _stringTableLoaded(false), _picture(), _pos(), _region() {
byte id = stream->readByte();
byte flag = stream->readByte();
debug("id: 0x%02x %u, flag: %u", id, id, flag);
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 7f96436fa3b..2b787d31df9 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -30,6 +30,8 @@
namespace AGDS {
+class Region;
+
class Object {
public:
typedef Common::Array<uint8> CodeType;
@@ -51,8 +53,9 @@ private:
StringTableType _stringTable;
bool _stringTableLoaded;
const Graphics::Surface * _picture;
+ Region * _region;
Common::Point _pos;
-
+ unsigned _clickHandler;
public:
Object(const Common::String &name, Common::SeekableReadStream * stream);
@@ -75,6 +78,18 @@ public:
return _picture;
}
+ void setRegion(Region *region) {
+ _region = region;
+ }
+
+ Region * getRegion() const {
+ return _region;
+ }
+
+ void setClickHandler(uint32 ip) {
+ _clickHandler = ip;
+ }
+
void paint(Graphics::Surface &backbuffer);
void move(Common::Point pos) {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 198885c8670..f1cdf3d0a2a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -120,6 +120,7 @@ void Process::loadFont() {
void Process::loadMouse() {
Common::String name = popFilename();
debug("loadMouse %s", name.c_str());
+ _engine->loadCursor(name);
}
void Process::setIntegerVariable() {
@@ -194,7 +195,7 @@ void Process::changeScreenPatch() {
void Process::loadMouseStub66() {
Common::String name = popFilename();
debug("loadMouseStub66 %s", name.c_str());
- _engine->loadCursor(name);
+ //_engine->loadCursor(name); //overlay cursor
}
void Process::fadeObject() {
@@ -377,6 +378,7 @@ void Process::onKey(unsigned size) {
void Process::onUse(unsigned size) {
debug("use? handler, %u instructions", size);
+ _object->setClickHandler(_ip);
_ip += size;
}
@@ -393,18 +395,17 @@ void Process::findObjectInMouseArea() {
Common::String arg1 = popString();
debug("findObjectInMouseArea %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
- Region *reg = _engine->loadRegion(arg1);
+ _engine->loadRegion(arg1);
push(205);
- _engine->loadObject(arg2);
- _engine->loadObject(arg3);
+ _engine->currentScreen()->add(_engine->loadObject(arg2));
+ _engine->currentScreen()->add(_engine->loadObject(arg3));
}
void Process::loadRegionFromObject() {
Common::String name = popString();
debug("loadRegionFromObject %s", name.c_str());
- Region *reg = _engine->loadRegion(name);
- delete reg;
+ _object->setRegion(_engine->loadRegion(name));
}
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index e764bc68e72..fd17f0d7753 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -63,8 +63,54 @@ Region::Region(const Common::String &resourceName, Common::SeekableReadStream *
}
}
+//FIXME: copied from wintermute/base_region.cpp
+
+typedef struct {
+ double x, y;
+} dPoint;
+
bool Region::pointIn(Common::Point point) const {
- return false;
+ debug("POINT IN");
+ uint32 size = points.size();
+ if (size < 3) {
+ return false;
+ }
+
+ int counter = 0;
+ double xinters;
+ dPoint p, p1, p2;
+
+ p.x = (double)point.x;
+ p.y = (double)point.y;
+
+ p1.x = (double)points[0].x;
+ p1.y = (double)points[0].y;
+
+ for (uint32 i = 1; i <= size; i++) {
+ p2.x = (double)points[i % size].x;
+ p2.y = (double)points[i % size].y;
+ debug("%g %g %g %g", p1.x, p1.y, p2.x, p2.y);
+
+ if (p.y > MIN(p1.y, p2.y)) {
+ if (p.y <= MAX(p1.y, p2.y)) {
+ if (p.x <= MAX(p1.x, p2.x)) {
+ if (p1.y != p2.y) {
+ xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
+ if (p1.x == p2.x || p.x <= xinters) {
+ counter++;
+ }
+ }
+ }
+ }
+ }
+ p1 = p2;
+ }
+
+ if (counter % 2 == 0) {
+ return false;
+ } else {
+ return true;
+ }
}
}
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 434ebff5ad5..9300d145f02 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -22,6 +22,7 @@
#include "agds/screen.h"
#include "agds/object.h"
+#include "agds/region.h"
namespace AGDS {
@@ -30,6 +31,10 @@ Screen::Screen(Object *object) {
}
void Screen::add(Object *object) {
+ for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
+ if (*i == object)
+ return;
+ }
_children.push_back(object);
}
@@ -45,8 +50,19 @@ void Screen::remove(const Common::String &name) {
void Screen::paint(Graphics::Surface &backbuffer) {
for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
- (*i)->paint(backbuffer);
+ Object *object = *i;
+ object->paint(backbuffer);
+ }
+}
+
+Object *Screen::find(Common::Point pos) const {
+ for(ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
+ Object *object = *i;
+ Region *region = object->getRegion();
+ if (region && region->pointIn(pos))
+ return object;
}
+ return NULL;
}
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 7d15d46d013..3428c17940f 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/list.h"
#include "common/str.h"
+#include "common/rect.h"
namespace Graphics {
class Surface;
@@ -44,6 +45,7 @@ public:
void add(Object *object);
void remove(const Common::String &name);
void paint(Graphics::Surface &backbuffer);
+ Object *find(Common::Point pos) const;
};
Commit: a79203fdc8eaa8d862895f2a9f2cf46597d117ab
https://github.com/scummvm/scummvm/commit/a79203fdc8eaa8d862895f2a9f2cf46597d117ab
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:53+01:00
Commit Message:
AGDS: implemented mouse enter/leave events
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
engines/agds/region.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index afcc34c1270..4d31c0b27ba 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -40,7 +40,7 @@ namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
_gameDescription(gameDesc), _sharedStorageIndex(-2), _timer(0),
_mjpgPlayer(NULL), _currentScreen(NULL), _mouseCursor(NULL),
- _mouse(400, 300), _userEnabled(false) {
+ _mouse(400, 300), _userEnabled(false), _currentRegion(NULL) {
}
AGDSEngine::~AGDSEngine() {
@@ -126,24 +126,27 @@ Common::String AGDSEngine::loadFilename(const Common::String &entryName) {
}
-Object *AGDSEngine::loadObject(const Common::String & name) {
+Object *AGDSEngine::loadObject(const Common::String & name, bool forceRun) {
ObjectsType::iterator i = _objects.find(name);
Object *object = i != _objects.end()? i->_value: NULL;
- if (object)
- return object;
-
- Common::SeekableReadStream * stream = _data.getEntry(name);
- if (!stream)
- error("no database entry for %s\n", name.c_str());
-
- object = new Object(name, stream);
- _objects.setVal(name, object);
+ bool run = forceRun;
+ if (!object) {
+ Common::SeekableReadStream * stream = _data.getEntry(name);
+ if (!stream)
+ error("no database entry for %s\n", name.c_str());
+
+ object = new Object(name, stream);
+ _objects.setVal(name, object);
+ run = true;
+ delete stream;
+ }
- delete stream;
+ if (run) {
+ _processes.push_front(Process(this, object));
+ if (_currentScreen)
+ _currentScreen->add(object);
+ }
- _processes.push_front(Process(this, object));
- if (_currentScreen)
- _currentScreen->add(object);
return object;
}
@@ -203,13 +206,27 @@ Common::Error AGDSEngine::run() {
switch(event.type) {
case Common::EVENT_MOUSEMOVE:
_mouse = event.mouse;
+ if (_userEnabled && _currentScreen) {
+ const MouseRegion *region = _mouseMap.find(_mouse);
+ if ((region? region->region: NULL) != _currentRegion) {
+ if (_currentRegion) {
+ _currentRegion = NULL;
+ loadObject(_onLeaveObject, true); //force execution even if it's loaded, fixme: move to another mehtod?
+ }
+ if (region) {
+ _onLeaveObject = region->onLeave;
+ _currentRegion = region->region;
+ loadObject(region->onEnter, true);
+ }
+ }
+ }
break;
case Common::EVENT_LBUTTONDOWN:
_mouse = event.mouse;
if (_userEnabled && _currentScreen) {
debug("lclick %d, %d", _mouse.x, _mouse.y);
Object *object = _currentScreen->find(_mouse);
- debug("found object %p", (void *)object);
+ debug("found object %p", (const void *)object);
}
break;
default:
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 30ebfc0ca50..d882f7c45f5 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -30,6 +30,7 @@
#include "agds/database.h"
#include "agds/processExitCode.h"
#include "agds/resourceManager.h"
+#include "agds/screen.h"
#include "graphics/pixelformat.h"
#include "video/flic_decoder.h"
@@ -66,7 +67,7 @@ private:
bool load();
void runProcess();
- Object * loadObject(const Common::String & name);
+ Object * loadObject(const Common::String & name, bool forceRun = false);
Screen * loadScreen(const Common::String & name);
Region * loadRegion(const Common::String &name);
@@ -129,7 +130,10 @@ private:
Screen * _currentScreen;
Video::FlicDecoder * _mouseCursor;
Common::Point _mouse;
+ Region * _currentRegion;
+ Common::String _onLeaveObject;
bool _userEnabled;
+ MouseMap _mouseMap;
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f1cdf3d0a2a..03d2c58e35b 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -195,7 +195,7 @@ void Process::changeScreenPatch() {
void Process::loadMouseStub66() {
Common::String name = popFilename();
debug("loadMouseStub66 %s", name.c_str());
- //_engine->loadCursor(name); //overlay cursor
+ _engine->loadCursor(name); //overlay cursor
}
void Process::fadeObject() {
@@ -394,12 +394,11 @@ void Process::findObjectInMouseArea() {
Common::String arg2 = popString();
Common::String arg1 = popString();
- debug("findObjectInMouseArea %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
- _engine->loadRegion(arg1);
+ debug("findObjectInMouseArea (region: %s) %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
+ Region *region = _engine->loadRegion(arg1);
push(205);
- _engine->currentScreen()->add(_engine->loadObject(arg2));
- _engine->currentScreen()->add(_engine->loadObject(arg3));
+ _engine->_mouseMap.add(MouseRegion(region, arg2, arg3));
}
void Process::loadRegionFromObject() {
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index fd17f0d7753..290035b0e07 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -70,7 +70,6 @@ typedef struct {
} dPoint;
bool Region::pointIn(Common::Point point) const {
- debug("POINT IN");
uint32 size = points.size();
if (size < 3) {
return false;
@@ -89,7 +88,6 @@ bool Region::pointIn(Common::Point point) const {
for (uint32 i = 1; i <= size; i++) {
p2.x = (double)points[i % size].x;
p2.y = (double)points[i % size].y;
- debug("%g %g %g %g", p1.x, p1.y, p2.x, p2.y);
if (p.y > MIN(p1.y, p2.y)) {
if (p.y <= MAX(p1.y, p2.y)) {
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 9300d145f02..05db7ca738f 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -65,5 +65,16 @@ Object *Screen::find(Common::Point pos) const {
return NULL;
}
+const MouseRegion * MouseMap::find(Common::Point pos) const {
+ for(MouseRegionsType::const_iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i) {
+ const MouseRegion &mouse = *i;
+ if (mouse.region->pointIn(pos))
+ return &mouse;
+ }
+ return NULL;
+
+}
+
+
}
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 3428c17940f..47c61c3acef 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -35,6 +35,30 @@ namespace Graphics {
namespace AGDS {
class Object;
+class Region;
+
+struct MouseRegion {
+ Region *region;
+ Common::String onEnter;
+ Common::String onLeave;
+
+ MouseRegion(): region() { }
+ MouseRegion(Region * reg, const Common::String &enter, const Common::String &leave):
+ region(reg), onEnter(enter), onLeave(leave) {
+ }
+};
+
+//fixme: move me away
+class MouseMap {
+ typedef Common::List<MouseRegion> MouseRegionsType;
+ MouseRegionsType _mouseRegions;
+
+public:
+ void add(const MouseRegion & area) {
+ _mouseRegions.push_back(area);
+ }
+ const MouseRegion * find(Common::Point pos) const;
+};
class Screen {
typedef Common::List<Object *> ChildrenType;
Commit: 1400c042a00021bc0e56e08664d60adc10b9b251
https://github.com/scummvm/scummvm/commit/1400c042a00021bc0e56e08664d60adc10b9b251
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:53+01:00
Commit Message:
AGDS: split loadObject and runObject, run objects from loadScreenObject/loadScreen opcodes for now
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 4d31c0b27ba..b4fea36d655 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -88,7 +88,7 @@ bool AGDSEngine::load() {
return false;
_patch.open("patch.adb"); //it's ok
- _currentScreen = loadScreen("main");
+ loadScreen("main");
return true;
}
@@ -126,10 +126,9 @@ Common::String AGDSEngine::loadFilename(const Common::String &entryName) {
}
-Object *AGDSEngine::loadObject(const Common::String & name, bool forceRun) {
+Object *AGDSEngine::loadObject(const Common::String & name) {
ObjectsType::iterator i = _objects.find(name);
Object *object = i != _objects.end()? i->_value: NULL;
- bool run = forceRun;
if (!object) {
Common::SeekableReadStream * stream = _data.getEntry(name);
if (!stream)
@@ -137,28 +136,28 @@ Object *AGDSEngine::loadObject(const Common::String & name, bool forceRun) {
object = new Object(name, stream);
_objects.setVal(name, object);
- run = true;
delete stream;
}
-
- if (run) {
- _processes.push_front(Process(this, object));
- if (_currentScreen)
- _currentScreen->add(object);
- }
-
return object;
}
-Screen *AGDSEngine::loadScreen(const Common::String & name) {
- ScreensType::iterator i = _screens.find(name);
- if (i != _screens.end())
- return i->_value;
+void AGDSEngine::runObject(Object *object) {
+ _processes.push_front(Process(this, object));
+ if (_currentScreen)
+ _currentScreen->add(object);
+}
+void AGDSEngine::loadScreen(const Common::String & name) {
debug("loadScreen %s", name.c_str());
- Screen *screen = new Screen(loadObject(name));
- _screens[name] = screen;
- return screen;
+ ScreensType::iterator i = _screens.find(name);
+ if (i == _screens.end())
+ {
+ Object *object = loadObject(name);
+ Screen *screen = new Screen(object);
+ _currentScreen = screen;
+ _screens[name] = screen;
+ }
+ runObject(name);
}
void AGDSEngine::runProcess() {
@@ -172,10 +171,10 @@ void AGDSEngine::runProcess() {
ProcessExitCode code = process.execute();
switch(code) {
case kExitCodeLoadScreenObject:
- loadObject(process.getExitValue());
+ runObject(process.getExitValue());
break;
case kExitCodeDestroyProcessSetNextScreen:
- _currentScreen = loadScreen(process.getExitValue());
+ loadScreen(process.getExitValue());
break;
case kExitCodeSuspend:
debug("process suspended");
@@ -211,12 +210,12 @@ Common::Error AGDSEngine::run() {
if ((region? region->region: NULL) != _currentRegion) {
if (_currentRegion) {
_currentRegion = NULL;
- loadObject(_onLeaveObject, true); //force execution even if it's loaded, fixme: move to another mehtod?
+ runObject(_onLeaveObject);
}
if (region) {
_onLeaveObject = region->onLeave;
_currentRegion = region->region;
- loadObject(region->onEnter, true);
+ runObject(region->onEnter);
}
}
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index d882f7c45f5..ccaa864c161 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -67,8 +67,13 @@ private:
bool load();
void runProcess();
- Object * loadObject(const Common::String & name, bool forceRun = false);
- Screen * loadScreen(const Common::String & name);
+ Object * loadObject(const Common::String & name);
+ void runObject(Object *object);
+
+ void runObject(const Common::String & name)
+ { runObject(loadObject(name)); }
+
+ void loadScreen(const Common::String & name);
Region * loadRegion(const Common::String &name);
Common::String loadFilename(const Common::String &name);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 03d2c58e35b..87a95e6ce3b 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -263,7 +263,7 @@ void Process::stub188() {
Common::String arg2 = popString();
Common::String arg1 = popString();
debug("stub188 %s %s %d", arg1.c_str(), arg2.c_str(), arg3);
- _engine->loadObject(arg1);
+ //_engine->loadObject(arg1);
}
Commit: 1360b04f0b807fea8a095d8fc741120d29a3d218
https://github.com/scummvm/scummvm/commit/1360b04f0b807fea8a095d8fc741120d29a3d218
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:53+01:00
Commit Message:
AGDS: added click handler for object
Changed paths:
engines/agds/agds.cpp
engines/agds/object.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index b4fea36d655..3b2ef6c2239 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -225,7 +225,13 @@ Common::Error AGDSEngine::run() {
if (_userEnabled && _currentScreen) {
debug("lclick %d, %d", _mouse.x, _mouse.y);
Object *object = _currentScreen->find(_mouse);
- debug("found object %p", (const void *)object);
+ if (object) {
+ uint ip = object->getClickHandler();
+ if (ip) {
+ debug("found handler: %s %08x", object->getName().c_str(), ip + 7);
+ _processes.push_front(Process(this, object, ip));
+ }
+ }
}
break;
default:
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 2b787d31df9..f2fe80b7c38 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -55,7 +55,7 @@ private:
const Graphics::Surface * _picture;
Region * _region;
Common::Point _pos;
- unsigned _clickHandler;
+ uint _clickHandler;
public:
Object(const Common::String &name, Common::SeekableReadStream * stream);
@@ -86,10 +86,14 @@ public:
return _region;
}
- void setClickHandler(uint32 ip) {
+ void setClickHandler(uint ip) {
_clickHandler = ip;
}
+ uint getClickHandler() const {
+ return _clickHandler;
+ }
+
void paint(Graphics::Surface &backbuffer);
void move(Common::Point pos) {
Commit: 8a4b5f54fe3785fcfeb094ba4acbcbb98d86caab
https://github.com/scummvm/scummvm/commit/8a4b5f54fe3785fcfeb094ba4acbcbb98d86caab
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:54+01:00
Commit Message:
AGDS: implemented resetGlobal, stub235 and quit opcodes
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 135db3fb233..d63cae8b0fa 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -152,7 +152,7 @@ enum Opcode {
kStub132 = 132,
kStub133 = 133,
kStub134 = 134,
- kStub135 = 135,
+ kResetGlobal = 135,
kStub136 = 136,
kStub137 = 137,
kStub138 = 138,
@@ -163,7 +163,7 @@ enum Opcode {
kSetIntegerVariable = 143,
kStub144 = 144,
kStub145 = 145,
- kGetRegionCenterX = 146,
+ kGetRegionCenterX = 146,
kGetRegionCenterY = 147,
kStub148 = 148,
kStub149 = 149,
@@ -175,7 +175,7 @@ enum Opcode {
kStub155 = 155,
kStub156 = 156,
kStub157 = 157,
- kStub158 = 158,
+ kQuit = 158,
kStub159 = 159,
kStub160 = 160,
kStub161 = 161,
@@ -212,8 +212,8 @@ enum Opcode {
kStub192 = 192,
kStub193 = 193,
kStub194 = 194,
- kGetObjectPictureWidth = 195,
- kGetObjectPictureHeight = 196,
+ kGetObjectPictureWidth = 195,
+ kGetObjectPictureHeight = 196,
kStub197 = 197,
kLoadPicture = 198,
kStub199 = 199,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index e85888ba46a..4c6ea276b3b 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -111,12 +111,18 @@ private:
void getRegionCenterY();
void fadeObject();
void moveScreenObject();
+ void setFontGlyphSize();
+ void getObjectPictureWidth();
+ void getObjectPictureHeight();
+ void exitProcessSetNextScreen();
+ void quit();
void setSystemVariable();
void getIntegerSystemVariable();
void setIntegerVariable();
void getGlobal(unsigned index);
void setGlobal();
+ void resetGlobal();
void hasGlobal();
void postIncrementGlobal();
void incrementGlobal(int value);
@@ -140,15 +146,12 @@ private:
void stub154();
void stub155();
void stub166();
- void setFontGlyphSize();
void stub188();
void stub190();
- void getObjectPictureWidth();
- void getObjectPictureHeight();
void stub202(unsigned size);
void playFilm();
void stub206();
- void exitProcessSetNextScreen();
+ void stub235();
void debug(const char *str, ...);
#define UNARY_OP(NAME, OP) void NAME () { int arg = pop(); debug(#NAME " %d", arg); push( OP arg ); }
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 87a95e6ce3b..524563e6a5a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -136,6 +136,12 @@ void Process::setGlobal() {
_engine->setGlobal(name, value);
}
+void Process::resetGlobal() {
+ Common::String name = popString();
+ _engine->setGlobal(name, 0);
+ debug("resetGlobal %s", name.c_str());
+}
+
void Process::getGlobal(unsigned index) {
const Common::String & name = _object->getString(index).string;
int value = _engine->getGlobal(name);
@@ -286,6 +292,11 @@ void Process::moveScreenObject() {
object->move(Common::Point(arg2, arg3));
}
+void Process::quit() {
+ debug("quit");
+ _engine->quitGame();
+}
+
void Process::stub190() {
int value = pop();
debug("stub190 %d", value);
@@ -426,6 +437,14 @@ void Process::setTimer() {
suspend();
}
+void Process::stub235() {
+ int arg3 = pop();
+ int arg2 = pop();
+ int arg1 = pop();
+ debug("stub235 (fadeScreen?) %d %d %d", arg1, arg2, arg3);
+ suspend();
+}
+
//fixme: add trace here
@@ -507,6 +526,7 @@ ProcessExitCode Process::execute() {
OP (kStub130, stub130);
OP (kStub133, stub133);
OP (kStub134, stub134);
+ OP (kResetGlobal, resetGlobal);
OP (kStub136, stub136);
OP (kScreenChangeScreenPatch, changeScreenPatch);
OP (kSetSystemVariable, setSystemVariable);
@@ -518,6 +538,7 @@ ProcessExitCode Process::execute() {
OP (kStub154, stub154);
OP (kStub155, stub155);
OP (kStub166, stub166);
+ OP (kQuit, quit);
OP (kExitScreen, exitScreen);
OP (kMoveScreenObject, moveScreenObject);
OP (kSetGlyphSize, setFontGlyphSize);
@@ -533,6 +554,7 @@ ProcessExitCode Process::execute() {
OP (kFindObjectInMouseArea, findObjectInMouseArea);
OP (kStub206, stub206);
OP_U (kOnKey, onKey);
+ OP (kStub235, stub235);
OP (kHasGlobal, hasGlobal);
default:
error("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _ip - 1, (unsigned)op, (unsigned)op);
Commit: c5e64237d3399aae8520492ddb2d018126b8907d
https://github.com/scummvm/scummvm/commit/c5e64237d3399aae8520492ddb2d018126b8907d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:54+01:00
Commit Message:
AGDS: added pcx format support
Changed paths:
engines/agds/resourceManager.cpp
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 50976f6e268..0f96cedb69d 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -27,6 +27,7 @@
#include "common/algorithm.h"
#include "common/ptr.h"
#include "image/bmp.h"
+#include "image/pcx.h"
#include "graphics/surface.h"
namespace AGDS {
@@ -151,8 +152,18 @@ namespace AGDS {
if (!stream)
return NULL;
- Image::BitmapDecoder bmp;
- return bmp.loadStream(*stream)? bmp.getSurface()->convertTo(format): NULL;
+ Common::String lname = name;
+ lname.toLowercase();
+
+ if (lname.hasSuffix(".bmp")) {
+ Image::BitmapDecoder bmp;
+ return bmp.loadStream(*stream)? bmp.getSurface()->convertTo(format): NULL;
+ } else if (lname.hasSuffix(".pcx")) {
+ Image::PCXDecoder pcx;
+ return pcx.loadStream(*stream)? pcx.getSurface()->convertTo(format): NULL;
+ } else
+ warning("unknown extensions for resource %s", name.c_str());
+ return NULL;
}
Commit: 7f578912a11ef56590a02facac8a65ae81a17957
https://github.com/scummvm/scummvm/commit/7f578912a11ef56590a02facac8a65ae81a17957
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:54+01:00
Commit Message:
AGDS: generalised Process::suspend(), implemented opcode 80 and fixed relative offset in callimm16
Changed paths:
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index d19e6cc5f7e..3a87d950991 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -76,6 +76,12 @@ Common::String Process::popFilename() {
return _engine->loadFilename(popString());
}
+void Process::suspendProcess(ProcessExitCode code) {
+ debug("suspendProcess");
+ _status = kStatusPassive;
+ _exitCode = code;
+}
+
void Process::activate() {
switch(_status)
{
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 4c6ea276b3b..82adb95fc47 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -87,7 +87,7 @@ private:
void enter(uint16 magic, uint16 size);
void exitProcess();
- void suspendProcess();
+ void suspendProcess(ProcessExitCode code = kExitCodeSuspend);
void exitScreen();
void call(uint16 addr);
@@ -115,6 +115,7 @@ private:
void getObjectPictureWidth();
void getObjectPictureHeight();
void exitProcessSetNextScreen();
+ void exitProcessSetNextScreen80();
void quit();
void setSystemVariable();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 524563e6a5a..bb03fbc86f4 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -343,12 +343,18 @@ void Process::stub206() {
}
void Process::exitProcessSetNextScreen() {
- debug("exitProcessSetNextScreen");
_exitValue = popString();
- _exitCode = kExitCodeDestroyProcessSetNextScreen;
- _status = kStatusPassive;
+ debug("exitProcessSetNextScreen %s", _exitValue.c_str());
+ suspend(kExitCodeDestroyProcessSetNextScreen);
}
+void Process::exitProcessSetNextScreen80() {
+ _exitValue = popString();
+ debug("exitProcessSetNextScreen80(code 7) %s", _exitValue.c_str());
+ suspend(kExitCodeDestroyProcessSetNextScreen);
+}
+
+
void Process::exitScreen()
{
debug("exitScreen? reactivating process...");
@@ -365,18 +371,11 @@ void Process::updateScreenHeightToDisplay() {
debug("updateScreenHeightToDisplay");
}
-
-void Process::suspendProcess() {
- debug("suspendProcess");
- _status = kStatusPassive;
- _exitCode = kExitCodeSuspend;
-}
-
void Process::call(uint16 addr) {
debug("call %04x", addr);
//original engine just create new process, save exit code in screen object
//and on stack, then just ignore return code, fixme?
- Process callee(_engine, _object, addr);
+ Process callee(_engine, _object, _ip + addr);
ProcessExitCode code = callee.execute();
debug("call returned %d", code);
}
@@ -513,6 +512,7 @@ ProcessExitCode Process::execute() {
OP (kEnableUser, enableUser);
OP (kClearScreen, clearScreen);
OP (kLoadMouse, loadMouse);
+ OP (kStub80, exitProcessSetNextScreen80);
OP (kSetScreenHeight, setScreenHeight);
OP (kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay);
OP (kScreenLoadObject, loadScreenObject);
Commit: fb7304cc6255b72d960b98f5cded32ee4477f32c
https://github.com/scummvm/scummvm/commit/fb7304cc6255b72d960b98f5cded32ee4477f32c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:54+01:00
Commit Message:
AGDS: added stubs 173/174, post decrement of global and generate region stub
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index d63cae8b0fa..8ecb160ce19 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -65,7 +65,7 @@ enum Opcode {
kStub43 = 43,
kStub44 = 44,
kPostIncrementGlobal = 45,
- kStub46 = 46,
+ kPostDecrementGlobal = 46,
kStub47 = 47,
kSetGlobal = 48,
kIncrementGlobalByTop = 49,
@@ -200,7 +200,7 @@ enum Opcode {
kStub180 = 180,
kStub181 = 181,
kSetGlyphSize = 182,
- kStub183 = 183,
+ kGenerateRegion = 183,
kStub184 = 184,
kStub185 = 185,
kStub186 = 186,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 82adb95fc47..36a71dee00d 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -102,6 +102,7 @@ private:
void updateScreenHeightToDisplay();
void findObjectInMouseArea();
void loadRegionFromObject();
+ void generateRegion();
void loadPictureFromObject();
void loadAnimationFromObject();
void loadAnimation();
@@ -126,6 +127,7 @@ private:
void resetGlobal();
void hasGlobal();
void postIncrementGlobal();
+ void postDecrementGlobal();
void incrementGlobal(int value);
void incrementGlobalByTop() { incrementGlobal(top()); }
void decrementGlobal(int value);
@@ -147,6 +149,8 @@ private:
void stub154();
void stub155();
void stub166();
+ void stub173();
+ void stub174();
void stub188();
void stub190();
void stub202(unsigned size);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index bb03fbc86f4..1d3af790c52 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -164,6 +164,14 @@ void Process::postIncrementGlobal() {
_engine->setGlobal(name, value + 1);
}
+void Process::postDecrementGlobal() {
+ Common::String name = popString();
+ int value = _engine->getGlobal(name);
+ debug("decrement global %s %d", name.c_str(), value);
+ push(value);
+ _engine->setGlobal(name, value - 1);
+}
+
void Process::incrementGlobal(int inc) {
Common::String name = popString();
int value = _engine->getGlobal(name);
@@ -258,12 +266,25 @@ void Process::stub166() {
debug("stub166 %d %d", arg1, arg2);
}
+void Process::stub173() {
+ debug("stub173: delAnimations?");
+}
+
+void Process::stub174() {
+ debug("stub174: mouse pointer mode 1?");
+}
+
void Process::setFontGlyphSize() {
_glyphHeight = pop();
_glyphWidth = pop();
debug("setFontGlyphSize %d %d", _glyphWidth, _glyphHeight);
}
+void Process::generateRegion() {
+ Common::String name = popString();
+ debug("generateRegion %s", name.c_str());
+}
+
void Process::stub188() {
int arg3 = pop();
Common::String arg2 = popString();
@@ -485,6 +506,7 @@ ProcessExitCode Process::execute() {
OP_W (kPushImm16_2, push);
OP_B (kGetGlobalImm8, getGlobal);
OP (kPostIncrementGlobal, postIncrementGlobal);
+ OP (kPostDecrementGlobal, postDecrementGlobal);
OP (kIncrementGlobalByTop, incrementGlobalByTop);
OP (kDecrementGlobalByTop, decrementGlobalByTop);
OP (kEquals, equals);
@@ -538,10 +560,13 @@ ProcessExitCode Process::execute() {
OP (kStub154, stub154);
OP (kStub155, stub155);
OP (kStub166, stub166);
+ OP (kStub173, stub173);
+ OP (kStub174, stub174);
OP (kQuit, quit);
OP (kExitScreen, exitScreen);
OP (kMoveScreenObject, moveScreenObject);
OP (kSetGlyphSize, setFontGlyphSize);
+ OP (kGenerateRegion, generateRegion);
OP (kStub188, stub188);
OP (kStub190, stub190);
OP (kGetObjectPictureWidth, getObjectPictureWidth);
Commit: 7087e7ee218a9504a99bc02d61147fbb2c2abf3b
https://github.com/scummvm/scummvm/commit/7087e7ee218a9504a99bc02d61147fbb2c2abf3b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:54+01:00
Commit Message:
AGDS: added more opcodes and extra argument to loadObject/runObject - prototype, simplified suspend() code
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3b2ef6c2239..0e77a60e1f2 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -126,15 +126,16 @@ Common::String AGDSEngine::loadFilename(const Common::String &entryName) {
}
-Object *AGDSEngine::loadObject(const Common::String & name) {
+Object *AGDSEngine::loadObject(const Common::String & name, const Common::String &prototype) {
ObjectsType::iterator i = _objects.find(name);
Object *object = i != _objects.end()? i->_value: NULL;
if (!object) {
- Common::SeekableReadStream * stream = _data.getEntry(name);
+ Common::String clone = prototype.empty()? name: prototype;
+ Common::SeekableReadStream * stream = _data.getEntry(clone);
if (!stream)
- error("no database entry for %s\n", name.c_str());
+ error("no database entry for %s\n", clone.c_str());
- object = new Object(name, stream);
+ object = new Object(clone, stream);
_objects.setVal(name, object);
delete stream;
}
@@ -171,10 +172,10 @@ void AGDSEngine::runProcess() {
ProcessExitCode code = process.execute();
switch(code) {
case kExitCodeLoadScreenObject:
- runObject(process.getExitValue());
+ runObject(process.getExitArg1(), process.getExitArg2());
break;
case kExitCodeDestroyProcessSetNextScreen:
- loadScreen(process.getExitValue());
+ loadScreen(process.getExitArg1());
break;
case kExitCodeSuspend:
debug("process suspended");
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index ccaa864c161..cec4222f6d2 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -67,11 +67,11 @@ private:
bool load();
void runProcess();
- Object * loadObject(const Common::String & name);
+ Object * loadObject(const Common::String & name, const Common::String & prototype = Common::String());
void runObject(Object *object);
- void runObject(const Common::String & name)
- { runObject(loadObject(name)); }
+ void runObject(const Common::String & name, const Common::String &prototype = Common::String())
+ { runObject(loadObject(name, prototype)); }
void loadScreen(const Common::String & name);
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 8ecb160ce19..ffddee58df5 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -52,9 +52,9 @@ enum Opcode {
kMul = 30,
kDiv = 31,
kStub32 = 32,
- kStub33 = 33,
- kStub34 = 34,
- kStub35 = 35,
+ kAnd = 33,
+ kOr = 34,
+ kXor = 35,
kNot = 36,
kStub37 = 37,
kStub38 = 38,
@@ -79,11 +79,11 @@ enum Opcode {
kStub57 = 57,
kStub58 = 58,
kCallImm16 = 59,
- kStub60 = 60,
+ kObjectRegisterLookHandler = 60,
kObjectRegisterUseHandler = 61,
kStub62 = 62,
kStub63 = 63,
- kStub64 = 64,
+ kScreenRegisterHandlerBD = 64,
kStub65 = 65,
kStub66 = 66,
kLoadRegionFromObject = 68,
@@ -91,11 +91,11 @@ enum Opcode {
kLoadAnimationFromObject = 70,
kSetScreenHeight = 71,
kUpdateScreenHeightToDisplay = 72,
- kStub73 = 73,
+ kLoadTextFromObject = 73,
kStub74 = 74,
kStub75 = 75,
kScreenLoadObject = 76,
- kStub77 = 77,
+ kScreenLoadObjectAs = 77,
kScreenRemoveObject = 78,
kExitProcessSetNextScreen = 79,
kStub80 = 80,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 36a71dee00d..85eebe66fad 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -44,8 +44,8 @@ private:
StackType _stack;
unsigned _ip, _lastIp;
Status _status;
- Common::String _exitValue;
ProcessExitCode _exitCode;
+ Common::String _exitArg1, _exitArg2;
int _glyphWidth, _glyphHeight;
private:
@@ -105,8 +105,10 @@ private:
void generateRegion();
void loadPictureFromObject();
void loadAnimationFromObject();
+ void loadTextFromObject();
void loadAnimation();
void loadSample();
+ void loadObjectAs();
void setTimer();
void getRegionCenterX();
void getRegionCenterY();
@@ -138,6 +140,8 @@ private:
void enableUser();
void onKey(unsigned size);
void onUse(unsigned size);
+ void onLook(unsigned size);
+ void onScreenBD(unsigned size);
void loadMouseStub66();
void stub128();
@@ -146,13 +150,18 @@ private:
void stub133();
void stub134();
void stub136();
+ void stub152();
+ void stub153();
void stub154();
void stub155();
void stub166();
void stub173();
void stub174();
+ void stub176();
void stub188();
void stub190();
+ void stub191();
+ void stub192();
void stub202(unsigned size);
void playFilm();
void stub206();
@@ -176,14 +185,19 @@ private:
BINARY_OP(sub, -)
BINARY_OP(mul, *)
BINARY_OP(div, /)
+ BINARY_OP(bitAnd, &)
+ BINARY_OP(bitOr, |)
+ BINARY_OP(bitXor, ^)
#undef UNARY_OP
#undef BINARY_OP
- void suspend(ProcessExitCode exitCode = kExitCodeSuspend) {
+ void suspend(ProcessExitCode exitCode = kExitCodeSuspend, const Common::String &arg1 = Common::String(), const Common::String &arg2 = Common::String()) {
if (_status == kStatusActive)
_status = kStatusPassive;
_exitCode = exitCode;
+ _exitArg1 = arg1;
+ _exitArg2 = arg2;
}
public:
@@ -201,8 +215,12 @@ public:
return _exitCode;
}
- const Common::String & getExitValue() const {
- return _exitValue;
+ const Common::String & getExitArg1() const {
+ return _exitArg1;
+ }
+
+ const Common::String & getExitArg2() const {
+ return _exitArg2;
}
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 1d3af790c52..9bdf90ec3d3 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -99,8 +99,14 @@ void Process::loadSample() {
void Process::loadScreenObject() {
Common::String name = popString();
debug("loadScreenObject: %s", name.c_str());
- _exitValue = name;
- suspend(kExitCodeLoadScreenObject);
+ suspend(kExitCodeLoadScreenObject, name);
+}
+
+void Process::loadObjectAs() {
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("loadObject: %s %s", arg1.c_str(), arg2.c_str());
+ suspend(kExitCodeLoadScreenObject, arg1, arg2);
}
void Process::removeScreenObject() {
@@ -193,6 +199,10 @@ void Process::appendToSharedStorage() {
push(index);
}
+void Process::stub176() {
+ debug("stub176");
+}
+
void Process::disableUser() {
debug("disableUser");
_engine->enableUser(false);
@@ -248,6 +258,18 @@ void Process::stub136() {
debug("stub136 sets value of stub130 to 1000000000");
}
+void Process::stub152() {
+ Common::String name = popString();
+ debug("stub152(getSomeX): %s", name.c_str());
+ push(152);
+}
+
+void Process::stub153() {
+ Common::String name = popString();
+ debug("stub153:(getSomeY): %s", name.c_str());
+ push(153);
+}
+
void Process::stub154() {
Common::String name = popString();
debug("stub154(getSomeX): %s", name.c_str());
@@ -274,6 +296,12 @@ void Process::stub174() {
debug("stub174: mouse pointer mode 1?");
}
+void Process::stub192() {
+ int value = pop();
+ Common::String name = popString();
+ debug("stub192: %s: set some object flag to %d", name.c_str(), value);
+}
+
void Process::setFontGlyphSize() {
_glyphHeight = pop();
_glyphWidth = pop();
@@ -323,6 +351,12 @@ void Process::stub190() {
debug("stub190 %d", value);
}
+void Process::stub191() {
+ int value = pop();
+ value = value > 0? 1: 0;
+ debug("stub191: setting some mouse flag to %d", value);
+}
+
void Process::getObjectPictureWidth() {
Common::String name = popString();
debug("getObjectPictureWidth %s", name.c_str());
@@ -364,15 +398,15 @@ void Process::stub206() {
}
void Process::exitProcessSetNextScreen() {
- _exitValue = popString();
- debug("exitProcessSetNextScreen %s", _exitValue.c_str());
- suspend(kExitCodeDestroyProcessSetNextScreen);
+ Common::String name = popString();
+ debug("exitProcessSetNextScreen %s", name.c_str());
+ suspend(kExitCodeDestroyProcessSetNextScreen, name);
}
void Process::exitProcessSetNextScreen80() {
- _exitValue = popString();
- debug("exitProcessSetNextScreen80(code 7) %s", _exitValue.c_str());
- suspend(kExitCodeDestroyProcessSetNextScreen);
+ Common::String name = popString();
+ debug("exitProcessSetNextScreen80(code 7) %s", name.c_str());
+ suspend(kExitCodeDestroyProcessSetNextScreen, name);
}
@@ -392,6 +426,11 @@ void Process::updateScreenHeightToDisplay() {
debug("updateScreenHeightToDisplay");
}
+void Process::loadTextFromObject() {
+ Common::String name = popFilename();
+ debug("loadTextFromObject %s", name.c_str());
+}
+
void Process::call(uint16 addr) {
debug("call %04x", addr);
//original engine just create new process, save exit code in screen object
@@ -413,6 +452,15 @@ void Process::onUse(unsigned size) {
_ip += size;
}
+void Process::onLook(unsigned size) {
+ debug("look? handler, %u instructions", size);
+ _ip += size;
+}
+
+void Process::onScreenBD(unsigned size) {
+ debug("onScreen(+BD) handler, %u instructions", size);
+ _ip += size;
+}
void Process::enableUser() {
//screen loading block user interaction until this instruction
@@ -522,10 +570,15 @@ ProcessExitCode Process::execute() {
OP (kSetGlobal, setGlobal);
OP (kBoolOr, boolOr);
OP (kBoolAnd, boolAnd);
+ OP (kAnd, bitAnd);
+ OP (kOr, bitOr);
+ OP (kXor, bitXor);
OP (kNot, bitNot);
OP (kBoolNot, boolNot);
OP_U (kCallImm16, call);
+ OP_U (kObjectRegisterLookHandler, onLook);
OP_U (kObjectRegisterUseHandler, onUse);
+ OP_U (kScreenRegisterHandlerBD, onScreenBD);
OP (kStub66, loadMouseStub66);
OP (kLoadRegionFromObject, loadRegionFromObject);
OP (kLoadPictureFromObject, loadPictureFromObject);
@@ -537,7 +590,9 @@ ProcessExitCode Process::execute() {
OP (kStub80, exitProcessSetNextScreen80);
OP (kSetScreenHeight, setScreenHeight);
OP (kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay);
+ OP (kLoadTextFromObject, loadTextFromObject);
OP (kScreenLoadObject, loadScreenObject);
+ OP (kScreenLoadObjectAs, loadObjectAs);
OP (kExitProcessSetNextScreen, exitProcessSetNextScreen);
OP (kScreenRemoveObject, removeScreenObject);
OP (kLoadAnimation, loadAnimation);
@@ -557,11 +612,15 @@ ProcessExitCode Process::execute() {
OP (kGetRegionCenterY, getRegionCenterY);
OP (kGetIntegerSystemVariable, getIntegerSystemVariable);
OP (kAppendToSharedStorage, appendToSharedStorage);
+ OP (kStub176, stub176);
+ OP (kStub152, stub152);
+ OP (kStub153, stub153);
OP (kStub154, stub154);
OP (kStub155, stub155);
OP (kStub166, stub166);
OP (kStub173, stub173);
OP (kStub174, stub174);
+ OP (kStub192, stub192);
OP (kQuit, quit);
OP (kExitScreen, exitScreen);
OP (kMoveScreenObject, moveScreenObject);
@@ -569,6 +628,7 @@ ProcessExitCode Process::execute() {
OP (kGenerateRegion, generateRegion);
OP (kStub188, stub188);
OP (kStub190, stub190);
+ OP (kStub191, stub191);
OP (kGetObjectPictureWidth, getObjectPictureWidth);
OP (kGetObjectPictureHeight, getObjectPictureHeight);
OP (kLoadPicture, loadPicture);
Commit: 0e4fbad0cce2dd2537445c819c04a8e1d5fdcdb8
https://github.com/scummvm/scummvm/commit/0e4fbad0cce2dd2537445c819c04a8e1d5fdcdb8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:54+01:00
Commit Message:
AGDS: more opcodes and stubs
Changed paths:
engines/agds/agds.cpp
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 0e77a60e1f2..0fe44193a8f 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -135,7 +135,7 @@ Object *AGDSEngine::loadObject(const Common::String & name, const Common::String
if (!stream)
error("no database entry for %s\n", clone.c_str());
- object = new Object(clone, stream);
+ object = new Object(name, stream);
_objects.setVal(name, object);
delete stream;
}
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index ffddee58df5..d9c331a758f 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -70,8 +70,8 @@ enum Opcode {
kSetGlobal = 48,
kIncrementGlobalByTop = 49,
kDecrementGlobalByTop = 50,
- kStub51 = 51,
- kStub52 = 52,
+ kMultiplyGlobalByTop = 51,
+ kDivideGlobalByTop = 52,
kStub53 = 53,
kStub54 = 54,
kStub55 = 55,
@@ -194,10 +194,10 @@ enum Opcode {
kStub174 = 174,
kAppendToSharedStorage = 175,
kStub176 = 176,
- kStub177 = 177,
+ kAppendNameToSharedStorage = 177,
kStub178 = 178,
kStub179 = 179,
- kStub180 = 180,
+ kGetObjectId = 180,
kStub181 = 181,
kSetGlyphSize = 182,
kGenerateRegion = 183,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 85eebe66fad..27a62e49fcd 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -91,6 +91,7 @@ private:
void exitScreen();
void call(uint16 addr);
+ void getObjectId();
void clearScreen();
void loadPicture();
void loadMouse();
@@ -134,7 +135,10 @@ private:
void incrementGlobalByTop() { incrementGlobal(top()); }
void decrementGlobal(int value);
void decrementGlobalByTop() { decrementGlobal(top()); }
+ void multiplyGlobalByTop();
+ void divideGlobalByTop();
void appendToSharedStorage();
+ void appendNameToSharedStorage();
void disableUser();
void enableUser();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 9bdf90ec3d3..d144cbbbb5e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -79,6 +79,18 @@ void Process::getRegionCenterY() {
debug("getRegionCenterY %s -> %d", name.c_str(), value);
}
+void Process::getObjectId() {
+ const Common::String &name = _object->getName();
+ //no rfind :(((
+ Common::String::const_iterator dotpos = 0;
+ for(Common::String::const_iterator i = name.begin(); i != name.end(); ++i)
+ if (*i == '.')
+ dotpos = i + 1;
+ Common::String id(dotpos, name.end());
+ int value = atoi(id.c_str());
+ debug("getObjectId %s %d", name.c_str(), value);
+ push(value);
+}
void Process::loadPicture() {
Common::String name = popFilename();
@@ -192,6 +204,22 @@ void Process::decrementGlobal(int dec) {
_engine->setGlobal(name, value - dec);
}
+void Process::multiplyGlobalByTop() {
+ Common::String name = popString();
+ int mul = top();
+ int value = _engine->getGlobal(name);
+ debug("multiply global %s %d by %d", name.c_str(), value, mul);
+ _engine->setGlobal(name, value * mul);
+}
+
+void Process::divideGlobalByTop() {
+ Common::String name = popString();
+ int div = top();
+ int value = _engine->getGlobal(name);
+ debug("divide global %s %d by %d", name.c_str(), value, div);
+ _engine->setGlobal(name, value / div);
+}
+
void Process::appendToSharedStorage() {
Common::String value = popString();
int index = _engine->appendToSharedStorage(value);
@@ -199,6 +227,13 @@ void Process::appendToSharedStorage() {
push(index);
}
+void Process::appendNameToSharedStorage() {
+ int index = _engine->appendToSharedStorage(_object->getName());
+ debug("appendNameToSharedStorage %s -> %d", _object->getName().c_str(), index);
+ push(index);
+}
+
+
void Process::stub176() {
debug("stub176");
}
@@ -557,6 +592,8 @@ ProcessExitCode Process::execute() {
OP (kPostDecrementGlobal, postDecrementGlobal);
OP (kIncrementGlobalByTop, incrementGlobalByTop);
OP (kDecrementGlobalByTop, decrementGlobalByTop);
+ OP (kMultiplyGlobalByTop, multiplyGlobalByTop);
+ OP (kDivideGlobalByTop, divideGlobalByTop);
OP (kEquals, equals);
OP (kNotEquals, notEquals);
OP (kGreater, greater);
@@ -612,6 +649,7 @@ ProcessExitCode Process::execute() {
OP (kGetRegionCenterY, getRegionCenterY);
OP (kGetIntegerSystemVariable, getIntegerSystemVariable);
OP (kAppendToSharedStorage, appendToSharedStorage);
+ OP (kAppendNameToSharedStorage, appendNameToSharedStorage);
OP (kStub176, stub176);
OP (kStub152, stub152);
OP (kStub153, stub153);
@@ -624,6 +662,7 @@ ProcessExitCode Process::execute() {
OP (kQuit, quit);
OP (kExitScreen, exitScreen);
OP (kMoveScreenObject, moveScreenObject);
+ OP (kGetObjectId, getObjectId);
OP (kSetGlyphSize, setFontGlyphSize);
OP (kGenerateRegion, generateRegion);
OP (kStub188, stub188);
Commit: b8ddde5508d8df06f987ecc192201a333d99503a
https://github.com/scummvm/scummvm/commit/b8ddde5508d8df06f987ecc192201a333d99503a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:54+01:00
Commit Message:
AGDS: cleanup mouse area for opcode 80
Changed paths:
engines/agds/process_opcodes.cpp
engines/agds/screen.h
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d144cbbbb5e..571764c5da8 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -441,6 +441,7 @@ void Process::exitProcessSetNextScreen() {
void Process::exitProcessSetNextScreen80() {
Common::String name = popString();
debug("exitProcessSetNextScreen80(code 7) %s", name.c_str());
+ _engine->_mouseMap.clear();
suspend(kExitCodeDestroyProcessSetNextScreen, name);
}
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 47c61c3acef..8eb9e451d1d 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -57,6 +57,9 @@ public:
void add(const MouseRegion & area) {
_mouseRegions.push_back(area);
}
+ void clear() {
+ _mouseRegions.clear();
+ }
const MouseRegion * find(Common::Point pos) const;
};
Commit: 26c9e5dbf5698becce8bc0e054f0fd48bde7e874
https://github.com/scummvm/scummvm/commit/26c9e5dbf5698becce8bc0e054f0fd48bde7e874
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:54+01:00
Commit Message:
AGDS: added navigating previous screen support (buggy)
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 0fe44193a8f..899a4f49283 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -150,21 +150,27 @@ void AGDSEngine::runObject(Object *object) {
void AGDSEngine::loadScreen(const Common::String & name) {
debug("loadScreen %s", name.c_str());
+ if (_currentScreen)
+ _previousScreen = _currentScreen->getName();
+
ScreensType::iterator i = _screens.find(name);
- if (i == _screens.end())
- {
- Object *object = loadObject(name);
- Screen *screen = new Screen(object);
- _currentScreen = screen;
+ Screen *screen;
+ if (i == _screens.end()) {
+ screen = new Screen(loadObject(name));
_screens[name] = screen;
- }
+ } else
+ screen = i->_value;
+
+ _currentScreen = screen;
runObject(name);
}
void AGDSEngine::runProcess() {
for(ProcessListType::iterator p = _processes.begin(); active() && p != _processes.end(); ) {
Process & process = *p;
+ const Common::String &name = process.getName();
if (process.getStatus() == Process::kStatusDone) {
+ debug("process %s finished", name.c_str());
p = _processes.erase(p);
continue;
}
@@ -177,11 +183,14 @@ void AGDSEngine::runProcess() {
case kExitCodeDestroyProcessSetNextScreen:
loadScreen(process.getExitArg1());
break;
+ case kExitCodeLoadPreviousScreenObject:
+ loadScreen(_previousScreen);
+ break;
case kExitCodeSuspend:
- debug("process suspended");
+ debug("process %s suspended", name.c_str());
return;
default:
- debug("destroying process...");
+ debug("destroying process %s...", name.c_str());
p = _processes.erase(p);
continue;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index cec4222f6d2..75425962415 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -133,6 +133,7 @@ private:
Graphics::PixelFormat _pixelFormat;
MJPGPlayer * _mjpgPlayer;
Screen * _currentScreen;
+ Common::String _previousScreen;
Video::FlicDecoder * _mouseCursor;
Common::Point _mouse;
Region * _currentRegion;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index d9c331a758f..1f5bd4dbe7e 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -181,7 +181,7 @@ enum Opcode {
kStub161 = 161,
kExitScreen = 162,
kStub163 = 163,
- kStub164 = 164,
+ kLoadPreviousScreen = 164,
kMoveScreenObject = 165,
kStub166 = 166,
kStub167 = 167,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 27a62e49fcd..16a2a486757 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -89,6 +89,9 @@ private:
void exitProcess();
void suspendProcess(ProcessExitCode code = kExitCodeSuspend);
void exitScreen();
+ void exitProcessSetNextScreen();
+ void exitProcessSetNextScreen80();
+ void loadPreviousScreen();
void call(uint16 addr);
void getObjectId();
@@ -118,8 +121,6 @@ private:
void setFontGlyphSize();
void getObjectPictureWidth();
void getObjectPictureHeight();
- void exitProcessSetNextScreen();
- void exitProcessSetNextScreen80();
void quit();
void setSystemVariable();
@@ -207,6 +208,10 @@ private:
public:
Process(AGDSEngine *engine, Object *object, unsigned ip = 0);
+ const Common::String & getName() const {
+ return _object->getName();
+ }
+
Status getStatus() const {
return _status;
}
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index 98a61eb0731..7ec4b6803da 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -30,7 +30,9 @@ namespace AGDS {
kExitCodeSuspend = 5,
kExitCodeDestroyProcessSetNextScreen = 6,
kExitCodeLoadScreenObject = 8,
- kExitCodeExitScreen = 15
+ kExitCodeExitScreen = 15,
+
+ kExitCodeLoadPreviousScreenObject = 99
};
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 571764c5da8..9537b0e3ddf 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -445,6 +445,11 @@ void Process::exitProcessSetNextScreen80() {
suspend(kExitCodeDestroyProcessSetNextScreen, name);
}
+void Process::loadPreviousScreen() {
+ debug("loadPreviousScreen");
+ _engine->_mouseMap.clear();
+ suspend(kExitCodeLoadPreviousScreenObject);
+}
void Process::exitScreen()
{
@@ -662,6 +667,7 @@ ProcessExitCode Process::execute() {
OP (kStub192, stub192);
OP (kQuit, quit);
OP (kExitScreen, exitScreen);
+ OP (kLoadPreviousScreen, loadPreviousScreen);
OP (kMoveScreenObject, moveScreenObject);
OP (kGetObjectId, getObjectId);
OP (kSetGlyphSize, setFontGlyphSize);
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 05db7ca738f..9b025f43b25 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -26,7 +26,7 @@
namespace AGDS {
-Screen::Screen(Object *object) {
+Screen::Screen(Object *object) : _name(object->getName()) {
add(object);
}
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 8eb9e451d1d..119354162c8 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -64,11 +64,17 @@ public:
};
class Screen {
+ Common::String _name;
typedef Common::List<Object *> ChildrenType;
ChildrenType _children;
public:
Screen(Object *object);
+
+ const Common::String &getName() const {
+ return _name;
+ }
+
void add(Object *object);
void remove(const Common::String &name);
void paint(Graphics::Surface &backbuffer);
Commit: 5c42ca702b3b4e40258071cddb5bf8b6096335c3
https://github.com/scummvm/scummvm/commit/5c42ca702b3b4e40258071cddb5bf8b6096335c3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:54+01:00
Commit Message:
AGDS: added more stubs to run new game
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 1f5bd4dbe7e..c0232c2fd4c 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -98,7 +98,7 @@ enum Opcode {
kScreenLoadObjectAs = 77,
kScreenRemoveObject = 78,
kExitProcessSetNextScreen = 79,
- kStub80 = 80,
+ kExitProcessNextScreen80 = 80,
kStub82 = 82,
kStub83 = 83,
kStub84 = 84,
@@ -195,8 +195,8 @@ enum Opcode {
kAppendToSharedStorage = 175,
kStub176 = 176,
kAppendNameToSharedStorage = 177,
- kStub178 = 178,
- kStub179 = 179,
+ kGetCloneVar = 178,
+ kSetCloneVar = 179,
kGetObjectId = 180,
kStub181 = 181,
kSetGlyphSize = 182,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 16a2a486757..711302cb362 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -140,6 +140,7 @@ private:
void divideGlobalByTop();
void appendToSharedStorage();
void appendNameToSharedStorage();
+ void setCloneVar();
void disableUser();
void enableUser();
@@ -149,6 +150,7 @@ private:
void onScreenBD(unsigned size);
void loadMouseStub66();
+ void stub82();
void stub128();
void stub129();
void stub130();
@@ -163,12 +165,14 @@ private:
void stub173();
void stub174();
void stub176();
+ void stub184();
void stub188();
void stub190();
void stub191();
void stub192();
void stub202(unsigned size);
void playFilm();
+ void stub200();
void stub206();
void stub235();
void debug(const char *str, ...);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 9537b0e3ddf..60b812fbc51 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -233,6 +233,34 @@ void Process::appendNameToSharedStorage() {
push(index);
}
+void Process::setCloneVar() {
+ int arg3 = pop();
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("setCloneVar %s %s %d", arg1.c_str(), arg2.c_str(), arg3);
+ bool isNumeric = false;
+ size_t prefixLength;
+ {
+ const char *begin = arg1.c_str();
+ const char *ptr = begin + arg1.size() - 1;
+ while(*ptr >= '0' && *ptr <= '9' && ptr > begin)
+ --ptr;
+ isNumeric = *ptr == '.';
+ prefixLength = isNumeric? ptr - begin: 0;
+ }
+
+ Common::String name;
+ if (isNumeric) {
+ //no substr :(((
+ name = Common::String(arg1.c_str(), arg1.c_str() + prefixLength) +
+ "." + arg2 + Common::String(arg1.c_str() + prefixLength);
+ } else {
+ name = arg1 + "." + arg2;
+ }
+ debug("global name for clone: %s", name.c_str());
+ _engine->setGlobal(name, arg3);
+ push(arg3);
+}
void Process::stub176() {
debug("stub176");
@@ -263,6 +291,11 @@ void Process::fadeObject() {
debug("fadeObject %s %d", name.c_str(), arg);
}
+void Process::stub82() {
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("stub82: %s %s", arg1.c_str(), arg2.c_str());
+}
void Process::stub128() {
debug("processCleanupStub128");
@@ -346,6 +379,12 @@ void Process::setFontGlyphSize() {
void Process::generateRegion() {
Common::String name = popString();
debug("generateRegion %s", name.c_str());
+
+}
+
+void Process::stub184() {
+ Common::String name = popString();
+ debug("stub184: %s", name.c_str());
}
void Process::stub188() {
@@ -426,6 +465,11 @@ void Process::playFilm() {
suspend();
}
+void Process::stub200() {
+ int value = pop();
+ debug("stub200: %d", value);
+}
+
void Process::stub206() {
int arg2 = pop();
int arg1 = pop();
@@ -630,7 +674,8 @@ ProcessExitCode Process::execute() {
OP (kEnableUser, enableUser);
OP (kClearScreen, clearScreen);
OP (kLoadMouse, loadMouse);
- OP (kStub80, exitProcessSetNextScreen80);
+ OP (kExitProcessNextScreen80, exitProcessSetNextScreen80);
+ OP (kStub82, stub82);
OP (kSetScreenHeight, setScreenHeight);
OP (kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay);
OP (kLoadTextFromObject, loadTextFromObject);
@@ -657,6 +702,7 @@ ProcessExitCode Process::execute() {
OP (kAppendToSharedStorage, appendToSharedStorage);
OP (kAppendNameToSharedStorage, appendNameToSharedStorage);
OP (kStub176, stub176);
+ OP (kSetCloneVar, setCloneVar);
OP (kStub152, stub152);
OP (kStub153, stub153);
OP (kStub154, stub154);
@@ -672,6 +718,7 @@ ProcessExitCode Process::execute() {
OP (kGetObjectId, getObjectId);
OP (kSetGlyphSize, setFontGlyphSize);
OP (kGenerateRegion, generateRegion);
+ OP (kStub184, stub184);
OP (kStub188, stub188);
OP (kStub190, stub190);
OP (kStub191, stub191);
@@ -683,6 +730,7 @@ ProcessExitCode Process::execute() {
OP_U (kStub202ScreenHandler, stub202);
OP (kPlayFilm, playFilm);
OP (kFindObjectInMouseArea, findObjectInMouseArea);
+ OP (kStub200, stub200);
OP (kStub206, stub206);
OP_U (kOnKey, onKey);
OP (kStub235, stub235);
Commit: a178bbc447150addb05547d5d99173bf7848b166
https://github.com/scummvm/scummvm/commit/a178bbc447150addb05547d5d99173bf7848b166
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-11-12T15:57:54+01:00
Commit Message:
AGDS: Fix warnings
Changed paths:
engines/agds/agds.h
engines/agds/object.h
engines/agds/resourceManager.h
engines/agds/screen.h
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 75425962415..da56e3fcd7c 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -43,13 +43,13 @@
* - Black Mirror (Windows)
*/
-namespace Graphics { class TransparentSurface; }
+namespace Graphics { struct TransparentSurface; }
namespace AGDS {
class Object;
class Process;
-class Region;
+struct Region;
class MJPGPlayer;
class Screen;
diff --git a/engines/agds/object.h b/engines/agds/object.h
index f2fe80b7c38..00ffa26b1fa 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -30,7 +30,7 @@
namespace AGDS {
-class Region;
+struct Region;
class Object {
public:
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 0f83d6a8276..cf8b8f96036 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -30,7 +30,7 @@
#include "common/hashmap.h"
#include "common/hash-str.h"
-namespace Graphics { class Surface; class PixelFormat; }
+namespace Graphics { struct Surface; struct PixelFormat; }
namespace AGDS {
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 119354162c8..30525fbacc0 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -29,13 +29,13 @@
#include "common/rect.h"
namespace Graphics {
- class Surface;
+ struct Surface;
}
namespace AGDS {
class Object;
-class Region;
+struct Region;
struct MouseRegion {
Region *region;
Commit: c3265484bc1b52c10179aade32c63c4aaf5d2a63
https://github.com/scummvm/scummvm/commit/c3265484bc1b52c10179aade32c63c4aaf5d2a63
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:55+01:00
Commit Message:
AGDS: renamed loadObjectAs to cloneObject
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index c0232c2fd4c..aa2bfe4dd0f 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -95,7 +95,7 @@ enum Opcode {
kStub74 = 74,
kStub75 = 75,
kScreenLoadObject = 76,
- kScreenLoadObjectAs = 77,
+ kScreenCloneObject = 77,
kScreenRemoveObject = 78,
kExitProcessSetNextScreen = 79,
kExitProcessNextScreen80 = 80,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 711302cb362..60f90db73c3 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -112,7 +112,7 @@ private:
void loadTextFromObject();
void loadAnimation();
void loadSample();
- void loadObjectAs();
+ void cloneObject();
void setTimer();
void getRegionCenterX();
void getRegionCenterY();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 60b812fbc51..20326d275c2 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -114,10 +114,10 @@ void Process::loadScreenObject() {
suspend(kExitCodeLoadScreenObject, name);
}
-void Process::loadObjectAs() {
+void Process::cloneObject() {
Common::String arg2 = popString();
Common::String arg1 = popString();
- debug("loadObject: %s %s", arg1.c_str(), arg2.c_str());
+ debug("cloneObject: %s %s", arg1.c_str(), arg2.c_str());
suspend(kExitCodeLoadScreenObject, arg1, arg2);
}
@@ -680,7 +680,7 @@ ProcessExitCode Process::execute() {
OP (kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay);
OP (kLoadTextFromObject, loadTextFromObject);
OP (kScreenLoadObject, loadScreenObject);
- OP (kScreenLoadObjectAs, loadObjectAs);
+ OP (kScreenCloneObject, cloneObject);
OP (kExitProcessSetNextScreen, exitProcessSetNextScreen);
OP (kScreenRemoveObject, removeScreenObject);
OP (kLoadAnimation, loadAnimation);
Commit: 4dfe665d4d20f0a7d9f8cce962790c200037ee45
https://github.com/scummvm/scummvm/commit/4dfe665d4d20f0a7d9f8cce962790c200037ee45
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:55+01:00
Commit Message:
AGDS: added loadText, removed local decryption code from engine
Changed paths:
engines/agds/agds.cpp
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 899a4f49283..3ca058b3f81 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -111,21 +111,9 @@ Region * AGDSEngine::loadRegion(const Common::String &name) {
}
Common::String AGDSEngine::loadFilename(const Common::String &entryName) {
- Common::SeekableReadStream * stream = _data.getEntry(entryName);
- if (!stream)
- error("no database entry for %s\n", entryName.c_str());
-
- byte name[32];
- int end = stream->read(name, sizeof(name));
- byte *nameEnd = Common::find(name, name + end, 0);
- unsigned size = nameEnd - name;
- ResourceManager::decrypt(name, size);
-
- delete stream;
- return Common::String(reinterpret_cast<const char *>(name), size);
+ return ResourceManager::loadText(_data.getEntry(entryName));
}
-
Object *AGDSEngine::loadObject(const Common::String & name, const Common::String &prototype) {
ObjectsType::iterator i = _objects.find(name);
Object *object = i != _objects.end()? i->_value: NULL;
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 0f96cedb69d..498d34c5484 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -166,5 +166,33 @@ namespace AGDS {
return NULL;
}
+ Common::String ResourceManager::loadText(Common::SeekableReadStream *stream)
+ {
+ if (!stream)
+ error("stream is null");
+ Common::Array<byte> text(stream->size());
+ if (stream->read(text.data(), text.size()) != text.size())
+ error("short read from text resource");
+ delete stream;
+
+ char *begin = reinterpret_cast<char *>(text.data());
+ char *end = begin + text.size();
+ while(begin != end && end[-1] == 0)
+ --end;
+
+ decrypt(text.data(), end - begin);
+
+ debug("last char %d %ld", (int)*end, end - begin);
+
+ return Common::String(begin, end);
+ }
+
+ Common::String ResourceManager::loadText(const Common::String & name) const {
+ Common::SeekableReadStream * stream = getResource(name);
+ if (!stream)
+ error("no text resource %s", name.c_str());
+ return loadText(stream);
+ }
+
} // End of namespace AGDS
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index cf8b8f96036..6af50512276 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -71,6 +71,9 @@ public:
Common::SeekableReadStream * getResource(const Common::String &name) const;
const Graphics::Surface * loadPicture(const Common::String & name, const Graphics::PixelFormat &format);
+
+ static Common::String loadText(Common::SeekableReadStream *stream);
+ Common::String loadText(const Common::String & name) const;
};
Commit: 262bc0cd061f9d8c594029ada569c7d888140a1a
https://github.com/scummvm/scummvm/commit/262bc0cd061f9d8c594029ada569c7d888140a1a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:55+01:00
Commit Message:
AGDS: added system variables support
Changed paths:
A engines/agds/systemVariable.cpp
A engines/agds/systemVariable.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/module.mk
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3ca058b3f81..9536e86534c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -26,6 +26,7 @@
#include "agds/process.h"
#include "agds/region.h"
#include "agds/screen.h"
+#include "agds/systemVariable.h"
#include "common/error.h"
#include "common/events.h"
#include "common/ini-file.h"
@@ -88,6 +89,8 @@ bool AGDSEngine::load() {
return false;
_patch.open("patch.adb"); //it's ok
+
+ initSystemVariables();
loadScreen("main");
return true;
@@ -337,4 +340,73 @@ Graphics::TransparentSurface *AGDSEngine::convertToTransparent(const Graphics::S
return t;
}
+void AGDSEngine::initSystemVariables() {
+ _systemVars["inventory_scr"] = new StringSystemVariable();
+ _systemVars["escape_scr"] = new StringSystemVariable("none");
+ _systemVars["load_scr"] = new StringSystemVariable();
+ _systemVars["load_scr"] = new StringSystemVariable();
+
+ _systemVars["gfx_bright"] = new IntegerSystemVariable(50);
+ _systemVars["gfx_contrast"] = new IntegerSystemVariable(50);
+
+ _systemVars["sound_volume"] = new IntegerSystemVariable(100);
+ _systemVars["music_volume"] = new IntegerSystemVariable(80);
+ _systemVars["tell_volume"] = new IntegerSystemVariable(100);
+
+ _systemVars["text_speed"] = new IntegerSystemVariable(70);
+ _systemVars["tell_mode"] = new IntegerSystemVariable(3);
+ _systemVars["version"] = new IntegerSystemVariable(1);
+
+ _systemVars["objtext_x"] = new IntegerSystemVariable(-1);
+ _systemVars["objtext_y"] = new IntegerSystemVariable(-1);
+ _systemVars["objtext_mode"] = new IntegerSystemVariable(-1);
+ _systemVars["objtext_font"] = new IntegerSystemVariable(-1);
+
+ _systemVars["inv_open"] = new StringSystemVariable();
+ _systemVars["inv_close"] = new StringSystemVariable();
+ _systemVars["inv_region"] = new StringSystemVariable();
+
+ _systemVars["anim_zoom"] = new IntegerSystemVariable(1);
+
+ _systemVars["screen_curtain"] = new IntegerSystemVariable(1);
+ _systemVars["music_curtain"] = new IntegerSystemVariable(1);
+ _systemVars["sound_curtain"] = new IntegerSystemVariable(1);
+
+ _systemVars["old_music_volume"] = new IntegerSystemVariable();
+ _systemVars["old_sound_volume"] = new IntegerSystemVariable();
+ _systemVars["old_screen_fade"] = new IntegerSystemVariable();
+
+ _systemVars["subtitle_x"] = new IntegerSystemVariable();
+ _systemVars["subtitle_y"] = new IntegerSystemVariable();
+ _systemVars["subtitle_type"] = new IntegerSystemVariable(3);
+ _systemVars["subtitles"] = new IntegerSystemVariable();
+
+ _systemVars["tell_font"] = new IntegerSystemVariable();
+ _systemVars["npc_tell_font"] = new IntegerSystemVariable();
+ _systemVars["edit_font"] = new IntegerSystemVariable();
+ _systemVars["delay_after_tell"] = new IntegerSystemVariable();
+
+ _systemVars["scroll_factor"] = new IntegerSystemVariable(30);
+
+ _systemVars["dialog_var"] = new IntegerSystemVariable();
+ _systemVars["subtitle_width"] = new IntegerSystemVariable(-1);
+ _systemVars["flash_mouse"] = new IntegerSystemVariable();
+ _systemVars["scale_char"] = new IntegerSystemVariable();
+
+ _systemVars["init_resources"] = new StringSystemVariable();
+ _systemVars["done_resources"] = new StringSystemVariable();
+ _systemVars["tell_close_inv"] = new IntegerSystemVariable(1);
+ _systemVars["gamma"] = new IntegerSystemVariable();
+}
+
+SystemVariable *AGDSEngine::getSystemVariable(const Common::String &name) {
+ SystemVariablesType::iterator i = _systemVars.find(name);
+ if (i != _systemVars.end())
+ return i->_value;
+
+ error("no system variable %s", name.c_str());
+}
+
+
+
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index da56e3fcd7c..396ec8930d7 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -52,6 +52,7 @@ class Process;
struct Region;
class MJPGPlayer;
class Screen;
+class SystemVariable;
class AGDSEngine : public Engine {
friend class Process;
@@ -112,10 +113,14 @@ private:
_userEnabled = enabled;
}
+ void initSystemVariables();
+ SystemVariable *getSystemVariable(const Common::String &name);
+
private:
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
typedef Common::HashMap<Common::String, Screen *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ScreensType;
typedef Common::HashMap<Common::String, Region *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> RegionsType;
+ typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
typedef Common::List<Process> ProcessListType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
@@ -129,6 +134,7 @@ private:
int _sharedStorageIndex;
Common::String _sharedStorage[10];
GlobalsType _globals;
+ SystemVariablesType _systemVars;
int _timer;
Graphics::PixelFormat _pixelFormat;
MJPGPlayer * _mjpgPlayer;
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index cd9ebd7aaf7..3ee497fd130 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -10,6 +10,7 @@ MODULE_OBJS := \
process_opcodes.o \
region.o \
resourceManager.o \
+ systemVariable.o \
screen.o
# This module can be built as a plugin
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index aa2bfe4dd0f..152bea272e2 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -159,8 +159,8 @@ enum Opcode {
kStub139 = 139,
kScreenChangeScreenPatch = 140,
kStub141 = 141,
- kSetSystemVariable = 142,
- kSetIntegerVariable = 143,
+ kSetStringSystemVariable = 142,
+ kSetSystemIntegerVariable = 143,
kStub144 = 144,
kStub145 = 145,
kGetRegionCenterX = 146,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 60f90db73c3..fb985bfdb56 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -123,9 +123,9 @@ private:
void getObjectPictureHeight();
void quit();
- void setSystemVariable();
+ void setStringSystemVariable();
void getIntegerSystemVariable();
- void setIntegerVariable();
+ void setIntegerSystemVariable();
void getGlobal(unsigned index);
void setGlobal();
void resetGlobal();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 20326d275c2..f2e69eb833d 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -25,6 +25,7 @@
#include "agds/opcode.h"
#include "agds/region.h"
#include "agds/screen.h"
+#include "agds/systemVariable.h"
#include "common/debug.h"
namespace AGDS {
@@ -44,21 +45,30 @@ void Process::enter(uint16 magic, uint16 size) {
_object->readStringTable(resOffset, resCount);
}
-void Process::setSystemVariable() {
+void Process::setStringSystemVariable() {
int16 valueIndex = pop();
Common::String name = popString();
if (valueIndex != -1) {
Common::String value = getString(valueIndex);
debug("setSystemVariable %s to %s", name.c_str(), value.c_str());
+ _engine->getSystemVariable(name)->setString(value);
} else {
debug("resetSystemVariable %s", name.c_str());
+ _engine->getSystemVariable(name)->reset();
}
}
+void Process::setIntegerSystemVariable() {
+ int value = pop();
+ Common::String name = popString();
+ debug("setIntegerSystemVariable: %s -> %d", name.c_str(), value);
+ _engine->getSystemVariable(name)->setInteger(value);
+}
+
void Process::getIntegerSystemVariable() {
Common::String name = popString();
- int value = 0;
+ int value = _engine->getSystemVariable(name)->getInteger();
debug("getIntegerSystemVariable: %s -> %d", name.c_str(), value);
push(value);
}
@@ -141,12 +151,6 @@ void Process::loadMouse() {
_engine->loadCursor(name);
}
-void Process::setIntegerVariable() {
- int value = pop();
- Common::String name = popString();
- debug("setIntegerVariable stub: %s -> %d", name.c_str(), value);
-}
-
void Process::setGlobal() {
Common::String name = popString();
int value = pop();
@@ -694,8 +698,8 @@ ProcessExitCode Process::execute() {
OP (kResetGlobal, resetGlobal);
OP (kStub136, stub136);
OP (kScreenChangeScreenPatch, changeScreenPatch);
- OP (kSetSystemVariable, setSystemVariable);
- OP (kSetIntegerVariable, setIntegerVariable);
+ OP (kSetStringSystemVariable, setStringSystemVariable);
+ OP (kSetSystemIntegerVariable, setIntegerSystemVariable);
OP (kGetRegionCenterX, getRegionCenterX);
OP (kGetRegionCenterY, getRegionCenterY);
OP (kGetIntegerSystemVariable, getIntegerSystemVariable);
diff --git a/engines/agds/systemVariable.cpp b/engines/agds/systemVariable.cpp
new file mode 100644
index 00000000000..75abec38ec4
--- /dev/null
+++ b/engines/agds/systemVariable.cpp
@@ -0,0 +1,61 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/systemVariable.h"
+#include "common/debug.h"
+#include "common/textconsole.h"
+
+namespace AGDS {
+
+ const Common::String & IntegerSystemVariable::getString() const {
+ error("invalid type");
+ }
+
+ int IntegerSystemVariable::getInteger() const {
+ return _value;
+ }
+
+ void IntegerSystemVariable::setString(const Common::String &value) {
+ error("invalid type");
+ }
+
+ void IntegerSystemVariable::setInteger(int value) {
+ _value = value;
+ }
+
+ const Common::String & StringSystemVariable::getString() const {
+ return _value;
+ }
+
+ int StringSystemVariable::getInteger() const {
+ error("invalid type");
+ }
+
+ void StringSystemVariable::setString(const Common::String &value) {
+ _value = value;
+ }
+
+ void StringSystemVariable::setInteger(int value) {
+ error("invalid type");
+ }
+
+}
diff --git a/engines/agds/systemVariable.h b/engines/agds/systemVariable.h
new file mode 100644
index 00000000000..7d12bb87d79
--- /dev/null
+++ b/engines/agds/systemVariable.h
@@ -0,0 +1,79 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_SYSTEM_VARIABLE_H
+#define AGDS_SYSTEM_VARIABLE_H
+
+#include "common/scummsys.h"
+#include "common/str.h"
+
+namespace AGDS {
+
+class SystemVariable {
+public:
+ virtual ~SystemVariable() {}
+
+ virtual const Common::String &getString() const = 0;
+ virtual int getInteger() const = 0;
+ virtual void setString(const Common::String &value) = 0;
+ virtual void setInteger(int value) = 0;
+ virtual void reset() = 0;
+};
+
+class IntegerSystemVariable : public SystemVariable {
+ int _value;
+ int _defaultValue;
+
+public:
+ IntegerSystemVariable(int defaultValue = 0):
+ _value(defaultValue), _defaultValue(defaultValue) {
+ }
+
+ virtual const Common::String &getString() const;
+ virtual int getInteger() const;
+ virtual void setString(const Common::String &value);
+ virtual void setInteger(int value);
+ virtual void reset() {
+ _value = _defaultValue;
+ }
+};
+
+class StringSystemVariable : public SystemVariable {
+ Common::String _value;
+ Common::String _defaultValue;
+
+public:
+ StringSystemVariable(const Common::String &defaultValue = Common::String()):
+ _value(defaultValue), _defaultValue(defaultValue) {
+ }
+ virtual const Common::String &getString() const;
+ virtual int getInteger() const;
+ virtual void setString(const Common::String &value);
+ virtual void setInteger(int value);
+ virtual void reset() {
+ _value = _defaultValue;
+ }
+};
+
+} // End of namespace AGDS
+
+#endif /* AGDS_SYSTEM_VARIABLE_H */
Commit: 674ce7b09fc8c148432cf762085a44ebb6cbfc1e
https://github.com/scummvm/scummvm/commit/674ce7b09fc8c148432cf762085a44ebb6cbfc1e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:55+01:00
Commit Message:
AGDS: added stubs 172/194
Changed paths:
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.h b/engines/agds/process.h
index fb985bfdb56..f048bf342f8 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -162,6 +162,7 @@ private:
void stub154();
void stub155();
void stub166();
+ void stub172();
void stub173();
void stub174();
void stub176();
@@ -170,6 +171,7 @@ private:
void stub190();
void stub191();
void stub192();
+ void stub194();
void stub202(unsigned size);
void playFilm();
void stub200();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f2e69eb833d..40db3835d36 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -266,10 +266,6 @@ void Process::setCloneVar() {
push(arg3);
}
-void Process::stub176() {
- debug("stub176");
-}
-
void Process::disableUser() {
debug("disableUser");
_engine->enableUser(false);
@@ -360,6 +356,11 @@ void Process::stub166() {
debug("stub166 %d %d", arg1, arg2);
}
+void Process::stub172() {
+ int value = pop();
+ debug("stub172: %d", value);
+}
+
void Process::stub173() {
debug("stub173: delAnimations?");
}
@@ -368,6 +369,10 @@ void Process::stub174() {
debug("stub174: mouse pointer mode 1?");
}
+void Process::stub176() {
+ debug("stub176");
+}
+
void Process::stub192() {
int value = pop();
Common::String name = popString();
@@ -435,6 +440,10 @@ void Process::stub191() {
debug("stub191: setting some mouse flag to %d", value);
}
+void Process::stub194() {
+ debug("stub194");
+}
+
void Process::getObjectPictureWidth() {
Common::String name = popString();
debug("getObjectPictureWidth %s", name.c_str());
@@ -712,6 +721,7 @@ ProcessExitCode Process::execute() {
OP (kStub154, stub154);
OP (kStub155, stub155);
OP (kStub166, stub166);
+ OP (kStub172, stub172);
OP (kStub173, stub173);
OP (kStub174, stub174);
OP (kStub192, stub192);
@@ -726,6 +736,7 @@ ProcessExitCode Process::execute() {
OP (kStub188, stub188);
OP (kStub190, stub190);
OP (kStub191, stub191);
+ OP (kStub194, stub194);
OP (kGetObjectPictureWidth, getObjectPictureWidth);
OP (kGetObjectPictureHeight, getObjectPictureHeight);
OP (kLoadPicture, loadPicture);
Commit: 372e78479fa881e3998add608f03ac214caddbdd
https://github.com/scummvm/scummvm/commit/372e78479fa881e3998add608f03ac214caddbdd
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:55+01:00
Commit Message:
AGDS: fixed non-transparent surfaces in objects
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 9536e86534c..baca10c85ee 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -328,14 +328,14 @@ void AGDSEngine::loadCursor(const Common::String &name, unsigned index) {
delete cursor;
}
-const Graphics::Surface * AGDSEngine::loadPicture(const Common::String &name)
+Graphics::TransparentSurface * AGDSEngine::loadPicture(const Common::String &name)
{ return convertToTransparent(_resourceManager.loadPicture(name, _pixelFormat)); }
Graphics::TransparentSurface *AGDSEngine::convertToTransparent(const Graphics::Surface *surface) {
if (!surface)
return NULL;
Graphics::TransparentSurface * t = new Graphics::TransparentSurface(*surface, true);
- t->applyColorKey(0xff, 0, 0xff, true);
+ t->applyColorKey(0xff, 0, 0xff);
delete surface;
return t;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 396ec8930d7..6bc82b9fe27 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -105,7 +105,7 @@ private:
return _currentScreen;
}
- const Graphics::Surface * loadPicture(const Common::String &name);
+ Graphics::TransparentSurface *loadPicture(const Common::String &name);
Graphics::TransparentSurface *convertToTransparent(const Graphics::Surface *surface); //destroys surface!
void loadCursor(const Common::String &name, unsigned index = 0);
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index be1f2afe8df..fd8618385e2 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -25,6 +25,7 @@
#include "common/memstream.h"
#include "common/rect.h"
#include "graphics/surface.h"
+#include "graphics/transparent_surface.h"
namespace AGDS {
@@ -87,7 +88,7 @@ const Object::StringEntry & Object::getString(uint16 index) const {
return _stringTable[index];
}
-void Object::setPicture(const Graphics::Surface *picture) {
+void Object::setPicture(Graphics::TransparentSurface *picture) {
delete _picture;
_picture = picture;
}
@@ -97,7 +98,7 @@ void Object::paint(Graphics::Surface &backbuffer) {
Common::Point dst = _pos;
Common::Rect srcRect = _picture->getRect();
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
- backbuffer.copyRectToSurface(*_picture, dst.x, dst.y, srcRect);
+ _picture->blit(backbuffer, _pos.x, _pos.y, Graphics::FLIP_NONE, &srcRect);
}
}
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 00ffa26b1fa..987b5c8c860 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -25,8 +25,10 @@
#include "common/scummsys.h"
#include "common/array.h"
+#include "common/rect.h"
#include "common/stream.h"
-#include "graphics/surface.h"
+
+namespace Graphics { class Surface; class TransparentSurface; }
namespace AGDS {
@@ -52,7 +54,7 @@ private:
CodeType _code;
StringTableType _stringTable;
bool _stringTableLoaded;
- const Graphics::Surface * _picture;
+ Graphics::TransparentSurface * _picture;
Region * _region;
Common::Point _pos;
uint _clickHandler;
@@ -72,9 +74,9 @@ public:
return _code;
}
- void setPicture(const Graphics::Surface *);
+ void setPicture(Graphics::TransparentSurface *);
- const Graphics::Surface *getPicture() const {
+ const Graphics::TransparentSurface *getPicture() const {
return _picture;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 40db3835d36..85ab91c0178 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -26,6 +26,7 @@
#include "agds/region.h"
#include "agds/screen.h"
#include "agds/systemVariable.h"
+#include "graphics/transparent_surface.h"
#include "common/debug.h"
namespace AGDS {
Commit: 899d64723962c99a7ab5438674706eae7cdbf041
https://github.com/scummvm/scummvm/commit/899d64723962c99a7ab5438674706eae7cdbf041
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:55+01:00
Commit Message:
AGDS: more stubs, implemented dup()
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 152bea272e2..9716127b1ac 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -30,7 +30,7 @@ enum Opcode {
kJumpZImm16 = 8,
kJumpImm16 = 9,
kPop = 10,
- kStub11 = 11,
+ kDup = 11,
kExitProcess = 12,
kSuspendProcess = 13,
kStub14 = 14,
@@ -118,7 +118,7 @@ enum Opcode {
kDisableUser = 98,
kEnableUser = 99,
kStub100 = 100,
- kStub101 = 101,
+ kUpdateSampleVarOr4 = 101,
kStub102 = 102,
kStub103 = 103,
kStub104 = 104,
@@ -159,8 +159,8 @@ enum Opcode {
kStub139 = 139,
kScreenChangeScreenPatch = 140,
kStub141 = 141,
- kSetStringSystemVariable = 142,
- kSetSystemIntegerVariable = 143,
+ kSetStringSystemVariable = 142,
+ kSetSystemIntegerVariable = 143,
kStub144 = 144,
kStub145 = 145,
kGetRegionCenterX = 146,
@@ -229,7 +229,7 @@ enum Opcode {
kStub209 = 209,
kStub210 = 210,
kStub211 = 211,
- kStub212 = 212,
+ kSetSampleVolumeAndPan = 212,
kStub213 = 213,
kStub214 = 214,
kStub215 = 215,
@@ -251,7 +251,7 @@ enum Opcode {
kStub231 = 231,
kStub232 = 232,
kStub233 = 233,
- kStub234 = 234,
+ kGetSampleVolume = 234,
kStub235 = 235,
kStub236 = 236,
kStub237 = 237,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index f048bf342f8..cb2b49d696a 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -69,6 +69,10 @@ private:
int32 pop();
int32 top();
+ void dup() {
+ push(top());
+ }
+
void jump(int delta)
{ _ip += delta; }
@@ -112,6 +116,9 @@ private:
void loadTextFromObject();
void loadAnimation();
void loadSample();
+ void getSampleVolume();
+ void setSampleVolumeAndPan();
+ void updateSampleVarOr4();
void cloneObject();
void setTimer();
void getRegionCenterX();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 85ab91c0178..1e14edad9b8 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -119,6 +119,26 @@ void Process::loadSample() {
debug("loadSample %s", name.c_str());
}
+void Process::getSampleVolume() {
+ Common::String name = popString();
+ debug("getSampleVolume: stub");
+ push(100);
+}
+
+void Process::setSampleVolumeAndPan() {
+ int pan = pop();
+ int volume = pop();
+ Common::String name = popString();
+ debug("setSampleVolumeAndPan %s %d %d", name.c_str(), volume, pan);
+}
+
+void Process::updateSampleVarOr4() {
+ Common::String name = popString();
+ debug("updateSampleVarOr4 stub %s", name.c_str());
+ int value = _engine->getGlobal(name);
+ _engine->setGlobal(name, value | 4);
+}
+
void Process::loadScreenObject() {
Common::String name = popString();
debug("loadScreenObject: %s", name.c_str());
@@ -645,6 +665,7 @@ ProcessExitCode Process::execute() {
OP_W (kJumpZImm16, jumpz);
OP_W (kJumpImm16, jump);
OP (kPop, pop);
+ OP (kDup, dup);
OP (kExitProcess, exitProcess);
OP (kSuspendProcess, suspendProcess);
OP_C (kPushImm8, push);
@@ -686,6 +707,7 @@ ProcessExitCode Process::execute() {
OP (kLoadAnimationFromObject, loadAnimationFromObject);
OP (kDisableUser, disableUser);
OP (kEnableUser, enableUser);
+ OP (kUpdateSampleVarOr4, updateSampleVarOr4);
OP (kClearScreen, clearScreen);
OP (kLoadMouse, loadMouse);
OP (kExitProcessNextScreen80, exitProcessSetNextScreen80);
@@ -741,6 +763,7 @@ ProcessExitCode Process::execute() {
OP (kGetObjectPictureWidth, getObjectPictureWidth);
OP (kGetObjectPictureHeight, getObjectPictureHeight);
OP (kLoadPicture, loadPicture);
+ OP (kSetSampleVolumeAndPan, setSampleVolumeAndPan);
OP (kFadeObject, fadeObject);
OP (kLoadFont, loadFont);
OP_U (kStub202ScreenHandler, stub202);
@@ -749,6 +772,7 @@ ProcessExitCode Process::execute() {
OP (kStub200, stub200);
OP (kStub206, stub206);
OP_U (kOnKey, onKey);
+ OP (kGetSampleVolume, getSampleVolume);
OP (kStub235, stub235);
OP (kHasGlobal, hasGlobal);
default:
Commit: 4348bf36f77916db20979a36454a940ff23d3d16
https://github.com/scummvm/scummvm/commit/4348bf36f77916db20979a36454a940ff23d3d16
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:55+01:00
Commit Message:
AGDS: added exitProcessCreatePatch stub
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 9716127b1ac..380b52a9cda 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -176,7 +176,7 @@ enum Opcode {
kStub156 = 156,
kStub157 = 157,
kQuit = 158,
- kStub159 = 159,
+ kExitProcessCreatePatch = 159,
kStub160 = 160,
kStub161 = 161,
kExitScreen = 162,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index cb2b49d696a..a97d5c48e94 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -91,6 +91,7 @@ private:
void enter(uint16 magic, uint16 size);
void exitProcess();
+ void exitProcessCreatePatch();
void suspendProcess(ProcessExitCode code = kExitCodeSuspend);
void exitScreen();
void exitProcessSetNextScreen();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 1e14edad9b8..b079f3da6fe 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -427,11 +427,15 @@ void Process::stub188() {
void Process::exitProcess() {
- debug("exit");
+ debug("exitProcess");
_status = kStatusDone;
_exitCode = kExitCodeDestroy;
}
+void Process::exitProcessCreatePatch() {
+ debug("exitProcessCreatePatch stub");
+}
+
void Process::clearScreen() {
debug("clearScreen");
}
@@ -749,6 +753,7 @@ ProcessExitCode Process::execute() {
OP (kStub174, stub174);
OP (kStub192, stub192);
OP (kQuit, quit);
+ OP (kExitProcessCreatePatch, exitProcessCreatePatch);
OP (kExitScreen, exitScreen);
OP (kLoadPreviousScreen, loadPreviousScreen);
OP (kMoveScreenObject, moveScreenObject);
Commit: 86ef95ea5342c84dd56b96b7491418d3e0cdb760
https://github.com/scummvm/scummvm/commit/86ef95ea5342c84dd56b96b7491418d3e0cdb760
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:55+01:00
Commit Message:
AGDS: return -1 when global was not declared
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index baca10c85ee..83c0f6511a5 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -314,8 +314,8 @@ int AGDSEngine::getGlobal(const Common::String &name) const {
if (i != _globals.end())
return i->_value;
else {
- debug("global %s was not declared, returning 0", name.c_str());
- return 0;
+ debug("global %s was not declared, returning -1", name.c_str());
+ return -1;
}
}
Commit: f566272553bc7c137496378536910fa09f2cee61
https://github.com/scummvm/scummvm/commit/f566272553bc7c137496378536910fa09f2cee61
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:55+01:00
Commit Message:
AGDS: implemented enough opcodes/stubs to run new game
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 83c0f6511a5..73ecf4669e0 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -41,7 +41,8 @@ namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
_gameDescription(gameDesc), _sharedStorageIndex(-2), _timer(0),
_mjpgPlayer(NULL), _currentScreen(NULL), _mouseCursor(NULL),
- _mouse(400, 300), _userEnabled(false), _currentRegion(NULL) {
+ _mouse(400, 300), _userEnabled(false), _currentRegion(NULL),
+ _random("agds") {
}
AGDSEngine::~AGDSEngine() {
@@ -177,6 +178,9 @@ void AGDSEngine::runProcess() {
case kExitCodeLoadPreviousScreenObject:
loadScreen(_previousScreen);
break;
+ case kExitCodeLoadInventoryObject:
+ loadObject(process.getExitArg1());
+ break;
case kExitCodeSuspend:
debug("process %s suspended", name.c_str());
return;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 6bc82b9fe27..91ce7e24527 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/hashmap.h"
+#include "common/random.h"
#include "common/rect.h"
#include "engines/advancedDetector.h"
#include "agds/database.h"
@@ -146,6 +147,7 @@ private:
Common::String _onLeaveObject;
bool _userEnabled;
MouseMap _mouseMap;
+ Common::RandomSource _random;
};
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 380b52a9cda..3b1d09ae008 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -33,7 +33,7 @@ enum Opcode {
kDup = 11,
kExitProcess = 12,
kSuspendProcess = 13,
- kStub14 = 14,
+ kPushImm32 = 14,
kPushImm16 = 15,
kPushImm8 = 16,
kPushImm16_2 = 17,
@@ -93,7 +93,7 @@ enum Opcode {
kUpdateScreenHeightToDisplay = 72,
kLoadTextFromObject = 73,
kStub74 = 74,
- kStub75 = 75,
+ kScreenLoadRegion = 75,
kScreenLoadObject = 76,
kScreenCloneObject = 77,
kScreenRemoveObject = 78,
@@ -117,18 +117,18 @@ enum Opcode {
kStub97 = 97,
kDisableUser = 98,
kEnableUser = 99,
- kStub100 = 100,
+ kUpdateSampleVarOr2 = 100,
kUpdateSampleVarOr4 = 101,
kStub102 = 102,
kStub103 = 103,
kStub104 = 104,
kClearScreen = 105,
- kStub106 = 106,
+ kInventoryClear = 106,
kStub107 = 107,
kLoadMouse = 108,
kStub109 = 109,
kStub110 = 110,
- kStub111 = 111,
+ kInventoryAddObject = 111,
kStub112 = 112,
kStub113 = 113,
kStub114 = 114,
@@ -139,9 +139,9 @@ enum Opcode {
kStub119 = 119,
kStub120 = 120,
kStub121 = 121,
- kStub122 = 122,
+ kPlayerSay = 122,
kStub123 = 123,
- kStub124 = 124,
+ kNPCSay = 124,
kStub125 = 125,
kStub126 = 126,
kSetTimer = 127,
@@ -188,7 +188,7 @@ enum Opcode {
kStub168 = 168,
kGetIntegerSystemVariable = 169,
kStub170 = 170,
- kStub171 = 171,
+ kGetRandomNumber = 171,
kStub172 = 172,
kStub173 = 173,
kStub174 = 174,
@@ -225,13 +225,13 @@ enum Opcode {
kFindObjectInMouseArea = 205,
kStub206 = 206,
kStub207 = 207,
- kStub208 = 208,
+ kFogOnCharacter = 208,
kStub209 = 209,
kStub210 = 210,
kStub211 = 211,
kSetSampleVolumeAndPan = 212,
kStub213 = 213,
- kStub214 = 214,
+ kPlaySound = 214,
kStub215 = 215,
kStub216 = 216,
kStub217 = 217,
@@ -264,7 +264,7 @@ enum Opcode {
kStub244 = 244,
kStub245 = 245,
kStub246 = 246,
- kStub247 = 247
+ kSetDialogForNextFilm = 247
};
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index a97d5c48e94..ca8f375d823 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -99,10 +99,14 @@ private:
void loadPreviousScreen();
void call(uint16 addr);
+ void inventoryClear();
+ void inventoryAddObject();
+
void getObjectId();
void clearScreen();
void loadPicture();
void loadMouse();
+ void loadScreenRegion();
void loadScreenObject();
void loadFont();
void removeScreenObject();
@@ -117,8 +121,10 @@ private:
void loadTextFromObject();
void loadAnimation();
void loadSample();
+ void playSound();
void getSampleVolume();
void setSampleVolumeAndPan();
+ void updateSampleVarOr2();
void updateSampleVarOr4();
void cloneObject();
void setTimer();
@@ -129,8 +135,14 @@ private:
void setFontGlyphSize();
void getObjectPictureWidth();
void getObjectPictureHeight();
+ void fogOnCharacter();
void quit();
+ void setDialogForNextFilm();
+ void npcSay();
+ void playerSay();
+
+ void getRandomNumber();
void setStringSystemVariable();
void getIntegerSystemVariable();
void setIntegerSystemVariable();
@@ -158,7 +170,9 @@ private:
void onScreenBD(unsigned size);
void loadMouseStub66();
+ void stub74();
void stub82();
+ void stub119();
void stub128();
void stub129();
void stub130();
@@ -180,10 +194,13 @@ private:
void stub191();
void stub192();
void stub194();
+ void stub199();
void stub202(unsigned size);
void playFilm();
void stub200();
void stub206();
+ void stub215();
+ void stub223();
void stub235();
void debug(const char *str, ...);
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index 7ec4b6803da..02d787b3e03 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -30,6 +30,7 @@ namespace AGDS {
kExitCodeSuspend = 5,
kExitCodeDestroyProcessSetNextScreen = 6,
kExitCodeLoadScreenObject = 8,
+ kExitCodeLoadInventoryObject = 10,
kExitCodeExitScreen = 15,
kExitCodeLoadPreviousScreenObject = 99
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b079f3da6fe..aa46a2f38bc 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -132,6 +132,19 @@ void Process::setSampleVolumeAndPan() {
debug("setSampleVolumeAndPan %s %d %d", name.c_str(), volume, pan);
}
+void Process::playSound() {
+ Common::String name = popFilename();
+ int arg = pop();
+ debug("playSound %s %d", name.c_str(), arg);
+}
+
+void Process::updateSampleVarOr2() {
+ Common::String name = popString();
+ debug("updateSampleVarOr4 stub %s", name.c_str());
+ int value = _engine->getGlobal(name);
+ _engine->setGlobal(name, value | 2);
+}
+
void Process::updateSampleVarOr4() {
Common::String name = popString();
debug("updateSampleVarOr4 stub %s", name.c_str());
@@ -145,6 +158,12 @@ void Process::loadScreenObject() {
suspend(kExitCodeLoadScreenObject, name);
}
+void Process::loadScreenRegion() {
+ Common::String name = popString();
+ debug("loadScreenRegion %s", name.c_str());
+ _engine->loadObject(_engine->currentScreen()->getName())->setRegion(_engine->loadRegion(name));
+}
+
void Process::cloneObject() {
Common::String arg2 = popString();
Common::String arg1 = popString();
@@ -172,6 +191,13 @@ void Process::loadMouse() {
_engine->loadCursor(name);
}
+void Process::getRandomNumber() {
+ int max = pop();
+ int value = max > 0? _engine->_random.getRandomNumber(max - 1): 0;
+ debug("random %d -> %d", max, value);
+ push(value);
+}
+
void Process::setGlobal() {
Common::String name = popString();
int value = pop();
@@ -312,12 +338,22 @@ void Process::fadeObject() {
debug("fadeObject %s %d", name.c_str(), arg);
}
+void Process::stub74() {
+ int arg2 = pop();
+ int arg1 = pop();
+ debug("stub74: %d %d", arg1, arg2);
+}
+
void Process::stub82() {
Common::String arg2 = popString();
Common::String arg1 = popString();
debug("stub82: %s %s", arg1.c_str(), arg2.c_str());
}
+void Process::stub119() {
+ debug("stub119");
+}
+
void Process::stub128() {
debug("processCleanupStub128");
}
@@ -400,6 +436,52 @@ void Process::stub192() {
debug("stub192: %s: set some object flag to %d", name.c_str(), value);
}
+void Process::stub190() {
+ int value = pop();
+ debug("stub190 %d", value);
+}
+
+void Process::stub191() {
+ int value = pop();
+ value = value > 0? 1: 0;
+ debug("stub191: setting some mouse flag to %d", value);
+}
+
+void Process::stub194() {
+ debug("stub194");
+}
+
+void Process::stub199() {
+ int value = pop();
+ debug("stub199: %d", value);
+}
+
+void Process::stub200() {
+ int value = pop();
+ debug("stub200: %d", value);
+}
+
+void Process::stub202(unsigned size) {
+ debug("stub203, %u instructions", size);
+ _ip += size;
+}
+
+void Process::stub206() {
+ int arg2 = pop();
+ int arg1 = pop();
+ debug("stub206 (mouse?) %d %d", arg1, arg2);
+}
+
+void Process::stub215() {
+ int id = pop();
+ debug("stub215: sound group %d", id);
+}
+
+void Process::stub223() {
+ int value = pop();
+ debug("stub199: %d", value);
+}
+
void Process::setFontGlyphSize() {
_glyphHeight = pop();
_glyphWidth = pop();
@@ -454,19 +536,22 @@ void Process::quit() {
_engine->quitGame();
}
-void Process::stub190() {
+void Process::setDialogForNextFilm() {
int value = pop();
- debug("stub190 %d", value);
+ debug("setDialogForNextFilm %d", value);
}
-void Process::stub191() {
- int value = pop();
- value = value > 0? 1: 0;
- debug("stub191: setting some mouse flag to %d", value);
+void Process::npcSay() {
+ debug("npcSay -> playerSay");
+ playerSay();
}
-void Process::stub194() {
- debug("stub194");
+void Process::playerSay() {
+ Common::String arg3 = popString();
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("playerSay %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
+ //close inventory here if close flag was set
}
void Process::getObjectPictureWidth() {
@@ -489,11 +574,6 @@ void Process::getObjectPictureHeight() {
push(value);
}
-void Process::stub202(unsigned size) {
- debug("stub203, %u instructions", size);
- _ip += size;
-}
-
void Process::playFilm() {
Common::String audio = popFilename();
Common::String video = popFilename();
@@ -503,15 +583,14 @@ void Process::playFilm() {
suspend();
}
-void Process::stub200() {
- int value = pop();
- debug("stub200: %d", value);
+void Process::inventoryClear() {
+ debug("inventoryClear");
}
-void Process::stub206() {
- int arg2 = pop();
- int arg1 = pop();
- debug("stub206 (mouse?) %d %d", arg1, arg2);
+void Process::inventoryAddObject() {
+ Common::String name = popString();
+ debug("inventoryAddObject %s", name.c_str());
+ suspend(kExitCodeLoadInventoryObject, name);
}
void Process::exitProcessSetNextScreen() {
@@ -603,6 +682,13 @@ void Process::findObjectInMouseArea() {
_engine->_mouseMap.add(MouseRegion(region, arg2, arg3));
}
+void Process::fogOnCharacter() {
+ int arg2 = pop();
+ int arg1 = pop();
+ Common::String name = popString();
+ debug("fogOnCharacter %s %d %d", name.c_str(), arg1, arg2);
+}
+
void Process::loadRegionFromObject() {
Common::String name = popString();
debug("loadRegionFromObject %s", name.c_str());
@@ -657,6 +743,9 @@ void Process::stub235() {
#define OP_UU(NAME, METHOD) \
case NAME: { uint16 arg1 = next16(); uint16 arg2 = next16(); METHOD (arg1, arg2); } break
+#define OP_D(NAME, METHOD) \
+ case NAME: { uint16 arg1 = next16(); uint32 arg2 = next16(); METHOD (arg1 | (arg2 << 16)); } break
+
ProcessExitCode Process::execute() {
_exitCode = kExitCodeDestroy;
@@ -672,6 +761,7 @@ ProcessExitCode Process::execute() {
OP (kDup, dup);
OP (kExitProcess, exitProcess);
OP (kSuspendProcess, suspendProcess);
+ OP_D (kPushImm32, push);
OP_C (kPushImm8, push);
OP_W (kPushImm16, push);
OP_C (kPushImm8_2, push);
@@ -711,20 +801,28 @@ ProcessExitCode Process::execute() {
OP (kLoadAnimationFromObject, loadAnimationFromObject);
OP (kDisableUser, disableUser);
OP (kEnableUser, enableUser);
+ OP (kUpdateSampleVarOr2, updateSampleVarOr2);
OP (kUpdateSampleVarOr4, updateSampleVarOr4);
OP (kClearScreen, clearScreen);
+ OP (kInventoryClear, inventoryClear);
OP (kLoadMouse, loadMouse);
+ OP (kInventoryAddObject, inventoryAddObject);
OP (kExitProcessNextScreen80, exitProcessSetNextScreen80);
OP (kStub82, stub82);
OP (kSetScreenHeight, setScreenHeight);
OP (kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay);
OP (kLoadTextFromObject, loadTextFromObject);
+ OP (kStub74, stub74);
OP (kScreenLoadObject, loadScreenObject);
+ OP (kScreenLoadRegion, loadScreenRegion);
OP (kScreenCloneObject, cloneObject);
OP (kExitProcessSetNextScreen, exitProcessSetNextScreen);
OP (kScreenRemoveObject, removeScreenObject);
OP (kLoadAnimation, loadAnimation);
OP (kLoadSample, loadSample);
+ OP (kStub119, stub119);
+ OP (kPlayerSay, playerSay);
+ OP (kNPCSay, npcSay);
OP (kSetTimer, setTimer);
OP (kProcessCleanupStub128, stub128);
OP (kStub129, stub129);
@@ -739,6 +837,7 @@ ProcessExitCode Process::execute() {
OP (kGetRegionCenterX, getRegionCenterX);
OP (kGetRegionCenterY, getRegionCenterY);
OP (kGetIntegerSystemVariable, getIntegerSystemVariable);
+ OP (kGetRandomNumber, getRandomNumber);
OP (kAppendToSharedStorage, appendToSharedStorage);
OP (kAppendNameToSharedStorage, appendNameToSharedStorage);
OP (kStub176, stub176);
@@ -768,18 +867,24 @@ ProcessExitCode Process::execute() {
OP (kGetObjectPictureWidth, getObjectPictureWidth);
OP (kGetObjectPictureHeight, getObjectPictureHeight);
OP (kLoadPicture, loadPicture);
+ OP (kStub199, stub199);
OP (kSetSampleVolumeAndPan, setSampleVolumeAndPan);
+ OP (kPlaySound, playSound);
+ OP (kStub215, stub215);
+ OP (kStub223, stub223);
OP (kFadeObject, fadeObject);
OP (kLoadFont, loadFont);
OP_U (kStub202ScreenHandler, stub202);
OP (kPlayFilm, playFilm);
OP (kFindObjectInMouseArea, findObjectInMouseArea);
+ OP (kFogOnCharacter, fogOnCharacter);
OP (kStub200, stub200);
OP (kStub206, stub206);
OP_U (kOnKey, onKey);
OP (kGetSampleVolume, getSampleVolume);
OP (kStub235, stub235);
OP (kHasGlobal, hasGlobal);
+ OP (kSetDialogForNextFilm, setDialogForNextFilm);
default:
error("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _ip - 1, (unsigned)op, (unsigned)op);
_status = kStatusError;
Commit: c5d0af1a14a07528d64e37340c65fac1ecf511de
https://github.com/scummvm/scummvm/commit/c5d0af1a14a07528d64e37340c65fac1ecf511de
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:55+01:00
Commit Message:
AGDS: implemented proper fps limiter
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 73ecf4669e0..c7727af022c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -202,6 +202,8 @@ Common::Error AGDSEngine::run() {
_system->fillScreen(0);
while(!shouldQuit()) {
+ uint32 frameStarted = _system->getMillis();
+
if (_timer > 0)
--_timer;
@@ -286,7 +288,13 @@ Common::Error AGDSEngine::run() {
_system->unlockScreen();
_system->updateScreen();
- _system->delayMillis(40);
+
+ static const uint32 kFPS = 25;
+ static const uint32 kMaxTick = 1000 / kFPS;
+
+ uint32 dt = _system->getMillis() - frameStarted;
+ if (dt < kMaxTick)
+ _system->delayMillis(kMaxTick - dt);
}
return Common::kNoError;
Commit: 8117f90d29e6ab97d3d6f475f6a62f78620bd3e8
https://github.com/scummvm/scummvm/commit/8117f90d29e6ab97d3d6f475f6a62f78620bd3e8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:56+01:00
Commit Message:
AGDS: implemented fadeObject
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index fd8618385e2..39e94760b33 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -29,7 +29,7 @@
namespace AGDS {
-Object::Object(const Common::String &name, Common::SeekableReadStream * stream) : _name(name), _stringTableLoaded(false), _picture(), _pos(), _region() {
+Object::Object(const Common::String &name, Common::SeekableReadStream * stream) : _name(name), _stringTableLoaded(false), _picture(), _pos(), _region(), _alpha(255) {
byte id = stream->readByte();
byte flag = stream->readByte();
debug("id: 0x%02x %u, flag: %u", id, id, flag);
@@ -97,8 +97,9 @@ void Object::paint(Graphics::Surface &backbuffer) {
if (_picture) {
Common::Point dst = _pos;
Common::Rect srcRect = _picture->getRect();
+ uint32 color = (_alpha << 24) | 0xffffff; //fixme: _picture->format.ARGBToColor(_alpha, 255, 255, 255); is not working
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
- _picture->blit(backbuffer, _pos.x, _pos.y, Graphics::FLIP_NONE, &srcRect);
+ _picture->blit(backbuffer, _pos.x, _pos.y, Graphics::FLIP_NONE, &srcRect, color);
}
}
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 987b5c8c860..7e0575dd6e1 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -58,6 +58,7 @@ private:
Region * _region;
Common::Point _pos;
uint _clickHandler;
+ int _alpha;
public:
Object(const Common::String &name, Common::SeekableReadStream * stream);
@@ -76,10 +77,14 @@ public:
void setPicture(Graphics::TransparentSurface *);
- const Graphics::TransparentSurface *getPicture() const {
+ Graphics::TransparentSurface *getPicture() const {
return _picture;
}
+ void setAlpha(int alpha) {
+ _alpha = (100 - alpha) * 255 / 100;
+ }
+
void setRegion(Region *region) {
_region = region;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index aa46a2f38bc..bbfb7cea40a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -333,9 +333,10 @@ void Process::loadMouseStub66() {
}
void Process::fadeObject() {
- int arg = pop();
+ int value = pop();
Common::String name = popString();
- debug("fadeObject %s %d", name.c_str(), arg);
+ debug("fadeObject %s %d", name.c_str(), value);
+ _engine->loadObject(name)->setAlpha(value);
}
void Process::stub74() {
Commit: 007ad05b962c0c68ed1867076e652f8e86eeffbb
https://github.com/scummvm/scummvm/commit/007ad05b962c0c68ed1867076e652f8e86eeffbb
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:56+01:00
Commit Message:
AGDS: clip input alpha to 0..100 boundaries
Changed paths:
engines/agds/object.h
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 7e0575dd6e1..52e570b2011 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -82,6 +82,10 @@ public:
}
void setAlpha(int alpha) {
+ if (alpha < 0)
+ alpha = 0;
+ if (alpha > 100)
+ alpha = 100;
_alpha = (100 - alpha) * 255 / 100;
}
Commit: 1f7952101a272afe525a5375f7921385760c0551
https://github.com/scummvm/scummvm/commit/1f7952101a272afe525a5375f7921385760c0551
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:56+01:00
Commit Message:
AGDS: reworked mouse area handling, figured out what op 206 does, removed mouse area clearing hacks
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c7727af022c..5b8ae9add09 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -178,6 +178,9 @@ void AGDSEngine::runProcess() {
case kExitCodeLoadPreviousScreenObject:
loadScreen(_previousScreen);
break;
+ case kExitCodeMouseAreaChange:
+ changeMouseArea(process.getExitIntArg1(), process.getExitIntArg2());
+ break;
case kExitCodeLoadInventoryObject:
loadObject(process.getExitArg1());
break;
@@ -193,6 +196,26 @@ void AGDSEngine::runProcess() {
}
}
+void AGDSEngine::changeMouseArea(int id, int enabled) {
+ MouseRegion * mouseArea = _mouseMap.find(id);
+ if (mouseArea) {
+ switch(enabled) {
+ case 1:
+ mouseArea->enabled = true;
+ break;
+ case 0:
+ if (mouseArea->currentlyIn) {
+ runObject(mouseArea->onLeave);
+ }
+ mouseArea->enabled = false;
+ break;
+ case -1:
+ _mouseMap.remove(id);
+ break;
+ }
+ } else
+ warning("mouse area %d could not be found", id);
+}
Common::Error AGDSEngine::run() {
if (!load())
@@ -213,15 +236,17 @@ Common::Error AGDSEngine::run() {
case Common::EVENT_MOUSEMOVE:
_mouse = event.mouse;
if (_userEnabled && _currentScreen) {
- const MouseRegion *region = _mouseMap.find(_mouse);
- if ((region? region->region: NULL) != _currentRegion) {
+ MouseRegion *region = _mouseMap.find(_mouse);
+ if (region != _currentRegion) {
if (_currentRegion) {
+ MouseRegion *currentRegion = _currentRegion;
_currentRegion = NULL;
- runObject(_onLeaveObject);
+ currentRegion->currentlyIn = false;
+ runObject(currentRegion->onLeave);
}
if (region) {
- _onLeaveObject = region->onLeave;
- _currentRegion = region->region;
+ _currentRegion = region;
+ _currentRegion->currentlyIn = true;
runObject(region->onEnter);
}
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 91ce7e24527..aa79d0a137e 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -51,6 +51,7 @@ namespace AGDS {
class Object;
class Process;
struct Region;
+struct MouseRegion;
class MJPGPlayer;
class Screen;
class SystemVariable;
@@ -110,6 +111,7 @@ private:
Graphics::TransparentSurface *convertToTransparent(const Graphics::Surface *surface); //destroys surface!
void loadCursor(const Common::String &name, unsigned index = 0);
+ void changeMouseArea(int id, int enabled);
void enableUser(bool enabled) {
_userEnabled = enabled;
}
@@ -143,8 +145,7 @@ private:
Common::String _previousScreen;
Video::FlicDecoder * _mouseCursor;
Common::Point _mouse;
- Region * _currentRegion;
- Common::String _onLeaveObject;
+ MouseRegion * _currentRegion;
bool _userEnabled;
MouseMap _mouseMap;
Common::RandomSource _random;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 3b1d09ae008..d4fe1334aef 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -222,8 +222,8 @@ enum Opcode {
kStub202ScreenHandler = 202,
kPlayFilm = 203,
kStub204 = 204,
- kFindObjectInMouseArea = 205,
- kStub206 = 206,
+ kAddMouseArea = 205,
+ kModifyMouseArea = 206,
kStub207 = 207,
kFogOnCharacter = 208,
kStub209 = 209,
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 3a87d950991..d19e6cc5f7e 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -76,12 +76,6 @@ Common::String Process::popFilename() {
return _engine->loadFilename(popString());
}
-void Process::suspendProcess(ProcessExitCode code) {
- debug("suspendProcess");
- _status = kStatusPassive;
- _exitCode = code;
-}
-
void Process::activate() {
switch(_status)
{
diff --git a/engines/agds/process.h b/engines/agds/process.h
index ca8f375d823..f79c1dc3f76 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -46,6 +46,7 @@ private:
Status _status;
ProcessExitCode _exitCode;
Common::String _exitArg1, _exitArg2;
+ int _exitIntArg1, _exitIntArg2;
int _glyphWidth, _glyphHeight;
private:
@@ -92,7 +93,6 @@ private:
void enter(uint16 magic, uint16 size);
void exitProcess();
void exitProcessCreatePatch();
- void suspendProcess(ProcessExitCode code = kExitCodeSuspend);
void exitScreen();
void exitProcessSetNextScreen();
void exitProcessSetNextScreen80();
@@ -113,7 +113,7 @@ private:
void changeScreenPatch();
void setScreenHeight();
void updateScreenHeightToDisplay();
- void findObjectInMouseArea();
+ void addMouseArea();
void loadRegionFromObject();
void generateRegion();
void loadPictureFromObject();
@@ -198,7 +198,7 @@ private:
void stub202(unsigned size);
void playFilm();
void stub200();
- void stub206();
+ void modifyMouseArea();
void stub215();
void stub223();
void stub235();
@@ -228,14 +228,26 @@ private:
#undef UNARY_OP
#undef BINARY_OP
- void suspend(ProcessExitCode exitCode = kExitCodeSuspend, const Common::String &arg1 = Common::String(), const Common::String &arg2 = Common::String()) {
+ void suspend(ProcessExitCode exitCode, const Common::String &arg1, const Common::String &arg2 = Common::String()) {
if (_status == kStatusActive)
_status = kStatusPassive;
_exitCode = exitCode;
+ _exitIntArg1 = 0;
+ _exitIntArg2 = 0;
_exitArg1 = arg1;
_exitArg2 = arg2;
}
+ void suspend(ProcessExitCode exitCode = kExitCodeSuspend, int arg1 = 0, int arg2 = 0) {
+ if (_status == kStatusActive)
+ _status = kStatusPassive;
+ _exitCode = exitCode;
+ _exitIntArg1 = arg1;
+ _exitIntArg2 = arg2;
+ _exitArg1.clear();
+ _exitArg2.clear();
+ }
+
public:
Process(AGDSEngine *engine, Object *object, unsigned ip = 0);
@@ -259,9 +271,18 @@ public:
return _exitArg1;
}
+ int getExitIntArg1() const {
+ return _exitIntArg1;
+ }
+
const Common::String & getExitArg2() const {
return _exitArg2;
}
+
+ int getExitIntArg2() const {
+ return _exitIntArg2;
+ }
+
};
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index 02d787b3e03..c6c7caa893d 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -31,6 +31,7 @@ namespace AGDS {
kExitCodeDestroyProcessSetNextScreen = 6,
kExitCodeLoadScreenObject = 8,
kExitCodeLoadInventoryObject = 10,
+ kExitCodeMouseAreaChange = 11,
kExitCodeExitScreen = 15,
kExitCodeLoadPreviousScreenObject = 99
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index bbfb7cea40a..061ed34d297 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -467,10 +467,11 @@ void Process::stub202(unsigned size) {
_ip += size;
}
-void Process::stub206() {
- int arg2 = pop();
- int arg1 = pop();
- debug("stub206 (mouse?) %d %d", arg1, arg2);
+void Process::modifyMouseArea() {
+ int enabled = pop();
+ int id = pop();
+ debug("modifyMouseArea %d, %d", id, enabled);
+ suspend(kExitCodeMouseAreaChange, id, enabled);
}
void Process::stub215() {
@@ -603,13 +604,11 @@ void Process::exitProcessSetNextScreen() {
void Process::exitProcessSetNextScreen80() {
Common::String name = popString();
debug("exitProcessSetNextScreen80(code 7) %s", name.c_str());
- _engine->_mouseMap.clear();
suspend(kExitCodeDestroyProcessSetNextScreen, name);
}
void Process::loadPreviousScreen() {
debug("loadPreviousScreen");
- _engine->_mouseMap.clear();
suspend(kExitCodeLoadPreviousScreenObject);
}
@@ -671,16 +670,17 @@ void Process::enableUser() {
_engine->enableUser(true);
}
-void Process::findObjectInMouseArea() {
+void Process::addMouseArea() {
Common::String arg3 = popString();
Common::String arg2 = popString();
Common::String arg1 = popString();
debug("findObjectInMouseArea (region: %s) %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
Region *region = _engine->loadRegion(arg1);
- push(205);
- _engine->_mouseMap.add(MouseRegion(region, arg2, arg3));
+ int value = _engine->_mouseMap.add(MouseRegion(region, arg2, arg3));
+ debug("\tmouse area id -> %d", value);
+ push(value);
}
void Process::fogOnCharacter() {
@@ -761,7 +761,7 @@ ProcessExitCode Process::execute() {
OP (kPop, pop);
OP (kDup, dup);
OP (kExitProcess, exitProcess);
- OP (kSuspendProcess, suspendProcess);
+ OP (kSuspendProcess, suspend);
OP_D (kPushImm32, push);
OP_C (kPushImm8, push);
OP_W (kPushImm16, push);
@@ -877,10 +877,10 @@ ProcessExitCode Process::execute() {
OP (kLoadFont, loadFont);
OP_U (kStub202ScreenHandler, stub202);
OP (kPlayFilm, playFilm);
- OP (kFindObjectInMouseArea, findObjectInMouseArea);
+ OP (kAddMouseArea, addMouseArea);
OP (kFogOnCharacter, fogOnCharacter);
OP (kStub200, stub200);
- OP (kStub206, stub206);
+ OP (kModifyMouseArea, modifyMouseArea);
OP_U (kOnKey, onKey);
OP (kGetSampleVolume, getSampleVolume);
OP (kStub235, stub235);
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 9b025f43b25..1854ae5fb2b 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -65,16 +65,35 @@ Object *Screen::find(Common::Point pos) const {
return NULL;
}
-const MouseRegion * MouseMap::find(Common::Point pos) const {
- for(MouseRegionsType::const_iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i) {
- const MouseRegion &mouse = *i;
- if (mouse.region->pointIn(pos))
+MouseRegion * MouseMap::find(Common::Point pos) {
+ for(MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i) {
+ MouseRegion &mouse = *i;
+ if (mouse.enabled && mouse.region->pointIn(pos))
return &mouse;
}
return NULL;
+}
+
+MouseRegion * MouseMap::find(int id) {
+ for(MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i) {
+ MouseRegion &mouse = *i;
+ if (mouse.id == id)
+ return &mouse;
+ }
+ return NULL;
+}
+void MouseMap::remove(int id) {
+ for(MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ) {
+ MouseRegion &mouse = *i;
+ if (mouse.id == id)
+ i = _mouseRegions.erase(i);
+ else
+ ++i;
+ }
}
+
}
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 30525fbacc0..b281496e302 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -38,13 +38,16 @@ class Object;
struct Region;
struct MouseRegion {
+ int id;
Region *region;
+ bool enabled;
+ bool currentlyIn;
Common::String onEnter;
Common::String onLeave;
- MouseRegion(): region() { }
+ MouseRegion(): id(-1), enabled(false), currentlyIn(false), region() { }
MouseRegion(Region * reg, const Common::String &enter, const Common::String &leave):
- region(reg), onEnter(enter), onLeave(leave) {
+ id(-1), region(reg), enabled(true), currentlyIn(false), onEnter(enter), onLeave(leave) {
}
};
@@ -52,15 +55,22 @@ struct MouseRegion {
class MouseMap {
typedef Common::List<MouseRegion> MouseRegionsType;
MouseRegionsType _mouseRegions;
+ int _nextId;
public:
- void add(const MouseRegion & area) {
+ MouseMap(): _nextId(1) { }
+
+ int add(const MouseRegion & area) {
_mouseRegions.push_back(area);
+ _mouseRegions.back().id = _nextId++;
+ return _mouseRegions.back().id;
}
- void clear() {
- _mouseRegions.clear();
- }
- const MouseRegion * find(Common::Point pos) const;
+// void clear() {
+// _mouseRegions.clear();
+// }
+ MouseRegion * find(Common::Point pos);
+ MouseRegion * find(int id);
+ void remove(int id);
};
class Screen {
Commit: dce6d14e422190bcaa8b8d0b1f066a5c62432e6b
https://github.com/scummvm/scummvm/commit/dce6d14e422190bcaa8b8d0b1f066a5c62432e6b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:56+01:00
Commit Message:
AGDS: added logs from jump instructions
Changed paths:
engines/agds/process.h
diff --git a/engines/agds/process.h b/engines/agds/process.h
index f79c1dc3f76..a632d9a79c2 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -75,11 +75,12 @@ private:
}
void jump(int delta)
- { _ip += delta; }
+ { debug("jump %+d", delta); _ip += delta; }
void jumpz(int delta)
{
int value = pop();
+ debug("jumpz %d %+d", value, delta);
if (value == 0)
jump(delta);
}
Commit: 3a3140470dc7c3b431871519a605fef9e0484803
https://github.com/scummvm/scummvm/commit/3a3140470dc7c3b431871519a605fef9e0484803
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:56+01:00
Commit Message:
AGDS: renamed resetGlobal to resetPhaseVar
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index d4fe1334aef..7fca22699ba 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -152,7 +152,7 @@ enum Opcode {
kStub132 = 132,
kStub133 = 133,
kStub134 = 134,
- kResetGlobal = 135,
+ kResetPhaseVar = 135,
kStub136 = 136,
kStub137 = 137,
kStub138 = 138,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index a632d9a79c2..5a4dab9d13c 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -149,7 +149,7 @@ private:
void setIntegerSystemVariable();
void getGlobal(unsigned index);
void setGlobal();
- void resetGlobal();
+ void resetPhaseVar();
void hasGlobal();
void postIncrementGlobal();
void postDecrementGlobal();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 061ed34d297..8924b713036 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -140,7 +140,7 @@ void Process::playSound() {
void Process::updateSampleVarOr2() {
Common::String name = popString();
- debug("updateSampleVarOr4 stub %s", name.c_str());
+ debug("updateSampleVarOr2 stub %s", name.c_str());
int value = _engine->getGlobal(name);
_engine->setGlobal(name, value | 2);
}
@@ -205,10 +205,10 @@ void Process::setGlobal() {
_engine->setGlobal(name, value);
}
-void Process::resetGlobal() {
+void Process::resetPhaseVar() {
Common::String name = popString();
_engine->setGlobal(name, 0);
- debug("resetGlobal %s", name.c_str());
+ debug("resetPhaseVar %s", name.c_str());
}
void Process::getGlobal(unsigned index) {
@@ -830,7 +830,7 @@ ProcessExitCode Process::execute() {
OP (kStub130, stub130);
OP (kStub133, stub133);
OP (kStub134, stub134);
- OP (kResetGlobal, resetGlobal);
+ OP (kResetPhaseVar, resetPhaseVar);
OP (kStub136, stub136);
OP (kScreenChangeScreenPatch, changeScreenPatch);
OP (kSetStringSystemVariable, setStringSystemVariable);
Commit: 47cb65f9f3d586a522a3100b700c73dec017ed5c
https://github.com/scummvm/scummvm/commit/47cb65f9f3d586a522a3100b700c73dec017ed5c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:56+01:00
Commit Message:
AGDS: renamed phase var opcodes, store current phase var
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 7fca22699ba..1e9f1bbf97d 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -117,8 +117,8 @@ enum Opcode {
kStub97 = 97,
kDisableUser = 98,
kEnableUser = 99,
- kUpdateSampleVarOr2 = 100,
- kUpdateSampleVarOr4 = 101,
+ kUpdatePhaseVarOr2 = 100,
+ kUpdatePhaseVarOr4 = 101,
kStub102 = 102,
kStub103 = 103,
kStub104 = 104,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 5a4dab9d13c..5d6eaf75de2 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -48,6 +48,7 @@ private:
Common::String _exitArg1, _exitArg2;
int _exitIntArg1, _exitIntArg2;
int _glyphWidth, _glyphHeight;
+ Common::String _phaseVar;
private:
uint8 next() {
@@ -125,8 +126,8 @@ private:
void playSound();
void getSampleVolume();
void setSampleVolumeAndPan();
- void updateSampleVarOr2();
- void updateSampleVarOr4();
+ void updatePhaseVarOr2();
+ void updatePhaseVarOr4();
void cloneObject();
void setTimer();
void getRegionCenterX();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 8924b713036..52e32f01758 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -138,16 +138,16 @@ void Process::playSound() {
debug("playSound %s %d", name.c_str(), arg);
}
-void Process::updateSampleVarOr2() {
+void Process::updatePhaseVarOr2() {
Common::String name = popString();
- debug("updateSampleVarOr2 stub %s", name.c_str());
+ debug("updatePhaseVarOr2 stub %s", name.c_str());
int value = _engine->getGlobal(name);
_engine->setGlobal(name, value | 2);
}
-void Process::updateSampleVarOr4() {
+void Process::updatePhaseVarOr4() {
Common::String name = popString();
- debug("updateSampleVarOr4 stub %s", name.c_str());
+ debug("updatePhaseVarOr4 stub %s", name.c_str());
int value = _engine->getGlobal(name);
_engine->setGlobal(name, value | 4);
}
@@ -208,6 +208,7 @@ void Process::setGlobal() {
void Process::resetPhaseVar() {
Common::String name = popString();
_engine->setGlobal(name, 0);
+ _phaseVar = name;
debug("resetPhaseVar %s", name.c_str());
}
@@ -357,6 +358,7 @@ void Process::stub119() {
void Process::stub128() {
debug("processCleanupStub128");
+ _phaseVar.clear();
}
void Process::stub129() {
@@ -802,8 +804,8 @@ ProcessExitCode Process::execute() {
OP (kLoadAnimationFromObject, loadAnimationFromObject);
OP (kDisableUser, disableUser);
OP (kEnableUser, enableUser);
- OP (kUpdateSampleVarOr2, updateSampleVarOr2);
- OP (kUpdateSampleVarOr4, updateSampleVarOr4);
+ OP (kUpdatePhaseVarOr2, updatePhaseVarOr2);
+ OP (kUpdatePhaseVarOr4, updatePhaseVarOr4);
OP (kClearScreen, clearScreen);
OP (kInventoryClear, inventoryClear);
OP (kLoadMouse, loadMouse);
Commit: 0c8d094d1c90ced0e8f4606eaf80adcad2ee4fe9
https://github.com/scummvm/scummvm/commit/0c8d094d1c90ced0e8f4606eaf80adcad2ee4fe9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:56+01:00
Commit Message:
AGDS: added SoundManager class
Changed paths:
A engines/agds/soundManager.cpp
A engines/agds/soundManager.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/module.mk
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 5b8ae9add09..14aa40e1861 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -38,11 +38,11 @@
namespace AGDS {
-AGDSEngine::AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst),
+AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Engine(system),
_gameDescription(gameDesc), _sharedStorageIndex(-2), _timer(0),
_mjpgPlayer(NULL), _currentScreen(NULL), _mouseCursor(NULL),
_mouse(400, 300), _userEnabled(false), _currentRegion(NULL),
- _random("agds") {
+ _random("agds"), _soundManager(this, system->getMixer()) {
}
AGDSEngine::~AGDSEngine() {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index aa79d0a137e..c1165d2a53f 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -28,6 +28,7 @@
#include "common/random.h"
#include "common/rect.h"
#include "engines/advancedDetector.h"
+#include "agds/soundManager.h"
#include "agds/database.h"
#include "agds/processExitCode.h"
#include "agds/resourceManager.h"
@@ -129,6 +130,7 @@ private:
const ADGameDescription * _gameDescription;
ResourceManager _resourceManager;
+ SoundManager _soundManager;
Database _data, _patch; //data and patch databases
ObjectsType _objects;
ScreensType _screens;
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index 3ee497fd130..29f1d846d89 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -10,8 +10,9 @@ MODULE_OBJS := \
process_opcodes.o \
region.o \
resourceManager.o \
- systemVariable.o \
- screen.o
+ screen.o \
+ soundManager.o \
+ systemVariable.o
# This module can be built as a plugin
ifeq ($(ENABLE_AGDS), DYNAMIC_PLUGIN)
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 52e32f01758..f0d303d4d6e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -117,6 +117,12 @@ void Process::loadAnimation() {
void Process::loadSample() {
Common::String name = popFilename();
debug("loadSample %s", name.c_str());
+ if (_phaseVar.empty()) {
+ warning("playing sample %s without phase var", _phaseVar.c_str());
+ return;
+ }
+ Common::SeekableReadStream *res = _engine->_resourceManager.getResource(name);
+ _engine->_soundManager.play(res, _phaseVar);
}
void Process::getSampleVolume() {
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
new file mode 100644
index 00000000000..64ffea4a4f4
--- /dev/null
+++ b/engines/agds/soundManager.cpp
@@ -0,0 +1,36 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/soundManager.h"
+#include "common/debug.h"
+#include "common/textconsole.h"
+#include "audio/audiostream.h"
+
+namespace AGDS {
+
+ void SoundManager::tick() {
+ }
+
+ void SoundManager::play(Common::SeekableReadStream *stream, const Common::String &phaseVar) {
+ }
+
+}
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
new file mode 100644
index 00000000000..16e50114651
--- /dev/null
+++ b/engines/agds/soundManager.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_SOUND_MANAGER_H
+#define AGDS_SOUND_MANAGER_H
+
+#include "common/scummsys.h"
+#include "common/str.h"
+#include "audio/mixer.h"
+
+namespace Common { class SeekableReadStream; }
+namespace Audio { class Mixer; }
+
+namespace AGDS {
+ class AGDSEngine;
+
+ class Sound {
+ Common::String name;
+ Common::String phaseVar;
+ Audio::SoundHandle handle;
+ };
+
+ class SoundManager {
+ AGDSEngine * _engine;
+ Audio::Mixer * _mixer;
+
+ public:
+ SoundManager(AGDSEngine *engine, Audio::Mixer *mixer): _engine(engine), _mixer(mixer) { }
+ void tick();
+ void play(Common::SeekableReadStream *stream, const Common::String &phaseVar);
+ };
+
+} // End of namespace AGDS
+
+#endif /* AGDS_SOUND_MANAGER_H */
Commit: ca88990e7c07b1de1961e3a606d85546a6e53f73
https://github.com/scummvm/scummvm/commit/ca88990e7c07b1de1961e3a606d85546a6e53f73
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:56+01:00
Commit Message:
AGDS: ported resource loading to scummvm's Archive/File
Changed paths:
engines/agds/agds.cpp
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 14aa40e1861..69703870ef4 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -357,8 +357,11 @@ int AGDSEngine::getGlobal(const Common::String &name) const {
}
void AGDSEngine::loadCursor(const Common::String &name, unsigned index) {
+ Common::SeekableReadStream *stream = _resourceManager.getResource(name);
+ if (!stream)
+ error("could not load cursor from %s", name.c_str());
Video::FlicDecoder * cursor = new Video::FlicDecoder;
- if (cursor->loadStream(_resourceManager.getResource(name))) {
+ if (cursor->loadStream(stream)) {
delete _mouseCursor;
_mouseCursor = cursor;
} else
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 498d34c5484..b728e2f8c2a 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -47,42 +47,45 @@ namespace AGDS {
}
}
- bool ResourceManager::addPath(const Common::String &grpFilename) {
+ bool ResourceManager::GrpFile::load(const Common::String &grpFilename) {
static const char * kSignature = "AGDS group file\x1a";
static const uint32 kMagic = 0x1a03c9e6;
static const uint32 kVersion1 = 44;
static const uint32 kVersion2 = 2;
debug("adding path %s", grpFilename.c_str());
- Common::File grp;
- if (!grp.open(grpFilename)) {
- error("failing opening grp file %s", grpFilename.c_str());
+ if (!_file.open(grpFilename)) {
+ warning("failing opening grp file %s", grpFilename.c_str());
return false;
}
uint8 header[0x2c];
- if (grp.read(header, sizeof(header)) != sizeof(header))
+ if (_file.read(header, sizeof(header)) != sizeof(header)) {
+ warning("short read from header");
return false;
+ }
decrypt(header, 0x10);
- if (strncmp(reinterpret_cast<const char*>(header), kSignature, 0x10) != 0)
+ if (strncmp(reinterpret_cast<const char*>(header), kSignature, 0x10) != 0) {
+ warning("invalid signature");
return false;
+ }
Common::MemoryReadStreamEndian reader(header + 0x10, sizeof(header) - 0x10, false);
uint32 version1 = reader.readUint32();
if (version1 != kVersion1) {
- error("invalid version 1 (%d)", version1);
+ warning("invalid version 1 (%d)", version1);
return false;
}
uint32 magic = reader.readUint32();
if (magic != kMagic) {
- error("invalid magic (0x%08x)", magic);
+ warning("invalid magic (0x%08x)", magic);
return false;
}
uint32 version2 = reader.readUint32();
if (version2 != kVersion2) {
- error("invalid version 2 (%d)", version2);
+ warning("invalid version 2 (%d)", version2);
return false;
}
@@ -90,21 +93,19 @@ namespace AGDS {
if (!reader.skip(3 * 4))
return false;
- GrpFilePtr grpFile(new GrpFile(grpFilename));
-
- debug("+%u files in index", dirCount);
+ //debug("+%u files in index", dirCount);
while(dirCount--) {
uint8 dirData[0x31];
uint8 * dirDataEnd = dirData + sizeof(dirData);
- if (grp.read(dirData, sizeof(dirData)) != sizeof(dirData)) {
- error("short read, corrupted file");
+ if (_file.read(dirData, sizeof(dirData)) != sizeof(dirData)) {
+ warning("short read, corrupted file");
return false;
}
uint8 *nameEnd = Common::find(dirData, dirDataEnd, 0);
if (nameEnd == dirDataEnd) {
- error("corrupted entry at %d", (int)grp.pos() - 0x31);
+ warning("corrupted entry at %d", (int)_file.pos() - 0x31);
continue;
}
@@ -117,34 +118,55 @@ namespace AGDS {
uint32 offset = dirReader.readSint32();
uint32 size = dirReader.readSint32();
//debug("\t\tfile %s %u %u", name.c_str(), offset, size);
- ResourcePtr resource(new Resource(grpFile, offset, size));
- _resources.setVal(name, resource);
+ ArchiveMemberPtr resource(new ArchiveMember(this, name, offset, size));
+ _members.setVal(name, resource);
}
- debug("\t%u files in index", _resources.size());
+ debug("%s: %u files in index", grpFilename.c_str(), _members.size());
return true;
}
- Common::SeekableReadStream * ResourceManager::getResource(const Common::String &name) const
- {
- ResourcesType::const_iterator i = _resources.find(name);
- if (i == _resources.end()) {
- error("no resource %s could be found", name.c_str());
- return NULL;
- }
+ int ResourceManager::GrpFile::listMembers(Common::ArchiveMemberList &list) const {
+ int size = 0;
+ for(MembersType::const_iterator i = _members.begin(); i != _members.end(); ++i, ++size)
+ list.push_back(i->_value);
+ return size;
+ }
- const ResourcePtr & resource = i->_value;
- assert(resource);
+ const Common::ArchiveMemberPtr ResourceManager::GrpFile::getMember(const Common::String &name) const {
+ Common::ArchiveMemberPtr member;
+ MembersType::const_iterator i = _members.find(name);
+ if (i != _members.end())
+ member = i->_value;
+ return member;
+ }
- const Common::String & filename = resource->grp->filename;
- Common::File grp;
- if (!grp.open(filename)) {
- error("could not open group file %s", filename.c_str());
- return NULL;
+ Common::SeekableReadStream *ResourceManager::GrpFile::createReadStreamForMember(const Common::String &name) const {
+ Common::ArchiveMemberPtr member = getMember(name);
+ return member? member->createReadStream(): NULL;
+ }
+
+
+ bool ResourceManager::addPath(const Common::String &grpFilename) {
+ GrpFile * grpFile = new GrpFile();
+ if (!grpFile->load(grpFilename)) {
+ delete grpFile;
+ return false;
}
- grp.seek(resource->offset);
- return grp.readStream(resource->size);
+ SearchMan.add(grpFilename, grpFile, 0, true);
+ return true;
+ }
+
+ Common::SeekableReadStream * ResourceManager::ArchiveMember::createReadStream() const {
+ Common::SeekableReadStream &file = _parent->getArchiveStream();
+ file.seek(_offset);
+ return file.readStream(_size);
+ }
+
+ Common::SeekableReadStream * ResourceManager::getResource(const Common::String &name) const {
+ Common::File file;
+ return (file.open(name))? file.readStream(file.size()): NULL;
}
const Graphics::Surface * ResourceManager::loadPicture(const Common::String & name, const Graphics::PixelFormat &format) {
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 6af50512276..86574cddf79 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -24,8 +24,9 @@
#define AGDS_RESOURCE_MANAGER_H
#include "common/scummsys.h"
+#include "common/archive.h"
+#include "common/file.h"
#include "common/str.h"
-#include "common/stream.h"
#include "common/ptr.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
@@ -37,29 +38,46 @@ namespace AGDS {
class ResourceManager {
private:
- //fixme: port to Archive
- struct GrpFile
+ class GrpFile;
+ class ArchiveMember : public Common::ArchiveMember
{
- Common::String filename;
-
- GrpFile(const Common::String &fname): filename(fname) {
+ GrpFile * _parent;
+ Common::String _name;
+ uint32 _offset;
+ uint32 _size;
+
+ public:
+ ArchiveMember(GrpFile * parent, const Common::String &name, uint32 offset, uint32 size):
+ _parent(parent), _name(name), _offset(offset), _size(size) {
+ }
+ virtual Common::SeekableReadStream *createReadStream() const;
+ virtual Common::String getName() const {
+ return _name;
}
};
- typedef Common::SharedPtr<GrpFile> GrpFilePtr;
+ typedef Common::SharedPtr<ArchiveMember> ArchiveMemberPtr;
- struct Resource
+ class GrpFile : public Common::Archive
{
- GrpFilePtr grp;
- uint32 offset;
- uint32 size;
- Resource(const GrpFilePtr &g, uint32 o, uint32 s):
- grp(g), offset(o), size(s) {
+ Common::File _file;
+
+ typedef Common::HashMap<Common::String, ArchiveMemberPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> MembersType;
+ MembersType _members;
+
+ public:
+ bool load(const Common::String &fname);
+
+ Common::SeekableReadStream &getArchiveStream() {
+ return _file;
}
- };
- typedef Common::SharedPtr<Resource> ResourcePtr;
- typedef Common::HashMap<Common::String, ResourcePtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ResourcesType;
- ResourcesType _resources;
+ virtual bool hasFile(const Common::String &name) const
+ { return _members.find(name) != _members.end(); }
+
+ virtual int listMembers(Common::ArchiveMemberList &list) const;
+ virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
+ virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
+ };
public:
ResourceManager();
Commit: 6b4c0f9954c9a762c2aa71b12fc78491e54f66c3
https://github.com/scummvm/scummvm/commit/6b4c0f9954c9a762c2aa71b12fc78491e54f66c3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:56+01:00
Commit Message:
AGDS: implemented playSound (only scummvm part)
Changed paths:
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f0d303d4d6e..40bd1527154 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -121,8 +121,7 @@ void Process::loadSample() {
warning("playing sample %s without phase var", _phaseVar.c_str());
return;
}
- Common::SeekableReadStream *res = _engine->_resourceManager.getResource(name);
- _engine->_soundManager.play(res, _phaseVar);
+ _engine->_soundManager.play(name, _phaseVar);
}
void Process::getSampleVolume() {
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 64ffea4a4f4..fb4a6d70e35 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -22,15 +22,38 @@
#include "agds/soundManager.h"
#include "common/debug.h"
+#include "common/file.h"
#include "common/textconsole.h"
#include "audio/audiostream.h"
+#include "audio/decoders/vorbis.h"
+#include "audio/decoders/wave.h"
namespace AGDS {
void SoundManager::tick() {
}
- void SoundManager::play(Common::SeekableReadStream *stream, const Common::String &phaseVar) {
+ void SoundManager::play(const Common::String &filename, const Common::String &phaseVar) {
+ Common::File *sound = new Common::File();
+ if (!sound->open(filename))
+ error("no sound %s", filename.c_str());
+
+ Common::String lname(filename);
+ lname.toLowercase();
+
+ Audio::SeekableAudioStream *stream = NULL;
+ if (lname.hasSuffix(".ogg")) {
+ stream = Audio::makeVorbisStream(sound, DisposeAfterUse::YES);
+ } else if (lname.hasSuffix(".wav")) {
+ stream = Audio::makeWAVStream(sound, DisposeAfterUse::YES);
+ }
+ if (!stream) {
+ warning("could not play sound %s", filename.c_str());
+ delete sound;
+ return;
+ }
+ Audio::SoundHandle handle;
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, stream);
}
}
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index 16e50114651..720b8420022 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -46,7 +46,7 @@ namespace AGDS {
public:
SoundManager(AGDSEngine *engine, Audio::Mixer *mixer): _engine(engine), _mixer(mixer) { }
void tick();
- void play(Common::SeekableReadStream *stream, const Common::String &phaseVar);
+ void play(const Common::String &file, const Common::String &phaseVar);
};
} // End of namespace AGDS
Commit: 7a11b0fe26664d4b6a6715121397e18b0aeb25bb
https://github.com/scummvm/scummvm/commit/7a11b0fe26664d4b6a6715121397e18b0aeb25bb
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:56+01:00
Commit Message:
AGDS: implemented sound list, reset phase var to zero for now
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 69703870ef4..bec297fff5e 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -271,6 +271,7 @@ Common::Error AGDSEngine::run() {
}
}
+ _soundManager.tick();
if (active())
runProcess();
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index c1165d2a53f..534ae23168c 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -66,6 +66,14 @@ public:
Common::Error run();
+ void setGlobal(const Common::String &name, int value) {
+ _globals.setVal(name, value);
+ }
+ bool hasGlobal(const Common::String &name) const {
+ return _globals.find(name) != _globals.end();
+ }
+ int getGlobal(const Common::String &name) const;
+
private:
bool initGraphics();
bool load();
@@ -85,14 +93,6 @@ private:
int appendToSharedStorage(const Common::String &value);
const Common::String & getSharedStorage(int id) const;
- void setGlobal(const Common::String &name, int value) {
- _globals.setVal(name, value);
- }
- bool hasGlobal(const Common::String &name) const {
- return _globals.find(name) != _globals.end();
- }
- int getGlobal(const Common::String &name) const;
-
void setTimer(int timer) {
_timer = timer;
}
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index fb4a6d70e35..2b20a44e0e5 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -21,6 +21,7 @@
*/
#include "agds/soundManager.h"
+#include "agds/agds.h"
#include "common/debug.h"
#include "common/file.h"
#include "common/textconsole.h"
@@ -31,29 +32,38 @@
namespace AGDS {
void SoundManager::tick() {
+ for(SoundList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) {
+ Sound & sound = *i;
+ int state = _engine->getGlobal(sound.phaseVar);
+ state = 0;
+ _mixer->isSoundHandleActive(sound.handle);
+ _engine->setGlobal(sound.phaseVar, state);
+ }
}
- void SoundManager::play(const Common::String &filename, const Common::String &phaseVar) {
- Common::File *sound = new Common::File();
- if (!sound->open(filename))
- error("no sound %s", filename.c_str());
+ void SoundManager::play(const Common::String &resource, const Common::String &phaseVar) {
+ Common::File *file = new Common::File();
+ if (!file->open(resource))
+ error("no sound %s", resource.c_str());
- Common::String lname(filename);
+ Common::String lname(resource);
lname.toLowercase();
Audio::SeekableAudioStream *stream = NULL;
if (lname.hasSuffix(".ogg")) {
- stream = Audio::makeVorbisStream(sound, DisposeAfterUse::YES);
+ stream = Audio::makeVorbisStream(file, DisposeAfterUse::YES);
} else if (lname.hasSuffix(".wav")) {
- stream = Audio::makeWAVStream(sound, DisposeAfterUse::YES);
+ stream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
}
if (!stream) {
- warning("could not play sound %s", filename.c_str());
- delete sound;
+ warning("could not play sound %s", resource.c_str());
+ delete file;
return;
}
Audio::SoundHandle handle;
_mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, stream);
+
+ _sounds.push_back(Sound(resource, phaseVar, handle));
}
}
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index 720b8420022..c74354dea30 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -25,6 +25,8 @@
#include "common/scummsys.h"
#include "common/str.h"
+#include "common/list.h"
+#include "common/hashmap.h"
#include "audio/mixer.h"
namespace Common { class SeekableReadStream; }
@@ -33,15 +35,21 @@ namespace Audio { class Mixer; }
namespace AGDS {
class AGDSEngine;
- class Sound {
- Common::String name;
- Common::String phaseVar;
- Audio::SoundHandle handle;
+ struct Sound {
+ Common::String name;
+ Common::String phaseVar;
+ Audio::SoundHandle handle;
+ int group;
+ Sound(const Common::String & res, const Common::String & var, Audio::SoundHandle h, int g = 0):
+ name(res), phaseVar(var), handle(h), group(g) {
+ }
};
class SoundManager {
+ typedef Common::List<Sound> SoundList;
AGDSEngine * _engine;
Audio::Mixer * _mixer;
+ SoundList _sounds;
public:
SoundManager(AGDSEngine *engine, Audio::Mixer *mixer): _engine(engine), _mixer(mixer) { }
Commit: 8e00b9f3a7ceb2ead7681a692b98a149b778a78a
https://github.com/scummvm/scummvm/commit/8e00b9f3a7ceb2ead7681a692b98a149b778a78a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:57+01:00
Commit Message:
AGDS: removed useless fillScreen(0) in run()
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index bec297fff5e..a4070b9ccb7 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -222,7 +222,6 @@ Common::Error AGDSEngine::run() {
return Common::kNoGameDataFoundError;
Common::EventManager *eventManager = _system->getEventManager();
- _system->fillScreen(0);
while(!shouldQuit()) {
uint32 frameStarted = _system->getMillis();
Commit: 7c921190f70d5319b13dd7592875f428f81250bc
https://github.com/scummvm/scummvm/commit/7c921190f70d5319b13dd7592875f428f81250bc
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:57+01:00
Commit Message:
AGDS: improved process suspend logging
Changed paths:
engines/agds/agds.cpp
engines/agds/process.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index a4070b9ccb7..96e6ccd8f92 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -185,7 +185,6 @@ void AGDSEngine::runProcess() {
loadObject(process.getExitArg1());
break;
case kExitCodeSuspend:
- debug("process %s suspended", name.c_str());
return;
default:
debug("destroying process %s...", name.c_str());
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 5d6eaf75de2..fd19de455b2 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -81,9 +81,10 @@ private:
void jumpz(int delta)
{
int value = pop();
- debug("jumpz %d %+d", value, delta);
- if (value == 0)
- jump(delta);
+ if (value == 0) {
+ debug("jumpz %d %+d", value, delta);
+ _ip += delta;
+ }
}
Common::String getString(int id);
@@ -231,6 +232,7 @@ private:
#undef BINARY_OP
void suspend(ProcessExitCode exitCode, const Common::String &arg1, const Common::String &arg2 = Common::String()) {
+ debug("suspend %d", exitCode);
if (_status == kStatusActive)
_status = kStatusPassive;
_exitCode = exitCode;
@@ -241,6 +243,7 @@ private:
}
void suspend(ProcessExitCode exitCode = kExitCodeSuspend, int arg1 = 0, int arg2 = 0) {
+ debug("suspend %d", exitCode);
if (_status == kStatusActive)
_status = kStatusPassive;
_exitCode = exitCode;
Commit: 18a1b63f6c1f980cc55d3791c1f4e8ea89bc6a60
https://github.com/scummvm/scummvm/commit/18a1b63f6c1f980cc55d3791c1f4e8ea89bc6a60
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:57+01:00
Commit Message:
AGDS: process all processes in one tick
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 96e6ccd8f92..f2d8f1706ec 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -191,7 +191,6 @@ void AGDSEngine::runProcess() {
p = _processes.erase(p);
continue;
}
- break;
}
}
Commit: a840773ffd9af4cb440b085b0d8f94f2fc44ef56
https://github.com/scummvm/scummvm/commit/a840773ffd9af4cb440b085b0d8f94f2fc44ef56
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:57+01:00
Commit Message:
AGDS: renamed loadFilename to loadText
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index f2d8f1706ec..cb57d8eb62d 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -114,7 +114,7 @@ Region * AGDSEngine::loadRegion(const Common::String &name) {
return region;
}
-Common::String AGDSEngine::loadFilename(const Common::String &entryName) {
+Common::String AGDSEngine::loadText(const Common::String &entryName) {
return ResourceManager::loadText(_data.getEntry(entryName));
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 534ae23168c..fa4913c5115 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -88,7 +88,7 @@ private:
void loadScreen(const Common::String & name);
Region * loadRegion(const Common::String &name);
- Common::String loadFilename(const Common::String &name);
+ Common::String loadText(const Common::String &name);
int appendToSharedStorage(const Common::String &value);
const Common::String & getSharedStorage(int id) const;
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index d19e6cc5f7e..b48b130ad3c 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -73,7 +73,7 @@ Common::String Process::getString(int id) {
}
Common::String Process::popFilename() {
- return _engine->loadFilename(popString());
+ return _engine->loadText(popString());
}
void Process::activate() {
Commit: ab9d0a76e43b87b610a034416b029e6a7c42cbd9
https://github.com/scummvm/scummvm/commit/ab9d0a76e43b87b610a034416b029e6a7c42cbd9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:57+01:00
Commit Message:
AGDS: more stubs, mostly for inventory
Changed paths:
engines/agds/agds.cpp
engines/agds/opcode.h
engines/agds/process.h
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index cb57d8eb62d..c95fa75a0e6 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -170,6 +170,7 @@ void AGDSEngine::runProcess() {
ProcessExitCode code = process.execute();
switch(code) {
case kExitCodeLoadScreenObject:
+ case kExitCodeRunDialog:
runObject(process.getExitArg1(), process.getExitArg2());
break;
case kExitCodeDestroyProcessSetNextScreen:
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 1e9f1bbf97d..9cf58cf52e4 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -111,7 +111,7 @@ enum Opcode {
kStub91 = 91,
kStub92 = 92,
kStub93 = 93,
- kStub94 = 94,
+ kLeaveCharacter = 94,
kStub95 = 95,
kStub96 = 96,
kStub97 = 97,
@@ -158,7 +158,7 @@ enum Opcode {
kStub138 = 138,
kStub139 = 139,
kScreenChangeScreenPatch = 140,
- kStub141 = 141,
+ kGetInventorySize = 141,
kSetStringSystemVariable = 142,
kSetSystemIntegerVariable = 143,
kStub144 = 144,
@@ -202,9 +202,9 @@ enum Opcode {
kSetGlyphSize = 182,
kGenerateRegion = 183,
kStub184 = 184,
- kStub185 = 185,
+ kGetMaxInventorySize = 185,
kStub186 = 186,
- kStub187 = 187,
+ kAppendInventoryObjectNameToSharedSpace = 187,
kStub188 = 188,
kStub189 = 189,
kStub190 = 190,
@@ -257,7 +257,7 @@ enum Opcode {
kStub237 = 237,
kStub238 = 238,
kStub239 = 239,
- kStub240 = 240,
+ kRunDialog = 240,
kStub241 = 241,
kHasGlobal = 242,
kStub243 = 243,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index fd19de455b2..1ed3636e7da 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -104,6 +104,9 @@ private:
void inventoryClear();
void inventoryAddObject();
+ void getMaxInventorySize();
+ void getInventorySize();
+ void appendInventoryObjectNameToSharedSpace();
void getObjectId();
void clearScreen();
@@ -139,11 +142,13 @@ private:
void getObjectPictureWidth();
void getObjectPictureHeight();
void fogOnCharacter();
+ void leaveCharacter();
void quit();
void setDialogForNextFilm();
void npcSay();
void playerSay();
+ void runDialog();
void getRandomNumber();
void setStringSystemVariable();
@@ -203,7 +208,9 @@ private:
void stub200();
void modifyMouseArea();
void stub215();
+ void stub221();
void stub223();
+ void stub225();
void stub235();
void debug(const char *str, ...);
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index c6c7caa893d..46263e17302 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -32,6 +32,7 @@ namespace AGDS {
kExitCodeLoadScreenObject = 8,
kExitCodeLoadInventoryObject = 10,
kExitCodeMouseAreaChange = 11,
+ kExitCodeRunDialog = 12,
kExitCodeExitScreen = 15,
kExitCodeLoadPreviousScreenObject = 99
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 40bd1527154..d15465fe6e4 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -486,9 +486,20 @@ void Process::stub215() {
debug("stub215: sound group %d", id);
}
+void Process::stub221() {
+ Common::String phaseVar = popString();
+ debug("stub221: animation related, phaseVar %s", phaseVar.c_str());
+}
+
void Process::stub223() {
int value = pop();
- debug("stub199: %d", value);
+ debug("stub223: %d", value);
+}
+
+void Process::stub225() {
+ int arg = pop();
+ Common::String phaseVar = popString();
+ debug("stub225: animation related, phaseVar %s, arg %d", phaseVar.c_str(), arg);
}
void Process::setFontGlyphSize() {
@@ -562,6 +573,18 @@ void Process::playerSay() {
debug("playerSay %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
//close inventory here if close flag was set
}
+void Process::runDialog() {
+ Common::String arg3 = popString();
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("runDialog %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
+ arg2 = _engine->loadText(arg2);
+ arg3 = _engine->loadText(arg3);
+ debug("definition:\n%s", arg3.c_str());
+ debug("dialog:\n%s", arg2.c_str());
+ suspend(kExitCodeRunDialog, arg1);
+}
+
void Process::getObjectPictureWidth() {
Common::String name = popString();
@@ -602,6 +625,22 @@ void Process::inventoryAddObject() {
suspend(kExitCodeLoadInventoryObject, name);
}
+void Process::getMaxInventorySize() {
+ debug("getMaxInventorySize");
+ push(35);
+}
+
+void Process::getInventorySize() {
+ debug("getInventorySize");
+ push(1);
+}
+
+void Process::appendInventoryObjectNameToSharedSpace() {
+ int index = pop();
+ debug("appendInventoryObjectNameToSharedSpace %d", index);
+ push(_engine->appendToSharedStorage("*inventory name stub*"));
+}
+
void Process::exitProcessSetNextScreen() {
Common::String name = popString();
debug("exitProcessSetNextScreen %s", name.c_str());
@@ -638,6 +677,8 @@ void Process::updateScreenHeightToDisplay() {
void Process::loadTextFromObject() {
Common::String name = popFilename();
debug("loadTextFromObject %s", name.c_str());
+ Common::String text = _engine->loadText(name);
+ debug("%s", text.c_str());
}
void Process::call(uint16 addr) {
@@ -690,6 +731,13 @@ void Process::addMouseArea() {
push(value);
}
+void Process::leaveCharacter() {
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("leaveCharacter %s %s", arg1.c_str(), arg2.c_str());
+ _engine->loadRegion(arg2);
+}
+
void Process::fogOnCharacter() {
int arg2 = pop();
int arg1 = pop();
@@ -807,6 +855,7 @@ ProcessExitCode Process::execute() {
OP (kLoadRegionFromObject, loadRegionFromObject);
OP (kLoadPictureFromObject, loadPictureFromObject);
OP (kLoadAnimationFromObject, loadAnimationFromObject);
+ OP (kLeaveCharacter, leaveCharacter);
OP (kDisableUser, disableUser);
OP (kEnableUser, enableUser);
OP (kUpdatePhaseVarOr2, updatePhaseVarOr2);
@@ -840,6 +889,7 @@ ProcessExitCode Process::execute() {
OP (kResetPhaseVar, resetPhaseVar);
OP (kStub136, stub136);
OP (kScreenChangeScreenPatch, changeScreenPatch);
+ OP (kGetInventorySize, getInventorySize);
OP (kSetStringSystemVariable, setStringSystemVariable);
OP (kSetSystemIntegerVariable, setIntegerSystemVariable);
OP (kGetRegionCenterX, getRegionCenterX);
@@ -867,6 +917,8 @@ ProcessExitCode Process::execute() {
OP (kGetObjectId, getObjectId);
OP (kSetGlyphSize, setFontGlyphSize);
OP (kGenerateRegion, generateRegion);
+ OP (kGetMaxInventorySize, getMaxInventorySize);
+ OP (kAppendInventoryObjectNameToSharedSpace, appendInventoryObjectNameToSharedSpace);
OP (kStub184, stub184);
OP (kStub188, stub188);
OP (kStub190, stub190);
@@ -879,7 +931,9 @@ ProcessExitCode Process::execute() {
OP (kSetSampleVolumeAndPan, setSampleVolumeAndPan);
OP (kPlaySound, playSound);
OP (kStub215, stub215);
+ OP (kStub221, stub221);
OP (kStub223, stub223);
+ OP (kStub225, stub225);
OP (kFadeObject, fadeObject);
OP (kLoadFont, loadFont);
OP_U (kStub202ScreenHandler, stub202);
@@ -891,6 +945,7 @@ ProcessExitCode Process::execute() {
OP_U (kOnKey, onKey);
OP (kGetSampleVolume, getSampleVolume);
OP (kStub235, stub235);
+ OP (kRunDialog, runDialog);
OP (kHasGlobal, hasGlobal);
OP (kSetDialogForNextFilm, setDialogForNextFilm);
default:
Commit: f8155280b67b43eea1a8b605c268e719a4b3e149
https://github.com/scummvm/scummvm/commit/f8155280b67b43eea1a8b605c268e719a4b3e149
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:57+01:00
Commit Message:
AGDS: implemented inventory
Changed paths:
A engines/agds/inventory.cpp
A engines/agds/inventory.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/module.mk
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c95fa75a0e6..5ee64794920 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -183,7 +183,7 @@ void AGDSEngine::runProcess() {
changeMouseArea(process.getExitIntArg1(), process.getExitIntArg2());
break;
case kExitCodeLoadInventoryObject:
- loadObject(process.getExitArg1());
+ _inventory.add(loadObject(process.getExitArg1()));
break;
case kExitCodeSuspend:
return;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index fa4913c5115..0e45fab808e 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -30,6 +30,7 @@
#include "engines/advancedDetector.h"
#include "agds/soundManager.h"
#include "agds/database.h"
+#include "agds/inventory.h"
#include "agds/processExitCode.h"
#include "agds/resourceManager.h"
#include "agds/screen.h"
@@ -104,6 +105,10 @@ private:
return _resourceManager;
}
+ Inventory & inventory() {
+ return _inventory;
+ }
+
Screen *currentScreen() {
return _currentScreen;
}
@@ -151,6 +156,7 @@ private:
bool _userEnabled;
MouseMap _mouseMap;
Common::RandomSource _random;
+ Inventory _inventory;
};
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
new file mode 100644
index 00000000000..89ecd766b75
--- /dev/null
+++ b/engines/agds/inventory.cpp
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/inventory.h"
+#include "common/debug.h"
+#include "common/textconsole.h"
+
+namespace AGDS {
+
+int Inventory::size() const {
+ int size = 0;
+ for(uint i = 0; i < _entries.size(); ++i)
+ if (_entries[i])
+ ++size;
+ return size;
+}
+
+int Inventory::add(Object *object) {
+ for(uint i = 0; i < _entries.size(); ++i) {
+ if (!_entries[i]) {
+ _entries[i] = object;
+ return i;
+ }
+ }
+ error("inventory overflow");
+}
+
+void Inventory::clear() {
+ for(uint i = 0; i < _entries.size(); ++i) {
+ _entries[i] = NULL;
+ }
+}
+
+
+}
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
new file mode 100644
index 00000000000..eadc62543b7
--- /dev/null
+++ b/engines/agds/inventory.h
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_INVENTORY_H
+#define AGDS_INVENTORY_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+
+namespace AGDS {
+class Object;
+
+class Inventory {
+ typedef Common::Array<Object *> EntriesType;
+ EntriesType _entries;
+
+public:
+ static const int kMaxSize = 35;
+
+ Inventory(): _entries(kMaxSize) { }
+
+ int add(Object *object);
+
+ Object *get(int index) const {
+ return _entries[index];
+ }
+
+ int size() const;
+ void clear();
+
+ int maxSize() const {
+ return _entries.size();
+ }
+
+};
+
+
+} // End of namespace AGDS
+
+#endif /* AGDS_INVENTORY_H */
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index 29f1d846d89..5b3f7dccfda 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -4,6 +4,7 @@ MODULE_OBJS := \
agds.o \
database.o \
detection.o \
+ inventory.o \
mjpgPlayer.o \
object.o \
process.o \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d15465fe6e4..b6479d56c20 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -617,6 +617,7 @@ void Process::playFilm() {
void Process::inventoryClear() {
debug("inventoryClear");
+ _engine->inventory().clear();
}
void Process::inventoryAddObject() {
@@ -626,19 +627,22 @@ void Process::inventoryAddObject() {
}
void Process::getMaxInventorySize() {
- debug("getMaxInventorySize");
- push(35);
+ int size = _engine->inventory().maxSize();
+ debug("getMaxInventorySize -> %d", size);
+ push(size);
}
void Process::getInventorySize() {
- debug("getInventorySize");
- push(1);
+ int size = _engine->inventory().size();
+ debug("getInventorySize -> %d", size);
+ push(size);
}
void Process::appendInventoryObjectNameToSharedSpace() {
int index = pop();
debug("appendInventoryObjectNameToSharedSpace %d", index);
- push(_engine->appendToSharedStorage("*inventory name stub*"));
+ Object *object = _engine->inventory().get(index);
+ push(_engine->appendToSharedStorage(object? object->getName(): Common::String()));
}
void Process::exitProcessSetNextScreen() {
Commit: 0a72f980d59f774c3ab2c5a2b6a2b4b8a290627c
https://github.com/scummvm/scummvm/commit/0a72f980d59f774c3ab2c5a2b6a2b4b8a290627c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:57+01:00
Commit Message:
AGDS: not inventory size, but free space in inventory, fixed
Changed paths:
engines/agds/inventory.cpp
engines/agds/inventory.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 89ecd766b75..87fa04abb62 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -26,12 +26,12 @@
namespace AGDS {
-int Inventory::size() const {
- int size = 0;
+int Inventory::free() const {
+ int free = 0;
for(uint i = 0; i < _entries.size(); ++i)
- if (_entries[i])
- ++size;
- return size;
+ if (!_entries[i])
+ ++free;
+ return free;
}
int Inventory::add(Object *object) {
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index eadc62543b7..ffca6710fe2 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -44,7 +44,7 @@ public:
return _entries[index];
}
- int size() const;
+ int free() const;
void clear();
int maxSize() const {
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 9cf58cf52e4..7987bd2e803 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -158,7 +158,7 @@ enum Opcode {
kStub138 = 138,
kStub139 = 139,
kScreenChangeScreenPatch = 140,
- kGetInventorySize = 141,
+ kGetFreeInventorySpace = 141,
kSetStringSystemVariable = 142,
kSetSystemIntegerVariable = 143,
kStub144 = 144,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 1ed3636e7da..719f9bb6905 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -105,7 +105,7 @@ private:
void inventoryClear();
void inventoryAddObject();
void getMaxInventorySize();
- void getInventorySize();
+ void getInventoryFreeSpace();
void appendInventoryObjectNameToSharedSpace();
void getObjectId();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b6479d56c20..3706e035c58 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -632,9 +632,9 @@ void Process::getMaxInventorySize() {
push(size);
}
-void Process::getInventorySize() {
- int size = _engine->inventory().size();
- debug("getInventorySize -> %d", size);
+void Process::getInventoryFreeSpace() {
+ int size = _engine->inventory().free();
+ debug("getInventoryFreeSpace -> %d", size);
push(size);
}
@@ -893,7 +893,7 @@ ProcessExitCode Process::execute() {
OP (kResetPhaseVar, resetPhaseVar);
OP (kStub136, stub136);
OP (kScreenChangeScreenPatch, changeScreenPatch);
- OP (kGetInventorySize, getInventorySize);
+ OP (kGetFreeInventorySpace, getInventoryFreeSpace);
OP (kSetStringSystemVariable, setStringSystemVariable);
OP (kSetSystemIntegerVariable, setIntegerSystemVariable);
OP (kGetRegionCenterX, getRegionCenterX);
Commit: 798fb215b6169e90bf67050acfd81d891f82075c
https://github.com/scummvm/scummvm/commit/798fb215b6169e90bf67050acfd81d891f82075c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:57+01:00
Commit Message:
AGDS: do not double-load text from loadTextFromObject
Changed paths:
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index b48b130ad3c..5d4819aa9f2 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -72,7 +72,7 @@ Common::String Process::getString(int id) {
return _object->getString(id).string;
}
-Common::String Process::popFilename() {
+Common::String Process::popText() {
return _engine->loadText(popString());
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 719f9bb6905..2463b505720 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -91,7 +91,7 @@ private:
Common::String popString() {
return getString(pop());
}
- Common::String popFilename();
+ Common::String popText();
void enter(uint16 magic, uint16 size);
void exitProcess();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3706e035c58..dd43f0503d9 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -104,18 +104,18 @@ void Process::getObjectId() {
}
void Process::loadPicture() {
- Common::String name = popFilename();
+ Common::String name = popText();
debug("loadPicture stub %s", name.c_str());
push(100500); //dummy
}
void Process::loadAnimation() {
- Common::String name = popFilename();
+ Common::String name = popText();
debug("loadAnimation %s", name.c_str());
}
void Process::loadSample() {
- Common::String name = popFilename();
+ Common::String name = popText();
debug("loadSample %s", name.c_str());
if (_phaseVar.empty()) {
warning("playing sample %s without phase var", _phaseVar.c_str());
@@ -138,7 +138,7 @@ void Process::setSampleVolumeAndPan() {
}
void Process::playSound() {
- Common::String name = popFilename();
+ Common::String name = popText();
int arg = pop();
debug("playSound %s %d", name.c_str(), arg);
}
@@ -185,13 +185,13 @@ void Process::removeScreenObject() {
}
void Process::loadFont() {
- Common::String name = popFilename();
+ Common::String name = popText();
int id = pop();
debug("loadFont %s %d stub", name.c_str(), id);
}
void Process::loadMouse() {
- Common::String name = popFilename();
+ Common::String name = popText();
debug("loadMouse %s", name.c_str());
_engine->loadCursor(name);
}
@@ -333,7 +333,7 @@ void Process::changeScreenPatch() {
}
void Process::loadMouseStub66() {
- Common::String name = popFilename();
+ Common::String name = popText();
debug("loadMouseStub66 %s", name.c_str());
_engine->loadCursor(name); //overlay cursor
}
@@ -607,8 +607,8 @@ void Process::getObjectPictureHeight() {
}
void Process::playFilm() {
- Common::String audio = popFilename();
- Common::String video = popFilename();
+ Common::String audio = popText();
+ Common::String video = popText();
debug("playFilm %s %s", video.c_str(), audio.c_str());
_engine->playFilm(video, audio);
@@ -679,10 +679,8 @@ void Process::updateScreenHeightToDisplay() {
}
void Process::loadTextFromObject() {
- Common::String name = popFilename();
- debug("loadTextFromObject %s", name.c_str());
- Common::String text = _engine->loadText(name);
- debug("%s", text.c_str());
+ Common::String text = popText();
+ debug("loadTextFromObject %s", text.c_str());
}
void Process::call(uint16 addr) {
@@ -757,13 +755,13 @@ void Process::loadRegionFromObject() {
void Process::loadPictureFromObject() {
- Common::String name = popFilename();
+ Common::String name = popText();
debug("loadPictureFromObject %s", name.c_str());
_object->setPicture(_engine->loadPicture(name));
}
void Process::loadAnimationFromObject() {
- Common::String name = popFilename();
+ Common::String name = popText();
debug("loadAnimationFromObject %s", name.c_str());
}
Commit: d97509314431777f1d38ba87b950583a2f6316c3
https://github.com/scummvm/scummvm/commit/d97509314431777f1d38ba87b950583a2f6316c3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:57+01:00
Commit Message:
AGDS: added more stubs, new game starts now
Changed paths:
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 2463b505720..b6a2f51ad7a 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -128,6 +128,7 @@ private:
void loadAnimation();
void loadSample();
void playSound();
+ void playFilm();
void getSampleVolume();
void setSampleVolumeAndPan();
void updatePhaseVarOr2();
@@ -178,6 +179,9 @@ private:
void onScreenBD(unsigned size);
void loadMouseStub66();
+ void modifyMouseArea();
+
+ void stub63(unsigned size);
void stub74();
void stub82();
void stub119();
@@ -204,10 +208,10 @@ private:
void stub194();
void stub199();
void stub202(unsigned size);
- void playFilm();
void stub200();
- void modifyMouseArea();
+ void stub209(unsigned size);
void stub215();
+ void stub217();
void stub221();
void stub223();
void stub225();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index dd43f0503d9..c5168512841 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -345,6 +345,12 @@ void Process::fadeObject() {
_engine->loadObject(name)->setAlpha(value);
}
+void Process::stub63(unsigned size) {
+ Common::String arg = popString();
+ debug("stub63: %u instructions, arg: %s", size, arg.c_str());
+ _ip += size;
+}
+
void Process::stub74() {
int arg2 = pop();
int arg1 = pop();
@@ -474,6 +480,11 @@ void Process::stub202(unsigned size) {
_ip += size;
}
+void Process::stub209(unsigned size) {
+ debug("stub209, %u instructions", size);
+ _ip += size;
+}
+
void Process::modifyMouseArea() {
int enabled = pop();
int id = pop();
@@ -486,6 +497,13 @@ void Process::stub215() {
debug("stub215: sound group %d", id);
}
+void Process::stub217() {
+ int soundGroup = pop();
+ int frame = pop();
+ int id = pop();
+ debug("stub217: animation? id: %d, frame: %d, soundGroup: %d", id, frame, soundGroup);
+}
+
void Process::stub221() {
Common::String phaseVar = popString();
debug("stub221: animation related, phaseVar %s", phaseVar.c_str());
@@ -852,6 +870,7 @@ ProcessExitCode Process::execute() {
OP_U (kCallImm16, call);
OP_U (kObjectRegisterLookHandler, onLook);
OP_U (kObjectRegisterUseHandler, onUse);
+ OP_U (kStub63, stub63);
OP_U (kScreenRegisterHandlerBD, onScreenBD);
OP (kStub66, loadMouseStub66);
OP (kLoadRegionFromObject, loadRegionFromObject);
@@ -933,6 +952,7 @@ ProcessExitCode Process::execute() {
OP (kSetSampleVolumeAndPan, setSampleVolumeAndPan);
OP (kPlaySound, playSound);
OP (kStub215, stub215);
+ OP (kStub217, stub217);
OP (kStub221, stub221);
OP (kStub223, stub223);
OP (kStub225, stub225);
@@ -944,6 +964,7 @@ ProcessExitCode Process::execute() {
OP (kFogOnCharacter, fogOnCharacter);
OP (kStub200, stub200);
OP (kModifyMouseArea, modifyMouseArea);
+ OP_U (kStub209, stub209);
OP_U (kOnKey, onKey);
OP (kGetSampleVolume, getSampleVolume);
OP (kStub235, stub235);
Commit: bc551f2891dbf117ab3826d59aa210092baa0cdf
https://github.com/scummvm/scummvm/commit/bc551f2891dbf117ab3826d59aa210092baa0cdf
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:57+01:00
Commit Message:
AGDS: updated mouse area log
Changed paths:
engines/agds/process_opcodes.cpp
engines/agds/screen.h
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c5168512841..0fe60e03f20 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -743,7 +743,7 @@ void Process::addMouseArea() {
Common::String arg2 = popString();
Common::String arg1 = popString();
- debug("findObjectInMouseArea (region: %s) %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
+ debug("addMouseArea (region: %s) %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
Region *region = _engine->loadRegion(arg1);
int value = _engine->_mouseMap.add(MouseRegion(region, arg2, arg3));
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index b281496e302..e04a1c479bb 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -55,10 +55,10 @@ struct MouseRegion {
class MouseMap {
typedef Common::List<MouseRegion> MouseRegionsType;
MouseRegionsType _mouseRegions;
- int _nextId;
+ int _nextId;
public:
- MouseMap(): _nextId(1) { }
+ MouseMap(): _nextId(0) { }
int add(const MouseRegion & area) {
_mouseRegions.push_back(area);
Commit: ae310a0ac557c511ecaa2d509710822a3f27c179
https://github.com/scummvm/scummvm/commit/ae310a0ac557c511ecaa2d509710822a3f27c179
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:58+01:00
Commit Message:
AGDS: stub191 is disableMouseAreas
Changed paths:
engines/agds/process.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/process.h b/engines/agds/process.h
index b6a2f51ad7a..3351d2e56d8 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -112,6 +112,7 @@ private:
void clearScreen();
void loadPicture();
void loadMouse();
+ void loadMouseStub66();
void loadScreenRegion();
void loadScreenObject();
void loadFont();
@@ -173,14 +174,13 @@ private:
void disableUser();
void enableUser();
+ void disableMouseAreas();
+ void modifyMouseArea();
void onKey(unsigned size);
void onUse(unsigned size);
void onLook(unsigned size);
void onScreenBD(unsigned size);
- void loadMouseStub66();
- void modifyMouseArea();
-
void stub63(unsigned size);
void stub74();
void stub82();
@@ -203,7 +203,6 @@ private:
void stub184();
void stub188();
void stub190();
- void stub191();
void stub192();
void stub194();
void stub199();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 0fe60e03f20..50acd9aa193 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -455,10 +455,10 @@ void Process::stub190() {
debug("stub190 %d", value);
}
-void Process::stub191() {
+void Process::disableMouseAreas() {
int value = pop();
- value = value > 0? 1: 0;
- debug("stub191: setting some mouse flag to %d", value);
+ debug("disableMouseAreas %d", value);
+ _engine->_mouseMap.disable(value > 0);
}
void Process::stub194() {
@@ -943,7 +943,7 @@ ProcessExitCode Process::execute() {
OP (kStub184, stub184);
OP (kStub188, stub188);
OP (kStub190, stub190);
- OP (kStub191, stub191);
+ OP (kStub191, disableMouseAreas);
OP (kStub194, stub194);
OP (kGetObjectPictureWidth, getObjectPictureWidth);
OP (kGetObjectPictureHeight, getObjectPictureHeight);
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 1854ae5fb2b..df1ee7f52db 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -66,6 +66,8 @@ Object *Screen::find(Common::Point pos) const {
}
MouseRegion * MouseMap::find(Common::Point pos) {
+ if (_disabled)
+ return NULL;
for(MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i) {
MouseRegion &mouse = *i;
if (mouse.enabled && mouse.region->pointIn(pos))
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index e04a1c479bb..3b12791c22e 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -56,9 +56,14 @@ class MouseMap {
typedef Common::List<MouseRegion> MouseRegionsType;
MouseRegionsType _mouseRegions;
int _nextId;
+ bool _disabled;
public:
- MouseMap(): _nextId(0) { }
+ MouseMap(): _nextId(0), _disabled(false) { }
+
+ void disable(bool disabled) {
+ _disabled = disabled;
+ }
int add(const MouseRegion & area) {
_mouseRegions.push_back(area);
Commit: 3e43a55b49402404cc80c597dceeb279eb0c71eb
https://github.com/scummvm/scummvm/commit/3e43a55b49402404cc80c597dceeb279eb0c71eb
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:58+01:00
Commit Message:
AGDS: destroy process on error condition
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 5ee64794920..69f1dc010ab 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -161,7 +161,7 @@ void AGDSEngine::runProcess() {
for(ProcessListType::iterator p = _processes.begin(); active() && p != _processes.end(); ) {
Process & process = *p;
const Common::String &name = process.getName();
- if (process.getStatus() == Process::kStatusDone) {
+ if (process.getStatus() == Process::kStatusDone || process.getStatus() == Process::kStatusError) {
debug("process %s finished", name.c_str());
p = _processes.erase(p);
continue;
Commit: 3ae2964c70045143c67b986cdaa0809af4e7e150
https://github.com/scummvm/scummvm/commit/3ae2964c70045143c67b986cdaa0809af4e7e150
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:58+01:00
Commit Message:
AGDS: do not run processes outside of current screen
Changed paths:
engines/agds/agds.cpp
engines/agds/process.cpp
engines/agds/process.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 69f1dc010ab..4a9a282ff2a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -160,6 +160,11 @@ void AGDSEngine::loadScreen(const Common::String & name) {
void AGDSEngine::runProcess() {
for(ProcessListType::iterator p = _processes.begin(); active() && p != _processes.end(); ) {
Process & process = *p;
+ if (process.parentScreen() != currentScreen()) {
+ ++p;
+ continue;
+ }
+
const Common::String &name = process.getName();
if (process.getStatus() == Process::kStatusDone || process.getStatus() == Process::kStatusError) {
debug("process %s finished", name.c_str());
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 5d4819aa9f2..d003e7d395d 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -28,8 +28,10 @@
namespace AGDS {
Process::Process(AGDSEngine *engine, Object* object, unsigned ip) :
- _engine(engine), _object(object), _ip(ip), _status(kStatusActive), _exitCode(kExitCodeDestroy),
+ _engine(engine), _parentScreen(engine->currentScreen()), _object(object), _ip(ip), _status(kStatusActive), _exitCode(kExitCodeDestroy),
_glyphWidth(16), _glyphHeight(16) {
+ if (!_parentScreen)
+ error("no parent screen");
}
void Process::debug(const char *str, ...) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 3351d2e56d8..5b0bd6b414e 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -32,6 +32,8 @@
namespace AGDS {
class AGDSEngine;
+class Screen;
+
class Process {
public:
enum Status { kStatusActive, kStatusPassive, kStatusDone, kStatusError };
@@ -40,6 +42,7 @@ private:
typedef Common::Stack<int32> StackType;
AGDSEngine * _engine;
+ Screen * _parentScreen;
Object * _object;
StackType _stack;
unsigned _ip, _lastIp;
@@ -270,6 +273,10 @@ public:
return _object->getName();
}
+ Screen *parentScreen() const {
+ return _parentScreen;
+ }
+
Status getStatus() const {
return _status;
}
Commit: ee51f039783998bc622c9ebd08f0e74eff020cb2
https://github.com/scummvm/scummvm/commit/ee51f039783998bc622c9ebd08f0e74eff020cb2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:58+01:00
Commit Message:
AGDS: made enabled flag counter
Changed paths:
engines/agds/agds.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 4a9a282ff2a..3aea6f648c0 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -205,13 +205,13 @@ void AGDSEngine::changeMouseArea(int id, int enabled) {
if (mouseArea) {
switch(enabled) {
case 1:
- mouseArea->enabled = true;
+ mouseArea->enable();
break;
case 0:
if (mouseArea->currentlyIn) {
runObject(mouseArea->onLeave);
}
- mouseArea->enabled = false;
+ mouseArea->disable();
break;
case -1:
_mouseMap.remove(id);
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 3b12791c22e..2e5aaa5fca0 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -38,16 +38,25 @@ class Object;
struct Region;
struct MouseRegion {
- int id;
- Region *region;
- bool enabled;
- bool currentlyIn;
+ int id;
+ Region * region;
+ int enabled;
+ bool currentlyIn;
+
Common::String onEnter;
Common::String onLeave;
- MouseRegion(): id(-1), enabled(false), currentlyIn(false), region() { }
+ void enable() {
+ ++enabled;
+ }
+
+ void disable() {
+ if (enabled > 0)
+ --enabled;
+ }
+
MouseRegion(Region * reg, const Common::String &enter, const Common::String &leave):
- id(-1), region(reg), enabled(true), currentlyIn(false), onEnter(enter), onLeave(leave) {
+ id(-1), region(reg), enabled(1), currentlyIn(false), onEnter(enter), onLeave(leave) {
}
};
Commit: b227a5a7ef8636685164f2067461581775ad0684
https://github.com/scummvm/scummvm/commit/b227a5a7ef8636685164f2067461581775ad0684
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:58+01:00
Commit Message:
AGDS: suspend after call
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 50acd9aa193..ca893a09f1d 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -708,6 +708,7 @@ void Process::call(uint16 addr) {
Process callee(_engine, _object, _ip + addr);
ProcessExitCode code = callee.execute();
debug("call returned %d", code);
+ suspend();
}
void Process::onKey(unsigned size) {
Commit: 64d0eb4364510d6a98fc7e5397236867854e8830
https://github.com/scummvm/scummvm/commit/64d0eb4364510d6a98fc7e5397236867854e8830
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:58+01:00
Commit Message:
AGDS: implemented runProcess closer to original, run object code once, push all processes once per tick after suspend
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3aea6f648c0..c46cb5bcef4 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -135,7 +135,9 @@ Object *AGDSEngine::loadObject(const Common::String & name, const Common::String
}
void AGDSEngine::runObject(Object *object) {
- _processes.push_front(Process(this, object));
+ _processes.push_back(Process(this, object));
+ ProcessListType::iterator it = _processes.reverse_begin();
+ runProcess(it);
if (_currentScreen)
_currentScreen->add(object);
}
@@ -157,46 +159,51 @@ void AGDSEngine::loadScreen(const Common::String & name) {
runObject(name);
}
+void AGDSEngine::runProcess(ProcessListType::iterator &it) {
+ Process & process = *it;
+ if (process.parentScreen() != currentScreen()) {
+ ++it;
+ return;
+ }
+
+ const Common::String &name = process.getName();
+ if (process.getStatus() == Process::kStatusDone || process.getStatus() == Process::kStatusError) {
+ debug("process %s finished", name.c_str());
+ it = _processes.erase(it);
+ return;
+ }
+ process.activate();
+ ProcessExitCode code = process.execute();
+ switch(code) {
+ case kExitCodeLoadScreenObject:
+ case kExitCodeRunDialog:
+ runObject(process.getExitArg1(), process.getExitArg2());
+ break;
+ case kExitCodeDestroyProcessSetNextScreen:
+ loadScreen(process.getExitArg1());
+ break;
+ case kExitCodeLoadPreviousScreenObject:
+ loadScreen(_previousScreen);
+ break;
+ case kExitCodeMouseAreaChange:
+ changeMouseArea(process.getExitIntArg1(), process.getExitIntArg2());
+ break;
+ case kExitCodeLoadInventoryObject:
+ _inventory.add(loadObject(process.getExitArg1()));
+ break;
+ case kExitCodeSuspend:
+ break;
+ default:
+ debug("destroying process %s...", name.c_str());
+ it = _processes.erase(it);
+ return;
+ }
+ ++it;
+}
+
void AGDSEngine::runProcess() {
for(ProcessListType::iterator p = _processes.begin(); active() && p != _processes.end(); ) {
- Process & process = *p;
- if (process.parentScreen() != currentScreen()) {
- ++p;
- continue;
- }
-
- const Common::String &name = process.getName();
- if (process.getStatus() == Process::kStatusDone || process.getStatus() == Process::kStatusError) {
- debug("process %s finished", name.c_str());
- p = _processes.erase(p);
- continue;
- }
- process.activate();
- ProcessExitCode code = process.execute();
- switch(code) {
- case kExitCodeLoadScreenObject:
- case kExitCodeRunDialog:
- runObject(process.getExitArg1(), process.getExitArg2());
- break;
- case kExitCodeDestroyProcessSetNextScreen:
- loadScreen(process.getExitArg1());
- break;
- case kExitCodeLoadPreviousScreenObject:
- loadScreen(_previousScreen);
- break;
- case kExitCodeMouseAreaChange:
- changeMouseArea(process.getExitIntArg1(), process.getExitIntArg2());
- break;
- case kExitCodeLoadInventoryObject:
- _inventory.add(loadObject(process.getExitArg1()));
- break;
- case kExitCodeSuspend:
- return;
- default:
- debug("destroying process %s...", name.c_str());
- p = _processes.erase(p);
- continue;
- }
+ runProcess(p);
}
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 0e45fab808e..25fcd7a295e 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -60,6 +60,7 @@ class SystemVariable;
class AGDSEngine : public Engine {
friend class Process;
+ typedef Common::List<Process> ProcessListType;
public:
AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc);
@@ -78,6 +79,7 @@ public:
private:
bool initGraphics();
bool load();
+ void runProcess(ProcessListType::iterator &it);
void runProcess();
Object * loadObject(const Common::String & name, const Common::String & prototype = Common::String());
@@ -130,7 +132,6 @@ private:
typedef Common::HashMap<Common::String, Screen *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ScreensType;
typedef Common::HashMap<Common::String, Region *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> RegionsType;
typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
- typedef Common::List<Process> ProcessListType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
const ADGameDescription * _gameDescription;
Commit: e8550ebde2c8926302ecb74a357f09954635483f
https://github.com/scummvm/scummvm/commit/e8550ebde2c8926302ecb74a357f09954635483f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:58+01:00
Commit Message:
AGDS: exitScreen seems to be disableInventory
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 7987bd2e803..e876106c155 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -179,7 +179,7 @@ enum Opcode {
kExitProcessCreatePatch = 159,
kStub160 = 160,
kStub161 = 161,
- kExitScreen = 162,
+ kDisableInventory = 162,
kStub163 = 163,
kLoadPreviousScreen = 164,
kMoveScreenObject = 165,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 5b0bd6b414e..849647a3f53 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -99,7 +99,7 @@ private:
void enter(uint16 magic, uint16 size);
void exitProcess();
void exitProcessCreatePatch();
- void exitScreen();
+ void disableInventory();
void exitProcessSetNextScreen();
void exitProcessSetNextScreen80();
void loadPreviousScreen();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index ca893a09f1d..1b41d80a1e8 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -680,11 +680,9 @@ void Process::loadPreviousScreen() {
suspend(kExitCodeLoadPreviousScreenObject);
}
-void Process::exitScreen()
+void Process::disableInventory()
{
- debug("exitScreen? reactivating process...");
- if (_status != kStatusDone)
- _status = kStatusActive;
+ debug("disableInventory");
}
void Process::setScreenHeight() {
@@ -933,7 +931,7 @@ ProcessExitCode Process::execute() {
OP (kStub192, stub192);
OP (kQuit, quit);
OP (kExitProcessCreatePatch, exitProcessCreatePatch);
- OP (kExitScreen, exitScreen);
+ OP (kDisableInventory, disableInventory);
OP (kLoadPreviousScreen, loadPreviousScreen);
OP (kMoveScreenObject, moveScreenObject);
OP (kGetObjectId, getObjectId);
Commit: 80a01d37f9c73bd237476b5d9c007d8b741663ec
https://github.com/scummvm/scummvm/commit/80a01d37f9c73bd237476b5d9c007d8b741663ec
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:58+01:00
Commit Message:
AGDS: implemented simple animation support, ported mouse cursor to it, properly resolve current cursor from current object
Changed paths:
A engines/agds/animation.cpp
A engines/agds/animation.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/module.mk
engines/agds/object.cpp
engines/agds/object.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c46cb5bcef4..31623c131c7 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -21,6 +21,7 @@
*/
#include "agds/agds.h"
+#include "agds/animation.h"
#include "agds/mjpgPlayer.h"
#include "agds/object.h"
#include "agds/process.h"
@@ -40,7 +41,8 @@ namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Engine(system),
_gameDescription(gameDesc), _sharedStorageIndex(-2), _timer(0),
- _mjpgPlayer(NULL), _currentScreen(NULL), _mouseCursor(NULL),
+ _mjpgPlayer(NULL), _currentScreen(NULL),
+ _defaultMouseCursor(NULL),
_mouse(400, 300), _userEnabled(false), _currentRegion(NULL),
_random("agds"), _soundManager(this, system->getMixer()) {
}
@@ -281,6 +283,15 @@ Common::Error AGDSEngine::run() {
}
}
+ Animation *mouseCursor = NULL;
+
+ if (_userEnabled && _currentScreen) {
+ Object *object = _currentScreen->find(_mouse);
+ Animation *cursor = object? object->getMouseCursor(): NULL;
+ if (cursor)
+ mouseCursor = cursor;
+ }
+
_soundManager.tick();
if (active())
runProcess();
@@ -308,18 +319,11 @@ Common::Error AGDSEngine::run() {
_currentScreen->paint(*backbuffer);
}
- if (_userEnabled && _mouseCursor) {
- const Graphics::Surface * frame = _mouseCursor->decodeNextFrame();
- if (!frame) {
- _mouseCursor->rewind();
- frame = _mouseCursor->decodeNextFrame();
- }
- Graphics::TransparentSurface * c = convertToTransparent(frame->convertTo(_pixelFormat, _mouseCursor->getPalette()));
- Common::Point dst = _mouse;
- Common::Rect srcRect = c->getRect();
- if (Common::Rect::getBlitRect(dst, srcRect, backbuffer->getRect()))
- c->blit(*backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
- delete c;
+ if (!mouseCursor)
+ mouseCursor = _defaultMouseCursor;
+
+ if (_userEnabled && mouseCursor) {
+ mouseCursor->paint(this, *backbuffer, _mouse);
}
_system->unlockScreen();
@@ -367,16 +371,19 @@ int AGDSEngine::getGlobal(const Common::String &name) const {
}
}
-void AGDSEngine::loadCursor(const Common::String &name, unsigned index) {
+Animation * AGDSEngine::loadAnimation(const Common::String &name) {
+ AnimationsType::iterator i = _animations.find(name);
+ if (i != _animations.end())
+ return i->_value;
+
Common::SeekableReadStream *stream = _resourceManager.getResource(name);
if (!stream)
- error("could not load cursor from %s", name.c_str());
- Video::FlicDecoder * cursor = new Video::FlicDecoder;
- if (cursor->loadStream(stream)) {
- delete _mouseCursor;
- _mouseCursor = cursor;
- } else
- delete cursor;
+ error("could not load animation from %s", name.c_str());
+ Animation *animation = new Animation();
+ if (!animation->load(stream))
+ error("could not load animation from %s", name.c_str());
+ _animations[name] = animation;
+ return animation;
}
Graphics::TransparentSurface * AGDSEngine::loadPicture(const Common::String &name)
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 25fcd7a295e..d73595f50ef 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -50,6 +50,7 @@ namespace Graphics { struct TransparentSurface; }
namespace AGDS {
+class Animation;
class Object;
class Process;
struct Region;
@@ -82,6 +83,7 @@ private:
void runProcess(ProcessListType::iterator &it);
void runProcess();
+public:
Object * loadObject(const Common::String & name, const Common::String & prototype = Common::String());
void runObject(Object *object);
@@ -115,10 +117,17 @@ private:
return _currentScreen;
}
+ const Graphics::PixelFormat & pixelFormat() const {
+ return _pixelFormat;
+ }
+
Graphics::TransparentSurface *loadPicture(const Common::String &name);
Graphics::TransparentSurface *convertToTransparent(const Graphics::Surface *surface); //destroys surface!
- void loadCursor(const Common::String &name, unsigned index = 0);
+ Animation * loadAnimation(const Common::String &name);
+ void loadDefaultMouseCursor(const Common::String &name) {
+ _defaultMouseCursor = loadAnimation(name);
+ }
void changeMouseArea(int id, int enabled);
void enableUser(bool enabled) {
_userEnabled = enabled;
@@ -133,6 +142,7 @@ private:
typedef Common::HashMap<Common::String, Region *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> RegionsType;
typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
+ typedef Common::HashMap<Common::String, Animation *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> AnimationsType;
const ADGameDescription * _gameDescription;
ResourceManager _resourceManager;
@@ -141,6 +151,7 @@ private:
ObjectsType _objects;
ScreensType _screens;
RegionsType _regions;
+ AnimationsType _animations;
ProcessListType _processes;
int _sharedStorageIndex;
Common::String _sharedStorage[10];
@@ -151,7 +162,7 @@ private:
MJPGPlayer * _mjpgPlayer;
Screen * _currentScreen;
Common::String _previousScreen;
- Video::FlicDecoder * _mouseCursor;
+ Animation * _defaultMouseCursor;
Common::Point _mouse;
MouseRegion * _currentRegion;
bool _userEnabled;
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
new file mode 100644
index 00000000000..90cdbbcd9cc
--- /dev/null
+++ b/engines/agds/animation.cpp
@@ -0,0 +1,74 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/animation.h"
+#include "agds/agds.h"
+#include "common/debug.h"
+#include "common/textconsole.h"
+#include "graphics/transparent_surface.h"
+#include "video/flic_decoder.h"
+
+namespace AGDS {
+
+Animation::Animation(): _flic() {
+}
+
+Animation::~Animation() {
+ delete _flic;
+}
+
+bool Animation::load(Common::SeekableReadStream* stream) {
+ Video::FlicDecoder * flic = new Video::FlicDecoder;
+ if (flic->loadStream(stream)) {
+ delete _flic;
+ _flic = flic;
+ return true;
+ } else {
+ delete flic;
+ return false;
+ }
+}
+
+
+void Animation::paint(AGDSEngine *engine, Graphics::Surface & backbuffer, Common::Point dst) {
+ const Graphics::Surface * frame = _flic->decodeNextFrame();
+ if (!frame) {
+ _flic->rewind();
+ frame = _flic->decodeNextFrame();
+ }
+ Graphics::TransparentSurface * c = engine->convertToTransparent(frame->convertTo(engine->pixelFormat(), _flic->getPalette()));
+ Common::Rect srcRect = c->getRect();
+ if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
+ c->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
+ delete c;
+}
+
+int Animation::width() const {
+ return _flic? _flic->getWidth(): 0;
+}
+int Animation::height() const {
+ return _flic? _flic->getHeight(): 0;
+}
+
+
+
+}
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
new file mode 100644
index 00000000000..327e522739b
--- /dev/null
+++ b/engines/agds/animation.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_ANIMATION_H
+#define AGDS_ANIMATION_H
+
+#include "common/scummsys.h"
+#include "common/rect.h"
+
+namespace Common { class SeekableReadStream; }
+namespace Graphics { class Surface; }
+namespace Video { class FlicDecoder; }
+
+namespace AGDS {
+
+class AGDSEngine;
+class Object;
+
+class Animation {
+ Video::FlicDecoder *_flic;
+
+public:
+ Animation();
+ ~Animation();
+
+ bool load(Common::SeekableReadStream *stream);
+ void paint(AGDSEngine *engine, Graphics::Surface & backbuffer, Common::Point dst);
+ int width() const;
+ int height() const;
+};
+
+
+} // End of namespace AGDS
+
+#endif /* AGDS_ANIMATION_H */
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index 5b3f7dccfda..79144fbd07e 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/agds
MODULE_OBJS := \
agds.o \
+ animation.o \
database.o \
detection.o \
inventory.o \
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 39e94760b33..91570732e1e 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -21,6 +21,7 @@
*/
#include "agds/object.h"
+#include "agds/animation.h"
#include "common/debug.h"
#include "common/memstream.h"
#include "common/rect.h"
@@ -29,7 +30,10 @@
namespace AGDS {
-Object::Object(const Common::String &name, Common::SeekableReadStream * stream) : _name(name), _stringTableLoaded(false), _picture(), _pos(), _region(), _alpha(255) {
+Object::Object(const Common::String &name, Common::SeekableReadStream * stream) :
+ _name(name), _stringTableLoaded(false),
+ _picture(), _region(), _mouseCursor(),
+ _pos(), _alpha(255) {
byte id = stream->readByte();
byte flag = stream->readByte();
debug("id: 0x%02x %u, flag: %u", id, id, flag);
@@ -93,6 +97,11 @@ void Object::setPicture(Graphics::TransparentSurface *picture) {
_picture = picture;
}
+void Object::setMouseCursor(Animation *animation) {
+ _mouseCursor = animation;
+}
+
+
void Object::paint(Graphics::Surface &backbuffer) {
if (_picture) {
Common::Point dst = _pos;
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 52e570b2011..c1d2d7e31a0 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -33,6 +33,7 @@ namespace Graphics { class Surface; class TransparentSurface; }
namespace AGDS {
struct Region;
+class Animation;
class Object {
public:
@@ -56,6 +57,7 @@ private:
bool _stringTableLoaded;
Graphics::TransparentSurface * _picture;
Region * _region;
+ Animation * _mouseCursor;
Common::Point _pos;
uint _clickHandler;
int _alpha;
@@ -75,8 +77,12 @@ public:
return _code;
}
- void setPicture(Graphics::TransparentSurface *);
+ void setMouseCursor(Animation *animation);
+ Animation *getMouseCursor() const {
+ return _mouseCursor;
+ }
+ void setPicture(Graphics::TransparentSurface *);
Graphics::TransparentSurface *getPicture() const {
return _picture;
}
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index e876106c155..02a8d310f43 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -85,7 +85,7 @@ enum Opcode {
kStub63 = 63,
kScreenRegisterHandlerBD = 64,
kStub65 = 65,
- kStub66 = 66,
+ kLoadMouseCursorFromObject = 66,
kLoadRegionFromObject = 68,
kLoadPictureFromObject = 69,
kLoadAnimationFromObject = 70,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 849647a3f53..0cf7a572025 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -115,7 +115,7 @@ private:
void clearScreen();
void loadPicture();
void loadMouse();
- void loadMouseStub66();
+ void loadMouseCursorFromObject();
void loadScreenRegion();
void loadScreenObject();
void loadFont();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 1b41d80a1e8..3ec49eb263d 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -193,7 +193,7 @@ void Process::loadFont() {
void Process::loadMouse() {
Common::String name = popText();
debug("loadMouse %s", name.c_str());
- _engine->loadCursor(name);
+ _engine->loadDefaultMouseCursor(name);
}
void Process::getRandomNumber() {
@@ -332,10 +332,10 @@ void Process::changeScreenPatch() {
push(0);
}
-void Process::loadMouseStub66() {
+void Process::loadMouseCursorFromObject() {
Common::String name = popText();
- debug("loadMouseStub66 %s", name.c_str());
- _engine->loadCursor(name); //overlay cursor
+ debug("loadMouseCursorFromObject %s", name.c_str());
+ _object->setMouseCursor(_engine->loadAnimation(name)); //overlay cursor
}
void Process::fadeObject() {
@@ -871,7 +871,7 @@ ProcessExitCode Process::execute() {
OP_U (kObjectRegisterUseHandler, onUse);
OP_U (kStub63, stub63);
OP_U (kScreenRegisterHandlerBD, onScreenBD);
- OP (kStub66, loadMouseStub66);
+ OP (kLoadMouseCursorFromObject, loadMouseCursorFromObject);
OP (kLoadRegionFromObject, loadRegionFromObject);
OP (kLoadPictureFromObject, loadPictureFromObject);
OP (kLoadAnimationFromObject, loadAnimationFromObject);
Commit: 73970dedc9641382c00ee8482fe991f3009cbfd7
https://github.com/scummvm/scummvm/commit/73970dedc9641382c00ee8482fe991f3009cbfd7
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-11-12T15:57:58+01:00
Commit Message:
AGDS: Fix warnings
Changed paths:
engines/agds/animation.h
engines/agds/object.h
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 327e522739b..0259a9aeb24 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -27,7 +27,7 @@
#include "common/rect.h"
namespace Common { class SeekableReadStream; }
-namespace Graphics { class Surface; }
+namespace Graphics { struct Surface; }
namespace Video { class FlicDecoder; }
namespace AGDS {
diff --git a/engines/agds/object.h b/engines/agds/object.h
index c1d2d7e31a0..8e2425679c0 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -28,7 +28,7 @@
#include "common/rect.h"
#include "common/stream.h"
-namespace Graphics { class Surface; class TransparentSurface; }
+namespace Graphics { struct Surface; struct TransparentSurface; }
namespace AGDS {
Commit: 1a01e9df56b3b0bbbaf316af52e67d460d8a7ae0
https://github.com/scummvm/scummvm/commit/1a01e9df56b3b0bbbaf316af52e67d460d8a7ae0
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:58+01:00
Commit Message:
AGDS: marked all known handlers with [handlers] word
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3ec49eb263d..6adb9aed047 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -347,7 +347,7 @@ void Process::fadeObject() {
void Process::stub63(unsigned size) {
Common::String arg = popString();
- debug("stub63: %u instructions, arg: %s", size, arg.c_str());
+ debug("stub63: [handler] %u instructions, arg: %s", size, arg.c_str());
_ip += size;
}
@@ -476,12 +476,12 @@ void Process::stub200() {
}
void Process::stub202(unsigned size) {
- debug("stub203, %u instructions", size);
+ debug("stub203, [handler] %u instructions", size);
_ip += size;
}
void Process::stub209(unsigned size) {
- debug("stub209, %u instructions", size);
+ debug("stub209, [handler] %u instructions", size);
_ip += size;
}
@@ -711,23 +711,23 @@ void Process::call(uint16 addr) {
void Process::onKey(unsigned size) {
Common::String key = popString();
- debug("onKey %s handler, %u instructions", key.c_str(), size);
+ debug("onKey %s [handler], %u instructions", key.c_str(), size);
_ip += size;
}
void Process::onUse(unsigned size) {
- debug("use? handler, %u instructions", size);
+ debug("lclick [handler], %u instructions", size);
_object->setClickHandler(_ip);
_ip += size;
}
void Process::onLook(unsigned size) {
- debug("look? handler, %u instructions", size);
+ debug("look? [handler], %u instructions", size);
_ip += size;
}
void Process::onScreenBD(unsigned size) {
- debug("onScreen(+BD) handler, %u instructions", size);
+ debug("onScreen(+BD) [handler], %u instructions", size);
_ip += size;
}
Commit: a6dba7e1a474c6749c0a0eaa5267b58664f77e66
https://github.com/scummvm/scummvm/commit/a6dba7e1a474c6749c0a0eaa5267b58664f77e66
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:59+01:00
Commit Message:
AGDS: return empty string for empty value
Changed paths:
engines/agds/resourceManager.cpp
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index b728e2f8c2a..f5fe069aea1 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -197,6 +197,9 @@ namespace AGDS {
error("short read from text resource");
delete stream;
+ if (text.empty())
+ return Common::String();
+
char *begin = reinterpret_cast<char *>(text.data());
char *end = begin + text.size();
while(begin != end && end[-1] == 0)
Commit: b183cf056d2545822fe71109e5de481bcdb440e9
https://github.com/scummvm/scummvm/commit/b183cf056d2545822fe71109e5de481bcdb440e9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:59+01:00
Commit Message:
AGDS: do not output noisy 'last char' log
Changed paths:
engines/agds/resourceManager.cpp
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index f5fe069aea1..33c343d185c 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -207,8 +207,6 @@ namespace AGDS {
decrypt(text.data(), end - begin);
- debug("last char %d %ld", (int)*end, end - begin);
-
return Common::String(begin, end);
}
Commit: c36248cfc316b9648abfbab978113a5ebca93693
https://github.com/scummvm/scummvm/commit/c36248cfc316b9648abfbab978113a5ebca93693
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:59+01:00
Commit Message:
AGDS: feeble attempt to pass reference rewriting and fixing previous screen handling
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 31623c131c7..86d3457e753 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -146,8 +146,9 @@ void AGDSEngine::runObject(Object *object) {
void AGDSEngine::loadScreen(const Common::String & name) {
debug("loadScreen %s", name.c_str());
+ Common::String currentScreenName;
if (_currentScreen)
- _previousScreen = _currentScreen->getName();
+ currentScreenName = _currentScreen->getName();
ScreensType::iterator i = _screens.find(name);
Screen *screen;
@@ -158,6 +159,7 @@ void AGDSEngine::loadScreen(const Common::String & name) {
screen = i->_value;
_currentScreen = screen;
+ _previousScreen = currentScreenName;
runObject(name);
}
Commit: a29fe16c1652c6fd55d17ca27bc65a0cb1daa6e5
https://github.com/scummvm/scummvm/commit/a29fe16c1652c6fd55d17ca27bc65a0cb1daa6e5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:59+01:00
Commit Message:
AGDS: non-existing global returned as zero (see opcode 21 and others)
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 86d3457e753..495a6ffb27c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -368,8 +368,8 @@ int AGDSEngine::getGlobal(const Common::String &name) const {
if (i != _globals.end())
return i->_value;
else {
- debug("global %s was not declared, returning -1", name.c_str());
- return -1;
+ debug("global %s was not declared, returning 0", name.c_str());
+ return 0;
}
}
Commit: a689f2f8605f7e773a1960f507126d0e84291159
https://github.com/scummvm/scummvm/commit/a689f2f8605f7e773a1960f507126d0e84291159
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:59+01:00
Commit Message:
AGDS: fixed formatting
Changed paths:
engines/agds/opcode.h
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 02a8d310f43..e8338572951 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -85,7 +85,7 @@ enum Opcode {
kStub63 = 63,
kScreenRegisterHandlerBD = 64,
kStub65 = 65,
- kLoadMouseCursorFromObject = 66,
+ kLoadMouseCursorFromObject = 66,
kLoadRegionFromObject = 68,
kLoadPictureFromObject = 69,
kLoadAnimationFromObject = 70,
@@ -179,7 +179,7 @@ enum Opcode {
kExitProcessCreatePatch = 159,
kStub160 = 160,
kStub161 = 161,
- kDisableInventory = 162,
+ kDisableInventory = 162,
kStub163 = 163,
kLoadPreviousScreen = 164,
kMoveScreenObject = 165,
Commit: 91e29f1b02c7f927353c6a362e55ee7a027b3546
https://github.com/scummvm/scummvm/commit/91e29f1b02c7f927353c6a362e55ee7a027b3546
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:59+01:00
Commit Message:
AGDS: implemented init_resources var handling
Changed paths:
engines/agds/agds.cpp
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 495a6ffb27c..0cc0af86f36 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -197,6 +197,9 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
break;
case kExitCodeSuspend:
break;
+ case kExitCodeCreatePatchLoadResources:
+ runObject(process.getExitArg1());
+ //deliberate fallthrough
default:
debug("destroying process %s...", name.c_str());
it = _processes.erase(it);
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index 46263e17302..4f475f76ffa 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -33,6 +33,7 @@ namespace AGDS {
kExitCodeLoadInventoryObject = 10,
kExitCodeMouseAreaChange = 11,
kExitCodeRunDialog = 12,
+ kExitCodeCreatePatchLoadResources = 13,
kExitCodeExitScreen = 15,
kExitCodeLoadPreviousScreenObject = 99
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 6adb9aed047..087650c9698 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -553,7 +553,12 @@ void Process::exitProcess() {
}
void Process::exitProcessCreatePatch() {
- debug("exitProcessCreatePatch stub");
+ SystemVariable * init = _engine->getSystemVariable("init_resources");
+ if (!init)
+ error("no init_resources declared");
+ Common::String name = init->getString();
+ debug("exitProcessCreatePatch stub, resource object: %s", name.c_str());
+ suspend(kExitCodeCreatePatchLoadResources, name);
}
void Process::clearScreen() {
Commit: 6b905c4813b7a38bcc7e706affcc2e49d270bfc4
https://github.com/scummvm/scummvm/commit/6b905c4813b7a38bcc7e706affcc2e49d270bfc4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:59+01:00
Commit Message:
AGDS: more code in createPatch stub, call done_resources object first, clear inventory, and then init_resource
Changed paths:
engines/agds/agds.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 0cc0af86f36..080ccf8e8ed 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -199,6 +199,8 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
break;
case kExitCodeCreatePatchLoadResources:
runObject(process.getExitArg1());
+ _inventory.clear();
+ runObject(process.getExitArg2());
//deliberate fallthrough
default:
debug("destroying process %s...", name.c_str());
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 087650c9698..91004c9c627 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -553,12 +553,17 @@ void Process::exitProcess() {
}
void Process::exitProcessCreatePatch() {
- SystemVariable * init = _engine->getSystemVariable("init_resources");
- if (!init)
+ SystemVariable * initVar = _engine->getSystemVariable("init_resources");
+ if (!initVar)
error("no init_resources declared");
- Common::String name = init->getString();
- debug("exitProcessCreatePatch stub, resource object: %s", name.c_str());
- suspend(kExitCodeCreatePatchLoadResources, name);
+ Common::String init = initVar->getString();
+
+ SystemVariable * doneVar = _engine->getSystemVariable("done_resources");
+ if (!doneVar)
+ error("no done_resources declared");
+ Common::String done = doneVar->getString();
+ debug("exitProcessCreatePatch stub, resource objects: %s %s", done.c_str(), init.c_str());
+ suspend(kExitCodeCreatePatchLoadResources, done, init);
}
void Process::clearScreen() {
Commit: 42096ea884e7351cfe9f35754955b13688b1135e
https://github.com/scummvm/scummvm/commit/42096ea884e7351cfe9f35754955b13688b1135e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:59+01:00
Commit Message:
AGDS: renamed stub188 to setObjectText
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index e8338572951..f7a5cc7be28 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -205,7 +205,7 @@ enum Opcode {
kGetMaxInventorySize = 185,
kStub186 = 186,
kAppendInventoryObjectNameToSharedSpace = 187,
- kStub188 = 188,
+ kSetObjectText = 188,
kStub189 = 189,
kStub190 = 190,
kStub191 = 191,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 0cf7a572025..089ae53964d 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -204,7 +204,7 @@ private:
void stub174();
void stub176();
void stub184();
- void stub188();
+ void setObjectText();
void stub190();
void stub192();
void stub194();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 91004c9c627..ed4fa8c964e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -537,11 +537,11 @@ void Process::stub184() {
debug("stub184: %s", name.c_str());
}
-void Process::stub188() {
+void Process::setObjectText() {
int arg3 = pop();
- Common::String arg2 = popString();
+ Common::String arg2 = popText();
Common::String arg1 = popString();
- debug("stub188 %s %s %d", arg1.c_str(), arg2.c_str(), arg3);
+ debug("setObjectText %s \"%s\" %d", arg1.c_str(), arg2.c_str(), arg3);
//_engine->loadObject(arg1);
}
@@ -950,7 +950,7 @@ ProcessExitCode Process::execute() {
OP (kGetMaxInventorySize, getMaxInventorySize);
OP (kAppendInventoryObjectNameToSharedSpace, appendInventoryObjectNameToSharedSpace);
OP (kStub184, stub184);
- OP (kStub188, stub188);
+ OP (kSetObjectText, setObjectText);
OP (kStub190, stub190);
OP (kStub191, disableMouseAreas);
OP (kStub194, stub194);
Commit: f86cb6acd51e20ae35f29d0a736b773c0961b4e6
https://github.com/scummvm/scummvm/commit/f86cb6acd51e20ae35f29d0a736b773c0961b4e6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:59+01:00
Commit Message:
AGDS: added few character stubs
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index f7a5cc7be28..76b587d4590 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -102,14 +102,14 @@ enum Opcode {
kStub82 = 82,
kStub83 = 83,
kStub84 = 84,
- kStub85 = 85,
+ kLoadCharacter = 85,
kStub86 = 86,
kStub87 = 87,
kStub88 = 88,
kStub89 = 89,
- kStub90 = 90,
+ kShowCharacter = 90,
kStub91 = 91,
- kStub92 = 92,
+ kEnableCharacter = 92,
kStub93 = 93,
kLeaveCharacter = 94,
kStub95 = 95,
@@ -180,7 +180,7 @@ enum Opcode {
kStub160 = 160,
kStub161 = 161,
kDisableInventory = 162,
- kStub163 = 163,
+ kEnableInventory = 163,
kLoadPreviousScreen = 164,
kMoveScreenObject = 165,
kStub166 = 166,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 089ae53964d..d7d09f0c96d 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -99,12 +99,13 @@ private:
void enter(uint16 magic, uint16 size);
void exitProcess();
void exitProcessCreatePatch();
- void disableInventory();
void exitProcessSetNextScreen();
void exitProcessSetNextScreen80();
void loadPreviousScreen();
void call(uint16 addr);
+ void disableInventory();
+ void enableInventory();
void inventoryClear();
void inventoryAddObject();
void getMaxInventorySize();
@@ -146,6 +147,9 @@ private:
void setFontGlyphSize();
void getObjectPictureWidth();
void getObjectPictureHeight();
+ void loadCharacter();
+ void enableCharacter();
+ void showCharacter();
void fogOnCharacter();
void leaveCharacter();
void quit();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index ed4fa8c964e..a94b762c375 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -690,11 +690,14 @@ void Process::loadPreviousScreen() {
suspend(kExitCodeLoadPreviousScreenObject);
}
-void Process::disableInventory()
-{
+void Process::disableInventory() {
debug("disableInventory");
}
+void Process::enableInventory() {
+ debug("enableInventory");
+}
+
void Process::setScreenHeight() {
int height = pop();
debug("setScreenHeight %d", height);
@@ -760,6 +763,23 @@ void Process::addMouseArea() {
push(value);
}
+void Process::loadCharacter() {
+ Common::String arg3 = popString();
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("loadCharacter %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
+}
+
+void Process::enableCharacter() {
+ Common::String name = popString();
+ debug("enableCharacter %s", name.c_str());
+}
+
+void Process::showCharacter() {
+ Common::String name = popString();
+ debug("showCharacter %s", name.c_str());
+}
+
void Process::leaveCharacter() {
Common::String arg2 = popString();
Common::String arg1 = popString();
@@ -885,6 +905,8 @@ ProcessExitCode Process::execute() {
OP (kLoadRegionFromObject, loadRegionFromObject);
OP (kLoadPictureFromObject, loadPictureFromObject);
OP (kLoadAnimationFromObject, loadAnimationFromObject);
+ OP (kShowCharacter, showCharacter);
+ OP (kEnableCharacter, enableCharacter);
OP (kLeaveCharacter, leaveCharacter);
OP (kDisableUser, disableUser);
OP (kEnableUser, enableUser);
@@ -896,6 +918,7 @@ ProcessExitCode Process::execute() {
OP (kInventoryAddObject, inventoryAddObject);
OP (kExitProcessNextScreen80, exitProcessSetNextScreen80);
OP (kStub82, stub82);
+ OP (kLoadCharacter, loadCharacter);
OP (kSetScreenHeight, setScreenHeight);
OP (kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay);
OP (kLoadTextFromObject, loadTextFromObject);
@@ -942,6 +965,7 @@ ProcessExitCode Process::execute() {
OP (kQuit, quit);
OP (kExitProcessCreatePatch, exitProcessCreatePatch);
OP (kDisableInventory, disableInventory);
+ OP (kEnableInventory, enableInventory);
OP (kLoadPreviousScreen, loadPreviousScreen);
OP (kMoveScreenObject, moveScreenObject);
OP (kGetObjectId, getObjectId);
Commit: c5b0dcb203fc976b3ce33e663c8174a1ace67ade
https://github.com/scummvm/scummvm/commit/c5b0dcb203fc976b3ce33e663c8174a1ace67ade
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:57:59+01:00
Commit Message:
AGDS: fixed previous screen support, opcode 80 stores current screen name in history before load
Changed paths:
engines/agds/agds.cpp
engines/agds/opcode.h
engines/agds/process.h
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 080ccf8e8ed..e7c91888e58 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -146,9 +146,6 @@ void AGDSEngine::runObject(Object *object) {
void AGDSEngine::loadScreen(const Common::String & name) {
debug("loadScreen %s", name.c_str());
- Common::String currentScreenName;
- if (_currentScreen)
- currentScreenName = _currentScreen->getName();
ScreensType::iterator i = _screens.find(name);
Screen *screen;
@@ -159,7 +156,6 @@ void AGDSEngine::loadScreen(const Common::String & name) {
screen = i->_value;
_currentScreen = screen;
- _previousScreen = currentScreenName;
runObject(name);
}
@@ -178,15 +174,24 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
}
process.activate();
ProcessExitCode code = process.execute();
+ bool destroy = false;
switch(code) {
case kExitCodeLoadScreenObject:
case kExitCodeRunDialog:
runObject(process.getExitArg1(), process.getExitArg2());
break;
- case kExitCodeDestroyProcessSetNextScreen:
+ case kExitCodeSetNextScreen:
+ loadScreen(process.getExitArg1());
+ destroy = true;
+ break;
+ case kExitCodeSetNextScreenSaveInHistory:
+ if (_currentScreen)
+ _previousScreen = _currentScreen->getName();
loadScreen(process.getExitArg1());
+ destroy = true;
break;
case kExitCodeLoadPreviousScreenObject:
+ debug("previous screen: %s", _previousScreen.c_str());
loadScreen(_previousScreen);
break;
case kExitCodeMouseAreaChange:
@@ -201,13 +206,16 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
runObject(process.getExitArg1());
_inventory.clear();
runObject(process.getExitArg2());
- //deliberate fallthrough
+ destroy = true;
+ break;
default:
+ destroy = true;
+ }
+ if (destroy) {
debug("destroying process %s...", name.c_str());
it = _processes.erase(it);
- return;
- }
- ++it;
+ } else
+ ++it;
}
void AGDSEngine::runProcess() {
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 76b587d4590..5728ceb652f 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -97,8 +97,8 @@ enum Opcode {
kScreenLoadObject = 76,
kScreenCloneObject = 77,
kScreenRemoveObject = 78,
- kExitProcessSetNextScreen = 79,
- kExitProcessNextScreen80 = 80,
+ kSetNextScreen = 79,
+ kSetNextScreenSaveInHistory = 80,
kStub82 = 82,
kStub83 = 83,
kStub84 = 84,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index d7d09f0c96d..d67934c5452 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -99,8 +99,8 @@ private:
void enter(uint16 magic, uint16 size);
void exitProcess();
void exitProcessCreatePatch();
- void exitProcessSetNextScreen();
- void exitProcessSetNextScreen80();
+ void setNextScreen();
+ void setNextScreenSaveInHistory();
void loadPreviousScreen();
void call(uint16 addr);
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index 4f475f76ffa..2408420a152 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -28,7 +28,8 @@ namespace AGDS {
enum ProcessExitCode {
kExitCodeDestroy = 2,
kExitCodeSuspend = 5,
- kExitCodeDestroyProcessSetNextScreen = 6,
+ kExitCodeSetNextScreen = 6,
+ kExitCodeSetNextScreenSaveInHistory = 7,
kExitCodeLoadScreenObject = 8,
kExitCodeLoadInventoryObject = 10,
kExitCodeMouseAreaChange = 11,
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index a94b762c375..dc32f1bd91b 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -673,16 +673,16 @@ void Process::appendInventoryObjectNameToSharedSpace() {
push(_engine->appendToSharedStorage(object? object->getName(): Common::String()));
}
-void Process::exitProcessSetNextScreen() {
+void Process::setNextScreen() {
Common::String name = popString();
debug("exitProcessSetNextScreen %s", name.c_str());
- suspend(kExitCodeDestroyProcessSetNextScreen, name);
+ suspend(kExitCodeSetNextScreen, name);
}
-void Process::exitProcessSetNextScreen80() {
+void Process::setNextScreenSaveInHistory() {
Common::String name = popString();
- debug("exitProcessSetNextScreen80(code 7) %s", name.c_str());
- suspend(kExitCodeDestroyProcessSetNextScreen, name);
+ debug("setNextScreenSaveInHistory %s", name.c_str());
+ suspend(kExitCodeSetNextScreenSaveInHistory, name);
}
void Process::loadPreviousScreen() {
@@ -916,7 +916,7 @@ ProcessExitCode Process::execute() {
OP (kInventoryClear, inventoryClear);
OP (kLoadMouse, loadMouse);
OP (kInventoryAddObject, inventoryAddObject);
- OP (kExitProcessNextScreen80, exitProcessSetNextScreen80);
+ OP (kSetNextScreenSaveInHistory, setNextScreenSaveInHistory);
OP (kStub82, stub82);
OP (kLoadCharacter, loadCharacter);
OP (kSetScreenHeight, setScreenHeight);
@@ -926,7 +926,7 @@ ProcessExitCode Process::execute() {
OP (kScreenLoadObject, loadScreenObject);
OP (kScreenLoadRegion, loadScreenRegion);
OP (kScreenCloneObject, cloneObject);
- OP (kExitProcessSetNextScreen, exitProcessSetNextScreen);
+ OP (kSetNextScreen, setNextScreen);
OP (kScreenRemoveObject, removeScreenObject);
OP (kLoadAnimation, loadAnimation);
OP (kLoadSample, loadSample);
Commit: 2c1ad059cfcffc66fb7d5b6e828444259262918a
https://github.com/scummvm/scummvm/commit/2c1ad059cfcffc66fb7d5b6e828444259262918a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:00+01:00
Commit Message:
AGDS: added stub216
Changed paths:
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.h b/engines/agds/process.h
index d67934c5452..ed9dde51c32 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -217,6 +217,7 @@ private:
void stub200();
void stub209(unsigned size);
void stub215();
+ void stub216();
void stub217();
void stub221();
void stub223();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index dc32f1bd91b..72e627dde5a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -497,6 +497,13 @@ void Process::stub215() {
debug("stub215: sound group %d", id);
}
+void Process::stub216() {
+ int soundGroup = pop();
+ int frame = pop();
+ int id = pop();
+ debug("stub216: animation? id: %d, frame: %d, soundGroup: %d", id, frame, soundGroup);
+}
+
void Process::stub217() {
int soundGroup = pop();
int frame = pop();
@@ -985,6 +992,7 @@ ProcessExitCode Process::execute() {
OP (kSetSampleVolumeAndPan, setSampleVolumeAndPan);
OP (kPlaySound, playSound);
OP (kStub215, stub215);
+ OP (kStub216, stub216);
OP (kStub217, stub217);
OP (kStub221, stub221);
OP (kStub223, stub223);
Commit: 260657c9ff8bd0dd15180ba40edd123b744957d5
https://github.com/scummvm/scummvm/commit/260657c9ff8bd0dd15180ba40edd123b744957d5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:00+01:00
Commit Message:
AGDS: put runObject(string) to definition file
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index e7c91888e58..679f2a2f6fd 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -144,6 +144,11 @@ void AGDSEngine::runObject(Object *object) {
_currentScreen->add(object);
}
+void AGDSEngine::runObject(const Common::String & name, const Common::String &prototype)
+{
+ runObject(loadObject(name, prototype));
+}
+
void AGDSEngine::loadScreen(const Common::String & name) {
debug("loadScreen %s", name.c_str());
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index d73595f50ef..5bd793754fb 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -86,9 +86,7 @@ private:
public:
Object * loadObject(const Common::String & name, const Common::String & prototype = Common::String());
void runObject(Object *object);
-
- void runObject(const Common::String & name, const Common::String &prototype = Common::String())
- { runObject(loadObject(name, prototype)); }
+ void runObject(const Common::String & name, const Common::String &prototype = Common::String());
void loadScreen(const Common::String & name);
Commit: 612d77ca7c84f93fbef0fdfd68d4bdf117e00468
https://github.com/scummvm/scummvm/commit/612d77ca7c84f93fbef0fdfd68d4bdf117e00468
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:00+01:00
Commit Message:
AGDS: extra logs for getglobalimm8 instruction
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 72e627dde5a..c197e4d4cb0 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -220,7 +220,7 @@ void Process::resetPhaseVar() {
void Process::getGlobal(unsigned index) {
const Common::String & name = _object->getString(index).string;
int value = _engine->getGlobal(name);
- debug("get global %s -> %d", name.c_str(), value);
+ debug("get global %u %s -> %d", index, name.c_str(), value);
push(value);
}
Commit: b4d4cb90277b54ea883ba873858fe6275aa95c48
https://github.com/scummvm/scummvm/commit/b4d4cb90277b54ea883ba873858fe6275aa95c48
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:00+01:00
Commit Message:
AGDS: call onleave before destroying, check that current area is not in use
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 679f2a2f6fd..d320bee88cc 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -237,13 +237,16 @@ void AGDSEngine::changeMouseArea(int id, int enabled) {
mouseArea->enable();
break;
case 0:
+ case -1:
if (mouseArea->currentlyIn) {
runObject(mouseArea->onLeave);
}
mouseArea->disable();
- break;
- case -1:
- _mouseMap.remove(id);
+ if (_currentRegion == mouseArea)
+ _currentRegion = NULL;
+ if (enabled == -1) {
+ _mouseMap.remove(id);
+ }
break;
}
} else
Commit: d709366cea1fb1904e4dee2d53bf842753ba96ce
https://github.com/scummvm/scummvm/commit/d709366cea1fb1904e4dee2d53bf842753ba96ce
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:00+01:00
Commit Message:
AGDS: original engine uses intrusive list to accumulate mouse areas and then link them to newly loaded screen.
Changed paths:
engines/agds/agds.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index d320bee88cc..8e33542bfd6 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -152,13 +152,21 @@ void AGDSEngine::runObject(const Common::String & name, const Common::String &pr
void AGDSEngine::loadScreen(const Common::String & name) {
debug("loadScreen %s", name.c_str());
+ if (_currentRegion) {
+ if (_currentRegion->currentlyIn)
+ runObject(_currentRegion->onLeave);
+ _currentRegion = NULL;
+ }
+
ScreensType::iterator i = _screens.find(name);
Screen *screen;
if (i == _screens.end()) {
- screen = new Screen(loadObject(name));
+ screen = new Screen(loadObject(name), _mouseMap);
_screens[name] = screen;
- } else
+ } else {
screen = i->_value;
+ }
+ _mouseMap.clear();
_currentScreen = screen;
runObject(name);
@@ -242,8 +250,6 @@ void AGDSEngine::changeMouseArea(int id, int enabled) {
runObject(mouseArea->onLeave);
}
mouseArea->disable();
- if (_currentRegion == mouseArea)
- _currentRegion = NULL;
if (enabled == -1) {
_mouseMap.remove(id);
}
@@ -271,7 +277,8 @@ Common::Error AGDSEngine::run() {
case Common::EVENT_MOUSEMOVE:
_mouse = event.mouse;
if (_userEnabled && _currentScreen) {
- MouseRegion *region = _mouseMap.find(_mouse);
+ MouseMap &mouseMap = _currentScreen->mouseMap();
+ MouseRegion *region = mouseMap.find(_mouse);
if (region != _currentRegion) {
if (_currentRegion) {
MouseRegion *currentRegion = _currentRegion;
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index df1ee7f52db..381d0852369 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -26,7 +26,7 @@
namespace AGDS {
-Screen::Screen(Object *object) : _name(object->getName()) {
+Screen::Screen(Object *object, const MouseMap &mouseMap) : _name(object->getName()), _mouseMap(mouseMap) {
add(object);
}
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 2e5aaa5fca0..f154ba128b4 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -79,26 +79,32 @@ public:
_mouseRegions.back().id = _nextId++;
return _mouseRegions.back().id;
}
-// void clear() {
-// _mouseRegions.clear();
-// }
+ void clear() {
+ _mouseRegions.clear();
+ }
MouseRegion * find(Common::Point pos);
MouseRegion * find(int id);
void remove(int id);
};
class Screen {
- Common::String _name;
typedef Common::List<Object *> ChildrenType;
- ChildrenType _children;
+
+ Common::String _name;
+ ChildrenType _children;
+ MouseMap _mouseMap;
public:
- Screen(Object *object);
+ Screen(Object *object, const MouseMap &mouseMap);
const Common::String &getName() const {
return _name;
}
+ MouseMap & mouseMap() {
+ return _mouseMap;
+ }
+
void add(Object *object);
void remove(const Common::String &name);
void paint(Graphics::Surface &backbuffer);
Commit: f529e85415832499fd747ccb682cdcc928804326
https://github.com/scummvm/scummvm/commit/f529e85415832499fd747ccb682cdcc928804326
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:00+01:00
Commit Message:
AGDS: do not destroy process on resource initialisation, reworked destroy flag
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 8e33542bfd6..44478c11e11 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -189,6 +189,9 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
ProcessExitCode code = process.execute();
bool destroy = false;
switch(code) {
+ case kExitCodeDestroy:
+ destroy = true;
+ break;
case kExitCodeLoadScreenObject:
case kExitCodeRunDialog:
runObject(process.getExitArg1(), process.getExitArg2());
@@ -219,10 +222,9 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
runObject(process.getExitArg1());
_inventory.clear();
runObject(process.getExitArg2());
- destroy = true;
break;
default:
- destroy = true;
+ error("unknown process exit code %d", code);
}
if (destroy) {
debug("destroying process %s...", name.c_str());
Commit: ca09fc8213a841b24f80aac7b260c4b6ff961789
https://github.com/scummvm/scummvm/commit/ca09fc8213a841b24f80aac7b260c4b6ff961789
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:00+01:00
Commit Message:
AGDS: skip mouse area modification with negative index, it's intentional and present in original code
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 44478c11e11..2993ea21a6d 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -240,6 +240,8 @@ void AGDSEngine::runProcess() {
}
void AGDSEngine::changeMouseArea(int id, int enabled) {
+ if (id < 0)
+ return;
MouseRegion * mouseArea = _mouseMap.find(id);
if (mouseArea) {
switch(enabled) {
Commit: b664ca593b03287053a11467c6212e9a8d536be4
https://github.com/scummvm/scummvm/commit/b664ca593b03287053a11467c6212e9a8d536be4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:00+01:00
Commit Message:
AGDS: more stubs, first locations are clickable
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 5728ceb652f..f63c86c25ab 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -110,11 +110,11 @@ enum Opcode {
kShowCharacter = 90,
kStub91 = 91,
kEnableCharacter = 92,
- kStub93 = 93,
+ kMoveCharacter = 93,
kLeaveCharacter = 94,
- kStub95 = 95,
+ kSetCharacter = 95,
kStub96 = 96,
- kStub97 = 97,
+ kPointCharacter = 97,
kDisableUser = 98,
kEnableUser = 99,
kUpdatePhaseVarOr2 = 100,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index ed9dde51c32..b71ce3e420c 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -149,9 +149,12 @@ private:
void getObjectPictureHeight();
void loadCharacter();
void enableCharacter();
+ void moveCharacter();
void showCharacter();
void fogOnCharacter();
void leaveCharacter();
+ void setCharacter();
+ void pointCharacter();
void quit();
void setDialogForNextFilm();
@@ -195,9 +198,12 @@ private:
void stub128();
void stub129();
void stub130();
+ void stub131();
void stub133();
void stub134();
void stub136();
+ void stub137();
+ void stub138();
void stub152();
void stub153();
void stub154();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c197e4d4cb0..abbb4602813 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -374,12 +374,17 @@ void Process::stub128() {
void Process::stub129() {
int value = pop();
- debug("stub129 %d", value);
+ debug("stub129 %d animation duration?", value);
}
void Process::stub130() {
int value = pop();
- debug("stub130 %d", value);
+ debug("stub130 %d sample loops?", value);
+}
+
+void Process::stub131() {
+ int value = pop();
+ debug("stub130 %d random sample?", value);
}
void Process::stub133() {
int pan = pop();
@@ -394,7 +399,19 @@ void Process::stub134() {
}
void Process::stub136() {
- debug("stub136 sets value of stub130 to 1000000000");
+ debug("stub136 sets value of stub130 (loops?) to 1000000000");
+}
+
+void Process::stub137() {
+ int value = pop();
+ debug("stub137 %d", value);
+}
+
+void Process::stub138() {
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("stub138 %s %s", arg1.c_str(), arg2.c_str());
+ suspend(kExitCodeLoadScreenObject, arg2);
}
void Process::stub152() {
@@ -782,6 +799,14 @@ void Process::enableCharacter() {
debug("enableCharacter %s", name.c_str());
}
+void Process::moveCharacter() {
+ int arg3 = pop();
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("moveCharacter %s %s %d", arg1.c_str(), arg2.c_str(), arg3);
+ suspend();
+}
+
void Process::showCharacter() {
Common::String name = popString();
debug("showCharacter %s", name.c_str());
@@ -794,6 +819,19 @@ void Process::leaveCharacter() {
_engine->loadRegion(arg2);
}
+void Process::setCharacter() {
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("setCharacter %s %s", arg1.c_str(), arg2.c_str());
+}
+
+void Process::pointCharacter() {
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("pointCharacter %s %s", arg1.c_str(), arg2.c_str());
+ suspend();
+}
+
void Process::fogOnCharacter() {
int arg2 = pop();
int arg1 = pop();
@@ -914,7 +952,10 @@ ProcessExitCode Process::execute() {
OP (kLoadAnimationFromObject, loadAnimationFromObject);
OP (kShowCharacter, showCharacter);
OP (kEnableCharacter, enableCharacter);
+ OP (kMoveCharacter, moveCharacter);
OP (kLeaveCharacter, leaveCharacter);
+ OP (kSetCharacter, setCharacter);
+ OP (kPointCharacter, pointCharacter);
OP (kDisableUser, disableUser);
OP (kEnableUser, enableUser);
OP (kUpdatePhaseVarOr2, updatePhaseVarOr2);
@@ -944,10 +985,13 @@ ProcessExitCode Process::execute() {
OP (kProcessCleanupStub128, stub128);
OP (kStub129, stub129);
OP (kStub130, stub130);
+ OP (kStub131, stub131);
OP (kStub133, stub133);
OP (kStub134, stub134);
OP (kResetPhaseVar, resetPhaseVar);
OP (kStub136, stub136);
+ OP (kStub137, stub137);
+ OP (kStub138, stub138);
OP (kScreenChangeScreenPatch, changeScreenPatch);
OP (kGetFreeInventorySpace, getInventoryFreeSpace);
OP (kSetStringSystemVariable, setStringSystemVariable);
Commit: f0282f0a3dc2a5aeab20725f4712eba7e9ad6390
https://github.com/scummvm/scummvm/commit/f0282f0a3dc2a5aeab20725f4712eba7e9ad6390
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:00+01:00
Commit Message:
AGDS: removed screen storage, it's not needed
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 2993ea21a6d..07260405f8c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -48,6 +48,7 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
}
AGDSEngine::~AGDSEngine() {
+ delete _currentScreen;
}
bool AGDSEngine::initGraphics() {
@@ -158,17 +159,10 @@ void AGDSEngine::loadScreen(const Common::String & name) {
_currentRegion = NULL;
}
- ScreensType::iterator i = _screens.find(name);
- Screen *screen;
- if (i == _screens.end()) {
- screen = new Screen(loadObject(name), _mouseMap);
- _screens[name] = screen;
- } else {
- screen = i->_value;
- }
+ delete _currentScreen;
+ _currentScreen = new Screen(loadObject(name), _mouseMap);
_mouseMap.clear();
- _currentScreen = screen;
runObject(name);
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 5bd793754fb..549959a44ab 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -136,7 +136,6 @@ public:
private:
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
- typedef Common::HashMap<Common::String, Screen *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ScreensType;
typedef Common::HashMap<Common::String, Region *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> RegionsType;
typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
@@ -147,7 +146,6 @@ private:
SoundManager _soundManager;
Database _data, _patch; //data and patch databases
ObjectsType _objects;
- ScreensType _screens;
RegionsType _regions;
AnimationsType _animations;
ProcessListType _processes;
Commit: 8583ace52913aba8b7381c7422d7ae446af22c0c
https://github.com/scummvm/scummvm/commit/8583ace52913aba8b7381c7422d7ae446af22c0c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:00+01:00
Commit Message:
AGDS: added object animation support
Changed paths:
engines/agds/agds.cpp
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 07260405f8c..b2223d5800e 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -344,14 +344,14 @@ Common::Error AGDSEngine::run() {
_mjpgPlayer = NULL;
}
} else if (_currentScreen) {
- _currentScreen->paint(*backbuffer);
+ _currentScreen->paint(*this, *backbuffer);
}
if (!mouseCursor)
mouseCursor = _defaultMouseCursor;
if (_userEnabled && mouseCursor) {
- mouseCursor->paint(this, *backbuffer, _mouse);
+ mouseCursor->paint(*this, *backbuffer, _mouse);
}
_system->unlockScreen();
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 90cdbbcd9cc..ad363fb7faa 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -49,13 +49,13 @@ bool Animation::load(Common::SeekableReadStream* stream) {
}
-void Animation::paint(AGDSEngine *engine, Graphics::Surface & backbuffer, Common::Point dst) {
+void Animation::paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Common::Point dst) {
const Graphics::Surface * frame = _flic->decodeNextFrame();
if (!frame) {
_flic->rewind();
frame = _flic->decodeNextFrame();
}
- Graphics::TransparentSurface * c = engine->convertToTransparent(frame->convertTo(engine->pixelFormat(), _flic->getPalette()));
+ Graphics::TransparentSurface * c = engine.convertToTransparent(frame->convertTo(engine.pixelFormat(), _flic->getPalette()));
Common::Rect srcRect = c->getRect();
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
c->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 0259a9aeb24..8aeb6d5645f 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -43,7 +43,7 @@ public:
~Animation();
bool load(Common::SeekableReadStream *stream);
- void paint(AGDSEngine *engine, Graphics::Surface & backbuffer, Common::Point dst);
+ void paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Common::Point dst);
int width() const;
int height() const;
};
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 91570732e1e..1ea001bb78f 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -32,7 +32,8 @@ namespace AGDS {
Object::Object(const Common::String &name, Common::SeekableReadStream * stream) :
_name(name), _stringTableLoaded(false),
- _picture(), _region(), _mouseCursor(),
+ _picture(), _region(),
+ _animation(), _mouseCursor(),
_pos(), _alpha(255) {
byte id = stream->readByte();
byte flag = stream->readByte();
@@ -97,12 +98,7 @@ void Object::setPicture(Graphics::TransparentSurface *picture) {
_picture = picture;
}
-void Object::setMouseCursor(Animation *animation) {
- _mouseCursor = animation;
-}
-
-
-void Object::paint(Graphics::Surface &backbuffer) {
+void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
if (_picture) {
Common::Point dst = _pos;
Common::Rect srcRect = _picture->getRect();
@@ -110,6 +106,9 @@ void Object::paint(Graphics::Surface &backbuffer) {
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
_picture->blit(backbuffer, _pos.x, _pos.y, Graphics::FLIP_NONE, &srcRect, color);
}
+ if (_animation) {
+ _animation->paint(engine, backbuffer, _animationPos);
+ }
}
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 8e2425679c0..ef1d8db51ca 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -32,6 +32,7 @@ namespace Graphics { struct Surface; struct TransparentSurface; }
namespace AGDS {
+class AGDSEngine;
struct Region;
class Animation;
@@ -57,8 +58,9 @@ private:
bool _stringTableLoaded;
Graphics::TransparentSurface * _picture;
Region * _region;
+ Animation * _animation;
Animation * _mouseCursor;
- Common::Point _pos;
+ Common::Point _pos, _animationPos;
uint _clickHandler;
int _alpha;
@@ -77,7 +79,21 @@ public:
return _code;
}
- void setMouseCursor(Animation *animation);
+ void setAnimation(Animation *animation) {
+ _animation = animation;
+ }
+
+ Animation *getAnimation() const {
+ return _animation;
+ }
+
+ void setAnimationPosition(Common::Point animationPos) {
+ _animationPos = animationPos;
+ }
+
+ void setMouseCursor(Animation *mouseCursor) {
+ _mouseCursor = mouseCursor;
+ }
Animation *getMouseCursor() const {
return _mouseCursor;
}
@@ -111,7 +127,7 @@ public:
return _clickHandler;
}
- void paint(Graphics::Surface &backbuffer);
+ void paint(AGDSEngine &engine, Graphics::Surface &backbuffer);
void move(Common::Point pos) {
_pos = pos;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index f63c86c25ab..81664d6b2c7 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -151,7 +151,7 @@ enum Opcode {
kStub131 = 131,
kStub132 = 132,
kStub133 = 133,
- kStub134 = 134,
+ kSetAnimationPosition = 134,
kResetPhaseVar = 135,
kStub136 = 136,
kStub137 = 137,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index b71ce3e420c..a3b7e3392c4 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -131,6 +131,7 @@ private:
void loadAnimationFromObject();
void loadTextFromObject();
void loadAnimation();
+ void setAnimationPosition();
void loadSample();
void playSound();
void playFilm();
@@ -161,6 +162,7 @@ private:
void npcSay();
void playerSay();
void runDialog();
+ void setObjectText();
void getRandomNumber();
void setStringSystemVariable();
@@ -200,7 +202,6 @@ private:
void stub130();
void stub131();
void stub133();
- void stub134();
void stub136();
void stub137();
void stub138();
@@ -214,7 +215,6 @@ private:
void stub174();
void stub176();
void stub184();
- void setObjectText();
void stub190();
void stub192();
void stub194();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index abbb4602813..80d8fad680a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -112,6 +112,7 @@ void Process::loadPicture() {
void Process::loadAnimation() {
Common::String name = popText();
debug("loadAnimation %s", name.c_str());
+ _object->setAnimation(_engine->loadAnimation(name));
}
void Process::loadSample() {
@@ -392,12 +393,6 @@ void Process::stub133() {
debug("stub133: pan? %d volume? %d", pan, volume);
}
-void Process::stub134() {
- int arg2 = pop();
- int arg1 = pop();
- debug("stub134, font related %d %d", arg1, arg2);
-}
-
void Process::stub136() {
debug("stub136 sets value of stub130 (loops?) to 1000000000");
}
@@ -857,6 +852,13 @@ void Process::loadAnimationFromObject() {
debug("loadAnimationFromObject %s", name.c_str());
}
+void Process::setAnimationPosition() {
+ int arg2 = pop();
+ int arg1 = pop();
+ debug("setAnimationPosition %d %d", arg1, arg2);
+ _object->setAnimationPosition(Common::Point(arg1, arg2));
+}
+
void Process::setTimer() {
int value = pop();
debug("setTimer %d", value);
@@ -987,7 +989,7 @@ ProcessExitCode Process::execute() {
OP (kStub130, stub130);
OP (kStub131, stub131);
OP (kStub133, stub133);
- OP (kStub134, stub134);
+ OP (kSetAnimationPosition, setAnimationPosition);
OP (kResetPhaseVar, resetPhaseVar);
OP (kStub136, stub136);
OP (kStub137, stub137);
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 381d0852369..1801f1e8dc2 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -48,10 +48,10 @@ void Screen::remove(const Common::String &name) {
}
-void Screen::paint(Graphics::Surface &backbuffer) {
+void Screen::paint(AGDSEngine & engine, Graphics::Surface & backbuffer) {
for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
Object *object = *i;
- object->paint(backbuffer);
+ object->paint(engine, backbuffer);
}
}
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index f154ba128b4..9994cceb4ae 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -34,6 +34,7 @@ namespace Graphics {
namespace AGDS {
+class AGDSEngine;
class Object;
struct Region;
@@ -106,8 +107,8 @@ public:
}
void add(Object *object);
- void remove(const Common::String &name);
- void paint(Graphics::Surface &backbuffer);
+ void remove(const Common::String & name);
+ void paint(AGDSEngine & engine, Graphics::Surface & backbuffer);
Object *find(Common::Point pos) const;
};
Commit: f46667b67e6ac8b9a09b0f726822f398307d345a
https://github.com/scummvm/scummvm/commit/f46667b67e6ac8b9a09b0f726822f398307d345a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:01+01:00
Commit Message:
AGDS: fixed previous screen name, and do not compare screen pointers, as they may differ
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index b2223d5800e..fbc6b05d331 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -41,14 +41,15 @@ namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Engine(system),
_gameDescription(gameDesc), _sharedStorageIndex(-2), _timer(0),
- _mjpgPlayer(NULL), _currentScreen(NULL),
- _defaultMouseCursor(NULL),
- _mouse(400, 300), _userEnabled(false), _currentRegion(NULL),
+ _mjpgPlayer(), _currentScreen(), _previousScreen(),
+ _defaultMouseCursor(),
+ _mouse(400, 300), _userEnabled(false), _currentRegion(),
_random("agds"), _soundManager(this, system->getMixer()) {
}
AGDSEngine::~AGDSEngine() {
delete _currentScreen;
+ delete _previousScreen;
}
bool AGDSEngine::initGraphics() {
@@ -152,7 +153,26 @@ void AGDSEngine::runObject(const Common::String & name, const Common::String &pr
void AGDSEngine::loadScreen(const Common::String & name) {
debug("loadScreen %s", name.c_str());
+ resetCurrentScreen();
+ _currentScreenName = name;
+ _currentScreen = new Screen(loadObject(name), _mouseMap);
+ _mouseMap.clear();
+ runObject(name); //is it called once or per screen activation?
+}
+
+void AGDSEngine::setCurrentScreen(Screen *screen) {
+ if (!screen)
+ error("no previous screen");
+
+ resetCurrentScreen();
+
+ _currentScreenName = screen->getName();
+ _currentScreen = screen;
+ _previousScreen = NULL;
+}
+void AGDSEngine::resetCurrentScreen()
+{
if (_currentRegion) {
if (_currentRegion->currentlyIn)
runObject(_currentRegion->onLeave);
@@ -160,15 +180,13 @@ void AGDSEngine::loadScreen(const Common::String & name) {
}
delete _currentScreen;
- _currentScreen = new Screen(loadObject(name), _mouseMap);
- _mouseMap.clear();
-
- runObject(name);
+ _currentScreen = NULL;
}
+
void AGDSEngine::runProcess(ProcessListType::iterator &it) {
Process & process = *it;
- if (process.parentScreen() != currentScreen()) {
+ if (process.parentScreenName() != _currentScreenName) {
++it;
return;
}
@@ -195,14 +213,16 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
destroy = true;
break;
case kExitCodeSetNextScreenSaveInHistory:
- if (_currentScreen)
- _previousScreen = _currentScreen->getName();
+ if (_currentScreen) {
+ delete _previousScreen;
+ _previousScreen = _currentScreen;
+ _currentScreen = NULL;
+ }
loadScreen(process.getExitArg1());
destroy = true;
break;
case kExitCodeLoadPreviousScreenObject:
- debug("previous screen: %s", _previousScreen.c_str());
- loadScreen(_previousScreen);
+ setCurrentScreen(_previousScreen);
break;
case kExitCodeMouseAreaChange:
changeMouseArea(process.getExitIntArg1(), process.getExitIntArg2());
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 549959a44ab..2054100c759 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -88,7 +88,9 @@ public:
void runObject(Object *object);
void runObject(const Common::String & name, const Common::String &prototype = Common::String());
+ void resetCurrentScreen();
void loadScreen(const Common::String & name);
+ void setCurrentScreen(Screen *screen);
Region * loadRegion(const Common::String &name);
Common::String loadText(const Common::String &name);
@@ -111,10 +113,14 @@ public:
return _inventory;
}
- Screen *currentScreen() {
+ Screen * getCurrentScreen() {
return _currentScreen;
}
+ Common::String & getCurrentScreenName() {
+ return _currentScreenName;
+ }
+
const Graphics::PixelFormat & pixelFormat() const {
return _pixelFormat;
}
@@ -157,7 +163,8 @@ private:
Graphics::PixelFormat _pixelFormat;
MJPGPlayer * _mjpgPlayer;
Screen * _currentScreen;
- Common::String _previousScreen;
+ Common::String _currentScreenName;
+ Screen * _previousScreen;
Animation * _defaultMouseCursor;
Common::Point _mouse;
MouseRegion * _currentRegion;
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index d003e7d395d..204db56b4bc 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -28,10 +28,8 @@
namespace AGDS {
Process::Process(AGDSEngine *engine, Object* object, unsigned ip) :
- _engine(engine), _parentScreen(engine->currentScreen()), _object(object), _ip(ip), _status(kStatusActive), _exitCode(kExitCodeDestroy),
+ _engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object), _ip(ip), _status(kStatusActive), _exitCode(kExitCodeDestroy),
_glyphWidth(16), _glyphHeight(16) {
- if (!_parentScreen)
- error("no parent screen");
}
void Process::debug(const char *str, ...) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index a3b7e3392c4..251ed5b14fe 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -42,7 +42,7 @@ private:
typedef Common::Stack<int32> StackType;
AGDSEngine * _engine;
- Screen * _parentScreen;
+ Common::String _parentScreen;
Object * _object;
StackType _stack;
unsigned _ip, _lastIp;
@@ -284,7 +284,7 @@ public:
return _object->getName();
}
- Screen *parentScreen() const {
+ const Common::String & parentScreenName() const {
return _parentScreen;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 80d8fad680a..02612722f54 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -167,7 +167,7 @@ void Process::loadScreenObject() {
void Process::loadScreenRegion() {
Common::String name = popString();
debug("loadScreenRegion %s", name.c_str());
- _engine->loadObject(_engine->currentScreen()->getName())->setRegion(_engine->loadRegion(name));
+ _engine->loadObject(_engine->getCurrentScreenName())->setRegion(_engine->loadRegion(name));
}
void Process::cloneObject() {
@@ -180,7 +180,7 @@ void Process::cloneObject() {
void Process::removeScreenObject() {
Common::String name = popString();
debug("removeScreenObject: %s", name.c_str());
- Screen *screen = _engine->currentScreen();
+ Screen *screen = _engine->getCurrentScreen();
if (screen)
screen->remove(name);
}
Commit: 0471073d50164374dc873ac87f7d4d246f179647
https://github.com/scummvm/scummvm/commit/0471073d50164374dc873ac87f7d4d246f179647
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:01+01:00
Commit Message:
AGDS: added stub83
Changed paths:
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 251ed5b14fe..8fd789aaac4 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -196,6 +196,7 @@ private:
void stub63(unsigned size);
void stub74();
void stub82();
+ void stub83();
void stub119();
void stub128();
void stub129();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 02612722f54..3f7040c999e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -364,6 +364,12 @@ void Process::stub82() {
debug("stub82: %s %s", arg1.c_str(), arg2.c_str());
}
+void Process::stub83() {
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("stub83: %s %s", arg1.c_str(), arg2.c_str());
+}
+
void Process::stub119() {
debug("stub119");
}
@@ -968,6 +974,7 @@ ProcessExitCode Process::execute() {
OP (kInventoryAddObject, inventoryAddObject);
OP (kSetNextScreenSaveInHistory, setNextScreenSaveInHistory);
OP (kStub82, stub82);
+ OP (kStub83, stub83);
OP (kLoadCharacter, loadCharacter);
OP (kSetScreenHeight, setScreenHeight);
OP (kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay);
Commit: 014226c2fdc4024c95feebb6675d2056a893063f
https://github.com/scummvm/scummvm/commit/014226c2fdc4024c95feebb6675d2056a893063f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:01+01:00
Commit Message:
AGDS: added key handling support
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/object.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index fbc6b05d331..67e9886bca2 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -44,7 +44,8 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_mjpgPlayer(), _currentScreen(), _previousScreen(),
_defaultMouseCursor(),
_mouse(400, 300), _userEnabled(false), _currentRegion(),
- _random("agds"), _soundManager(this, system->getMixer()) {
+ _random("agds"), _soundManager(this, system->getMixer()),
+ _fastMode(false) {
}
AGDSEngine::~AGDSEngine() {
@@ -139,13 +140,17 @@ Object *AGDSEngine::loadObject(const Common::String & name, const Common::String
}
void AGDSEngine::runObject(Object *object) {
- _processes.push_back(Process(this, object));
- ProcessListType::iterator it = _processes.reverse_begin();
- runProcess(it);
+ runProcess(object);
if (_currentScreen)
_currentScreen->add(object);
}
+void AGDSEngine::runProcess(Object *object, uint ip) {
+ _processes.push_back(Process(this, object, ip));
+ ProcessListType::iterator it = _processes.reverse_begin();
+ runProcess(it);
+}
+
void AGDSEngine::runObject(const Common::String & name, const Common::String &prototype)
{
runObject(loadObject(name, prototype));
@@ -291,10 +296,40 @@ Common::Error AGDSEngine::run() {
Common::Event event;
while(eventManager->pollEvent(event)) {
+ if (!_currentScreen)
+ continue;
+
switch(event.type) {
+ case Common::EVENT_KEYDOWN:
+ {
+ Common::String key;
+
+ switch(event.kbd.keycode) {
+ case Common::KEYCODE_SPACE:
+ key = "space";
+ break;
+ case Common::KEYCODE_ESCAPE:
+ key = "escape";
+ break;
+ case Common::KEYCODE_TAB:
+ key = "tab";
+ break;
+ default:
+ if (event.kbd.ascii)
+ key = Common::String(static_cast<char>(event.kbd.ascii));
+ };
+ if (!key.empty()) {
+ Screen::KeyHandler handler = _currentScreen->findKeyHandler(key);
+ if (handler.object) {
+ debug("found handler for key %s: %s %08x", key.c_str(), handler.object->getName().c_str(), handler.ip + 7);
+ runProcess(handler.object, handler.ip);
+ }
+ }
+ }
+ break;
case Common::EVENT_MOUSEMOVE:
_mouse = event.mouse;
- if (_userEnabled && _currentScreen) {
+ if (_userEnabled) {
MouseMap &mouseMap = _currentScreen->mouseMap();
MouseRegion *region = mouseMap.find(_mouse);
if (region != _currentRegion) {
@@ -314,14 +349,14 @@ Common::Error AGDSEngine::run() {
break;
case Common::EVENT_LBUTTONDOWN:
_mouse = event.mouse;
- if (_userEnabled && _currentScreen) {
+ if (_userEnabled) {
debug("lclick %d, %d", _mouse.x, _mouse.y);
Object *object = _currentScreen->find(_mouse);
if (object) {
uint ip = object->getClickHandler();
if (ip) {
debug("found handler: %s %08x", object->getName().c_str(), ip + 7);
- _processes.push_front(Process(this, object, ip));
+ runProcess(object, ip);
}
}
}
@@ -377,12 +412,14 @@ Common::Error AGDSEngine::run() {
_system->unlockScreen();
_system->updateScreen();
- static const uint32 kFPS = 25;
- static const uint32 kMaxTick = 1000 / kFPS;
+ if (!_fastMode) {
+ static const uint32 kFPS = 25;
+ static const uint32 kMaxTick = 1000 / kFPS;
- uint32 dt = _system->getMillis() - frameStarted;
- if (dt < kMaxTick)
- _system->delayMillis(kMaxTick - dt);
+ uint32 dt = _system->getMillis() - frameStarted;
+ if (dt < kMaxTick)
+ _system->delayMillis(kMaxTick - dt);
+ }
}
return Common::kNoError;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 2054100c759..16065dbdbdb 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -87,6 +87,7 @@ public:
Object * loadObject(const Common::String & name, const Common::String & prototype = Common::String());
void runObject(Object *object);
void runObject(const Common::String & name, const Common::String &prototype = Common::String());
+ void runProcess(Object *object, uint ip = 0);
void resetCurrentScreen();
void loadScreen(const Common::String & name);
@@ -172,6 +173,7 @@ private:
MouseMap _mouseMap;
Common::RandomSource _random;
Inventory _inventory;
+ bool _fastMode;
};
diff --git a/engines/agds/object.h b/engines/agds/object.h
index ef1d8db51ca..bebf0ea14cf 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -25,6 +25,8 @@
#include "common/scummsys.h"
#include "common/array.h"
+#include "common/hash-str.h"
+#include "common/hashmap.h"
#include "common/rect.h"
#include "common/stream.h"
@@ -51,11 +53,13 @@ public:
private:
typedef Common::Array<StringEntry> StringTableType;
+ typedef Common::HashMap<Common::String, uint, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> KeyHandlersType;
Common::String _name;
CodeType _code;
StringTableType _stringTable;
bool _stringTableLoaded;
+ KeyHandlersType _keyHandlers;
Graphics::TransparentSurface * _picture;
Region * _region;
Animation * _animation;
@@ -133,11 +137,17 @@ public:
_pos = pos;
}
- int getX() const {
- return _pos.x;
+ Common::Point getPosition() const {
+ return _pos;
}
- int getY() const {
- return _pos.y;
+
+ void setKeyHandler(const Common::String &name, uint ip) {
+ _keyHandlers[name] = ip;
+ }
+
+ uint getKeyHandler(const Common::String &name) const {
+ KeyHandlersType::const_iterator i = _keyHandlers.find(name);
+ return i != _keyHandlers.end()? i->_value: 0;
}
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3f7040c999e..ea014884ad6 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -750,6 +750,7 @@ void Process::call(uint16 addr) {
void Process::onKey(unsigned size) {
Common::String key = popString();
debug("onKey %s [handler], %u instructions", key.c_str(), size);
+ _object->setKeyHandler(key, _ip);
_ip += size;
}
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 1801f1e8dc2..72ae1e0292a 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -65,6 +65,21 @@ Object *Screen::find(Common::Point pos) const {
return NULL;
}
+Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
+ KeyHandler keyHandler;
+ for(ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
+ Object *object = *i;
+ uint ip = object->getKeyHandler(keyName);
+ if (ip) {
+ keyHandler.ip = ip;
+ keyHandler.object = object;
+ break;
+ }
+ }
+ return keyHandler;
+
+}
+
MouseRegion * MouseMap::find(Common::Point pos) {
if (_disabled)
return NULL;
@@ -95,7 +110,4 @@ void MouseMap::remove(int id) {
}
}
-
-
-
}
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 9994cceb4ae..f184ce01300 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -96,6 +96,14 @@ class Screen {
MouseMap _mouseMap;
public:
+ struct KeyHandler {
+ Object * object;
+ uint ip;
+
+ KeyHandler(): object(), ip() { }
+ KeyHandler(Object *o, uint i): object(o), ip(i) { }
+ };
+
Screen(Object *object, const MouseMap &mouseMap);
const Common::String &getName() const {
@@ -110,6 +118,7 @@ public:
void remove(const Common::String & name);
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer);
Object *find(Common::Point pos) const;
+ KeyHandler findKeyHandler(const Common::String &keyName);
};
Commit: ab76a35cd777f361cb68bf9f11789398fb745e59
https://github.com/scummvm/scummvm/commit/ab76a35cd777f361cb68bf9f11789398fb745e59
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:01+01:00
Commit Message:
AGDS: added skipFilm by space/escape key
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 67e9886bca2..d3696c757fa 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -306,9 +306,11 @@ Common::Error AGDSEngine::run() {
switch(event.kbd.keycode) {
case Common::KEYCODE_SPACE:
+ skipFilm();
key = "space";
break;
case Common::KEYCODE_ESCAPE:
+ skipFilm();
key = "escape";
break;
case Common::KEYCODE_TAB:
@@ -430,6 +432,10 @@ void AGDSEngine::playFilm(const Common::String &video, const Common::String &aud
_mjpgPlayer = new MJPGPlayer(_resourceManager.getResource(video));
}
+void AGDSEngine::skipFilm() {
+ delete _mjpgPlayer;
+ _mjpgPlayer = NULL;
+}
int AGDSEngine::appendToSharedStorage(const Common::String &value) {
int index = _sharedStorageIndex;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 16065dbdbdb..6d893df3371 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -105,6 +105,7 @@ public:
bool active() const { return _timer <= 0 && !_mjpgPlayer; }
void playFilm(const Common::String &video, const Common::String &audio);
+ void skipFilm();
ResourceManager & resourceManager() {
return _resourceManager;
Commit: 2cf522a3a7ee1b0ede7000c37fd15a4c52cefc39
https://github.com/scummvm/scummvm/commit/2cf522a3a7ee1b0ede7000c37fd15a4c52cefc39
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:01+01:00
Commit Message:
AGDS: added fastmode hotkey (ctrl-f)
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index d3696c757fa..6cf9b8b13ed 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -316,6 +316,11 @@ Common::Error AGDSEngine::run() {
case Common::KEYCODE_TAB:
key = "tab";
break;
+ case Common::KEYCODE_f:
+ if (event.kbd.flags & Common::KBD_CTRL) {
+ _fastMode = !_fastMode;
+ break;
+ }
default:
if (event.kbd.ascii)
key = Common::String(static_cast<char>(event.kbd.ascii));
Commit: ede26f4c2eb5704caedf0fc726ebefdaf79157d2
https://github.com/scummvm/scummvm/commit/ede26f4c2eb5704caedf0fc726ebefdaf79157d2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:01+01:00
Commit Message:
AGDS: reverted old behaviour, new process spawns first (engine uses single global current_pid)
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 6cf9b8b13ed..9b85b00e047 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -146,8 +146,8 @@ void AGDSEngine::runObject(Object *object) {
}
void AGDSEngine::runProcess(Object *object, uint ip) {
- _processes.push_back(Process(this, object, ip));
- ProcessListType::iterator it = _processes.reverse_begin();
+ _processes.push_front(Process(this, object, ip));
+ ProcessListType::iterator it = _processes.begin();
runProcess(it);
}
Commit: a9be4fb59164c5b26265ec5ed590fb1ad0a4057b
https://github.com/scummvm/scummvm/commit/a9be4fb59164c5b26265ec5ed590fb1ad0a4057b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:01+01:00
Commit Message:
AGDS: do not process key handlers if user flag is disabled
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 9b85b00e047..75d119d527b 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -325,7 +325,7 @@ Common::Error AGDSEngine::run() {
if (event.kbd.ascii)
key = Common::String(static_cast<char>(event.kbd.ascii));
};
- if (!key.empty()) {
+ if (_userEnabled && !key.empty()) {
Screen::KeyHandler handler = _currentScreen->findKeyHandler(key);
if (handler.object) {
debug("found handler for key %s: %s %08x", key.c_str(), handler.object->getName().c_str(), handler.ip + 7);
Commit: fdca7c11351a84eace020c684e68c317e0dbb449
https://github.com/scummvm/scummvm/commit/fdca7c11351a84eace020c684e68c317e0dbb449
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:01+01:00
Commit Message:
AGDS: implemented loadPicture and picture cache
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 75d119d527b..0d323adf221 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -40,7 +40,7 @@
namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Engine(system),
- _gameDescription(gameDesc), _sharedStorageIndex(-2), _timer(0),
+ _gameDescription(gameDesc), _pictureCacheId(0), _sharedStorageIndex(-2), _timer(0),
_mjpgPlayer(), _currentScreen(), _previousScreen(),
_defaultMouseCursor(),
_mouse(400, 300), _userEnabled(false), _currentRegion(),
@@ -485,6 +485,11 @@ Animation * AGDSEngine::loadAnimation(const Common::String &name) {
Graphics::TransparentSurface * AGDSEngine::loadPicture(const Common::String &name)
{ return convertToTransparent(_resourceManager.loadPicture(name, _pixelFormat)); }
+Graphics::TransparentSurface *AGDSEngine::loadFromCache(int id) const {
+ PictureCacheType::const_iterator i = _pictureCache.find(id);
+ return (i != _pictureCache.end())? i->_value: NULL;
+}
+
Graphics::TransparentSurface *AGDSEngine::convertToTransparent(const Graphics::Surface *surface) {
if (!surface)
return NULL;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 6d893df3371..1a0c9c441a6 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -129,6 +129,14 @@ public:
Graphics::TransparentSurface *loadPicture(const Common::String &name);
Graphics::TransparentSurface *convertToTransparent(const Graphics::Surface *surface); //destroys surface!
+ Graphics::TransparentSurface *loadFromCache(int id) const;
+ int saveToCache(Graphics::TransparentSurface *surface) {
+ if (!surface)
+ return -1;
+ int id = _pictureCacheId++;
+ _pictureCache[id] = surface;
+ return id;
+ }
Animation * loadAnimation(const Common::String &name);
void loadDefaultMouseCursor(const Common::String &name) {
@@ -143,6 +151,7 @@ public:
SystemVariable *getSystemVariable(const Common::String &name);
private:
+ typedef Common::HashMap<int, Graphics::TransparentSurface *> PictureCacheType;
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
typedef Common::HashMap<Common::String, Region *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> RegionsType;
typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
@@ -153,6 +162,8 @@ private:
ResourceManager _resourceManager;
SoundManager _soundManager;
Database _data, _patch; //data and patch databases
+ PictureCacheType _pictureCache;
+ int _pictureCacheId;
ObjectsType _objects;
RegionsType _regions;
AnimationsType _animations;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index ea014884ad6..dba92b7f8b5 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -105,8 +105,9 @@ void Process::getObjectId() {
void Process::loadPicture() {
Common::String name = popText();
- debug("loadPicture stub %s", name.c_str());
- push(100500); //dummy
+ int value = _engine->saveToCache(_engine->loadPicture(name));
+ debug("loadPicture %s -> %d", name.c_str(), value);
+ push(value);
}
void Process::loadAnimation() {
Commit: 5cb9d608d1abbcb21133820c1d4f46d526348e0e
https://github.com/scummvm/scummvm/commit/5cb9d608d1abbcb21133820c1d4f46d526348e0e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:01+01:00
Commit Message:
AGDS: store text assosiated with the object as member
Changed paths:
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.h b/engines/agds/object.h
index bebf0ea14cf..537277c9e03 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -65,6 +65,7 @@ private:
Animation * _animation;
Animation * _mouseCursor;
Common::Point _pos, _animationPos;
+ Common::String _text;
uint _clickHandler;
int _alpha;
@@ -137,6 +138,14 @@ public:
_pos = pos;
}
+ const Common::String & getText() const {
+ return _text;
+ }
+
+ void setText(const Common::String &text) {
+ _text = text;
+ }
+
Common::Point getPosition() const {
return _pos;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index dba92b7f8b5..fb9f1bc0394 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -736,6 +736,7 @@ void Process::updateScreenHeightToDisplay() {
void Process::loadTextFromObject() {
Common::String text = popText();
debug("loadTextFromObject %s", text.c_str());
+ _object->setText(text);
}
void Process::call(uint16 addr) {
Commit: e275b269274de8ce1a19847186abefee1008101a
https://github.com/scummvm/scummvm/commit/e275b269274de8ce1a19847186abefee1008101a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:01+01:00
Commit Message:
AGDS: added setObjectText implementation
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index fb9f1bc0394..d03fb3af032 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -565,10 +565,10 @@ void Process::stub184() {
void Process::setObjectText() {
int arg3 = pop();
- Common::String arg2 = popText();
- Common::String arg1 = popString();
- debug("setObjectText %s \"%s\" %d", arg1.c_str(), arg2.c_str(), arg3);
- //_engine->loadObject(arg1);
+ Common::String text = popText();
+ Common::String name = popString();
+ debug("setObjectText %s \"%s\" %d", name.c_str(), text.c_str(), arg3);
+ _engine->loadObject(name)->setText(text);
}
Commit: 951f66628ab394b9c0a914faf53f24e82b62209a
https://github.com/scummvm/scummvm/commit/951f66628ab394b9c0a914faf53f24e82b62209a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:02+01:00
Commit Message:
AGDS: added preliminary text rendering support and Font class
Changed paths:
A engines/agds/font.cpp
A engines/agds/font.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/module.mk
engines/agds/object.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 0d323adf221..d529684e5f0 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -22,6 +22,7 @@
#include "agds/agds.h"
#include "agds/animation.h"
+#include "agds/font.h"
#include "agds/mjpgPlayer.h"
#include "agds/object.h"
#include "agds/process.h"
@@ -490,6 +491,21 @@ Graphics::TransparentSurface *AGDSEngine::loadFromCache(int id) const {
return (i != _pictureCache.end())? i->_value: NULL;
}
+void AGDSEngine::loadFont(int id, const Common::String &name, int gw, int gh) {
+ debug("loadFont %d %s %d %d", id, name.c_str(), gw, gh);
+ Graphics::TransparentSurface *surface = loadPicture(name);
+ Font * & font = _fonts[id];
+ delete font;
+ font = new Font(surface, gw, gh);
+}
+
+Font *AGDSEngine::getFont(int id) const {
+ FontsType::const_iterator i = _fonts.find(id);
+ if (i == _fonts.end())
+ error("no font with id %d", id);
+ return i->_value;
+}
+
Graphics::TransparentSurface *AGDSEngine::convertToTransparent(const Graphics::Surface *surface) {
if (!surface)
return NULL;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 1a0c9c441a6..cc4d0f7ea33 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -51,6 +51,7 @@ namespace Graphics { struct TransparentSurface; }
namespace AGDS {
class Animation;
+class Font;
class Object;
class Process;
struct Region;
@@ -138,6 +139,9 @@ public:
return id;
}
+ void loadFont(int id, const Common::String &name, int gw, int gh);
+ Font *getFont(int id) const;
+
Animation * loadAnimation(const Common::String &name);
void loadDefaultMouseCursor(const Common::String &name) {
_defaultMouseCursor = loadAnimation(name);
@@ -157,6 +161,7 @@ private:
typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
typedef Common::HashMap<Common::String, Animation *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> AnimationsType;
+ typedef Common::HashMap<int, Font *> FontsType;
const ADGameDescription * _gameDescription;
ResourceManager _resourceManager;
@@ -164,6 +169,7 @@ private:
Database _data, _patch; //data and patch databases
PictureCacheType _pictureCache;
int _pictureCacheId;
+ FontsType _fonts;
ObjectsType _objects;
RegionsType _regions;
AnimationsType _animations;
diff --git a/engines/agds/font.cpp b/engines/agds/font.cpp
new file mode 100644
index 00000000000..16c88d1e5c4
--- /dev/null
+++ b/engines/agds/font.cpp
@@ -0,0 +1,18 @@
+#include "agds/font.h"
+#include "graphics/transparent_surface.h"
+
+namespace AGDS {
+
+Font::Font(Graphics::TransparentSurface *surface, int gw, int gh): _surface(surface), _gw(gw), _gh(gh) {
+}
+
+void Font::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const {
+ if (chr >= 0x100)
+ return;
+
+ Common::Rect srcRect(_gw, _gh);
+ srcRect.moveTo(_surface->w / 16 * (chr & 0x0f), _surface->h / 16 * (chr >> 4));
+ _surface->blit(*dst, x, y, Graphics::FLIP_NONE, &srcRect);
+}
+
+}
diff --git a/engines/agds/font.h b/engines/agds/font.h
new file mode 100644
index 00000000000..9fc5bdf6614
--- /dev/null
+++ b/engines/agds/font.h
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_FONT_H
+#define AGDS_FONT_H
+
+#include "graphics/font.h"
+
+namespace Graphics {
+ struct TransparentSurface;
+}
+
+namespace AGDS {
+
+class Font : public Graphics::Font {
+ Graphics::TransparentSurface * _surface;
+ int _gw, _gh;
+
+public:
+ Font(Graphics::TransparentSurface *surface, int gw, int gh);
+
+ virtual int getFontHeight() const {
+ return _gh;
+ }
+
+ virtual int getMaxCharWidth() const {
+ return _gw;
+ }
+
+ virtual int getCharWidth(uint32 chr) const {
+ return _gw;
+ }
+
+ virtual void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const;
+
+};
+
+} // End of namespace AGDS
+
+#endif /* AGDS_FONT_H */
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index 79144fbd07e..30cdd0b192f 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS := \
animation.o \
database.o \
detection.o \
+ font.o \
inventory.o \
mjpgPlayer.o \
object.o \
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 1ea001bb78f..d9fb2083064 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -21,6 +21,8 @@
*/
#include "agds/object.h"
+#include "agds/agds.h"
+#include "agds/font.h"
#include "agds/animation.h"
#include "common/debug.h"
#include "common/memstream.h"
@@ -109,6 +111,10 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
if (_animation) {
_animation->paint(engine, backbuffer, _animationPos);
}
+ if (!_text.empty()) {
+ int w = backbuffer.w - _pos.x;
+ engine.getFont(1)->drawString(&backbuffer, _text, _pos.x, _pos.y, w, 0);
+ }
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d03fb3af032..cb5bfbe937f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -189,7 +189,8 @@ void Process::removeScreenObject() {
void Process::loadFont() {
Common::String name = popText();
int id = pop();
- debug("loadFont %s %d stub", name.c_str(), id);
+ debug("loadFont %s %d", name.c_str(), id);
+ _engine->loadFont(id, name, _glyphWidth, _glyphHeight);
}
void Process::loadMouse() {
Commit: 1a832b9dbc2926c6528c246aa873cbdb7a766a2d
https://github.com/scummvm/scummvm/commit/1a832b9dbc2926c6528c246aa873cbdb7a766a2d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:02+01:00
Commit Message:
AGDS: added negate op and stub233
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 81664d6b2c7..39b709a221d 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -61,7 +61,7 @@ enum Opcode {
kBoolAnd = 39,
kBoolOr = 40,
kBoolNot = 41,
- kStub42 = 42,
+ kNegate = 42,
kStub43 = 43,
kStub44 = 44,
kPostIncrementGlobal = 45,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 8fd789aaac4..8431e3c808c 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -229,6 +229,7 @@ private:
void stub221();
void stub223();
void stub225();
+ void stub233();
void stub235();
void debug(const char *str, ...);
@@ -237,6 +238,7 @@ private:
UNARY_OP(boolNot, !)
UNARY_OP(bitNot, ~)
+ UNARY_OP(negate, -)
BINARY_OP(boolOr, ||)
BINARY_OP(boolAnd, &&)
BINARY_OP(equals, ==)
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index cb5bfbe937f..840447d0492 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -876,6 +876,11 @@ void Process::setTimer() {
suspend();
}
+void Process::stub233() {
+ Common::String name = popString();
+ debug("stub233 %s", name.c_str());
+}
+
void Process::stub235() {
int arg3 = pop();
int arg2 = pop();
@@ -953,6 +958,7 @@ ProcessExitCode Process::execute() {
OP (kXor, bitXor);
OP (kNot, bitNot);
OP (kBoolNot, boolNot);
+ OP (kNegate, negate);
OP_U (kCallImm16, call);
OP_U (kObjectRegisterLookHandler, onLook);
OP_U (kObjectRegisterUseHandler, onUse);
@@ -1065,6 +1071,7 @@ ProcessExitCode Process::execute() {
OP_U (kStub209, stub209);
OP_U (kOnKey, onKey);
OP (kGetSampleVolume, getSampleVolume);
+ OP (kStub233, stub233);
OP (kStub235, stub235);
OP (kRunDialog, runDialog);
OP (kHasGlobal, hasGlobal);
Commit: 9f099904c2f11906741457ae679939b65143a4fb
https://github.com/scummvm/scummvm/commit/9f099904c2f11906741457ae679939b65143a4fb
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:02+01:00
Commit Message:
AGDS: skip resulting zeroes at the end of the string
Changed paths:
engines/agds/resourceManager.cpp
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 33c343d185c..b9c86e6d029 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -207,6 +207,9 @@ namespace AGDS {
decrypt(text.data(), end - begin);
+ while(begin != end && end[-1] == 0)
+ --end;
+
return Common::String(begin, end);
}
Commit: 0fbd894299523e38841b67edeeade20e1855f8ad
https://github.com/scummvm/scummvm/commit/0fbd894299523e38841b67edeeade20e1855f8ad
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:02+01:00
Commit Message:
AGDS: scan glyphs and determine their actual width
Changed paths:
engines/agds/font.cpp
engines/agds/font.h
diff --git a/engines/agds/font.cpp b/engines/agds/font.cpp
index 16c88d1e5c4..c9354fd689c 100644
--- a/engines/agds/font.cpp
+++ b/engines/agds/font.cpp
@@ -3,15 +3,36 @@
namespace AGDS {
-Font::Font(Graphics::TransparentSurface *surface, int gw, int gh): _surface(surface), _gw(gw), _gh(gh) {
+Font::Font(Graphics::TransparentSurface *surface, int gw, int gh):
+ _surface(surface),
+ _glyphW(gw), _glyphH(gh),
+ _cellW(surface->w / 16), _cellH(surface->h / 16) {
+
+ //debug("surface cell %dx%d", _cellW, _cellH);
+ for(int y = 0; y < 16; ++y) {
+ for(int x = 0; x < 16; ++x) {
+ const uint32 *pixels = static_cast<uint32 *>(_surface->getBasePtr(x * _cellW, y * _cellH));
+ int w;
+ int ch = (y << 4) | x;
+ for(w = 0; w <= _glyphW; ++w, ++pixels) {
+ uint8 r, g, b, a;
+ //debug("%d color #%08x", ch, *pixels);
+ surface->format.colorToARGB(*pixels, r, g, b, a);
+ //debug("%d %d %d %d", r, g, b, a);
+ if (r == 0) //fixme: mapped incorrectly
+ break;
+ }
+ _width[ch] = w;
+ }
+ }
}
void Font::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const {
if (chr >= 0x100)
return;
- Common::Rect srcRect(_gw, _gh);
- srcRect.moveTo(_surface->w / 16 * (chr & 0x0f), _surface->h / 16 * (chr >> 4));
+ Common::Rect srcRect(getCharWidth(chr), _glyphH);
+ srcRect.moveTo(_cellW * (chr & 0x0f), _cellH * (chr >> 4));
_surface->blit(*dst, x, y, Graphics::FLIP_NONE, &srcRect);
}
diff --git a/engines/agds/font.h b/engines/agds/font.h
index 9fc5bdf6614..ceff1ade677 100644
--- a/engines/agds/font.h
+++ b/engines/agds/font.h
@@ -33,21 +33,23 @@ namespace AGDS {
class Font : public Graphics::Font {
Graphics::TransparentSurface * _surface;
- int _gw, _gh;
+ int _glyphW, _glyphH;
+ int _cellW, _cellH;
+ uint8 _width[0x100];
public:
Font(Graphics::TransparentSurface *surface, int gw, int gh);
virtual int getFontHeight() const {
- return _gh;
+ return _glyphH;
}
virtual int getMaxCharWidth() const {
- return _gw;
+ return _glyphW;
}
virtual int getCharWidth(uint32 chr) const {
- return _gw;
+ return chr < 0x100? _width[chr]: 0;
}
virtual void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const;
Commit: 8714aa1d5904f59464c3faf1e3614dcfc8882be1
https://github.com/scummvm/scummvm/commit/8714aa1d5904f59464c3faf1e3614dcfc8882be1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:02+01:00
Commit Message:
AGDS: change region centerX/Y type to Point, render object name using region center for now
Changed paths:
engines/agds/object.cpp
engines/agds/process_opcodes.cpp
engines/agds/region.cpp
engines/agds/region.h
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index d9fb2083064..23724be43eb 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -21,9 +21,10 @@
*/
#include "agds/object.h"
+#include "agds/animation.h"
#include "agds/agds.h"
#include "agds/font.h"
-#include "agds/animation.h"
+#include "agds/region.h"
#include "common/debug.h"
#include "common/memstream.h"
#include "common/rect.h"
@@ -112,8 +113,9 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
_animation->paint(engine, backbuffer, _animationPos);
}
if (!_text.empty()) {
- int w = backbuffer.w - _pos.x;
- engine.getFont(1)->drawString(&backbuffer, _text, _pos.x, _pos.y, w, 0);
+ Common::Point pos = _region? _region->center: _pos;
+ int w = backbuffer.w - pos.x;
+ engine.getFont(1)->drawString(&backbuffer, _text, pos.x, pos.y, w, 0);
}
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 840447d0492..00a053ac299 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -77,7 +77,7 @@ void Process::getIntegerSystemVariable() {
void Process::getRegionCenterX() {
Common::String name = popString();
Region *reg = _engine->loadRegion(name);
- int value = reg->centerX;
+ int value = reg->center.x;
push(value);
debug("getRegionCenterX %s -> %d", name.c_str(), value);
}
@@ -85,7 +85,7 @@ void Process::getRegionCenterX() {
void Process::getRegionCenterY() {
Common::String name = popString();
Region *reg = _engine->loadRegion(name);
- int value = reg->centerY;
+ int value = reg->center.y;
push(value);
debug("getRegionCenterY %s -> %d", name.c_str(), value);
}
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index 290035b0e07..fc9388d2cc3 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -41,10 +41,10 @@ Region::Region(const Common::String &resourceName, Common::SeekableReadStream *
error("invalid region %s", resourceName.c_str());
byte * nameEnd = Common::find(header, header + 0x20, 0);
name = Common::String(reinterpret_cast<char *>(header), nameEnd - header);
- centerX = READ_UINT16(header + kRegionHeaderWidthOffset);
- centerY = READ_UINT16(header + kRegionHeaderHeightOffset);
+ center.x = READ_UINT16(header + kRegionHeaderWidthOffset);
+ center.y = READ_UINT16(header + kRegionHeaderHeightOffset);
flags = READ_UINT16(header + kRegionHeaderFlagsOffset);
- debug("region %s at (%d,%d) %04x", name.c_str(), centerX, centerY, flags);
+ debug("region %s at (%d,%d) %04x", name.c_str(), center.x, center.y, flags);
if (size > kRegionHeaderSize) {
uint16 ext = stream->readUint16LE();
//debug("extended entries %u", ext);
diff --git a/engines/agds/region.h b/engines/agds/region.h
index a0c7d508fd3..6820ef1d303 100644
--- a/engines/agds/region.h
+++ b/engines/agds/region.h
@@ -34,8 +34,7 @@ struct Region {
typedef Common::Array<Common::Point> PointsType;
Common::String name;
- uint16 centerX;
- uint16 centerY;
+ Common::Point center;
uint16 flags;
PointsType points;
Commit: 58e24f6412a5dd5b6c584a7f21d674ef2fd08db5
https://github.com/scummvm/scummvm/commit/58e24f6412a5dd5b6c584a7f21d674ef2fd08db5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:02+01:00
Commit Message:
AGDS: fixed fallthrough in F key handling
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index d529684e5f0..411053cccea 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -320,8 +320,8 @@ Common::Error AGDSEngine::run() {
case Common::KEYCODE_f:
if (event.kbd.flags & Common::KBD_CTRL) {
_fastMode = !_fastMode;
- break;
}
+ break;
default:
if (event.kbd.ascii)
key = Common::String(static_cast<char>(event.kbd.ascii));
Commit: b1d418755bfaff0586f424451e0c112821508b74
https://github.com/scummvm/scummvm/commit/b1d418755bfaff0586f424451e0c112821508b74
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:02+01:00
Commit Message:
AGDS: fixed stub166
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 00a053ac299..9f2bc96532a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -442,9 +442,10 @@ void Process::stub155() {
}
void Process::stub166() {
+ int arg3 = pop();
int arg2 = pop();
- int arg1 = pop();
- debug("stub166 %d %d", arg1, arg2);
+ Common::String arg1 = popString();
+ debug("stub166 %s %d %d", arg1.c_str(), arg2, arg3);
}
void Process::stub172() {
Commit: 14ff04f7be6cad759d6cd4b65f25ce59ffd1198c
https://github.com/scummvm/scummvm/commit/14ff04f7be6cad759d6cd4b65f25ce59ffd1198c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:02+01:00
Commit Message:
AGDS: renamed stub176 to cloneName
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 39b709a221d..8910698e4d4 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -193,7 +193,7 @@ enum Opcode {
kStub173 = 173,
kStub174 = 174,
kAppendToSharedStorage = 175,
- kStub176 = 176,
+ kCloneName = 176,
kAppendNameToSharedStorage = 177,
kGetCloneVar = 178,
kSetCloneVar = 179,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 8431e3c808c..e6cd80418a2 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -183,6 +183,7 @@ private:
void appendToSharedStorage();
void appendNameToSharedStorage();
void setCloneVar();
+ void cloneName();
void disableUser();
void enableUser();
@@ -214,7 +215,6 @@ private:
void stub172();
void stub173();
void stub174();
- void stub176();
void stub184();
void stub190();
void stub192();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 9f2bc96532a..e12b8852f78 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -322,6 +322,12 @@ void Process::setCloneVar() {
push(arg3);
}
+void Process::cloneName() {
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("cloneName: stub %s %s", arg1.c_str(), arg2.c_str());
+}
+
void Process::disableUser() {
debug("disableUser");
_engine->enableUser(false);
@@ -461,10 +467,6 @@ void Process::stub174() {
debug("stub174: mouse pointer mode 1?");
}
-void Process::stub176() {
- debug("stub176");
-}
-
void Process::stub192() {
int value = pop();
Common::String name = popString();
@@ -1022,7 +1024,7 @@ ProcessExitCode Process::execute() {
OP (kGetRandomNumber, getRandomNumber);
OP (kAppendToSharedStorage, appendToSharedStorage);
OP (kAppendNameToSharedStorage, appendNameToSharedStorage);
- OP (kStub176, stub176);
+ OP (kCloneName, cloneName);
OP (kSetCloneVar, setCloneVar);
OP (kStub152, stub152);
OP (kStub153, stub153);
Commit: 81a6574862a447087d1b10a16c348899cc1d2463
https://github.com/scummvm/scummvm/commit/81a6574862a447087d1b10a16c348899cc1d2463
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:02+01:00
Commit Message:
AGDS: output stack size in debug()
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 204db56b4bc..82e59230651 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -36,7 +36,7 @@ void Process::debug(const char *str, ...) {
va_list va;
va_start(va, str);
- Common::String format = Common::String::format("%s %04x: %s", _object->getName().c_str(), _lastIp + 7, str);
+ Common::String format = Common::String::format("%s %04x[%u]: %s", _object->getName().c_str(), _lastIp + 7, _stack.size(), str);
Common::String buf = Common::String::vformat(format.c_str(), va);
buf += '\n';
Commit: 22148b73f7ea95fb53ec0bcb208d460e0b0d7b68
https://github.com/scummvm/scummvm/commit/22148b73f7ea95fb53ec0bcb208d460e0b0d7b68
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:02+01:00
Commit Message:
AGDS: marked stub194 as possible mute
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index e12b8852f78..89b8d5b51bc 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -485,7 +485,7 @@ void Process::disableMouseAreas() {
}
void Process::stub194() {
- debug("stub194");
+ debug("stub194: mute?");
}
void Process::stub199() {
Commit: 980fc16761b70d5b81d99da16f6b04a54cb5c400
https://github.com/scummvm/scummvm/commit/980fc16761b70d5b81d99da16f6b04a54cb5c400
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:03+01:00
Commit Message:
AGDS: do not suspend process in moveCharacter
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 89b8d5b51bc..ffb0d4d21dd 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -812,7 +812,8 @@ void Process::moveCharacter() {
Common::String arg2 = popString();
Common::String arg1 = popString();
debug("moveCharacter %s %s %d", arg1.c_str(), arg2.c_str(), arg3);
- suspend();
+ if (_status == kStatusPassive)
+ suspend();
}
void Process::showCharacter() {
Commit: 5171327a9068a39dae4a6587798af5b62c173439
https://github.com/scummvm/scummvm/commit/5171327a9068a39dae4a6587798af5b62c173439
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:03+01:00
Commit Message:
AGDS: renamed stubs 71/74
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 8910698e4d4..9933fbb61cf 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -89,10 +89,10 @@ enum Opcode {
kLoadRegionFromObject = 68,
kLoadPictureFromObject = 69,
kLoadAnimationFromObject = 70,
- kSetScreenHeight = 71,
+ kSetObjectHeight = 71,
kUpdateScreenHeightToDisplay = 72,
kLoadTextFromObject = 73,
- kStub74 = 74,
+ kScreenSetHeight = 74,
kScreenLoadRegion = 75,
kScreenLoadObject = 76,
kScreenCloneObject = 77,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index e6cd80418a2..db9a4f1c053 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -122,6 +122,7 @@ private:
void loadFont();
void removeScreenObject();
void changeScreenPatch();
+ void setObjectHeight();
void setScreenHeight();
void updateScreenHeightToDisplay();
void addMouseArea();
@@ -195,7 +196,6 @@ private:
void onScreenBD(unsigned size);
void stub63(unsigned size);
- void stub74();
void stub82();
void stub83();
void stub119();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index ffb0d4d21dd..29d2c534e0a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -360,10 +360,10 @@ void Process::stub63(unsigned size) {
_ip += size;
}
-void Process::stub74() {
+void Process::setScreenHeight() {
int arg2 = pop();
int arg1 = pop();
- debug("stub74: %d %d", arg1, arg2);
+ debug("setScreenHeight: %d %d", arg1, arg2);
}
void Process::stub82() {
@@ -728,9 +728,9 @@ void Process::enableInventory() {
debug("enableInventory");
}
-void Process::setScreenHeight() {
+void Process::setObjectHeight() {
int height = pop();
- debug("setScreenHeight %d", height);
+ debug("setObjectHeight %d", height);
}
void Process::updateScreenHeightToDisplay() {
@@ -990,10 +990,10 @@ ProcessExitCode Process::execute() {
OP (kStub82, stub82);
OP (kStub83, stub83);
OP (kLoadCharacter, loadCharacter);
- OP (kSetScreenHeight, setScreenHeight);
+ OP (kSetObjectHeight, setObjectHeight);
OP (kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay);
OP (kLoadTextFromObject, loadTextFromObject);
- OP (kStub74, stub74);
+ OP (kScreenSetHeight, setScreenHeight);
OP (kScreenLoadObject, loadScreenObject);
OP (kScreenLoadRegion, loadScreenRegion);
OP (kScreenCloneObject, cloneObject);
Commit: 9042cfb3a22bfce063fc8291a1de276b8660fb75
https://github.com/scummvm/scummvm/commit/9042cfb3a22bfce063fc8291a1de276b8660fb75
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:03+01:00
Commit Message:
AGDS: added another variant of moveCharacter (usermove: 0)
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 9933fbb61cf..11bb1e3ec31 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -110,7 +110,7 @@ enum Opcode {
kShowCharacter = 90,
kStub91 = 91,
kEnableCharacter = 92,
- kMoveCharacter = 93,
+ kMoveCharacterUserMove = 93,
kLeaveCharacter = 94,
kSetCharacter = 95,
kStub96 = 96,
@@ -245,7 +245,7 @@ enum Opcode {
kStub225 = 225,
kFadeObject = 226,
kLoadFont = 227,
- kStub228 = 228,
+ kMoveCharacterNoUserMove = 228,
kOnKey = 229,
kStub230 = 230,
kStub231 = 231,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index db9a4f1c053..f4c655e937d 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -151,7 +151,7 @@ private:
void getObjectPictureHeight();
void loadCharacter();
void enableCharacter();
- void moveCharacter();
+ void moveCharacter(bool usermove);
void showCharacter();
void fogOnCharacter();
void leaveCharacter();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 29d2c534e0a..6bda6ee7b4e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -807,11 +807,11 @@ void Process::enableCharacter() {
debug("enableCharacter %s", name.c_str());
}
-void Process::moveCharacter() {
+void Process::moveCharacter(bool usermove) {
int arg3 = pop();
Common::String arg2 = popString();
Common::String arg1 = popString();
- debug("moveCharacter %s %s %d", arg1.c_str(), arg2.c_str(), arg3);
+ debug("moveCharacter %s %s %d, usermove: %d", arg1.c_str(), arg2.c_str(), arg3, usermove);
if (_status == kStatusPassive)
suspend();
}
@@ -899,6 +899,9 @@ void Process::stub235() {
#define OP(NAME, METHOD) \
case NAME: METHOD (); break
+#define OP_I(NAME, METHOD, IMM) \
+ case NAME: { METHOD (IMM); } break
+
#define OP_C(NAME, METHOD) \
case NAME: { int8 arg = next(); METHOD (arg); } break
@@ -974,7 +977,7 @@ ProcessExitCode Process::execute() {
OP (kLoadAnimationFromObject, loadAnimationFromObject);
OP (kShowCharacter, showCharacter);
OP (kEnableCharacter, enableCharacter);
- OP (kMoveCharacter, moveCharacter);
+ OP_I (kMoveCharacterUserMove, moveCharacter, true);
OP (kLeaveCharacter, leaveCharacter);
OP (kSetCharacter, setCharacter);
OP (kPointCharacter, pointCharacter);
@@ -1073,6 +1076,7 @@ ProcessExitCode Process::execute() {
OP (kStub200, stub200);
OP (kModifyMouseArea, modifyMouseArea);
OP_U (kStub209, stub209);
+ OP_I (kMoveCharacterNoUserMove, moveCharacter, false);
OP_U (kOnKey, onKey);
OP (kGetSampleVolume, getSampleVolume);
OP (kStub233, stub233);
Commit: 7991092b2dca066ba0aaa60e34fe8f3219b0d6f6
https://github.com/scummvm/scummvm/commit/7991092b2dca066ba0aaa60e34fe8f3219b0d6f6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:03+01:00
Commit Message:
AGDS: more stubs regarding character animation
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 11bb1e3ec31..479a903fdc3 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -105,7 +105,7 @@ enum Opcode {
kLoadCharacter = 85,
kStub86 = 86,
kStub87 = 87,
- kStub88 = 88,
+ kAnimateCharacter = 88,
kStub89 = 89,
kShowCharacter = 90,
kStub91 = 91,
@@ -165,7 +165,7 @@ enum Opcode {
kStub145 = 145,
kGetRegionCenterX = 146,
kGetRegionCenterY = 147,
- kStub148 = 148,
+ kGetCharacterAnimationPhase = 148,
kStub149 = 149,
kStub150 = 150,
kStub151 = 151,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index f4c655e937d..a2e83dc7b13 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -157,6 +157,8 @@ private:
void leaveCharacter();
void setCharacter();
void pointCharacter();
+ void animateCharacter();
+ void getCharacterAnimationPhase();
void quit();
void setDialogForNextFilm();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 6bda6ee7b4e..68eb69f22e9 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -816,6 +816,12 @@ void Process::moveCharacter(bool usermove) {
suspend();
}
+void Process::animateCharacter() {
+ int arg2 = pop();
+ Common::String arg1 = popString();
+ debug("animateCharacter: %s %d", arg1.c_str(), arg2);
+}
+
void Process::showCharacter() {
Common::String name = popString();
debug("showCharacter %s", name.c_str());
@@ -841,6 +847,13 @@ void Process::pointCharacter() {
suspend();
}
+void Process::getCharacterAnimationPhase() {
+ Common::String name = popString();
+ debug("getCharacterAnimationPhase: stub");
+ push(100);
+}
+
+
void Process::fogOnCharacter() {
int arg2 = pop();
int arg1 = pop();
@@ -992,6 +1005,7 @@ ProcessExitCode Process::execute() {
OP (kSetNextScreenSaveInHistory, setNextScreenSaveInHistory);
OP (kStub82, stub82);
OP (kStub83, stub83);
+ OP (kAnimateCharacter, animateCharacter);
OP (kLoadCharacter, loadCharacter);
OP (kSetObjectHeight, setObjectHeight);
OP (kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay);
@@ -1024,6 +1038,7 @@ ProcessExitCode Process::execute() {
OP (kSetSystemIntegerVariable, setIntegerSystemVariable);
OP (kGetRegionCenterX, getRegionCenterX);
OP (kGetRegionCenterY, getRegionCenterY);
+ OP (kGetCharacterAnimationPhase, getCharacterAnimationPhase);
OP (kGetIntegerSystemVariable, getIntegerSystemVariable);
OP (kGetRandomNumber, getRandomNumber);
OP (kAppendToSharedStorage, appendToSharedStorage);
Commit: a89103474f63f160763dc570d98ddbd718ed33e6
https://github.com/scummvm/scummvm/commit/a89103474f63f160763dc570d98ddbd718ed33e6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:03+01:00
Commit Message:
AGDS: implemented cloneName
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 68eb69f22e9..d82d10e399b 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -323,9 +323,11 @@ void Process::setCloneVar() {
}
void Process::cloneName() {
- Common::String arg2 = popString();
+ int arg2 = pop();
Common::String arg1 = popString();
- debug("cloneName: stub %s %s", arg1.c_str(), arg2.c_str());
+ Common::String name = Common::String::format("%s.%d", arg1.c_str(), arg2);
+ debug("cloneName: %s %d -> %s", arg1.c_str(), arg2, name.c_str());
+ push(_engine->appendToSharedStorage(name));
}
void Process::disableUser() {
Commit: 07e17e55739b0d1a82edbf333b373f205073fed2
https://github.com/scummvm/scummvm/commit/07e17e55739b0d1a82edbf333b373f205073fed2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:03+01:00
Commit Message:
AGDS: more globals arithmetics
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 479a903fdc3..4904ab435d8 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -72,12 +72,12 @@ enum Opcode {
kDecrementGlobalByTop = 50,
kMultiplyGlobalByTop = 51,
kDivideGlobalByTop = 52,
- kStub53 = 53,
- kStub54 = 54,
- kStub55 = 55,
- kStub56 = 56,
- kStub57 = 57,
- kStub58 = 58,
+ kModGlobalByTop = 53,
+ kShlGlobalByTop = 54,
+ kShrGlobalByTop = 55,
+ kAndGlobalByTop = 56,
+ kOrGlobalByTop = 57,
+ kXorGlobalByTop = 58,
kCallImm16 = 59,
kObjectRegisterLookHandler = 60,
kObjectRegisterUseHandler = 61,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index a2e83dc7b13..34ae53951f1 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -183,6 +183,13 @@ private:
void decrementGlobalByTop() { decrementGlobal(top()); }
void multiplyGlobalByTop();
void divideGlobalByTop();
+ void modGlobalByTop();
+ void shlGlobalByTop();
+ void shrGlobalByTop();
+ void andGlobalByTop();
+ void orGlobalByTop();
+ void xorGlobalByTop();
+
void appendToSharedStorage();
void appendNameToSharedStorage();
void setCloneVar();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d82d10e399b..f8511877667 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -280,6 +280,54 @@ void Process::divideGlobalByTop() {
_engine->setGlobal(name, value / div);
}
+void Process::modGlobalByTop() {
+ Common::String name = popString();
+ int div = top();
+ int value = _engine->getGlobal(name);
+ debug("mod global %s %d by %d", name.c_str(), value, div);
+ _engine->setGlobal(name, value % div);
+}
+
+void Process::shlGlobalByTop() {
+ Common::String name = popString();
+ int bits = top();
+ int value = _engine->getGlobal(name);
+ debug("shift global left %s %d by %d", name.c_str(), value, bits);
+ _engine->setGlobal(name, value << bits);
+}
+
+void Process::shrGlobalByTop() {
+ Common::String name = popString();
+ int bits = top();
+ int value = _engine->getGlobal(name);
+ debug("shift global right %s %d by %d", name.c_str(), value, bits);
+ _engine->setGlobal(name, value >> bits);
+}
+
+void Process::andGlobalByTop() {
+ Common::String name = popString();
+ int arg = top();
+ int value = _engine->getGlobal(name);
+ debug("and global %s %d by %d", name.c_str(), value, arg);
+ _engine->setGlobal(name, value & arg);
+}
+
+void Process::orGlobalByTop() {
+ Common::String name = popString();
+ int arg = top();
+ int value = _engine->getGlobal(name);
+ debug("or global %s %d by %d", name.c_str(), value, arg);
+ _engine->setGlobal(name, value | arg);
+}
+
+void Process::xorGlobalByTop() {
+ Common::String name = popString();
+ int arg = top();
+ int value = _engine->getGlobal(name);
+ debug("xor global %s %d by %d", name.c_str(), value, arg);
+ _engine->setGlobal(name, value ^ arg);
+}
+
void Process::appendToSharedStorage() {
Common::String value = popString();
int index = _engine->appendToSharedStorage(value);
@@ -962,6 +1010,12 @@ ProcessExitCode Process::execute() {
OP (kDecrementGlobalByTop, decrementGlobalByTop);
OP (kMultiplyGlobalByTop, multiplyGlobalByTop);
OP (kDivideGlobalByTop, divideGlobalByTop);
+ OP (kModGlobalByTop, modGlobalByTop);
+ OP (kShlGlobalByTop, shlGlobalByTop);
+ OP (kShrGlobalByTop, shrGlobalByTop);
+ OP (kAndGlobalByTop, andGlobalByTop);
+ OP (kOrGlobalByTop, orGlobalByTop);
+ OP (kXorGlobalByTop, xorGlobalByTop);
OP (kEquals, equals);
OP (kNotEquals, notEquals);
OP (kGreater, greater);
Commit: d2636a07139ac8a07810437bc6618977542ace8a
https://github.com/scummvm/scummvm/commit/d2636a07139ac8a07810437bc6618977542ace8a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:03+01:00
Commit Message:
AGDS: added stub231
Changed paths:
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 34ae53951f1..ef8226a9a16 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -238,6 +238,7 @@ private:
void stub221();
void stub223();
void stub225();
+ void stub231();
void stub233();
void stub235();
void debug(const char *str, ...);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f8511877667..9c260985732 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -943,6 +943,12 @@ void Process::setTimer() {
suspend();
}
+void Process::stub231() {
+ int arg2 = pop();
+ int arg1 = pop();
+ debug("stub231 %d %d", arg1, arg2);
+}
+
void Process::stub233() {
Common::String name = popString();
debug("stub233 %s", name.c_str());
@@ -1150,6 +1156,7 @@ ProcessExitCode Process::execute() {
OP_I (kMoveCharacterNoUserMove, moveCharacter, false);
OP_U (kOnKey, onKey);
OP (kGetSampleVolume, getSampleVolume);
+ OP (kStub231, stub231);
OP (kStub233, stub233);
OP (kStub235, stub235);
OP (kRunDialog, runDialog);
Commit: f4d72e794052d80e4037dbd98f7da7ccf6fdd4a9
https://github.com/scummvm/scummvm/commit/f4d72e794052d80e4037dbd98f7da7ccf6fdd4a9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:03+01:00
Commit Message:
AGDS: implemented getCloneVar
Changed paths:
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.h b/engines/agds/process.h
index ef8226a9a16..41e16fda39a 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -192,6 +192,8 @@ private:
void appendToSharedStorage();
void appendNameToSharedStorage();
+ Common::String getCloneVarName(const Common::String & arg1, const Common::String & arg2);
+ void getCloneVar();
void setCloneVar();
void cloneName();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 9c260985732..7e9007a2bc0 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -341,11 +341,7 @@ void Process::appendNameToSharedStorage() {
push(index);
}
-void Process::setCloneVar() {
- int arg3 = pop();
- Common::String arg2 = popString();
- Common::String arg1 = popString();
- debug("setCloneVar %s %s %d", arg1.c_str(), arg2.c_str(), arg3);
+Common::String Process::getCloneVarName(const Common::String & arg1, const Common::String & arg2) {
bool isNumeric = false;
size_t prefixLength;
{
@@ -365,6 +361,24 @@ void Process::setCloneVar() {
} else {
name = arg1 + "." + arg2;
}
+ return name;
+}
+
+void Process::getCloneVar() {
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("getCloneVar %s %s", arg1.c_str(), arg2.c_str());
+ Common::String name = getCloneVarName(arg1, arg2);
+ debug("global name for clone: %s", name.c_str());
+ push(_engine->getGlobal(name));
+}
+
+void Process::setCloneVar() {
+ int arg3 = pop();
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("setCloneVar %s %s %d", arg1.c_str(), arg2.c_str(), arg3);
+ Common::String name = getCloneVarName(arg1, arg2);
debug("global name for clone: %s", name.c_str());
_engine->setGlobal(name, arg3);
push(arg3);
@@ -1106,6 +1120,7 @@ ProcessExitCode Process::execute() {
OP (kAppendToSharedStorage, appendToSharedStorage);
OP (kAppendNameToSharedStorage, appendNameToSharedStorage);
OP (kCloneName, cloneName);
+ OP (kGetCloneVar, getCloneVar);
OP (kSetCloneVar, setCloneVar);
OP (kStub152, stub152);
OP (kStub153, stub153);
Commit: 7961f356736a19bd9c2254e112d0328423d19f6b
https://github.com/scummvm/scummvm/commit/7961f356736a19bd9c2254e112d0328423d19f6b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:03+01:00
Commit Message:
AGDS: created Character stub and added simple animation phase support
Changed paths:
A engines/agds/character.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 411053cccea..d7e0ff6d00a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -22,6 +22,7 @@
#include "agds/agds.h"
#include "agds/animation.h"
+#include "agds/character.h"
#include "agds/font.h"
#include "agds/mjpgPlayer.h"
#include "agds/object.h"
@@ -417,6 +418,9 @@ Common::Error AGDSEngine::run() {
mouseCursor->paint(*this, *backbuffer, _mouse);
}
+ for(CharactersType::iterator i = _characters.begin(); i != _characters.end(); ++i)
+ i->_value->paint(*this, *backbuffer);
+
_system->unlockScreen();
_system->updateScreen();
@@ -483,6 +487,26 @@ Animation * AGDSEngine::loadAnimation(const Common::String &name) {
return animation;
}
+Character * AGDSEngine::loadCharacter(const Common::String &name) {
+ CharactersType::iterator i = _characters.find(name);
+ if (i != _characters.end())
+ return i->_value;
+
+// Common::SeekableReadStream *stream = _resourceManager.getResource(name);
+// if (!stream)
+// error("could not load character from %s", name.c_str());
+ Character *character = new Character();
+// if (!character->load(stream))
+// error("could not load character from %s", name.c_str());
+ _characters[name] = character;
+ return character;
+}
+
+Character * AGDSEngine::getCharacter(const Common::String &name) const {
+ CharactersType::const_iterator i = _characters.find(name);
+ return i != _characters.end() ? i->_value: NULL;
+}
+
Graphics::TransparentSurface * AGDSEngine::loadPicture(const Common::String &name)
{ return convertToTransparent(_resourceManager.loadPicture(name, _pixelFormat)); }
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index cc4d0f7ea33..5f1365fc460 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -51,6 +51,7 @@ namespace Graphics { struct TransparentSurface; }
namespace AGDS {
class Animation;
+class Character;
class Font;
class Object;
class Process;
@@ -143,6 +144,9 @@ public:
Font *getFont(int id) const;
Animation * loadAnimation(const Common::String &name);
+ Character * loadCharacter(const Common::String &name);
+ Character * getCharacter(const Common::String &name) const;
+
void loadDefaultMouseCursor(const Common::String &name) {
_defaultMouseCursor = loadAnimation(name);
}
@@ -161,6 +165,7 @@ private:
typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
typedef Common::HashMap<Common::String, Animation *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> AnimationsType;
+ typedef Common::HashMap<Common::String, Character *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> CharactersType;
typedef Common::HashMap<int, Font *> FontsType;
const ADGameDescription * _gameDescription;
@@ -173,6 +178,7 @@ private:
ObjectsType _objects;
RegionsType _regions;
AnimationsType _animations;
+ CharactersType _characters;
ProcessListType _processes;
int _sharedStorageIndex;
Common::String _sharedStorage[10];
diff --git a/engines/agds/character.h b/engines/agds/character.h
new file mode 100644
index 00000000000..1d0d6244eb1
--- /dev/null
+++ b/engines/agds/character.h
@@ -0,0 +1,70 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_CHARACTER_H
+#define AGDS_CHARACTER_H
+
+#include "common/scummsys.h"
+#include "common/rect.h"
+
+namespace Common { class SeekableReadStream; }
+namespace Graphics { struct Surface; }
+namespace Video { class FlicDecoder; }
+
+namespace AGDS {
+
+class AGDSEngine;
+class Object;
+
+class Character {
+ int _counter;
+
+public:
+ Character(): _counter(-1) {
+ }
+
+ bool load(Common::SeekableReadStream* stream) {
+ return true;
+ }
+
+ void enable(bool enabled = true) {
+ }
+
+ void animate(int frames) {
+ _counter = frames;
+ }
+
+ int getPhase() const {
+ return _counter;
+ }
+
+ void paint(AGDSEngine & engine, Graphics::Surface & backbuffer) {
+ if (_counter >= 0)
+ --_counter;
+ }
+
+};
+
+
+} // End of namespace AGDS
+
+#endif /* AGDS_ANIMATION_H */
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 7e9007a2bc0..5f29b74163b 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -22,6 +22,7 @@
#include "agds/process.h"
#include "agds/agds.h"
+#include "agds/character.h"
#include "agds/opcode.h"
#include "agds/region.h"
#include "agds/screen.h"
@@ -862,13 +863,19 @@ void Process::addMouseArea() {
void Process::loadCharacter() {
Common::String arg3 = popString();
Common::String arg2 = popString();
- Common::String arg1 = popString();
- debug("loadCharacter %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
+ Common::String name = popString();
+ debug("loadCharacter %s %s %s", name.c_str(), arg2.c_str(), arg3.c_str());
+ _engine->loadCharacter(name);
}
void Process::enableCharacter() {
Common::String name = popString();
debug("enableCharacter %s", name.c_str());
+ Character *character = _engine->getCharacter(name);
+ if (character)
+ character->enable();
+ else
+ warning("character %s could not be found", name.c_str());
}
void Process::moveCharacter(bool usermove) {
@@ -882,8 +889,14 @@ void Process::moveCharacter(bool usermove) {
void Process::animateCharacter() {
int arg2 = pop();
- Common::String arg1 = popString();
- debug("animateCharacter: %s %d", arg1.c_str(), arg2);
+ Common::String name = popString();
+ debug("animateCharacter: stub %s %d", name.c_str(), arg2);
+
+ Character *character = _engine->getCharacter(name);
+ if (character)
+ character->animate(arg2);
+ else
+ warning("character %s could not be found", name.c_str());
}
void Process::showCharacter() {
@@ -913,8 +926,11 @@ void Process::pointCharacter() {
void Process::getCharacterAnimationPhase() {
Common::String name = popString();
- debug("getCharacterAnimationPhase: stub");
- push(100);
+ debug("getCharacterAnimationPhase: stub %s", name.c_str());
+ Character *character = _engine->getCharacter(name);
+ int phase = character? character->getPhase(): -1;
+ debug("animation phase = %d", phase);
+ push(phase);
}
Commit: b119f9edb5be55a0c9c5c42665a660e0341789d9
https://github.com/scummvm/scummvm/commit/b119f9edb5be55a0c9c5c42665a660e0341789d9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:04+01:00
Commit Message:
AGDS: found proper names/opcodes for set delay/random/cycles
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 4904ab435d8..529634fbb14 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -147,9 +147,9 @@ enum Opcode {
kSetTimer = 127,
kProcessCleanupStub128 = 128,
kStub129 = 129,
- kStub130 = 130,
- kStub131 = 131,
- kStub132 = 132,
+ kSetCycles = 130,
+ kSetRandom = 131,
+ kSetPeriodic = 132,
kStub133 = 133,
kSetAnimationPosition = 134,
kResetPhaseVar = 135,
@@ -187,7 +187,7 @@ enum Opcode {
kStub167 = 167,
kStub168 = 168,
kGetIntegerSystemVariable = 169,
- kStub170 = 170,
+ kSetDelay = 170,
kGetRandomNumber = 171,
kStub172 = 172,
kStub173 = 173,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 41e16fda39a..041ad4c1660 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -196,6 +196,7 @@ private:
void getCloneVar();
void setCloneVar();
void cloneName();
+ void setDelay();
void disableUser();
void enableUser();
@@ -212,8 +213,8 @@ private:
void stub119();
void stub128();
void stub129();
- void stub130();
- void stub131();
+ void setCycles();
+ void setRandom();
void stub133();
void stub136();
void stub137();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 5f29b74163b..305fc86e1f5 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -431,6 +431,21 @@ void Process::setScreenHeight() {
debug("setScreenHeight: %d %d", arg1, arg2);
}
+void Process::setDelay() {
+ int delay = pop();
+ debug("setDelay stub %d", delay);
+}
+
+void Process::setCycles() {
+ int value = pop();
+ debug("setCycles stub %d", value);
+}
+
+void Process::setRandom() {
+ int value = pop();
+ debug("setRandom stub %d", value);
+}
+
void Process::stub82() {
Common::String arg2 = popString();
Common::String arg1 = popString();
@@ -457,15 +472,6 @@ void Process::stub129() {
debug("stub129 %d animation duration?", value);
}
-void Process::stub130() {
- int value = pop();
- debug("stub130 %d sample loops?", value);
-}
-
-void Process::stub131() {
- int value = pop();
- debug("stub130 %d random sample?", value);
-}
void Process::stub133() {
int pan = pop();
int volume = pop();
@@ -1116,8 +1122,8 @@ ProcessExitCode Process::execute() {
OP (kSetTimer, setTimer);
OP (kProcessCleanupStub128, stub128);
OP (kStub129, stub129);
- OP (kStub130, stub130);
- OP (kStub131, stub131);
+ OP (kSetCycles, setCycles);
+ OP (kSetRandom, setRandom);
OP (kStub133, stub133);
OP (kSetAnimationPosition, setAnimationPosition);
OP (kResetPhaseVar, resetPhaseVar);
@@ -1143,6 +1149,7 @@ ProcessExitCode Process::execute() {
OP (kStub154, stub154);
OP (kStub155, stub155);
OP (kStub166, stub166);
+ OP (kSetDelay, setDelay);
OP (kStub172, stub172);
OP (kStub173, stub173);
OP (kStub174, stub174);
Commit: c829a08cbb6824f69e2e9a31f06077f9ac407214
https://github.com/scummvm/scummvm/commit/c829a08cbb6824f69e2e9a31f06077f9ac407214
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:04+01:00
Commit Message:
AGDS: make Screen::remove return bool and output warning if nothing was found
Changed paths:
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 305fc86e1f5..23bc796f3b6 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -183,8 +183,10 @@ void Process::removeScreenObject() {
Common::String name = popString();
debug("removeScreenObject: %s", name.c_str());
Screen *screen = _engine->getCurrentScreen();
- if (screen)
- screen->remove(name);
+ if (screen) {
+ if (!screen->remove(name))
+ warning("removeScreenObject: object %s not found", name.c_str());
+ }
}
void Process::loadFont() {
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 72ae1e0292a..4aeded858eb 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -38,13 +38,16 @@ void Screen::add(Object *object) {
_children.push_back(object);
}
-void Screen::remove(const Common::String &name) {
+bool Screen::remove(const Common::String &name) {
+ bool found = false;
for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ) {
- if ((*i)->getName() == name)
+ if ((*i)->getName() == name) {
i = _children.erase(i);
- else
+ found = true;
+ } else
++i;
}
+ return found;
}
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index f184ce01300..0ad9f52d117 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -115,7 +115,7 @@ public:
}
void add(Object *object);
- void remove(const Common::String & name);
+ bool remove(const Common::String & name);
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer);
Object *find(Common::Point pos) const;
KeyHandler findKeyHandler(const Common::String &keyName);
Commit: 3e4b7c62dc379b771a89248bd7eaa115c5b738c2
https://github.com/scummvm/scummvm/commit/3e4b7c62dc379b771a89248bd7eaa115c5b738c2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:04+01:00
Commit Message:
AGDS: implemented modifyMouseRegion
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 23bc796f3b6..da7f02a9059 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -585,6 +585,11 @@ void Process::modifyMouseArea() {
int enabled = pop();
int id = pop();
debug("modifyMouseArea %d, %d", id, enabled);
+ MouseRegion * region = _engine->_mouseMap.find(id);
+ if (region) {
+ region->enabled = enabled;
+ } else
+ warning("modifyMouseArea: mouse region %d not found", id);
suspend(kExitCodeMouseAreaChange, id, enabled);
}
Commit: 560b13050aa218bef90a72bbfd51df2d29cae1f1
https://github.com/scummvm/scummvm/commit/560b13050aa218bef90a72bbfd51df2d29cae1f1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:04+01:00
Commit Message:
AGDS: fixed lifetime of the objects, removed global object cache
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/animation.cpp
engines/agds/detection.cpp
engines/agds/inventory.cpp
engines/agds/inventory.h
engines/agds/object.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
engines/agds/soundManager.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index d7e0ff6d00a..3c896da4f4a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -125,29 +125,27 @@ Common::String AGDSEngine::loadText(const Common::String &entryName) {
return ResourceManager::loadText(_data.getEntry(entryName));
}
-Object *AGDSEngine::loadObject(const Common::String & name, const Common::String &prototype) {
- ObjectsType::iterator i = _objects.find(name);
- Object *object = i != _objects.end()? i->_value: NULL;
- if (!object) {
- Common::String clone = prototype.empty()? name: prototype;
- Common::SeekableReadStream * stream = _data.getEntry(clone);
- if (!stream)
- error("no database entry for %s\n", clone.c_str());
-
- object = new Object(name, stream);
- _objects.setVal(name, object);
- delete stream;
- }
+ObjectPtr AGDSEngine::loadObject(const Common::String & name, const Common::String &prototype) {
+ debug("loadObject %s %s", name.c_str(), prototype.c_str());
+ Common::String clone = prototype.empty()? name: prototype;
+ Common::SeekableReadStream * stream = _data.getEntry(clone);
+ if (!stream)
+ error("no database entry for %s\n", clone.c_str());
+
+ ObjectPtr object(new Object(name, stream));
+ delete stream;
return object;
}
-void AGDSEngine::runObject(Object *object) {
- runProcess(object);
+void AGDSEngine::runObject(ObjectPtr object) {
if (_currentScreen)
_currentScreen->add(object);
+ else
+ warning("object leak");
+ runProcess(object);
}
-void AGDSEngine::runProcess(Object *object, uint ip) {
+void AGDSEngine::runProcess(ObjectPtr object, uint ip) {
_processes.push_front(Process(this, object, ip));
ProcessListType::iterator it = _processes.begin();
runProcess(it);
@@ -155,7 +153,10 @@ void AGDSEngine::runProcess(Object *object, uint ip) {
void AGDSEngine::runObject(const Common::String & name, const Common::String &prototype)
{
- runObject(loadObject(name, prototype));
+ ObjectPtr object = getCurrentScreenObject(name);
+ if (!object)
+ object = loadObject(name, prototype);
+ runObject(object);
}
void AGDSEngine::loadScreen(const Common::String & name) {
@@ -164,7 +165,7 @@ void AGDSEngine::loadScreen(const Common::String & name) {
_currentScreenName = name;
_currentScreen = new Screen(loadObject(name), _mouseMap);
_mouseMap.clear();
- runObject(name); //is it called once or per screen activation?
+ runObject(_currentScreen->getObject()); //is it called once or per screen activation?
}
void AGDSEngine::setCurrentScreen(Screen *screen) {
@@ -360,7 +361,7 @@ Common::Error AGDSEngine::run() {
_mouse = event.mouse;
if (_userEnabled) {
debug("lclick %d, %d", _mouse.x, _mouse.y);
- Object *object = _currentScreen->find(_mouse);
+ ObjectPtr object = _currentScreen->find(_mouse);
if (object) {
uint ip = object->getClickHandler();
if (ip) {
@@ -378,7 +379,7 @@ Common::Error AGDSEngine::run() {
Animation *mouseCursor = NULL;
if (_userEnabled && _currentScreen) {
- Object *object = _currentScreen->find(_mouse);
+ ObjectPtr object = _currentScreen->find(_mouse);
Animation *cursor = object? object->getMouseCursor(): NULL;
if (cursor)
mouseCursor = cursor;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 5f1365fc460..75a52eff550 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/hashmap.h"
+#include "common/ptr.h"
#include "common/random.h"
#include "common/rect.h"
#include "engines/advancedDetector.h"
@@ -54,6 +55,7 @@ class Animation;
class Character;
class Font;
class Object;
+typedef Common::SharedPtr<Object> ObjectPtr;
class Process;
struct Region;
struct MouseRegion;
@@ -86,10 +88,10 @@ private:
void runProcess();
public:
- Object * loadObject(const Common::String & name, const Common::String & prototype = Common::String());
- void runObject(Object *object);
+ ObjectPtr loadObject(const Common::String & name, const Common::String & prototype = Common::String());
+ void runObject(ObjectPtr object);
void runObject(const Common::String & name, const Common::String &prototype = Common::String());
- void runProcess(Object *object, uint ip = 0);
+ void runProcess(ObjectPtr object, uint ip = 0);
void resetCurrentScreen();
void loadScreen(const Common::String & name);
@@ -121,6 +123,10 @@ public:
return _currentScreen;
}
+ ObjectPtr getCurrentScreenObject(const Common::String &name) {
+ return _currentScreen? _currentScreen->find(name): ObjectPtr();
+ }
+
Common::String & getCurrentScreenName() {
return _currentScreenName;
}
@@ -175,7 +181,6 @@ private:
PictureCacheType _pictureCache;
int _pictureCacheId;
FontsType _fonts;
- ObjectsType _objects;
RegionsType _regions;
AnimationsType _animations;
CharactersType _characters;
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index ad363fb7faa..67c62dccb01 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -22,6 +22,7 @@
#include "agds/animation.h"
#include "agds/agds.h"
+#include "agds/object.h"
#include "common/debug.h"
#include "common/textconsole.h"
#include "graphics/transparent_surface.h"
diff --git a/engines/agds/detection.cpp b/engines/agds/detection.cpp
index 8abe49cd8c0..53d2a3968fc 100644
--- a/engines/agds/detection.cpp
+++ b/engines/agds/detection.cpp
@@ -21,6 +21,7 @@
*/
#include "agds/agds.h"
+#include "agds/object.h"
#include "engines/advancedDetector.h"
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 87fa04abb62..db719676ef6 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -21,10 +21,13 @@
*/
#include "agds/inventory.h"
+#include "agds/object.h"
#include "common/debug.h"
#include "common/textconsole.h"
namespace AGDS {
+Inventory::Inventory(): _entries(kMaxSize) { }
+Inventory::~Inventory() { }
int Inventory::free() const {
int free = 0;
@@ -34,7 +37,7 @@ int Inventory::free() const {
return free;
}
-int Inventory::add(Object *object) {
+int Inventory::add(ObjectPtr object) {
for(uint i = 0; i < _entries.size(); ++i) {
if (!_entries[i]) {
_entries[i] = object;
@@ -46,7 +49,7 @@ int Inventory::add(Object *object) {
void Inventory::clear() {
for(uint i = 0; i < _entries.size(); ++i) {
- _entries[i] = NULL;
+ _entries[i].reset();
}
}
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index ffca6710fe2..e1dc1fff624 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -25,22 +25,25 @@
#include "common/scummsys.h"
#include "common/array.h"
+#include "common/ptr.h"
namespace AGDS {
class Object;
+typedef Common::SharedPtr<Object> ObjectPtr;
class Inventory {
- typedef Common::Array<Object *> EntriesType;
+ typedef Common::Array<ObjectPtr> EntriesType;
EntriesType _entries;
public:
static const int kMaxSize = 35;
- Inventory(): _entries(kMaxSize) { }
+ Inventory();
+ ~Inventory();
- int add(Object *object);
+ int add(ObjectPtr object);
- Object *get(int index) const {
+ ObjectPtr get(int index) const {
return _entries[index];
}
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 537277c9e03..ae94de59fbe 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -27,6 +27,7 @@
#include "common/array.h"
#include "common/hash-str.h"
#include "common/hashmap.h"
+#include "common/ptr.h"
#include "common/rect.h"
#include "common/stream.h"
@@ -159,6 +160,7 @@ public:
return i != _keyHandlers.end()? i->_value: 0;
}
};
+typedef Common::SharedPtr<Object> ObjectPtr;
} // End of namespace AGDS
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 82e59230651..bfcf214433c 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -27,7 +27,7 @@
namespace AGDS {
-Process::Process(AGDSEngine *engine, Object* object, unsigned ip) :
+Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
_engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object), _ip(ip), _status(kStatusActive), _exitCode(kExitCodeDestroy),
_glyphWidth(16), _glyphHeight(16) {
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 041ad4c1660..970651086cf 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -43,7 +43,7 @@ private:
AGDSEngine * _engine;
Common::String _parentScreen;
- Object * _object;
+ ObjectPtr _object;
StackType _stack;
unsigned _ip, _lastIp;
Status _status;
@@ -294,7 +294,7 @@ private:
}
public:
- Process(AGDSEngine *engine, Object *object, unsigned ip = 0);
+ Process(AGDSEngine *engine, ObjectPtr object, unsigned ip = 0);
const Common::String & getName() const {
return _object->getName();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index da7f02a9059..12df0e7081e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -163,13 +163,23 @@ void Process::updatePhaseVarOr4() {
void Process::loadScreenObject() {
Common::String name = popString();
debug("loadScreenObject: %s", name.c_str());
+ Screen * screen = _engine->getCurrentScreen();
+ if (!screen->find(name)) {
+ screen->add(_engine->loadObject(name));
+ } else{
+ warning("loadScreenObject: object %s already loaded", name.c_str());
+ }
suspend(kExitCodeLoadScreenObject, name);
}
void Process::loadScreenRegion() {
Common::String name = popString();
debug("loadScreenRegion %s", name.c_str());
- _engine->loadObject(_engine->getCurrentScreenName())->setRegion(_engine->loadRegion(name));
+ Screen * screen = _engine->getCurrentScreen();
+ if (screen)
+ screen->getObject()->setRegion(_engine->loadRegion(name));
+ else
+ warning("no current screen");
}
void Process::cloneObject() {
@@ -418,7 +428,11 @@ void Process::fadeObject() {
int value = pop();
Common::String name = popString();
debug("fadeObject %s %d", name.c_str(), value);
- _engine->loadObject(name)->setAlpha(value);
+ ObjectPtr object = _engine->getCurrentScreenObject(name);
+ if (object)
+ object->setAlpha(value);
+ else
+ warning("fadeObject: object %s not found", name.c_str());
}
void Process::stub63(unsigned size) {
@@ -650,7 +664,11 @@ void Process::setObjectText() {
Common::String text = popText();
Common::String name = popString();
debug("setObjectText %s \"%s\" %d", name.c_str(), text.c_str(), arg3);
- _engine->loadObject(name)->setText(text);
+ ObjectPtr object = _engine->getCurrentScreenObject(name);
+ if (object)
+ object->setText(text);
+ else
+ warning("setObjectText: object %s not found", name.c_str());
}
@@ -681,10 +699,13 @@ void Process::clearScreen() {
void Process::moveScreenObject() {
int arg3 = pop();
int arg2 = pop();
- Common::String arg1 = popString();
- debug("moveScreenObject %s %d %d", arg1.c_str(), arg2, arg3);
- Object *object = _engine->loadObject(arg1);
- object->move(Common::Point(arg2, arg3));
+ Common::String name = popString();
+ debug("moveScreenObject %s %d %d", name.c_str(), arg2, arg3);
+ ObjectPtr object = _engine->getCurrentScreenObject(name);
+ if (object)
+ object->move(Common::Point(arg2, arg3));
+ else
+ warning("moveScreenObject: object %s not found", name.c_str());
}
void Process::quit() {
@@ -725,21 +746,31 @@ void Process::runDialog() {
void Process::getObjectPictureWidth() {
Common::String name = popString();
debug("getObjectPictureWidth %s", name.c_str());
- Object *object = _engine->loadObject(name);
- const Graphics::Surface *picture = object->getPicture();
- int value = picture? picture->w: 0;
- debug("\t->%d", value);
- push(value);
+ ObjectPtr object = _engine->getCurrentScreenObject(name);
+ if (object) {
+ const Graphics::Surface *picture = object->getPicture();
+ int value = picture? picture->w: 0;
+ debug("\t->%d", value);
+ push(value);
+ } else {
+ warning("getObjectPictureWidth: object %s not found", name.c_str());
+ push(0);
+ }
}
void Process::getObjectPictureHeight() {
Common::String name = popString();
debug("getObjectPictureHeight %s", name.c_str());
- Object *object = _engine->loadObject(name);
- const Graphics::Surface *picture = object->getPicture();
- int value = picture? picture->h: 0;
- debug("\t->%d", value);
- push(value);
+ ObjectPtr object = _engine->getCurrentScreenObject(name);
+ if (object) {
+ const Graphics::Surface *picture = object->getPicture();
+ int value = picture? picture->h: 0;
+ debug("\t->%d", value);
+ push(value);
+ } else {
+ warning("getObjectPictureHeight: object %s not found", name.c_str());
+ push(0);
+ }
}
void Process::playFilm() {
@@ -777,7 +808,7 @@ void Process::getInventoryFreeSpace() {
void Process::appendInventoryObjectNameToSharedSpace() {
int index = pop();
debug("appendInventoryObjectNameToSharedSpace %d", index);
- Object *object = _engine->inventory().get(index);
+ ObjectPtr object = _engine->inventory().get(index);
push(_engine->appendToSharedStorage(object? object->getName(): Common::String()));
}
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 4aeded858eb..1c187e95ec9 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -26,11 +26,19 @@
namespace AGDS {
-Screen::Screen(Object *object, const MouseMap &mouseMap) : _name(object->getName()), _mouseMap(mouseMap) {
+Screen::Screen(ObjectPtr object, const MouseMap &mouseMap) : _object(object), _name(object->getName()), _mouseMap(mouseMap) {
add(object);
}
-void Screen::add(Object *object) {
+Screen::~Screen() {
+ _children.clear();
+}
+
+void Screen::add(ObjectPtr object) {
+ if (object == NULL) {
+ warning("refusing to add null to scene");
+ return;
+ }
for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
if (*i == object)
return;
@@ -38,11 +46,19 @@ void Screen::add(Object *object) {
_children.push_back(object);
}
+ObjectPtr Screen::find(const Common::String &name) {
+ for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
+ if ((*i)->getName() == name)
+ return *i;
+ }
+ return ObjectPtr();
+}
+
bool Screen::remove(const Common::String &name) {
bool found = false;
for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ) {
if ((*i)->getName() == name) {
- i = _children.erase(i);
+ i = _children.erase(i); //fixme: object leak
found = true;
} else
++i;
@@ -53,25 +69,24 @@ bool Screen::remove(const Common::String &name) {
void Screen::paint(AGDSEngine & engine, Graphics::Surface & backbuffer) {
for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
- Object *object = *i;
- object->paint(engine, backbuffer);
+ (*i)->paint(engine, backbuffer);
}
}
-Object *Screen::find(Common::Point pos) const {
+ObjectPtr Screen::find(Common::Point pos) const {
for(ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
- Object *object = *i;
+ ObjectPtr object = *i;
Region *region = object->getRegion();
if (region && region->pointIn(pos))
return object;
}
- return NULL;
+ return ObjectPtr();
}
Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
KeyHandler keyHandler;
for(ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
- Object *object = *i;
+ ObjectPtr object = *i;
uint ip = object->getKeyHandler(keyName);
if (ip) {
keyHandler.ip = ip;
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 0ad9f52d117..89fb49126e7 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/list.h"
+#include "common/ptr.h"
#include "common/str.h"
#include "common/rect.h"
@@ -36,6 +37,7 @@ namespace AGDS {
class AGDSEngine;
class Object;
+typedef Common::SharedPtr<Object> ObjectPtr;
struct Region;
struct MouseRegion {
@@ -89,22 +91,28 @@ public:
};
class Screen {
- typedef Common::List<Object *> ChildrenType;
+ typedef Common::List<ObjectPtr> ChildrenType;
+ ObjectPtr _object;
Common::String _name;
ChildrenType _children;
MouseMap _mouseMap;
public:
struct KeyHandler {
- Object * object;
+ ObjectPtr object;
uint ip;
KeyHandler(): object(), ip() { }
KeyHandler(Object *o, uint i): object(o), ip(i) { }
};
- Screen(Object *object, const MouseMap &mouseMap);
+ Screen(ObjectPtr object, const MouseMap &mouseMap);
+ ~Screen();
+
+ ObjectPtr getObject() {
+ return _object;
+ }
const Common::String &getName() const {
return _name;
@@ -114,10 +122,11 @@ public:
return _mouseMap;
}
- void add(Object *object);
+ void add(ObjectPtr object);
bool remove(const Common::String & name);
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer);
- Object *find(Common::Point pos) const;
+ ObjectPtr find(Common::Point pos) const;
+ ObjectPtr find(const Common::String &name);
KeyHandler findKeyHandler(const Common::String &keyName);
};
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 2b20a44e0e5..fbc29aaf614 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -22,6 +22,7 @@
#include "agds/soundManager.h"
#include "agds/agds.h"
+#include "agds/object.h"
#include "common/debug.h"
#include "common/file.h"
#include "common/textconsole.h"
Commit: 544d7ee1dbebf5351b9fc743832b79464aeb288d
https://github.com/scummvm/scummvm/commit/544d7ee1dbebf5351b9fc743832b79464aeb288d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:04+01:00
Commit Message:
AGDS: added opcodes 102 and 220
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 529634fbb14..00553361166 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -237,7 +237,7 @@ enum Opcode {
kStub217 = 217,
kStub218 = 218,
kStub219 = 219,
- kStub220 = 220,
+ kStopCharacter = 220,
kStub221 = 221,
kStub222 = 222,
kStub223 = 223,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 970651086cf..2184c1200ef 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -159,6 +159,7 @@ private:
void pointCharacter();
void animateCharacter();
void getCharacterAnimationPhase();
+ void stopCharacter();
void quit();
void setDialogForNextFilm();
@@ -210,6 +211,7 @@ private:
void stub63(unsigned size);
void stub82();
void stub83();
+ void stub102();
void stub119();
void stub128();
void stub129();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 12df0e7081e..de498a3bbaf 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -474,6 +474,11 @@ void Process::stub83() {
debug("stub83: %s %s", arg1.c_str(), arg2.c_str());
}
+void Process::stub102() {
+ Common::String name = popString();
+ debug("stub102: load picture? %s");
+}
+
void Process::stub119() {
debug("stub119");
}
@@ -977,6 +982,11 @@ void Process::getCharacterAnimationPhase() {
push(phase);
}
+void Process::stopCharacter() {
+ int arg = pop();
+ Common::String name = popString();
+ debug("stopCharacter: stub %s %d", name.c_str(), arg);
+}
void Process::fogOnCharacter() {
int arg2 = pop();
@@ -1134,6 +1144,7 @@ ProcessExitCode Process::execute() {
OP (kEnableUser, enableUser);
OP (kUpdatePhaseVarOr2, updatePhaseVarOr2);
OP (kUpdatePhaseVarOr4, updatePhaseVarOr4);
+ OP (kStub102, stub102);
OP (kClearScreen, clearScreen);
OP (kInventoryClear, inventoryClear);
OP (kLoadMouse, loadMouse);
@@ -1217,6 +1228,7 @@ ProcessExitCode Process::execute() {
OP (kStub215, stub215);
OP (kStub216, stub216);
OP (kStub217, stub217);
+ OP (kStopCharacter, stopCharacter);
OP (kStub221, stub221);
OP (kStub223, stub223);
OP (kStub225, stub225);
Commit: c3d2142d9ef46e7d60dab9560bf45ef35b80d7b3
https://github.com/scummvm/scummvm/commit/c3d2142d9ef46e7d60dab9560bf45ef35b80d7b3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:04+01:00
Commit Message:
AGDS: implemented InventoryHasObject and some inventory related stub
Changed paths:
engines/agds/inventory.cpp
engines/agds/inventory.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index db719676ef6..1d95f38881a 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -47,6 +47,13 @@ int Inventory::add(ObjectPtr object) {
error("inventory overflow");
}
+int Inventory::find(const Common::String &name) const {
+ for(uint i = 0; i < _entries.size(); ++i)
+ if (_entries[i] && _entries[i]->getName() == name)
+ return i;
+ return -1;
+}
+
void Inventory::clear() {
for(uint i = 0; i < _entries.size(); ++i) {
_entries[i].reset();
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index e1dc1fff624..4bc662089b4 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -46,6 +46,7 @@ public:
ObjectPtr get(int index) const {
return _entries[index];
}
+ int find(const Common::String &name) const;
int free() const;
void clear();
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 00553361166..367fe898788 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -255,7 +255,7 @@ enum Opcode {
kStub235 = 235,
kStub236 = 236,
kStub237 = 237,
- kStub238 = 238,
+ kInventoryHasObject = 238,
kStub239 = 239,
kRunDialog = 240,
kStub241 = 241,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 2184c1200ef..abdb602c131 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -108,6 +108,7 @@ private:
void enableInventory();
void inventoryClear();
void inventoryAddObject();
+ void inventoryHasObject();
void getMaxInventorySize();
void getInventoryFreeSpace();
void appendInventoryObjectNameToSharedSpace();
@@ -232,6 +233,7 @@ private:
void stub184();
void stub190();
void stub192();
+ void stub193();
void stub194();
void stub199();
void stub202(unsigned size);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index de498a3bbaf..f4fda2f5aad 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -565,6 +565,10 @@ void Process::stub192() {
debug("stub192: %s: set some object flag to %d", name.c_str(), value);
}
+void Process::stub193() {
+ debug("stub193: removing inventory object 0?");
+}
+
void Process::stub190() {
int value = pop();
debug("stub190 %d", value);
@@ -795,9 +799,18 @@ void Process::inventoryClear() {
void Process::inventoryAddObject() {
Common::String name = popString();
debug("inventoryAddObject %s", name.c_str());
+ _engine->inventory().add(_engine->loadObject(name));
suspend(kExitCodeLoadInventoryObject, name);
}
+void Process::inventoryHasObject() {
+ Common::String name = popString();
+ debug("inventoryHasObject %s", name.c_str());
+ int index = _engine->inventory().find(name);
+ debug("\t->%d", index);
+ push(index);
+}
+
void Process::getMaxInventorySize() {
int size = _engine->inventory().maxSize();
debug("getMaxInventorySize -> %d", size);
@@ -1218,6 +1231,7 @@ ProcessExitCode Process::execute() {
OP (kSetObjectText, setObjectText);
OP (kStub190, stub190);
OP (kStub191, disableMouseAreas);
+ OP (kStub193, stub193);
OP (kStub194, stub194);
OP (kGetObjectPictureWidth, getObjectPictureWidth);
OP (kGetObjectPictureHeight, getObjectPictureHeight);
@@ -1247,6 +1261,7 @@ ProcessExitCode Process::execute() {
OP (kStub231, stub231);
OP (kStub233, stub233);
OP (kStub235, stub235);
+ OP (kInventoryHasObject, inventoryHasObject);
OP (kRunDialog, runDialog);
OP (kHasGlobal, hasGlobal);
OP (kSetDialogForNextFilm, setDialogForNextFilm);
Commit: f37e82e09938b3a254bec0a064caf63dc84b056f
https://github.com/scummvm/scummvm/commit/f37e82e09938b3a254bec0a064caf63dc84b056f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:04+01:00
Commit Message:
AGDS: implemented stub 202
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 367fe898788..a9b91619e9c 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -218,7 +218,7 @@ enum Opcode {
kLoadPicture = 198,
kStub199 = 199,
kStub200 = 200,
- kStub201 = 201,
+ kStub201Handler = 201,
kStub202ScreenHandler = 202,
kPlayFilm = 203,
kStub204 = 204,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index abdb602c131..d7284e70707 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -236,8 +236,9 @@ private:
void stub193();
void stub194();
void stub199();
- void stub202(unsigned size);
void stub200();
+ void stub201(unsigned size);
+ void stub202(unsigned size);
void stub209(unsigned size);
void stub215();
void stub216();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f4fda2f5aad..3a9a229323d 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -594,8 +594,13 @@ void Process::stub200() {
debug("stub200: %d", value);
}
+void Process::stub201(unsigned size) {
+ debug("stub201, [handler] %u instructions", size);
+ _ip += size;
+}
+
void Process::stub202(unsigned size) {
- debug("stub203, [handler] %u instructions", size);
+ debug("stub202, [handler] %u instructions", size);
_ip += size;
}
@@ -1248,6 +1253,7 @@ ProcessExitCode Process::execute() {
OP (kStub225, stub225);
OP (kFadeObject, fadeObject);
OP (kLoadFont, loadFont);
+ OP_U (kStub201Handler, stub201);
OP_U (kStub202ScreenHandler, stub202);
OP (kPlayFilm, playFilm);
OP (kAddMouseArea, addMouseArea);
Commit: 7d83dc09535a854497e9fe737c7c3d9abf79367b
https://github.com/scummvm/scummvm/commit/7d83dc09535a854497e9fe737c7c3d9abf79367b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:04+01:00
Commit Message:
AGDS: support FLIC as surface resources (tab hints)
Changed paths:
engines/agds/resourceManager.cpp
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index b9c86e6d029..abf7cf279f0 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -29,6 +29,7 @@
#include "image/bmp.h"
#include "image/pcx.h"
#include "graphics/surface.h"
+#include "video/flic_decoder.h"
namespace AGDS {
ResourceManager::ResourceManager()
@@ -183,6 +184,14 @@ namespace AGDS {
} else if (lname.hasSuffix(".pcx")) {
Image::PCXDecoder pcx;
return pcx.loadStream(*stream)? pcx.getSurface()->convertTo(format): NULL;
+ } else if (lname.hasSuffix(".flc")) {
+ Video::FlicDecoder flic;
+ if (!flic.loadStream(stream)) {
+ warning("flic decoder failed to load %s", name.c_str());
+ return NULL;
+ }
+ const Graphics::Surface *surface = flic.decodeNextFrame();
+ return surface? surface->convertTo(format, flic.getPalette()): surface;
} else
warning("unknown extensions for resource %s", name.c_str());
return NULL;
Commit: 2d1d999afdc7823b8ef94e3c00bcfc5366dc0066
https://github.com/scummvm/scummvm/commit/2d1d999afdc7823b8ef94e3c00bcfc5366dc0066
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:04+01:00
Commit Message:
AGDS: implement stub 233 as unload picture
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3a9a229323d..a1ac95c02ec 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1053,7 +1053,10 @@ void Process::stub231() {
void Process::stub233() {
Common::String name = popString();
- debug("stub233 %s", name.c_str());
+ debug("stub233 %s unload picture?", name.c_str());
+ ObjectPtr object = _engine->getCurrentScreenObject(name);
+ if (object)
+ object->setPicture(NULL);
}
void Process::stub235() {
Commit: e6a818006fbc77918f84f6f165f7ae1e45ddade4
https://github.com/scummvm/scummvm/commit/e6a818006fbc77918f84f6f165f7ae1e45ddade4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:04+01:00
Commit Message:
AGDS: added stub160
Changed paths:
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.h b/engines/agds/process.h
index d7284e70707..e37763c269e 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -226,6 +226,7 @@ private:
void stub153();
void stub154();
void stub155();
+ void stub160();
void stub166();
void stub172();
void stub173();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index a1ac95c02ec..7aec7be4d2a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -539,6 +539,11 @@ void Process::stub155() {
push(155);
}
+void Process::stub160() {
+ int arg = pop();
+ debug("stub160: %d", arg);
+}
+
void Process::stub166() {
int arg3 = pop();
int arg2 = pop();
@@ -1218,6 +1223,7 @@ ProcessExitCode Process::execute() {
OP (kStub153, stub153);
OP (kStub154, stub154);
OP (kStub155, stub155);
+ OP (kStub160, stub160);
OP (kStub166, stub166);
OP (kSetDelay, setDelay);
OP (kStub172, stub172);
Commit: 7f14576fd17fbee955caa6a77770ef0721202b2f
https://github.com/scummvm/scummvm/commit/7f14576fd17fbee955caa6a77770ef0721202b2f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:05+01:00
Commit Message:
AGDS: removed 'leak' comments
Changed paths:
engines/agds/agds.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3c896da4f4a..da2998eb7d1 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -141,7 +141,7 @@ void AGDSEngine::runObject(ObjectPtr object) {
if (_currentScreen)
_currentScreen->add(object);
else
- warning("object leak");
+ warning("object %s has been loaded, but was not added to any screen", object->getName().c_str());
runProcess(object);
}
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 1c187e95ec9..3a1a9c666b5 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -58,7 +58,7 @@ bool Screen::remove(const Common::String &name) {
bool found = false;
for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ) {
if ((*i)->getName() == name) {
- i = _children.erase(i); //fixme: object leak
+ i = _children.erase(i);
found = true;
} else
++i;
Commit: 751490866407a4c69a0d78dc70a9f9336c3503a4
https://github.com/scummvm/scummvm/commit/751490866407a4c69a0d78dc70a9f9336c3503a4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:05+01:00
Commit Message:
AGDS: renamed arguments for addMouseArea
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 7aec7be4d2a..cc22d265ed4 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -920,14 +920,14 @@ void Process::enableUser() {
}
void Process::addMouseArea() {
- Common::String arg3 = popString();
- Common::String arg2 = popString();
- Common::String arg1 = popString();
+ Common::String onLeave = popString();
+ Common::String onEnter = popString();
+ Common::String name = popString();
- debug("addMouseArea (region: %s) %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
- Region *region = _engine->loadRegion(arg1);
+ debug("addMouseArea (region: %s) %s %s", name.c_str(), onEnter.c_str(), onLeave.c_str());
+ Region *region = _engine->loadRegion(name);
- int value = _engine->_mouseMap.add(MouseRegion(region, arg2, arg3));
+ int value = _engine->_mouseMap.add(MouseRegion(region, onEnter, onLeave));
debug("\tmouse area id -> %d", value);
push(value);
}
Commit: d6005a9c44bbc6beae6bc609e23fb0dd90b03c8e
https://github.com/scummvm/scummvm/commit/d6005a9c44bbc6beae6bc609e23fb0dd90b03c8e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:05+01:00
Commit Message:
AGDS: fixed current screen handling while navigating back in history
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index da2998eb7d1..51d2fb9540a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -187,7 +187,8 @@ void AGDSEngine::resetCurrentScreen()
_currentRegion = NULL;
}
- delete _currentScreen;
+ if (_currentScreen != _previousScreen) //we didnt come from back command, fixme: refactor it
+ delete _currentScreen;
_currentScreen = NULL;
}
@@ -224,7 +225,6 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
if (_currentScreen) {
delete _previousScreen;
_previousScreen = _currentScreen;
- _currentScreen = NULL;
}
loadScreen(process.getExitArg1());
destroy = true;
Commit: b0f7896470ee711c7583603d00b9af6cf75a2a5a
https://github.com/scummvm/scummvm/commit/b0f7896470ee711c7583603d00b9af6cf75a2a5a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:05+01:00
Commit Message:
AGDS: read text from resource for fogOnCharacter
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index cc22d265ed4..4a9660b840a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1014,7 +1014,7 @@ void Process::stopCharacter() {
void Process::fogOnCharacter() {
int arg2 = pop();
int arg1 = pop();
- Common::String name = popString();
+ Common::String name = popText();
debug("fogOnCharacter %s %d %d", name.c_str(), arg1, arg2);
}
Commit: 992ae7a242534959aa7a8b58d7d4bd6c5837cb5d
https://github.com/scummvm/scummvm/commit/992ae7a242534959aa7a8b58d7d4bd6c5837cb5d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:05+01:00
Commit Message:
AGDS: fixed memory leaks reported by valgrind
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/animation.cpp
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 51d2fb9540a..ba48e86bba7 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -53,6 +53,10 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
AGDSEngine::~AGDSEngine() {
delete _currentScreen;
delete _previousScreen;
+ for(PictureCacheType::iterator i = _pictureCache.begin(); i != _pictureCache.end(); ++i) {
+ i->_value->free();
+ delete i->_value;
+ }
}
bool AGDSEngine::initGraphics() {
@@ -401,6 +405,7 @@ Common::Error AGDSEngine::run() {
Common::Rect srcRect(converted->getRect());
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer->getRect()))
backbuffer->copyRectToSurface(*converted, dst.x, dst.y, srcRect);
+ converted->free();
delete converted;
}
@@ -484,6 +489,7 @@ Animation * AGDSEngine::loadAnimation(const Common::String &name) {
Animation *animation = new Animation();
if (!animation->load(stream))
error("could not load animation from %s", name.c_str());
+
_animations[name] = animation;
return animation;
}
@@ -531,11 +537,12 @@ Font *AGDSEngine::getFont(int id) const {
return i->_value;
}
-Graphics::TransparentSurface *AGDSEngine::convertToTransparent(const Graphics::Surface *surface) {
+Graphics::TransparentSurface *AGDSEngine::convertToTransparent(Graphics::Surface *surface) {
if (!surface)
return NULL;
Graphics::TransparentSurface * t = new Graphics::TransparentSurface(*surface, true);
t->applyColorKey(0xff, 0, 0xff);
+ surface->free();
delete surface;
return t;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 75a52eff550..3c545a81b5f 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -136,7 +136,7 @@ public:
}
Graphics::TransparentSurface *loadPicture(const Common::String &name);
- Graphics::TransparentSurface *convertToTransparent(const Graphics::Surface *surface); //destroys surface!
+ Graphics::TransparentSurface *convertToTransparent(Graphics::Surface *surface); //destroys surface!
Graphics::TransparentSurface *loadFromCache(int id) const;
int saveToCache(Graphics::TransparentSurface *surface) {
if (!surface)
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 67c62dccb01..dbf77283821 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -60,6 +60,7 @@ void Animation::paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Commo
Common::Rect srcRect = c->getRect();
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
c->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
+ c->free();
delete c;
}
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index abf7cf279f0..40231012464 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -170,7 +170,7 @@ namespace AGDS {
return (file.open(name))? file.readStream(file.size()): NULL;
}
- const Graphics::Surface * ResourceManager::loadPicture(const Common::String & name, const Graphics::PixelFormat &format) {
+ Graphics::Surface * ResourceManager::loadPicture(const Common::String & name, const Graphics::PixelFormat &format) {
Common::SeekableReadStream *stream = getResource(name);
if (!stream)
return NULL;
@@ -191,7 +191,7 @@ namespace AGDS {
return NULL;
}
const Graphics::Surface *surface = flic.decodeNextFrame();
- return surface? surface->convertTo(format, flic.getPalette()): surface;
+ return surface? surface->convertTo(format, flic.getPalette()): NULL;
} else
warning("unknown extensions for resource %s", name.c_str());
return NULL;
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 86574cddf79..7889a655be4 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -88,7 +88,7 @@ public:
bool addPath(const Common::String &grpFilename);
Common::SeekableReadStream * getResource(const Common::String &name) const;
- const Graphics::Surface * loadPicture(const Common::String & name, const Graphics::PixelFormat &format);
+ Graphics::Surface * loadPicture(const Common::String & name, const Graphics::PixelFormat &format);
static Common::String loadText(Common::SeekableReadStream *stream);
Common::String loadText(const Common::String & name) const;
Commit: 0fec63ea155fcdef86328020433df56287174347
https://github.com/scummvm/scummvm/commit/0fec63ea155fcdef86328020433df56287174347
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:05+01:00
Commit Message:
AGDS: minor cleanups, almost every location in chapter 1 is accessible
Changed paths:
engines/agds/agds.cpp
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ba48e86bba7..32b78ca5dfa 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -217,6 +217,7 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
case kExitCodeDestroy:
destroy = true;
break;
+ case kExitCodeLoadScreenObjectAs:
case kExitCodeLoadScreenObject:
case kExitCodeRunDialog:
runObject(process.getExitArg1(), process.getExitArg2());
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index 2408420a152..cee83e5d224 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -31,10 +31,12 @@ namespace AGDS {
kExitCodeSetNextScreen = 6,
kExitCodeSetNextScreenSaveInHistory = 7,
kExitCodeLoadScreenObject = 8,
+ kExitCodeLoadScreenObjectAs = 9,
kExitCodeLoadInventoryObject = 10,
kExitCodeMouseAreaChange = 11,
kExitCodeRunDialog = 12,
kExitCodeCreatePatchLoadResources = 13,
+ kExitCodeLoadSaveGame = 14,
kExitCodeExitScreen = 15,
kExitCodeLoadPreviousScreenObject = 99
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4a9660b840a..eae27bc25e3 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -186,7 +186,7 @@ void Process::cloneObject() {
Common::String arg2 = popString();
Common::String arg1 = popString();
debug("cloneObject: %s %s", arg1.c_str(), arg2.c_str());
- suspend(kExitCodeLoadScreenObject, arg1, arg2);
+ suspend(kExitCodeLoadScreenObjectAs, arg1, arg2);
}
void Process::removeScreenObject() {
@@ -1016,6 +1016,8 @@ void Process::fogOnCharacter() {
int arg1 = pop();
Common::String name = popText();
debug("fogOnCharacter %s %d %d", name.c_str(), arg1, arg2);
+ debug("fixme: some script commands call enableUser again");
+ enableUser();
}
void Process::loadRegionFromObject() {
@@ -1069,7 +1071,8 @@ void Process::stub235() {
int arg2 = pop();
int arg1 = pop();
debug("stub235 (fadeScreen?) %d %d %d", arg1, arg2, arg3);
- suspend();
+ if (_status == kStatusPassive)
+ suspend();
}
Commit: 613016458e2dbd352e556cf1d24005711cd5d7e3
https://github.com/scummvm/scummvm/commit/613016458e2dbd352e556cf1d24005711cd5d7e3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:05+01:00
Commit Message:
AGDS: implement Process::error(), skip stack overflows and terminate process
it looks it repeats original behaviour when music stops playing for some time
Changed paths:
engines/agds/process.cpp
engines/agds/process.h
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index bfcf214433c..0daa7ea5d39 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -47,19 +47,40 @@ void Process::debug(const char *str, ...) {
va_end(va);
}
+//fixme: remove copy-paste
+void Process::error(const char *str, ...) {
+ va_list va;
+ va_start(va, str);
+
+ Common::String format = Common::String::format("%s %04x[%u]: %s", _object->getName().c_str(), _lastIp + 7, _stack.size(), str);
+ Common::String buf = Common::String::vformat(format.c_str(), va);
+
+ buf += '\n';
+
+ if (g_system)
+ g_system->logMessage(LogMessageType::kWarning, buf.c_str());
+
+ va_end(va);
+ _status = kStatusError;
+}
+
void Process::push(int32 value) {
_stack.push(value);
}
int32 Process::pop() {
- if (_stack.empty())
+ if (_stack.empty()) {
error("stack underflow at %s:%04x", _object->getName().c_str(), _lastIp + 7);
+ return 0;
+ }
return _stack.pop();
}
int32 Process::top() {
- if (_stack.empty())
+ if (_stack.empty()) {
error("stack underflow, %s:%04x", _object->getName().c_str(), _lastIp + 7);
+ return 0;
+ }
return _stack.top();
}
@@ -86,6 +107,7 @@ void Process::activate() {
break;
default:
error("process in invalid state %d", _status);
+ _status = kStatusError;
}
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index e37763c269e..d2ee8898c40 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -251,6 +251,7 @@ private:
void stub233();
void stub235();
void debug(const char *str, ...);
+ void error(const char *str, ...);
#define UNARY_OP(NAME, OP) void NAME () { int arg = pop(); debug(#NAME " %d", arg); push( OP arg ); }
#define BINARY_OP(NAME, OP) void NAME () { int arg2 = pop(); int arg1 = pop(); debug(#NAME " %d " #OP " %d", arg1, arg2); push(arg1 OP arg2); }
Commit: 3f9bb3fb7edda75b68bd2c7c5db49c7e04832f80
https://github.com/scummvm/scummvm/commit/3f9bb3fb7edda75b68bd2c7c5db49c7e04832f80
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:05+01:00
Commit Message:
AGDS: provide additional info for stub63, it looks like it's inventory presence flag
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index eae27bc25e3..6253a255b5a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -437,7 +437,8 @@ void Process::fadeObject() {
void Process::stub63(unsigned size) {
Common::String arg = popString();
- debug("stub63: [handler] %u instructions, arg: %s", size, arg.c_str());
+ int value = _engine->getGlobal(arg);
+ debug("stub63: [handler] %u instructions, loop range: 0-%d", size, value);
_ip += size;
}
Commit: ae0143bee119e752da52e2986eb3f18811fe3e41
https://github.com/scummvm/scummvm/commit/ae0143bee119e752da52e2986eb3f18811fe3e41
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:05+01:00
Commit Message:
AGDS: documented changeScreenPatch logic
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 6253a255b5a..f52c72d41c1 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -411,11 +411,21 @@ void Process::disableUser() {
}
void Process::changeScreenPatch() {
- Common::String res2 = popString();
- Common::String res1 = popString();
- //change screen patch
- debug("changeScreenPatch: '%s' '%s'", res1.c_str(), res2.c_str());
- push(0);
+ Common::String objectName = popString();
+ Common::String screenName = popString();
+ Screen * screen = _engine->getCurrentScreen();
+ if (!screen) {
+ error("no current screen");
+ return;
+ }
+
+ if (screenName.empty())
+ screenName = screen->getName();
+
+ //change screen patch (load and return 1)
+ int value = 0;
+ debug("changeScreenPatch: screen: %s, object: %s -> %d", screenName.c_str(), objectName.c_str(), value);
+ push(value);
}
void Process::loadMouseCursorFromObject() {
Commit: cc265633a095e7189d624f58838d93e46eef5115
https://github.com/scummvm/scummvm/commit/cc265633a095e7189d624f58838d93e46eef5115
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:05+01:00
Commit Message:
AGDS: implement changeScreenPatch
Changed paths:
engines/agds/agds.cpp
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 32b78ca5dfa..5282836b464 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -150,6 +150,7 @@ void AGDSEngine::runObject(ObjectPtr object) {
}
void AGDSEngine::runProcess(ObjectPtr object, uint ip) {
+ object->activate(true);
_processes.push_front(Process(this, object, ip));
ProcessListType::iterator it = _processes.begin();
runProcess(it);
@@ -207,6 +208,7 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
const Common::String &name = process.getName();
if (process.getStatus() == Process::kStatusDone || process.getStatus() == Process::kStatusError) {
debug("process %s finished", name.c_str());
+ process.getObject()->activate(false);
it = _processes.erase(it);
return;
}
@@ -255,6 +257,7 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
}
if (destroy) {
debug("destroying process %s...", name.c_str());
+ process.getObject()->activate(false);
it = _processes.erase(it);
} else
++it;
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 23724be43eb..e1dd4bf6799 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -37,7 +37,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream * stream)
_name(name), _stringTableLoaded(false),
_picture(), _region(),
_animation(), _mouseCursor(),
- _pos(), _alpha(255) {
+ _pos(), _alpha(255), _active(false) {
byte id = stream->readByte();
byte flag = stream->readByte();
debug("id: 0x%02x %u, flag: %u", id, id, flag);
diff --git a/engines/agds/object.h b/engines/agds/object.h
index ae94de59fbe..046b7bdf294 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -69,6 +69,7 @@ private:
Common::String _text;
uint _clickHandler;
int _alpha;
+ bool _active;
public:
Object(const Common::String &name, Common::SeekableReadStream * stream);
@@ -159,6 +160,12 @@ public:
KeyHandlersType::const_iterator i = _keyHandlers.find(name);
return i != _keyHandlers.end()? i->_value: 0;
}
+
+ bool isActive() const
+ { return _active; }
+
+ void activate(bool active)
+ { _active = active; }
};
typedef Common::SharedPtr<Object> ObjectPtr;
diff --git a/engines/agds/process.h b/engines/agds/process.h
index d2ee8898c40..e4b1b8a6ec6 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -303,6 +303,10 @@ private:
public:
Process(AGDSEngine *engine, ObjectPtr object, unsigned ip = 0);
+ ObjectPtr getObject() const {
+ return _object;
+ }
+
const Common::String & getName() const {
return _object->getName();
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f52c72d41c1..803ad552f89 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -423,7 +423,8 @@ void Process::changeScreenPatch() {
screenName = screen->getName();
//change screen patch (load and return 1)
- int value = 0;
+ ObjectPtr object = screen->find(objectName);
+ int value = object && object->isActive();
debug("changeScreenPatch: screen: %s, object: %s -> %d", screenName.c_str(), objectName.c_str(), value);
push(value);
}
Commit: af3d96f5f763a34bc1bd2af3e2367555f24eedd4
https://github.com/scummvm/scummvm/commit/af3d96f5f763a34bc1bd2af3e2367555f24eedd4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:06+01:00
Commit Message:
AGDS: implement proper animation phase logic for characters
Changed paths:
engines/agds/character.h
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 1d0d6244eb1..e49b72b257d 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -36,10 +36,12 @@ class AGDSEngine;
class Object;
class Character {
- int _counter;
+ bool _enabled;
+ int _phase;
+ int _frames;
public:
- Character(): _counter(-1) {
+ Character(): _enabled(true), _phase(0), _frames(0) {
}
bool load(Common::SeekableReadStream* stream) {
@@ -47,19 +49,21 @@ public:
}
void enable(bool enabled = true) {
+ _enabled = enabled;
}
void animate(int frames) {
- _counter = frames;
+ _phase = 0;
+ _frames = frames;
}
int getPhase() const {
- return _counter;
+ return _phase < _frames? _phase: -1;
}
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer) {
- if (_counter >= 0)
- --_counter;
+ if (_enabled && _phase < _frames)
+ ++_phase;
}
};
Commit: 7ecd56aca76ff33791faff4df96c4fac201bd3b5
https://github.com/scummvm/scummvm/commit/7ecd56aca76ff33791faff4df96c4fac201bd3b5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:06+01:00
Commit Message:
AGDS: add some text stubs
Changed paths:
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.h b/engines/agds/process.h
index e4b1b8a6ec6..4405d476726 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -250,6 +250,7 @@ private:
void stub231();
void stub233();
void stub235();
+ void stub244();
void debug(const char *str, ...);
void error(const char *str, ...);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 803ad552f89..24069fe52d9 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -770,6 +770,8 @@ void Process::runDialog() {
arg3 = _engine->loadText(arg3);
debug("definition:\n%s", arg3.c_str());
debug("dialog:\n%s", arg2.c_str());
+
+ _engine->getSystemVariable("dialog_var")->setInteger(1);
suspend(kExitCodeRunDialog, arg1);
}
@@ -1087,6 +1089,15 @@ void Process::stub235() {
suspend();
}
+void Process::stub244() {
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+
+ debug("stub244 [text tell status?] %s %s", arg1.c_str(), arg2.c_str());
+ _engine->setGlobal(arg1, 1);
+ _engine->setGlobal(arg2, 1);
+ _engine->getSystemVariable("dialog_var")->setInteger(1);
+}
//fixme: add trace here
@@ -1291,6 +1302,7 @@ ProcessExitCode Process::execute() {
OP (kStub231, stub231);
OP (kStub233, stub233);
OP (kStub235, stub235);
+ OP (kStub244, stub244);
OP (kInventoryHasObject, inventoryHasObject);
OP (kRunDialog, runDialog);
OP (kHasGlobal, hasGlobal);
Commit: c5bf06c73057c69b6db46fdc263888b7b46f8ede
https://github.com/scummvm/scummvm/commit/c5bf06c73057c69b6db46fdc263888b7b46f8ede
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:06+01:00
Commit Message:
AGDS: implement runDialog stub with defs parsing
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 5282836b464..4833d9b6292 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -47,7 +47,8 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_defaultMouseCursor(),
_mouse(400, 300), _userEnabled(false), _currentRegion(),
_random("agds"), _soundManager(this, system->getMixer()),
- _fastMode(false) {
+ _fastMode(false),
+ _dialogScriptPos(0) {
}
AGDSEngine::~AGDSEngine() {
@@ -618,6 +619,45 @@ SystemVariable *AGDSEngine::getSystemVariable(const Common::String &name) {
error("no system variable %s", name.c_str());
}
+void AGDSEngine::runDialog(const Common::String &dialogScript, const Common::String & defs) {
+ parseDialogDefs(defs);
+ _dialogScript = dialogScript;
+ debug("dialog:\n%s", dialogScript.c_str());
+ _dialogScriptPos = 0;
+ getSystemVariable("dialog_var")->setInteger(-1);
+}
+
+void AGDSEngine::parseDialogDefs(const Common::String &defs) {
+ Common::String name, value;
+ bool readName = true;
+ for(uint32 p = 0, size = defs.size(); p < size; ++p) {
+ char ch = defs[p];
+ if (ch == ' ') {
+ continue;
+ } else if (ch == '\n' || ch == '\r') {
+ debug("dialog definition: '%s' = '%s'", name.c_str(), value.c_str());
+ if (!name.empty() && !value.empty()) {
+ _dialogDefs[name] = atoi(value.c_str());
+ }
+ readName = true;
+ name.clear();
+ value.clear();
+ continue;
+ } else if (ch == '=') {
+ if (readName) {
+ readName = false;
+ } else {
+ warning("equal sign in value, skipping");
+ }
+ } else {
+ if (readName)
+ name += ch;
+ else
+ value += ch;
+ }
+ }
+}
+
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 3c545a81b5f..88a0efe29f3 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -164,7 +164,11 @@ public:
void initSystemVariables();
SystemVariable *getSystemVariable(const Common::String &name);
+ void runDialog(const Common::String &dialogScript, const Common::String & defs);
+
private:
+ void parseDialogDefs(const Common::String &defs);
+
typedef Common::HashMap<int, Graphics::TransparentSurface *> PictureCacheType;
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
typedef Common::HashMap<Common::String, Region *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> RegionsType;
@@ -173,6 +177,7 @@ private:
typedef Common::HashMap<Common::String, Animation *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> AnimationsType;
typedef Common::HashMap<Common::String, Character *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> CharactersType;
typedef Common::HashMap<int, Font *> FontsType;
+ typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> DialogDefsType;
const ADGameDescription * _gameDescription;
ResourceManager _resourceManager;
@@ -203,6 +208,9 @@ private:
Common::RandomSource _random;
Inventory _inventory;
bool _fastMode;
+ DialogDefsType _dialogDefs;
+ Common::String _dialogScript;
+ uint32 _dialogScriptPos;
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 24069fe52d9..d8250f8a04c 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -768,10 +768,9 @@ void Process::runDialog() {
debug("runDialog %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
arg2 = _engine->loadText(arg2);
arg3 = _engine->loadText(arg3);
- debug("definition:\n%s", arg3.c_str());
- debug("dialog:\n%s", arg2.c_str());
- _engine->getSystemVariable("dialog_var")->setInteger(1);
+ _engine->runDialog(arg2, arg3);
+
suspend(kExitCodeRunDialog, arg1);
}
Commit: a49b59ede499e3db58d33c0fc92c15f6b7c2507f
https://github.com/scummvm/scummvm/commit/a49b59ede499e3db58d33c0fc92c15f6b7c2507f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:06+01:00
Commit Message:
AGDS: uncommented extended region entries
Changed paths:
engines/agds/region.cpp
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index fc9388d2cc3..74129221a7a 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -51,11 +51,11 @@ Region::Region(const Common::String &resourceName, Common::SeekableReadStream *
while(ext--) {
int16 a = stream->readSint16LE();
int16 b = stream->readSint16LE();
- /* int16 c = */ stream->readUint16LE();
-// if (c != -12851) //0xcdcd
-// debug("extended entry: %d %d %d", a, b, c);
-// else
-// debug("extended entry: %d %d", a, b);
+ int16 c = stream->readUint16LE();
+ if (c != -12851) //0xcdcd
+ debug("extended entry: %d %d %d", a, b, c);
+ else
+ debug("extended entry: %d %d", a, b);
points.push_back(Common::Point(a, b));
}
if (stream->pos() != size)
Commit: a00bbf0ee6dd848cfe8a68ecbab5602539e6d318
https://github.com/scummvm/scummvm/commit/a00bbf0ee6dd848cfe8a68ecbab5602539e6d318
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:06+01:00
Commit Message:
AGDS: timer is per-process, not per-engine
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 4833d9b6292..6724cfdbaed 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -42,7 +42,7 @@
namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Engine(system),
- _gameDescription(gameDesc), _pictureCacheId(0), _sharedStorageIndex(-2), _timer(0),
+ _gameDescription(gameDesc), _pictureCacheId(0), _sharedStorageIndex(-2),
_mjpgPlayer(), _currentScreen(), _previousScreen(),
_defaultMouseCursor(),
_mouse(400, 300), _userEnabled(false), _currentRegion(),
@@ -206,6 +206,9 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
return;
}
+ if (!process.active())
+ return;
+
const Common::String &name = process.getName();
if (process.getStatus() == Process::kStatusDone || process.getStatus() == Process::kStatusError) {
debug("process %s finished", name.c_str());
@@ -303,9 +306,6 @@ Common::Error AGDSEngine::run() {
while(!shouldQuit()) {
uint32 frameStarted = _system->getMillis();
- if (_timer > 0)
- --_timer;
-
Common::Event event;
while(eventManager->pollEvent(event)) {
if (!_currentScreen)
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 88a0efe29f3..3dbe1e3a78d 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -103,11 +103,7 @@ public:
int appendToSharedStorage(const Common::String &value);
const Common::String & getSharedStorage(int id) const;
- void setTimer(int timer) {
- _timer = timer;
- }
-
- bool active() const { return _timer <= 0 && !_mjpgPlayer; }
+ bool active() const { return !_mjpgPlayer; }
void playFilm(const Common::String &video, const Common::String &audio);
void skipFilm();
@@ -194,7 +190,6 @@ private:
Common::String _sharedStorage[10];
GlobalsType _globals;
SystemVariablesType _systemVars;
- int _timer;
Graphics::PixelFormat _pixelFormat;
MJPGPlayer * _mjpgPlayer;
Screen * _currentScreen;
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 0daa7ea5d39..d53fe2c12c1 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -29,7 +29,8 @@ namespace AGDS {
Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
_engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object), _ip(ip), _status(kStatusActive), _exitCode(kExitCodeDestroy),
- _glyphWidth(16), _glyphHeight(16) {
+ _glyphWidth(16), _glyphHeight(16),
+ _timer(0) {
}
void Process::debug(const char *str, ...) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 4405d476726..18b8ea5780a 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -52,6 +52,7 @@ private:
int _exitIntArg1, _exitIntArg2;
int _glyphWidth, _glyphHeight;
Common::String _phaseVar;
+ int _timer;
private:
uint8 next() {
@@ -344,6 +345,13 @@ public:
return _exitIntArg2;
}
+ bool active() {
+ if (_timer <= 0)
+ return true;
+ --_timer;
+ return false;
+ }
+
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d8250f8a04c..33f16777bdc 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1061,7 +1061,7 @@ void Process::setAnimationPosition() {
void Process::setTimer() {
int value = pop();
debug("setTimer %d", value);
- _engine->setTimer(value);
+ _timer = value;
suspend();
}
Commit: 997fe75abce2530f81caee3907e13808dcc4647a
https://github.com/scummvm/scummvm/commit/997fe75abce2530f81caee3907e13808dcc4647a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:06+01:00
Commit Message:
AGDS: added some magic dialog_var values, handle end of the dialog
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 6724cfdbaed..c44ab66e5ec 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -267,7 +267,8 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
++it;
}
-void AGDSEngine::runProcess() {
+void AGDSEngine::tick() {
+ tickDialog();
for(ProcessListType::iterator p = _processes.begin(); active() && p != _processes.end(); ) {
runProcess(p);
}
@@ -396,7 +397,7 @@ Common::Error AGDSEngine::run() {
_soundManager.tick();
if (active())
- runProcess();
+ tick();
Graphics::Surface *backbuffer = _system->lockScreen();
backbuffer->fillRect(backbuffer->getRect(), 0);
@@ -635,7 +636,7 @@ void AGDSEngine::parseDialogDefs(const Common::String &defs) {
if (ch == ' ') {
continue;
} else if (ch == '\n' || ch == '\r') {
- debug("dialog definition: '%s' = '%s'", name.c_str(), value.c_str());
+ //debug("dialog definition: '%s' = '%s'", name.c_str(), value.c_str());
if (!name.empty() && !value.empty()) {
_dialogDefs[name] = atoi(value.c_str());
}
@@ -658,6 +659,46 @@ void AGDSEngine::parseDialogDefs(const Common::String &defs) {
}
}
+void AGDSEngine::tickDialog() {
+ uint n = _dialogScript.size();
+ if (_dialogScriptPos >= n)
+ return;
+
+ Common::String line;
+ while(_dialogScriptPos < n && _dialogScript[_dialogScriptPos] != '\n' && _dialogScript[_dialogScriptPos] != '\r') {
+ line += _dialogScript[_dialogScriptPos++];
+ }
+ ++_dialogScriptPos;
+
+ if (line.empty())
+ return;
+
+ if (line[0] == '@') {
+ if (line[1] == '@') //comment
+ return;
+
+ line.erase(0, 1);
+
+ if (line.hasPrefix("sound")) {
+ debug("sound: %s", line.c_str());
+ } else {
+ DialogDefsType::const_iterator it = _dialogDefs.find(line);
+ if (it != _dialogDefs.end()) {
+ int value = it->_value;
+ debug("dialog value %d (0x%04x)", value, value);
+ getSystemVariable("dialog_var")->setInteger(value);
+ } else
+ warning("invalid dialog directive: %s", line.c_str());
+ }
+ } else if (line[0] == ' ') {
+ debug("text: %s", line.c_str() + 1);
+ }
+ if (_dialogScriptPos >= n) {
+ debug("end of dialog");
+ getSystemVariable("dialog_var")->setInteger(-2);
+ }
+}
+
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 3dbe1e3a78d..6b96b4c4056 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -85,7 +85,7 @@ private:
bool initGraphics();
bool load();
void runProcess(ProcessListType::iterator &it);
- void runProcess();
+ void tick();
public:
ObjectPtr loadObject(const Common::String & name, const Common::String & prototype = Common::String());
@@ -161,6 +161,7 @@ public:
SystemVariable *getSystemVariable(const Common::String &name);
void runDialog(const Common::String &dialogScript, const Common::String & defs);
+ void tickDialog();
private:
void parseDialogDefs(const Common::String &defs);
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index a9b91619e9c..fa3e2006225 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -145,7 +145,7 @@ enum Opcode {
kStub125 = 125,
kStub126 = 126,
kSetTimer = 127,
- kProcessCleanupStub128 = 128,
+ kProcessResetState = 128,
kStub129 = 129,
kSetCycles = 130,
kSetRandom = 131,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 18b8ea5780a..63912c1a4b7 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -215,7 +215,7 @@ private:
void stub83();
void stub102();
void stub119();
- void stub128();
+ void resetState();
void stub129();
void setCycles();
void setRandom();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 33f16777bdc..a1a81a79b96 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -495,8 +495,8 @@ void Process::stub119() {
debug("stub119");
}
-void Process::stub128() {
- debug("processCleanupStub128");
+void Process::resetState() {
+ debug("process reset state");
_phaseVar.clear();
}
@@ -1220,7 +1220,7 @@ ProcessExitCode Process::execute() {
OP (kPlayerSay, playerSay);
OP (kNPCSay, npcSay);
OP (kSetTimer, setTimer);
- OP (kProcessCleanupStub128, stub128);
+ OP (kProcessResetState, resetState);
OP (kStub129, stub129);
OP (kSetCycles, setCycles);
OP (kSetRandom, setRandom);
Commit: 58803d9d52b0622ab2816aceeeb62e0a06051159
https://github.com/scummvm/scummvm/commit/58803d9d52b0622ab2816aceeeb62e0a06051159
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:06+01:00
Commit Message:
AGDS: schedule dialog process after dialog finished
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c44ab66e5ec..2ef12fe0eec 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -225,9 +225,11 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
break;
case kExitCodeLoadScreenObjectAs:
case kExitCodeLoadScreenObject:
- case kExitCodeRunDialog:
runObject(process.getExitArg1(), process.getExitArg2());
break;
+ case kExitCodeRunDialog:
+ _dialogProcessName = process.getExitArg1();
+ break;
case kExitCodeSetNextScreen:
loadScreen(process.getExitArg1());
destroy = true;
@@ -693,7 +695,11 @@ void AGDSEngine::tickDialog() {
} else if (line[0] == ' ') {
debug("text: %s", line.c_str() + 1);
}
- if (_dialogScriptPos >= n) {
+ if (_dialogScriptPos >= n && !_dialogProcessName.empty()) {
+ Common::String process = _dialogProcessName;
+ _dialogProcessName.clear();
+
+ runObject(process);
debug("end of dialog");
getSystemVariable("dialog_var")->setInteger(-2);
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 6b96b4c4056..7ac8c7e35b6 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -207,6 +207,7 @@ private:
DialogDefsType _dialogDefs;
Common::String _dialogScript;
uint32 _dialogScriptPos;
+ Common::String _dialogProcessName;
};
Commit: ec68759c69eeb17bf0c85311a5fc075ccf0a9b1f
https://github.com/scummvm/scummvm/commit/ec68759c69eeb17bf0c85311a5fc075ccf0a9b1f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:06+01:00
Commit Message:
AGDS: removed dialog from logs
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 2ef12fe0eec..29ba0ecd2a1 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -625,7 +625,6 @@ SystemVariable *AGDSEngine::getSystemVariable(const Common::String &name) {
void AGDSEngine::runDialog(const Common::String &dialogScript, const Common::String & defs) {
parseDialogDefs(defs);
_dialogScript = dialogScript;
- debug("dialog:\n%s", dialogScript.c_str());
_dialogScriptPos = 0;
getSystemVariable("dialog_var")->setInteger(-1);
}
Commit: 9541e4aaf2ada115e709ad6f69db8b6284fd6076
https://github.com/scummvm/scummvm/commit/9541e4aaf2ada115e709ad6f69db8b6284fd6076
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:06+01:00
Commit Message:
AGDS: more dialog state transitions
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 29ba0ecd2a1..189c097e902 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -661,6 +661,18 @@ void AGDSEngine::parseDialogDefs(const Common::String &defs) {
}
void AGDSEngine::tickDialog() {
+ if (_dialogProcessName.empty())
+ return;
+
+ int dialog_var = getSystemVariable("dialog_var")->getInteger();
+ if (dialog_var > 0) {
+ getSystemVariable("dialog_var")->setInteger(-3);
+ return;
+ } else if (dialog_var < 0) {
+ getSystemVariable("dialog_var")->setInteger(0);
+ return;
+ }
+
uint n = _dialogScript.size();
if (_dialogScriptPos >= n)
return;
Commit: 0d5e00c3d7b52bfd9149fc5646945c15515677ef
https://github.com/scummvm/scummvm/commit/0d5e00c3d7b52bfd9149fc5646945c15515677ef
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:06+01:00
Commit Message:
AGDS: animation frames start from 1 and goes to N (inclusive)
Changed paths:
engines/agds/character.h
diff --git a/engines/agds/character.h b/engines/agds/character.h
index e49b72b257d..1d37a92c5a8 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -58,11 +58,11 @@ public:
}
int getPhase() const {
- return _phase < _frames? _phase: -1;
+ return _phase <= _frames? _phase + 1: -1;
}
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer) {
- if (_enabled && _phase < _frames)
+ if (_enabled && _phase <= _frames)
++_phase;
}
Commit: 39efed20532b732922252e9cd403c5b34a59291c
https://github.com/scummvm/scummvm/commit/39efed20532b732922252e9cd403c5b34a59291c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:07+01:00
Commit Message:
AGDS: implemented stubs 154/155
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index a1a81a79b96..4d7ce010548 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -542,13 +542,15 @@ void Process::stub153() {
void Process::stub154() {
Common::String name = popString();
debug("stub154(getSomeX): %s", name.c_str());
- push(154);
+ ObjectPtr object = _engine->getCurrentScreenObject(name);
+ push(object->getPosition().x);
}
void Process::stub155() {
Common::String name = popString();
- debug("stub154(getSomeY): %s", name.c_str());
- push(155);
+ debug("stub155(getSomeY): %s", name.c_str());
+ ObjectPtr object = _engine->getCurrentScreenObject(name);
+ push(object->getPosition().y);
}
void Process::stub160() {
Commit: 47d4efa7b3922b98f3c7b1ee55676e1e5ced8297
https://github.com/scummvm/scummvm/commit/47d4efa7b3922b98f3c7b1ee55676e1e5ced8297
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:07+01:00
Commit Message:
AGDS: log dialog object
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 189c097e902..e9525e66a47 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -710,8 +710,8 @@ void AGDSEngine::tickDialog() {
Common::String process = _dialogProcessName;
_dialogProcessName.clear();
+ debug("end of dialog, running %s", process.c_str());
runObject(process);
- debug("end of dialog");
getSystemVariable("dialog_var")->setInteger(-2);
}
}
Commit: 9d34468e014b3f00aa383cec5871a470b4e69be5
https://github.com/scummvm/scummvm/commit/9d34468e014b3f00aa383cec5871a470b4e69be5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:07+01:00
Commit Message:
AGDS: added enableUser from fadescreen
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4d7ce010548..13aad60f8e1 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1086,6 +1086,7 @@ void Process::stub235() {
int arg2 = pop();
int arg1 = pop();
debug("stub235 (fadeScreen?) %d %d %d", arg1, arg2, arg3);
+ enableUser();
if (_status == kStatusPassive)
suspend();
}
Commit: f6087e9a238815840dc042dbf0d8c02fde51ec89
https://github.com/scummvm/scummvm/commit/f6087e9a238815840dc042dbf0d8c02fde51ec89
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:07+01:00
Commit Message:
AGDS: removed mouse area code, it's already handled in changeMouseArea
Changed paths:
engines/agds/agds.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index e9525e66a47..0113047331c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -279,6 +279,7 @@ void AGDSEngine::tick() {
void AGDSEngine::changeMouseArea(int id, int enabled) {
if (id < 0)
return;
+ debug("changeMouseArea %d %s", id, enabled? "enabled": "disabled");
MouseRegion * mouseArea = _mouseMap.find(id);
if (mouseArea) {
switch(enabled) {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 13aad60f8e1..33e960986df 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -632,11 +632,6 @@ void Process::modifyMouseArea() {
int enabled = pop();
int id = pop();
debug("modifyMouseArea %d, %d", id, enabled);
- MouseRegion * region = _engine->_mouseMap.find(id);
- if (region) {
- region->enabled = enabled;
- } else
- warning("modifyMouseArea: mouse region %d not found", id);
suspend(kExitCodeMouseAreaChange, id, enabled);
}
Commit: 25fcdf3f39b193442c7c620fdbd6e92de18f93b9
https://github.com/scummvm/scummvm/commit/25fcdf3f39b193442c7c620fdbd6e92de18f93b9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:07+01:00
Commit Message:
AGDS: added inventory enable/disable implementation + tick stub
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/inventory.cpp
engines/agds/inventory.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 0113047331c..750fedc1e95 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -271,6 +271,7 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
void AGDSEngine::tick() {
tickDialog();
+ tickInventory();
for(ProcessListType::iterator p = _processes.begin(); active() && p != _processes.end(); ) {
runProcess(p);
}
@@ -279,7 +280,8 @@ void AGDSEngine::tick() {
void AGDSEngine::changeMouseArea(int id, int enabled) {
if (id < 0)
return;
- debug("changeMouseArea %d %s", id, enabled? "enabled": "disabled");
+
+ debug("changeMouseArea %d %d", id, enabled);
MouseRegion * mouseArea = _mouseMap.find(id);
if (mouseArea) {
switch(enabled) {
@@ -287,14 +289,12 @@ void AGDSEngine::changeMouseArea(int id, int enabled) {
mouseArea->enable();
break;
case 0:
- case -1:
if (mouseArea->currentlyIn) {
runObject(mouseArea->onLeave);
}
mouseArea->disable();
- if (enabled == -1) {
- _mouseMap.remove(id);
- }
+ break;
+ case -1:
break;
}
} else
@@ -661,6 +661,19 @@ void AGDSEngine::parseDialogDefs(const Common::String &defs) {
}
}
+void AGDSEngine::tickInventory() {
+ if (!_inventory.enabled())
+ return;
+
+ const Common::String & inv_region_name = getSystemVariable("inv_region")->getString();
+ if (inv_region_name.empty())
+ return;
+
+ Region * inv_region = loadRegion(inv_region_name);
+ if (!inv_region)
+ return;
+}
+
void AGDSEngine::tickDialog() {
if (_dialogProcessName.empty())
return;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 7ac8c7e35b6..79daca1847b 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -162,6 +162,7 @@ public:
void runDialog(const Common::String &dialogScript, const Common::String & defs);
void tickDialog();
+ void tickInventory();
private:
void parseDialogDefs(const Common::String &defs);
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 1d95f38881a..9993bdc4eac 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -26,7 +26,8 @@
#include "common/textconsole.h"
namespace AGDS {
-Inventory::Inventory(): _entries(kMaxSize) { }
+
+Inventory::Inventory(): _entries(kMaxSize), _enabled(true) { }
Inventory::~Inventory() { }
int Inventory::free() const {
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index 4bc662089b4..fc8cfb6a37b 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -34,6 +34,7 @@ typedef Common::SharedPtr<Object> ObjectPtr;
class Inventory {
typedef Common::Array<ObjectPtr> EntriesType;
EntriesType _entries;
+ bool _enabled;
public:
static const int kMaxSize = 35;
@@ -41,6 +42,13 @@ public:
Inventory();
~Inventory();
+ bool enabled() const {
+ return _enabled;
+ }
+ void enable(bool enabled) {
+ _enabled = enabled;
+ }
+
int add(ObjectPtr object);
ObjectPtr get(int index) const {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 33e960986df..382a770df88 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -869,10 +869,12 @@ void Process::loadPreviousScreen() {
void Process::disableInventory() {
debug("disableInventory");
+ _engine->inventory().enable(false);
}
void Process::enableInventory() {
debug("enableInventory");
+ _engine->inventory().enable(true);
}
void Process::setObjectHeight() {
Commit: 6462aa84b1b0b769e4aeeaa918867a2e6af98cb0
https://github.com/scummvm/scummvm/commit/6462aa84b1b0b769e4aeeaa918867a2e6af98cb0
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:07+01:00
Commit Message:
AGDS: removed `stub` word from getCharacterPhase
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 382a770df88..3d11f6333ae 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1010,7 +1010,7 @@ void Process::pointCharacter() {
void Process::getCharacterAnimationPhase() {
Common::String name = popString();
- debug("getCharacterAnimationPhase: stub %s", name.c_str());
+ debug("getCharacterAnimationPhase: %s", name.c_str());
Character *character = _engine->getCharacter(name);
int phase = character? character->getPhase(): -1;
debug("animation phase = %d", phase);
Commit: 66326e76e72574e392e5a51a4745cbd1489b9ce9
https://github.com/scummvm/scummvm/commit/66326e76e72574e392e5a51a4745cbd1489b9ce9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:07+01:00
Commit Message:
AGDS: added missing pop() in stub200
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3d11f6333ae..f8fefcd8cbf 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -610,7 +610,8 @@ void Process::stub199() {
void Process::stub200() {
int value = pop();
- debug("stub200: %d", value);
+ int resource = pop();
+ debug("stub200: %d %d", value, resource);
}
void Process::stub201(unsigned size) {
Commit: ca316c6bebfcfc0c3fc85cc259a9d8460774b52f
https://github.com/scummvm/scummvm/commit/ca316c6bebfcfc0c3fc85cc259a9d8460774b52f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:07+01:00
Commit Message:
AGDS: assorted fixes of inventory related opcodes
Changed paths:
engines/agds/agds.cpp
engines/agds/inventory.cpp
engines/agds/inventory.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 750fedc1e95..3599272e3eb 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -662,8 +662,19 @@ void AGDSEngine::parseDialogDefs(const Common::String &defs) {
}
void AGDSEngine::tickInventory() {
- if (!_inventory.enabled())
- return;
+ if (!_inventory.enabled() && _inventory.visible()) {
+ debug("closing inventory...");
+ Common::String inv_close = getSystemVariable("inv_close")->getString();
+ if (!inv_close.empty())
+ runObject(inv_close);
+ _inventory.visible(false);
+ } else if (_inventory.enabled() && !_inventory.visible()) {
+ debug("opening inventory...");
+ Common::String inv_open = getSystemVariable("inv_open")->getString();
+ if (!inv_open.empty())
+ runObject(inv_open);
+ _inventory.visible(true);
+ }
const Common::String & inv_region_name = getSystemVariable("inv_region")->getString();
if (inv_region_name.empty())
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 9993bdc4eac..04ca042dbcf 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -27,7 +27,7 @@
namespace AGDS {
-Inventory::Inventory(): _entries(kMaxSize), _enabled(true) { }
+Inventory::Inventory(): _entries(kMaxSize), _enabled(false) { }
Inventory::~Inventory() { }
int Inventory::free() const {
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index fc8cfb6a37b..322bbd2f841 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -35,6 +35,7 @@ class Inventory {
typedef Common::Array<ObjectPtr> EntriesType;
EntriesType _entries;
bool _enabled;
+ bool _visible;
public:
static const int kMaxSize = 35;
@@ -49,10 +50,18 @@ public:
_enabled = enabled;
}
+ bool visible() const {
+ return _visible;
+ }
+
+ void visible(bool visible) {
+ _visible = visible;
+ }
+
int add(ObjectPtr object);
ObjectPtr get(int index) const {
- return _entries[index];
+ return index >= 0 && index < kMaxSize? _entries[index]: ObjectPtr();
}
int find(const Common::String &name) const;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index fa3e2006225..cd9d99749e1 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -81,7 +81,7 @@ enum Opcode {
kCallImm16 = 59,
kObjectRegisterLookHandler = 60,
kObjectRegisterUseHandler = 61,
- kStub62 = 62,
+ kObjectRegisterHandlerC1 = 62,
kStub63 = 63,
kScreenRegisterHandlerBD = 64,
kStub65 = 65,
@@ -203,7 +203,7 @@ enum Opcode {
kGenerateRegion = 183,
kStub184 = 184,
kGetMaxInventorySize = 185,
- kStub186 = 186,
+ kInventoryHasObject = 186,
kAppendInventoryObjectNameToSharedSpace = 187,
kSetObjectText = 188,
kStub189 = 189,
@@ -255,7 +255,7 @@ enum Opcode {
kStub235 = 235,
kStub236 = 236,
kStub237 = 237,
- kInventoryHasObject = 238,
+ kInventoryFindObjectByName = 238,
kStub239 = 239,
kRunDialog = 240,
kStub241 = 241,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 63912c1a4b7..4e468e1ca0d 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -110,6 +110,7 @@ private:
void inventoryClear();
void inventoryAddObject();
void inventoryHasObject();
+ void inventoryFindObjectByName();
void getMaxInventorySize();
void getInventoryFreeSpace();
void appendInventoryObjectNameToSharedSpace();
@@ -208,6 +209,7 @@ private:
void onKey(unsigned size);
void onUse(unsigned size);
void onLook(unsigned size);
+ void onObjectC1(unsigned size);
void onScreenBD(unsigned size);
void stub63(unsigned size);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f8fefcd8cbf..aa10a3523d8 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -543,14 +543,14 @@ void Process::stub154() {
Common::String name = popString();
debug("stub154(getSomeX): %s", name.c_str());
ObjectPtr object = _engine->getCurrentScreenObject(name);
- push(object->getPosition().x);
+ push(0);
}
void Process::stub155() {
Common::String name = popString();
debug("stub155(getSomeY): %s", name.c_str());
ObjectPtr object = _engine->getCurrentScreenObject(name);
- push(object->getPosition().y);
+ push(0);
}
void Process::stub160() {
@@ -824,14 +824,22 @@ void Process::inventoryAddObject() {
suspend(kExitCodeLoadInventoryObject, name);
}
-void Process::inventoryHasObject() {
+void Process::inventoryFindObjectByName() {
Common::String name = popString();
- debug("inventoryHasObject %s", name.c_str());
+ debug("inventoryFindObjectByName %s", name.c_str());
int index = _engine->inventory().find(name);
debug("\t->%d", index);
push(index);
}
+void Process::inventoryHasObject() {
+ int index = pop();
+ debug("inventoryHasObject %d", index);
+ bool hasObject = _engine->inventory().get(index);
+ debug("\t->%d", hasObject);
+ push(hasObject);
+}
+
void Process::getMaxInventorySize() {
int size = _engine->inventory().maxSize();
debug("getMaxInventorySize -> %d", size);
@@ -916,6 +924,11 @@ void Process::onUse(unsigned size) {
_ip += size;
}
+void Process::onObjectC1(unsigned size) {
+ debug("unknown (0xc1) [handler], %u instructions", size);
+ _ip += size;
+}
+
void Process::onLook(unsigned size) {
debug("look? [handler], %u instructions", size);
_ip += size;
@@ -1180,7 +1193,7 @@ ProcessExitCode Process::execute() {
OP_U (kCallImm16, call);
OP_U (kObjectRegisterLookHandler, onLook);
OP_U (kObjectRegisterUseHandler, onUse);
- OP_U (kStub63, stub63);
+ OP_U (kObjectRegisterHandlerC1, onObjectC1);
OP_U (kScreenRegisterHandlerBD, onScreenBD);
OP (kLoadMouseCursorFromObject, loadMouseCursorFromObject);
OP (kLoadRegionFromObject, loadRegionFromObject);
@@ -1202,6 +1215,7 @@ ProcessExitCode Process::execute() {
OP (kLoadMouse, loadMouse);
OP (kInventoryAddObject, inventoryAddObject);
OP (kSetNextScreenSaveInHistory, setNextScreenSaveInHistory);
+ OP_U (kStub63, stub63);
OP (kStub82, stub82);
OP (kStub83, stub83);
OP (kAnimateCharacter, animateCharacter);
@@ -1268,6 +1282,7 @@ ProcessExitCode Process::execute() {
OP (kGetMaxInventorySize, getMaxInventorySize);
OP (kAppendInventoryObjectNameToSharedSpace, appendInventoryObjectNameToSharedSpace);
OP (kStub184, stub184);
+ OP (kInventoryHasObject, inventoryHasObject);
OP (kSetObjectText, setObjectText);
OP (kStub190, stub190);
OP (kStub191, disableMouseAreas);
@@ -1303,7 +1318,7 @@ ProcessExitCode Process::execute() {
OP (kStub233, stub233);
OP (kStub235, stub235);
OP (kStub244, stub244);
- OP (kInventoryHasObject, inventoryHasObject);
+ OP (kInventoryFindObjectByName, inventoryFindObjectByName);
OP (kRunDialog, runDialog);
OP (kHasGlobal, hasGlobal);
OP (kSetDialogForNextFilm, setDialogForNextFilm);
Commit: 2b91921808bc2e82da02becdb055dc139eb2e923
https://github.com/scummvm/scummvm/commit/2b91921808bc2e82da02becdb055dc139eb2e923
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:07+01:00
Commit Message:
AGDS: cleaned up mouse area handling
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3599272e3eb..7508d7cf7f9 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -281,20 +281,23 @@ void AGDSEngine::changeMouseArea(int id, int enabled) {
if (id < 0)
return;
- debug("changeMouseArea %d %d", id, enabled);
MouseRegion * mouseArea = _mouseMap.find(id);
if (mouseArea) {
switch(enabled) {
case 1:
+ debug("enabling mouse area %d", id);
mouseArea->enable();
break;
case 0:
+ debug("disabling mouse area %d", id);
if (mouseArea->currentlyIn) {
runObject(mouseArea->onLeave);
}
mouseArea->disable();
break;
case -1:
+ debug("removing mouse area %d", id);
+ _mouseMap.remove(id);
break;
}
} else
Commit: d4856c57d52ffb06b88b836649c4a6011623852e
https://github.com/scummvm/scummvm/commit/d4856c57d52ffb06b88b836649c4a6011623852e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:07+01:00
Commit Message:
AGDS: cleaned up sounds a bit, added support for text voice over
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 7508d7cf7f9..afbbb76ace3 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -168,6 +168,7 @@ void AGDSEngine::runObject(const Common::String & name, const Common::String &pr
void AGDSEngine::loadScreen(const Common::String & name) {
debug("loadScreen %s", name.c_str());
resetCurrentScreen();
+ _soundManager.stopAll();
_currentScreenName = name;
_currentScreen = new Screen(loadObject(name), _mouseMap);
_mouseMap.clear();
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 79daca1847b..c6418a59b98 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -164,6 +164,10 @@ public:
void tickDialog();
void tickInventory();
+ void playSound(const Common::String &resource, const Common::String &phaseVar) {
+ _soundManager.play(resource, phaseVar);
+ }
+
private:
void parseDialogDefs(const Common::String &defs);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index aa10a3523d8..862bbb3b28f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -124,7 +124,7 @@ void Process::loadSample() {
warning("playing sample %s without phase var", _phaseVar.c_str());
return;
}
- _engine->_soundManager.play(name, _phaseVar);
+ _engine->playSound(name, _phaseVar);
}
void Process::getSampleVolume() {
@@ -144,6 +144,7 @@ void Process::playSound() {
Common::String name = popText();
int arg = pop();
debug("playSound %s %d", name.c_str(), arg);
+ _engine->playSound(name, _phaseVar);
}
void Process::updatePhaseVarOr2() {
@@ -753,12 +754,15 @@ void Process::npcSay() {
}
void Process::playerSay() {
- Common::String arg3 = popString();
- Common::String arg2 = popString();
+ Common::String sound = popText();
+ Common::String arg2 = popText();
Common::String arg1 = popString();
- debug("playerSay %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
+ debug("playerSay '%s' '%s' '%s'", arg1.c_str(), arg2.c_str(), sound.c_str());
+ if (!sound.empty())
+ _engine->playSound(sound, _phaseVar);
//close inventory here if close flag was set
}
+
void Process::runDialog() {
Common::String arg3 = popString();
Common::String arg2 = popString();
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index fbc29aaf614..5a695e944d6 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -33,15 +33,25 @@
namespace AGDS {
void SoundManager::tick() {
+ for(SoundList::iterator i = _sounds.begin(); i != _sounds.end(); ) {
+ Sound & sound = *i;
+ if (!_mixer->isSoundHandleActive(sound.handle)) {
+ _engine->setGlobal(sound.phaseVar, -1);
+ i = _sounds.erase(i);
+ } else
+ ++i;
+ }
+ }
+
+ void SoundManager::stopAll() {
+ _mixer->stopAll();
for(SoundList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) {
Sound & sound = *i;
- int state = _engine->getGlobal(sound.phaseVar);
- state = 0;
- _mixer->isSoundHandleActive(sound.handle);
- _engine->setGlobal(sound.phaseVar, state);
+ _engine->setGlobal(sound.phaseVar, 0);
}
}
+
void SoundManager::play(const Common::String &resource, const Common::String &phaseVar) {
Common::File *file = new Common::File();
if (!file->open(resource))
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index c74354dea30..7112448a3b1 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -55,6 +55,7 @@ namespace AGDS {
SoundManager(AGDSEngine *engine, Audio::Mixer *mixer): _engine(engine), _mixer(mixer) { }
void tick();
void play(const Common::String &file, const Common::String &phaseVar);
+ void stopAll();
};
} // End of namespace AGDS
Commit: f8dbabbc3b3fb0ccdfa760f0a83b7e60d6be8543
https://github.com/scummvm/scummvm/commit/f8dbabbc3b3fb0ccdfa760f0a83b7e60d6be8543
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:08+01:00
Commit Message:
AGDS: cleaned up phase vars a bit, started investigating animations
Changed paths:
engines/agds/animation.h
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 8aeb6d5645f..9cd5b22a71f 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -37,11 +37,19 @@ class Object;
class Animation {
Video::FlicDecoder *_flic;
+ Common::String _phaseVar;
public:
Animation();
~Animation();
+ const Common::String & phaseVar() const {
+ return _phaseVar;
+ }
+ void phaseVar(const Common::String & phaseVar) {
+ _phaseVar = phaseVar;
+ }
+
bool load(Common::SeekableReadStream *stream);
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Common::Point dst);
int width() const;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 862bbb3b28f..edb666df06c 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -22,6 +22,7 @@
#include "agds/process.h"
#include "agds/agds.h"
+#include "agds/animation.h"
#include "agds/character.h"
#include "agds/opcode.h"
#include "agds/region.h"
@@ -1066,6 +1067,13 @@ void Process::loadPictureFromObject() {
void Process::loadAnimationFromObject() {
Common::String name = popText();
debug("loadAnimationFromObject %s", name.c_str());
+ if (!_phaseVar.empty()) {
+ _engine->setGlobal(_phaseVar, -2);
+
+ Animation * animation = _engine->loadAnimation(name);
+ if (animation)
+ animation->phaseVar(_phaseVar);
+ }
}
void Process::setAnimationPosition() {
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 5a695e944d6..c2b8ba47cd4 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -36,10 +36,15 @@ namespace AGDS {
for(SoundList::iterator i = _sounds.begin(); i != _sounds.end(); ) {
Sound & sound = *i;
if (!_mixer->isSoundHandleActive(sound.handle)) {
- _engine->setGlobal(sound.phaseVar, -1);
+ //FIXME: re-enable me later
+ // if (!sound.phaseVar.empty())
+ // _engine->setGlobal(sound.phaseVar, -1);
i = _sounds.erase(i);
- } else
+ } else {
+ // if (!sound.phaseVar.empty())
+ // _engine->setGlobal(sound.phaseVar, _engine->getGlobal(sound.phaseVar) + 1);
++i;
+ }
}
}
Commit: d54b5d3b20243ff4de8e24382e152950a558253f
https://github.com/scummvm/scummvm/commit/d54b5d3b20243ff4de8e24382e152950a558253f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:08+01:00
Commit Message:
AGDS: fixed typo
Changed paths:
engines/agds/character.h
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 1d37a92c5a8..fee371396cc 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -71,4 +71,4 @@ public:
} // End of namespace AGDS
-#endif /* AGDS_ANIMATION_H */
+#endif /* AGDS_CHARACTER_H */
Commit: d23092e96879e5d54f92b786e8e69c64db82bc6c
https://github.com/scummvm/scummvm/commit/d23092e96879e5d54f92b786e8e69c64db82bc6c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:08+01:00
Commit Message:
AGDS: fix animation phase control, implement loop, cycle
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/object.cpp
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index afbbb76ace3..b17e4ae65be 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -278,6 +278,14 @@ void AGDSEngine::tick() {
}
}
+Animation * AGDSEngine::loadMouseCursor(const Common::String &name) {
+ Animation *animation = loadAnimation(name);
+ animation->loop(true);
+ animation->phaseVar(Common::String());
+ animation->play();
+ return animation;
+}
+
void AGDSEngine::changeMouseArea(int id, int enabled) {
if (id < 0)
return;
@@ -507,6 +515,16 @@ Animation * AGDSEngine::loadAnimation(const Common::String &name) {
return animation;
}
+Animation * AGDSEngine::findAnimationByPhaseVar(const Common::String &phaseVar) {
+ for(AnimationsType::iterator i = _animations.begin(); i != _animations.end(); ++i) {
+ Animation * animation = i->_value;
+ if (animation->phaseVar() == phaseVar)
+ return animation;
+ }
+ return NULL;
+}
+
+
Character * AGDSEngine::loadCharacter(const Common::String &name) {
CharactersType::iterator i = _characters.find(name);
if (i != _characters.end())
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index c6418a59b98..422d6cc1301 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -146,12 +146,15 @@ public:
Font *getFont(int id) const;
Animation * loadAnimation(const Common::String &name);
+ Animation * loadMouseCursor(const Common::String &name);
+ Animation * findAnimationByPhaseVar(const Common::String &phaseVar);
Character * loadCharacter(const Common::String &name);
Character * getCharacter(const Common::String &name) const;
void loadDefaultMouseCursor(const Common::String &name) {
- _defaultMouseCursor = loadAnimation(name);
+ _defaultMouseCursor = loadMouseCursor(name);
}
+
void changeMouseArea(int id, int enabled);
void enableUser(bool enabled) {
_userEnabled = enabled;
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index dbf77283821..20ef9197c53 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -30,7 +30,7 @@
namespace AGDS {
-Animation::Animation(): _flic() {
+Animation::Animation(): _flic(), _loop(false), _cycles(1), _phase(0), _paused(true) {
}
Animation::~Animation() {
@@ -51,11 +51,24 @@ bool Animation::load(Common::SeekableReadStream* stream) {
void Animation::paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Common::Point dst) {
+ if (_cycles <= 0 || _paused) {
+ return;
+ }
+
const Graphics::Surface * frame = _flic->decodeNextFrame();
if (!frame) {
+ if (!_loop && --_cycles <= 0) {
+ _phase = -1; //end of animation
+ return;
+ }
+ _phase = 0;
_flic->rewind();
frame = _flic->decodeNextFrame();
- }
+ if (!frame)
+ error("failed decoding frame after rewind");
+ } else
+ ++_phase;
+
Graphics::TransparentSurface * c = engine.convertToTransparent(frame->convertTo(engine.pixelFormat(), _flic->getPalette()));
Common::Rect srcRect = c->getRect();
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 9cd5b22a71f..6a59d3b8a4a 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -38,6 +38,10 @@ class Object;
class Animation {
Video::FlicDecoder *_flic;
Common::String _phaseVar;
+ bool _loop;
+ int _cycles;
+ int _phase;
+ bool _paused;
public:
Animation();
@@ -46,10 +50,31 @@ public:
const Common::String & phaseVar() const {
return _phaseVar;
}
+
void phaseVar(const Common::String & phaseVar) {
_phaseVar = phaseVar;
}
+ void loop(bool loop) {
+ _loop = loop;
+ }
+
+ void cycles(int cycles) {
+ _cycles = cycles;
+ }
+
+ int phase() const {
+ return _phase;
+ }
+
+ void play() {
+ _paused = false;
+ }
+
+ void stop() {
+ _paused = true;
+ }
+
bool load(Common::SeekableReadStream *stream);
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Common::Point dst);
int width() const;
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index e1dd4bf6799..7b7be607590 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -111,6 +111,10 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
}
if (_animation) {
_animation->paint(engine, backbuffer, _animationPos);
+ const Common::String & phaseVar = _animation->phaseVar();
+ if (!phaseVar.empty()) {
+ engine.setGlobal(_animation->phaseVar(), _animation->phase()); //-1 eof
+ }
}
if (!_text.empty()) {
Common::Point pos = _region? _region->center: _pos;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index cd9d99749e1..97cc4eb6693 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -152,8 +152,8 @@ enum Opcode {
kSetPeriodic = 132,
kStub133 = 133,
kSetAnimationPosition = 134,
- kResetPhaseVar = 135,
- kStub136 = 136,
+ kSetPhaseVar = 135,
+ kSetAnimationLoop = 136,
kStub137 = 137,
kStub138 = 138,
kStub139 = 139,
@@ -238,7 +238,7 @@ enum Opcode {
kStub218 = 218,
kStub219 = 219,
kStopCharacter = 220,
- kStub221 = 221,
+ kPlayAnimationWithPhaseVar = 221,
kStub222 = 222,
kStub223 = 223,
kStub224 = 224,
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index d53fe2c12c1..b5383f18b72 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -30,7 +30,8 @@ namespace AGDS {
Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
_engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object), _ip(ip), _status(kStatusActive), _exitCode(kExitCodeDestroy),
_glyphWidth(16), _glyphHeight(16),
- _timer(0) {
+ _timer(0),
+ _animationCycles(1), _animationLoop(false) {
}
void Process::debug(const char *str, ...) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 4e468e1ca0d..c24ac832d61 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -53,6 +53,8 @@ private:
int _glyphWidth, _glyphHeight;
Common::String _phaseVar;
int _timer;
+ int _animationCycles;
+ bool _animationLoop;
private:
uint8 next() {
@@ -177,7 +179,7 @@ private:
void setIntegerSystemVariable();
void getGlobal(unsigned index);
void setGlobal();
- void resetPhaseVar();
+ void setPhaseVar();
void hasGlobal();
void postIncrementGlobal();
void postDecrementGlobal();
@@ -222,7 +224,6 @@ private:
void setCycles();
void setRandom();
void stub133();
- void stub136();
void stub137();
void stub138();
void stub152();
@@ -247,7 +248,8 @@ private:
void stub215();
void stub216();
void stub217();
- void stub221();
+ void playAnimationWithPhaseVar();
+ void setAnimationLoop();
void stub223();
void stub225();
void stub231();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index edb666df06c..9b32fc74c3e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -115,7 +115,13 @@ void Process::loadPicture() {
void Process::loadAnimation() {
Common::String name = popText();
debug("loadAnimation %s", name.c_str());
- _object->setAnimation(_engine->loadAnimation(name));
+ Animation *animation = _engine->loadAnimation(name);
+ if (animation) {
+ animation->phaseVar(_phaseVar);
+ animation->loop(_animationLoop);
+ animation->cycles(_animationCycles);
+ _object->setAnimation(animation);
+ }
}
void Process::loadSample() {
@@ -228,11 +234,11 @@ void Process::setGlobal() {
_engine->setGlobal(name, value);
}
-void Process::resetPhaseVar() {
+void Process::setPhaseVar() {
Common::String name = popString();
_engine->setGlobal(name, 0);
_phaseVar = name;
- debug("resetPhaseVar %s", name.c_str());
+ debug("setPhaseVar %s", name.c_str());
}
void Process::getGlobal(unsigned index) {
@@ -434,7 +440,8 @@ void Process::changeScreenPatch() {
void Process::loadMouseCursorFromObject() {
Common::String name = popText();
debug("loadMouseCursorFromObject %s", name.c_str());
- _object->setMouseCursor(_engine->loadAnimation(name)); //overlay cursor
+ Animation *cursor = _engine->loadMouseCursor(name);
+ _object->setMouseCursor(cursor); //overlay cursor
}
void Process::fadeObject() {
@@ -468,7 +475,8 @@ void Process::setDelay() {
void Process::setCycles() {
int value = pop();
- debug("setCycles stub %d", value);
+ debug("setCycles %d", value);
+ _animationCycles = value;
}
void Process::setRandom() {
@@ -500,6 +508,8 @@ void Process::stub119() {
void Process::resetState() {
debug("process reset state");
_phaseVar.clear();
+ _animationCycles = 1;
+ _animationLoop = false;
}
void Process::stub129() {
@@ -513,8 +523,9 @@ void Process::stub133() {
debug("stub133: pan? %d volume? %d", pan, volume);
}
-void Process::stub136() {
- debug("stub136 sets value of stub130 (loops?) to 1000000000");
+void Process::setAnimationLoop() {
+ debug("loopAnimation");
+ _animationLoop = true;
}
void Process::stub137() {
@@ -657,9 +668,16 @@ void Process::stub217() {
debug("stub217: animation? id: %d, frame: %d, soundGroup: %d", id, frame, soundGroup);
}
-void Process::stub221() {
+void Process::playAnimationWithPhaseVar() {
Common::String phaseVar = popString();
- debug("stub221: animation related, phaseVar %s", phaseVar.c_str());
+ debug("playAnimationWithPhaseVar %s", phaseVar.c_str());
+ Animation * animation = _engine->findAnimationByPhaseVar(phaseVar);
+ if (animation) {
+ animation->phaseVar(phaseVar);
+ animation->play();
+ }
+ else
+ warning("no animation with phase var %s found", phaseVar.c_str());
}
void Process::stub223() {
@@ -1069,10 +1087,12 @@ void Process::loadAnimationFromObject() {
debug("loadAnimationFromObject %s", name.c_str());
if (!_phaseVar.empty()) {
_engine->setGlobal(_phaseVar, -2);
-
- Animation * animation = _engine->loadAnimation(name);
- if (animation)
- animation->phaseVar(_phaseVar);
+ }
+ Animation * animation = _engine->loadAnimation(name);
+ if (animation) {
+ animation->phaseVar(_phaseVar);
+ animation->loop(_animationLoop);
+ animation->cycles(_animationCycles);
}
}
@@ -1253,8 +1273,8 @@ ProcessExitCode Process::execute() {
OP (kSetRandom, setRandom);
OP (kStub133, stub133);
OP (kSetAnimationPosition, setAnimationPosition);
- OP (kResetPhaseVar, resetPhaseVar);
- OP (kStub136, stub136);
+ OP (kSetPhaseVar, setPhaseVar);
+ OP (kSetAnimationLoop, setAnimationLoop);
OP (kStub137, stub137);
OP (kStub138, stub138);
OP (kScreenChangeScreenPatch, changeScreenPatch);
@@ -1310,7 +1330,7 @@ ProcessExitCode Process::execute() {
OP (kStub216, stub216);
OP (kStub217, stub217);
OP (kStopCharacter, stopCharacter);
- OP (kStub221, stub221);
+ OP (kPlayAnimationWithPhaseVar, playAnimationWithPhaseVar);
OP (kStub223, stub223);
OP (kStub225, stub225);
OP (kFadeObject, fadeObject);
Commit: 06cafe66c2829c40521ae1297568707635ef43f8
https://github.com/scummvm/scummvm/commit/06cafe66c2829c40521ae1297568707635ef43f8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:08+01:00
Commit Message:
AGDS: add name and object to Character
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/character.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index b17e4ae65be..17c260123fc 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -525,18 +525,13 @@ Animation * AGDSEngine::findAnimationByPhaseVar(const Common::String &phaseVar)
}
-Character * AGDSEngine::loadCharacter(const Common::String &name) {
- CharactersType::iterator i = _characters.find(name);
+Character * AGDSEngine::loadCharacter(const Common::String &id, const Common::String &name, const Common::String &object) {
+ CharactersType::iterator i = _characters.find(id);
if (i != _characters.end())
return i->_value;
-// Common::SeekableReadStream *stream = _resourceManager.getResource(name);
-// if (!stream)
-// error("could not load character from %s", name.c_str());
- Character *character = new Character();
-// if (!character->load(stream))
-// error("could not load character from %s", name.c_str());
- _characters[name] = character;
+ Character *character = new Character(name, object);
+ _characters[id] = character;
return character;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 422d6cc1301..e16fe999e61 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -148,7 +148,7 @@ public:
Animation * loadAnimation(const Common::String &name);
Animation * loadMouseCursor(const Common::String &name);
Animation * findAnimationByPhaseVar(const Common::String &phaseVar);
- Character * loadCharacter(const Common::String &name);
+ Character * loadCharacter(const Common::String &id, const Common::String &name, const Common::String &object);
Character * getCharacter(const Common::String &name) const;
void loadDefaultMouseCursor(const Common::String &name) {
diff --git a/engines/agds/character.h b/engines/agds/character.h
index fee371396cc..f1a4429ae2e 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -36,12 +36,23 @@ class AGDSEngine;
class Object;
class Character {
+ Common::String _name;
+ Common::String _object;
bool _enabled;
int _phase;
int _frames;
public:
- Character(): _enabled(true), _phase(0), _frames(0) {
+ Character(const Common::String & name, const Common::String & object):
+ _enabled(true), _phase(0), _frames(0), _name(name), _object(object) {
+ }
+
+ const Common::String & name() const {
+ return _name;
+ }
+
+ const Common::String & object() const {
+ return _object;
}
bool load(Common::SeekableReadStream* stream) {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 9b32fc74c3e..4629d395101 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -982,11 +982,11 @@ void Process::addMouseArea() {
}
void Process::loadCharacter() {
- Common::String arg3 = popString();
- Common::String arg2 = popString();
- Common::String name = popString();
- debug("loadCharacter %s %s %s", name.c_str(), arg2.c_str(), arg3.c_str());
- _engine->loadCharacter(name);
+ Common::String object = popString();
+ Common::String name = popText();
+ Common::String id = popString();
+ debug("loadCharacter %s %s %s", id.c_str(), name.c_str(), object.c_str());
+ _engine->loadCharacter(id, name, object);
}
void Process::enableCharacter() {
@@ -1011,7 +1011,7 @@ void Process::moveCharacter(bool usermove) {
void Process::animateCharacter() {
int arg2 = pop();
Common::String name = popString();
- debug("animateCharacter: stub %s %d", name.c_str(), arg2);
+ debug("animateCharacter: %s %d", name.c_str(), arg2);
Character *character = _engine->getCharacter(name);
if (character)
@@ -1023,6 +1023,11 @@ void Process::animateCharacter() {
void Process::showCharacter() {
Common::String name = popString();
debug("showCharacter %s", name.c_str());
+ Character *character = _engine->getCharacter(name);
+ if (character)
+ _engine->runObject(character->object());
+ else
+ warning("character %s could not be found", name.c_str());
}
void Process::leaveCharacter() {
Commit: 76f330a8c5f0bb359e73b43192aff752dca5a402
https://github.com/scummvm/scummvm/commit/76f330a8c5f0bb359e73b43192aff752dca5a402
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:08+01:00
Commit Message:
AGDS: implement opcode 236: userEnabled
Changed paths:
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index e16fe999e61..a4b38ae1ccf 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -156,9 +156,13 @@ public:
}
void changeMouseArea(int id, int enabled);
+
void enableUser(bool enabled) {
_userEnabled = enabled;
}
+ bool userEnabled() const {
+ return _userEnabled;
+ }
void initSystemVariables();
SystemVariable *getSystemVariable(const Common::String &name);
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 97cc4eb6693..fd389b81e5c 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -253,7 +253,7 @@ enum Opcode {
kStub233 = 233,
kGetSampleVolume = 234,
kStub235 = 235,
- kStub236 = 236,
+ kUserEnabled = 236,
kStub237 = 237,
kInventoryFindObjectByName = 238,
kStub239 = 239,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index c24ac832d61..6b094f336fb 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -255,6 +255,7 @@ private:
void stub231();
void stub233();
void stub235();
+ void userEnabled();
void stub244();
void debug(const char *str, ...);
void error(const char *str, ...);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4629d395101..4200c5e2433 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -418,6 +418,12 @@ void Process::disableUser() {
_engine->enableUser(false);
}
+void Process::userEnabled() {
+ bool enabled = _engine->userEnabled();
+ debug("userEnabled -> %d", enabled);
+ push(enabled);
+}
+
void Process::changeScreenPatch() {
Common::String objectName = popString();
Common::String screenName = popString();
@@ -1354,6 +1360,7 @@ ProcessExitCode Process::execute() {
OP (kStub231, stub231);
OP (kStub233, stub233);
OP (kStub235, stub235);
+ OP (kUserEnabled, userEnabled);
OP (kStub244, stub244);
OP (kInventoryFindObjectByName, inventoryFindObjectByName);
OP (kRunDialog, runDialog);
Commit: bc0accc92ab3af4fc18a9a3aa89b9c9f978c5a32
https://github.com/scummvm/scummvm/commit/bc0accc92ab3af4fc18a9a3aa89b9c9f978c5a32
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:08+01:00
Commit Message:
AGDS: added WARNING prefix for Process::error()
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index b5383f18b72..fd0de5ef750 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -54,7 +54,7 @@ void Process::error(const char *str, ...) {
va_list va;
va_start(va, str);
- Common::String format = Common::String::format("%s %04x[%u]: %s", _object->getName().c_str(), _lastIp + 7, _stack.size(), str);
+ Common::String format = Common::String::format("WARNING: %s %04x[%u]: %s", _object->getName().c_str(), _lastIp + 7, _stack.size(), str);
Common::String buf = Common::String::vformat(format.c_str(), va);
buf += '\n';
Commit: 74034f4c92b45de747a9301834907ddc1a6e41c4
https://github.com/scummvm/scummvm/commit/74034f4c92b45de747a9301834907ddc1a6e41c4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:08+01:00
Commit Message:
AGDS: implement on-screen animation
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 20ef9197c53..d9cd6e4b4b6 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -70,6 +70,7 @@ void Animation::paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Commo
++_phase;
Graphics::TransparentSurface * c = engine.convertToTransparent(frame->convertTo(engine.pixelFormat(), _flic->getPalette()));
+ dst += _position;
Common::Rect srcRect = c->getRect();
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
c->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 6a59d3b8a4a..d37934b7f0b 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -37,6 +37,7 @@ class Object;
class Animation {
Video::FlicDecoder *_flic;
+ Common::Point _position;
Common::String _phaseVar;
bool _loop;
int _cycles;
@@ -47,6 +48,10 @@ public:
Animation();
~Animation();
+ void position(Common::Point position) {
+ _position = position;
+ }
+
const Common::String & phaseVar() const {
return _phaseVar;
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 6b094f336fb..247c982bc51 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -55,6 +55,7 @@ private:
int _timer;
int _animationCycles;
bool _animationLoop;
+ Common::Point _animationPosition;
private:
uint8 next() {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4200c5e2433..3a9800fb319 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -117,10 +117,12 @@ void Process::loadAnimation() {
debug("loadAnimation %s", name.c_str());
Animation *animation = _engine->loadAnimation(name);
if (animation) {
+ animation->position(_animationPosition);
animation->phaseVar(_phaseVar);
animation->loop(_animationLoop);
animation->cycles(_animationCycles);
- _object->setAnimation(animation);
+ animation->play();
+ _engine->getCurrentScreen()->add(animation);
}
}
@@ -516,6 +518,7 @@ void Process::resetState() {
_phaseVar.clear();
_animationCycles = 1;
_animationLoop = false;
+ _animationPosition = Common::Point();
}
void Process::stub129() {
@@ -1111,7 +1114,8 @@ void Process::setAnimationPosition() {
int arg2 = pop();
int arg1 = pop();
debug("setAnimationPosition %d %d", arg1, arg2);
- _object->setAnimationPosition(Common::Point(arg1, arg2));
+ _animationPosition.x = arg1;
+ _animationPosition.y = arg2;
}
void Process::setTimer() {
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 3a1a9c666b5..9db69e6e36f 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -21,6 +21,7 @@
*/
#include "agds/screen.h"
+#include "agds/animation.h"
#include "agds/object.h"
#include "agds/region.h"
@@ -71,6 +72,10 @@ void Screen::paint(AGDSEngine & engine, Graphics::Surface & backbuffer) {
for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
(*i)->paint(engine, backbuffer);
}
+ for(AnimationsType::iterator i = _animations.begin(); i != _animations.end(); ++i) {
+ Animation * animation = *i;
+ animation->paint(engine, backbuffer, Common::Point());
+ }
}
ObjectPtr Screen::find(Common::Point pos) const {
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 89fb49126e7..082ada79e9b 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -37,6 +37,7 @@ namespace AGDS {
class AGDSEngine;
class Object;
+class Animation;
typedef Common::SharedPtr<Object> ObjectPtr;
struct Region;
@@ -91,11 +92,13 @@ public:
};
class Screen {
+ typedef Common::List<Animation *> AnimationsType;
typedef Common::List<ObjectPtr> ChildrenType;
ObjectPtr _object;
Common::String _name;
ChildrenType _children;
+ AnimationsType _animations;
MouseMap _mouseMap;
public:
@@ -123,6 +126,9 @@ public:
}
void add(ObjectPtr object);
+ void add(Animation * animation) {
+ _animations.push_back(animation);
+ }
bool remove(const Common::String & name);
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer);
ObjectPtr find(Common::Point pos) const;
Commit: c423e2d375937fea72e679a4441d851f5f10b553
https://github.com/scummvm/scummvm/commit/c423e2d375937fea72e679a4441d851f5f10b553
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:08+01:00
Commit Message:
AGDS: implemented opcode 119: animation paused
Changed paths:
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index fd389b81e5c..13241e55bed 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -136,7 +136,7 @@ enum Opcode {
kStub116 = 116,
kLoadAnimation = 117,
kLoadSample = 118,
- kStub119 = 119,
+ kSetAnimationPaused = 119,
kStub120 = 120,
kStub121 = 121,
kPlayerSay = 122,
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index fd0de5ef750..dcd0c37db7c 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -31,7 +31,7 @@ Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
_engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object), _ip(ip), _status(kStatusActive), _exitCode(kExitCodeDestroy),
_glyphWidth(16), _glyphHeight(16),
_timer(0),
- _animationCycles(1), _animationLoop(false) {
+ _animationCycles(1), _animationLoop(false), _animationPaused(false) {
}
void Process::debug(const char *str, ...) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 247c982bc51..cdddbf2565c 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -56,6 +56,7 @@ private:
int _animationCycles;
bool _animationLoop;
Common::Point _animationPosition;
+ bool _animationPaused;
private:
uint8 next() {
@@ -219,7 +220,6 @@ private:
void stub82();
void stub83();
void stub102();
- void stub119();
void resetState();
void stub129();
void setCycles();
@@ -251,6 +251,7 @@ private:
void stub217();
void playAnimationWithPhaseVar();
void setAnimationLoop();
+ void setAnimationPaused();
void stub223();
void stub225();
void stub231();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3a9800fb319..1492401d261 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -121,7 +121,10 @@ void Process::loadAnimation() {
animation->phaseVar(_phaseVar);
animation->loop(_animationLoop);
animation->cycles(_animationCycles);
- animation->play();
+ if (_animationPaused)
+ animation->stop();
+ else
+ animation->play();
_engine->getCurrentScreen()->add(animation);
}
}
@@ -509,8 +512,9 @@ void Process::stub102() {
debug("stub102: load picture? %s");
}
-void Process::stub119() {
- debug("stub119");
+void Process::setAnimationPaused() {
+ debug("setAnimationPaused");
+ _animationPaused = true;
}
void Process::resetState() {
@@ -519,6 +523,7 @@ void Process::resetState() {
_animationCycles = 1;
_animationLoop = false;
_animationPosition = Common::Point();
+ _animationPaused = false;
}
void Process::stub129() {
@@ -1107,6 +1112,8 @@ void Process::loadAnimationFromObject() {
animation->phaseVar(_phaseVar);
animation->loop(_animationLoop);
animation->cycles(_animationCycles);
+ if (_animationPaused)
+ animation->stop();
}
}
@@ -1278,7 +1285,7 @@ ProcessExitCode Process::execute() {
OP (kScreenRemoveObject, removeScreenObject);
OP (kLoadAnimation, loadAnimation);
OP (kLoadSample, loadSample);
- OP (kStub119, stub119);
+ OP (kSetAnimationPaused, setAnimationPaused);
OP (kPlayerSay, playerSay);
OP (kNPCSay, npcSay);
OP (kSetTimer, setTimer);
Commit: d052d761dda834c9371d4af664c9f7731607681d
https://github.com/scummvm/scummvm/commit/d052d761dda834c9371d4af664c9f7731607681d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:08+01:00
Commit Message:
AGDS: chain character animations, partially implement stopCharacter
Changed paths:
engines/agds/character.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/character.h b/engines/agds/character.h
index f1a4429ae2e..f690807c316 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -64,8 +64,12 @@ public:
}
void animate(int frames) {
+ _frames += frames;
+ }
+
+ void stop() {
_phase = 0;
- _frames = frames;
+ _frames = 0;
}
int getPhase() const {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 1492401d261..c7e1445fc58 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1077,6 +1077,11 @@ void Process::stopCharacter() {
int arg = pop();
Common::String name = popString();
debug("stopCharacter: stub %s %d", name.c_str(), arg);
+ Character * character = _engine->getCharacter(name);
+ if (character)
+ character->stop();
+ else
+ warning("could not find character %s", name.c_str());
}
void Process::fogOnCharacter() {
Commit: 1df655ae58a466860b8ef3d434121f3a8dc29ce4
https://github.com/scummvm/scummvm/commit/1df655ae58a466860b8ef3d434121f3a8dc29ce4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:08+01:00
Commit Message:
AGDS: do not run anything in parallel while dialog plays
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 17c260123fc..2c90cfc3db9 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -271,7 +271,8 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
}
void AGDSEngine::tick() {
- tickDialog();
+ if (tickDialog())
+ return;
tickInventory();
for(ProcessListType::iterator p = _processes.begin(); active() && p != _processes.end(); ) {
runProcess(p);
@@ -702,22 +703,22 @@ void AGDSEngine::tickInventory() {
return;
}
-void AGDSEngine::tickDialog() {
+bool AGDSEngine::tickDialog() {
if (_dialogProcessName.empty())
- return;
+ return false;
int dialog_var = getSystemVariable("dialog_var")->getInteger();
if (dialog_var > 0) {
getSystemVariable("dialog_var")->setInteger(-3);
- return;
+ return false;
} else if (dialog_var < 0) {
getSystemVariable("dialog_var")->setInteger(0);
- return;
+ return true;
}
uint n = _dialogScript.size();
if (_dialogScriptPos >= n)
- return;
+ return false;
Common::String line;
while(_dialogScriptPos < n && _dialogScript[_dialogScriptPos] != '\n' && _dialogScript[_dialogScriptPos] != '\r') {
@@ -726,11 +727,11 @@ void AGDSEngine::tickDialog() {
++_dialogScriptPos;
if (line.empty())
- return;
+ return true;
if (line[0] == '@') {
if (line[1] == '@') //comment
- return;
+ return true;
line.erase(0, 1);
@@ -755,7 +756,9 @@ void AGDSEngine::tickDialog() {
debug("end of dialog, running %s", process.c_str());
runObject(process);
getSystemVariable("dialog_var")->setInteger(-2);
+ return false;
}
+ return true;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index a4b38ae1ccf..0a94f23e139 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -168,7 +168,7 @@ public:
SystemVariable *getSystemVariable(const Common::String &name);
void runDialog(const Common::String &dialogScript, const Common::String & defs);
- void tickDialog();
+ bool tickDialog();
void tickInventory();
void playSound(const Common::String &resource, const Common::String &phaseVar) {
Commit: 147aab490de2e68a94031aa9e45b6b9b6a4a5d5e
https://github.com/scummvm/scummvm/commit/147aab490de2e68a94031aa9e45b6b9b6a4a5d5e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:09+01:00
Commit Message:
AGDS: partially implement setCharacter
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c7e1445fc58..6d1bd91749d 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1052,9 +1052,10 @@ void Process::leaveCharacter() {
}
void Process::setCharacter() {
- Common::String arg2 = popString();
- Common::String arg1 = popString();
- debug("setCharacter %s %s", arg1.c_str(), arg2.c_str());
+ Common::String object = popString();
+ Common::String region = popString();
+ debug("setCharacter %s %s", region.c_str(), object.c_str());
+ _engine->runObject(object);
}
void Process::pointCharacter() {
Commit: 6e370f6f2fc0060b395532273315fad2b33f5214
https://github.com/scummvm/scummvm/commit/6e370f6f2fc0060b395532273315fad2b33f5214
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:09+01:00
Commit Message:
AGDS: fixed animation timings
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index d9cd6e4b4b6..a9225957b76 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -30,7 +30,8 @@
namespace AGDS {
-Animation::Animation(): _flic(), _loop(false), _cycles(1), _phase(0), _paused(true) {
+Animation::Animation():
+ _flic(), _loop(false), _cycles(1), _phase(0), _paused(true), _speed(100) {
}
Animation::~Animation() {
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index d37934b7f0b..65386c6f92d 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -43,6 +43,7 @@ class Animation {
int _cycles;
int _phase;
bool _paused;
+ int _speed;
public:
Animation();
@@ -80,6 +81,10 @@ public:
_paused = true;
}
+ void speed(int speed) {
+ _speed = speed;
+ }
+
bool load(Common::SeekableReadStream *stream);
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Common::Point dst);
int width() const;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 13241e55bed..ddbf1c98319 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -154,7 +154,7 @@ enum Opcode {
kSetAnimationPosition = 134,
kSetPhaseVar = 135,
kSetAnimationLoop = 136,
- kStub137 = 137,
+ kSetAnimationSpeed = 137,
kStub138 = 138,
kStub139 = 139,
kScreenChangeScreenPatch = 140,
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index dcd0c37db7c..149f53011ee 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -31,7 +31,7 @@ Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
_engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object), _ip(ip), _status(kStatusActive), _exitCode(kExitCodeDestroy),
_glyphWidth(16), _glyphHeight(16),
_timer(0),
- _animationCycles(1), _animationLoop(false), _animationPaused(false) {
+ _animationCycles(1), _animationLoop(false), _animationPaused(false), _animationSpeed(100) {
}
void Process::debug(const char *str, ...) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index cdddbf2565c..f0636b343da 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -57,6 +57,7 @@ private:
bool _animationLoop;
Common::Point _animationPosition;
bool _animationPaused;
+ int _animationSpeed;
private:
uint8 next() {
@@ -225,7 +226,6 @@ private:
void setCycles();
void setRandom();
void stub133();
- void stub137();
void stub138();
void stub152();
void stub153();
@@ -252,6 +252,7 @@ private:
void playAnimationWithPhaseVar();
void setAnimationLoop();
void setAnimationPaused();
+ void setAnimationSpeed();
void stub223();
void stub225();
void stub231();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 6d1bd91749d..61896af7ab1 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -542,9 +542,11 @@ void Process::setAnimationLoop() {
_animationLoop = true;
}
-void Process::stub137() {
+void Process::setAnimationSpeed() {
int value = pop();
- debug("stub137 %d", value);
+ debug("setAnimationSpeed %d", value);
+ if (value != 0)
+ _animationSpeed = value;
}
void Process::stub138() {
@@ -1029,7 +1031,7 @@ void Process::animateCharacter() {
Character *character = _engine->getCharacter(name);
if (character)
- character->animate(arg2);
+ character->animate(arg2 * 100 / _animationSpeed);
else
warning("character %s could not be found", name.c_str());
}
@@ -1303,7 +1305,7 @@ ProcessExitCode Process::execute() {
OP (kSetAnimationPosition, setAnimationPosition);
OP (kSetPhaseVar, setPhaseVar);
OP (kSetAnimationLoop, setAnimationLoop);
- OP (kStub137, stub137);
+ OP (kSetAnimationSpeed, setAnimationSpeed);
OP (kStub138, stub138);
OP (kScreenChangeScreenPatch, changeScreenPatch);
OP (kGetFreeInventorySpace, getInventoryFreeSpace);
Commit: f7c35d51c47527208ea6b30406a145747e39b8a9
https://github.com/scummvm/scummvm/commit/f7c35d51c47527208ea6b30406a145747e39b8a9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:09+01:00
Commit Message:
AGDS: added experimental examine handler, reworked animation frames/cycle/loop counters
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index a9225957b76..7b19d189bc1 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -31,7 +31,7 @@
namespace AGDS {
Animation::Animation():
- _flic(), _loop(false), _cycles(1), _phase(0), _paused(true), _speed(100) {
+ _flic(), _frames(0), _loop(false), _cycles(1), _phase(0), _paused(true), _speed(100) {
}
Animation::~Animation() {
@@ -41,34 +41,42 @@ Animation::~Animation() {
bool Animation::load(Common::SeekableReadStream* stream) {
Video::FlicDecoder * flic = new Video::FlicDecoder;
if (flic->loadStream(stream)) {
+ _frames = flic->getFrameCount();
delete _flic;
_flic = flic;
return true;
} else {
+ _frames = 0;
delete flic;
return false;
}
}
+void Animation::updatePhaseVar(AGDSEngine & engine) {
+ if (!_phaseVar.empty())
+ engine.setGlobal(_phaseVar, _phase);
+}
void Animation::paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Common::Point dst) {
- if (_cycles <= 0 || _paused) {
+ if (_paused || _phase == -1) {
return;
}
const Graphics::Surface * frame = _flic->decodeNextFrame();
if (!frame) {
- if (!_loop && --_cycles <= 0) {
+ if (!_loop && _phase >= _cycles * _frames) {
_phase = -1; //end of animation
+ updatePhaseVar(engine);
return;
}
- _phase = 0;
_flic->rewind();
frame = _flic->decodeNextFrame();
if (!frame)
error("failed decoding frame after rewind");
- } else
- ++_phase;
+ }
+
+ ++_phase;
+ updatePhaseVar(engine);
Graphics::TransparentSurface * c = engine.convertToTransparent(frame->convertTo(engine.pixelFormat(), _flic->getPalette()));
dst += _position;
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 65386c6f92d..0fb9847908f 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -37,6 +37,7 @@ class Object;
class Animation {
Video::FlicDecoder *_flic;
+ int _frames;
Common::Point _position;
Common::String _phaseVar;
bool _loop;
@@ -75,6 +76,7 @@ public:
void play() {
_paused = false;
+ _phase = 0;
}
void stop() {
@@ -86,6 +88,7 @@ public:
}
bool load(Common::SeekableReadStream *stream);
+ void updatePhaseVar(AGDSEngine & engine);
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Common::Point dst);
int width() const;
int height() const;
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 7b7be607590..1ed9ce97314 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -37,7 +37,9 @@ Object::Object(const Common::String &name, Common::SeekableReadStream * stream)
_name(name), _stringTableLoaded(false),
_picture(), _region(),
_animation(), _mouseCursor(),
- _pos(), _alpha(255), _active(false) {
+ _pos(),
+ _clickHandler(0), _examineHandler(0),
+ _alpha(255), _active(false) {
byte id = stream->readByte();
byte flag = stream->readByte();
debug("id: 0x%02x %u, flag: %u", id, id, flag);
@@ -111,10 +113,6 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
}
if (_animation) {
_animation->paint(engine, backbuffer, _animationPos);
- const Common::String & phaseVar = _animation->phaseVar();
- if (!phaseVar.empty()) {
- engine.setGlobal(_animation->phaseVar(), _animation->phase()); //-1 eof
- }
}
if (!_text.empty()) {
Common::Point pos = _region? _region->center: _pos;
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 046b7bdf294..707633f2994 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -68,6 +68,7 @@ private:
Common::Point _pos, _animationPos;
Common::String _text;
uint _clickHandler;
+ uint _examineHandler;
int _alpha;
bool _active;
@@ -134,6 +135,14 @@ public:
return _clickHandler;
}
+ void setExamineHandler(uint ip) {
+ _examineHandler = ip;
+ }
+
+ uint getExamineHandler() const {
+ return _examineHandler;
+ }
+
void paint(AGDSEngine &engine, Graphics::Surface &backbuffer);
void move(Common::Point pos) {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 61896af7ab1..65c3ff19f7a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -970,6 +970,7 @@ void Process::onObjectC1(unsigned size) {
void Process::onLook(unsigned size) {
debug("look? [handler], %u instructions", size);
+ _object->setExamineHandler(_ip);
_ip += size;
}
Commit: 502e4c67c86fbebd5582bad3d8da2f7dbf7bce43
https://github.com/scummvm/scummvm/commit/502e4c67c86fbebd5582bad3d8da2f7dbf7bce43
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:09+01:00
Commit Message:
AGDS: implemented register use object handler opcode 63
Changed paths:
engines/agds/object.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 707633f2994..da74407ef12 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -55,12 +55,14 @@ public:
private:
typedef Common::Array<StringEntry> StringTableType;
typedef Common::HashMap<Common::String, uint, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> KeyHandlersType;
+ typedef Common::HashMap<Common::String, uint> UseHandlersType;
Common::String _name;
CodeType _code;
StringTableType _stringTable;
bool _stringTableLoaded;
KeyHandlersType _keyHandlers;
+ UseHandlersType _useHandlers;
Graphics::TransparentSurface * _picture;
Region * _region;
Animation * _animation;
@@ -143,6 +145,10 @@ public:
return _examineHandler;
}
+ void setUseHandler(const Common::String &name, uint ip) {
+ _useHandlers[name] = ip;
+ }
+
void paint(AGDSEngine &engine, Graphics::Surface &backbuffer);
void move(Common::Point pos) {
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index ddbf1c98319..3fbb2f51821 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -82,7 +82,7 @@ enum Opcode {
kObjectRegisterLookHandler = 60,
kObjectRegisterUseHandler = 61,
kObjectRegisterHandlerC1 = 62,
- kStub63 = 63,
+ kObjectRegisterUseObjectHandler = 63,
kScreenRegisterHandlerBD = 64,
kStub65 = 65,
kLoadMouseCursorFromObject = 66,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index f0636b343da..191ad29c521 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -216,8 +216,8 @@ private:
void onLook(unsigned size);
void onObjectC1(unsigned size);
void onScreenBD(unsigned size);
+ void onObjectUse(unsigned size);
- void stub63(unsigned size);
void stub82();
void stub83();
void stub102();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 65c3ff19f7a..993a200f4cb 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -466,10 +466,10 @@ void Process::fadeObject() {
warning("fadeObject: object %s not found", name.c_str());
}
-void Process::stub63(unsigned size) {
+void Process::onObjectUse(unsigned size) {
Common::String arg = popString();
- int value = _engine->getGlobal(arg);
- debug("stub63: [handler] %u instructions, loop range: 0-%d", size, value);
+ debug("register use object handler %s -> %u", arg.c_str(), _ip);
+ _object->setUseHandler(arg, _ip);
_ip += size;
}
@@ -1278,7 +1278,7 @@ ProcessExitCode Process::execute() {
OP (kLoadMouse, loadMouse);
OP (kInventoryAddObject, inventoryAddObject);
OP (kSetNextScreenSaveInHistory, setNextScreenSaveInHistory);
- OP_U (kStub63, stub63);
+ OP_U (kObjectRegisterUseObjectHandler, onObjectUse);
OP (kStub82, stub82);
OP (kStub83, stub83);
OP (kAnimateCharacter, animateCharacter);
Commit: 660087b0150cac31ba25f277ee5038c5619db894
https://github.com/scummvm/scummvm/commit/660087b0150cac31ba25f277ee5038c5619db894
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:09+01:00
Commit Message:
AGDS: improved logic in changeScreenPatch
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 993a200f4cb..7f82db8aa7f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -432,20 +432,27 @@ void Process::userEnabled() {
void Process::changeScreenPatch() {
Common::String objectName = popString();
Common::String screenName = popString();
+ Common::String inventoryScr = _engine->getSystemVariable("inventory_scr")->getString();
+ debug("changeScreenPatch: screen: %s, object: %s, inventory: %s",
+ screenName.empty()? "none": screenName.c_str(), objectName.c_str(), inventoryScr.empty()? "none": inventoryScr.c_str());
+
Screen * screen = _engine->getCurrentScreen();
if (!screen) {
error("no current screen");
return;
}
- if (screenName.empty())
- screenName = screen->getName();
-
- //change screen patch (load and return 1)
- ObjectPtr object = screen->find(objectName);
- int value = object && object->isActive();
- debug("changeScreenPatch: screen: %s, object: %s -> %d", screenName.c_str(), objectName.c_str(), value);
- push(value);
+ if (!screenName.empty()) {
+ debug("stub, returning 0");
+ //check that patch exist
+ push(0);
+ return;
+ } else {
+ //change screen patch (load and return 1)
+ ObjectPtr object = screen->find(objectName);
+ int value = object && object->isActive();
+ push(value);
+ }
}
void Process::loadMouseCursorFromObject() {
Commit: 5e4f7f2b190c1a2ffb9e85e47004b61f215e1039
https://github.com/scummvm/scummvm/commit/5e4f7f2b190c1a2ffb9e85e47004b61f215e1039
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:09+01:00
Commit Message:
AGDS: fixed obvious typos, added missing logs
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 7f82db8aa7f..c5972d76b60 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -141,7 +141,7 @@ void Process::loadSample() {
void Process::getSampleVolume() {
Common::String name = popString();
- debug("getSampleVolume: stub");
+ debug("getSampleVolume: stub %s", name.c_str());
push(100);
}
@@ -516,7 +516,7 @@ void Process::stub83() {
void Process::stub102() {
Common::String name = popString();
- debug("stub102: load picture? %s");
+ debug("stub102: load picture? %s", name.c_str());
}
void Process::setAnimationPaused() {
@@ -723,7 +723,6 @@ void Process::setFontGlyphSize() {
void Process::generateRegion() {
Common::String name = popString();
debug("generateRegion %s", name.c_str());
-
}
void Process::stub184() {
Commit: 59335f16906c2219bfe0dab41069b2f006f7f0ac
https://github.com/scummvm/scummvm/commit/59335f16906c2219bfe0dab41069b2f006f7f0ac
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:09+01:00
Commit Message:
AGDS: added hex output for data size in object
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 1ed9ce97314..4f95a68e38d 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -46,7 +46,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream * stream)
uint16 dataSize = stream->readUint16LE();
if (dataSize != 0)
- error("implement me: object with data (%u)", dataSize);
+ error("implement me: object with data (%u/0x%04x)", dataSize, dataSize);
uint16 codeSize = stream->readUint16LE();
uint8 flags = stream->readByte();
if (flags != 1)
Commit: cd268d02a91558103e86999359e9bc1a02ec8439
https://github.com/scummvm/scummvm/commit/cd268d02a91558103e86999359e9bc1a02ec8439
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:09+01:00
Commit Message:
AGDS: remove runObject from setCharacter for now
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c5972d76b60..e3e2a4c1934 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1064,7 +1064,6 @@ void Process::setCharacter() {
Common::String object = popString();
Common::String region = popString();
debug("setCharacter %s %s", region.c_str(), object.c_str());
- _engine->runObject(object);
}
void Process::pointCharacter() {
Commit: 56e17c162ceec1c3f4e2d28d90806fc7497ab041
https://github.com/scummvm/scummvm/commit/56e17c162ceec1c3f4e2d28d90806fc7497ab041
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:09+01:00
Commit Message:
AGDS: properly implement call
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 2c90cfc3db9..8462ea97e87 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -150,9 +150,9 @@ void AGDSEngine::runObject(ObjectPtr object) {
runProcess(object);
}
-void AGDSEngine::runProcess(ObjectPtr object, uint ip) {
+void AGDSEngine::runProcess(ObjectPtr object, uint ip, Process * caller) {
object->activate(true);
- _processes.push_front(Process(this, object, ip));
+ _processes.push_front(Process(this, object, ip, caller));
ProcessListType::iterator it = _processes.begin();
runProcess(it);
}
@@ -207,17 +207,19 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
return;
}
- if (!process.active())
+ if (!process.active()) {
+ ++it;
return;
+ }
const Common::String &name = process.getName();
if (process.getStatus() == Process::kStatusDone || process.getStatus() == Process::kStatusError) {
debug("process %s finished", name.c_str());
- process.getObject()->activate(false);
+ process.activate(false);
it = _processes.erase(it);
return;
}
- process.activate();
+ process.activate(true);
ProcessExitCode code = process.execute();
bool destroy = false;
switch(code) {
@@ -264,7 +266,7 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
}
if (destroy) {
debug("destroying process %s...", name.c_str());
- process.getObject()->activate(false);
+ process.activate(false);
it = _processes.erase(it);
} else
++it;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 0a94f23e139..e2b2d6938ff 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -91,7 +91,7 @@ public:
ObjectPtr loadObject(const Common::String & name, const Common::String & prototype = Common::String());
void runObject(ObjectPtr object);
void runObject(const Common::String & name, const Common::String &prototype = Common::String());
- void runProcess(ObjectPtr object, uint ip = 0);
+ void runProcess(ObjectPtr object, uint ip = 0, Process * caller = NULL);
void resetCurrentScreen();
void loadScreen(const Common::String & name);
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 149f53011ee..312bb27164f 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -27,11 +27,13 @@
namespace AGDS {
-Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
- _engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object), _ip(ip), _status(kStatusActive), _exitCode(kExitCodeDestroy),
+Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip, Process * caller) :
+ _engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object), _ip(ip),
+ _status(kStatusActive), _caller(caller), _exitCode(kExitCodeDestroy),
_glyphWidth(16), _glyphHeight(16),
_timer(0),
- _animationCycles(1), _animationLoop(false), _animationPaused(false), _animationSpeed(100) {
+ _animationCycles(1), _animationLoop(false), _animationPaused(false), _animationSpeed(100),
+ _waitForCall(false) {
}
void Process::debug(const char *str, ...) {
@@ -99,17 +101,27 @@ Common::String Process::popText() {
return _engine->loadText(popString());
}
-void Process::activate() {
- switch(_status)
- {
- case kStatusActive:
- break;
- case kStatusPassive:
- _status = kStatusActive;
- break;
- default:
- error("process in invalid state %d", _status);
- _status = kStatusError;
+void Process::activate(bool active) {
+ if (active) {
+ _object->activate(active);
+ switch(_status)
+ {
+ case kStatusActive:
+ break;
+ case kStatusPassive:
+ _status = kStatusActive;
+ break;
+ default:
+ error("process in invalid state %d", _status);
+ _status = kStatusError;
+ }
+ } else {
+ if (_caller) {
+ debug("returning to caller");
+ _caller->_waitForCall = false;
+ } else {
+ _object->activate(false);
+ }
}
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 191ad29c521..3c187746aca 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -47,6 +47,7 @@ private:
StackType _stack;
unsigned _ip, _lastIp;
Status _status;
+ Process * _caller;
ProcessExitCode _exitCode;
Common::String _exitArg1, _exitArg2;
int _exitIntArg1, _exitIntArg2;
@@ -58,6 +59,7 @@ private:
Common::Point _animationPosition;
bool _animationPaused;
int _animationSpeed;
+ bool _waitForCall;
private:
uint8 next() {
@@ -311,7 +313,7 @@ private:
}
public:
- Process(AGDSEngine *engine, ObjectPtr object, unsigned ip = 0);
+ Process(AGDSEngine *engine, ObjectPtr object, unsigned ip = 0, Process * caller = NULL);
ObjectPtr getObject() const {
return _object;
@@ -329,7 +331,7 @@ public:
return _status;
}
- void activate();
+ void activate(bool active);
ProcessExitCode execute();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index e3e2a4c1934..0f56a8b28c3 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -950,9 +950,8 @@ void Process::call(uint16 addr) {
debug("call %04x", addr);
//original engine just create new process, save exit code in screen object
//and on stack, then just ignore return code, fixme?
- Process callee(_engine, _object, _ip + addr);
- ProcessExitCode code = callee.execute();
- debug("call returned %d", code);
+ _waitForCall = true;
+ _engine->runProcess(_object, _ip + addr, this);
suspend();
}
@@ -1207,6 +1206,10 @@ void Process::stub244() {
case NAME: { uint16 arg1 = next16(); uint32 arg2 = next16(); METHOD (arg1 | (arg2 << 16)); } break
ProcessExitCode Process::execute() {
+ if (_waitForCall) {
+ _exitCode = kExitCodeSuspend;
+ return _exitCode;
+ }
_exitCode = kExitCodeDestroy;
const Object::CodeType &code = _object->getCode();
Commit: 1cd04ef15da05df262ee509706dc24b122f11d87
https://github.com/scummvm/scummvm/commit/1cd04ef15da05df262ee509706dc24b122f11d87
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:09+01:00
Commit Message:
AGDS: set global to zero before animation actually started playing (fixes some infinite loops)
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 0f56a8b28c3..8d1ade984ac 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -698,6 +698,7 @@ void Process::playAnimationWithPhaseVar() {
if (animation) {
animation->phaseVar(phaseVar);
animation->play();
+ _engine->setGlobal(phaseVar, 0);
}
else
warning("no animation with phase var %s found", phaseVar.c_str());
Commit: c279f45d444a96cc767e5eab870507a64fca8bbf
https://github.com/scummvm/scummvm/commit/c279f45d444a96cc767e5eab870507a64fca8bbf
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:10+01:00
Commit Message:
AGDS: do not fail on invalid string id, resolve it later
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 4f95a68e38d..20940f288dd 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -85,6 +85,7 @@ void Object::readStringTable(unsigned resOffset, uint16 resCount) {
//debug("resource table 1[%04u]: 0x%04x %s", i, flags, name.c_str());
_stringTable[i] = StringEntry(name, flags);
}
+ debug("loaded %u strings", resCount);
_stringTableLoaded = true;
}
@@ -92,8 +93,11 @@ const Object::StringEntry & Object::getString(uint16 index) const {
if (!_stringTableLoaded)
error("no string table loaded");
- if (index >= _stringTable.size())
- error("no resource name with id %u", index);
+ if (index >= _stringTable.size()) {
+ static StringEntry empty;
+ warning("no resource name with id %u", index);
+ return empty;
+ }
return _stringTable[index];
}
Commit: 8b7bf44307e31dbcb92567878072fc3a7b3c3ad9
https://github.com/scummvm/scummvm/commit/8b7bf44307e31dbcb92567878072fc3a7b3c3ad9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:10+01:00
Commit Message:
AGDS: added inventory region handling
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 8462ea97e87..3172c84c114 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -46,7 +46,9 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_mjpgPlayer(), _currentScreen(), _previousScreen(),
_defaultMouseCursor(),
_mouse(400, 300), _userEnabled(false), _currentRegion(),
- _random("agds"), _soundManager(this, system->getMixer()),
+ _random("agds"),
+ _inventoryRegion(),
+ _soundManager(this, system->getMixer()),
_fastMode(false),
_dialogScriptPos(0) {
}
@@ -383,6 +385,8 @@ Common::Error AGDSEngine::run() {
runObject(region->onEnter);
}
}
+ if (_inventoryRegion)
+ _inventory.visible(_inventoryRegion->pointIn(_mouse));
}
break;
case Common::EVENT_LBUTTONDOWN:
@@ -700,9 +704,7 @@ void AGDSEngine::tickInventory() {
if (inv_region_name.empty())
return;
- Region * inv_region = loadRegion(inv_region_name);
- if (!inv_region)
- return;
+ _inventoryRegion = loadRegion(inv_region_name);
}
bool AGDSEngine::tickDialog() {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index e2b2d6938ff..92554f18d32 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -215,6 +215,7 @@ private:
MouseMap _mouseMap;
Common::RandomSource _random;
Inventory _inventory;
+ Region * _inventoryRegion;
bool _fastMode;
DialogDefsType _dialogDefs;
Common::String _dialogScript;
Commit: 5a62f1feb3356d7c6e58c00c630edcbf75341818
https://github.com/scummvm/scummvm/commit/5a62f1feb3356d7c6e58c00c630edcbf75341818
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:10+01:00
Commit Message:
AGDS: rename glyph size to tile size
Changed paths:
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 3fbb2f51821..adc97f4d71d 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -199,7 +199,7 @@ enum Opcode {
kSetCloneVar = 179,
kGetObjectId = 180,
kStub181 = 181,
- kSetGlyphSize = 182,
+ kSetTileSize = 182,
kGenerateRegion = 183,
kStub184 = 184,
kGetMaxInventorySize = 185,
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 312bb27164f..5edec864d40 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -30,7 +30,7 @@ namespace AGDS {
Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip, Process * caller) :
_engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object), _ip(ip),
_status(kStatusActive), _caller(caller), _exitCode(kExitCodeDestroy),
- _glyphWidth(16), _glyphHeight(16),
+ _tileWidth(16), _tileHeight(16),
_timer(0),
_animationCycles(1), _animationLoop(false), _animationPaused(false), _animationSpeed(100),
_waitForCall(false) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 3c187746aca..f34a5e4afa5 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -51,7 +51,7 @@ private:
ProcessExitCode _exitCode;
Common::String _exitArg1, _exitArg2;
int _exitIntArg1, _exitIntArg2;
- int _glyphWidth, _glyphHeight;
+ int _tileWidth, _tileHeight;
Common::String _phaseVar;
int _timer;
int _animationCycles;
@@ -156,7 +156,7 @@ private:
void getRegionCenterY();
void fadeObject();
void moveScreenObject();
- void setFontGlyphSize();
+ void setTileSize();
void getObjectPictureWidth();
void getObjectPictureHeight();
void loadCharacter();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 8d1ade984ac..e4ad6b11433 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -216,7 +216,7 @@ void Process::loadFont() {
Common::String name = popText();
int id = pop();
debug("loadFont %s %d", name.c_str(), id);
- _engine->loadFont(id, name, _glyphWidth, _glyphHeight);
+ _engine->loadFont(id, name, _tileWidth, _tileHeight);
}
void Process::loadMouse() {
@@ -715,10 +715,10 @@ void Process::stub225() {
debug("stub225: animation related, phaseVar %s, arg %d", phaseVar.c_str(), arg);
}
-void Process::setFontGlyphSize() {
- _glyphHeight = pop();
- _glyphWidth = pop();
- debug("setFontGlyphSize %d %d", _glyphWidth, _glyphHeight);
+void Process::setTileSize() {
+ _tileHeight = pop();
+ _tileWidth = pop();
+ debug("setTileSize %d %d", _tileWidth, _tileHeight);
}
void Process::generateRegion() {
@@ -1349,7 +1349,7 @@ ProcessExitCode Process::execute() {
OP (kLoadPreviousScreen, loadPreviousScreen);
OP (kMoveScreenObject, moveScreenObject);
OP (kGetObjectId, getObjectId);
- OP (kSetGlyphSize, setFontGlyphSize);
+ OP (kSetTileSize, setTileSize);
OP (kGenerateRegion, generateRegion);
OP (kGetMaxInventorySize, getMaxInventorySize);
OP (kAppendInventoryObjectNameToSharedSpace, appendInventoryObjectNameToSharedSpace);
Commit: d0ba885b01386f3ebe728f19e3e14e37e161e12a
https://github.com/scummvm/scummvm/commit/d0ba885b01386f3ebe728f19e3e14e37e161e12a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:10+01:00
Commit Message:
AGDS: better inventory enable/disable condition
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3172c84c114..699836f3c66 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -385,8 +385,7 @@ Common::Error AGDSEngine::run() {
runObject(region->onEnter);
}
}
- if (_inventoryRegion)
- _inventory.visible(_inventoryRegion->pointIn(_mouse));
+ _inventory.enable(_inventoryRegion? _inventoryRegion->pointIn(_mouse): false);
}
break;
case Common::EVENT_LBUTTONDOWN:
Commit: 4ec20caa0ee01fc100defb23b1dade2c783c8750
https://github.com/scummvm/scummvm/commit/4ec20caa0ee01fc100defb23b1dade2c783c8750
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:10+01:00
Commit Message:
AGDS: renamed stub200 to SetTileIndex
Changed paths:
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index adc97f4d71d..cdfbf5a8f8f 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -217,7 +217,7 @@ enum Opcode {
kStub197 = 197,
kLoadPicture = 198,
kStub199 = 199,
- kStub200 = 200,
+ kSetTileIndex = 200,
kStub201Handler = 201,
kStub202ScreenHandler = 202,
kPlayFilm = 203,
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 5edec864d40..50bda86f148 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -30,7 +30,7 @@ namespace AGDS {
Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip, Process * caller) :
_engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object), _ip(ip),
_status(kStatusActive), _caller(caller), _exitCode(kExitCodeDestroy),
- _tileWidth(16), _tileHeight(16),
+ _tileWidth(16), _tileHeight(16), _tileResource(0), _tileIndex(0),
_timer(0),
_animationCycles(1), _animationLoop(false), _animationPaused(false), _animationSpeed(100),
_waitForCall(false) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index f34a5e4afa5..07d3623e5e7 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -52,6 +52,8 @@ private:
Common::String _exitArg1, _exitArg2;
int _exitIntArg1, _exitIntArg2;
int _tileWidth, _tileHeight;
+ int _tileResource;
+ int _tileIndex;
Common::String _phaseVar;
int _timer;
int _animationCycles;
@@ -157,6 +159,7 @@ private:
void fadeObject();
void moveScreenObject();
void setTileSize();
+ void setTileIndex();
void getObjectPictureWidth();
void getObjectPictureHeight();
void loadCharacter();
@@ -244,7 +247,6 @@ private:
void stub193();
void stub194();
void stub199();
- void stub200();
void stub201(unsigned size);
void stub202(unsigned size);
void stub209(unsigned size);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index e4ad6b11433..02f9d3c6b5a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -531,6 +531,11 @@ void Process::resetState() {
_animationLoop = false;
_animationPosition = Common::Point();
_animationPaused = false;
+
+ _tileWidth = 16;
+ _tileHeight = 16;
+ _tileIndex = 0;
+ _tileResource = 0;
}
void Process::stub129() {
@@ -644,10 +649,10 @@ void Process::stub199() {
debug("stub199: %d", value);
}
-void Process::stub200() {
- int value = pop();
+void Process::setTileIndex() {
+ int index = pop();
int resource = pop();
- debug("stub200: %d %d", value, resource);
+ debug("setTileIndex: index: %d, resource id: %d ", index, resource);
}
void Process::stub201(unsigned size) {
@@ -1380,7 +1385,7 @@ ProcessExitCode Process::execute() {
OP (kPlayFilm, playFilm);
OP (kAddMouseArea, addMouseArea);
OP (kFogOnCharacter, fogOnCharacter);
- OP (kStub200, stub200);
+ OP (kSetTileIndex, setTileIndex);
OP (kModifyMouseArea, modifyMouseArea);
OP_U (kStub209, stub209);
OP_I (kMoveCharacterNoUserMove, moveCharacter, false);
Commit: caeebc5b80625e8c01f6f3e6e5aaa8d83372dd9e
https://github.com/scummvm/scummvm/commit/caeebc5b80625e8c01f6f3e6e5aaa8d83372dd9e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:10+01:00
Commit Message:
AGDS: better picture caching, allow name -> id lookup and picture reuse
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 699836f3c66..e1301785efc 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -42,7 +42,7 @@
namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Engine(system),
- _gameDescription(gameDesc), _pictureCacheId(0), _sharedStorageIndex(-2),
+ _gameDescription(gameDesc), _pictureCacheId(1), _sharedStorageIndex(-2),
_mjpgPlayer(), _currentScreen(), _previousScreen(),
_defaultMouseCursor(),
_mouse(400, 300), _userEnabled(false), _currentRegion(),
@@ -549,6 +549,20 @@ Character * AGDSEngine::getCharacter(const Common::String &name) const {
Graphics::TransparentSurface * AGDSEngine::loadPicture(const Common::String &name)
{ return convertToTransparent(_resourceManager.loadPicture(name, _pixelFormat)); }
+int AGDSEngine::loadFromCache(const Common::String & name) const {
+ PictureCacheLookup::const_iterator i = _pictureCacheLookup.find(name);
+ return i != _pictureCacheLookup.end()? i->_value: -1;
+}
+
+int AGDSEngine::saveToCache(const Common::String & name, Graphics::TransparentSurface *surface) {
+ if (!surface)
+ return -1;
+ int id = _pictureCacheId++;
+ _pictureCacheLookup[name] = id;
+ _pictureCache[id] = surface;
+ return id;
+}
+
Graphics::TransparentSurface *AGDSEngine::loadFromCache(int id) const {
PictureCacheType::const_iterator i = _pictureCache.find(id);
return (i != _pictureCache.end())? i->_value: NULL;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 92554f18d32..c6ca19ae36c 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -133,14 +133,10 @@ public:
Graphics::TransparentSurface *loadPicture(const Common::String &name);
Graphics::TransparentSurface *convertToTransparent(Graphics::Surface *surface); //destroys surface!
+
+ int loadFromCache(const Common::String & name) const;
Graphics::TransparentSurface *loadFromCache(int id) const;
- int saveToCache(Graphics::TransparentSurface *surface) {
- if (!surface)
- return -1;
- int id = _pictureCacheId++;
- _pictureCache[id] = surface;
- return id;
- }
+ int saveToCache(const Common::String &name, Graphics::TransparentSurface *surface);
void loadFont(int id, const Common::String &name, int gw, int gh);
Font *getFont(int id) const;
@@ -179,6 +175,7 @@ private:
void parseDialogDefs(const Common::String &defs);
typedef Common::HashMap<int, Graphics::TransparentSurface *> PictureCacheType;
+ typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PictureCacheLookup;
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
typedef Common::HashMap<Common::String, Region *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> RegionsType;
typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
@@ -193,6 +190,7 @@ private:
SoundManager _soundManager;
Database _data, _patch; //data and patch databases
PictureCacheType _pictureCache;
+ PictureCacheLookup _pictureCacheLookup;
int _pictureCacheId;
FontsType _fonts;
RegionsType _regions;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 02f9d3c6b5a..960bae8c38e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -107,9 +107,12 @@ void Process::getObjectId() {
void Process::loadPicture() {
Common::String name = popText();
- int value = _engine->saveToCache(_engine->loadPicture(name));
- debug("loadPicture %s -> %d", name.c_str(), value);
- push(value);
+ int cacheId = _engine->loadFromCache(name);
+ if (cacheId < 0) {
+ cacheId = _engine->saveToCache(name, _engine->loadPicture(name));
+ }
+ debug("loadPicture %s -> %d", name.c_str(), cacheId);
+ push(cacheId);
}
void Process::loadAnimation() {
Commit: e7dbd9cd5ce7ac4c0e29cc71b4039815e7476387
https://github.com/scummvm/scummvm/commit/e7dbd9cd5ce7ac4c0e29cc71b4039815e7476387
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:10+01:00
Commit Message:
AGDS: implement SetObjectTile (184) stub
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index cdfbf5a8f8f..80955c98875 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -201,7 +201,7 @@ enum Opcode {
kStub181 = 181,
kSetTileSize = 182,
kGenerateRegion = 183,
- kStub184 = 184,
+ kSetObjectTile = 184,
kGetMaxInventorySize = 185,
kInventoryHasObject = 186,
kAppendInventoryObjectNameToSharedSpace = 187,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 07d3623e5e7..a1043de2f80 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -141,6 +141,7 @@ private:
void loadRegionFromObject();
void generateRegion();
void loadPictureFromObject();
+ void setObjectTile();
void loadAnimationFromObject();
void loadTextFromObject();
void loadAnimation();
@@ -241,7 +242,6 @@ private:
void stub172();
void stub173();
void stub174();
- void stub184();
void stub190();
void stub192();
void stub193();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 960bae8c38e..2628c60cebc 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -653,9 +653,9 @@ void Process::stub199() {
}
void Process::setTileIndex() {
- int index = pop();
- int resource = pop();
- debug("setTileIndex: index: %d, resource id: %d ", index, resource);
+ _tileIndex = pop();
+ _tileResource = pop();
+ debug("setTileIndex: index: %d, resource id: %d ", _tileIndex, _tileResource);
}
void Process::stub201(unsigned size) {
@@ -734,9 +734,18 @@ void Process::generateRegion() {
debug("generateRegion %s", name.c_str());
}
-void Process::stub184() {
+void Process::setObjectTile() {
Common::String name = popString();
- debug("stub184: %s", name.c_str());
+ debug("setObjectTile: %s, tile: %d, resource: %d", name.c_str(), _tileIndex, _tileResource);
+ if (_tileResource <= 0) {
+ warning("invalid resource id, skipping");
+ return;
+ }
+ Graphics::TransparentSurface * surface = _engine->loadFromCache(_tileResource);
+ if (!surface) {
+ warning("picture %d was not loaded", _tileResource);
+ }
+ debug("OK");
}
void Process::setObjectText() {
@@ -1361,7 +1370,7 @@ ProcessExitCode Process::execute() {
OP (kGenerateRegion, generateRegion);
OP (kGetMaxInventorySize, getMaxInventorySize);
OP (kAppendInventoryObjectNameToSharedSpace, appendInventoryObjectNameToSharedSpace);
- OP (kStub184, stub184);
+ OP (kSetObjectTile, setObjectTile);
OP (kInventoryHasObject, inventoryHasObject);
OP (kSetObjectText, setObjectText);
OP (kStub190, stub190);
Commit: 9875a417ef546baa47f569cc829f2c63998b3fe9
https://github.com/scummvm/scummvm/commit/9875a417ef546baa47f569cc829f2c63998b3fe9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:10+01:00
Commit Message:
AGDS: added missing ~Object
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 20940f288dd..8c7ca854470 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -57,6 +57,14 @@ Object::Object(const Common::String &name, Common::SeekableReadStream * stream)
stream->read(_code.data(), _code.size());
}
+Object::~Object() {
+ if (_picture) {
+ _picture->free();
+ delete _picture;
+ }
+}
+
+
void Object::readStringTable(unsigned resOffset, uint16 resCount) {
if (_stringTableLoaded)
return;
@@ -103,7 +111,10 @@ const Object::StringEntry & Object::getString(uint16 index) const {
}
void Object::setPicture(Graphics::TransparentSurface *picture) {
- delete _picture;
+ if (_picture) {
+ _picture->free();
+ delete _picture;
+ }
_picture = picture;
}
diff --git a/engines/agds/object.h b/engines/agds/object.h
index da74407ef12..0720298fb70 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -76,6 +76,7 @@ private:
public:
Object(const Common::String &name, Common::SeekableReadStream * stream);
+ ~Object();
void readStringTable(unsigned resOffset, uint16 resCount);
const StringEntry & getString(uint16 index) const;
Commit: 83d341772e0a1155e85bec72a598cac912c8bd79
https://github.com/scummvm/scummvm/commit/83d341772e0a1155e85bec72a598cac912c8bd79
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:10+01:00
Commit Message:
AGDS: implemented setObjectTile, copy tile data from cache
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 2628c60cebc..b3403076fc3 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -736,16 +736,40 @@ void Process::generateRegion() {
void Process::setObjectTile() {
Common::String name = popString();
- debug("setObjectTile: %s, tile: %d, resource: %d", name.c_str(), _tileIndex, _tileResource);
+ debug("setObjectTile: %s, tile: %d %dx%d, resource: %d", name.c_str(), _tileIndex, _tileWidth, _tileHeight, _tileResource);
+
+ ObjectPtr object = _engine->getCurrentScreen()->find(name);
+ if (!object) {
+ warning("could not find object %s in screen", name.c_str());
+ return;
+ }
+
if (_tileResource <= 0) {
warning("invalid resource id, skipping");
return;
}
+ if (_tileHeight <= 0 || _tileWidth <= 0) {
+ warning("invalid tile size");
+ return;
+ }
Graphics::TransparentSurface * surface = _engine->loadFromCache(_tileResource);
if (!surface) {
warning("picture %d was not loaded", _tileResource);
+ return;
}
- debug("OK");
+
+ int tw = surface->w / _tileWidth;
+ int y = _tileIndex / tw;
+ int x = _tileIndex % tw;
+ debug("tile coordinate %dx%d", x, y);
+
+ Graphics::TransparentSurface * tile = new Graphics::TransparentSurface();
+ tile->create(_tileWidth, _tileHeight, surface->format);
+ tile->applyColorKey(0xff, 0, 0xff);
+ Common::Rect srcRect(_tileWidth, _tileHeight);
+ srcRect.translate(x * _tileWidth, y * _tileHeight);
+ surface->blit(*tile, 0, 0, Graphics::FLIP_NONE, &srcRect);
+ object->setPicture(tile);
}
void Process::setObjectText() {
Commit: aa2333b5775f9186b9bb9a3ab0c0b3843b0bd226
https://github.com/scummvm/scummvm/commit/aa2333b5775f9186b9bb9a3ab0c0b3843b0bd226
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:10+01:00
Commit Message:
AGDS: rename stub190 to SetObjectScale
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 80955c98875..db6160af3e0 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -207,7 +207,7 @@ enum Opcode {
kAppendInventoryObjectNameToSharedSpace = 187,
kSetObjectText = 188,
kStub189 = 189,
- kStub190 = 190,
+ kSetObjectScale = 190,
kStub191 = 191,
kStub192 = 192,
kStub193 = 193,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index a1043de2f80..1459de8c43c 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -242,7 +242,7 @@ private:
void stub172();
void stub173();
void stub174();
- void stub190();
+ void setObjectScale();
void stub192();
void stub193();
void stub194();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b3403076fc3..f3df5171af5 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -632,9 +632,9 @@ void Process::stub193() {
debug("stub193: removing inventory object 0?");
}
-void Process::stub190() {
+void Process::setObjectScale() {
int value = pop();
- debug("stub190 %d", value);
+ debug("setObjectScale stub %d", value);
}
void Process::disableMouseAreas() {
@@ -1397,7 +1397,7 @@ ProcessExitCode Process::execute() {
OP (kSetObjectTile, setObjectTile);
OP (kInventoryHasObject, inventoryHasObject);
OP (kSetObjectText, setObjectText);
- OP (kStub190, stub190);
+ OP (kSetObjectScale, setObjectScale);
OP (kStub191, disableMouseAreas);
OP (kStub193, stub193);
OP (kStub194, stub194);
Commit: 254311b2a3002513c8550f94a304b7b7a4ee9463
https://github.com/scummvm/scummvm/commit/254311b2a3002513c8550f94a304b7b7a4ee9463
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:11+01:00
Commit Message:
AGDS: remove 152/153 offset in stubs
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f3df5171af5..720d583a517 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -574,13 +574,13 @@ void Process::stub138() {
void Process::stub152() {
Common::String name = popString();
debug("stub152(getSomeX): %s", name.c_str());
- push(152);
+ push(0);
}
void Process::stub153() {
Common::String name = popString();
debug("stub153:(getSomeY): %s", name.c_str());
- push(153);
+ push(0);
}
void Process::stub154() {
Commit: c07b92e22803b1365e5f27addc853cee6d2d810d
https://github.com/scummvm/scummvm/commit/c07b92e22803b1365e5f27addc853cee6d2d810d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:11+01:00
Commit Message:
AGDS: check mouse area disabled flag when checking inventory
Changed paths:
engines/agds/agds.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index e1301785efc..7058becc55e 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -385,7 +385,7 @@ Common::Error AGDSEngine::run() {
runObject(region->onEnter);
}
}
- _inventory.enable(_inventoryRegion? _inventoryRegion->pointIn(_mouse): false);
+ _inventory.enable(_inventoryRegion? !mouseMap.disabled() && _inventoryRegion->pointIn(_mouse): false);
}
break;
case Common::EVENT_LBUTTONDOWN:
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 082ada79e9b..8e403634c18 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -78,6 +78,10 @@ public:
_disabled = disabled;
}
+ bool disabled() const {
+ return _disabled;
+ }
+
int add(const MouseRegion & area) {
_mouseRegions.push_back(area);
_mouseRegions.back().id = _nextId++;
Commit: 4a611bbd663eea13712d50d14791abaed5ca141a
https://github.com/scummvm/scummvm/commit/4a611bbd663eea13712d50d14791abaed5ca141a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:11+01:00
Commit Message:
AGDS: add region generation stub
Changed paths:
engines/agds/process_opcodes.cpp
engines/agds/region.cpp
engines/agds/region.h
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 720d583a517..f8194aebaf1 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -731,7 +731,12 @@ void Process::setTileSize() {
void Process::generateRegion() {
Common::String name = popString();
- debug("generateRegion %s", name.c_str());
+ debug("generateRegion %d %d %d %d", _animationPosition.x, _animationPosition.y, _tileWidth, _tileHeight);
+ Common::Rect rect(_tileWidth, _tileHeight);
+ rect.translate(_animationPosition.x, _animationPosition.y);
+ Region * region = new Region(rect);
+ //fixme: leaking region
+ _object->setRegion(region);
}
void Process::setObjectTile() {
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index 74129221a7a..ab68525692a 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -63,6 +63,16 @@ Region::Region(const Common::String &resourceName, Common::SeekableReadStream *
}
}
+Region::Region(const Common::Rect rect): flags(0) {
+ points.push_back(Common::Point(rect.left, rect.top));
+ points.push_back(Common::Point(rect.right, rect.top));
+ points.push_back(Common::Point(rect.right, rect.bottom));
+ points.push_back(Common::Point(rect.left, rect.bottom));
+ center.x = (rect.left + rect.right) / 2;
+ center.y = (rect.top + rect.bottom) / 2;
+}
+
+
//FIXME: copied from wintermute/base_region.cpp
typedef struct {
diff --git a/engines/agds/region.h b/engines/agds/region.h
index 6820ef1d303..e55c098f997 100644
--- a/engines/agds/region.h
+++ b/engines/agds/region.h
@@ -39,6 +39,7 @@ struct Region {
PointsType points;
Region(const Common::String &resourceName, Common::SeekableReadStream * stream);
+ Region(const Common::Rect rect);
bool pointIn(Common::Point point) const;
};
Commit: 769d3c789fd187dcb2475e80dadf6f80c28c2ed3
https://github.com/scummvm/scummvm/commit/769d3c789fd187dcb2475e80dadf6f80c28c2ed3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:11+01:00
Commit Message:
AGDS: fixed SetObjectZ
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index db6160af3e0..d1827a39f1b 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -89,7 +89,7 @@ enum Opcode {
kLoadRegionFromObject = 68,
kLoadPictureFromObject = 69,
kLoadAnimationFromObject = 70,
- kSetObjectHeight = 71,
+ kSetObjectZ = 71,
kUpdateScreenHeightToDisplay = 72,
kLoadTextFromObject = 73,
kScreenSetHeight = 74,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 1459de8c43c..a42920e30a8 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -134,7 +134,7 @@ private:
void loadFont();
void removeScreenObject();
void changeScreenPatch();
- void setObjectHeight();
+ void setObjectZ();
void setScreenHeight();
void updateScreenHeightToDisplay();
void addMouseArea();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f8194aebaf1..90efd2f3937 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -978,9 +978,9 @@ void Process::enableInventory() {
_engine->inventory().enable(true);
}
-void Process::setObjectHeight() {
- int height = pop();
- debug("setObjectHeight %d", height);
+void Process::setObjectZ() {
+ int z = pop();
+ debug("setObjectZ %d", z);
}
void Process::updateScreenHeightToDisplay() {
@@ -1338,7 +1338,7 @@ ProcessExitCode Process::execute() {
OP (kStub83, stub83);
OP (kAnimateCharacter, animateCharacter);
OP (kLoadCharacter, loadCharacter);
- OP (kSetObjectHeight, setObjectHeight);
+ OP (kSetObjectZ, setObjectZ);
OP (kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay);
OP (kLoadTextFromObject, loadTextFromObject);
OP (kScreenSetHeight, setScreenHeight);
Commit: 08505a590eb36c48fccd897199f08640082210ec
https://github.com/scummvm/scummvm/commit/08505a590eb36c48fccd897199f08640082210ec
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:11+01:00
Commit Message:
AGDS: implemented z-order (animations have to be fixed too)
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 8c7ca854470..37b6eaeeee1 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -37,7 +37,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream * stream)
_name(name), _stringTableLoaded(false),
_picture(), _region(),
_animation(), _mouseCursor(),
- _pos(),
+ _pos(), _z(0),
_clickHandler(0), _examineHandler(0),
_alpha(255), _active(false) {
byte id = stream->readByte();
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 0720298fb70..7dbad6817ba 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -68,6 +68,7 @@ private:
Animation * _animation;
Animation * _mouseCursor;
Common::Point _pos, _animationPos;
+ int _z;
Common::String _text;
uint _clickHandler;
uint _examineHandler;
@@ -156,6 +157,14 @@ public:
_pos = pos;
}
+ void z(int z) {
+ _z = z;
+ }
+
+ int z() const {
+ return _z;
+ }
+
const Common::String & getText() const {
return _text;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 90efd2f3937..053a0606d30 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -981,6 +981,12 @@ void Process::enableInventory() {
void Process::setObjectZ() {
int z = pop();
debug("setObjectZ %d", z);
+ _object->z(z);
+ Screen *screen = _engine->getCurrentScreen();
+ bool found = screen->remove(_object);
+ if (found) {
+ screen->add(_object);
+ }
}
void Process::updateScreenHeightToDisplay() {
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 9db69e6e36f..2db4435586f 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -27,7 +27,11 @@
namespace AGDS {
-Screen::Screen(ObjectPtr object, const MouseMap &mouseMap) : _object(object), _name(object->getName()), _mouseMap(mouseMap) {
+int Screen::ObjectZCompare(const ObjectPtr & a, const ObjectPtr & b) {
+ return a->z() - b->z();
+}
+
+Screen::Screen(ObjectPtr object, const MouseMap &mouseMap) : _object(object), _name(object->getName()), _mouseMap(mouseMap), _children(&ObjectZCompare) {
add(object);
}
@@ -44,7 +48,7 @@ void Screen::add(ObjectPtr object) {
if (*i == object)
return;
}
- _children.push_back(object);
+ _children.insert(object);
}
ObjectPtr Screen::find(const Common::String &name) {
@@ -55,6 +59,18 @@ ObjectPtr Screen::find(const Common::String &name) {
return ObjectPtr();
}
+bool Screen::remove(const ObjectPtr & object) {
+ bool found = false;
+ for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ) {
+ if (*i == object) {
+ i = _children.erase(i);
+ found = true;
+ } else
+ ++i;
+ }
+ return found;
+}
+
bool Screen::remove(const Common::String &name) {
bool found = false;
for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ) {
@@ -69,13 +85,21 @@ bool Screen::remove(const Common::String &name) {
void Screen::paint(AGDSEngine & engine, Graphics::Surface & backbuffer) {
- for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
- (*i)->paint(engine, backbuffer);
+ ChildrenType::iterator i;
+ for(i = _children.begin(); i != _children.end(); ++i) {
+ ObjectPtr object = *i;
+ if (object->z() > 0)
+ break;
+ object->paint(engine, backbuffer);
}
- for(AnimationsType::iterator i = _animations.begin(); i != _animations.end(); ++i) {
- Animation * animation = *i;
+ for(AnimationsType::iterator j = _animations.begin(); j != _animations.end(); ++j) {
+ Animation * animation = *j;
animation->paint(engine, backbuffer, Common::Point());
}
+ for(; i != _children.end(); ++i) {
+ ObjectPtr object = *i;
+ object->paint(engine, backbuffer);
+ }
}
ObjectPtr Screen::find(Common::Point pos) const {
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 8e403634c18..4c98db0f03c 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -24,6 +24,7 @@
#define AGDS_SCREEN_H
#include "common/scummsys.h"
+#include "common/array.h"
#include "common/list.h"
#include "common/ptr.h"
#include "common/str.h"
@@ -96,8 +97,10 @@ public:
};
class Screen {
+ static int ObjectZCompare(const ObjectPtr & a, const ObjectPtr & b);
+
typedef Common::List<Animation *> AnimationsType;
- typedef Common::List<ObjectPtr> ChildrenType;
+ typedef Common::SortedArray<ObjectPtr, const ObjectPtr &> ChildrenType;
ObjectPtr _object;
Common::String _name;
@@ -134,6 +137,7 @@ public:
_animations.push_back(animation);
}
bool remove(const Common::String & name);
+ bool remove(const ObjectPtr & object);
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer);
ObjectPtr find(Common::Point pos) const;
ObjectPtr find(const Common::String &name);
Commit: 358084b4bad9bcb584b24673420fd7a4131c05f4
https://github.com/scummvm/scummvm/commit/358084b4bad9bcb584b24673420fd7a4131c05f4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:11+01:00
Commit Message:
AGDS: sorted animation by z, implemented global and local z-order
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 7b19d189bc1..d3f77d614ad 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -31,7 +31,7 @@
namespace AGDS {
Animation::Animation():
- _flic(), _frames(0), _loop(false), _cycles(1), _phase(0), _paused(true), _speed(100) {
+ _flic(), _frames(0), _loop(false), _cycles(1), _phase(0), _paused(true), _speed(100), _z(0) {
}
Animation::~Animation() {
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 0fb9847908f..b90cc65283b 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -45,6 +45,7 @@ class Animation {
int _phase;
bool _paused;
int _speed;
+ int _z;
public:
Animation();
@@ -87,6 +88,14 @@ public:
_speed = speed;
}
+ void z(int z) {
+ _z = z;
+ }
+
+ int z() const {
+ return _z;
+ }
+
bool load(Common::SeekableReadStream *stream);
void updatePhaseVar(AGDSEngine & engine);
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Common::Point dst);
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index d1827a39f1b..b9551bfff27 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -146,7 +146,7 @@ enum Opcode {
kStub126 = 126,
kSetTimer = 127,
kProcessResetState = 128,
- kStub129 = 129,
+ kSetAnimationZ = 129,
kSetCycles = 130,
kSetRandom = 131,
kSetPeriodic = 132,
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 50bda86f148..a30a8364fac 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -32,7 +32,7 @@ Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip, Process * ca
_status(kStatusActive), _caller(caller), _exitCode(kExitCodeDestroy),
_tileWidth(16), _tileHeight(16), _tileResource(0), _tileIndex(0),
_timer(0),
- _animationCycles(1), _animationLoop(false), _animationPaused(false), _animationSpeed(100),
+ _animationCycles(1), _animationLoop(false), _animationZ(0), _animationPaused(false), _animationSpeed(100),
_waitForCall(false) {
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index a42920e30a8..0a5d023105b 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -59,6 +59,7 @@ private:
int _animationCycles;
bool _animationLoop;
Common::Point _animationPosition;
+ int _animationZ;
bool _animationPaused;
int _animationSpeed;
bool _waitForCall;
@@ -228,7 +229,6 @@ private:
void stub83();
void stub102();
void resetState();
- void stub129();
void setCycles();
void setRandom();
void stub133();
@@ -257,6 +257,7 @@ private:
void setAnimationLoop();
void setAnimationPaused();
void setAnimationSpeed();
+ void setAnimationZ();
void stub223();
void stub225();
void stub231();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 053a0606d30..3f4d451da27 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -121,6 +121,7 @@ void Process::loadAnimation() {
Animation *animation = _engine->loadAnimation(name);
if (animation) {
animation->position(_animationPosition);
+ animation->z(_animationZ);
animation->phaseVar(_phaseVar);
animation->loop(_animationLoop);
animation->cycles(_animationCycles);
@@ -534,6 +535,7 @@ void Process::resetState() {
_animationLoop = false;
_animationPosition = Common::Point();
_animationPaused = false;
+ _animationZ = 0;
_tileWidth = 16;
_tileHeight = 16;
@@ -541,9 +543,10 @@ void Process::resetState() {
_tileResource = 0;
}
-void Process::stub129() {
- int value = pop();
- debug("stub129 %d animation duration?", value);
+void Process::setAnimationZ() {
+ int z = pop();
+ debug("setAnimationZ %d", z);
+ _animationZ = z;
}
void Process::stub133() {
@@ -1360,7 +1363,7 @@ ProcessExitCode Process::execute() {
OP (kNPCSay, npcSay);
OP (kSetTimer, setTimer);
OP (kProcessResetState, resetState);
- OP (kStub129, stub129);
+ OP (kSetAnimationZ, setAnimationZ);
OP (kSetCycles, setCycles);
OP (kSetRandom, setRandom);
OP (kStub133, stub133);
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 2db4435586f..0f4521ec62c 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -31,7 +31,13 @@ int Screen::ObjectZCompare(const ObjectPtr & a, const ObjectPtr & b) {
return a->z() - b->z();
}
-Screen::Screen(ObjectPtr object, const MouseMap &mouseMap) : _object(object), _name(object->getName()), _mouseMap(mouseMap), _children(&ObjectZCompare) {
+int Screen::AnimationZCompare(const Animation *a, const Animation *b) {
+ return a->z() - b->z();
+}
+
+Screen::Screen(ObjectPtr object, const MouseMap &mouseMap) :
+ _object(object), _name(object->getName()), _mouseMap(mouseMap),
+ _children(&ObjectZCompare), _animations(&AnimationZCompare) {
add(object);
}
@@ -85,21 +91,50 @@ bool Screen::remove(const Common::String &name) {
void Screen::paint(AGDSEngine & engine, Graphics::Surface & backbuffer) {
+#if 0
+ ChildrenType::iterator child = _children.begin();
+ AnimationsType::iterator animation = _animations.begin();
+ int idx = 0;
+ while(child != _children.end() || animation != _animations.end()) {
+ bool child_valid = child != _children.end();
+ bool animation_valid = animation != _animations.end();
+ if (child_valid && animation_valid) {
+ if ((*child)->z() < (*animation)->z()) {
+ debug("object %d, z: %d", idx++, (*child)->z());
+ (*child)->paint(engine, backbuffer);
+ ++child;
+ } else {
+ debug("animatin %d, z: %d", idx++, (*animation)->z());
+ (*animation)->paint(engine, backbuffer, Common::Point());
+ ++animation;
+ }
+ } else if (child_valid) {
+ debug("object %d, z: %d", idx++, (*child)->z());
+ (*child)->paint(engine, backbuffer);
+ ++child;
+ } else {
+ debug("animatin %d, z: %d", idx++, (*animation)->z());
+ (*animation)->paint(engine, backbuffer, Common::Point());
+ ++animation;
+ }
+ }
+#else
ChildrenType::iterator i;
for(i = _children.begin(); i != _children.end(); ++i) {
- ObjectPtr object = *i;
- if (object->z() > 0)
- break;
- object->paint(engine, backbuffer);
+ ObjectPtr object = *i;
+ if (object->z() > 0)
+ break;
+ object->paint(engine, backbuffer);
}
for(AnimationsType::iterator j = _animations.begin(); j != _animations.end(); ++j) {
- Animation * animation = *j;
- animation->paint(engine, backbuffer, Common::Point());
+ Animation * animation = *j;
+ animation->paint(engine, backbuffer, Common::Point());
}
for(; i != _children.end(); ++i) {
- ObjectPtr object = *i;
- object->paint(engine, backbuffer);
+ ObjectPtr object = *i;
+ object->paint(engine, backbuffer);
}
+#endif
}
ObjectPtr Screen::find(Common::Point pos) const {
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 4c98db0f03c..44c4f01e5d6 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -98,8 +98,9 @@ public:
class Screen {
static int ObjectZCompare(const ObjectPtr & a, const ObjectPtr & b);
+ static int AnimationZCompare(const Animation *a, const Animation *b);
- typedef Common::List<Animation *> AnimationsType;
+ typedef Common::SortedArray<Animation *, const Animation *> AnimationsType;
typedef Common::SortedArray<ObjectPtr, const ObjectPtr &> ChildrenType;
ObjectPtr _object;
@@ -134,7 +135,7 @@ public:
void add(ObjectPtr object);
void add(Animation * animation) {
- _animations.push_back(animation);
+ _animations.insert(animation);
}
bool remove(const Common::String & name);
bool remove(const ObjectPtr & object);
Commit: 557e529d287e8af65d3ef57f775bf3cb3aae560b
https://github.com/scummvm/scummvm/commit/557e529d287e8af65d3ef57f775bf3cb3aae560b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:11+01:00
Commit Message:
AGDS: implemented generateRegion
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3f4d451da27..32c622032ac 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -734,12 +734,16 @@ void Process::setTileSize() {
void Process::generateRegion() {
Common::String name = popString();
- debug("generateRegion %d %d %d %d", _animationPosition.x, _animationPosition.y, _tileWidth, _tileHeight);
+ debug("generateRegion %s %d %d %d %d", name.c_str(), _animationPosition.x, _animationPosition.y, _tileWidth, _tileHeight);
Common::Rect rect(_tileWidth, _tileHeight);
rect.translate(_animationPosition.x, _animationPosition.y);
Region * region = new Region(rect);
//fixme: leaking region
- _object->setRegion(region);
+ ObjectPtr object = _engine->getCurrentScreen()->find(name);
+ if (object)
+ _object->setRegion(region);
+ else
+ warning("no object found");
}
void Process::setObjectTile() {
Commit: b403f1fe91287b4196a62b42c94714f025187f0c
https://github.com/scummvm/scummvm/commit/b403f1fe91287b4196a62b42c94714f025187f0c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:11+01:00
Commit Message:
AGDS: added rclick handler
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 7058becc55e..965bc14ef37 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -389,12 +389,14 @@ Common::Error AGDSEngine::run() {
}
break;
case Common::EVENT_LBUTTONDOWN:
+ case Common::EVENT_RBUTTONDOWN:
_mouse = event.mouse;
if (_userEnabled) {
- debug("lclick %d, %d", _mouse.x, _mouse.y);
+ bool lclick = event.type == Common::EVENT_LBUTTONDOWN;
+ debug("%s %d, %d", lclick? "lclick": "rclick", _mouse.x, _mouse.y);
ObjectPtr object = _currentScreen->find(_mouse);
if (object) {
- uint ip = object->getClickHandler();
+ uint ip = lclick? object->getClickHandler(): object->getExamineHandler();
if (ip) {
debug("found handler: %s %08x", object->getName().c_str(), ip + 7);
runProcess(object, ip);
Commit: 2561dcfd9d8e0083ff7e4f139d008b789644db3b
https://github.com/scummvm/scummvm/commit/2561dcfd9d8e0083ff7e4f139d008b789644db3b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:11+01:00
Commit Message:
AGDS: add region to screen object
Changed paths:
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 32c622032ac..f1ec52a70c8 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -192,11 +192,7 @@ void Process::loadScreenObject() {
void Process::loadScreenRegion() {
Common::String name = popString();
debug("loadScreenRegion %s", name.c_str());
- Screen * screen = _engine->getCurrentScreen();
- if (screen)
- screen->getObject()->setRegion(_engine->loadRegion(name));
- else
- warning("no current screen");
+ _engine->getCurrentScreen()->region(_engine->loadRegion(name));
}
void Process::cloneObject() {
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 0f4521ec62c..82f3696ba3a 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -36,7 +36,7 @@ int Screen::AnimationZCompare(const Animation *a, const Animation *b) {
}
Screen::Screen(ObjectPtr object, const MouseMap &mouseMap) :
- _object(object), _name(object->getName()), _mouseMap(mouseMap),
+ _object(object), _name(object->getName()), _mouseMap(mouseMap), _region(NULL),
_children(&ObjectZCompare), _animations(&AnimationZCompare) {
add(object);
}
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 44c4f01e5d6..11980bdea7b 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -108,6 +108,7 @@ class Screen {
ChildrenType _children;
AnimationsType _animations;
MouseMap _mouseMap;
+ Region * _region;
public:
struct KeyHandler {
@@ -133,6 +134,14 @@ public:
return _mouseMap;
}
+ Region * region() const {
+ return _region;
+ }
+
+ void region(Region * region) {
+ _region = region;
+ }
+
void add(ObjectPtr object);
void add(Animation * animation) {
_animations.insert(animation);
Commit: efed59d26d24a1e94eed13eba36798f707ec15a4
https://github.com/scummvm/scummvm/commit/efed59d26d24a1e94eed13eba36798f707ec15a4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:11+01:00
Commit Message:
AGDS: add Region::toString
Changed paths:
engines/agds/process_opcodes.cpp
engines/agds/region.cpp
engines/agds/region.h
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f1ec52a70c8..6e9a2331ca5 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -734,7 +734,8 @@ void Process::generateRegion() {
Common::Rect rect(_tileWidth, _tileHeight);
rect.translate(_animationPosition.x, _animationPosition.y);
Region * region = new Region(rect);
- //fixme: leaking region
+ debug("result region: %s", region->toString().c_str());
+ //fixme: leaking region, convert regions to RegionPtr
ObjectPtr object = _engine->getCurrentScreen()->find(name);
if (object)
_object->setRegion(region);
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index ab68525692a..ffd678ace88 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -72,6 +72,16 @@ Region::Region(const Common::Rect rect): flags(0) {
center.y = (rect.top + rect.bottom) / 2;
}
+Common::String Region::toString() const {
+ Common::String str = Common::String::format("region(%d, %d, [", center.x, center.y);
+ for(size_t i = 0; i < points.size(); ++i) {
+ if (i != 0)
+ str += ", ";
+ str += Common::String::format("(%d, %d)", points[i].x, points[i].y);
+ }
+ str += "]";
+ return str;
+}
//FIXME: copied from wintermute/base_region.cpp
diff --git a/engines/agds/region.h b/engines/agds/region.h
index e55c098f997..2d78c06fe5c 100644
--- a/engines/agds/region.h
+++ b/engines/agds/region.h
@@ -42,6 +42,7 @@ struct Region {
Region(const Common::Rect rect);
bool pointIn(Common::Point point) const;
+ Common::String toString() const;
};
Commit: 9b69df80ecad69a747a2169c3126fd2f181cae39
https://github.com/scummvm/scummvm/commit/9b69df80ecad69a747a2169c3126fd2f181cae39
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:12+01:00
Commit Message:
AGDS: convert region pointer to shared pointer, removed _regions
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/object.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 965bc14ef37..4c58ea8098b 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -111,20 +111,15 @@ bool AGDSEngine::load() {
return true;
}
-Region * AGDSEngine::loadRegion(const Common::String &name) {
- RegionsType::iterator i = _regions.find(name);
- if (i != _regions.end())
- return i->_value;
-
+RegionPtr AGDSEngine::loadRegion(const Common::String &name) {
debug("loading region %s", name.c_str());
Common::SeekableReadStream * stream = _data.getEntry(name);
if (!stream)
error("no database entry for %s\n", name.c_str());
- Region *region = new Region(name, stream);
+ RegionPtr region(new Region(name, stream));
delete stream;
- _regions[name] = region;
return region;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index c6ca19ae36c..0ec64b049ee 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -58,6 +58,7 @@ class Object;
typedef Common::SharedPtr<Object> ObjectPtr;
class Process;
struct Region;
+typedef Common::SharedPtr<Region> RegionPtr;
struct MouseRegion;
class MJPGPlayer;
class Screen;
@@ -97,7 +98,7 @@ public:
void loadScreen(const Common::String & name);
void setCurrentScreen(Screen *screen);
- Region * loadRegion(const Common::String &name);
+ RegionPtr loadRegion(const Common::String &name);
Common::String loadText(const Common::String &name);
int appendToSharedStorage(const Common::String &value);
@@ -177,7 +178,6 @@ private:
typedef Common::HashMap<int, Graphics::TransparentSurface *> PictureCacheType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PictureCacheLookup;
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
- typedef Common::HashMap<Common::String, Region *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> RegionsType;
typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
typedef Common::HashMap<Common::String, Animation *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> AnimationsType;
@@ -193,7 +193,6 @@ private:
PictureCacheLookup _pictureCacheLookup;
int _pictureCacheId;
FontsType _fonts;
- RegionsType _regions;
AnimationsType _animations;
CharactersType _characters;
ProcessListType _processes;
@@ -213,7 +212,7 @@ private:
MouseMap _mouseMap;
Common::RandomSource _random;
Inventory _inventory;
- Region * _inventoryRegion;
+ RegionPtr _inventoryRegion;
bool _fastMode;
DialogDefsType _dialogDefs;
Common::String _dialogScript;
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 7dbad6817ba..5038f483815 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -37,6 +37,7 @@ namespace AGDS {
class AGDSEngine;
struct Region;
+typedef Common::SharedPtr<Region> RegionPtr;
class Animation;
class Object {
@@ -64,7 +65,7 @@ private:
KeyHandlersType _keyHandlers;
UseHandlersType _useHandlers;
Graphics::TransparentSurface * _picture;
- Region * _region;
+ RegionPtr _region;
Animation * _animation;
Animation * _mouseCursor;
Common::Point _pos, _animationPos;
@@ -123,11 +124,11 @@ public:
_alpha = (100 - alpha) * 255 / 100;
}
- void setRegion(Region *region) {
+ void region(RegionPtr region) {
_region = region;
}
- Region * getRegion() const {
+ RegionPtr region() const {
return _region;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 6e9a2331ca5..e8ef47b46cd 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -78,7 +78,7 @@ void Process::getIntegerSystemVariable() {
void Process::getRegionCenterX() {
Common::String name = popString();
- Region *reg = _engine->loadRegion(name);
+ RegionPtr reg = _engine->loadRegion(name);
int value = reg->center.x;
push(value);
debug("getRegionCenterX %s -> %d", name.c_str(), value);
@@ -86,7 +86,7 @@ void Process::getRegionCenterX() {
void Process::getRegionCenterY() {
Common::String name = popString();
- Region *reg = _engine->loadRegion(name);
+ RegionPtr reg = _engine->loadRegion(name);
int value = reg->center.y;
push(value);
debug("getRegionCenterY %s -> %d", name.c_str(), value);
@@ -192,7 +192,9 @@ void Process::loadScreenObject() {
void Process::loadScreenRegion() {
Common::String name = popString();
debug("loadScreenRegion %s", name.c_str());
- _engine->getCurrentScreen()->region(_engine->loadRegion(name));
+ RegionPtr region = _engine->loadRegion(name);
+ _engine->getCurrentScreen()->region(region);
+ debug("region: %s", region->toString().c_str());
}
void Process::cloneObject() {
@@ -733,12 +735,11 @@ void Process::generateRegion() {
debug("generateRegion %s %d %d %d %d", name.c_str(), _animationPosition.x, _animationPosition.y, _tileWidth, _tileHeight);
Common::Rect rect(_tileWidth, _tileHeight);
rect.translate(_animationPosition.x, _animationPosition.y);
- Region * region = new Region(rect);
+ RegionPtr region(new Region(rect));
debug("result region: %s", region->toString().c_str());
- //fixme: leaking region, convert regions to RegionPtr
ObjectPtr object = _engine->getCurrentScreen()->find(name);
if (object)
- _object->setRegion(region);
+ _object->region(region);
else
warning("no object found");
}
@@ -824,9 +825,12 @@ void Process::moveScreenObject() {
Common::String name = popString();
debug("moveScreenObject %s %d %d", name.c_str(), arg2, arg3);
ObjectPtr object = _engine->getCurrentScreenObject(name);
- if (object)
+ if (object) {
+ RegionPtr region = object->region();
+ if (region)
+ debug("object region %s", region->toString().c_str());
object->move(Common::Point(arg2, arg3));
- else
+ } else
warning("moveScreenObject: object %s not found", name.c_str());
}
@@ -1053,7 +1057,8 @@ void Process::addMouseArea() {
Common::String name = popString();
debug("addMouseArea (region: %s) %s %s", name.c_str(), onEnter.c_str(), onLeave.c_str());
- Region *region = _engine->loadRegion(name);
+ RegionPtr region = _engine->loadRegion(name);
+ debug("region: %s", region->toString().c_str());
int value = _engine->_mouseMap.add(MouseRegion(region, onEnter, onLeave));
debug("\tmouse area id -> %d", value);
@@ -1113,7 +1118,8 @@ void Process::leaveCharacter() {
Common::String arg2 = popString();
Common::String arg1 = popString();
debug("leaveCharacter %s %s", arg1.c_str(), arg2.c_str());
- _engine->loadRegion(arg2);
+ RegionPtr region = _engine->loadRegion(arg2);
+ debug("region: %s", region->toString().c_str());
}
void Process::setCharacter() {
@@ -1161,7 +1167,9 @@ void Process::fogOnCharacter() {
void Process::loadRegionFromObject() {
Common::String name = popString();
debug("loadRegionFromObject %s", name.c_str());
- _object->setRegion(_engine->loadRegion(name));
+ RegionPtr region = _engine->loadRegion(name);
+ debug("region: %s", region->toString().c_str());
+ _object->region(region);
}
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 82f3696ba3a..8d8065081dd 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -36,7 +36,7 @@ int Screen::AnimationZCompare(const Animation *a, const Animation *b) {
}
Screen::Screen(ObjectPtr object, const MouseMap &mouseMap) :
- _object(object), _name(object->getName()), _mouseMap(mouseMap), _region(NULL),
+ _object(object), _name(object->getName()), _mouseMap(mouseMap),
_children(&ObjectZCompare), _animations(&AnimationZCompare) {
add(object);
}
@@ -140,7 +140,7 @@ void Screen::paint(AGDSEngine & engine, Graphics::Surface & backbuffer) {
ObjectPtr Screen::find(Common::Point pos) const {
for(ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
- Region *region = object->getRegion();
+ RegionPtr region = object->region();
if (region && region->pointIn(pos))
return object;
}
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 11980bdea7b..0b3c7a0e665 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -41,10 +41,12 @@ class Object;
class Animation;
typedef Common::SharedPtr<Object> ObjectPtr;
struct Region;
+typedef Common::SharedPtr<Region> RegionPtr;
+
struct MouseRegion {
int id;
- Region * region;
+ RegionPtr region;
int enabled;
bool currentlyIn;
@@ -60,7 +62,7 @@ struct MouseRegion {
--enabled;
}
- MouseRegion(Region * reg, const Common::String &enter, const Common::String &leave):
+ MouseRegion(RegionPtr reg, const Common::String &enter, const Common::String &leave):
id(-1), region(reg), enabled(1), currentlyIn(false), onEnter(enter), onLeave(leave) {
}
};
@@ -108,7 +110,7 @@ class Screen {
ChildrenType _children;
AnimationsType _animations;
MouseMap _mouseMap;
- Region * _region;
+ RegionPtr _region;
public:
struct KeyHandler {
@@ -134,11 +136,11 @@ public:
return _mouseMap;
}
- Region * region() const {
+ RegionPtr region() const {
return _region;
}
- void region(Region * region) {
+ void region(RegionPtr region) {
_region = region;
}
Commit: 864593241684b520e7555811d787a65ac492ca2e
https://github.com/scummvm/scummvm/commit/864593241684b520e7555811d787a65ac492ca2e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:12+01:00
Commit Message:
AGDS: renamed Object::move to Object::moveTo
Changed paths:
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 5038f483815..1f90b31c0ee 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -154,7 +154,7 @@ public:
void paint(AGDSEngine &engine, Graphics::Surface &backbuffer);
- void move(Common::Point pos) {
+ void moveTo(Common::Point pos) {
_pos = pos;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index e8ef47b46cd..25b517b9a2a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -829,7 +829,7 @@ void Process::moveScreenObject() {
RegionPtr region = object->region();
if (region)
debug("object region %s", region->toString().c_str());
- object->move(Common::Point(arg2, arg3));
+ object->moveTo(Common::Point(arg2, arg3));
} else
warning("moveScreenObject: object %s not found", name.c_str());
}
Commit: 98a64b9c0eb27900324ffda68768ddd7ada03b07
https://github.com/scummvm/scummvm/commit/98a64b9c0eb27900324ffda68768ddd7ada03b07
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:12+01:00
Commit Message:
AGDS: remove loadObject from inventoryAdd
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 25b517b9a2a..263406bc8f7 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -920,7 +920,6 @@ void Process::inventoryClear() {
void Process::inventoryAddObject() {
Common::String name = popString();
debug("inventoryAddObject %s", name.c_str());
- _engine->inventory().add(_engine->loadObject(name));
suspend(kExitCodeLoadInventoryObject, name);
}
Commit: be5ddfa47857032a8681ff464e5b821eefec87f7
https://github.com/scummvm/scummvm/commit/be5ddfa47857032a8681ff464e5b821eefec87f7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:12+01:00
Commit Message:
AGDS: skip movies in fast mode
Changed paths:
engines/agds/agds.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 0ec64b049ee..dada7739e73 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -172,6 +172,10 @@ public:
_soundManager.play(resource, phaseVar);
}
+ bool fastMode() const {
+ return _fastMode;
+ }
+
private:
void parseDialogDefs(const Common::String &defs);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 263406bc8f7..fc15d8188e6 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -908,7 +908,9 @@ void Process::playFilm() {
Common::String video = popText();
debug("playFilm %s %s", video.c_str(), audio.c_str());
- _engine->playFilm(video, audio);
+ if (!_engine->fastMode()) {
+ _engine->playFilm(video, audio);
+ }
suspend();
}
Commit: 18b2366f68c10f15a97ba8930e49ad0085c763b2
https://github.com/scummvm/scummvm/commit/18b2366f68c10f15a97ba8930e49ad0085c763b2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:12+01:00
Commit Message:
AGDS: add Region::move
Changed paths:
engines/agds/region.cpp
engines/agds/region.h
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index ffd678ace88..13fc10a3a0e 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -83,6 +83,16 @@ Common::String Region::toString() const {
return str;
}
+void Region::move(Common::Point rel) {
+ if (rel.x == 0 && rel.y == 0)
+ return;
+
+ center += rel;
+ for(uint i = 0; i < points.size(); ++i)
+ points[i] += rel;
+}
+
+
//FIXME: copied from wintermute/base_region.cpp
typedef struct {
diff --git a/engines/agds/region.h b/engines/agds/region.h
index 2d78c06fe5c..bcdc6642a8f 100644
--- a/engines/agds/region.h
+++ b/engines/agds/region.h
@@ -43,6 +43,7 @@ struct Region {
bool pointIn(Common::Point point) const;
Common::String toString() const;
+ void move(Common::Point rel);
};
Commit: 1fadd916fd31e56fc59cbf250ddce19a12b967c1
https://github.com/scummvm/scummvm/commit/1fadd916fd31e56fc59cbf250ddce19a12b967c1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:12+01:00
Commit Message:
AGDS: rename stack arguments
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index fc15d8188e6..c9d4811b081 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -820,16 +820,16 @@ void Process::clearScreen() {
}
void Process::moveScreenObject() {
- int arg3 = pop();
- int arg2 = pop();
+ int y = pop();
+ int x = pop();
Common::String name = popString();
- debug("moveScreenObject %s %d %d", name.c_str(), arg2, arg3);
+ debug("moveScreenObject %s %d %d", name.c_str(), x, y);
ObjectPtr object = _engine->getCurrentScreenObject(name);
if (object) {
RegionPtr region = object->region();
if (region)
debug("object region %s", region->toString().c_str());
- object->moveTo(Common::Point(arg2, arg3));
+ object->moveTo(Common::Point(x, y));
} else
warning("moveScreenObject: object %s not found", name.c_str());
}
Commit: d834fd88d41921423bb8382a3718908b0257d807
https://github.com/scummvm/scummvm/commit/d834fd88d41921423bb8382a3718908b0257d807
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:12+01:00
Commit Message:
AGDS: added getEngineId
Changed paths:
engines/agds/detection.cpp
diff --git a/engines/agds/detection.cpp b/engines/agds/detection.cpp
index 53d2a3968fc..b65a3a09cdc 100644
--- a/engines/agds/detection.cpp
+++ b/engines/agds/detection.cpp
@@ -37,6 +37,9 @@ public:
AGDSMetaEngine() : AdvancedMetaEngine(AGDS::gameDescriptions, sizeof(ADGameDescription), agdsGames) {
_maxScanDepth = 3;
}
+ virtual const char *getEngineId() const {
+ return "agds";
+ }
virtual const char *getName() const {
return "AGDS Engine";
Commit: 83bfb88b555fbadcddf7023faf710655f4614838
https://github.com/scummvm/scummvm/commit/83bfb88b555fbadcddf7023faf710655f4614838
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:12+01:00
Commit Message:
AGDS: fix typo
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 4c58ea8098b..eecdd488aba 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -594,7 +594,7 @@ void AGDSEngine::initSystemVariables() {
_systemVars["inventory_scr"] = new StringSystemVariable();
_systemVars["escape_scr"] = new StringSystemVariable("none");
_systemVars["load_scr"] = new StringSystemVariable();
- _systemVars["load_scr"] = new StringSystemVariable();
+ _systemVars["save_scr"] = new StringSystemVariable();
_systemVars["gfx_bright"] = new IntegerSystemVariable(50);
_systemVars["gfx_contrast"] = new IntegerSystemVariable(50);
Commit: 10c806386e14f3cd72c1188c2f10dfebcf6e2145
https://github.com/scummvm/scummvm/commit/10c806386e14f3cd72c1188c2f10dfebcf6e2145
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:12+01:00
Commit Message:
AGDS: add double-add warning
Changed paths:
engines/agds/screen.cpp
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 8d8065081dd..64ba0e24ff1 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -51,8 +51,10 @@ void Screen::add(ObjectPtr object) {
return;
}
for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
- if (*i == object)
+ if (*i == object) {
+ warning("double adding object %s", (*i)->getName().c_str());
return;
+ }
}
_children.insert(object);
}
Commit: ddfacea58abca5c18b16407ac8acdba60f64af28
https://github.com/scummvm/scummvm/commit/ddfacea58abca5c18b16407ac8acdba60f64af28
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:12+01:00
Commit Message:
AGDS: change z to 10 (seems to be game's default)
Changed paths:
engines/agds/object.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 37b6eaeeee1..6c3a42a0be5 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -37,12 +37,11 @@ Object::Object(const Common::String &name, Common::SeekableReadStream * stream)
_name(name), _stringTableLoaded(false),
_picture(), _region(),
_animation(), _mouseCursor(),
- _pos(), _z(0),
+ _pos(), _z(10),
_clickHandler(0), _examineHandler(0),
_alpha(255), _active(false) {
- byte id = stream->readByte();
- byte flag = stream->readByte();
- debug("id: 0x%02x %u, flag: %u", id, id, flag);
+ byte id = stream->readUint16LE();
+ debug("id: 0x%02x %u", id, id);
uint16 dataSize = stream->readUint16LE();
if (dataSize != 0)
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 64ba0e24ff1..4d7afb5061c 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -124,7 +124,7 @@ void Screen::paint(AGDSEngine & engine, Graphics::Surface & backbuffer) {
ChildrenType::iterator i;
for(i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
- if (object->z() > 0)
+ if (object->z() > 10)
break;
object->paint(engine, backbuffer);
}
Commit: 4ef0bfa0bd53487215f658c3dc4fc2f1a2f3bf78
https://github.com/scummvm/scummvm/commit/4ef0bfa0bd53487215f658c3dc4fc2f1a2f3bf78
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:13+01:00
Commit Message:
AGDS: destroy processes owned by different screen
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index eecdd488aba..4a4d5723205 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -200,7 +200,9 @@ void AGDSEngine::resetCurrentScreen()
void AGDSEngine::runProcess(ProcessListType::iterator &it) {
Process & process = *it;
if (process.parentScreenName() != _currentScreenName) {
- ++it;
+ if (process.active())
+ process.activate(false);
+ it = _processes.erase(it);
return;
}
Commit: 20cb24ea43ce3a1d8d1df95af5f6fa6075d085e3
https://github.com/scummvm/scummvm/commit/20cb24ea43ce3a1d8d1df95af5f6fa6075d085e3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:13+01:00
Commit Message:
AGDS: speculative fix for z order, assume default z of 1000, instead of 10.
Changed paths:
engines/agds/object.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 6c3a42a0be5..7ec81b17433 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -37,7 +37,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream * stream)
_name(name), _stringTableLoaded(false),
_picture(), _region(),
_animation(), _mouseCursor(),
- _pos(), _z(10),
+ _pos(), _z(1000),
_clickHandler(0), _examineHandler(0),
_alpha(255), _active(false) {
byte id = stream->readUint16LE();
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 4d7afb5061c..624f97fd8d9 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -28,11 +28,11 @@
namespace AGDS {
int Screen::ObjectZCompare(const ObjectPtr & a, const ObjectPtr & b) {
- return a->z() - b->z();
+ return b->z() - a->z();
}
int Screen::AnimationZCompare(const Animation *a, const Animation *b) {
- return a->z() - b->z();
+ return b->z() - a->z();
}
Screen::Screen(ObjectPtr object, const MouseMap &mouseMap) :
@@ -123,18 +123,18 @@ void Screen::paint(AGDSEngine & engine, Graphics::Surface & backbuffer) {
#else
ChildrenType::iterator i;
for(i = _children.begin(); i != _children.end(); ++i) {
- ObjectPtr object = *i;
- if (object->z() > 10)
- break;
- object->paint(engine, backbuffer);
+ ObjectPtr object = *i;
+ if (object->z() < 1000)
+ break;
+ object->paint(engine, backbuffer);
}
for(AnimationsType::iterator j = _animations.begin(); j != _animations.end(); ++j) {
- Animation * animation = *j;
- animation->paint(engine, backbuffer, Common::Point());
+ Animation * animation = *j;
+ animation->paint(engine, backbuffer, Common::Point());
}
for(; i != _children.end(); ++i) {
- ObjectPtr object = *i;
- object->paint(engine, backbuffer);
+ ObjectPtr object = *i;
+ object->paint(engine, backbuffer);
}
#endif
}
Commit: 98a8946b437d088b94e900fe84186b732e1aa83a
https://github.com/scummvm/scummvm/commit/98a8946b437d088b94e900fe84186b732e1aa83a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:13+01:00
Commit Message:
AGDS: enable scummvm-based save/load dialogs
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/detection.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 4a4d5723205..08992d7ee79 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -777,6 +777,24 @@ bool AGDSEngine::tickDialog() {
return true;
}
+bool AGDSEngine::hasFeature(EngineFeature f) const
+{
+ switch(f)
+ {
+ case kSupportsSubtitleOptions:
+ case kSupportsReturnToLauncher:
+ case kSupportsLoadingDuringRuntime:
+ case kSupportsSavingDuringRuntime:
+ return true;
+ default:
+ return false;
+ }
+}
+
+Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file)
+{ return Common::Error(Common::kNoError); }
+Common::Error AGDSEngine::saveGameStream(Common::WriteStream *file, bool isAutosave)
+{ return Common::Error(Common::kNoError); }
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index dada7739e73..4abaeb43e3b 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -89,6 +89,13 @@ private:
void tick();
public:
+
+ bool hasFeature(EngineFeature f) const;
+ Common::Error loadGameStream(Common::SeekableReadStream *file);
+ Common::Error saveGameStream(Common::WriteStream *file, bool isAutosave);
+ bool canLoadGameStateCurrently() override { return true; }
+ bool canSaveGameStateCurrently() override { return _userEnabled; }
+
ObjectPtr loadObject(const Common::String & name, const Common::String & prototype = Common::String());
void runObject(ObjectPtr object);
void runObject(const Common::String & name, const Common::String &prototype = Common::String());
diff --git a/engines/agds/detection.cpp b/engines/agds/detection.cpp
index b65a3a09cdc..eb214a87429 100644
--- a/engines/agds/detection.cpp
+++ b/engines/agds/detection.cpp
@@ -50,6 +50,24 @@ public:
}
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+ virtual bool hasFeature(MetaEngineFeature f) const
+ {
+ switch(f) {
+ case kSavesSupportThumbnail:
+ case kSavesUseExtendedFormat:
+ case kSimpleSavesNames:
+ case kSupportsDeleteSave:
+ case kSupportsListSaves:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ int getMaximumSaveSlot() const {
+ return 99;
+ }
+
};
bool AGDSMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
Commit: 02b818057d7a41bb16075634b7b992b5d1628b7d
https://github.com/scummvm/scummvm/commit/02b818057d7a41bb16075634b7b992b5d1628b7d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:13+01:00
Commit Message:
AGDS: reformat with clang-format --style=file
Changed paths:
engines/agds/agds.cpp
engines/agds/animation.cpp
engines/agds/database.cpp
engines/agds/detection.cpp
engines/agds/font.cpp
engines/agds/inventory.cpp
engines/agds/mjpgPlayer.cpp
engines/agds/object.cpp
engines/agds/process.cpp
engines/agds/process_opcodes.cpp
engines/agds/region.cpp
engines/agds/resourceManager.cpp
engines/agds/screen.cpp
engines/agds/soundManager.cpp
engines/agds/systemVariable.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 08992d7ee79..752b42ecf7c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -30,11 +30,11 @@
#include "agds/region.h"
#include "agds/screen.h"
#include "agds/systemVariable.h"
+#include "common/debug.h"
#include "common/error.h"
#include "common/events.h"
-#include "common/ini-file.h"
#include "common/file.h"
-#include "common/debug.h"
+#include "common/ini-file.h"
#include "common/system.h"
#include "engines/util.h"
#include "graphics/transparent_surface.h"
@@ -42,21 +42,21 @@
namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Engine(system),
- _gameDescription(gameDesc), _pictureCacheId(1), _sharedStorageIndex(-2),
- _mjpgPlayer(), _currentScreen(), _previousScreen(),
- _defaultMouseCursor(),
- _mouse(400, 300), _userEnabled(false), _currentRegion(),
- _random("agds"),
- _inventoryRegion(),
- _soundManager(this, system->getMixer()),
- _fastMode(false),
- _dialogScriptPos(0) {
+ _gameDescription(gameDesc), _pictureCacheId(1), _sharedStorageIndex(-2),
+ _mjpgPlayer(), _currentScreen(), _previousScreen(),
+ _defaultMouseCursor(),
+ _mouse(400, 300), _userEnabled(false), _currentRegion(),
+ _random("agds"),
+ _inventoryRegion(),
+ _soundManager(this, system->getMixer()),
+ _fastMode(false),
+ _dialogScriptPos(0) {
}
AGDSEngine::~AGDSEngine() {
delete _currentScreen;
delete _previousScreen;
- for(PictureCacheType::iterator i = _pictureCache.begin(); i != _pictureCache.end(); ++i) {
+ for (PictureCacheType::iterator i = _pictureCache.begin(); i != _pictureCache.end(); ++i) {
i->_value->free();
delete i->_value;
}
@@ -67,8 +67,8 @@ bool AGDSEngine::initGraphics() {
typedef Common::List<Graphics::PixelFormat> FormatsType;
FormatsType formats = _system->getSupportedFormats();
- for(FormatsType::iterator fi = formats.begin(); fi != formats.end(); ++fi) {
- const Graphics::PixelFormat & format = *fi;
+ for (FormatsType::iterator fi = formats.begin(); fi != formats.end(); ++fi) {
+ const Graphics::PixelFormat &format = *fi;
if (fi->bytesPerPixel == 4 && format == Graphics::TransparentSurface::getSupportedPixelFormat()) {
debug("found mode %s", format.toString().c_str());
_pixelFormat = format;
@@ -95,7 +95,7 @@ bool AGDSEngine::load() {
error("no video mode found");
Common::INIFile::SectionKeyList values = config.getKeys("core");
- for(Common::INIFile::SectionKeyList::iterator i = values.begin(); i != values.end(); ++i) {
+ for (Common::INIFile::SectionKeyList::iterator i = values.begin(); i != values.end(); ++i) {
if (i->key == "path")
if (!_resourceManager.addPath(i->value))
return false;
@@ -113,7 +113,7 @@ bool AGDSEngine::load() {
RegionPtr AGDSEngine::loadRegion(const Common::String &name) {
debug("loading region %s", name.c_str());
- Common::SeekableReadStream * stream = _data.getEntry(name);
+ Common::SeekableReadStream *stream = _data.getEntry(name);
if (!stream)
error("no database entry for %s\n", name.c_str());
@@ -127,10 +127,10 @@ Common::String AGDSEngine::loadText(const Common::String &entryName) {
return ResourceManager::loadText(_data.getEntry(entryName));
}
-ObjectPtr AGDSEngine::loadObject(const Common::String & name, const Common::String &prototype) {
+ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::String &prototype) {
debug("loadObject %s %s", name.c_str(), prototype.c_str());
- Common::String clone = prototype.empty()? name: prototype;
- Common::SeekableReadStream * stream = _data.getEntry(clone);
+ Common::String clone = prototype.empty() ? name : prototype;
+ Common::SeekableReadStream *stream = _data.getEntry(clone);
if (!stream)
error("no database entry for %s\n", clone.c_str());
@@ -147,22 +147,21 @@ void AGDSEngine::runObject(ObjectPtr object) {
runProcess(object);
}
-void AGDSEngine::runProcess(ObjectPtr object, uint ip, Process * caller) {
+void AGDSEngine::runProcess(ObjectPtr object, uint ip, Process *caller) {
object->activate(true);
_processes.push_front(Process(this, object, ip, caller));
ProcessListType::iterator it = _processes.begin();
runProcess(it);
}
-void AGDSEngine::runObject(const Common::String & name, const Common::String &prototype)
-{
+void AGDSEngine::runObject(const Common::String &name, const Common::String &prototype) {
ObjectPtr object = getCurrentScreenObject(name);
if (!object)
object = loadObject(name, prototype);
runObject(object);
}
-void AGDSEngine::loadScreen(const Common::String & name) {
+void AGDSEngine::loadScreen(const Common::String &name) {
debug("loadScreen %s", name.c_str());
resetCurrentScreen();
_soundManager.stopAll();
@@ -183,8 +182,7 @@ void AGDSEngine::setCurrentScreen(Screen *screen) {
_previousScreen = NULL;
}
-void AGDSEngine::resetCurrentScreen()
-{
+void AGDSEngine::resetCurrentScreen() {
if (_currentRegion) {
if (_currentRegion->currentlyIn)
runObject(_currentRegion->onLeave);
@@ -196,9 +194,8 @@ void AGDSEngine::resetCurrentScreen()
_currentScreen = NULL;
}
-
void AGDSEngine::runProcess(ProcessListType::iterator &it) {
- Process & process = *it;
+ Process &process = *it;
if (process.parentScreenName() != _currentScreenName) {
if (process.active())
process.activate(false);
@@ -221,7 +218,7 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
process.activate(true);
ProcessExitCode code = process.execute();
bool destroy = false;
- switch(code) {
+ switch (code) {
case kExitCodeDestroy:
destroy = true;
break;
@@ -275,12 +272,12 @@ void AGDSEngine::tick() {
if (tickDialog())
return;
tickInventory();
- for(ProcessListType::iterator p = _processes.begin(); active() && p != _processes.end(); ) {
+ for (ProcessListType::iterator p = _processes.begin(); active() && p != _processes.end();) {
runProcess(p);
}
}
-Animation * AGDSEngine::loadMouseCursor(const Common::String &name) {
+Animation *AGDSEngine::loadMouseCursor(const Common::String &name) {
Animation *animation = loadAnimation(name);
animation->loop(true);
animation->phaseVar(Common::String());
@@ -292,24 +289,24 @@ void AGDSEngine::changeMouseArea(int id, int enabled) {
if (id < 0)
return;
- MouseRegion * mouseArea = _mouseMap.find(id);
+ MouseRegion *mouseArea = _mouseMap.find(id);
if (mouseArea) {
- switch(enabled) {
- case 1:
- debug("enabling mouse area %d", id);
- mouseArea->enable();
- break;
- case 0:
- debug("disabling mouse area %d", id);
- if (mouseArea->currentlyIn) {
- runObject(mouseArea->onLeave);
- }
- mouseArea->disable();
- break;
- case -1:
- debug("removing mouse area %d", id);
- _mouseMap.remove(id);
- break;
+ switch (enabled) {
+ case 1:
+ debug("enabling mouse area %d", id);
+ mouseArea->enable();
+ break;
+ case 0:
+ debug("disabling mouse area %d", id);
+ if (mouseArea->currentlyIn) {
+ runObject(mouseArea->onLeave);
+ }
+ mouseArea->disable();
+ break;
+ case -1:
+ debug("removing mouse area %d", id);
+ _mouseMap.remove(id);
+ break;
}
} else
warning("mouse area %d could not be found", id);
@@ -321,88 +318,86 @@ Common::Error AGDSEngine::run() {
Common::EventManager *eventManager = _system->getEventManager();
- while(!shouldQuit()) {
+ while (!shouldQuit()) {
uint32 frameStarted = _system->getMillis();
Common::Event event;
- while(eventManager->pollEvent(event)) {
+ while (eventManager->pollEvent(event)) {
if (!_currentScreen)
continue;
- switch(event.type) {
- case Common::EVENT_KEYDOWN:
- {
- Common::String key;
-
- switch(event.kbd.keycode) {
- case Common::KEYCODE_SPACE:
- skipFilm();
- key = "space";
- break;
- case Common::KEYCODE_ESCAPE:
- skipFilm();
- key = "escape";
- break;
- case Common::KEYCODE_TAB:
- key = "tab";
- break;
- case Common::KEYCODE_f:
- if (event.kbd.flags & Common::KBD_CTRL) {
- _fastMode = !_fastMode;
- }
- break;
- default:
- if (event.kbd.ascii)
- key = Common::String(static_cast<char>(event.kbd.ascii));
- };
- if (_userEnabled && !key.empty()) {
- Screen::KeyHandler handler = _currentScreen->findKeyHandler(key);
- if (handler.object) {
- debug("found handler for key %s: %s %08x", key.c_str(), handler.object->getName().c_str(), handler.ip + 7);
- runProcess(handler.object, handler.ip);
- }
- }
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN: {
+ Common::String key;
+
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_SPACE:
+ skipFilm();
+ key = "space";
+ break;
+ case Common::KEYCODE_ESCAPE:
+ skipFilm();
+ key = "escape";
+ break;
+ case Common::KEYCODE_TAB:
+ key = "tab";
+ break;
+ case Common::KEYCODE_f:
+ if (event.kbd.flags & Common::KBD_CTRL) {
+ _fastMode = !_fastMode;
}
break;
- case Common::EVENT_MOUSEMOVE:
- _mouse = event.mouse;
- if (_userEnabled) {
- MouseMap &mouseMap = _currentScreen->mouseMap();
- MouseRegion *region = mouseMap.find(_mouse);
- if (region != _currentRegion) {
- if (_currentRegion) {
- MouseRegion *currentRegion = _currentRegion;
- _currentRegion = NULL;
- currentRegion->currentlyIn = false;
- runObject(currentRegion->onLeave);
- }
- if (region) {
- _currentRegion = region;
- _currentRegion->currentlyIn = true;
- runObject(region->onEnter);
- }
+ default:
+ if (event.kbd.ascii)
+ key = Common::String(static_cast<char>(event.kbd.ascii));
+ };
+ if (_userEnabled && !key.empty()) {
+ Screen::KeyHandler handler = _currentScreen->findKeyHandler(key);
+ if (handler.object) {
+ debug("found handler for key %s: %s %08x", key.c_str(), handler.object->getName().c_str(), handler.ip + 7);
+ runProcess(handler.object, handler.ip);
+ }
+ }
+ } break;
+ case Common::EVENT_MOUSEMOVE:
+ _mouse = event.mouse;
+ if (_userEnabled) {
+ MouseMap &mouseMap = _currentScreen->mouseMap();
+ MouseRegion *region = mouseMap.find(_mouse);
+ if (region != _currentRegion) {
+ if (_currentRegion) {
+ MouseRegion *currentRegion = _currentRegion;
+ _currentRegion = NULL;
+ currentRegion->currentlyIn = false;
+ runObject(currentRegion->onLeave);
+ }
+ if (region) {
+ _currentRegion = region;
+ _currentRegion->currentlyIn = true;
+ runObject(region->onEnter);
}
- _inventory.enable(_inventoryRegion? !mouseMap.disabled() && _inventoryRegion->pointIn(_mouse): false);
}
- break;
- case Common::EVENT_LBUTTONDOWN:
- case Common::EVENT_RBUTTONDOWN:
- _mouse = event.mouse;
- if (_userEnabled) {
- bool lclick = event.type == Common::EVENT_LBUTTONDOWN;
- debug("%s %d, %d", lclick? "lclick": "rclick", _mouse.x, _mouse.y);
- ObjectPtr object = _currentScreen->find(_mouse);
- if (object) {
- uint ip = lclick? object->getClickHandler(): object->getExamineHandler();
- if (ip) {
- debug("found handler: %s %08x", object->getName().c_str(), ip + 7);
- runProcess(object, ip);
- }
+ _inventory.enable(_inventoryRegion ? !mouseMap.disabled() && _inventoryRegion->pointIn(_mouse) : false);
+ }
+ break;
+ case Common::EVENT_LBUTTONDOWN:
+ case Common::EVENT_RBUTTONDOWN:
+ _mouse = event.mouse;
+ if (_userEnabled) {
+ bool lclick = event.type == Common::EVENT_LBUTTONDOWN;
+ debug("%s %d, %d", lclick ? "lclick" : "rclick", _mouse.x, _mouse.y);
+ ObjectPtr object = _currentScreen->find(_mouse);
+ if (object) {
+ uint ip = lclick ? object->getClickHandler() : object->getExamineHandler();
+ if (ip) {
+ debug("found handler: %s %08x", object->getName().c_str(), ip + 7);
+ runProcess(object, ip);
}
}
- break;
- default:
- break;
+ }
+ break;
+ default:
+ break;
}
}
@@ -410,7 +405,7 @@ Common::Error AGDSEngine::run() {
if (_userEnabled && _currentScreen) {
ObjectPtr object = _currentScreen->find(_mouse);
- Animation *cursor = object? object->getMouseCursor(): NULL;
+ Animation *cursor = object ? object->getMouseCursor() : NULL;
if (cursor)
mouseCursor = cursor;
}
@@ -426,7 +421,7 @@ Common::Error AGDSEngine::run() {
const Graphics::Surface *surface = _mjpgPlayer->decodeFrame();
if (surface) {
- Graphics::Surface * converted = surface->convertTo(_pixelFormat);
+ Graphics::Surface *converted = surface->convertTo(_pixelFormat);
Common::Point dst((backbuffer->w - converted->w) / 2, (backbuffer->h - converted->h) / 2);
Common::Rect srcRect(converted->getRect());
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer->getRect()))
@@ -450,7 +445,7 @@ Common::Error AGDSEngine::run() {
mouseCursor->paint(*this, *backbuffer, _mouse);
}
- for(CharactersType::iterator i = _characters.begin(); i != _characters.end(); ++i)
+ for (CharactersType::iterator i = _characters.begin(); i != _characters.end(); ++i)
i->_value->paint(*this, *backbuffer);
_system->unlockScreen();
@@ -487,7 +482,7 @@ int AGDSEngine::appendToSharedStorage(const Common::String &value) {
return index;
}
-const Common::String & AGDSEngine::getSharedStorage(int id) const {
+const Common::String &AGDSEngine::getSharedStorage(int id) const {
int index = -2 - id;
if (index < 0 || index >= 10)
error("shared storage id is out of range");
@@ -504,7 +499,7 @@ int AGDSEngine::getGlobal(const Common::String &name) const {
}
}
-Animation * AGDSEngine::loadAnimation(const Common::String &name) {
+Animation *AGDSEngine::loadAnimation(const Common::String &name) {
AnimationsType::iterator i = _animations.find(name);
if (i != _animations.end())
return i->_value;
@@ -520,17 +515,16 @@ Animation * AGDSEngine::loadAnimation(const Common::String &name) {
return animation;
}
-Animation * AGDSEngine::findAnimationByPhaseVar(const Common::String &phaseVar) {
- for(AnimationsType::iterator i = _animations.begin(); i != _animations.end(); ++i) {
- Animation * animation = i->_value;
+Animation *AGDSEngine::findAnimationByPhaseVar(const Common::String &phaseVar) {
+ for (AnimationsType::iterator i = _animations.begin(); i != _animations.end(); ++i) {
+ Animation *animation = i->_value;
if (animation->phaseVar() == phaseVar)
return animation;
}
return NULL;
}
-
-Character * AGDSEngine::loadCharacter(const Common::String &id, const Common::String &name, const Common::String &object) {
+Character *AGDSEngine::loadCharacter(const Common::String &id, const Common::String &name, const Common::String &object) {
CharactersType::iterator i = _characters.find(id);
if (i != _characters.end())
return i->_value;
@@ -540,20 +534,19 @@ Character * AGDSEngine::loadCharacter(const Common::String &id, const Common::St
return character;
}
-Character * AGDSEngine::getCharacter(const Common::String &name) const {
+Character *AGDSEngine::getCharacter(const Common::String &name) const {
CharactersType::const_iterator i = _characters.find(name);
- return i != _characters.end() ? i->_value: NULL;
+ return i != _characters.end() ? i->_value : NULL;
}
-Graphics::TransparentSurface * AGDSEngine::loadPicture(const Common::String &name)
-{ return convertToTransparent(_resourceManager.loadPicture(name, _pixelFormat)); }
+Graphics::TransparentSurface *AGDSEngine::loadPicture(const Common::String &name) { return convertToTransparent(_resourceManager.loadPicture(name, _pixelFormat)); }
-int AGDSEngine::loadFromCache(const Common::String & name) const {
+int AGDSEngine::loadFromCache(const Common::String &name) const {
PictureCacheLookup::const_iterator i = _pictureCacheLookup.find(name);
- return i != _pictureCacheLookup.end()? i->_value: -1;
+ return i != _pictureCacheLookup.end() ? i->_value : -1;
}
-int AGDSEngine::saveToCache(const Common::String & name, Graphics::TransparentSurface *surface) {
+int AGDSEngine::saveToCache(const Common::String &name, Graphics::TransparentSurface *surface) {
if (!surface)
return -1;
int id = _pictureCacheId++;
@@ -564,13 +557,13 @@ int AGDSEngine::saveToCache(const Common::String & name, Graphics::TransparentSu
Graphics::TransparentSurface *AGDSEngine::loadFromCache(int id) const {
PictureCacheType::const_iterator i = _pictureCache.find(id);
- return (i != _pictureCache.end())? i->_value: NULL;
+ return (i != _pictureCache.end()) ? i->_value : NULL;
}
void AGDSEngine::loadFont(int id, const Common::String &name, int gw, int gh) {
debug("loadFont %d %s %d %d", id, name.c_str(), gw, gh);
Graphics::TransparentSurface *surface = loadPicture(name);
- Font * & font = _fonts[id];
+ Font *&font = _fonts[id];
delete font;
font = new Font(surface, gw, gh);
}
@@ -585,7 +578,7 @@ Font *AGDSEngine::getFont(int id) const {
Graphics::TransparentSurface *AGDSEngine::convertToTransparent(Graphics::Surface *surface) {
if (!surface)
return NULL;
- Graphics::TransparentSurface * t = new Graphics::TransparentSurface(*surface, true);
+ Graphics::TransparentSurface *t = new Graphics::TransparentSurface(*surface, true);
t->applyColorKey(0xff, 0, 0xff);
surface->free();
delete surface;
@@ -593,62 +586,62 @@ Graphics::TransparentSurface *AGDSEngine::convertToTransparent(Graphics::Surface
}
void AGDSEngine::initSystemVariables() {
- _systemVars["inventory_scr"] = new StringSystemVariable();
- _systemVars["escape_scr"] = new StringSystemVariable("none");
- _systemVars["load_scr"] = new StringSystemVariable();
- _systemVars["save_scr"] = new StringSystemVariable();
+ _systemVars["inventory_scr"] = new StringSystemVariable();
+ _systemVars["escape_scr"] = new StringSystemVariable("none");
+ _systemVars["load_scr"] = new StringSystemVariable();
+ _systemVars["save_scr"] = new StringSystemVariable();
- _systemVars["gfx_bright"] = new IntegerSystemVariable(50);
- _systemVars["gfx_contrast"] = new IntegerSystemVariable(50);
+ _systemVars["gfx_bright"] = new IntegerSystemVariable(50);
+ _systemVars["gfx_contrast"] = new IntegerSystemVariable(50);
- _systemVars["sound_volume"] = new IntegerSystemVariable(100);
- _systemVars["music_volume"] = new IntegerSystemVariable(80);
- _systemVars["tell_volume"] = new IntegerSystemVariable(100);
+ _systemVars["sound_volume"] = new IntegerSystemVariable(100);
+ _systemVars["music_volume"] = new IntegerSystemVariable(80);
+ _systemVars["tell_volume"] = new IntegerSystemVariable(100);
- _systemVars["text_speed"] = new IntegerSystemVariable(70);
- _systemVars["tell_mode"] = new IntegerSystemVariable(3);
- _systemVars["version"] = new IntegerSystemVariable(1);
+ _systemVars["text_speed"] = new IntegerSystemVariable(70);
+ _systemVars["tell_mode"] = new IntegerSystemVariable(3);
+ _systemVars["version"] = new IntegerSystemVariable(1);
- _systemVars["objtext_x"] = new IntegerSystemVariable(-1);
- _systemVars["objtext_y"] = new IntegerSystemVariable(-1);
- _systemVars["objtext_mode"] = new IntegerSystemVariable(-1);
- _systemVars["objtext_font"] = new IntegerSystemVariable(-1);
+ _systemVars["objtext_x"] = new IntegerSystemVariable(-1);
+ _systemVars["objtext_y"] = new IntegerSystemVariable(-1);
+ _systemVars["objtext_mode"] = new IntegerSystemVariable(-1);
+ _systemVars["objtext_font"] = new IntegerSystemVariable(-1);
- _systemVars["inv_open"] = new StringSystemVariable();
- _systemVars["inv_close"] = new StringSystemVariable();
- _systemVars["inv_region"] = new StringSystemVariable();
+ _systemVars["inv_open"] = new StringSystemVariable();
+ _systemVars["inv_close"] = new StringSystemVariable();
+ _systemVars["inv_region"] = new StringSystemVariable();
- _systemVars["anim_zoom"] = new IntegerSystemVariable(1);
+ _systemVars["anim_zoom"] = new IntegerSystemVariable(1);
- _systemVars["screen_curtain"] = new IntegerSystemVariable(1);
- _systemVars["music_curtain"] = new IntegerSystemVariable(1);
- _systemVars["sound_curtain"] = new IntegerSystemVariable(1);
+ _systemVars["screen_curtain"] = new IntegerSystemVariable(1);
+ _systemVars["music_curtain"] = new IntegerSystemVariable(1);
+ _systemVars["sound_curtain"] = new IntegerSystemVariable(1);
- _systemVars["old_music_volume"] = new IntegerSystemVariable();
- _systemVars["old_sound_volume"] = new IntegerSystemVariable();
- _systemVars["old_screen_fade"] = new IntegerSystemVariable();
+ _systemVars["old_music_volume"] = new IntegerSystemVariable();
+ _systemVars["old_sound_volume"] = new IntegerSystemVariable();
+ _systemVars["old_screen_fade"] = new IntegerSystemVariable();
- _systemVars["subtitle_x"] = new IntegerSystemVariable();
- _systemVars["subtitle_y"] = new IntegerSystemVariable();
- _systemVars["subtitle_type"] = new IntegerSystemVariable(3);
- _systemVars["subtitles"] = new IntegerSystemVariable();
+ _systemVars["subtitle_x"] = new IntegerSystemVariable();
+ _systemVars["subtitle_y"] = new IntegerSystemVariable();
+ _systemVars["subtitle_type"] = new IntegerSystemVariable(3);
+ _systemVars["subtitles"] = new IntegerSystemVariable();
- _systemVars["tell_font"] = new IntegerSystemVariable();
- _systemVars["npc_tell_font"] = new IntegerSystemVariable();
- _systemVars["edit_font"] = new IntegerSystemVariable();
- _systemVars["delay_after_tell"] = new IntegerSystemVariable();
+ _systemVars["tell_font"] = new IntegerSystemVariable();
+ _systemVars["npc_tell_font"] = new IntegerSystemVariable();
+ _systemVars["edit_font"] = new IntegerSystemVariable();
+ _systemVars["delay_after_tell"] = new IntegerSystemVariable();
- _systemVars["scroll_factor"] = new IntegerSystemVariable(30);
+ _systemVars["scroll_factor"] = new IntegerSystemVariable(30);
- _systemVars["dialog_var"] = new IntegerSystemVariable();
- _systemVars["subtitle_width"] = new IntegerSystemVariable(-1);
- _systemVars["flash_mouse"] = new IntegerSystemVariable();
- _systemVars["scale_char"] = new IntegerSystemVariable();
+ _systemVars["dialog_var"] = new IntegerSystemVariable();
+ _systemVars["subtitle_width"] = new IntegerSystemVariable(-1);
+ _systemVars["flash_mouse"] = new IntegerSystemVariable();
+ _systemVars["scale_char"] = new IntegerSystemVariable();
- _systemVars["init_resources"] = new StringSystemVariable();
- _systemVars["done_resources"] = new StringSystemVariable();
- _systemVars["tell_close_inv"] = new IntegerSystemVariable(1);
- _systemVars["gamma"] = new IntegerSystemVariable();
+ _systemVars["init_resources"] = new StringSystemVariable();
+ _systemVars["done_resources"] = new StringSystemVariable();
+ _systemVars["tell_close_inv"] = new IntegerSystemVariable(1);
+ _systemVars["gamma"] = new IntegerSystemVariable();
}
SystemVariable *AGDSEngine::getSystemVariable(const Common::String &name) {
@@ -659,7 +652,7 @@ SystemVariable *AGDSEngine::getSystemVariable(const Common::String &name) {
error("no system variable %s", name.c_str());
}
-void AGDSEngine::runDialog(const Common::String &dialogScript, const Common::String & defs) {
+void AGDSEngine::runDialog(const Common::String &dialogScript, const Common::String &defs) {
parseDialogDefs(defs);
_dialogScript = dialogScript;
_dialogScriptPos = 0;
@@ -669,7 +662,7 @@ void AGDSEngine::runDialog(const Common::String &dialogScript, const Common::Str
void AGDSEngine::parseDialogDefs(const Common::String &defs) {
Common::String name, value;
bool readName = true;
- for(uint32 p = 0, size = defs.size(); p < size; ++p) {
+ for (uint32 p = 0, size = defs.size(); p < size; ++p) {
char ch = defs[p];
if (ch == ' ') {
continue;
@@ -712,7 +705,7 @@ void AGDSEngine::tickInventory() {
_inventory.visible(true);
}
- const Common::String & inv_region_name = getSystemVariable("inv_region")->getString();
+ const Common::String &inv_region_name = getSystemVariable("inv_region")->getString();
if (inv_region_name.empty())
return;
@@ -737,7 +730,7 @@ bool AGDSEngine::tickDialog() {
return false;
Common::String line;
- while(_dialogScriptPos < n && _dialogScript[_dialogScriptPos] != '\n' && _dialogScript[_dialogScriptPos] != '\r') {
+ while (_dialogScriptPos < n && _dialogScript[_dialogScriptPos] != '\n' && _dialogScript[_dialogScriptPos] != '\r') {
line += _dialogScript[_dialogScriptPos++];
}
++_dialogScriptPos;
@@ -777,24 +770,20 @@ bool AGDSEngine::tickDialog() {
return true;
}
-bool AGDSEngine::hasFeature(EngineFeature f) const
-{
- switch(f)
- {
- case kSupportsSubtitleOptions:
- case kSupportsReturnToLauncher:
- case kSupportsLoadingDuringRuntime:
- case kSupportsSavingDuringRuntime:
- return true;
- default:
- return false;
+bool AGDSEngine::hasFeature(EngineFeature f) const {
+ switch (f) {
+ case kSupportsSubtitleOptions:
+ case kSupportsReturnToLauncher:
+ case kSupportsLoadingDuringRuntime:
+ case kSupportsSavingDuringRuntime:
+ return true;
+ default:
+ return false;
}
}
-Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file)
-{ return Common::Error(Common::kNoError); }
+Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) { return Common::Error(Common::kNoError); }
-Common::Error AGDSEngine::saveGameStream(Common::WriteStream *file, bool isAutosave)
-{ return Common::Error(Common::kNoError); }
+Common::Error AGDSEngine::saveGameStream(Common::WriteStream *file, bool isAutosave) { return Common::Error(Common::kNoError); }
} // End of namespace AGDS
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index d3f77d614ad..f9513518280 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -30,16 +30,15 @@
namespace AGDS {
-Animation::Animation():
- _flic(), _frames(0), _loop(false), _cycles(1), _phase(0), _paused(true), _speed(100), _z(0) {
+Animation::Animation() : _flic(), _frames(0), _loop(false), _cycles(1), _phase(0), _paused(true), _speed(100), _z(0) {
}
Animation::~Animation() {
delete _flic;
}
-bool Animation::load(Common::SeekableReadStream* stream) {
- Video::FlicDecoder * flic = new Video::FlicDecoder;
+bool Animation::load(Common::SeekableReadStream *stream) {
+ Video::FlicDecoder *flic = new Video::FlicDecoder;
if (flic->loadStream(stream)) {
_frames = flic->getFrameCount();
delete _flic;
@@ -52,17 +51,17 @@ bool Animation::load(Common::SeekableReadStream* stream) {
}
}
-void Animation::updatePhaseVar(AGDSEngine & engine) {
+void Animation::updatePhaseVar(AGDSEngine &engine) {
if (!_phaseVar.empty())
engine.setGlobal(_phaseVar, _phase);
}
-void Animation::paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Common::Point dst) {
+void Animation::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point dst) {
if (_paused || _phase == -1) {
return;
}
- const Graphics::Surface * frame = _flic->decodeNextFrame();
+ const Graphics::Surface *frame = _flic->decodeNextFrame();
if (!frame) {
if (!_loop && _phase >= _cycles * _frames) {
_phase = -1; //end of animation
@@ -78,7 +77,7 @@ void Animation::paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Commo
++_phase;
updatePhaseVar(engine);
- Graphics::TransparentSurface * c = engine.convertToTransparent(frame->convertTo(engine.pixelFormat(), _flic->getPalette()));
+ Graphics::TransparentSurface *c = engine.convertToTransparent(frame->convertTo(engine.pixelFormat(), _flic->getPalette()));
dst += _position;
Common::Rect srcRect = c->getRect();
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
@@ -88,12 +87,10 @@ void Animation::paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Commo
}
int Animation::width() const {
- return _flic? _flic->getWidth(): 0;
+ return _flic ? _flic->getWidth() : 0;
}
int Animation::height() const {
- return _flic? _flic->getHeight(): 0;
+ return _flic ? _flic->getHeight() : 0;
}
-
-
-}
+} // namespace AGDS
diff --git a/engines/agds/database.cpp b/engines/agds/database.cpp
index 02ad3ad04be..4e27e60aef0 100644
--- a/engines/agds/database.cpp
+++ b/engines/agds/database.cpp
@@ -21,64 +21,63 @@
*/
#include "agds/database.h"
+#include "common/algorithm.h"
#include "common/debug.h"
#include "common/file.h"
-#include "common/algorithm.h"
namespace AGDS {
- bool Database::open(const Common::String& filename) {
- static const uint32 kMagic = 666;
+bool Database::open(const Common::String &filename) {
+ static const uint32 kMagic = 666;
- _filename = filename;
- Common::File file;
- if (!file.open(filename))
- return false;
- uint32 magic = file.readUint32LE();
- if (magic != kMagic) {
- debug("invalid magic for database %s", filename.c_str());
- return false;
- }
- _writeable = file.readUint32LE();
- _totalEntries = file.readUint32LE();
- _usedEntries = file.readUint32LE();
- _maxNameSize = file.readUint32LE();
- if (_maxNameSize == 0) {
- debug("invalid max name record size");
- return false;
- }
-
- static const uint32 kHeaderFieldSize = 0x09;
- static const uint32 kHeaderSize = 0x14;
+ _filename = filename;
+ Common::File file;
+ if (!file.open(filename))
+ return false;
+ uint32 magic = file.readUint32LE();
+ if (magic != kMagic) {
+ debug("invalid magic for database %s", filename.c_str());
+ return false;
+ }
+ _writeable = file.readUint32LE();
+ _totalEntries = file.readUint32LE();
+ _usedEntries = file.readUint32LE();
+ _maxNameSize = file.readUint32LE();
+ if (_maxNameSize == 0) {
+ debug("invalid max name record size");
+ return false;
+ }
- uint32 dataOffset = kHeaderSize + (_maxNameSize + kHeaderFieldSize) * _totalEntries;
- Common::Array<char> nameBuffer(_maxNameSize + 1);
- for(uint32 i = 0; i < _usedEntries; ++i) {
- uint32 offset = file.readUint32LE();
- file.read(nameBuffer.data(), nameBuffer.size());
- char *z = Common::find(nameBuffer.begin(), nameBuffer.end(), 0);
- Common::String name(nameBuffer.data(), z - nameBuffer.begin());
- uint32 size = file.readUint32LE();
- //debug("adb entry: %s, offset %08x, size: %u", name.c_str(), offset, size);
- _entries.setVal(name, Entry(dataOffset + offset, size));
- }
+ static const uint32 kHeaderFieldSize = 0x09;
+ static const uint32 kHeaderSize = 0x14;
- return true;
+ uint32 dataOffset = kHeaderSize + (_maxNameSize + kHeaderFieldSize) * _totalEntries;
+ Common::Array<char> nameBuffer(_maxNameSize + 1);
+ for (uint32 i = 0; i < _usedEntries; ++i) {
+ uint32 offset = file.readUint32LE();
+ file.read(nameBuffer.data(), nameBuffer.size());
+ char *z = Common::find(nameBuffer.begin(), nameBuffer.end(), 0);
+ Common::String name(nameBuffer.data(), z - nameBuffer.begin());
+ uint32 size = file.readUint32LE();
+ //debug("adb entry: %s, offset %08x, size: %u", name.c_str(), offset, size);
+ _entries.setVal(name, Entry(dataOffset + offset, size));
}
- Common::SeekableReadStream * Database::getEntry(const Common::String &name) const
- {
- EntriesType::const_iterator i = _entries.find(name);
- if (i == _entries.end())
- return NULL;
+ return true;
+}
+
+Common::SeekableReadStream *Database::getEntry(const Common::String &name) const {
+ EntriesType::const_iterator i = _entries.find(name);
+ if (i == _entries.end())
+ return NULL;
- Common::File file;
- if (!file.open(_filename)) {
- error("could not open database file %s", _filename.c_str()); //previously available, but now disappeared or no fd, error
- return NULL;
- }
- const Entry &entry = i->_value;
- file.seek(entry.offset);
- return file.readStream(entry.size);
+ Common::File file;
+ if (!file.open(_filename)) {
+ error("could not open database file %s", _filename.c_str()); //previously available, but now disappeared or no fd, error
+ return NULL;
}
+ const Entry &entry = i->_value;
+ file.seek(entry.offset);
+ return file.readStream(entry.size);
}
+} // namespace AGDS
diff --git a/engines/agds/detection.cpp b/engines/agds/detection.cpp
index eb214a87429..c67ea424de7 100644
--- a/engines/agds/detection.cpp
+++ b/engines/agds/detection.cpp
@@ -26,9 +26,8 @@
#include "engines/advancedDetector.h"
static const PlainGameDescriptor agdsGames[] = {
- { "black-mirror", "Black Mirror" },
- { 0, 0 }
-};
+ {"black-mirror", "Black Mirror"},
+ {0, 0}};
#include "agds/detection_tables.h"
@@ -50,24 +49,22 @@ public:
}
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
- virtual bool hasFeature(MetaEngineFeature f) const
- {
- switch(f) {
- case kSavesSupportThumbnail:
- case kSavesUseExtendedFormat:
- case kSimpleSavesNames:
- case kSupportsDeleteSave:
- case kSupportsListSaves:
- return true;
- default:
- return false;
+ virtual bool hasFeature(MetaEngineFeature f) const {
+ switch (f) {
+ case kSavesSupportThumbnail:
+ case kSavesUseExtendedFormat:
+ case kSimpleSavesNames:
+ case kSupportsDeleteSave:
+ case kSupportsListSaves:
+ return true;
+ default:
+ return false;
}
}
int getMaximumSaveSlot() const {
return 99;
}
-
};
bool AGDSMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
@@ -78,7 +75,7 @@ bool AGDSMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGame
}
#if PLUGIN_ENABLED_DYNAMIC(AGDS)
- REGISTER_PLUGIN_DYNAMIC(AGDS, PLUGIN_TYPE_ENGINE, AGDSMetaEngine);
+REGISTER_PLUGIN_DYNAMIC(AGDS, PLUGIN_TYPE_ENGINE, AGDSMetaEngine);
#else
- REGISTER_PLUGIN_STATIC(AGDS, PLUGIN_TYPE_ENGINE, AGDSMetaEngine);
+REGISTER_PLUGIN_STATIC(AGDS, PLUGIN_TYPE_ENGINE, AGDSMetaEngine);
#endif
diff --git a/engines/agds/font.cpp b/engines/agds/font.cpp
index c9354fd689c..01e7ea1053e 100644
--- a/engines/agds/font.cpp
+++ b/engines/agds/font.cpp
@@ -3,18 +3,17 @@
namespace AGDS {
-Font::Font(Graphics::TransparentSurface *surface, int gw, int gh):
- _surface(surface),
- _glyphW(gw), _glyphH(gh),
- _cellW(surface->w / 16), _cellH(surface->h / 16) {
+Font::Font(Graphics::TransparentSurface *surface, int gw, int gh) : _surface(surface),
+ _glyphW(gw), _glyphH(gh),
+ _cellW(surface->w / 16), _cellH(surface->h / 16) {
//debug("surface cell %dx%d", _cellW, _cellH);
- for(int y = 0; y < 16; ++y) {
- for(int x = 0; x < 16; ++x) {
+ for (int y = 0; y < 16; ++y) {
+ for (int x = 0; x < 16; ++x) {
const uint32 *pixels = static_cast<uint32 *>(_surface->getBasePtr(x * _cellW, y * _cellH));
int w;
int ch = (y << 4) | x;
- for(w = 0; w <= _glyphW; ++w, ++pixels) {
+ for (w = 0; w <= _glyphW; ++w, ++pixels) {
uint8 r, g, b, a;
//debug("%d color #%08x", ch, *pixels);
surface->format.colorToARGB(*pixels, r, g, b, a);
@@ -36,4 +35,4 @@ void Font::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 col
_surface->blit(*dst, x, y, Graphics::FLIP_NONE, &srcRect);
}
-}
+} // namespace AGDS
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 04ca042dbcf..02d72935924 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -27,19 +27,19 @@
namespace AGDS {
-Inventory::Inventory(): _entries(kMaxSize), _enabled(false) { }
-Inventory::~Inventory() { }
+Inventory::Inventory() : _entries(kMaxSize), _enabled(false) {}
+Inventory::~Inventory() {}
int Inventory::free() const {
int free = 0;
- for(uint i = 0; i < _entries.size(); ++i)
+ for (uint i = 0; i < _entries.size(); ++i)
if (!_entries[i])
++free;
return free;
}
int Inventory::add(ObjectPtr object) {
- for(uint i = 0; i < _entries.size(); ++i) {
+ for (uint i = 0; i < _entries.size(); ++i) {
if (!_entries[i]) {
_entries[i] = object;
return i;
@@ -49,17 +49,16 @@ int Inventory::add(ObjectPtr object) {
}
int Inventory::find(const Common::String &name) const {
- for(uint i = 0; i < _entries.size(); ++i)
+ for (uint i = 0; i < _entries.size(); ++i)
if (_entries[i] && _entries[i]->getName() == name)
return i;
return -1;
}
void Inventory::clear() {
- for(uint i = 0; i < _entries.size(); ++i) {
+ for (uint i = 0; i < _entries.size(); ++i) {
_entries[i].reset();
}
}
-
-}
+} // namespace AGDS
diff --git a/engines/agds/mjpgPlayer.cpp b/engines/agds/mjpgPlayer.cpp
index 2a696b92d5f..9105cbdd229 100644
--- a/engines/agds/mjpgPlayer.cpp
+++ b/engines/agds/mjpgPlayer.cpp
@@ -25,7 +25,7 @@
namespace AGDS {
-MJPGPlayer::MJPGPlayer(Common::SeekableReadStream * stream): _stream(stream), _firstFramePos(_stream->pos()) {
+MJPGPlayer::MJPGPlayer(Common::SeekableReadStream *stream) : _stream(stream), _firstFramePos(_stream->pos()) {
}
MJPGPlayer::~MJPGPlayer() {
@@ -52,5 +52,4 @@ const Graphics::Surface *MJPGPlayer::decodeFrame() {
return surface;
}
-
-}
+} // namespace AGDS
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 7ec81b17433..80cc43f15d9 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -21,8 +21,8 @@
*/
#include "agds/object.h"
-#include "agds/animation.h"
#include "agds/agds.h"
+#include "agds/animation.h"
#include "agds/font.h"
#include "agds/region.h"
#include "common/debug.h"
@@ -33,13 +33,12 @@
namespace AGDS {
-Object::Object(const Common::String &name, Common::SeekableReadStream * stream) :
- _name(name), _stringTableLoaded(false),
- _picture(), _region(),
- _animation(), _mouseCursor(),
- _pos(), _z(1000),
- _clickHandler(0), _examineHandler(0),
- _alpha(255), _active(false) {
+Object::Object(const Common::String &name, Common::SeekableReadStream *stream) : _name(name), _stringTableLoaded(false),
+ _picture(), _region(),
+ _animation(), _mouseCursor(),
+ _pos(), _z(1000),
+ _clickHandler(0), _examineHandler(0),
+ _alpha(255), _active(false) {
byte id = stream->readUint16LE();
debug("id: 0x%02x %u", id, id);
@@ -63,7 +62,6 @@ Object::~Object() {
}
}
-
void Object::readStringTable(unsigned resOffset, uint16 resCount) {
if (_stringTableLoaded)
return;
@@ -75,7 +73,7 @@ void Object::readStringTable(unsigned resOffset, uint16 resCount) {
//debug("resource table at %08x", resOffset);
Common::MemoryReadStream stream(_code.data() + resOffset, _code.size() - resOffset);
_stringTable.resize(resCount);
- for(uint16 i = 0; i < resCount; ++i) {
+ for (uint16 i = 0; i < resCount; ++i) {
uint16 offset = stream.readUint16LE();
uint16 flags = stream.readUint16LE();
@@ -83,9 +81,9 @@ void Object::readStringTable(unsigned resOffset, uint16 resCount) {
if (nameOffset > _code.size())
error("invalid resource name offset");
- const char * nameBegin = reinterpret_cast<const char *>(_code.data() + nameOffset);
- const char * codeEnd = reinterpret_cast<const char *>(_code.data() + _code.size());
- const char * nameEnd = Common::find(nameBegin, codeEnd, 0);
+ const char *nameBegin = reinterpret_cast<const char *>(_code.data() + nameOffset);
+ const char *codeEnd = reinterpret_cast<const char *>(_code.data() + _code.size());
+ const char *nameEnd = Common::find(nameBegin, codeEnd, 0);
Common::String name(nameBegin, nameEnd - nameBegin);
@@ -96,7 +94,7 @@ void Object::readStringTable(unsigned resOffset, uint16 resCount) {
_stringTableLoaded = true;
}
-const Object::StringEntry & Object::getString(uint16 index) const {
+const Object::StringEntry &Object::getString(uint16 index) const {
if (!_stringTableLoaded)
error("no string table loaded");
@@ -129,11 +127,10 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
_animation->paint(engine, backbuffer, _animationPos);
}
if (!_text.empty()) {
- Common::Point pos = _region? _region->center: _pos;
+ Common::Point pos = _region ? _region->center : _pos;
int w = backbuffer.w - pos.x;
engine.getFont(1)->drawString(&backbuffer, _text, pos.x, pos.y, w, 0);
}
}
-
-}
+} // namespace AGDS
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index a30a8364fac..6191069ae67 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -27,13 +27,12 @@
namespace AGDS {
-Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip, Process * caller) :
- _engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object), _ip(ip),
- _status(kStatusActive), _caller(caller), _exitCode(kExitCodeDestroy),
- _tileWidth(16), _tileHeight(16), _tileResource(0), _tileIndex(0),
- _timer(0),
- _animationCycles(1), _animationLoop(false), _animationZ(0), _animationPaused(false), _animationSpeed(100),
- _waitForCall(false) {
+Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip, Process *caller) : _engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object), _ip(ip),
+ _status(kStatusActive), _caller(caller), _exitCode(kExitCodeDestroy),
+ _tileWidth(16), _tileHeight(16), _tileResource(0), _tileIndex(0),
+ _timer(0),
+ _animationCycles(1), _animationLoop(false), _animationZ(0), _animationPaused(false), _animationSpeed(100),
+ _waitForCall(false) {
}
void Process::debug(const char *str, ...) {
@@ -104,16 +103,15 @@ Common::String Process::popText() {
void Process::activate(bool active) {
if (active) {
_object->activate(active);
- switch(_status)
- {
- case kStatusActive:
- break;
- case kStatusPassive:
- _status = kStatusActive;
- break;
- default:
- error("process in invalid state %d", _status);
- _status = kStatusError;
+ switch (_status) {
+ case kStatusActive:
+ break;
+ case kStatusPassive:
+ _status = kStatusActive;
+ break;
+ default:
+ error("process in invalid state %d", _status);
+ _status = kStatusError;
}
} else {
if (_caller) {
@@ -125,4 +123,4 @@ void Process::activate(bool active) {
}
}
-}
+} // namespace AGDS
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c9d4811b081..b216e57a9fe 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -20,30 +20,31 @@
*
*/
-#include "agds/process.h"
#include "agds/agds.h"
#include "agds/animation.h"
#include "agds/character.h"
#include "agds/opcode.h"
+#include "agds/process.h"
#include "agds/region.h"
#include "agds/screen.h"
#include "agds/systemVariable.h"
-#include "graphics/transparent_surface.h"
#include "common/debug.h"
+#include "graphics/transparent_surface.h"
namespace AGDS {
void Process::enter(uint16 magic, uint16 size) {
if (magic != 0xdead || size != 0x0c)
error("invalid enter() magic: 0x%04x or size: %u", magic, size);
- uint16 unk1 = next16();
- uint16 unk2 = next16();
- uint16 unk3 = next16();
- unsigned resOffset = next16();
- uint16 resCount = next16();
- uint16 unk4 = next16();
+ uint16 unk1 = next16();
+ uint16 unk2 = next16();
+ uint16 unk3 = next16();
+ unsigned resOffset = next16();
+ uint16 resCount = next16();
+ uint16 unk4 = next16();
debug("resource block %04x %04x %04x %04x,"
- " resources table with %u entries", unk1, unk2, unk3, unk4, resCount);
+ " resources table with %u entries",
+ unk1, unk2, unk3, unk4, resCount);
_object->readStringTable(resOffset, resCount);
}
@@ -96,7 +97,7 @@ void Process::getObjectId() {
const Common::String &name = _object->getName();
//no rfind :(((
Common::String::const_iterator dotpos = 0;
- for(Common::String::const_iterator i = name.begin(); i != name.end(); ++i)
+ for (Common::String::const_iterator i = name.begin(); i != name.end(); ++i)
if (*i == '.')
dotpos = i + 1;
Common::String id(dotpos, name.end());
@@ -180,10 +181,10 @@ void Process::updatePhaseVarOr4() {
void Process::loadScreenObject() {
Common::String name = popString();
debug("loadScreenObject: %s", name.c_str());
- Screen * screen = _engine->getCurrentScreen();
+ Screen *screen = _engine->getCurrentScreen();
if (!screen->find(name)) {
screen->add(_engine->loadObject(name));
- } else{
+ } else {
warning("loadScreenObject: object %s already loaded", name.c_str());
}
suspend(kExitCodeLoadScreenObject, name);
@@ -229,7 +230,7 @@ void Process::loadMouse() {
void Process::getRandomNumber() {
int max = pop();
- int value = max > 0? _engine->_random.getRandomNumber(max - 1): 0;
+ int value = max > 0 ? _engine->_random.getRandomNumber(max - 1) : 0;
debug("random %d -> %d", max, value);
push(value);
}
@@ -249,7 +250,7 @@ void Process::setPhaseVar() {
}
void Process::getGlobal(unsigned index) {
- const Common::String & name = _object->getString(index).string;
+ const Common::String &name = _object->getString(index).string;
int value = _engine->getGlobal(name);
debug("get global %u %s -> %d", index, name.c_str(), value);
push(value);
@@ -257,7 +258,7 @@ void Process::getGlobal(unsigned index) {
void Process::hasGlobal() {
Common::String name = popString();
- int result = _engine->hasGlobal(name)? 1: 0;
+ int result = _engine->hasGlobal(name) ? 1 : 0;
debug("hasGlobal %s %d", name.c_str(), result);
push(result);
}
@@ -369,23 +370,23 @@ void Process::appendNameToSharedStorage() {
push(index);
}
-Common::String Process::getCloneVarName(const Common::String & arg1, const Common::String & arg2) {
+Common::String Process::getCloneVarName(const Common::String &arg1, const Common::String &arg2) {
bool isNumeric = false;
size_t prefixLength;
{
const char *begin = arg1.c_str();
const char *ptr = begin + arg1.size() - 1;
- while(*ptr >= '0' && *ptr <= '9' && ptr > begin)
+ while (*ptr >= '0' && *ptr <= '9' && ptr > begin)
--ptr;
isNumeric = *ptr == '.';
- prefixLength = isNumeric? ptr - begin: 0;
+ prefixLength = isNumeric ? ptr - begin : 0;
}
Common::String name;
if (isNumeric) {
//no substr :(((
name = Common::String(arg1.c_str(), arg1.c_str() + prefixLength) +
- "." + arg2 + Common::String(arg1.c_str() + prefixLength);
+ "." + arg2 + Common::String(arg1.c_str() + prefixLength);
} else {
name = arg1 + "." + arg2;
}
@@ -436,9 +437,9 @@ void Process::changeScreenPatch() {
Common::String screenName = popString();
Common::String inventoryScr = _engine->getSystemVariable("inventory_scr")->getString();
debug("changeScreenPatch: screen: %s, object: %s, inventory: %s",
- screenName.empty()? "none": screenName.c_str(), objectName.c_str(), inventoryScr.empty()? "none": inventoryScr.c_str());
+ screenName.empty() ? "none" : screenName.c_str(), objectName.c_str(), inventoryScr.empty() ? "none" : inventoryScr.c_str());
- Screen * screen = _engine->getCurrentScreen();
+ Screen *screen = _engine->getCurrentScreen();
if (!screen) {
error("no current screen");
return;
@@ -703,13 +704,12 @@ void Process::stub217() {
void Process::playAnimationWithPhaseVar() {
Common::String phaseVar = popString();
debug("playAnimationWithPhaseVar %s", phaseVar.c_str());
- Animation * animation = _engine->findAnimationByPhaseVar(phaseVar);
+ Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
if (animation) {
animation->phaseVar(phaseVar);
animation->play();
_engine->setGlobal(phaseVar, 0);
- }
- else
+ } else
warning("no animation with phase var %s found", phaseVar.c_str());
}
@@ -762,7 +762,7 @@ void Process::setObjectTile() {
warning("invalid tile size");
return;
}
- Graphics::TransparentSurface * surface = _engine->loadFromCache(_tileResource);
+ Graphics::TransparentSurface *surface = _engine->loadFromCache(_tileResource);
if (!surface) {
warning("picture %d was not loaded", _tileResource);
return;
@@ -773,7 +773,7 @@ void Process::setObjectTile() {
int x = _tileIndex % tw;
debug("tile coordinate %dx%d", x, y);
- Graphics::TransparentSurface * tile = new Graphics::TransparentSurface();
+ Graphics::TransparentSurface *tile = new Graphics::TransparentSurface();
tile->create(_tileWidth, _tileHeight, surface->format);
tile->applyColorKey(0xff, 0, 0xff);
Common::Rect srcRect(_tileWidth, _tileHeight);
@@ -794,7 +794,6 @@ void Process::setObjectText() {
warning("setObjectText: object %s not found", name.c_str());
}
-
void Process::exitProcess() {
debug("exitProcess");
_status = kStatusDone;
@@ -802,12 +801,12 @@ void Process::exitProcess() {
}
void Process::exitProcessCreatePatch() {
- SystemVariable * initVar = _engine->getSystemVariable("init_resources");
+ SystemVariable *initVar = _engine->getSystemVariable("init_resources");
if (!initVar)
error("no init_resources declared");
Common::String init = initVar->getString();
- SystemVariable * doneVar = _engine->getSystemVariable("done_resources");
+ SystemVariable *doneVar = _engine->getSystemVariable("done_resources");
if (!doneVar)
error("no done_resources declared");
Common::String done = doneVar->getString();
@@ -872,14 +871,13 @@ void Process::runDialog() {
suspend(kExitCodeRunDialog, arg1);
}
-
void Process::getObjectPictureWidth() {
Common::String name = popString();
debug("getObjectPictureWidth %s", name.c_str());
ObjectPtr object = _engine->getCurrentScreenObject(name);
if (object) {
const Graphics::Surface *picture = object->getPicture();
- int value = picture? picture->w: 0;
+ int value = picture ? picture->w : 0;
debug("\t->%d", value);
push(value);
} else {
@@ -894,7 +892,7 @@ void Process::getObjectPictureHeight() {
ObjectPtr object = _engine->getCurrentScreenObject(name);
if (object) {
const Graphics::Surface *picture = object->getPicture();
- int value = picture? picture->h: 0;
+ int value = picture ? picture->h : 0;
debug("\t->%d", value);
push(value);
} else {
@@ -957,7 +955,7 @@ void Process::appendInventoryObjectNameToSharedSpace() {
int index = pop();
debug("appendInventoryObjectNameToSharedSpace %d", index);
ObjectPtr object = _engine->inventory().get(index);
- push(_engine->appendToSharedStorage(object? object->getName(): Common::String()));
+ push(_engine->appendToSharedStorage(object ? object->getName() : Common::String()));
}
void Process::setNextScreen() {
@@ -1140,7 +1138,7 @@ void Process::getCharacterAnimationPhase() {
Common::String name = popString();
debug("getCharacterAnimationPhase: %s", name.c_str());
Character *character = _engine->getCharacter(name);
- int phase = character? character->getPhase(): -1;
+ int phase = character ? character->getPhase() : -1;
debug("animation phase = %d", phase);
push(phase);
}
@@ -1149,7 +1147,7 @@ void Process::stopCharacter() {
int arg = pop();
Common::String name = popString();
debug("stopCharacter: stub %s %d", name.c_str(), arg);
- Character * character = _engine->getCharacter(name);
+ Character *character = _engine->getCharacter(name);
if (character)
character->stop();
else
@@ -1173,7 +1171,6 @@ void Process::loadRegionFromObject() {
_object->region(region);
}
-
void Process::loadPictureFromObject() {
Common::String name = popText();
debug("loadPictureFromObject %s", name.c_str());
@@ -1186,7 +1183,7 @@ void Process::loadAnimationFromObject() {
if (!_phaseVar.empty()) {
_engine->setGlobal(_phaseVar, -2);
}
- Animation * animation = _engine->loadAnimation(name);
+ Animation *animation = _engine->loadAnimation(name);
if (animation) {
animation->phaseVar(_phaseVar);
animation->loop(_animationLoop);
@@ -1245,31 +1242,54 @@ void Process::stub244() {
_engine->getSystemVariable("dialog_var")->setInteger(1);
}
-
//fixme: add trace here
#define OP(NAME, METHOD) \
- case NAME: METHOD (); break
+ case NAME: \
+ METHOD(); \
+ break
#define OP_I(NAME, METHOD, IMM) \
- case NAME: { METHOD (IMM); } break
+ case NAME: { \
+ METHOD(IMM); \
+ } break
#define OP_C(NAME, METHOD) \
- case NAME: { int8 arg = next(); METHOD (arg); } break
-
-#define OP_B(NAME, METHOD) \
- case NAME: { uint8 arg = next(); METHOD (arg); } break
-
-#define OP_W(NAME, METHOD) \
- case NAME: { int16 arg = next16(); METHOD (arg); } break
-
-#define OP_U(NAME, METHOD) \
- case NAME: { uint16 arg = next16(); METHOD (arg); } break
-
-#define OP_UU(NAME, METHOD) \
- case NAME: { uint16 arg1 = next16(); uint16 arg2 = next16(); METHOD (arg1, arg2); } break
-
-#define OP_D(NAME, METHOD) \
- case NAME: { uint16 arg1 = next16(); uint32 arg2 = next16(); METHOD (arg1 | (arg2 << 16)); } break
+ case NAME: { \
+ int8 arg = next(); \
+ METHOD(arg); \
+ } break
+
+#define OP_B(NAME, METHOD) \
+ case NAME: { \
+ uint8 arg = next(); \
+ METHOD(arg); \
+ } break
+
+#define OP_W(NAME, METHOD) \
+ case NAME: { \
+ int16 arg = next16(); \
+ METHOD(arg); \
+ } break
+
+#define OP_U(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg = next16(); \
+ METHOD(arg); \
+ } break
+
+#define OP_UU(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg1 = next16(); \
+ uint16 arg2 = next16(); \
+ METHOD(arg1, arg2); \
+ } break
+
+#define OP_D(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg1 = next16(); \
+ uint32 arg2 = next16(); \
+ METHOD(arg1 | (arg2 << 16)); \
+ } break
ProcessExitCode Process::execute() {
if (_waitForCall) {
@@ -1279,187 +1299,187 @@ ProcessExitCode Process::execute() {
_exitCode = kExitCodeDestroy;
const Object::CodeType &code = _object->getCode();
- while(_status == kStatusActive && _ip < code.size()) {
+ while (_status == kStatusActive && _ip < code.size()) {
_lastIp = _ip;
uint8 op = next();
- switch(op) {
- OP_UU (kEnter, enter);
- OP_W (kJumpZImm16, jumpz);
- OP_W (kJumpImm16, jump);
- OP (kPop, pop);
- OP (kDup, dup);
- OP (kExitProcess, exitProcess);
- OP (kSuspendProcess, suspend);
- OP_D (kPushImm32, push);
- OP_C (kPushImm8, push);
- OP_W (kPushImm16, push);
- OP_C (kPushImm8_2, push);
- OP_W (kPushImm16_2, push);
- OP_B (kGetGlobalImm8, getGlobal);
- OP (kPostIncrementGlobal, postIncrementGlobal);
- OP (kPostDecrementGlobal, postDecrementGlobal);
- OP (kIncrementGlobalByTop, incrementGlobalByTop);
- OP (kDecrementGlobalByTop, decrementGlobalByTop);
- OP (kMultiplyGlobalByTop, multiplyGlobalByTop);
- OP (kDivideGlobalByTop, divideGlobalByTop);
- OP (kModGlobalByTop, modGlobalByTop);
- OP (kShlGlobalByTop, shlGlobalByTop);
- OP (kShrGlobalByTop, shrGlobalByTop);
- OP (kAndGlobalByTop, andGlobalByTop);
- OP (kOrGlobalByTop, orGlobalByTop);
- OP (kXorGlobalByTop, xorGlobalByTop);
- OP (kEquals, equals);
- OP (kNotEquals, notEquals);
- OP (kGreater, greater);
- OP (kLess, less);
- OP (kGreaterOrEquals, greaterOrEquals);
- OP (kLessOrEquals, lessOrEquals);
- OP (kAdd, add);
- OP (kSub, sub);
- OP (kMul, mul);
- OP (kDiv, div);
- OP (kSetGlobal, setGlobal);
- OP (kBoolOr, boolOr);
- OP (kBoolAnd, boolAnd);
- OP (kAnd, bitAnd);
- OP (kOr, bitOr);
- OP (kXor, bitXor);
- OP (kNot, bitNot);
- OP (kBoolNot, boolNot);
- OP (kNegate, negate);
- OP_U (kCallImm16, call);
- OP_U (kObjectRegisterLookHandler, onLook);
- OP_U (kObjectRegisterUseHandler, onUse);
- OP_U (kObjectRegisterHandlerC1, onObjectC1);
- OP_U (kScreenRegisterHandlerBD, onScreenBD);
- OP (kLoadMouseCursorFromObject, loadMouseCursorFromObject);
- OP (kLoadRegionFromObject, loadRegionFromObject);
- OP (kLoadPictureFromObject, loadPictureFromObject);
- OP (kLoadAnimationFromObject, loadAnimationFromObject);
- OP (kShowCharacter, showCharacter);
- OP (kEnableCharacter, enableCharacter);
- OP_I (kMoveCharacterUserMove, moveCharacter, true);
- OP (kLeaveCharacter, leaveCharacter);
- OP (kSetCharacter, setCharacter);
- OP (kPointCharacter, pointCharacter);
- OP (kDisableUser, disableUser);
- OP (kEnableUser, enableUser);
- OP (kUpdatePhaseVarOr2, updatePhaseVarOr2);
- OP (kUpdatePhaseVarOr4, updatePhaseVarOr4);
- OP (kStub102, stub102);
- OP (kClearScreen, clearScreen);
- OP (kInventoryClear, inventoryClear);
- OP (kLoadMouse, loadMouse);
- OP (kInventoryAddObject, inventoryAddObject);
- OP (kSetNextScreenSaveInHistory, setNextScreenSaveInHistory);
- OP_U (kObjectRegisterUseObjectHandler, onObjectUse);
- OP (kStub82, stub82);
- OP (kStub83, stub83);
- OP (kAnimateCharacter, animateCharacter);
- OP (kLoadCharacter, loadCharacter);
- OP (kSetObjectZ, setObjectZ);
- OP (kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay);
- OP (kLoadTextFromObject, loadTextFromObject);
- OP (kScreenSetHeight, setScreenHeight);
- OP (kScreenLoadObject, loadScreenObject);
- OP (kScreenLoadRegion, loadScreenRegion);
- OP (kScreenCloneObject, cloneObject);
- OP (kSetNextScreen, setNextScreen);
- OP (kScreenRemoveObject, removeScreenObject);
- OP (kLoadAnimation, loadAnimation);
- OP (kLoadSample, loadSample);
- OP (kSetAnimationPaused, setAnimationPaused);
- OP (kPlayerSay, playerSay);
- OP (kNPCSay, npcSay);
- OP (kSetTimer, setTimer);
- OP (kProcessResetState, resetState);
- OP (kSetAnimationZ, setAnimationZ);
- OP (kSetCycles, setCycles);
- OP (kSetRandom, setRandom);
- OP (kStub133, stub133);
- OP (kSetAnimationPosition, setAnimationPosition);
- OP (kSetPhaseVar, setPhaseVar);
- OP (kSetAnimationLoop, setAnimationLoop);
- OP (kSetAnimationSpeed, setAnimationSpeed);
- OP (kStub138, stub138);
- OP (kScreenChangeScreenPatch, changeScreenPatch);
- OP (kGetFreeInventorySpace, getInventoryFreeSpace);
- OP (kSetStringSystemVariable, setStringSystemVariable);
- OP (kSetSystemIntegerVariable, setIntegerSystemVariable);
- OP (kGetRegionCenterX, getRegionCenterX);
- OP (kGetRegionCenterY, getRegionCenterY);
- OP (kGetCharacterAnimationPhase, getCharacterAnimationPhase);
- OP (kGetIntegerSystemVariable, getIntegerSystemVariable);
- OP (kGetRandomNumber, getRandomNumber);
- OP (kAppendToSharedStorage, appendToSharedStorage);
- OP (kAppendNameToSharedStorage, appendNameToSharedStorage);
- OP (kCloneName, cloneName);
- OP (kGetCloneVar, getCloneVar);
- OP (kSetCloneVar, setCloneVar);
- OP (kStub152, stub152);
- OP (kStub153, stub153);
- OP (kStub154, stub154);
- OP (kStub155, stub155);
- OP (kStub160, stub160);
- OP (kStub166, stub166);
- OP (kSetDelay, setDelay);
- OP (kStub172, stub172);
- OP (kStub173, stub173);
- OP (kStub174, stub174);
- OP (kStub192, stub192);
- OP (kQuit, quit);
- OP (kExitProcessCreatePatch, exitProcessCreatePatch);
- OP (kDisableInventory, disableInventory);
- OP (kEnableInventory, enableInventory);
- OP (kLoadPreviousScreen, loadPreviousScreen);
- OP (kMoveScreenObject, moveScreenObject);
- OP (kGetObjectId, getObjectId);
- OP (kSetTileSize, setTileSize);
- OP (kGenerateRegion, generateRegion);
- OP (kGetMaxInventorySize, getMaxInventorySize);
- OP (kAppendInventoryObjectNameToSharedSpace, appendInventoryObjectNameToSharedSpace);
- OP (kSetObjectTile, setObjectTile);
- OP (kInventoryHasObject, inventoryHasObject);
- OP (kSetObjectText, setObjectText);
- OP (kSetObjectScale, setObjectScale);
- OP (kStub191, disableMouseAreas);
- OP (kStub193, stub193);
- OP (kStub194, stub194);
- OP (kGetObjectPictureWidth, getObjectPictureWidth);
- OP (kGetObjectPictureHeight, getObjectPictureHeight);
- OP (kLoadPicture, loadPicture);
- OP (kStub199, stub199);
- OP (kSetSampleVolumeAndPan, setSampleVolumeAndPan);
- OP (kPlaySound, playSound);
- OP (kStub215, stub215);
- OP (kStub216, stub216);
- OP (kStub217, stub217);
- OP (kStopCharacter, stopCharacter);
- OP (kPlayAnimationWithPhaseVar, playAnimationWithPhaseVar);
- OP (kStub223, stub223);
- OP (kStub225, stub225);
- OP (kFadeObject, fadeObject);
- OP (kLoadFont, loadFont);
- OP_U (kStub201Handler, stub201);
- OP_U (kStub202ScreenHandler, stub202);
- OP (kPlayFilm, playFilm);
- OP (kAddMouseArea, addMouseArea);
- OP (kFogOnCharacter, fogOnCharacter);
- OP (kSetTileIndex, setTileIndex);
- OP (kModifyMouseArea, modifyMouseArea);
- OP_U (kStub209, stub209);
- OP_I (kMoveCharacterNoUserMove, moveCharacter, false);
- OP_U (kOnKey, onKey);
- OP (kGetSampleVolume, getSampleVolume);
- OP (kStub231, stub231);
- OP (kStub233, stub233);
- OP (kStub235, stub235);
- OP (kUserEnabled, userEnabled);
- OP (kStub244, stub244);
- OP (kInventoryFindObjectByName, inventoryFindObjectByName);
- OP (kRunDialog, runDialog);
- OP (kHasGlobal, hasGlobal);
- OP (kSetDialogForNextFilm, setDialogForNextFilm);
+ switch (op) {
+ OP_UU(kEnter, enter);
+ OP_W(kJumpZImm16, jumpz);
+ OP_W(kJumpImm16, jump);
+ OP(kPop, pop);
+ OP(kDup, dup);
+ OP(kExitProcess, exitProcess);
+ OP(kSuspendProcess, suspend);
+ OP_D(kPushImm32, push);
+ OP_C(kPushImm8, push);
+ OP_W(kPushImm16, push);
+ OP_C(kPushImm8_2, push);
+ OP_W(kPushImm16_2, push);
+ OP_B(kGetGlobalImm8, getGlobal);
+ OP(kPostIncrementGlobal, postIncrementGlobal);
+ OP(kPostDecrementGlobal, postDecrementGlobal);
+ OP(kIncrementGlobalByTop, incrementGlobalByTop);
+ OP(kDecrementGlobalByTop, decrementGlobalByTop);
+ OP(kMultiplyGlobalByTop, multiplyGlobalByTop);
+ OP(kDivideGlobalByTop, divideGlobalByTop);
+ OP(kModGlobalByTop, modGlobalByTop);
+ OP(kShlGlobalByTop, shlGlobalByTop);
+ OP(kShrGlobalByTop, shrGlobalByTop);
+ OP(kAndGlobalByTop, andGlobalByTop);
+ OP(kOrGlobalByTop, orGlobalByTop);
+ OP(kXorGlobalByTop, xorGlobalByTop);
+ OP(kEquals, equals);
+ OP(kNotEquals, notEquals);
+ OP(kGreater, greater);
+ OP(kLess, less);
+ OP(kGreaterOrEquals, greaterOrEquals);
+ OP(kLessOrEquals, lessOrEquals);
+ OP(kAdd, add);
+ OP(kSub, sub);
+ OP(kMul, mul);
+ OP(kDiv, div);
+ OP(kSetGlobal, setGlobal);
+ OP(kBoolOr, boolOr);
+ OP(kBoolAnd, boolAnd);
+ OP(kAnd, bitAnd);
+ OP(kOr, bitOr);
+ OP(kXor, bitXor);
+ OP(kNot, bitNot);
+ OP(kBoolNot, boolNot);
+ OP(kNegate, negate);
+ OP_U(kCallImm16, call);
+ OP_U(kObjectRegisterLookHandler, onLook);
+ OP_U(kObjectRegisterUseHandler, onUse);
+ OP_U(kObjectRegisterHandlerC1, onObjectC1);
+ OP_U(kScreenRegisterHandlerBD, onScreenBD);
+ OP(kLoadMouseCursorFromObject, loadMouseCursorFromObject);
+ OP(kLoadRegionFromObject, loadRegionFromObject);
+ OP(kLoadPictureFromObject, loadPictureFromObject);
+ OP(kLoadAnimationFromObject, loadAnimationFromObject);
+ OP(kShowCharacter, showCharacter);
+ OP(kEnableCharacter, enableCharacter);
+ OP_I(kMoveCharacterUserMove, moveCharacter, true);
+ OP(kLeaveCharacter, leaveCharacter);
+ OP(kSetCharacter, setCharacter);
+ OP(kPointCharacter, pointCharacter);
+ OP(kDisableUser, disableUser);
+ OP(kEnableUser, enableUser);
+ OP(kUpdatePhaseVarOr2, updatePhaseVarOr2);
+ OP(kUpdatePhaseVarOr4, updatePhaseVarOr4);
+ OP(kStub102, stub102);
+ OP(kClearScreen, clearScreen);
+ OP(kInventoryClear, inventoryClear);
+ OP(kLoadMouse, loadMouse);
+ OP(kInventoryAddObject, inventoryAddObject);
+ OP(kSetNextScreenSaveInHistory, setNextScreenSaveInHistory);
+ OP_U(kObjectRegisterUseObjectHandler, onObjectUse);
+ OP(kStub82, stub82);
+ OP(kStub83, stub83);
+ OP(kAnimateCharacter, animateCharacter);
+ OP(kLoadCharacter, loadCharacter);
+ OP(kSetObjectZ, setObjectZ);
+ OP(kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay);
+ OP(kLoadTextFromObject, loadTextFromObject);
+ OP(kScreenSetHeight, setScreenHeight);
+ OP(kScreenLoadObject, loadScreenObject);
+ OP(kScreenLoadRegion, loadScreenRegion);
+ OP(kScreenCloneObject, cloneObject);
+ OP(kSetNextScreen, setNextScreen);
+ OP(kScreenRemoveObject, removeScreenObject);
+ OP(kLoadAnimation, loadAnimation);
+ OP(kLoadSample, loadSample);
+ OP(kSetAnimationPaused, setAnimationPaused);
+ OP(kPlayerSay, playerSay);
+ OP(kNPCSay, npcSay);
+ OP(kSetTimer, setTimer);
+ OP(kProcessResetState, resetState);
+ OP(kSetAnimationZ, setAnimationZ);
+ OP(kSetCycles, setCycles);
+ OP(kSetRandom, setRandom);
+ OP(kStub133, stub133);
+ OP(kSetAnimationPosition, setAnimationPosition);
+ OP(kSetPhaseVar, setPhaseVar);
+ OP(kSetAnimationLoop, setAnimationLoop);
+ OP(kSetAnimationSpeed, setAnimationSpeed);
+ OP(kStub138, stub138);
+ OP(kScreenChangeScreenPatch, changeScreenPatch);
+ OP(kGetFreeInventorySpace, getInventoryFreeSpace);
+ OP(kSetStringSystemVariable, setStringSystemVariable);
+ OP(kSetSystemIntegerVariable, setIntegerSystemVariable);
+ OP(kGetRegionCenterX, getRegionCenterX);
+ OP(kGetRegionCenterY, getRegionCenterY);
+ OP(kGetCharacterAnimationPhase, getCharacterAnimationPhase);
+ OP(kGetIntegerSystemVariable, getIntegerSystemVariable);
+ OP(kGetRandomNumber, getRandomNumber);
+ OP(kAppendToSharedStorage, appendToSharedStorage);
+ OP(kAppendNameToSharedStorage, appendNameToSharedStorage);
+ OP(kCloneName, cloneName);
+ OP(kGetCloneVar, getCloneVar);
+ OP(kSetCloneVar, setCloneVar);
+ OP(kStub152, stub152);
+ OP(kStub153, stub153);
+ OP(kStub154, stub154);
+ OP(kStub155, stub155);
+ OP(kStub160, stub160);
+ OP(kStub166, stub166);
+ OP(kSetDelay, setDelay);
+ OP(kStub172, stub172);
+ OP(kStub173, stub173);
+ OP(kStub174, stub174);
+ OP(kStub192, stub192);
+ OP(kQuit, quit);
+ OP(kExitProcessCreatePatch, exitProcessCreatePatch);
+ OP(kDisableInventory, disableInventory);
+ OP(kEnableInventory, enableInventory);
+ OP(kLoadPreviousScreen, loadPreviousScreen);
+ OP(kMoveScreenObject, moveScreenObject);
+ OP(kGetObjectId, getObjectId);
+ OP(kSetTileSize, setTileSize);
+ OP(kGenerateRegion, generateRegion);
+ OP(kGetMaxInventorySize, getMaxInventorySize);
+ OP(kAppendInventoryObjectNameToSharedSpace, appendInventoryObjectNameToSharedSpace);
+ OP(kSetObjectTile, setObjectTile);
+ OP(kInventoryHasObject, inventoryHasObject);
+ OP(kSetObjectText, setObjectText);
+ OP(kSetObjectScale, setObjectScale);
+ OP(kStub191, disableMouseAreas);
+ OP(kStub193, stub193);
+ OP(kStub194, stub194);
+ OP(kGetObjectPictureWidth, getObjectPictureWidth);
+ OP(kGetObjectPictureHeight, getObjectPictureHeight);
+ OP(kLoadPicture, loadPicture);
+ OP(kStub199, stub199);
+ OP(kSetSampleVolumeAndPan, setSampleVolumeAndPan);
+ OP(kPlaySound, playSound);
+ OP(kStub215, stub215);
+ OP(kStub216, stub216);
+ OP(kStub217, stub217);
+ OP(kStopCharacter, stopCharacter);
+ OP(kPlayAnimationWithPhaseVar, playAnimationWithPhaseVar);
+ OP(kStub223, stub223);
+ OP(kStub225, stub225);
+ OP(kFadeObject, fadeObject);
+ OP(kLoadFont, loadFont);
+ OP_U(kStub201Handler, stub201);
+ OP_U(kStub202ScreenHandler, stub202);
+ OP(kPlayFilm, playFilm);
+ OP(kAddMouseArea, addMouseArea);
+ OP(kFogOnCharacter, fogOnCharacter);
+ OP(kSetTileIndex, setTileIndex);
+ OP(kModifyMouseArea, modifyMouseArea);
+ OP_U(kStub209, stub209);
+ OP_I(kMoveCharacterNoUserMove, moveCharacter, false);
+ OP_U(kOnKey, onKey);
+ OP(kGetSampleVolume, getSampleVolume);
+ OP(kStub231, stub231);
+ OP(kStub233, stub233);
+ OP(kStub235, stub235);
+ OP(kUserEnabled, userEnabled);
+ OP(kStub244, stub244);
+ OP(kInventoryFindObjectByName, inventoryFindObjectByName);
+ OP(kRunDialog, runDialog);
+ OP(kHasGlobal, hasGlobal);
+ OP(kSetDialogForNextFilm, setDialogForNextFilm);
default:
error("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _ip - 1, (unsigned)op, (unsigned)op);
_status = kStatusError;
@@ -1474,4 +1494,4 @@ ProcessExitCode Process::execute() {
return _exitCode;
}
-}
+} // namespace AGDS
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index 13fc10a3a0e..ce7bc35ba88 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -21,14 +21,14 @@
*/
#include "agds/region.h"
-#include "common/debug.h"
-#include "common/textconsole.h"
#include "common/algorithm.h"
+#include "common/debug.h"
#include "common/endian.h"
+#include "common/textconsole.h"
namespace AGDS {
-Region::Region(const Common::String &resourceName, Common::SeekableReadStream * stream) {
+Region::Region(const Common::String &resourceName, Common::SeekableReadStream *stream) {
static const int kRegionHeaderSize = 0x26;
static const int kRegionHeaderWidthOffset = 0x20;
static const int kRegionHeaderHeightOffset = 0x22;
@@ -39,16 +39,16 @@ Region::Region(const Common::String &resourceName, Common::SeekableReadStream *
byte header[kRegionHeaderSize];
if (stream->read(header, kRegionHeaderSize) != kRegionHeaderSize)
error("invalid region %s", resourceName.c_str());
- byte * nameEnd = Common::find(header, header + 0x20, 0);
- name = Common::String(reinterpret_cast<char *>(header), nameEnd - header);
- center.x = READ_UINT16(header + kRegionHeaderWidthOffset);
- center.y = READ_UINT16(header + kRegionHeaderHeightOffset);
- flags = READ_UINT16(header + kRegionHeaderFlagsOffset);
+ byte *nameEnd = Common::find(header, header + 0x20, 0);
+ name = Common::String(reinterpret_cast<char *>(header), nameEnd - header);
+ center.x = READ_UINT16(header + kRegionHeaderWidthOffset);
+ center.y = READ_UINT16(header + kRegionHeaderHeightOffset);
+ flags = READ_UINT16(header + kRegionHeaderFlagsOffset);
debug("region %s at (%d,%d) %04x", name.c_str(), center.x, center.y, flags);
if (size > kRegionHeaderSize) {
- uint16 ext = stream->readUint16LE();
+ uint16 ext = stream->readUint16LE();
//debug("extended entries %u", ext);
- while(ext--) {
+ while (ext--) {
int16 a = stream->readSint16LE();
int16 b = stream->readSint16LE();
int16 c = stream->readUint16LE();
@@ -63,7 +63,7 @@ Region::Region(const Common::String &resourceName, Common::SeekableReadStream *
}
}
-Region::Region(const Common::Rect rect): flags(0) {
+Region::Region(const Common::Rect rect) : flags(0) {
points.push_back(Common::Point(rect.left, rect.top));
points.push_back(Common::Point(rect.right, rect.top));
points.push_back(Common::Point(rect.right, rect.bottom));
@@ -74,7 +74,7 @@ Region::Region(const Common::Rect rect): flags(0) {
Common::String Region::toString() const {
Common::String str = Common::String::format("region(%d, %d, [", center.x, center.y);
- for(size_t i = 0; i < points.size(); ++i) {
+ for (size_t i = 0; i < points.size(); ++i) {
if (i != 0)
str += ", ";
str += Common::String::format("(%d, %d)", points[i].x, points[i].y);
@@ -88,11 +88,10 @@ void Region::move(Common::Point rel) {
return;
center += rel;
- for(uint i = 0; i < points.size(); ++i)
+ for (uint i = 0; i < points.size(); ++i)
points[i] += rel;
}
-
//FIXME: copied from wintermute/base_region.cpp
typedef struct {
@@ -141,4 +140,4 @@ bool Region::pointIn(Common::Point point) const {
}
}
-}
+} // namespace AGDS
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 40231012464..0e1aed0a479 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -21,213 +21,208 @@
*/
#include "agds/resourceManager.h"
+#include "common/algorithm.h"
#include "common/debug.h"
#include "common/file.h"
#include "common/memstream.h"
-#include "common/algorithm.h"
#include "common/ptr.h"
+#include "graphics/surface.h"
#include "image/bmp.h"
#include "image/pcx.h"
-#include "graphics/surface.h"
#include "video/flic_decoder.h"
namespace AGDS {
- ResourceManager::ResourceManager()
- { }
-
- ResourceManager::~ResourceManager()
- { }
-
- void ResourceManager::decrypt(uint8 * data, unsigned size) {
- static const char * kKey = "Vyvojovy tym AGDS varuje: Hackerovani skodi obchodu!";
- const char *ptr = kKey;
- while(size--) {
- *data++ ^= 0xff ^ *ptr++;
- if (*ptr == 0)
- ptr = kKey;
- }
- }
-
- bool ResourceManager::GrpFile::load(const Common::String &grpFilename) {
- static const char * kSignature = "AGDS group file\x1a";
- static const uint32 kMagic = 0x1a03c9e6;
- static const uint32 kVersion1 = 44;
- static const uint32 kVersion2 = 2;
-
- debug("adding path %s", grpFilename.c_str());
- if (!_file.open(grpFilename)) {
- warning("failing opening grp file %s", grpFilename.c_str());
- return false;
- }
- uint8 header[0x2c];
- if (_file.read(header, sizeof(header)) != sizeof(header)) {
- warning("short read from header");
- return false;
- }
+ResourceManager::ResourceManager() {}
- decrypt(header, 0x10);
- if (strncmp(reinterpret_cast<const char*>(header), kSignature, 0x10) != 0) {
- warning("invalid signature");
- return false;
- }
-
- Common::MemoryReadStreamEndian reader(header + 0x10, sizeof(header) - 0x10, false);
- uint32 version1 = reader.readUint32();
- if (version1 != kVersion1) {
- warning("invalid version 1 (%d)", version1);
- return false;
- }
-
- uint32 magic = reader.readUint32();
- if (magic != kMagic) {
- warning("invalid magic (0x%08x)", magic);
- return false;
- }
-
- uint32 version2 = reader.readUint32();
- if (version2 != kVersion2) {
- warning("invalid version 2 (%d)", version2);
- return false;
- }
+ResourceManager::~ResourceManager() {}
- unsigned dirCount = reader.readUint32();
- if (!reader.skip(3 * 4))
- return false;
-
- //debug("+%u files in index", dirCount);
- while(dirCount--) {
- uint8 dirData[0x31];
- uint8 * dirDataEnd = dirData + sizeof(dirData);
-
- if (_file.read(dirData, sizeof(dirData)) != sizeof(dirData)) {
- warning("short read, corrupted file");
- return false;
- }
-
- uint8 *nameEnd = Common::find(dirData, dirDataEnd, 0);
- if (nameEnd == dirDataEnd) {
- warning("corrupted entry at %d", (int)_file.pos() - 0x31);
- continue;
- }
-
- unsigned nameLength = nameEnd - dirData;
- decrypt(dirData, nameLength);
- Common::String name(reinterpret_cast<char *>(dirData), nameLength);
-
- Common::MemoryReadStreamEndian dirReader(dirData + 0x21, 8, false);
-
- uint32 offset = dirReader.readSint32();
- uint32 size = dirReader.readSint32();
- //debug("\t\tfile %s %u %u", name.c_str(), offset, size);
- ArchiveMemberPtr resource(new ArchiveMember(this, name, offset, size));
- _members.setVal(name, resource);
- }
+void ResourceManager::decrypt(uint8 *data, unsigned size) {
+ static const char *kKey = "Vyvojovy tym AGDS varuje: Hackerovani skodi obchodu!";
+ const char *ptr = kKey;
+ while (size--) {
+ *data++ ^= 0xff ^ *ptr++;
+ if (*ptr == 0)
+ ptr = kKey;
+ }
+}
+
+bool ResourceManager::GrpFile::load(const Common::String &grpFilename) {
+ static const char *kSignature = "AGDS group file\x1a";
+ static const uint32 kMagic = 0x1a03c9e6;
+ static const uint32 kVersion1 = 44;
+ static const uint32 kVersion2 = 2;
+
+ debug("adding path %s", grpFilename.c_str());
+ if (!_file.open(grpFilename)) {
+ warning("failing opening grp file %s", grpFilename.c_str());
+ return false;
+ }
+ uint8 header[0x2c];
+ if (_file.read(header, sizeof(header)) != sizeof(header)) {
+ warning("short read from header");
+ return false;
+ }
- debug("%s: %u files in index", grpFilename.c_str(), _members.size());
- return true;
+ decrypt(header, 0x10);
+ if (strncmp(reinterpret_cast<const char *>(header), kSignature, 0x10) != 0) {
+ warning("invalid signature");
+ return false;
}
- int ResourceManager::GrpFile::listMembers(Common::ArchiveMemberList &list) const {
- int size = 0;
- for(MembersType::const_iterator i = _members.begin(); i != _members.end(); ++i, ++size)
- list.push_back(i->_value);
- return size;
+ Common::MemoryReadStreamEndian reader(header + 0x10, sizeof(header) - 0x10, false);
+ uint32 version1 = reader.readUint32();
+ if (version1 != kVersion1) {
+ warning("invalid version 1 (%d)", version1);
+ return false;
}
- const Common::ArchiveMemberPtr ResourceManager::GrpFile::getMember(const Common::String &name) const {
- Common::ArchiveMemberPtr member;
- MembersType::const_iterator i = _members.find(name);
- if (i != _members.end())
- member = i->_value;
- return member;
+ uint32 magic = reader.readUint32();
+ if (magic != kMagic) {
+ warning("invalid magic (0x%08x)", magic);
+ return false;
}
- Common::SeekableReadStream *ResourceManager::GrpFile::createReadStreamForMember(const Common::String &name) const {
- Common::ArchiveMemberPtr member = getMember(name);
- return member? member->createReadStream(): NULL;
+ uint32 version2 = reader.readUint32();
+ if (version2 != kVersion2) {
+ warning("invalid version 2 (%d)", version2);
+ return false;
}
+ unsigned dirCount = reader.readUint32();
+ if (!reader.skip(3 * 4))
+ return false;
- bool ResourceManager::addPath(const Common::String &grpFilename) {
- GrpFile * grpFile = new GrpFile();
- if (!grpFile->load(grpFilename)) {
- delete grpFile;
+ //debug("+%u files in index", dirCount);
+ while (dirCount--) {
+ uint8 dirData[0x31];
+ uint8 *dirDataEnd = dirData + sizeof(dirData);
+
+ if (_file.read(dirData, sizeof(dirData)) != sizeof(dirData)) {
+ warning("short read, corrupted file");
return false;
}
- SearchMan.add(grpFilename, grpFile, 0, true);
- return true;
- }
-
- Common::SeekableReadStream * ResourceManager::ArchiveMember::createReadStream() const {
- Common::SeekableReadStream &file = _parent->getArchiveStream();
- file.seek(_offset);
- return file.readStream(_size);
- }
+ uint8 *nameEnd = Common::find(dirData, dirDataEnd, 0);
+ if (nameEnd == dirDataEnd) {
+ warning("corrupted entry at %d", (int)_file.pos() - 0x31);
+ continue;
+ }
- Common::SeekableReadStream * ResourceManager::getResource(const Common::String &name) const {
- Common::File file;
- return (file.open(name))? file.readStream(file.size()): NULL;
- }
+ unsigned nameLength = nameEnd - dirData;
+ decrypt(dirData, nameLength);
+ Common::String name(reinterpret_cast<char *>(dirData), nameLength);
- Graphics::Surface * ResourceManager::loadPicture(const Common::String & name, const Graphics::PixelFormat &format) {
- Common::SeekableReadStream *stream = getResource(name);
- if (!stream)
- return NULL;
+ Common::MemoryReadStreamEndian dirReader(dirData + 0x21, 8, false);
- Common::String lname = name;
- lname.toLowercase();
-
- if (lname.hasSuffix(".bmp")) {
- Image::BitmapDecoder bmp;
- return bmp.loadStream(*stream)? bmp.getSurface()->convertTo(format): NULL;
- } else if (lname.hasSuffix(".pcx")) {
- Image::PCXDecoder pcx;
- return pcx.loadStream(*stream)? pcx.getSurface()->convertTo(format): NULL;
- } else if (lname.hasSuffix(".flc")) {
- Video::FlicDecoder flic;
- if (!flic.loadStream(stream)) {
- warning("flic decoder failed to load %s", name.c_str());
- return NULL;
- }
- const Graphics::Surface *surface = flic.decodeNextFrame();
- return surface? surface->convertTo(format, flic.getPalette()): NULL;
- } else
- warning("unknown extensions for resource %s", name.c_str());
- return NULL;
+ uint32 offset = dirReader.readSint32();
+ uint32 size = dirReader.readSint32();
+ //debug("\t\tfile %s %u %u", name.c_str(), offset, size);
+ ArchiveMemberPtr resource(new ArchiveMember(this, name, offset, size));
+ _members.setVal(name, resource);
}
- Common::String ResourceManager::loadText(Common::SeekableReadStream *stream)
- {
- if (!stream)
- error("stream is null");
- Common::Array<byte> text(stream->size());
- if (stream->read(text.data(), text.size()) != text.size())
- error("short read from text resource");
- delete stream;
-
- if (text.empty())
- return Common::String();
+ debug("%s: %u files in index", grpFilename.c_str(), _members.size());
+ return true;
+}
+
+int ResourceManager::GrpFile::listMembers(Common::ArchiveMemberList &list) const {
+ int size = 0;
+ for (MembersType::const_iterator i = _members.begin(); i != _members.end(); ++i, ++size)
+ list.push_back(i->_value);
+ return size;
+}
+
+const Common::ArchiveMemberPtr ResourceManager::GrpFile::getMember(const Common::String &name) const {
+ Common::ArchiveMemberPtr member;
+ MembersType::const_iterator i = _members.find(name);
+ if (i != _members.end())
+ member = i->_value;
+ return member;
+}
+
+Common::SeekableReadStream *ResourceManager::GrpFile::createReadStreamForMember(const Common::String &name) const {
+ Common::ArchiveMemberPtr member = getMember(name);
+ return member ? member->createReadStream() : NULL;
+}
+
+bool ResourceManager::addPath(const Common::String &grpFilename) {
+ GrpFile *grpFile = new GrpFile();
+ if (!grpFile->load(grpFilename)) {
+ delete grpFile;
+ return false;
+ }
- char *begin = reinterpret_cast<char *>(text.data());
- char *end = begin + text.size();
- while(begin != end && end[-1] == 0)
- --end;
+ SearchMan.add(grpFilename, grpFile, 0, true);
+ return true;
+}
- decrypt(text.data(), end - begin);
+Common::SeekableReadStream *ResourceManager::ArchiveMember::createReadStream() const {
+ Common::SeekableReadStream &file = _parent->getArchiveStream();
+ file.seek(_offset);
+ return file.readStream(_size);
+}
- while(begin != end && end[-1] == 0)
- --end;
+Common::SeekableReadStream *ResourceManager::getResource(const Common::String &name) const {
+ Common::File file;
+ return (file.open(name)) ? file.readStream(file.size()) : NULL;
+}
- return Common::String(begin, end);
- }
-
- Common::String ResourceManager::loadText(const Common::String & name) const {
- Common::SeekableReadStream * stream = getResource(name);
- if (!stream)
- error("no text resource %s", name.c_str());
- return loadText(stream);
- }
+Graphics::Surface *ResourceManager::loadPicture(const Common::String &name, const Graphics::PixelFormat &format) {
+ Common::SeekableReadStream *stream = getResource(name);
+ if (!stream)
+ return NULL;
+ Common::String lname = name;
+ lname.toLowercase();
+
+ if (lname.hasSuffix(".bmp")) {
+ Image::BitmapDecoder bmp;
+ return bmp.loadStream(*stream) ? bmp.getSurface()->convertTo(format) : NULL;
+ } else if (lname.hasSuffix(".pcx")) {
+ Image::PCXDecoder pcx;
+ return pcx.loadStream(*stream) ? pcx.getSurface()->convertTo(format) : NULL;
+ } else if (lname.hasSuffix(".flc")) {
+ Video::FlicDecoder flic;
+ if (!flic.loadStream(stream)) {
+ warning("flic decoder failed to load %s", name.c_str());
+ return NULL;
+ }
+ const Graphics::Surface *surface = flic.decodeNextFrame();
+ return surface ? surface->convertTo(format, flic.getPalette()) : NULL;
+ } else
+ warning("unknown extensions for resource %s", name.c_str());
+ return NULL;
+}
+
+Common::String ResourceManager::loadText(Common::SeekableReadStream *stream) {
+ if (!stream)
+ error("stream is null");
+ Common::Array<byte> text(stream->size());
+ if (stream->read(text.data(), text.size()) != text.size())
+ error("short read from text resource");
+ delete stream;
+
+ if (text.empty())
+ return Common::String();
+
+ char *begin = reinterpret_cast<char *>(text.data());
+ char *end = begin + text.size();
+ while (begin != end && end[-1] == 0)
+ --end;
+
+ decrypt(text.data(), end - begin);
+
+ while (begin != end && end[-1] == 0)
+ --end;
+
+ return Common::String(begin, end);
+}
+
+Common::String ResourceManager::loadText(const Common::String &name) const {
+ Common::SeekableReadStream *stream = getResource(name);
+ if (!stream)
+ error("no text resource %s", name.c_str());
+ return loadText(stream);
+}
} // End of namespace AGDS
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 624f97fd8d9..368e9e04dab 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -27,7 +27,7 @@
namespace AGDS {
-int Screen::ObjectZCompare(const ObjectPtr & a, const ObjectPtr & b) {
+int Screen::ObjectZCompare(const ObjectPtr &a, const ObjectPtr &b) {
return b->z() - a->z();
}
@@ -35,9 +35,8 @@ int Screen::AnimationZCompare(const Animation *a, const Animation *b) {
return b->z() - a->z();
}
-Screen::Screen(ObjectPtr object, const MouseMap &mouseMap) :
- _object(object), _name(object->getName()), _mouseMap(mouseMap),
- _children(&ObjectZCompare), _animations(&AnimationZCompare) {
+Screen::Screen(ObjectPtr object, const MouseMap &mouseMap) : _object(object), _name(object->getName()), _mouseMap(mouseMap),
+ _children(&ObjectZCompare), _animations(&AnimationZCompare) {
add(object);
}
@@ -50,7 +49,7 @@ void Screen::add(ObjectPtr object) {
warning("refusing to add null to scene");
return;
}
- for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
+ for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
if (*i == object) {
warning("double adding object %s", (*i)->getName().c_str());
return;
@@ -60,16 +59,16 @@ void Screen::add(ObjectPtr object) {
}
ObjectPtr Screen::find(const Common::String &name) {
- for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
+ for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
if ((*i)->getName() == name)
return *i;
}
return ObjectPtr();
}
-bool Screen::remove(const ObjectPtr & object) {
+bool Screen::remove(const ObjectPtr &object) {
bool found = false;
- for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ) {
+ for (ChildrenType::iterator i = _children.begin(); i != _children.end();) {
if (*i == object) {
i = _children.erase(i);
found = true;
@@ -81,7 +80,7 @@ bool Screen::remove(const ObjectPtr & object) {
bool Screen::remove(const Common::String &name) {
bool found = false;
- for(ChildrenType::iterator i = _children.begin(); i != _children.end(); ) {
+ for (ChildrenType::iterator i = _children.begin(); i != _children.end();) {
if ((*i)->getName() == name) {
i = _children.erase(i);
found = true;
@@ -91,8 +90,7 @@ bool Screen::remove(const Common::String &name) {
return found;
}
-
-void Screen::paint(AGDSEngine & engine, Graphics::Surface & backbuffer) {
+void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
#if 0
ChildrenType::iterator child = _children.begin();
AnimationsType::iterator animation = _animations.begin();
@@ -122,17 +120,17 @@ void Screen::paint(AGDSEngine & engine, Graphics::Surface & backbuffer) {
}
#else
ChildrenType::iterator i;
- for(i = _children.begin(); i != _children.end(); ++i) {
+ for (i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
if (object->z() < 1000)
- break;
+ break;
object->paint(engine, backbuffer);
}
- for(AnimationsType::iterator j = _animations.begin(); j != _animations.end(); ++j) {
- Animation * animation = *j;
+ for (AnimationsType::iterator j = _animations.begin(); j != _animations.end(); ++j) {
+ Animation *animation = *j;
animation->paint(engine, backbuffer, Common::Point());
}
- for(; i != _children.end(); ++i) {
+ for (; i != _children.end(); ++i) {
ObjectPtr object = *i;
object->paint(engine, backbuffer);
}
@@ -140,7 +138,7 @@ void Screen::paint(AGDSEngine & engine, Graphics::Surface & backbuffer) {
}
ObjectPtr Screen::find(Common::Point pos) const {
- for(ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
+ for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
RegionPtr region = object->region();
if (region && region->pointIn(pos))
@@ -151,7 +149,7 @@ ObjectPtr Screen::find(Common::Point pos) const {
Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
KeyHandler keyHandler;
- for(ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
+ for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
uint ip = object->getKeyHandler(keyName);
if (ip) {
@@ -161,13 +159,12 @@ Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
}
}
return keyHandler;
-
}
-MouseRegion * MouseMap::find(Common::Point pos) {
+MouseRegion *MouseMap::find(Common::Point pos) {
if (_disabled)
return NULL;
- for(MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i) {
+ for (MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i) {
MouseRegion &mouse = *i;
if (mouse.enabled && mouse.region->pointIn(pos))
return &mouse;
@@ -175,8 +172,8 @@ MouseRegion * MouseMap::find(Common::Point pos) {
return NULL;
}
-MouseRegion * MouseMap::find(int id) {
- for(MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i) {
+MouseRegion *MouseMap::find(int id) {
+ for (MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i) {
MouseRegion &mouse = *i;
if (mouse.id == id)
return &mouse;
@@ -185,7 +182,7 @@ MouseRegion * MouseMap::find(int id) {
}
void MouseMap::remove(int id) {
- for(MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ) {
+ for (MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end();) {
MouseRegion &mouse = *i;
if (mouse.id == id)
i = _mouseRegions.erase(i);
@@ -194,4 +191,4 @@ void MouseMap::remove(int id) {
}
}
-}
+} // namespace AGDS
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index c2b8ba47cd4..50fb521019e 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -23,63 +23,62 @@
#include "agds/soundManager.h"
#include "agds/agds.h"
#include "agds/object.h"
-#include "common/debug.h"
-#include "common/file.h"
-#include "common/textconsole.h"
#include "audio/audiostream.h"
#include "audio/decoders/vorbis.h"
#include "audio/decoders/wave.h"
+#include "common/debug.h"
+#include "common/file.h"
+#include "common/textconsole.h"
namespace AGDS {
- void SoundManager::tick() {
- for(SoundList::iterator i = _sounds.begin(); i != _sounds.end(); ) {
- Sound & sound = *i;
- if (!_mixer->isSoundHandleActive(sound.handle)) {
- //FIXME: re-enable me later
- // if (!sound.phaseVar.empty())
- // _engine->setGlobal(sound.phaseVar, -1);
- i = _sounds.erase(i);
- } else {
- // if (!sound.phaseVar.empty())
- // _engine->setGlobal(sound.phaseVar, _engine->getGlobal(sound.phaseVar) + 1);
- ++i;
- }
+void SoundManager::tick() {
+ for (SoundList::iterator i = _sounds.begin(); i != _sounds.end();) {
+ Sound &sound = *i;
+ if (!_mixer->isSoundHandleActive(sound.handle)) {
+ //FIXME: re-enable me later
+ // if (!sound.phaseVar.empty())
+ // _engine->setGlobal(sound.phaseVar, -1);
+ i = _sounds.erase(i);
+ } else {
+ // if (!sound.phaseVar.empty())
+ // _engine->setGlobal(sound.phaseVar, _engine->getGlobal(sound.phaseVar) + 1);
+ ++i;
}
}
+}
- void SoundManager::stopAll() {
- _mixer->stopAll();
- for(SoundList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) {
- Sound & sound = *i;
- _engine->setGlobal(sound.phaseVar, 0);
- }
+void SoundManager::stopAll() {
+ _mixer->stopAll();
+ for (SoundList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) {
+ Sound &sound = *i;
+ _engine->setGlobal(sound.phaseVar, 0);
}
+}
+void SoundManager::play(const Common::String &resource, const Common::String &phaseVar) {
+ Common::File *file = new Common::File();
+ if (!file->open(resource))
+ error("no sound %s", resource.c_str());
- void SoundManager::play(const Common::String &resource, const Common::String &phaseVar) {
- Common::File *file = new Common::File();
- if (!file->open(resource))
- error("no sound %s", resource.c_str());
-
- Common::String lname(resource);
- lname.toLowercase();
+ Common::String lname(resource);
+ lname.toLowercase();
- Audio::SeekableAudioStream *stream = NULL;
- if (lname.hasSuffix(".ogg")) {
- stream = Audio::makeVorbisStream(file, DisposeAfterUse::YES);
- } else if (lname.hasSuffix(".wav")) {
- stream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
- }
- if (!stream) {
- warning("could not play sound %s", resource.c_str());
- delete file;
- return;
- }
- Audio::SoundHandle handle;
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, stream);
-
- _sounds.push_back(Sound(resource, phaseVar, handle));
+ Audio::SeekableAudioStream *stream = NULL;
+ if (lname.hasSuffix(".ogg")) {
+ stream = Audio::makeVorbisStream(file, DisposeAfterUse::YES);
+ } else if (lname.hasSuffix(".wav")) {
+ stream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
+ }
+ if (!stream) {
+ warning("could not play sound %s", resource.c_str());
+ delete file;
+ return;
}
+ Audio::SoundHandle handle;
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, stream);
+ _sounds.push_back(Sound(resource, phaseVar, handle));
}
+
+} // namespace AGDS
diff --git a/engines/agds/systemVariable.cpp b/engines/agds/systemVariable.cpp
index 75abec38ec4..7f5ca9c4661 100644
--- a/engines/agds/systemVariable.cpp
+++ b/engines/agds/systemVariable.cpp
@@ -26,36 +26,36 @@
namespace AGDS {
- const Common::String & IntegerSystemVariable::getString() const {
- error("invalid type");
- }
-
- int IntegerSystemVariable::getInteger() const {
- return _value;
- }
+const Common::String &IntegerSystemVariable::getString() const {
+ error("invalid type");
+}
- void IntegerSystemVariable::setString(const Common::String &value) {
- error("invalid type");
- }
+int IntegerSystemVariable::getInteger() const {
+ return _value;
+}
- void IntegerSystemVariable::setInteger(int value) {
- _value = value;
- }
+void IntegerSystemVariable::setString(const Common::String &value) {
+ error("invalid type");
+}
- const Common::String & StringSystemVariable::getString() const {
- return _value;
- }
+void IntegerSystemVariable::setInteger(int value) {
+ _value = value;
+}
- int StringSystemVariable::getInteger() const {
- error("invalid type");
- }
+const Common::String &StringSystemVariable::getString() const {
+ return _value;
+}
- void StringSystemVariable::setString(const Common::String &value) {
- _value = value;
- }
+int StringSystemVariable::getInteger() const {
+ error("invalid type");
+}
- void StringSystemVariable::setInteger(int value) {
- error("invalid type");
- }
+void StringSystemVariable::setString(const Common::String &value) {
+ _value = value;
+}
+void StringSystemVariable::setInteger(int value) {
+ error("invalid type");
}
+
+} // namespace AGDS
Commit: b4185bc1c75ead8fbb60ffd1fe01f61931a5a9cf
https://github.com/scummvm/scummvm/commit/b4185bc1c75ead8fbb60ffd1fe01f61931a5a9cf
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:13+01:00
Commit Message:
AGDS: remove virtual, add metadata feature to metaengine
Changed paths:
engines/agds/agds.cpp
engines/agds/detection.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 752b42ecf7c..472373a4bae 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -776,9 +776,10 @@ bool AGDSEngine::hasFeature(EngineFeature f) const {
case kSupportsReturnToLauncher:
case kSupportsLoadingDuringRuntime:
case kSupportsSavingDuringRuntime:
+ case kSupportsChangingOptionsDuringRuntime:
return true;
default:
- return false;
+ return Engine::hasFeature(f);
}
}
diff --git a/engines/agds/detection.cpp b/engines/agds/detection.cpp
index c67ea424de7..9c8b8777e8b 100644
--- a/engines/agds/detection.cpp
+++ b/engines/agds/detection.cpp
@@ -36,21 +36,23 @@ public:
AGDSMetaEngine() : AdvancedMetaEngine(AGDS::gameDescriptions, sizeof(ADGameDescription), agdsGames) {
_maxScanDepth = 3;
}
- virtual const char *getEngineId() const {
+
+ const char *getEngineId() const {
return "agds";
}
- virtual const char *getName() const {
+ const char *getName() const {
return "AGDS Engine";
}
- virtual const char *getOriginalCopyright() const {
+ const char *getOriginalCopyright() const {
return "AGDS (C) Future Games";
}
- virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
- virtual bool hasFeature(MetaEngineFeature f) const {
+ bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+ bool hasFeature(MetaEngineFeature f) const override {
switch (f) {
+ case kSavesSupportMetaInfo:
case kSavesSupportThumbnail:
case kSavesUseExtendedFormat:
case kSimpleSavesNames:
@@ -58,7 +60,7 @@ public:
case kSupportsListSaves:
return true;
default:
- return false;
+ return AdvancedMetaEngine::hasFeature(f);
}
}
Commit: 2db39bd7df92385b3949da34a402f12eb1aca360
https://github.com/scummvm/scummvm/commit/2db39bd7df92385b3949da34a402f12eb1aca360
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:13+01:00
Commit Message:
AGDS: add override
Changed paths:
engines/agds/agds.h
engines/agds/detection.cpp
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 4abaeb43e3b..e47ea2fe1e3 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -72,7 +72,7 @@ public:
AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc);
~AGDSEngine();
- Common::Error run();
+ Common::Error run() override;
void setGlobal(const Common::String &name, int value) {
_globals.setVal(name, value);
diff --git a/engines/agds/detection.cpp b/engines/agds/detection.cpp
index 9c8b8777e8b..5c527f52b65 100644
--- a/engines/agds/detection.cpp
+++ b/engines/agds/detection.cpp
@@ -37,19 +37,19 @@ public:
_maxScanDepth = 3;
}
- const char *getEngineId() const {
+ const char *getEngineId() const override {
return "agds";
}
- const char *getName() const {
+ const char *getName() const override {
return "AGDS Engine";
}
- const char *getOriginalCopyright() const {
+ const char *getOriginalCopyright() const override{
return "AGDS (C) Future Games";
}
- bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+ bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
bool hasFeature(MetaEngineFeature f) const override {
switch (f) {
case kSavesSupportMetaInfo:
@@ -64,12 +64,12 @@ public:
}
}
- int getMaximumSaveSlot() const {
+ int getMaximumSaveSlot() const override {
return 99;
}
};
-bool AGDSMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+bool AGDSMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override {
if (desc) {
*engine = new AGDS::AGDSEngine(syst, desc);
}
Commit: 37b4af34bd436de2f13a3c4139a831f6f0cecd17
https://github.com/scummvm/scummvm/commit/37b4af34bd436de2f13a3c4139a831f6f0cecd17
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:13+01:00
Commit Message:
AGDS: implemented opcode 160, kLoadSaveSlotNamePicture
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index b9551bfff27..2a7cd67f100 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -177,7 +177,7 @@ enum Opcode {
kStub157 = 157,
kQuit = 158,
kExitProcessCreatePatch = 159,
- kStub160 = 160,
+ kLoadSaveSlotNamePicture = 160,
kStub161 = 161,
kDisableInventory = 162,
kEnableInventory = 163,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 0a5d023105b..4d76beced00 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -237,7 +237,7 @@ private:
void stub153();
void stub154();
void stub155();
- void stub160();
+ void loadSaveSlotNamePicture();
void stub166();
void stub172();
void stub173();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b216e57a9fe..764a3e1373f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -23,12 +23,14 @@
#include "agds/agds.h"
#include "agds/animation.h"
#include "agds/character.h"
+#include "agds/font.h"
#include "agds/opcode.h"
#include "agds/process.h"
#include "agds/region.h"
#include "agds/screen.h"
#include "agds/systemVariable.h"
#include "common/debug.h"
+#include "common/savefile.h"
#include "graphics/transparent_surface.h"
namespace AGDS {
@@ -599,9 +601,35 @@ void Process::stub155() {
push(0);
}
-void Process::stub160() {
- int arg = pop();
- debug("stub160: %d", arg);
+void Process::loadSaveSlotNamePicture() {
+ int saveSlot = pop();
+ debug("loadSaveSlotNamePicture: %d", saveSlot);
+
+ Common::String saveSlotName = _engine->getSaveStateName(saveSlot);
+ Common::SaveFileManager * saveMan = _engine->getSaveFileManager();
+ Common::InSaveFile * save = saveMan->openForLoading(saveSlotName);
+ if (!save) {
+ debug("no save in slot %d", saveSlot);
+ return;
+ }
+
+ debug("save state name: %s", saveSlotName.c_str());
+ int fontId = _engine->getSystemVariable("edit_font")->getInteger();
+
+ debug("font id = %d", fontId);
+ Font * font = _engine->getFont(fontId);
+ int h = font->getFontHeight();
+ static const int w = 400;
+
+ Graphics::Surface * label = _engine->createSurface(w, h);
+ uint32 color = _engine->pixelFormat().RGBToColor(255, 0, 255);
+ label->fillRect(label->getRect(), color);
+ font->drawString(label, saveSlotName, 0, 0, w, color);
+ Graphics::TransparentSurface *transparentLabel = _engine->convertToTransparent(label);
+ _object->setPicture(transparentLabel);
+ _object->generateRegion();
+
+ delete save;
}
void Process::stub166() {
@@ -1420,7 +1448,7 @@ ProcessExitCode Process::execute() {
OP(kStub153, stub153);
OP(kStub154, stub154);
OP(kStub155, stub155);
- OP(kStub160, stub160);
+ OP(kLoadSaveSlotNamePicture, loadSaveSlotNamePicture);
OP(kStub166, stub166);
OP(kSetDelay, setDelay);
OP(kStub172, stub172);
Commit: d1168cd9464fab168fdbe0e4647778a5c898433a
https://github.com/scummvm/scummvm/commit/d1168cd9464fab168fdbe0e4647778a5c898433a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:13+01:00
Commit Message:
AGDS: sync position and region.
When region loads, position updates to top-left of region.
When object moves, region shift coordinates relative to the original position.
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/region.cpp
engines/agds/region.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 472373a4bae..804e95a6aaa 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -575,6 +575,12 @@ Font *AGDSEngine::getFont(int id) const {
return i->_value;
}
+Graphics::Surface *AGDSEngine::createSurface(int w, int h) {
+ Graphics::Surface *surface = new Graphics::Surface();
+ surface->create(w, h, _pixelFormat);
+ return surface;
+}
+
Graphics::TransparentSurface *AGDSEngine::convertToTransparent(Graphics::Surface *surface) {
if (!surface)
return NULL;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index e47ea2fe1e3..6a28231a660 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -140,6 +140,7 @@ public:
}
Graphics::TransparentSurface *loadPicture(const Common::String &name);
+ Graphics::Surface *createSurface(int w, int h);
Graphics::TransparentSurface *convertToTransparent(Graphics::Surface *surface); //destroys surface!
int loadFromCache(const Common::String & name) const;
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 80cc43f15d9..8c1ef879f23 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -115,6 +115,32 @@ void Object::setPicture(Graphics::TransparentSurface *picture) {
_picture = picture;
}
+void Object::region(RegionPtr region) {
+ _region = region;
+ _pos = region->topLeft();
+}
+
+void Object::moveTo(Common::Point pos)
+{
+ Common::Point delta = pos - _pos;
+ debug("moving object %+d,%+d", delta.x, delta.y);
+ if (_region)
+ _region->move(delta);
+ _pos = pos;
+}
+
+void Object::generateRegion() {
+ if (!_picture) {
+ warning("generateRegion called on null picture");
+ return;
+ }
+
+ Common::Rect rect = _picture->getRect();
+ rect.moveTo(_pos.x, _pos.y);
+ _region = RegionPtr(new Region(rect));
+ debug("%s: generated region: %s", _name.c_str(), _region->toString().c_str());
+}
+
void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
if (_picture) {
Common::Point dst = _pos;
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 1f90b31c0ee..8b4c6a7cfc8 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -112,10 +112,13 @@ public:
}
void setPicture(Graphics::TransparentSurface *);
+
Graphics::TransparentSurface *getPicture() const {
return _picture;
}
+ void generateRegion();
+
void setAlpha(int alpha) {
if (alpha < 0)
alpha = 0;
@@ -124,9 +127,7 @@ public:
_alpha = (100 - alpha) * 255 / 100;
}
- void region(RegionPtr region) {
- _region = region;
- }
+ void region(RegionPtr region);
RegionPtr region() const {
return _region;
@@ -154,9 +155,7 @@ public:
void paint(AGDSEngine &engine, Graphics::Surface &backbuffer);
- void moveTo(Common::Point pos) {
- _pos = pos;
- }
+ void moveTo(Common::Point pos);
void z(int z) {
_z = z;
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index ce7bc35ba88..40e0b020bf5 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -92,6 +92,21 @@ void Region::move(Common::Point rel) {
points[i] += rel;
}
+Common::Point Region::topLeft() const {
+ if (points.empty())
+ return Common::Point();
+
+ Common::Point p = points[0];
+ for(uint i = 1; i < points.size(); ++i) {
+ Common::Point point = points[i];
+ if (point.x < p.x)
+ p.x = point.x;
+ if (point.y < p.y)
+ p.y = point.y;
+ }
+ return p;
+}
+
//FIXME: copied from wintermute/base_region.cpp
typedef struct {
diff --git a/engines/agds/region.h b/engines/agds/region.h
index bcdc6642a8f..d6de9a80fa3 100644
--- a/engines/agds/region.h
+++ b/engines/agds/region.h
@@ -44,6 +44,7 @@ struct Region {
bool pointIn(Common::Point point) const;
Common::String toString() const;
void move(Common::Point rel);
+ Common::Point topLeft() const;
};
Commit: 36278f97ad686b422c246106c1be516d8665bab3
https://github.com/scummvm/scummvm/commit/36278f97ad686b422c246106c1be516d8665bab3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:13+01:00
Commit Message:
AGDS: add kLoadGame opcode
Changed paths:
engines/agds/agds.cpp
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 804e95a6aaa..b8f91026b45 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -257,6 +257,9 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
_inventory.clear();
runObject(process.getExitArg2());
break;
+ case kExitCodeLoadSaveGame:
+ loadGameState(process.getExitIntArg1());
+ break;
default:
error("unknown process exit code %d", code);
}
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 2a7cd67f100..edcad21e24d 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -173,7 +173,7 @@ enum Opcode {
kStub153 = 153,
kStub154 = 154,
kStub155 = 155,
- kStub156 = 156,
+ kLoadGame = 156,
kStub157 = 157,
kQuit = 158,
kExitProcessCreatePatch = 159,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 4d76beced00..7c10583eadf 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -237,6 +237,7 @@ private:
void stub153();
void stub154();
void stub155();
+ void loadGame();
void loadSaveSlotNamePicture();
void stub166();
void stub172();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 764a3e1373f..466cdd2ebbf 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -601,6 +601,12 @@ void Process::stub155() {
push(0);
}
+void Process::loadGame() {
+ int saveSlot = pop();
+ debug("loadGame %d", saveSlot);
+ suspend(kExitCodeLoadSaveGame, saveSlot);
+}
+
void Process::loadSaveSlotNamePicture() {
int saveSlot = pop();
debug("loadSaveSlotNamePicture: %d", saveSlot);
@@ -1448,6 +1454,7 @@ ProcessExitCode Process::execute() {
OP(kStub153, stub153);
OP(kStub154, stub154);
OP(kStub155, stub155);
+ OP(kLoadGame, loadGame);
OP(kLoadSaveSlotNamePicture, loadSaveSlotNamePicture);
OP(kStub166, stub166);
OP(kSetDelay, setDelay);
Commit: 3053385a562b727187d0d782e3eab8b8209f4b22
https://github.com/scummvm/scummvm/commit/3053385a562b727187d0d782e3eab8b8209f4b22
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:14+01:00
Commit Message:
AGDS: allow streams to be used for database
Changed paths:
engines/agds/database.cpp
engines/agds/database.h
diff --git a/engines/agds/database.cpp b/engines/agds/database.cpp
index 4e27e60aef0..599e28ab2c7 100644
--- a/engines/agds/database.cpp
+++ b/engines/agds/database.cpp
@@ -28,21 +28,26 @@
namespace AGDS {
bool Database::open(const Common::String &filename) {
- static const uint32 kMagic = 666;
-
- _filename = filename;
Common::File file;
if (!file.open(filename))
return false;
- uint32 magic = file.readUint32LE();
+
+ return open(filename, &file);
+}
+
+bool Database::open(const Common::String &filename, Common::SeekableReadStream *stream) {
+ static const uint32 kMagic = 666;
+
+ _filename = filename;
+ uint32 magic = stream->readUint32LE();
if (magic != kMagic) {
- debug("invalid magic for database %s", filename.c_str());
+ debug("invalid magic for database %s", _filename.c_str());
return false;
}
- _writeable = file.readUint32LE();
- _totalEntries = file.readUint32LE();
- _usedEntries = file.readUint32LE();
- _maxNameSize = file.readUint32LE();
+ _writeable = stream->readUint32LE();
+ _totalEntries = stream->readUint32LE();
+ _usedEntries = stream->readUint32LE();
+ _maxNameSize = stream->readUint32LE();
if (_maxNameSize == 0) {
debug("invalid max name record size");
return false;
@@ -54,11 +59,11 @@ bool Database::open(const Common::String &filename) {
uint32 dataOffset = kHeaderSize + (_maxNameSize + kHeaderFieldSize) * _totalEntries;
Common::Array<char> nameBuffer(_maxNameSize + 1);
for (uint32 i = 0; i < _usedEntries; ++i) {
- uint32 offset = file.readUint32LE();
- file.read(nameBuffer.data(), nameBuffer.size());
+ uint32 offset = stream->readUint32LE();
+ stream->read(nameBuffer.data(), nameBuffer.size());
char *z = Common::find(nameBuffer.begin(), nameBuffer.end(), 0);
Common::String name(nameBuffer.data(), z - nameBuffer.begin());
- uint32 size = file.readUint32LE();
+ uint32 size = stream->readUint32LE();
//debug("adb entry: %s, offset %08x, size: %u", name.c_str(), offset, size);
_entries.setVal(name, Entry(dataOffset + offset, size));
}
@@ -67,17 +72,22 @@ bool Database::open(const Common::String &filename) {
}
Common::SeekableReadStream *Database::getEntry(const Common::String &name) const {
- EntriesType::const_iterator i = _entries.find(name);
- if (i == _entries.end())
- return NULL;
-
Common::File file;
if (!file.open(_filename)) {
error("could not open database file %s", _filename.c_str()); //previously available, but now disappeared or no fd, error
return NULL;
}
+
+ return getEntry(&file, name);
+}
+
+Common::SeekableReadStream *Database::getEntry(Common::SeekableReadStream *parent, const Common::String &name) const {
+ EntriesType::const_iterator i = _entries.find(name);
+ if (i == _entries.end())
+ return NULL;
+
const Entry &entry = i->_value;
- file.seek(entry.offset);
- return file.readStream(entry.size);
+ parent->seek(entry.offset);
+ return parent->readStream(entry.size);
}
} // namespace AGDS
diff --git a/engines/agds/database.h b/engines/agds/database.h
index 24582b1cd27..999e348e298 100644
--- a/engines/agds/database.h
+++ b/engines/agds/database.h
@@ -54,7 +54,10 @@ private:
public:
bool open(const Common::String &filename);
+ bool open(const Common::String &filename, Common::SeekableReadStream *stream);
+
Common::SeekableReadStream * getEntry(const Common::String &name) const;
+ Common::SeekableReadStream *getEntry(Common::SeekableReadStream *parent, const Common::String &name) const;
};
Commit: d806c435b8273bcf2a62cfefada88104da2e2bfd
https://github.com/scummvm/scummvm/commit/d806c435b8273bcf2a62cfefada88104da2e2bfd
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:14+01:00
Commit Message:
AGDS: implemented loadGame stub
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index b8f91026b45..1e65791f920 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -23,6 +23,7 @@
#include "agds/agds.h"
#include "agds/animation.h"
#include "agds/character.h"
+#include "agds/database.h"
#include "agds/font.h"
#include "agds/mjpgPlayer.h"
#include "agds/object.h"
@@ -792,7 +793,83 @@ bool AGDSEngine::hasFeature(EngineFeature f) const {
}
}
-Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) { return Common::Error(Common::kNoError); }
+Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
+ Database db;
+ if (!db.open("savefile", file))
+ return Common::kReadingFailed;
+
+ {
+ // Compiled version (should be 2)
+ Common::ScopedPtr<Common::SeekableReadStream> agds_ver(db.getEntry(file, "__agds_ver"));
+ int version = agds_ver->readUint32LE();
+ debug("version: %d", version);
+ if (version != 2) {
+ warning("wrong engine version (%d)", version);
+ return Common::kReadingFailed;
+ }
+ }
+
+ {
+ // Global vars
+ _globals.clear();
+ Common::ScopedPtr<Common::SeekableReadStream> agds_v(db.getEntry(file, "__agds_v"));
+ uint32 n = agds_v->readUint32LE();
+ debug("reading %u vars...", n);
+ Common::Array<char> name(33);
+ while(n--) {
+ agds_v->read(name.data(), 32);
+ int value = agds_v->readSint32LE();
+ debug("setting var %s to %d", name.data(), value);
+ setGlobal(name.data(), value);
+ }
+ }
+ {
+ // Current character
+ Common::ScopedPtr<Common::SeekableReadStream> agds_c(db.getEntry(file, "__agds_c"));
+ Common::Array<char> data(0x61);
+ agds_c->read(data.data(), 0x60);
+ Common::String object(data.data());
+ Common::String name(data.data() + 0x20);
+ Common::String id(data.data() + 0x40);
+ debug("savegame character %s %s %s", object.c_str(), name.c_str(), id.c_str());
+ //loadCharacter(id, name, object);
+ int x = agds_c->readUint16LE();
+ int y = agds_c->readUint16LE();
+ debug("character at %d, %d", x, y);
+ int n = 3;
+ while(n--) {
+ int v = agds_c->readUint16LE();
+ debug("savegame character leftover: %d", v);
+ }
+ }
+
+ {
+ // Inventory
+ _inventory.clear();
+ Common::ScopedPtr<Common::SeekableReadStream> agds_i(db.getEntry(file, "__agds_i"));
+ int n = 34;
+ Common::Array<char> name(33);
+ while(n--) {
+ agds_i->read(name.data(), 32);
+ int unk = agds_i->readUint32LE();
+ int present = agds_i->readUint32LE();
+ debug("inventory: %s %d %d", name.data(), unk, present);
+ if (!name.empty() && present) {
+ _inventory.add(loadObject(name.data()));
+ }
+ }
+ }
+
+ {
+ // Screenshot and screen name
+ Common::ScopedPtr<Common::SeekableReadStream> agds_s(db.getEntry(file, "__agds_s"));
+ Common::Array<char> screenName(33);
+ agds_s->read(screenName.data(), 32);
+ loadScreen(Common::String(screenName.data()));
+ }
+
+ return Common::kNoError;
+}
Common::Error AGDSEngine::saveGameStream(Common::WriteStream *file, bool isAutosave) { return Common::Error(Common::kNoError); }
Commit: 132e5a03127265d8d4ade6c7fcb9b45f02b6868c
https://github.com/scummvm/scummvm/commit/132e5a03127265d8d4ade6c7fcb9b45f02b6868c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:14+01:00
Commit Message:
AGDS: parse character file
Changed paths:
A engines/agds/character.cpp
engines/agds/agds.cpp
engines/agds/character.h
engines/agds/module.mk
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 1e65791f920..3d6ef940920 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -528,12 +528,13 @@ Animation *AGDSEngine::findAnimationByPhaseVar(const Common::String &phaseVar) {
return NULL;
}
-Character *AGDSEngine::loadCharacter(const Common::String &id, const Common::String &name, const Common::String &object) {
+Character *AGDSEngine::loadCharacter(const Common::String &id, const Common::String &filename, const Common::String &object) {
CharactersType::iterator i = _characters.find(id);
if (i != _characters.end())
return i->_value;
- Character *character = new Character(name, object);
+ Character *character = new Character(id, object);
+ character->load(_resourceManager.getResource(filename));
_characters[id] = character;
return character;
}
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
new file mode 100644
index 00000000000..e17f8fb68da
--- /dev/null
+++ b/engines/agds/character.cpp
@@ -0,0 +1,79 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/character.h"
+#include "common/array.h"
+#include "common/debug.h"
+#include "common/error.h"
+#include "common/stream.h"
+#include "common/textconsole.h"
+#include "common/util.h"
+
+namespace AGDS {
+
+void Character::load(Common::SeekableReadStream* stream) {
+ debug("loading character...");
+ stream->readUint32LE(); //unk
+ uint16 magic = stream->readUint16LE();
+ uint n;
+ switch(magic) {
+ case 0xdead:
+ n = 16;
+ break;
+ case 0x8888:
+ n = 8;
+ break;
+ default:
+ error("invalid magic %04x", magic);
+ }
+
+ _animations.clear();
+ while(stream->pos() < stream->size()) {
+ uint size = stream->readUint32LE();
+ uint index = stream->readUint16LE();
+ debug("header size %u, index: %u", size, index);
+
+ uint16 frames = stream->readUint16LE();
+ uint16 format = stream->readUint16LE();
+ Common::Array<char> nameData(33);
+ stream->read(nameData.data(), 32);
+
+ AnimationDescription animation;
+ animation.filename = Common::String(nameData.data());
+ debug("animation %s, frames: %d, format: %d", animation.filename.c_str(), frames, format);
+ while(frames--) {
+ int x = stream->readSint16LE();
+ int y = stream->readSint16LE();
+ int w = stream->readUint32LE();
+ int h = stream->readUint32LE();
+ AnimationDescription::Frame frame = { x, y, w, h };
+ animation.frames.push_back(frame);
+ debug("frame %d, %d, %dx%d", x, y, w, h);
+ stream->skip(50);
+ }
+ _animations.push_back(animation);
+ }
+
+ delete stream;
+}
+
+}
diff --git a/engines/agds/character.h b/engines/agds/character.h
index f690807c316..e6908d691ab 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -24,6 +24,7 @@
#define AGDS_CHARACTER_H
#include "common/scummsys.h"
+#include "common/array.h"
#include "common/rect.h"
namespace Common { class SeekableReadStream; }
@@ -42,9 +43,20 @@ class Character {
int _phase;
int _frames;
+ struct AnimationDescription {
+ struct Frame {
+ int x, y;
+ int w, h;
+ };
+
+ Common::String filename;
+ Common::Array<Frame> frames;
+ };
+ Common::Array<AnimationDescription> _animations;
+
public:
Character(const Common::String & name, const Common::String & object):
- _enabled(true), _phase(0), _frames(0), _name(name), _object(object) {
+ _name(name), _object(object), _enabled(true), _phase(0), _frames(0) {
}
const Common::String & name() const {
@@ -55,9 +67,7 @@ public:
return _object;
}
- bool load(Common::SeekableReadStream* stream) {
- return true;
- }
+ void load(Common::SeekableReadStream* stream);
void enable(bool enabled = true) {
_enabled = enabled;
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index 30cdd0b192f..3d35f85a195 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -3,6 +3,7 @@ MODULE := engines/agds
MODULE_OBJS := \
agds.o \
animation.o \
+ character.o \
database.o \
detection.o \
font.o \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 466cdd2ebbf..7bfcfd65922 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1100,10 +1100,10 @@ void Process::addMouseArea() {
void Process::loadCharacter() {
Common::String object = popString();
- Common::String name = popText();
+ Common::String chrFilename = popText();
Common::String id = popString();
- debug("loadCharacter %s %s %s", id.c_str(), name.c_str(), object.c_str());
- _engine->loadCharacter(id, name, object);
+ debug("loadCharacter %s %s %s", id.c_str(), chrFilename.c_str(), object.c_str());
+ _engine->loadCharacter(id, chrFilename, object);
}
void Process::enableCharacter() {
Commit: 28a2d8c21e40832e2ab11eb9a4f863214d714a17
https://github.com/scummvm/scummvm/commit/28a2d8c21e40832e2ab11eb9a4f863214d714a17
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:14+01:00
Commit Message:
AGDS: cleaning up saves, allow save_slot (-x)
Changed paths:
engines/agds/agds.cpp
engines/agds/detection.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3d6ef940920..3b85f1a82e4 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -31,6 +31,7 @@
#include "agds/region.h"
#include "agds/screen.h"
#include "agds/systemVariable.h"
+#include "common/config-manager.h"
#include "common/debug.h"
#include "common/error.h"
#include "common/events.h"
@@ -320,6 +321,10 @@ Common::Error AGDSEngine::run() {
if (!load())
return Common::kNoGameDataFoundError;
+ int loadSlot = ConfMan.getInt("save_slot");
+ if (loadSlot >= 0)
+ loadGameState(loadSlot);
+
Common::EventManager *eventManager = _system->getEventManager();
while (!shouldQuit()) {
diff --git a/engines/agds/detection.cpp b/engines/agds/detection.cpp
index 5c527f52b65..b35300b3413 100644
--- a/engines/agds/detection.cpp
+++ b/engines/agds/detection.cpp
@@ -52,12 +52,12 @@ public:
bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
bool hasFeature(MetaEngineFeature f) const override {
switch (f) {
+ case kSupportsListSaves:
+ case kSupportsLoadingDuringStartup:
+ case kSupportsDeleteSave:
case kSavesSupportMetaInfo:
case kSavesSupportThumbnail:
- case kSavesUseExtendedFormat:
case kSimpleSavesNames:
- case kSupportsDeleteSave:
- case kSupportsListSaves:
return true;
default:
return AdvancedMetaEngine::hasFeature(f);
Commit: 99084ff065adb0d03ff83ee1d710c8b2ae177404
https://github.com/scummvm/scummvm/commit/99084ff065adb0d03ff83ee1d710c8b2ae177404
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:14+01:00
Commit Message:
AGDS: load system vars from save
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/systemVariable.cpp
engines/agds/systemVariable.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3b85f1a82e4..996f0242fc3 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -601,63 +601,56 @@ Graphics::TransparentSurface *AGDSEngine::convertToTransparent(Graphics::Surface
return t;
}
-void AGDSEngine::initSystemVariables() {
- _systemVars["inventory_scr"] = new StringSystemVariable();
- _systemVars["escape_scr"] = new StringSystemVariable("none");
- _systemVars["load_scr"] = new StringSystemVariable();
- _systemVars["save_scr"] = new StringSystemVariable();
-
- _systemVars["gfx_bright"] = new IntegerSystemVariable(50);
- _systemVars["gfx_contrast"] = new IntegerSystemVariable(50);
-
- _systemVars["sound_volume"] = new IntegerSystemVariable(100);
- _systemVars["music_volume"] = new IntegerSystemVariable(80);
- _systemVars["tell_volume"] = new IntegerSystemVariable(100);
-
- _systemVars["text_speed"] = new IntegerSystemVariable(70);
- _systemVars["tell_mode"] = new IntegerSystemVariable(3);
- _systemVars["version"] = new IntegerSystemVariable(1);
-
- _systemVars["objtext_x"] = new IntegerSystemVariable(-1);
- _systemVars["objtext_y"] = new IntegerSystemVariable(-1);
- _systemVars["objtext_mode"] = new IntegerSystemVariable(-1);
- _systemVars["objtext_font"] = new IntegerSystemVariable(-1);
-
- _systemVars["inv_open"] = new StringSystemVariable();
- _systemVars["inv_close"] = new StringSystemVariable();
- _systemVars["inv_region"] = new StringSystemVariable();
-
- _systemVars["anim_zoom"] = new IntegerSystemVariable(1);
-
- _systemVars["screen_curtain"] = new IntegerSystemVariable(1);
- _systemVars["music_curtain"] = new IntegerSystemVariable(1);
- _systemVars["sound_curtain"] = new IntegerSystemVariable(1);
-
- _systemVars["old_music_volume"] = new IntegerSystemVariable();
- _systemVars["old_sound_volume"] = new IntegerSystemVariable();
- _systemVars["old_screen_fade"] = new IntegerSystemVariable();
-
- _systemVars["subtitle_x"] = new IntegerSystemVariable();
- _systemVars["subtitle_y"] = new IntegerSystemVariable();
- _systemVars["subtitle_type"] = new IntegerSystemVariable(3);
- _systemVars["subtitles"] = new IntegerSystemVariable();
-
- _systemVars["tell_font"] = new IntegerSystemVariable();
- _systemVars["npc_tell_font"] = new IntegerSystemVariable();
- _systemVars["edit_font"] = new IntegerSystemVariable();
- _systemVars["delay_after_tell"] = new IntegerSystemVariable();
-
- _systemVars["scroll_factor"] = new IntegerSystemVariable(30);
+void AGDSEngine::addSystemVar(const Common::String &name, SystemVariable *var) {
+ _systemVarList.push_back(name);
+ _systemVars[name] = var;
+}
- _systemVars["dialog_var"] = new IntegerSystemVariable();
- _systemVars["subtitle_width"] = new IntegerSystemVariable(-1);
- _systemVars["flash_mouse"] = new IntegerSystemVariable();
- _systemVars["scale_char"] = new IntegerSystemVariable();
- _systemVars["init_resources"] = new StringSystemVariable();
- _systemVars["done_resources"] = new StringSystemVariable();
- _systemVars["tell_close_inv"] = new IntegerSystemVariable(1);
- _systemVars["gamma"] = new IntegerSystemVariable();
+void AGDSEngine::initSystemVariables() {
+ addSystemVar("inventory_scr", new StringSystemVariable());
+ addSystemVar("escape_scr", new StringSystemVariable("none"));
+ addSystemVar("load_scr", new StringSystemVariable());
+ addSystemVar("save_scr", new StringSystemVariable());
+ addSystemVar("gfx_bright", new IntegerSystemVariable(50));
+ addSystemVar("gfx_contrast", new IntegerSystemVariable(50));
+ addSystemVar("sound_volume", new IntegerSystemVariable(100));
+ addSystemVar("music_volume", new IntegerSystemVariable(80));
+ addSystemVar("tell_volume", new IntegerSystemVariable(100));
+ addSystemVar("text_speed", new IntegerSystemVariable(70));
+ addSystemVar("tell_mode", new IntegerSystemVariable(3));
+ addSystemVar("version", new IntegerSystemVariable(1));
+ addSystemVar("objtext_x", new IntegerSystemVariable(-1));
+ addSystemVar("objtext_y", new IntegerSystemVariable(-1));
+ addSystemVar("objtext_mode", new IntegerSystemVariable(-1));
+ addSystemVar("objtext_font", new IntegerSystemVariable(-1));
+ addSystemVar("inv_open", new StringSystemVariable());
+ addSystemVar("inv_close", new StringSystemVariable());
+ addSystemVar("inv_region", new StringSystemVariable());
+ addSystemVar("anim_zoom", new IntegerSystemVariable(1));
+ addSystemVar("screen_curtain", new IntegerSystemVariable(1));
+ addSystemVar("music_curtain", new IntegerSystemVariable(1));
+ addSystemVar("sound_curtain", new IntegerSystemVariable(1));
+ addSystemVar("old_music_volume", new IntegerSystemVariable());
+ addSystemVar("old_sound_volume", new IntegerSystemVariable());
+ addSystemVar("old_screen_fade", new IntegerSystemVariable());
+ addSystemVar("subtitle_x", new IntegerSystemVariable());
+ addSystemVar("subtitle_y", new IntegerSystemVariable());
+ addSystemVar("subtitle_type", new IntegerSystemVariable(3));
+ addSystemVar("subtitles", new IntegerSystemVariable());
+ addSystemVar("tell_font", new IntegerSystemVariable());
+ addSystemVar("npc_tell_font", new IntegerSystemVariable());
+ addSystemVar("edit_font", new IntegerSystemVariable());
+ addSystemVar("delay_after_tell", new IntegerSystemVariable());
+ addSystemVar("scroll_factor", new IntegerSystemVariable(30));
+ addSystemVar("dialog_var", new IntegerSystemVariable());
+ addSystemVar("subtitle_width", new IntegerSystemVariable(-1));
+ addSystemVar("flash_mouse", new IntegerSystemVariable());
+ addSystemVar("scale_char", new IntegerSystemVariable());
+ addSystemVar("init_resources", new StringSystemVariable());
+ addSystemVar("done_resources", new StringSystemVariable());
+ addSystemVar("tell_close_inv", new IntegerSystemVariable(1));
+ addSystemVar("gamma", new IntegerSystemVariable());
}
SystemVariable *AGDSEngine::getSystemVariable(const Common::String &name) {
@@ -815,6 +808,15 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
}
}
+ {
+ // System vars
+ Common::ScopedPtr<Common::SeekableReadStream> agds_d(db.getEntry(file, "__agds_d"));
+ for(uint i = 0, n = _systemVarList.size(); i < n; ++i) {
+ Common::String & name = _systemVarList[i];
+ _systemVars[name]->read(agds_d.get());
+ }
+ }
+
{
// Global vars
_globals.clear();
@@ -859,8 +861,8 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
agds_i->read(name.data(), 32);
int unk = agds_i->readUint32LE();
int present = agds_i->readUint32LE();
- debug("inventory: %s %d %d", name.data(), unk, present);
if (!name.empty() && present) {
+ debug("inventory: %s %d %d", name.data(), unk, present);
_inventory.add(loadObject(name.data()));
}
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 6a28231a660..e37256409f1 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -83,6 +83,7 @@ public:
int getGlobal(const Common::String &name) const;
private:
+ void addSystemVar(const Common::String &name, SystemVariable *var);
bool initGraphics();
bool load();
void runProcess(ProcessListType::iterator &it);
@@ -190,6 +191,7 @@ private:
typedef Common::HashMap<int, Graphics::TransparentSurface *> PictureCacheType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PictureCacheLookup;
typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
+ typedef Common::Array<Common::String> SystemVariablesListType;
typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
typedef Common::HashMap<Common::String, Animation *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> AnimationsType;
@@ -211,6 +213,7 @@ private:
int _sharedStorageIndex;
Common::String _sharedStorage[10];
GlobalsType _globals;
+ SystemVariablesListType _systemVarList;
SystemVariablesType _systemVars;
Graphics::PixelFormat _pixelFormat;
MJPGPlayer * _mjpgPlayer;
diff --git a/engines/agds/systemVariable.cpp b/engines/agds/systemVariable.cpp
index 7f5ca9c4661..051dfcdaa16 100644
--- a/engines/agds/systemVariable.cpp
+++ b/engines/agds/systemVariable.cpp
@@ -21,7 +21,9 @@
*/
#include "agds/systemVariable.h"
+#include "common/array.h"
#include "common/debug.h"
+#include "common/stream.h"
#include "common/textconsole.h"
namespace AGDS {
@@ -42,6 +44,14 @@ void IntegerSystemVariable::setInteger(int value) {
_value = value;
}
+void IntegerSystemVariable::read(Common::ReadStream * stream) {
+ _value = stream->readUint32LE();
+}
+
+void IntegerSystemVariable::write(Common::WriteStream * stream) const {
+ stream->writeUint32LE(_value);
+}
+
const Common::String &StringSystemVariable::getString() const {
return _value;
}
@@ -58,4 +68,21 @@ void StringSystemVariable::setInteger(int value) {
error("invalid type");
}
+void StringSystemVariable::read(Common::ReadStream * stream) {
+ byte len = stream->readByte();
+ if (len == 0)
+ error("invalid string var length");
+ Common::Array<char> str(len);
+ stream->read(str.data(), str.size());
+ _value = Common::String(str.data(), len - 1);
+}
+
+void StringSystemVariable::write(Common::WriteStream * stream) const {
+ uint len = _value.size() + 1;
+ if (len > 255)
+ error("variable too long, %u", len);
+ stream->writeByte(len);
+ stream->write(_value.c_str(), len);
+}
+
} // namespace AGDS
diff --git a/engines/agds/systemVariable.h b/engines/agds/systemVariable.h
index 7d12bb87d79..6d25ae67760 100644
--- a/engines/agds/systemVariable.h
+++ b/engines/agds/systemVariable.h
@@ -26,6 +26,11 @@
#include "common/scummsys.h"
#include "common/str.h"
+namespace Common {
+ class ReadStream;
+ class WriteStream;
+}
+
namespace AGDS {
class SystemVariable {
@@ -37,6 +42,8 @@ public:
virtual void setString(const Common::String &value) = 0;
virtual void setInteger(int value) = 0;
virtual void reset() = 0;
+ virtual void read(Common::ReadStream * stream) = 0;
+ virtual void write(Common::WriteStream * stream) const = 0;
};
class IntegerSystemVariable : public SystemVariable {
@@ -55,6 +62,8 @@ public:
virtual void reset() {
_value = _defaultValue;
}
+ virtual void read(Common::ReadStream * stream);
+ virtual void write(Common::WriteStream * stream) const;
};
class StringSystemVariable : public SystemVariable {
@@ -72,6 +81,8 @@ public:
virtual void reset() {
_value = _defaultValue;
}
+ virtual void read(Common::ReadStream * stream);
+ virtual void write(Common::WriteStream * stream) const;
};
} // End of namespace AGDS
Commit: dc7c01d0a04ea8a63e6df7779e4e14b0f58750d0
https://github.com/scummvm/scummvm/commit/dc7c01d0a04ea8a63e6df7779e4e14b0f58750d0
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:14+01:00
Commit Message:
AGDS: call loadCharacter from loadGameState
Changed paths:
engines/agds/agds.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 996f0242fc3..f87341eae53 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -534,6 +534,7 @@ Animation *AGDSEngine::findAnimationByPhaseVar(const Common::String &phaseVar) {
}
Character *AGDSEngine::loadCharacter(const Common::String &id, const Common::String &filename, const Common::String &object) {
+ debug("loadCharacter %s %s %s", id.c_str(), filename.c_str(), object.c_str());
CharactersType::iterator i = _characters.find(id);
if (i != _characters.end())
return i->_value;
@@ -839,8 +840,9 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
Common::String object(data.data());
Common::String name(data.data() + 0x20);
Common::String id(data.data() + 0x40);
- debug("savegame character %s %s %s", object.c_str(), name.c_str(), id.c_str());
- //loadCharacter(id, name, object);
+ Common::String filename = loadText(name);
+ debug("savegame character %s %s -> %s %s", object.c_str(), name.c_str(), filename.c_str(), id.c_str());
+ loadCharacter(id, filename, object);
int x = agds_c->readUint16LE();
int y = agds_c->readUint16LE();
debug("character at %d, %d", x, y);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 7bfcfd65922..a1da368ea5b 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1102,7 +1102,6 @@ void Process::loadCharacter() {
Common::String object = popString();
Common::String chrFilename = popText();
Common::String id = popString();
- debug("loadCharacter %s %s %s", id.c_str(), chrFilename.c_str(), object.c_str());
_engine->loadCharacter(id, chrFilename, object);
}
Commit: 5a4614e876a3343d5ffb11b12320190beedea221
https://github.com/scummvm/scummvm/commit/5a4614e876a3343d5ffb11b12320190beedea221
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:14+01:00
Commit Message:
AGDS: run inventory object code when loading objects
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index f87341eae53..046633db4cb 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -865,7 +865,9 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
int present = agds_i->readUint32LE();
if (!name.empty() && present) {
debug("inventory: %s %d %d", name.data(), unk, present);
- _inventory.add(loadObject(name.data()));
+ ObjectPtr object = loadObject(name.data());
+ runObject(name.data());
+ _inventory.add(object);
}
}
}
Commit: 4efede434a82ce26a8e136cccd1303c61aaa2746
https://github.com/scummvm/scummvm/commit/4efede434a82ce26a8e136cccd1303c61aaa2746
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:14+01:00
Commit Message:
AGDS: add readString(stream, size)
Changed paths:
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 0e1aed0a479..06ea8188535 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -197,7 +197,7 @@ Graphics::Surface *ResourceManager::loadPicture(const Common::String &name, cons
Common::String ResourceManager::loadText(Common::SeekableReadStream *stream) {
if (!stream)
error("stream is null");
- Common::Array<byte> text(stream->size());
+ Common::Array<char> text(stream->size());
if (stream->read(text.data(), text.size()) != text.size())
error("short read from text resource");
delete stream;
@@ -205,12 +205,12 @@ Common::String ResourceManager::loadText(Common::SeekableReadStream *stream) {
if (text.empty())
return Common::String();
- char *begin = reinterpret_cast<char *>(text.data());
+ char *begin = text.data();
char *end = begin + text.size();
while (begin != end && end[-1] == 0)
--end;
- decrypt(text.data(), end - begin);
+ decrypt(reinterpret_cast<uint8 *>(text.data()), end - begin);
while (begin != end && end[-1] == 0)
--end;
@@ -225,4 +225,14 @@ Common::String ResourceManager::loadText(const Common::String &name) const {
return loadText(stream);
}
+Common::String readString(Common::SeekableReadStream * stream, uint size) {
+ Common::Array<char> text(size);
+ if (stream->read(text.data(), text.size()) != text.size())
+ error("readString: short read");
+
+ uint len;
+ for(len = 0; len < text.size() && text[len]; ++len);
+ return Common::String(text.data(), len);
+}
+
} // End of namespace AGDS
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 7889a655be4..c54d9bd88bb 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -94,6 +94,7 @@ public:
Common::String loadText(const Common::String & name) const;
};
+Common::String readString(Common::SeekableReadStream * stream, uint size);
} // End of namespace AGDS
Commit: 5165e84a64e5e4de7fce718f3b7065b259ccaff8
https://github.com/scummvm/scummvm/commit/5165e84a64e5e4de7fce718f3b7065b259ccaff8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:14+01:00
Commit Message:
AGDS: load engine state parts in original order
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 046633db4cb..da19c513f93 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -810,14 +810,35 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
}
{
- // System vars
- Common::ScopedPtr<Common::SeekableReadStream> agds_d(db.getEntry(file, "__agds_d"));
- for(uint i = 0, n = _systemVarList.size(); i < n; ++i) {
- Common::String & name = _systemVarList[i];
- _systemVars[name]->read(agds_d.get());
+ // Current character
+ Common::ScopedPtr<Common::SeekableReadStream> agds_c(db.getEntry(file, "__agds_c"));
+ Common::Array<char> data(0x61);
+ agds_c->read(data.data(), 0x60);
+ Common::String object(data.data());
+ Common::String name(data.data() + 0x20);
+ Common::String id(data.data() + 0x40);
+ Common::String filename = loadText(name);
+ debug("savegame character %s %s -> %s %s", object.c_str(), name.c_str(), filename.c_str(), id.c_str());
+ loadCharacter(id, filename, object);
+ int x = agds_c->readUint16LE();
+ int y = agds_c->readUint16LE();
+ debug("character at %d, %d", x, y);
+ int n = 3;
+ while(n--) {
+ int v = agds_c->readUint16LE();
+ debug("savegame character leftover: %d", v);
}
}
+ Common::String screenName;
+ {
+ // Screenshot and screen name
+ Common::ScopedPtr<Common::SeekableReadStream> agds_s(db.getEntry(file, "__agds_s"));
+ Common::Array<char> screenNameData(33);
+ agds_s->read(screenNameData.data(), 32);
+ screenName = Common::String(screenNameData.data());
+ }
+
{
// Global vars
_globals.clear();
@@ -832,24 +853,20 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
setGlobal(name.data(), value);
}
}
+
{
- // Current character
- Common::ScopedPtr<Common::SeekableReadStream> agds_c(db.getEntry(file, "__agds_c"));
- Common::Array<char> data(0x61);
- agds_c->read(data.data(), 0x60);
- Common::String object(data.data());
- Common::String name(data.data() + 0x20);
- Common::String id(data.data() + 0x40);
- Common::String filename = loadText(name);
- debug("savegame character %s %s -> %s %s", object.c_str(), name.c_str(), filename.c_str(), id.c_str());
- loadCharacter(id, filename, object);
- int x = agds_c->readUint16LE();
- int y = agds_c->readUint16LE();
- debug("character at %d, %d", x, y);
- int n = 3;
- while(n--) {
- int v = agds_c->readUint16LE();
- debug("savegame character leftover: %d", v);
+ // Audio samples
+ Common::ScopedPtr<Common::SeekableReadStream> agds_a(db.getEntry(file, "__agds_a"));
+ char buffer[0x48] = {};
+ agds_a->read(buffer, sizeof(buffer));
+ }
+
+ {
+ // System vars
+ Common::ScopedPtr<Common::SeekableReadStream> agds_d(db.getEntry(file, "__agds_d"));
+ for(uint i = 0, n = _systemVarList.size(); i < n; ++i) {
+ Common::String & name = _systemVarList[i];
+ _systemVars[name]->read(agds_d.get());
}
}
@@ -872,13 +889,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
}
}
- {
- // Screenshot and screen name
- Common::ScopedPtr<Common::SeekableReadStream> agds_s(db.getEntry(file, "__agds_s"));
- Common::Array<char> screenName(33);
- agds_s->read(screenName.data(), 32);
- loadScreen(Common::String(screenName.data()));
- }
+ loadScreen(screenName);
return Common::kNoError;
}
Commit: 365f8674f05d43e7261e661724ddf23ad05e65a3
https://github.com/scummvm/scummvm/commit/365f8674f05d43e7261e661724ddf23ad05e65a3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:14+01:00
Commit Message:
AGDS: call init_resources after loading save state
Changed paths:
engines/agds/agds.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index da19c513f93..ecdf08484ee 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -889,6 +889,9 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
}
}
+ SystemVariable *initVar = getSystemVariable("init_resources");
+ runObject(initVar->getString());
+
loadScreen(screenName);
return Common::kNoError;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index a1da368ea5b..a0ac279b5a8 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -836,14 +836,11 @@ void Process::exitProcess() {
void Process::exitProcessCreatePatch() {
SystemVariable *initVar = _engine->getSystemVariable("init_resources");
- if (!initVar)
- error("no init_resources declared");
Common::String init = initVar->getString();
SystemVariable *doneVar = _engine->getSystemVariable("done_resources");
- if (!doneVar)
- error("no done_resources declared");
Common::String done = doneVar->getString();
+
debug("exitProcessCreatePatch stub, resource objects: %s %s", done.c_str(), init.c_str());
suspend(kExitCodeCreatePatchLoadResources, done, init);
}
Commit: 001a7d0f0c0ea691a6a557d4f3c190a797f452a1
https://github.com/scummvm/scummvm/commit/001a7d0f0c0ea691a6a557d4f3c190a797f452a1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:15+01:00
Commit Message:
AGDS: remove ugly Common::Array<char>
Changed paths:
engines/agds/agds.cpp
engines/agds/character.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ecdf08484ee..e30d29b780c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -812,11 +812,9 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
{
// Current character
Common::ScopedPtr<Common::SeekableReadStream> agds_c(db.getEntry(file, "__agds_c"));
- Common::Array<char> data(0x61);
- agds_c->read(data.data(), 0x60);
- Common::String object(data.data());
- Common::String name(data.data() + 0x20);
- Common::String id(data.data() + 0x40);
+ Common::String object = readString(agds_c.get(), 32);
+ Common::String name = readString(agds_c.get(), 32);
+ Common::String id = readString(agds_c.get(), 32);
Common::String filename = loadText(name);
debug("savegame character %s %s -> %s %s", object.c_str(), name.c_str(), filename.c_str(), id.c_str());
loadCharacter(id, filename, object);
@@ -834,9 +832,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
{
// Screenshot and screen name
Common::ScopedPtr<Common::SeekableReadStream> agds_s(db.getEntry(file, "__agds_s"));
- Common::Array<char> screenNameData(33);
- agds_s->read(screenNameData.data(), 32);
- screenName = Common::String(screenNameData.data());
+ screenName = readString(agds_s.get(), 32);
}
{
@@ -845,20 +841,23 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
Common::ScopedPtr<Common::SeekableReadStream> agds_v(db.getEntry(file, "__agds_v"));
uint32 n = agds_v->readUint32LE();
debug("reading %u vars...", n);
- Common::Array<char> name(33);
while(n--) {
- agds_v->read(name.data(), 32);
+ Common::String name = readString(agds_v.get(), 32);
int value = agds_v->readSint32LE();
- debug("setting var %s to %d", name.data(), value);
- setGlobal(name.data(), value);
+ debug("setting var %s to %d", name.c_str(), value);
+ setGlobal(name, value);
}
}
{
// Audio samples
Common::ScopedPtr<Common::SeekableReadStream> agds_a(db.getEntry(file, "__agds_a"));
- char buffer[0x48] = {};
- agds_a->read(buffer, sizeof(buffer));
+ Common::String sample = loadText(readString(agds_a.get(), 32));
+ Common::String phaseVar = readString(agds_a.get(), 32);
+ uint unk0 = agds_a->readUint32LE();
+ uint unk1 = agds_a->readUint32LE();
+ debug("saved audio state: sample: %s, var: %s %u %u", sample.c_str(), phaseVar.c_str(), unk0, unk1);
+ playSound(sample, phaseVar);
}
{
@@ -875,15 +874,14 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
_inventory.clear();
Common::ScopedPtr<Common::SeekableReadStream> agds_i(db.getEntry(file, "__agds_i"));
int n = 34;
- Common::Array<char> name(33);
while(n--) {
- agds_i->read(name.data(), 32);
+ Common::String name = readString(agds_i.get(), 32);
int unk = agds_i->readUint32LE();
int present = agds_i->readUint32LE();
if (!name.empty() && present) {
- debug("inventory: %s %d %d", name.data(), unk, present);
- ObjectPtr object = loadObject(name.data());
- runObject(name.data());
+ debug("inventory: %s %d %d", name.c_str(), unk, present);
+ ObjectPtr object = loadObject(name);
+ runObject(name);
_inventory.add(object);
}
}
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index e17f8fb68da..e654f362b20 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -21,6 +21,7 @@
*/
#include "agds/character.h"
+#include "agds/resourceManager.h"
#include "common/array.h"
#include "common/debug.h"
#include "common/error.h"
@@ -54,11 +55,10 @@ void Character::load(Common::SeekableReadStream* stream) {
uint16 frames = stream->readUint16LE();
uint16 format = stream->readUint16LE();
- Common::Array<char> nameData(33);
- stream->read(nameData.data(), 32);
+ Common::String filename = readString(stream, 32);
AnimationDescription animation;
- animation.filename = Common::String(nameData.data());
+ animation.filename = filename;
debug("animation %s, frames: %d, format: %d", animation.filename.c_str(), frames, format);
while(frames--) {
int x = stream->readSint16LE();
Commit: 15cd0d6e304356abad1b3426b5a75253b1039a14
https://github.com/scummvm/scummvm/commit/15cd0d6e304356abad1b3426b5a75253b1039a14
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:15+01:00
Commit Message:
AGDS: remove warning about double-adding object
Changed paths:
engines/agds/screen.cpp
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 368e9e04dab..5fae1afd80a 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -51,7 +51,7 @@ void Screen::add(ObjectPtr object) {
}
for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
if (*i == object) {
- warning("double adding object %s", (*i)->getName().c_str());
+ debug("double adding object %s", (*i)->getName().c_str());
return;
}
}
Commit: 27ebd9ce70a46dc3d8b70a8cf95e270ce09b36e5
https://github.com/scummvm/scummvm/commit/27ebd9ce70a46dc3d8b70a8cf95e270ce09b36e5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:15+01:00
Commit Message:
AGDS: fix all known z order issues, restored engine's default z of 10
Changed paths:
engines/agds/object.cpp
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 8c1ef879f23..b55d5dc57c6 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -36,7 +36,7 @@ namespace AGDS {
Object::Object(const Common::String &name, Common::SeekableReadStream *stream) : _name(name), _stringTableLoaded(false),
_picture(), _region(),
_animation(), _mouseCursor(),
- _pos(), _z(1000),
+ _pos(), _z(10),
_clickHandler(0), _examineHandler(0),
_alpha(255), _active(false) {
byte id = stream->readUint16LE();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index a0ac279b5a8..dccdd9280bb 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1020,15 +1020,13 @@ void Process::setObjectZ() {
int z = pop();
debug("setObjectZ %d", z);
_object->z(z);
- Screen *screen = _engine->getCurrentScreen();
- bool found = screen->remove(_object);
- if (found) {
- screen->add(_object);
- }
+ _engine->getCurrentScreen()->update(_object);
}
void Process::updateScreenHeightToDisplay() {
- debug("updateScreenHeightToDisplay");
+ debug("updateObjectZtoDisplayHeight");
+ _object->z(600);
+ _engine->getCurrentScreen()->update(_object);
}
void Process::loadTextFromObject() {
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 5fae1afd80a..0a6fce26a38 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -91,7 +91,6 @@ bool Screen::remove(const Common::String &name) {
}
void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
-#if 0
ChildrenType::iterator child = _children.begin();
AnimationsType::iterator animation = _animations.begin();
int idx = 0;
@@ -99,12 +98,12 @@ void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
bool child_valid = child != _children.end();
bool animation_valid = animation != _animations.end();
if (child_valid && animation_valid) {
- if ((*child)->z() < (*animation)->z()) {
+ if ((*child)->z() > (*animation)->z()) {
debug("object %d, z: %d", idx++, (*child)->z());
(*child)->paint(engine, backbuffer);
++child;
} else {
- debug("animatin %d, z: %d", idx++, (*animation)->z());
+ debug("animation %d, z: %d", idx++, (*animation)->z());
(*animation)->paint(engine, backbuffer, Common::Point());
++animation;
}
@@ -113,28 +112,11 @@ void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
(*child)->paint(engine, backbuffer);
++child;
} else {
- debug("animatin %d, z: %d", idx++, (*animation)->z());
+ debug("animation %d, z: %d", idx++, (*animation)->z());
(*animation)->paint(engine, backbuffer, Common::Point());
++animation;
}
}
-#else
- ChildrenType::iterator i;
- for (i = _children.begin(); i != _children.end(); ++i) {
- ObjectPtr object = *i;
- if (object->z() < 1000)
- break;
- object->paint(engine, backbuffer);
- }
- for (AnimationsType::iterator j = _animations.begin(); j != _animations.end(); ++j) {
- Animation *animation = *j;
- animation->paint(engine, backbuffer, Common::Point());
- }
- for (; i != _children.end(); ++i) {
- ObjectPtr object = *i;
- object->paint(engine, backbuffer);
- }
-#endif
}
ObjectPtr Screen::find(Common::Point pos) const {
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 0b3c7a0e665..597c20d031e 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -148,6 +148,13 @@ public:
void add(Animation * animation) {
_animations.insert(animation);
}
+
+ void update(const ObjectPtr &object) {
+ bool found = remove(object);
+ if (found)
+ add(object);
+ }
+
bool remove(const Common::String & name);
bool remove(const ObjectPtr & object);
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer);
Commit: f458e2858263e5d79cf6dfdcf0a5154d64b37376
https://github.com/scummvm/scummvm/commit/f458e2858263e5d79cf6dfdcf0a5154d64b37376
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:15+01:00
Commit Message:
AGDS: comment out debug in paint
Changed paths:
engines/agds/screen.cpp
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 0a6fce26a38..0c54c80334d 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -99,20 +99,20 @@ void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
bool animation_valid = animation != _animations.end();
if (child_valid && animation_valid) {
if ((*child)->z() > (*animation)->z()) {
- debug("object %d, z: %d", idx++, (*child)->z());
+ //debug("object %d, z: %d", idx++, (*child)->z());
(*child)->paint(engine, backbuffer);
++child;
} else {
- debug("animation %d, z: %d", idx++, (*animation)->z());
+ //debug("animation %d, z: %d", idx++, (*animation)->z());
(*animation)->paint(engine, backbuffer, Common::Point());
++animation;
}
} else if (child_valid) {
- debug("object %d, z: %d", idx++, (*child)->z());
+ //debug("object %d, z: %d", idx++, (*child)->z());
(*child)->paint(engine, backbuffer);
++child;
} else {
- debug("animation %d, z: %d", idx++, (*animation)->z());
+ //debug("animation %d, z: %d", idx++, (*animation)->z());
(*animation)->paint(engine, backbuffer, Common::Point());
++animation;
}
Commit: 971f691a75e756071028497b6878b4337b06677f
https://github.com/scummvm/scummvm/commit/971f691a75e756071028497b6878b4337b06677f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:15+01:00
Commit Message:
AGDS: rename stub154/155 to getObjectSurfaceX/Y
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index edcad21e24d..a00612a1dca 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -171,8 +171,8 @@ enum Opcode {
kStub151 = 151,
kStub152 = 152,
kStub153 = 153,
- kStub154 = 154,
- kStub155 = 155,
+ kGetObjectSurfaceX = 154,
+ kGetObjectSurfaceY = 155,
kLoadGame = 156,
kStub157 = 157,
kQuit = 158,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 7c10583eadf..bc1135c2c79 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -235,8 +235,8 @@ private:
void stub138();
void stub152();
void stub153();
- void stub154();
- void stub155();
+ void getObjectSurfaceX();
+ void getObjectSurfaceY();
void loadGame();
void loadSaveSlotNamePicture();
void stub166();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index dccdd9280bb..a34845d64ec 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -587,18 +587,20 @@ void Process::stub153() {
push(0);
}
-void Process::stub154() {
+void Process::getObjectSurfaceX() {
Common::String name = popString();
- debug("stub154(getSomeX): %s", name.c_str());
- ObjectPtr object = _engine->getCurrentScreenObject(name);
- push(0);
+ debug("getObjectSurfaceX: %s", name.c_str());
+ int x = _engine->getCurrentScreenObject(name)->getPosition().x;
+ debug("\t%d", x);
+ push(x);
}
-void Process::stub155() {
+void Process::getObjectSurfaceY() {
Common::String name = popString();
- debug("stub155(getSomeY): %s", name.c_str());
- ObjectPtr object = _engine->getCurrentScreenObject(name);
- push(0);
+ debug("getObjectSurfaceY: %s", name.c_str());
+ int y = _engine->getCurrentScreenObject(name)->getPosition().y;
+ debug("\t%d", y);
+ push(y);
}
void Process::loadGame() {
@@ -1446,8 +1448,8 @@ ProcessExitCode Process::execute() {
OP(kSetCloneVar, setCloneVar);
OP(kStub152, stub152);
OP(kStub153, stub153);
- OP(kStub154, stub154);
- OP(kStub155, stub155);
+ OP(kGetObjectSurfaceX, getObjectSurfaceX);
+ OP(kGetObjectSurfaceY, getObjectSurfaceX);
OP(kLoadGame, loadGame);
OP(kLoadSaveSlotNamePicture, loadSaveSlotNamePicture);
OP(kStub166, stub166);
Commit: b6fbb7abbdc789fd402240885e061dc5742ef685
https://github.com/scummvm/scummvm/commit/b6fbb7abbdc789fd402240885e061dc5742ef685
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:15+01:00
Commit Message:
AGDS: replace _pos with dst (typo)
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index b55d5dc57c6..ea4f66ea773 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -146,8 +146,9 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
Common::Point dst = _pos;
Common::Rect srcRect = _picture->getRect();
uint32 color = (_alpha << 24) | 0xffffff; //fixme: _picture->format.ARGBToColor(_alpha, 255, 255, 255); is not working
- if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
- _picture->blit(backbuffer, _pos.x, _pos.y, Graphics::FLIP_NONE, &srcRect, color);
+ if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect())) {
+ _picture->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
+ }
}
if (_animation) {
_animation->paint(engine, backbuffer, _animationPos);
Commit: 0fc72c41f6bb0e14607737221657a9f1fca5d11b
https://github.com/scummvm/scummvm/commit/0fc72c41f6bb0e14607737221657a9f1fca5d11b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:15+01:00
Commit Message:
AGDS: do not assume returned object was not null
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index a34845d64ec..3e8751fa703 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -590,7 +590,8 @@ void Process::stub153() {
void Process::getObjectSurfaceX() {
Common::String name = popString();
debug("getObjectSurfaceX: %s", name.c_str());
- int x = _engine->getCurrentScreenObject(name)->getPosition().x;
+ ObjectPtr object = _engine->getCurrentScreenObject(name);
+ int x = object? object->getPosition().x: 0;
debug("\t%d", x);
push(x);
}
@@ -598,7 +599,8 @@ void Process::getObjectSurfaceX() {
void Process::getObjectSurfaceY() {
Common::String name = popString();
debug("getObjectSurfaceY: %s", name.c_str());
- int y = _engine->getCurrentScreenObject(name)->getPosition().y;
+ ObjectPtr object = _engine->getCurrentScreenObject(name);
+ int y = object? object->getPosition().y: 0;
debug("\t%d", y);
push(y);
}
Commit: c3b94ea7d772b92a7ff0fa22f378f77c74187f0b
https://github.com/scummvm/scummvm/commit/c3b94ea7d772b92a7ff0fa22f378f77c74187f0b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:15+01:00
Commit Message:
AGDS: simplify region loading
Changed paths:
engines/agds/region.cpp
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index 40e0b020bf5..488b641831b 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -21,6 +21,7 @@
*/
#include "agds/region.h"
+#include "agds/resourceManager.h"
#include "common/algorithm.h"
#include "common/debug.h"
#include "common/endian.h"
@@ -29,23 +30,13 @@
namespace AGDS {
Region::Region(const Common::String &resourceName, Common::SeekableReadStream *stream) {
- static const int kRegionHeaderSize = 0x26;
- static const int kRegionHeaderWidthOffset = 0x20;
- static const int kRegionHeaderHeightOffset = 0x22;
- static const int kRegionHeaderFlagsOffset = 0x24;
-
int size = stream->size();
- debug("region size %d, data %d", size, size - kRegionHeaderSize);
- byte header[kRegionHeaderSize];
- if (stream->read(header, kRegionHeaderSize) != kRegionHeaderSize)
- error("invalid region %s", resourceName.c_str());
- byte *nameEnd = Common::find(header, header + 0x20, 0);
- name = Common::String(reinterpret_cast<char *>(header), nameEnd - header);
- center.x = READ_UINT16(header + kRegionHeaderWidthOffset);
- center.y = READ_UINT16(header + kRegionHeaderHeightOffset);
- flags = READ_UINT16(header + kRegionHeaderFlagsOffset);
+ name = readString(stream, 32);
+ center.x = stream->readUint16LE();
+ center.y = stream->readUint16LE();
+ flags = stream->readUint16LE();
debug("region %s at (%d,%d) %04x", name.c_str(), center.x, center.y, flags);
- if (size > kRegionHeaderSize) {
+ if (stream->pos() < size) {
uint16 ext = stream->readUint16LE();
//debug("extended entries %u", ext);
while (ext--) {
Commit: 7d3cbde881525637f8a03590e9bf48ec44658ae8
https://github.com/scummvm/scummvm/commit/7d3cbde881525637f8a03590e9bf48ec44658ae8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:15+01:00
Commit Message:
AGDS: scan default picture offset (tranparent left/top parts)
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index ea4f66ea773..69fc19c7a20 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -113,6 +113,35 @@ void Object::setPicture(Graphics::TransparentSurface *picture) {
delete _picture;
}
_picture = picture;
+
+ if (!picture) {
+ _offset = Common::Point();
+ return;
+ }
+
+ assert(picture->format.bytesPerPixel == 4);
+ const byte *pixels = static_cast<const byte *>(picture->getPixels());
+ uint pitch = picture->pitch;
+
+ uint16 w = picture->w, h = picture->h;
+ _offset.x = w;
+ _offset.y = h;
+
+ for (uint16 y = 0; y < h; ++y) {
+ for (uint16 x = 0; x < w; ++x) {
+ uint32 color = *reinterpret_cast<const uint32 *>(pixels + (y * pitch + x * picture->format.bytesPerPixel));
+ uint8 r, g, b, a;
+ picture->format.colorToARGB(color, a, r, g, b);
+ if (a != 0) {
+ if (y < _offset.y)
+ _offset.y = y;
+ if (x < _offset.x)
+ _offset.x = x;
+ break;
+ }
+ }
+ }
+ debug("OFFSET %d, %d", _offset.x, _offset.y);
}
void Object::region(RegionPtr region) {
@@ -143,7 +172,7 @@ void Object::generateRegion() {
void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
if (_picture) {
- Common::Point dst = _pos;
+ Common::Point dst = _pos - _offset;
Common::Rect srcRect = _picture->getRect();
uint32 color = (_alpha << 24) | 0xffffff; //fixme: _picture->format.ARGBToColor(_alpha, 255, 255, 255); is not working
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect())) {
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 8b4c6a7cfc8..a8becaecc9d 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -68,7 +68,7 @@ private:
RegionPtr _region;
Animation * _animation;
Animation * _mouseCursor;
- Common::Point _pos, _animationPos;
+ Common::Point _pos, _animationPos, _offset;
int _z;
Common::String _text;
uint _clickHandler;
@@ -177,6 +177,10 @@ public:
return _pos;
}
+ Common::Point getOffset() const {
+ return _offset;
+ }
+
void setKeyHandler(const Common::String &name, uint ip) {
_keyHandlers[name] = ip;
}
Commit: 09b89fd05b5db492b4c1b92dceecb3979591fac3
https://github.com/scummvm/scummvm/commit/09b89fd05b5db492b4c1b92dceecb3979591fac3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:15+01:00
Commit Message:
AGDS: implement stub152/153 (get base picture offset x/y)
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index a00612a1dca..06757e5bcfc 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -169,8 +169,8 @@ enum Opcode {
kStub149 = 149,
kStub150 = 150,
kStub151 = 151,
- kStub152 = 152,
- kStub153 = 153,
+ kGetPictureBaseX = 152,
+ kGetPictureBaseY = 153,
kGetObjectSurfaceX = 154,
kGetObjectSurfaceY = 155,
kLoadGame = 156,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index bc1135c2c79..8e1444b4439 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -233,8 +233,8 @@ private:
void setRandom();
void stub133();
void stub138();
- void stub152();
- void stub153();
+ void getPictureBaseX();
+ void getPictureBaseY();
void getObjectSurfaceX();
void getObjectSurfaceY();
void loadGame();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3e8751fa703..9f65b506db1 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -575,16 +575,22 @@ void Process::stub138() {
suspend(kExitCodeLoadScreenObject, arg2);
}
-void Process::stub152() {
+void Process::getPictureBaseX() {
Common::String name = popString();
- debug("stub152(getSomeX): %s", name.c_str());
- push(0);
+ debug("getPictureBaseX: %s", name.c_str());
+ ObjectPtr object = _engine->getCurrentScreenObject(name);
+ int x = object? object->getOffset().x: 0;
+ debug("\t%d", x);
+ push(x);
}
-void Process::stub153() {
+void Process::getPictureBaseY() {
Common::String name = popString();
- debug("stub153:(getSomeY): %s", name.c_str());
- push(0);
+ debug("getPictureBaseY: %s", name.c_str());
+ ObjectPtr object = _engine->getCurrentScreenObject(name);
+ int y = object? object->getOffset().y: 0;
+ debug("\t%d", y);
+ push(y);
}
void Process::getObjectSurfaceX() {
@@ -1448,8 +1454,8 @@ ProcessExitCode Process::execute() {
OP(kCloneName, cloneName);
OP(kGetCloneVar, getCloneVar);
OP(kSetCloneVar, setCloneVar);
- OP(kStub152, stub152);
- OP(kStub153, stub153);
+ OP(kGetPictureBaseX, getPictureBaseX);
+ OP(kGetPictureBaseY, getPictureBaseY);
OP(kGetObjectSurfaceX, getObjectSurfaceX);
OP(kGetObjectSurfaceY, getObjectSurfaceX);
OP(kLoadGame, loadGame);
Commit: ab94cefa997104b15e518f445de4efbe990190a0
https://github.com/scummvm/scummvm/commit/ab94cefa997104b15e518f445de4efbe990190a0
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:16+01:00
Commit Message:
AGDS: Add russian version of Nibiru: Age of Secrets to detection tables
Changed paths:
engines/agds/detection.cpp
engines/agds/detection_tables.h
diff --git a/engines/agds/detection.cpp b/engines/agds/detection.cpp
index b35300b3413..6a21c51a17c 100644
--- a/engines/agds/detection.cpp
+++ b/engines/agds/detection.cpp
@@ -26,6 +26,7 @@
#include "engines/advancedDetector.h"
static const PlainGameDescriptor agdsGames[] = {
+ {"nibiru", "NiBiRu: Age of Secrets"},
{"black-mirror", "Black Mirror"},
{0, 0}};
diff --git a/engines/agds/detection_tables.h b/engines/agds/detection_tables.h
index 3d3e0db2172..9c0a8ada89b 100644
--- a/engines/agds/detection_tables.h
+++ b/engines/agds/detection_tables.h
@@ -29,7 +29,17 @@ static const ADGameDescription gameDescriptions[] = {
"black-mirror",
0,
AD_ENTRY1s("gfx1.grp", "6665ce103cf12a362fd55f863d1ec9e6", 907820240),
- Common::EN_ANY,
+ Common::EN_USA,
+ Common::kPlatformWindows,
+ ADGF_DROPPLATFORM,
+ GUIO1(GUIO_NONE)
+ },
+
+ {
+ "nibiru",
+ 0,
+ AD_ENTRY1s("gfx1.grp", "c8e711bc01b16cd82849cbd996d02642", 381768360),
+ Common::RU_RUS,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NONE)
Commit: d6191ac566e8c71b50d75b69c2cb5df5e6288fb9
https://github.com/scummvm/scummvm/commit/d6191ac566e8c71b50d75b69c2cb5df5e6288fb9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:16+01:00
Commit Message:
AGDS: parse videomode from config
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index e30d29b780c..bae1d7ffa03 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -64,7 +64,7 @@ AGDSEngine::~AGDSEngine() {
}
}
-bool AGDSEngine::initGraphics() {
+bool AGDSEngine::initGraphics(int w, int h) {
//fixme: get mode from config?
typedef Common::List<Graphics::PixelFormat> FormatsType;
FormatsType formats = _system->getSupportedFormats();
@@ -74,7 +74,7 @@ bool AGDSEngine::initGraphics() {
if (fi->bytesPerPixel == 4 && format == Graphics::TransparentSurface::getSupportedPixelFormat()) {
debug("found mode %s", format.toString().c_str());
_pixelFormat = format;
- ::initGraphics(800, 600, &_pixelFormat);
+ ::initGraphics(w, h, &_pixelFormat);
return true;
}
}
@@ -93,7 +93,13 @@ bool AGDSEngine::load() {
if (!config.loadFromStream(configFile))
return false;
- if (!initGraphics())
+ int w = 800, h = 600, d = 32;
+ Common::String videoMode;
+ if (config.getKey("videomode", "core", videoMode) && sscanf(videoMode.c_str(), "%dx%dx%d", &w, &h, &d) == 3) {
+ debug("config videomode = %dx%d", w, h);
+ }
+
+ if (!initGraphics(w, h))
error("no video mode found");
Common::INIFile::SectionKeyList values = config.getKeys("core");
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index e37256409f1..db946f6016e 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -84,7 +84,7 @@ public:
private:
void addSystemVar(const Common::String &name, SystemVariable *var);
- bool initGraphics();
+ bool initGraphics(int w, int h);
bool load();
void runProcess(ProcessListType::iterator &it);
void tick();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 9f65b506db1..5cf7d0a4a35 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -31,6 +31,7 @@
#include "agds/systemVariable.h"
#include "common/debug.h"
#include "common/savefile.h"
+#include "common/system.h"
#include "graphics/transparent_surface.h"
namespace AGDS {
@@ -1035,7 +1036,7 @@ void Process::setObjectZ() {
void Process::updateScreenHeightToDisplay() {
debug("updateObjectZtoDisplayHeight");
- _object->z(600);
+ _object->z(g_system->getHeight());
_engine->getCurrentScreen()->update(_object);
}
Commit: 27ec2f449f1a288898d7d2854cc77e0c0c6af027
https://github.com/scummvm/scummvm/commit/27ec2f449f1a288898d7d2854cc77e0c0c6af027
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:16+01:00
Commit Message:
AGDS: set default size for readString()
Changed paths:
engines/agds/agds.cpp
engines/agds/character.cpp
engines/agds/region.cpp
engines/agds/resourceManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index bae1d7ffa03..fd925e73f12 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -818,9 +818,9 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
{
// Current character
Common::ScopedPtr<Common::SeekableReadStream> agds_c(db.getEntry(file, "__agds_c"));
- Common::String object = readString(agds_c.get(), 32);
- Common::String name = readString(agds_c.get(), 32);
- Common::String id = readString(agds_c.get(), 32);
+ Common::String object = readString(agds_c.get());
+ Common::String name = readString(agds_c.get());
+ Common::String id = readString(agds_c.get());
Common::String filename = loadText(name);
debug("savegame character %s %s -> %s %s", object.c_str(), name.c_str(), filename.c_str(), id.c_str());
loadCharacter(id, filename, object);
@@ -838,7 +838,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
{
// Screenshot and screen name
Common::ScopedPtr<Common::SeekableReadStream> agds_s(db.getEntry(file, "__agds_s"));
- screenName = readString(agds_s.get(), 32);
+ screenName = readString(agds_s.get());
}
{
@@ -848,7 +848,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
uint32 n = agds_v->readUint32LE();
debug("reading %u vars...", n);
while(n--) {
- Common::String name = readString(agds_v.get(), 32);
+ Common::String name = readString(agds_v.get());
int value = agds_v->readSint32LE();
debug("setting var %s to %d", name.c_str(), value);
setGlobal(name, value);
@@ -858,8 +858,8 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
{
// Audio samples
Common::ScopedPtr<Common::SeekableReadStream> agds_a(db.getEntry(file, "__agds_a"));
- Common::String sample = loadText(readString(agds_a.get(), 32));
- Common::String phaseVar = readString(agds_a.get(), 32);
+ Common::String sample = loadText(readString(agds_a.get()));
+ Common::String phaseVar = readString(agds_a.get());
uint unk0 = agds_a->readUint32LE();
uint unk1 = agds_a->readUint32LE();
debug("saved audio state: sample: %s, var: %s %u %u", sample.c_str(), phaseVar.c_str(), unk0, unk1);
@@ -881,7 +881,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
Common::ScopedPtr<Common::SeekableReadStream> agds_i(db.getEntry(file, "__agds_i"));
int n = 34;
while(n--) {
- Common::String name = readString(agds_i.get(), 32);
+ Common::String name = readString(agds_i.get());
int unk = agds_i->readUint32LE();
int present = agds_i->readUint32LE();
if (!name.empty() && present) {
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index e654f362b20..0c3d22cedda 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -55,7 +55,7 @@ void Character::load(Common::SeekableReadStream* stream) {
uint16 frames = stream->readUint16LE();
uint16 format = stream->readUint16LE();
- Common::String filename = readString(stream, 32);
+ Common::String filename = readString(stream);
AnimationDescription animation;
animation.filename = filename;
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index 488b641831b..5da0d57457e 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -31,7 +31,7 @@ namespace AGDS {
Region::Region(const Common::String &resourceName, Common::SeekableReadStream *stream) {
int size = stream->size();
- name = readString(stream, 32);
+ name = readString(stream);
center.x = stream->readUint16LE();
center.y = stream->readUint16LE();
flags = stream->readUint16LE();
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index c54d9bd88bb..d008a43bd8d 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -94,7 +94,7 @@ public:
Common::String loadText(const Common::String & name) const;
};
-Common::String readString(Common::SeekableReadStream * stream, uint size);
+Common::String readString(Common::SeekableReadStream * stream, uint size = 32);
} // End of namespace AGDS
Commit: b12e7de6e869cdae441de2c276a97c4bf941e983
https://github.com/scummvm/scummvm/commit/b12e7de6e869cdae441de2c276a97c4bf941e983
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:16+01:00
Commit Message:
AGDS: implement patches
Changed paths:
A engines/agds/patch.cpp
A engines/agds/patch.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/character.h
engines/agds/database.cpp
engines/agds/database.h
engines/agds/module.mk
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index fd925e73f12..8b46ef27483 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -27,6 +27,7 @@
#include "agds/font.h"
#include "agds/mjpgPlayer.h"
#include "agds/object.h"
+#include "agds/patch.h"
#include "agds/process.h"
#include "agds/region.h"
#include "agds/screen.h"
@@ -111,11 +112,16 @@ bool AGDSEngine::load() {
if (!_data.open("data.adb"))
return false;
- _patch.open("patch.adb"); //it's ok
-
initSystemVariables();
loadScreen("main");
+ Common::File file;
+ file.open("patch.adb");
+ Database patch;
+ patch.open("patch.adb");
+
+ loadPatches(&file, patch);
+
return true;
}
@@ -799,6 +805,24 @@ bool AGDSEngine::hasFeature(EngineFeature f) const {
}
}
+void AGDSEngine::loadPatches(Common::SeekableReadStream *file, Database & db) {
+ debug("loading patches");
+ _patches.clear();
+ Common::Array<Common::String> entries = db.getEntries();
+ for (uint i = 0; i < entries.size(); ++i) {
+ const Common::String & name = entries[i];
+ if (name[0] == '_')
+ continue;
+ debug("loading patch for %s", name.c_str());
+ Common::ScopedPtr<Common::SeekableReadStream> patchStream(db.getEntry(file, name));
+ PatchPtr patch(new Patch());
+ patch->load(patchStream.get());
+ _patches[name] = patch;
+ }
+ debug("done loading patches");
+}
+
+
Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
Database db;
if (!db.open("savefile", file))
@@ -875,6 +899,11 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
}
}
+ SystemVariable *initVar = getSystemVariable("init_resources");
+ runObject(initVar->getString());
+
+ loadScreen(screenName);
+
{
// Inventory
_inventory.clear();
@@ -892,11 +921,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
}
}
}
-
- SystemVariable *initVar = getSystemVariable("init_resources");
- runObject(initVar->getString());
-
- loadScreen(screenName);
+ loadPatches(file, db);
return Common::kNoError;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index db946f6016e..ce1af378280 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -56,6 +56,8 @@ class Character;
class Font;
class Object;
typedef Common::SharedPtr<Object> ObjectPtr;
+struct Patch;
+typedef Common::SharedPtr<Patch> PatchPtr;
class Process;
struct Region;
typedef Common::SharedPtr<Region> RegionPtr;
@@ -187,6 +189,7 @@ public:
private:
void parseDialogDefs(const Common::String &defs);
+ void loadPatches(Common::SeekableReadStream *file, Database & db);
typedef Common::HashMap<int, Graphics::TransparentSurface *> PictureCacheType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PictureCacheLookup;
@@ -198,11 +201,12 @@ private:
typedef Common::HashMap<Common::String, Character *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> CharactersType;
typedef Common::HashMap<int, Font *> FontsType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> DialogDefsType;
+ typedef Common::HashMap<Common::String, PatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PatchesType;
const ADGameDescription * _gameDescription;
ResourceManager _resourceManager;
SoundManager _soundManager;
- Database _data, _patch; //data and patch databases
+ Database _data;
PictureCacheType _pictureCache;
PictureCacheLookup _pictureCacheLookup;
int _pictureCacheId;
@@ -210,6 +214,7 @@ private:
AnimationsType _animations;
CharactersType _characters;
ProcessListType _processes;
+ PatchesType _patches;
int _sharedStorageIndex;
Common::String _sharedStorage[10];
GlobalsType _globals;
diff --git a/engines/agds/character.h b/engines/agds/character.h
index e6908d691ab..0f7701cdee9 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -29,7 +29,6 @@
namespace Common { class SeekableReadStream; }
namespace Graphics { struct Surface; }
-namespace Video { class FlicDecoder; }
namespace AGDS {
diff --git a/engines/agds/database.cpp b/engines/agds/database.cpp
index 599e28ab2c7..d15b750aa2e 100644
--- a/engines/agds/database.cpp
+++ b/engines/agds/database.cpp
@@ -71,6 +71,14 @@ bool Database::open(const Common::String &filename, Common::SeekableReadStream *
return true;
}
+Common::Array<Common::String> Database::getEntries() const {
+ Common::Array<Common::String> names;
+ for(EntriesType::const_iterator i = _entries.begin(); i != _entries.end(); ++i) {
+ names.push_back(i->_key);
+ }
+ return names;
+}
+
Common::SeekableReadStream *Database::getEntry(const Common::String &name) const {
Common::File file;
if (!file.open(_filename)) {
diff --git a/engines/agds/database.h b/engines/agds/database.h
index 999e348e298..51f7764f0b8 100644
--- a/engines/agds/database.h
+++ b/engines/agds/database.h
@@ -55,6 +55,7 @@ private:
public:
bool open(const Common::String &filename);
bool open(const Common::String &filename, Common::SeekableReadStream *stream);
+ Common::Array<Common::String> getEntries() const;
Common::SeekableReadStream * getEntry(const Common::String &name) const;
Common::SeekableReadStream *getEntry(Common::SeekableReadStream *parent, const Common::String &name) const;
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index 3d35f85a195..3a003dfb1e1 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -10,6 +10,7 @@ MODULE_OBJS := \
inventory.o \
mjpgPlayer.o \
object.o \
+ patch.o \
process.o \
process_opcodes.o \
region.o \
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
new file mode 100644
index 00000000000..496cdcb96bc
--- /dev/null
+++ b/engines/agds/patch.cpp
@@ -0,0 +1,39 @@
+#include "agds/patch.h"
+#include "agds/resourceManager.h"
+#include "common/stream.h"
+#include "common/debug.h"
+#include "common/error.h"
+
+namespace AGDS {
+
+void Patch::load(Common::SeekableReadStream *stream) {
+ bool regionNameValid = stream->readByte();
+ if (regionNameValid) {
+ screenRegionName = readString(stream);
+ } else {
+ stream->skip(32);
+ }
+ prevScreenName = readString(stream);
+ unk41 = stream->readUint32LE();
+ characterX = stream->readUint32LE();
+ characterY = stream->readUint32LE();
+ characterDirection = stream->readUint32LE();
+ unk51 = stream->readUint32LE();
+ debug("unknown entries: %u (character at %u,%u with dir: %u) %u", unk41, characterX, characterY, characterDirection, unk51);
+ uint object_count = stream->readUint32LE();
+ debug("objects in this patch: %u", object_count);
+ if (stream->read(palette, sizeof(palette)) != sizeof(palette)) {
+ error("short read, can't read palette");
+ }
+
+ defaultMousePointerName = readString(stream);
+ debug("default pointer name: %s", defaultMousePointerName.c_str());
+ objects.clear();
+ for(uint i = 0; i < object_count; ++i) {
+ int flag = stream->readSint16LE();
+ Common::String name = readString(stream);
+ debug("object %s, status: %d", name.c_str(), flag);
+ }
+}
+
+}
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
new file mode 100644
index 00000000000..6ce3772a616
--- /dev/null
+++ b/engines/agds/patch.h
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_PATCH_H
+#define AGDS_PATCH_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/str.h"
+
+namespace Common { class SeekableReadStream; }
+
+namespace AGDS {
+
+class AGDSEngine;
+class Object;
+
+struct Patch {
+ struct Object {
+ Common::String name;
+ uint32 flag;
+ };
+
+ Common::String screenRegionName;
+ Common::String prevScreenName;
+
+ uint unk41;
+ uint characterX;
+ uint characterY;
+ uint characterDirection;
+ uint unk51;
+
+ byte palette[0x300];
+ Common::String defaultMousePointerName;
+ Common::Array<Object> objects;
+
+ void load(Common::SeekableReadStream *stream);
+};
+
+
+} // End of namespace AGDS
+
+#endif /* AGDS_PATCH_H */
Commit: dacf2ad6d0faba37a1f4307336451f6cae8e24fa
https://github.com/scummvm/scummvm/commit/dacf2ad6d0faba37a1f4307336451f6cae8e24fa
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:16+01:00
Commit Message:
AGDS: add russian language detection (steam version)
Changed paths:
engines/agds/detection_tables.h
diff --git a/engines/agds/detection_tables.h b/engines/agds/detection_tables.h
index 9c0a8ada89b..0a37032852f 100644
--- a/engines/agds/detection_tables.h
+++ b/engines/agds/detection_tables.h
@@ -34,6 +34,15 @@ static const ADGameDescription gameDescriptions[] = {
ADGF_DROPPLATFORM,
GUIO1(GUIO_NONE)
},
+ {
+ "black-mirror",
+ 0,
+ AD_ENTRY1s("gfx1.grp", "652f931f02c5a79fb9bcbe32abafbdf7", 907732355),
+ Common::RU_RUS,
+ Common::kPlatformWindows,
+ ADGF_DROPPLATFORM,
+ GUIO1(GUIO_NONE)
+ },
{
"nibiru",
Commit: 43833892db90763aeb80802f2cdb967fd5a66dd5
https://github.com/scummvm/scummvm/commit/43833892db90763aeb80802f2cdb967fd5a66dd5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:16+01:00
Commit Message:
AGDS: allow previousScreenName to be used
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 8b46ef27483..3ce0edd20fe 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -194,6 +194,7 @@ void AGDSEngine::setCurrentScreen(Screen *screen) {
_currentScreenName = screen->getName();
_currentScreen = screen;
_previousScreen = NULL;
+ _previousScreenName.clear();
}
void AGDSEngine::resetCurrentScreen() {
@@ -206,6 +207,7 @@ void AGDSEngine::resetCurrentScreen() {
if (_currentScreen != _previousScreen) //we didnt come from back command, fixme: refactor it
delete _currentScreen;
_currentScreen = NULL;
+ _currentScreenName.clear();
}
void AGDSEngine::runProcess(ProcessListType::iterator &it) {
@@ -251,12 +253,18 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
if (_currentScreen) {
delete _previousScreen;
_previousScreen = _currentScreen;
+ _previousScreenName = _currentScreenName;
}
loadScreen(process.getExitArg1());
destroy = true;
break;
case kExitCodeLoadPreviousScreenObject:
- setCurrentScreen(_previousScreen);
+ if (_previousScreen)
+ setCurrentScreen(_previousScreen);
+ else if (!_previousScreenName.empty()) {
+ loadScreen(_previousScreenName);
+ _previousScreenName.clear();
+ }
break;
case kExitCodeMouseAreaChange:
changeMouseArea(process.getExitIntArg1(), process.getExitIntArg2());
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index ce1af378280..8130a4f0c14 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -225,6 +225,7 @@ private:
Screen * _currentScreen;
Common::String _currentScreenName;
Screen * _previousScreen;
+ Common::String _previousScreenName;
Animation * _defaultMouseCursor;
Common::Point _mouse;
MouseRegion * _currentRegion;
Commit: 6a146d750f30773dfc856aded507acc2e84b0cc7
https://github.com/scummvm/scummvm/commit/6a146d750f30773dfc856aded507acc2e84b0cc7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:16+01:00
Commit Message:
AGDS: handle object patches
Changed paths:
engines/agds/patch.cpp
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index 496cdcb96bc..aad2d6df72c 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -7,13 +7,19 @@
namespace AGDS {
void Patch::load(Common::SeekableReadStream *stream) {
- bool regionNameValid = stream->readByte();
- if (regionNameValid) {
- screenRegionName = readString(stream);
- } else {
- stream->skip(32);
+ byte extended = stream->readByte();
+ if (extended != 1 && extended != 0) {
+ Common::String prototype = (char)extended + readString(stream, 31);
+ Common::String unk = readString(stream);
+ debug("patch for object: %s %s", prototype.c_str(), unk.c_str());
+ return;
}
+
+ screenRegionName = readString(stream);
prevScreenName = readString(stream);
+ if (extended == 0)
+ return;
+
unk41 = stream->readUint32LE();
characterX = stream->readUint32LE();
characterY = stream->readUint32LE();
Commit: 7774d6c632d1a443556a03bda961d58d9d2cf4b2
https://github.com/scummvm/scummvm/commit/7774d6c632d1a443556a03bda961d58d9d2cf4b2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:16+01:00
Commit Message:
AGDS: process objects specified in patch
Changed paths:
engines/agds/agds.cpp
engines/agds/patch.cpp
engines/agds/patch.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3ce0edd20fe..c311a3e7252 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -183,6 +183,23 @@ void AGDSEngine::loadScreen(const Common::String &name) {
_currentScreen = new Screen(loadObject(name), _mouseMap);
_mouseMap.clear();
runObject(_currentScreen->getObject()); //is it called once or per screen activation?
+
+ PatchesType::const_iterator it = _patches.find(name);
+ if (it == _patches.end())
+ return;
+
+ debug("found patch");
+ PatchPtr patch = it->_value;
+ const Common::Array<Patch::Object> &objects = patch->objects;
+ for(uint i = 0; i < objects.size(); ++i) {
+ const Patch::Object &object = objects[i];
+ if (object.flag <= 0)
+ _currentScreen->remove(object.name);
+ else if (!_currentScreen->find(object.name)) {
+ runObject(object.name);
+ }
+ }
+ loadDefaultMouseCursor(patch->defaultMouseCursor);
}
void AGDSEngine::setCurrentScreen(Screen *screen) {
@@ -529,6 +546,7 @@ int AGDSEngine::getGlobal(const Common::String &name) const {
}
Animation *AGDSEngine::loadAnimation(const Common::String &name) {
+ debug("loadAnimation %s", name.c_str());
AnimationsType::iterator i = _animations.find(name);
if (i != _animations.end())
return i->_value;
@@ -910,6 +928,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
SystemVariable *initVar = getSystemVariable("init_resources");
runObject(initVar->getString());
+ loadPatches(file, db);
loadScreen(screenName);
{
@@ -929,7 +948,6 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
}
}
}
- loadPatches(file, db);
return Common::kNoError;
}
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index aad2d6df72c..aa4509e0799 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -32,8 +32,8 @@ void Patch::load(Common::SeekableReadStream *stream) {
error("short read, can't read palette");
}
- defaultMousePointerName = readString(stream);
- debug("default pointer name: %s", defaultMousePointerName.c_str());
+ defaultMouseCursor = readString(stream);
+ debug("default pointer name: %s", defaultMouseCursor.c_str());
objects.clear();
for(uint i = 0; i < object_count; ++i) {
int flag = stream->readSint16LE();
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index 6ce3772a616..da3ad9c4494 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -50,7 +50,7 @@ struct Patch {
uint unk51;
byte palette[0x300];
- Common::String defaultMousePointerName;
+ Common::String defaultMouseCursor;
Common::Array<Object> objects;
void load(Common::SeekableReadStream *stream);
Commit: d549134665c3e0f1554dc9f9d973ee8517fe046a
https://github.com/scummvm/scummvm/commit/d549134665c3e0f1554dc9f9d973ee8517fe046a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:16+01:00
Commit Message:
AGDS: debug logs in patch
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c311a3e7252..cce1bb0407b 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -188,11 +188,12 @@ void AGDSEngine::loadScreen(const Common::String &name) {
if (it == _patches.end())
return;
- debug("found patch");
PatchPtr patch = it->_value;
const Common::Array<Patch::Object> &objects = patch->objects;
+ debug("found patch with %u objects", objects.size());
for(uint i = 0; i < objects.size(); ++i) {
const Patch::Object &object = objects[i];
+ debug("patch object %s %d", object.name.c_str(), object.flag);
if (object.flag <= 0)
_currentScreen->remove(object.name);
else if (!_currentScreen->find(object.name)) {
Commit: f52cdfc5833608307e05d4545da40a693281ebee
https://github.com/scummvm/scummvm/commit/f52cdfc5833608307e05d4545da40a693281ebee
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:16+01:00
Commit Message:
AGDS: actually push object to patch
Changed paths:
engines/agds/patch.cpp
engines/agds/patch.h
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index aa4509e0799..ab095a7034b 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -38,7 +38,7 @@ void Patch::load(Common::SeekableReadStream *stream) {
for(uint i = 0; i < object_count; ++i) {
int flag = stream->readSint16LE();
Common::String name = readString(stream);
- debug("object %s, status: %d", name.c_str(), flag);
+ objects.push_back(Object(name, flag));
}
}
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index da3ad9c4494..35fb1e318b8 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -37,7 +37,9 @@ class Object;
struct Patch {
struct Object {
Common::String name;
- uint32 flag;
+ int flag;
+
+ Object(const Common::String &n, int f): name(n), flag(f) {}
};
Common::String screenRegionName;
Commit: fbea702a40a7b08225966e8d09cd649940035535
https://github.com/scummvm/scummvm/commit/fbea702a40a7b08225966e8d09cd649940035535
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:17+01:00
Commit Message:
AGDS: implemented exitprocesscreatepatch (actually reinitialisation of the game)
Changed paths:
engines/agds/agds.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index cce1bb0407b..2e6a707ca01 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -293,9 +293,21 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
case kExitCodeSuspend:
break;
case kExitCodeCreatePatchLoadResources:
- runObject(process.getExitArg1());
- _inventory.clear();
- runObject(process.getExitArg2());
+ {
+ debug("exitProcessCreatePatch");
+
+ SystemVariable *doneVar = getSystemVariable("done_resources");
+ Common::String done = doneVar->getString();
+ runObject(done);
+
+ _patches.clear();
+ _inventory.clear();
+ _globals.clear();
+
+ SystemVariable *initVar = getSystemVariable("init_resources");
+ Common::String init = initVar->getString();
+ runObject(init);
+ }
break;
case kExitCodeLoadSaveGame:
loadGameState(process.getExitIntArg1());
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 5cf7d0a4a35..fe4fe98d798 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -846,14 +846,7 @@ void Process::exitProcess() {
}
void Process::exitProcessCreatePatch() {
- SystemVariable *initVar = _engine->getSystemVariable("init_resources");
- Common::String init = initVar->getString();
-
- SystemVariable *doneVar = _engine->getSystemVariable("done_resources");
- Common::String done = doneVar->getString();
-
- debug("exitProcessCreatePatch stub, resource objects: %s %s", done.c_str(), init.c_str());
- suspend(kExitCodeCreatePatchLoadResources, done, init);
+ suspend(kExitCodeCreatePatchLoadResources);
}
void Process::clearScreen() {
Commit: e2a8a0bb99e6c2960cdb6607e3e6044a9f5e05a5
https://github.com/scummvm/scummvm/commit/e2a8a0bb99e6c2960cdb6607e3e6044a9f5e05a5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:17+01:00
Commit Message:
AGDS: move mousemap/region code to separate files
Changed paths:
A engines/agds/mouseMap.cpp
A engines/agds/mouseMap.h
engines/agds/module.mk
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index 3a003dfb1e1..e70cc3dffbb 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -9,6 +9,7 @@ MODULE_OBJS := \
font.o \
inventory.o \
mjpgPlayer.o \
+ mouseMap.o \
object.o \
patch.o \
process.o \
diff --git a/engines/agds/mouseMap.cpp b/engines/agds/mouseMap.cpp
new file mode 100644
index 00000000000..ee4f53bda53
--- /dev/null
+++ b/engines/agds/mouseMap.cpp
@@ -0,0 +1,38 @@
+#include "agds/mouseMap.h"
+#include "agds/region.h"
+
+namespace AGDS {
+
+MouseRegion *MouseMap::find(Common::Point pos) {
+ if (_disabled)
+ return NULL;
+ for (MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i) {
+ MouseRegion &mouse = *i;
+ if (mouse.enabled && mouse.region->pointIn(pos))
+ return &mouse;
+ }
+ return NULL;
+}
+
+MouseRegion *MouseMap::find(int id) {
+ for (MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i) {
+ MouseRegion &mouse = *i;
+ if (mouse.id == id)
+ return &mouse;
+ }
+ return NULL;
+}
+
+void MouseMap::remove(int id) {
+ for (MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end();) {
+ MouseRegion &mouse = *i;
+ if (mouse.id == id)
+ i = _mouseRegions.erase(i);
+ else
+ ++i;
+ }
+}
+
+
+} // End of namespace AGDS
+
diff --git a/engines/agds/mouseMap.h b/engines/agds/mouseMap.h
new file mode 100644
index 00000000000..0206d226986
--- /dev/null
+++ b/engines/agds/mouseMap.h
@@ -0,0 +1,91 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_MOUSE_MAP_H
+#define AGDS_MOUSE_MAP_H
+
+#include "common/list.h"
+#include "common/ptr.h"
+#include "common/rect.h"
+#include "common/str.h"
+
+namespace AGDS {
+
+struct Region;
+typedef Common::SharedPtr<Region> RegionPtr;
+
+struct MouseRegion {
+ int id;
+ RegionPtr region;
+ int enabled;
+ bool currentlyIn;
+
+ Common::String onEnter;
+ Common::String onLeave;
+
+ void enable() {
+ ++enabled;
+ }
+
+ void disable() {
+ if (enabled > 0)
+ --enabled;
+ }
+
+ MouseRegion(RegionPtr reg, const Common::String &enter, const Common::String &leave):
+ id(-1), region(reg), enabled(1), currentlyIn(false), onEnter(enter), onLeave(leave) {
+ }
+};
+
+class MouseMap {
+ typedef Common::List<MouseRegion> MouseRegionsType;
+ MouseRegionsType _mouseRegions;
+ int _nextId;
+ bool _disabled;
+
+public:
+ MouseMap(): _nextId(0), _disabled(false) { }
+
+ void disable(bool disabled) {
+ _disabled = disabled;
+ }
+
+ bool disabled() const {
+ return _disabled;
+ }
+
+ int add(const MouseRegion & area) {
+ _mouseRegions.push_back(area);
+ _mouseRegions.back().id = _nextId++;
+ return _mouseRegions.back().id;
+ }
+ void clear() {
+ _mouseRegions.clear();
+ }
+ MouseRegion * find(Common::Point pos);
+ MouseRegion * find(int id);
+ void remove(int id);
+};
+
+} // End of namespace AGDS
+
+#endif /* AGDS_SCREEN_H */
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 0c54c80334d..48f5bf241a8 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -93,7 +93,6 @@ bool Screen::remove(const Common::String &name) {
void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
ChildrenType::iterator child = _children.begin();
AnimationsType::iterator animation = _animations.begin();
- int idx = 0;
while(child != _children.end() || animation != _animations.end()) {
bool child_valid = child != _children.end();
bool animation_valid = animation != _animations.end();
@@ -143,34 +142,4 @@ Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
return keyHandler;
}
-MouseRegion *MouseMap::find(Common::Point pos) {
- if (_disabled)
- return NULL;
- for (MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i) {
- MouseRegion &mouse = *i;
- if (mouse.enabled && mouse.region->pointIn(pos))
- return &mouse;
- }
- return NULL;
-}
-
-MouseRegion *MouseMap::find(int id) {
- for (MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i) {
- MouseRegion &mouse = *i;
- if (mouse.id == id)
- return &mouse;
- }
- return NULL;
-}
-
-void MouseMap::remove(int id) {
- for (MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end();) {
- MouseRegion &mouse = *i;
- if (mouse.id == id)
- i = _mouseRegions.erase(i);
- else
- ++i;
- }
-}
-
} // namespace AGDS
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 597c20d031e..5d61665a963 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -25,10 +25,10 @@
#include "common/scummsys.h"
#include "common/array.h"
-#include "common/list.h"
#include "common/ptr.h"
#include "common/str.h"
#include "common/rect.h"
+#include "agds/mouseMap.h"
namespace Graphics {
struct Surface;
@@ -43,61 +43,6 @@ typedef Common::SharedPtr<Object> ObjectPtr;
struct Region;
typedef Common::SharedPtr<Region> RegionPtr;
-
-struct MouseRegion {
- int id;
- RegionPtr region;
- int enabled;
- bool currentlyIn;
-
- Common::String onEnter;
- Common::String onLeave;
-
- void enable() {
- ++enabled;
- }
-
- void disable() {
- if (enabled > 0)
- --enabled;
- }
-
- MouseRegion(RegionPtr reg, const Common::String &enter, const Common::String &leave):
- id(-1), region(reg), enabled(1), currentlyIn(false), onEnter(enter), onLeave(leave) {
- }
-};
-
-//fixme: move me away
-class MouseMap {
- typedef Common::List<MouseRegion> MouseRegionsType;
- MouseRegionsType _mouseRegions;
- int _nextId;
- bool _disabled;
-
-public:
- MouseMap(): _nextId(0), _disabled(false) { }
-
- void disable(bool disabled) {
- _disabled = disabled;
- }
-
- bool disabled() const {
- return _disabled;
- }
-
- int add(const MouseRegion & area) {
- _mouseRegions.push_back(area);
- _mouseRegions.back().id = _nextId++;
- return _mouseRegions.back().id;
- }
- void clear() {
- _mouseRegions.clear();
- }
- MouseRegion * find(Common::Point pos);
- MouseRegion * find(int id);
- void remove(int id);
-};
-
class Screen {
static int ObjectZCompare(const ObjectPtr & a, const ObjectPtr & b);
static int AnimationZCompare(const Animation *a, const Animation *b);
Commit: ed05d0cd0b5ce80709cee9496d7c593f0386d83b
https://github.com/scummvm/scummvm/commit/ed05d0cd0b5ce80709cee9496d7c593f0386d83b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:17+01:00
Commit Message:
AGDS: clear mouse map and call done if exists
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 2e6a707ca01..e16d584e36f 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -878,6 +878,11 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
}
}
+ SystemVariable *doneVar = getSystemVariable("done_resources");
+ Common::String done = doneVar->getString();
+ if (!done.empty())
+ runObject(done);
+
{
// Current character
Common::ScopedPtr<Common::SeekableReadStream> agds_c(db.getEntry(file, "__agds_c"));
@@ -938,6 +943,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
}
}
+ _mouseMap.clear();
SystemVariable *initVar = getSystemVariable("init_resources");
runObject(initVar->getString());
Commit: 1ea7540714aec40354d8681dd70bba8efb041b3a
https://github.com/scummvm/scummvm/commit/1ea7540714aec40354d8681dd70bba8efb041b3a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:17+01:00
Commit Message:
AGDS: fix mouse area leftovers
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index e16d584e36f..edddc19e951 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -943,10 +943,10 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
}
}
- _mouseMap.clear();
SystemVariable *initVar = getSystemVariable("init_resources");
runObject(initVar->getString());
+ _mouseMap.clear();
loadPatches(file, db);
loadScreen(screenName);
Commit: b7ab93bf719d4928b8508f46aa7cef1a941b254b
https://github.com/scummvm/scummvm/commit/b7ab93bf719d4928b8508f46aa7cef1a941b254b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:17+01:00
Commit Message:
AGDS: remove override for now
Changed paths:
engines/agds/agds.h
engines/agds/detection.cpp
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 8130a4f0c14..46966173053 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -96,8 +96,8 @@ public:
bool hasFeature(EngineFeature f) const;
Common::Error loadGameStream(Common::SeekableReadStream *file);
Common::Error saveGameStream(Common::WriteStream *file, bool isAutosave);
- bool canLoadGameStateCurrently() override { return true; }
- bool canSaveGameStateCurrently() override { return _userEnabled; }
+ bool canLoadGameStateCurrently() { return true; }
+ bool canSaveGameStateCurrently() { return _userEnabled; }
ObjectPtr loadObject(const Common::String & name, const Common::String & prototype = Common::String());
void runObject(ObjectPtr object);
diff --git a/engines/agds/detection.cpp b/engines/agds/detection.cpp
index 6a21c51a17c..d4253186e45 100644
--- a/engines/agds/detection.cpp
+++ b/engines/agds/detection.cpp
@@ -38,11 +38,11 @@ public:
_maxScanDepth = 3;
}
- const char *getEngineId() const override {
+ const char *getEngineId() const {
return "agds";
}
- const char *getName() const override {
+ const char *getName() const {
return "AGDS Engine";
}
@@ -51,7 +51,7 @@ public:
}
bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
- bool hasFeature(MetaEngineFeature f) const override {
+ bool hasFeature(MetaEngineFeature f) const {
switch (f) {
case kSupportsListSaves:
case kSupportsLoadingDuringStartup:
@@ -65,12 +65,12 @@ public:
}
}
- int getMaximumSaveSlot() const override {
+ int getMaximumSaveSlot() const {
return 99;
}
};
-bool AGDSMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override {
+bool AGDSMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
if (desc) {
*engine = new AGDS::AGDSEngine(syst, desc);
}
Commit: 1cbaa5f126e67e4055a14e61556c91e74063def8
https://github.com/scummvm/scummvm/commit/1cbaa5f126e67e4055a14e61556c91e74063def8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:17+01:00
Commit Message:
AGDS: fix opcode 166 (changeScreenPatch), return patch status instead of process status
Changed paths:
engines/agds/agds.cpp
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process.cpp
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index edddc19e951..7bcd9a3b5e5 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -162,7 +162,7 @@ void AGDSEngine::runObject(ObjectPtr object) {
}
void AGDSEngine::runProcess(ObjectPtr object, uint ip, Process *caller) {
- object->activate(true);
+ object->inScene(true);
_processes.push_front(Process(this, object, ip, caller));
ProcessListType::iterator it = _processes.begin();
runProcess(it);
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 69fc19c7a20..9b54cd19acb 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -38,7 +38,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_animation(), _mouseCursor(),
_pos(), _z(10),
_clickHandler(0), _examineHandler(0),
- _alpha(255), _active(false) {
+ _alpha(255), _inScene(false) {
byte id = stream->readUint16LE();
debug("id: 0x%02x %u", id, id);
diff --git a/engines/agds/object.h b/engines/agds/object.h
index a8becaecc9d..42bd9bb7738 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -74,7 +74,7 @@ private:
uint _clickHandler;
uint _examineHandler;
int _alpha;
- bool _active;
+ bool _inScene;
public:
Object(const Common::String &name, Common::SeekableReadStream * stream);
@@ -190,11 +190,11 @@ public:
return i != _keyHandlers.end()? i->_value: 0;
}
- bool isActive() const
- { return _active; }
+ bool inScene() const
+ { return _inScene; }
- void activate(bool active)
- { _active = active; }
+ void inScene(bool value)
+ { _inScene = value; }
};
typedef Common::SharedPtr<Object> ObjectPtr;
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 6191069ae67..15639f812bd 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -102,7 +102,6 @@ Common::String Process::popText() {
void Process::activate(bool active) {
if (active) {
- _object->activate(active);
switch (_status) {
case kStatusActive:
break;
@@ -117,8 +116,6 @@ void Process::activate(bool active) {
if (_caller) {
debug("returning to caller");
_caller->_waitForCall = false;
- } else {
- _object->activate(false);
}
}
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index fe4fe98d798..7c697362f2e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -456,7 +456,8 @@ void Process::changeScreenPatch() {
} else {
//change screen patch (load and return 1)
ObjectPtr object = screen->find(objectName);
- int value = object && object->isActive();
+ int value = object && object->inScene();
+ debug("\t%d", value);
push(value);
}
}
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 48f5bf241a8..cbc88756aae 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -71,6 +71,7 @@ bool Screen::remove(const ObjectPtr &object) {
for (ChildrenType::iterator i = _children.begin(); i != _children.end();) {
if (*i == object) {
i = _children.erase(i);
+ object->inScene(false);
found = true;
} else
++i;
@@ -81,7 +82,9 @@ bool Screen::remove(const ObjectPtr &object) {
bool Screen::remove(const Common::String &name) {
bool found = false;
for (ChildrenType::iterator i = _children.begin(); i != _children.end();) {
- if ((*i)->getName() == name) {
+ const ObjectPtr & object = *i;
+ if (object->getName() == name) {
+ object->inScene(false);
i = _children.erase(i);
found = true;
} else
Commit: 1b698ff9e1b477848dbef7ad575e4923a693ba39
https://github.com/scummvm/scummvm/commit/1b698ff9e1b477848dbef7ad575e4923a693ba39
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:17+01:00
Commit Message:
AGDS: reworked mouse map, remove it from screen
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/mouseMap.cpp
engines/agds/mouseMap.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 7bcd9a3b5e5..6141b149f54 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -178,10 +178,11 @@ void AGDSEngine::runObject(const Common::String &name, const Common::String &pro
void AGDSEngine::loadScreen(const Common::String &name) {
debug("loadScreen %s", name.c_str());
resetCurrentScreen();
+
+ _mouseMap.hideAll(this);
_soundManager.stopAll();
_currentScreenName = name;
- _currentScreen = new Screen(loadObject(name), _mouseMap);
- _mouseMap.clear();
+ _currentScreen = new Screen(loadObject(name));
runObject(_currentScreen->getObject()); //is it called once or per screen activation?
PatchesType::const_iterator it = _patches.find(name);
@@ -217,8 +218,7 @@ void AGDSEngine::setCurrentScreen(Screen *screen) {
void AGDSEngine::resetCurrentScreen() {
if (_currentRegion) {
- if (_currentRegion->currentlyIn)
- runObject(_currentRegion->onLeave);
+ _currentRegion->hide(this);
_currentRegion = NULL;
}
@@ -341,8 +341,10 @@ Animation *AGDSEngine::loadMouseCursor(const Common::String &name) {
}
void AGDSEngine::changeMouseArea(int id, int enabled) {
- if (id < 0)
+ if (id < 0) {
+ warning("invalid mouse area %d", id);
return;
+ }
MouseRegion *mouseArea = _mouseMap.find(id);
if (mouseArea) {
@@ -353,15 +355,22 @@ void AGDSEngine::changeMouseArea(int id, int enabled) {
break;
case 0:
debug("disabling mouse area %d", id);
- if (mouseArea->currentlyIn) {
- runObject(mouseArea->onLeave);
+ if (_currentRegion && _currentRegion->id) {
+ _currentRegion->hide(this);
+ _currentRegion = NULL;
}
- mouseArea->disable();
+ mouseArea->disable(this);
break;
case -1:
debug("removing mouse area %d", id);
- _mouseMap.remove(id);
+ if (_currentRegion && _currentRegion->id) {
+ _currentRegion->hide(this);
+ _currentRegion = NULL;
+ }
+ _mouseMap.remove(this, id);
break;
+ default:
+ warning("invalid value for changeMouseArea: %d", enabled);
}
} else
warning("mouse area %d could not be found", id);
@@ -421,22 +430,20 @@ Common::Error AGDSEngine::run() {
case Common::EVENT_MOUSEMOVE:
_mouse = event.mouse;
if (_userEnabled) {
- MouseMap &mouseMap = _currentScreen->mouseMap();
- MouseRegion *region = mouseMap.find(_mouse);
+ MouseRegion *region = _mouseMap.find(_mouse);
if (region != _currentRegion) {
if (_currentRegion) {
MouseRegion *currentRegion = _currentRegion;
_currentRegion = NULL;
- currentRegion->currentlyIn = false;
- runObject(currentRegion->onLeave);
+ currentRegion->hide(this);
}
+
if (region) {
_currentRegion = region;
- _currentRegion->currentlyIn = true;
- runObject(region->onEnter);
+ region->show(this);
}
}
- _inventory.enable(_inventoryRegion ? !mouseMap.disabled() && _inventoryRegion->pointIn(_mouse) : false);
+ _inventory.enable(_inventoryRegion ? !_mouseMap.disabled() && _inventoryRegion->pointIn(_mouse) : false);
}
break;
case Common::EVENT_LBUTTONDOWN:
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 46966173053..d89dbee5f64 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -32,6 +32,7 @@
#include "agds/soundManager.h"
#include "agds/database.h"
#include "agds/inventory.h"
+#include "agds/mouseMap.h"
#include "agds/processExitCode.h"
#include "agds/resourceManager.h"
#include "agds/screen.h"
diff --git a/engines/agds/mouseMap.cpp b/engines/agds/mouseMap.cpp
index ee4f53bda53..2e55dd258fc 100644
--- a/engines/agds/mouseMap.cpp
+++ b/engines/agds/mouseMap.cpp
@@ -1,8 +1,17 @@
#include "agds/mouseMap.h"
+#include "agds/agds.h"
#include "agds/region.h"
+#include "agds/object.h"
namespace AGDS {
+int MouseMap::add(const MouseRegion & area) {
+ int id = _nextId++;
+ _mouseRegions.push_back(area);
+ _mouseRegions.back().id = id;
+ return id;
+}
+
MouseRegion *MouseMap::find(Common::Point pos) {
if (_disabled)
return NULL;
@@ -23,16 +32,39 @@ MouseRegion *MouseMap::find(int id) {
return NULL;
}
-void MouseMap::remove(int id) {
+void MouseMap::remove(AGDSEngine *engine, int id) {
for (MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end();) {
MouseRegion &mouse = *i;
- if (mouse.id == id)
+ if (mouse.id == id) {
+ i->disable(engine);
i = _mouseRegions.erase(i);
- else
+ } else
++i;
}
}
+void MouseRegion::show(AGDSEngine *engine) {
+ if (visible)
+ return;
+
+ visible = true;
+ debug("calling mouseArea[%d].onEnter...", id);
+ engine->runObject(onEnter);
+}
+
+void MouseRegion::hide(AGDSEngine *engine) {
+ if (!visible)
+ return;
+
+ visible = false;
+ debug("calling mouseArea[%d].onLeave...", id);
+ engine->runObject(onLeave);
+}
+
+void MouseMap::hideAll(AGDSEngine *engine) {
+ for (MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i)
+ i->hide(engine);
+}
} // End of namespace AGDS
diff --git a/engines/agds/mouseMap.h b/engines/agds/mouseMap.h
index 0206d226986..182aa9ec46a 100644
--- a/engines/agds/mouseMap.h
+++ b/engines/agds/mouseMap.h
@@ -30,30 +30,34 @@
namespace AGDS {
+class AGDSEngine;
struct Region;
typedef Common::SharedPtr<Region> RegionPtr;
struct MouseRegion {
int id;
RegionPtr region;
- int enabled;
- bool currentlyIn;
+ bool enabled;
+ bool visible;
Common::String onEnter;
Common::String onLeave;
void enable() {
- ++enabled;
+ enabled = true;
}
- void disable() {
- if (enabled > 0)
- --enabled;
+ void disable(AGDSEngine *engine) {
+ enabled = false;
+ hide(engine);
}
MouseRegion(RegionPtr reg, const Common::String &enter, const Common::String &leave):
- id(-1), region(reg), enabled(1), currentlyIn(false), onEnter(enter), onLeave(leave) {
+ id(-1), region(reg), enabled(1), visible(false), onEnter(enter), onLeave(leave) {
}
+
+ void hide(AGDSEngine * engine);
+ void show(AGDSEngine * engine);
};
class MouseMap {
@@ -65,25 +69,26 @@ class MouseMap {
public:
MouseMap(): _nextId(0), _disabled(false) { }
- void disable(bool disabled) {
+ void disable(AGDSEngine * engine, bool disabled) {
_disabled = disabled;
+ if (disabled)
+ hideAll(engine);
}
bool disabled() const {
return _disabled;
}
- int add(const MouseRegion & area) {
- _mouseRegions.push_back(area);
- _mouseRegions.back().id = _nextId++;
- return _mouseRegions.back().id;
- }
+ int add(const MouseRegion & area);
+ void remove(AGDSEngine *engine, int id);
+
+ void hideAll(AGDSEngine *engine);
+
void clear() {
_mouseRegions.clear();
}
MouseRegion * find(Common::Point pos);
MouseRegion * find(int id);
- void remove(int id);
};
} // End of namespace AGDS
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 7c697362f2e..62445c8b20f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -688,7 +688,7 @@ void Process::setObjectScale() {
void Process::disableMouseAreas() {
int value = pop();
debug("disableMouseAreas %d", value);
- _engine->_mouseMap.disable(value > 0);
+ _engine->_mouseMap.disable(_engine, value > 0);
}
void Process::stub194() {
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index cbc88756aae..d170c283d7d 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -35,8 +35,7 @@ int Screen::AnimationZCompare(const Animation *a, const Animation *b) {
return b->z() - a->z();
}
-Screen::Screen(ObjectPtr object, const MouseMap &mouseMap) : _object(object), _name(object->getName()), _mouseMap(mouseMap),
- _children(&ObjectZCompare), _animations(&AnimationZCompare) {
+Screen::Screen(ObjectPtr object) : _object(object), _name(object->getName()), _children(&ObjectZCompare), _animations(&AnimationZCompare) {
add(object);
}
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 5d61665a963..3482ce304d6 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -28,7 +28,6 @@
#include "common/ptr.h"
#include "common/str.h"
#include "common/rect.h"
-#include "agds/mouseMap.h"
namespace Graphics {
struct Surface;
@@ -54,7 +53,6 @@ class Screen {
Common::String _name;
ChildrenType _children;
AnimationsType _animations;
- MouseMap _mouseMap;
RegionPtr _region;
public:
@@ -66,7 +64,7 @@ public:
KeyHandler(Object *o, uint i): object(o), ip(i) { }
};
- Screen(ObjectPtr object, const MouseMap &mouseMap);
+ Screen(ObjectPtr object);
~Screen();
ObjectPtr getObject() {
@@ -77,10 +75,6 @@ public:
return _name;
}
- MouseMap & mouseMap() {
- return _mouseMap;
- }
-
RegionPtr region() const {
return _region;
}
Commit: 757c20f5cc7e4071341474048f5bda966cce74f1
https://github.com/scummvm/scummvm/commit/757c20f5cc7e4071341474048f5bda966cce74f1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:17+01:00
Commit Message:
AGDS: reimplement scheduler
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 6141b149f54..b80ab74680a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -161,11 +161,10 @@ void AGDSEngine::runObject(ObjectPtr object) {
runProcess(object);
}
-void AGDSEngine::runProcess(ObjectPtr object, uint ip, Process *caller) {
+void AGDSEngine::runProcess(ObjectPtr object, uint ip) {
+ debug("starting process %s:%04x", object->getName().c_str(), ip);
object->inScene(true);
- _processes.push_front(Process(this, object, ip, caller));
- ProcessListType::iterator it = _processes.begin();
- runProcess(it);
+ _processes.push_front(Process(this, object, ip));
}
void AGDSEngine::runObject(const Common::String &name, const Common::String &prototype) {
@@ -183,7 +182,7 @@ void AGDSEngine::loadScreen(const Common::String &name) {
_soundManager.stopAll();
_currentScreenName = name;
_currentScreen = new Screen(loadObject(name));
- runObject(_currentScreen->getObject()); //is it called once or per screen activation?
+ runProcess(_currentScreen->getObject());
PatchesType::const_iterator it = _patches.find(name);
if (it == _patches.end())
@@ -228,30 +227,25 @@ void AGDSEngine::resetCurrentScreen() {
_currentScreenName.clear();
}
-void AGDSEngine::runProcess(ProcessListType::iterator &it) {
- Process &process = *it;
- if (process.parentScreenName() != _currentScreenName) {
- if (process.active())
- process.activate(false);
- it = _processes.erase(it);
- return;
- }
-
- if (!process.active()) {
- ++it;
- return;
- }
+void AGDSEngine::runProcess(Process &process, bool &destroy, bool &suspend) {
+ // if (process.parentScreenName() != _currentScreenName) {
+ // debug("process %s from different screen, quit", process.getName().c_str());
+ // process.activate(false);
+ // return true;
+ // }
+ suspend = false;
const Common::String &name = process.getName();
if (process.getStatus() == Process::kStatusDone || process.getStatus() == Process::kStatusError) {
debug("process %s finished", name.c_str());
process.activate(false);
- it = _processes.erase(it);
+ destroy = true;
return;
}
+
+ destroy = false;
process.activate(true);
ProcessExitCode code = process.execute();
- bool destroy = false;
switch (code) {
case kExitCodeDestroy:
destroy = true;
@@ -291,6 +285,7 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
_inventory.add(loadObject(process.getExitArg1()));
break;
case kExitCodeSuspend:
+ suspend = true;
break;
case kExitCodeCreatePatchLoadResources:
{
@@ -315,21 +310,40 @@ void AGDSEngine::runProcess(ProcessListType::iterator &it) {
default:
error("unknown process exit code %d", code);
}
- if (destroy) {
- debug("destroying process %s...", name.c_str());
- process.activate(false);
- it = _processes.erase(it);
- } else
- ++it;
}
+void AGDSEngine::runProcesses() {
+ if (_processes.empty())
+ return;
+
+ debug("enter");
+ bool destroy;
+ do {
+ for (ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
+ Process & process = *i;
+ bool suspend;
+ runProcess(process, destroy, suspend);
+ if (destroy) {
+ debug("destroying process %s...", process.getName().c_str());
+ process.activate(false);
+ i = _processes.erase(i);
+ break;
+ } else if (!suspend) {
+ break;
+ } else {
+ ++i;
+ }
+ }
+ } while (destroy && !_processes.empty());
+ debug("exit");
+}
+
+
void AGDSEngine::tick() {
if (tickDialog())
return;
tickInventory();
- for (ProcessListType::iterator p = _processes.begin(); active() && p != _processes.end();) {
- runProcess(p);
- }
+ runProcesses();
}
Animation *AGDSEngine::loadMouseCursor(const Common::String &name) {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index d89dbee5f64..e4e87cfcf5c 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -89,7 +89,8 @@ private:
void addSystemVar(const Common::String &name, SystemVariable *var);
bool initGraphics(int w, int h);
bool load();
- void runProcess(ProcessListType::iterator &it);
+ void runProcess(Process &process, bool &destroy, bool &suspend);
+ void runProcesses();
void tick();
public:
@@ -103,7 +104,7 @@ public:
ObjectPtr loadObject(const Common::String & name, const Common::String & prototype = Common::String());
void runObject(ObjectPtr object);
void runObject(const Common::String & name, const Common::String &prototype = Common::String());
- void runProcess(ObjectPtr object, uint ip = 0, Process * caller = NULL);
+ void runProcess(ObjectPtr object, uint ip = 0);
void resetCurrentScreen();
void loadScreen(const Common::String & name);
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 15639f812bd..7f84c127916 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -27,12 +27,12 @@
namespace AGDS {
-Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip, Process *caller) : _engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object), _ip(ip),
- _status(kStatusActive), _caller(caller), _exitCode(kExitCodeDestroy),
+Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) : _engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object), _ip(ip),
+ _status(kStatusActive), _exitCode(kExitCodeDestroy),
_tileWidth(16), _tileHeight(16), _tileResource(0), _tileIndex(0),
_timer(0),
- _animationCycles(1), _animationLoop(false), _animationZ(0), _animationPaused(false), _animationSpeed(100),
- _waitForCall(false) {
+ _animationCycles(1), _animationLoop(false), _animationZ(0), _animationPaused(false), _animationSpeed(100)
+ {
}
void Process::debug(const char *str, ...) {
@@ -112,11 +112,6 @@ void Process::activate(bool active) {
error("process in invalid state %d", _status);
_status = kStatusError;
}
- } else {
- if (_caller) {
- debug("returning to caller");
- _caller->_waitForCall = false;
- }
}
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 8e1444b4439..86e81a81486 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -47,7 +47,6 @@ private:
StackType _stack;
unsigned _ip, _lastIp;
Status _status;
- Process * _caller;
ProcessExitCode _exitCode;
Common::String _exitArg1, _exitArg2;
int _exitIntArg1, _exitIntArg2;
@@ -62,7 +61,6 @@ private:
int _animationZ;
bool _animationPaused;
int _animationSpeed;
- bool _waitForCall;
private:
uint8 next() {
@@ -317,7 +315,7 @@ private:
}
public:
- Process(AGDSEngine *engine, ObjectPtr object, unsigned ip = 0, Process * caller = NULL);
+ Process(AGDSEngine *engine, ObjectPtr object, unsigned ip = 0);
ObjectPtr getObject() const {
return _object;
@@ -359,13 +357,6 @@ public:
return _exitIntArg2;
}
- bool active() {
- if (_timer <= 0)
- return true;
- --_timer;
- return false;
- }
-
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 62445c8b20f..18c77448897 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1044,8 +1044,7 @@ void Process::call(uint16 addr) {
debug("call %04x", addr);
//original engine just create new process, save exit code in screen object
//and on stack, then just ignore return code, fixme?
- _waitForCall = true;
- _engine->runProcess(_object, _ip + addr, this);
+ _engine->runProcess(_object, _ip + addr);
suspend();
}
@@ -1325,7 +1324,9 @@ void Process::stub244() {
} break
ProcessExitCode Process::execute() {
- if (_waitForCall) {
+ if (_timer > 0) {
+ debug("waiting for timer (%d)...", _timer);
+ --_timer;
_exitCode = kExitCodeSuspend;
return _exitCode;
}
Commit: c4eed516cec601ff1e35f2810668c889bd42c858
https://github.com/scummvm/scummvm/commit/c4eed516cec601ff1e35f2810668c889bd42c858
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:17+01:00
Commit Message:
AGDS: call loadScreen outside of scheduler
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index b80ab74680a..c8feb793109 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -177,6 +177,15 @@ void AGDSEngine::runObject(const Common::String &name, const Common::String &pro
void AGDSEngine::loadScreen(const Common::String &name) {
debug("loadScreen %s", name.c_str());
resetCurrentScreen();
+ for(ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
+ Process &process = *i;
+ if (process.parentScreenName() != _currentScreenName) {
+ debug("process %s from different screen, destroy", process.getName().c_str());
+ process.activate(false);
+ i = _processes.erase(i);
+ } else
+ ++i;
+ }
_mouseMap.hideAll(this);
_soundManager.stopAll();
@@ -228,11 +237,6 @@ void AGDSEngine::resetCurrentScreen() {
}
void AGDSEngine::runProcess(Process &process, bool &destroy, bool &suspend) {
- // if (process.parentScreenName() != _currentScreenName) {
- // debug("process %s from different screen, quit", process.getName().c_str());
- // process.activate(false);
- // return true;
- // }
suspend = false;
const Common::String &name = process.getName();
@@ -248,6 +252,7 @@ void AGDSEngine::runProcess(Process &process, bool &destroy, bool &suspend) {
ProcessExitCode code = process.execute();
switch (code) {
case kExitCodeDestroy:
+ debug("process returned destroy exit code");
destroy = true;
break;
case kExitCodeLoadScreenObjectAs:
@@ -258,7 +263,8 @@ void AGDSEngine::runProcess(Process &process, bool &destroy, bool &suspend) {
_dialogProcessName = process.getExitArg1();
break;
case kExitCodeSetNextScreen:
- loadScreen(process.getExitArg1());
+ _nextScreenName = process.getExitArg1();
+ debug("process returned load screen/destroy exit code");
destroy = true;
break;
case kExitCodeSetNextScreenSaveInHistory:
@@ -267,14 +273,14 @@ void AGDSEngine::runProcess(Process &process, bool &destroy, bool &suspend) {
_previousScreen = _currentScreen;
_previousScreenName = _currentScreenName;
}
- loadScreen(process.getExitArg1());
+ _nextScreenName = process.getExitArg1();
destroy = true;
break;
case kExitCodeLoadPreviousScreenObject:
if (_previousScreen)
setCurrentScreen(_previousScreen);
else if (!_previousScreenName.empty()) {
- loadScreen(_previousScreenName);
+ _nextScreenName = _previousScreenName;
_previousScreenName.clear();
}
break;
@@ -316,12 +322,11 @@ void AGDSEngine::runProcesses() {
if (_processes.empty())
return;
- debug("enter");
- bool destroy;
+ bool destroy, suspend;
do {
for (ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
Process & process = *i;
- bool suspend;
+ process.activate(true);
runProcess(process, destroy, suspend);
if (destroy) {
debug("destroying process %s...", process.getName().c_str());
@@ -334,8 +339,13 @@ void AGDSEngine::runProcesses() {
++i;
}
}
- } while (destroy && !_processes.empty());
- debug("exit");
+ } while (!_processes.empty() && destroy);
+
+ while (!_nextScreenName.empty()) {
+ Common::String nextScreenName = _nextScreenName;
+ _nextScreenName.clear();
+ loadScreen(nextScreenName);
+ }
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index e4e87cfcf5c..f76501b8336 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -226,6 +226,7 @@ private:
MJPGPlayer * _mjpgPlayer;
Screen * _currentScreen;
Common::String _currentScreenName;
+ Common::String _nextScreenName;
Screen * _previousScreen;
Common::String _previousScreenName;
Animation * _defaultMouseCursor;
Commit: d648d65c82b437dd316450c4a2087ca1eb51db93
https://github.com/scummvm/scummvm/commit/d648d65c82b437dd316450c4a2087ca1eb51db93
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:17+01:00
Commit Message:
AGDS: Remove previous screen
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c8feb793109..95d8415a264 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -46,7 +46,7 @@ namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Engine(system),
_gameDescription(gameDesc), _pictureCacheId(1), _sharedStorageIndex(-2),
- _mjpgPlayer(), _currentScreen(), _previousScreen(),
+ _mjpgPlayer(), _currentScreen(),
_defaultMouseCursor(),
_mouse(400, 300), _userEnabled(false), _currentRegion(),
_random("agds"),
@@ -58,7 +58,6 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
AGDSEngine::~AGDSEngine() {
delete _currentScreen;
- delete _previousScreen;
for (PictureCacheType::iterator i = _pictureCache.begin(); i != _pictureCache.end(); ++i) {
i->_value->free();
delete i->_value;
@@ -220,7 +219,6 @@ void AGDSEngine::setCurrentScreen(Screen *screen) {
_currentScreenName = screen->getName();
_currentScreen = screen;
- _previousScreen = NULL;
_previousScreenName.clear();
}
@@ -230,8 +228,7 @@ void AGDSEngine::resetCurrentScreen() {
_currentRegion = NULL;
}
- if (_currentScreen != _previousScreen) //we didnt come from back command, fixme: refactor it
- delete _currentScreen;
+ delete _currentScreen;
_currentScreen = NULL;
_currentScreenName.clear();
}
@@ -269,17 +266,13 @@ void AGDSEngine::runProcess(Process &process, bool &destroy, bool &suspend) {
break;
case kExitCodeSetNextScreenSaveInHistory:
if (_currentScreen) {
- delete _previousScreen;
- _previousScreen = _currentScreen;
_previousScreenName = _currentScreenName;
}
_nextScreenName = process.getExitArg1();
destroy = true;
break;
case kExitCodeLoadPreviousScreenObject:
- if (_previousScreen)
- setCurrentScreen(_previousScreen);
- else if (!_previousScreenName.empty()) {
+ if (!_previousScreenName.empty()) {
_nextScreenName = _previousScreenName;
_previousScreenName.clear();
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index f76501b8336..2b589bb1b24 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -227,7 +227,6 @@ private:
Screen * _currentScreen;
Common::String _currentScreenName;
Common::String _nextScreenName;
- Screen * _previousScreen;
Common::String _previousScreenName;
Animation * _defaultMouseCursor;
Common::Point _mouse;
Commit: 1311d4825b0c06377c7d8dbaec0b1b02f820338e
https://github.com/scummvm/scummvm/commit/1311d4825b0c06377c7d8dbaec0b1b02f820338e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:18+01:00
Commit Message:
AGDS: simplified logic for exit-and-load
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 18c77448897..53c10d3ff51 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -184,12 +184,6 @@ void Process::updatePhaseVarOr4() {
void Process::loadScreenObject() {
Common::String name = popString();
debug("loadScreenObject: %s", name.c_str());
- Screen *screen = _engine->getCurrentScreen();
- if (!screen->find(name)) {
- screen->add(_engine->loadObject(name));
- } else {
- warning("loadScreenObject: object %s already loaded", name.c_str());
- }
suspend(kExitCodeLoadScreenObject, name);
}
Commit: 60b977ad8c2fd56bbf538b51fd0d0059d613e468
https://github.com/scummvm/scummvm/commit/60b977ad8c2fd56bbf538b51fd0d0059d613e468
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:18+01:00
Commit Message:
AGDS: return bool from Screen::add()
Changed paths:
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index d170c283d7d..c15a89d8dcf 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -43,18 +43,19 @@ Screen::~Screen() {
_children.clear();
}
-void Screen::add(ObjectPtr object) {
+bool Screen::add(ObjectPtr object) {
if (object == NULL) {
warning("refusing to add null to scene");
- return;
+ return false;
}
for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
if (*i == object) {
debug("double adding object %s", (*i)->getName().c_str());
- return;
+ return false;
}
}
_children.insert(object);
+ return true;
}
ObjectPtr Screen::find(const Common::String &name) {
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 3482ce304d6..5dbadf08071 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -83,7 +83,7 @@ public:
_region = region;
}
- void add(ObjectPtr object);
+ bool add(ObjectPtr object);
void add(Animation * animation) {
_animations.insert(animation);
}
Commit: 7a77b10570b957824de340b2950f21a16cd9323d
https://github.com/scummvm/scummvm/commit/7a77b10570b957824de340b2950f21a16cd9323d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:18+01:00
Commit Message:
AGDS: remove invalid assumption that mouse id could not be 0
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 95d8415a264..f99f5976b46 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -372,7 +372,7 @@ void AGDSEngine::changeMouseArea(int id, int enabled) {
break;
case 0:
debug("disabling mouse area %d", id);
- if (_currentRegion && _currentRegion->id) {
+ if (_currentRegion) {
_currentRegion->hide(this);
_currentRegion = NULL;
}
@@ -380,7 +380,7 @@ void AGDSEngine::changeMouseArea(int id, int enabled) {
break;
case -1:
debug("removing mouse area %d", id);
- if (_currentRegion && _currentRegion->id) {
+ if (_currentRegion) {
_currentRegion->hide(this);
_currentRegion = NULL;
}
Commit: 26cd4203328013abab53bddff2fb92e6fabc596e
https://github.com/scummvm/scummvm/commit/26cd4203328013abab53bddff2fb92e6fabc596e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:18+01:00
Commit Message:
AGDS: add any running object to screen
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index f99f5976b46..3e1de31cbdb 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -153,15 +153,15 @@ ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::Strin
}
void AGDSEngine::runObject(ObjectPtr object) {
- if (_currentScreen)
- _currentScreen->add(object);
- else
- warning("object %s has been loaded, but was not added to any screen", object->getName().c_str());
runProcess(object);
}
void AGDSEngine::runProcess(ObjectPtr object, uint ip) {
debug("starting process %s:%04x", object->getName().c_str(), ip);
+ if (_currentScreen)
+ _currentScreen->add(object);
+ else
+ warning("object %s has been loaded, but was not added to any screen", object->getName().c_str());
object->inScene(true);
_processes.push_front(Process(this, object, ip));
}
Commit: ccc2483b2beba3be3f54ccd99e53d863ced54e81
https://github.com/scummvm/scummvm/commit/ccc2483b2beba3be3f54ccd99e53d863ced54e81
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:18+01:00
Commit Message:
AGDS: hide current mouse area before resetting screen
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3e1de31cbdb..57ed2e998f5 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -175,6 +175,7 @@ void AGDSEngine::runObject(const Common::String &name, const Common::String &pro
void AGDSEngine::loadScreen(const Common::String &name) {
debug("loadScreen %s", name.c_str());
+ _mouseMap.hideAll(this);
resetCurrentScreen();
for(ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
Process &process = *i;
@@ -186,7 +187,6 @@ void AGDSEngine::loadScreen(const Common::String &name) {
++i;
}
- _mouseMap.hideAll(this);
_soundManager.stopAll();
_currentScreenName = name;
_currentScreen = new Screen(loadObject(name));
Commit: 16f9b2c9e07cfcaf67d72f4e5fb8f8f147d0c389
https://github.com/scummvm/scummvm/commit/16f9b2c9e07cfcaf67d72f4e5fb8f8f147d0c389
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:18+01:00
Commit Message:
AGDS: remove Process::activate
Changed paths:
engines/agds/agds.cpp
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 57ed2e998f5..65ac52d883b 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -181,7 +181,6 @@ void AGDSEngine::loadScreen(const Common::String &name) {
Process &process = *i;
if (process.parentScreenName() != _currentScreenName) {
debug("process %s from different screen, destroy", process.getName().c_str());
- process.activate(false);
i = _processes.erase(i);
} else
++i;
@@ -239,13 +238,11 @@ void AGDSEngine::runProcess(Process &process, bool &destroy, bool &suspend) {
const Common::String &name = process.getName();
if (process.getStatus() == Process::kStatusDone || process.getStatus() == Process::kStatusError) {
debug("process %s finished", name.c_str());
- process.activate(false);
destroy = true;
return;
}
destroy = false;
- process.activate(true);
ProcessExitCode code = process.execute();
switch (code) {
case kExitCodeDestroy:
@@ -319,20 +316,18 @@ void AGDSEngine::runProcesses() {
do {
for (ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
Process & process = *i;
- process.activate(true);
runProcess(process, destroy, suspend);
if (destroy) {
debug("destroying process %s...", process.getName().c_str());
- process.activate(false);
i = _processes.erase(i);
break;
- } else if (!suspend) {
+ } else if (suspend) {
break;
} else {
++i;
}
}
- } while (!_processes.empty() && destroy);
+ } while (!_processes.empty() && !suspend);
while (!_nextScreenName.empty()) {
Common::String nextScreenName = _nextScreenName;
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 7f84c127916..1e1ae9f0c1f 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -100,19 +100,4 @@ Common::String Process::popText() {
return _engine->loadText(popString());
}
-void Process::activate(bool active) {
- if (active) {
- switch (_status) {
- case kStatusActive:
- break;
- case kStatusPassive:
- _status = kStatusActive;
- break;
- default:
- error("process in invalid state %d", _status);
- _status = kStatusError;
- }
- }
-}
-
} // namespace AGDS
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 86e81a81486..5cab30719c2 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -333,8 +333,6 @@ public:
return _status;
}
- void activate(bool active);
-
ProcessExitCode execute();
ProcessExitCode getExitCode() const {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 53c10d3ff51..984e0aff4d2 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1321,9 +1321,11 @@ ProcessExitCode Process::execute() {
if (_timer > 0) {
debug("waiting for timer (%d)...", _timer);
--_timer;
+ _status = kStatusPassive;
_exitCode = kExitCodeSuspend;
return _exitCode;
}
+ _status = kStatusActive;
_exitCode = kExitCodeDestroy;
const Object::CodeType &code = _object->getCode();
Commit: 046ac3c71967ad3dbf5358d148ad1a16ea26dc49
https://github.com/scummvm/scummvm/commit/046ac3c71967ad3dbf5358d148ad1a16ea26dc49
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:18+01:00
Commit Message:
AGDS: move exit code handling to Process
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 65ac52d883b..d84c4ecf63a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -232,116 +232,54 @@ void AGDSEngine::resetCurrentScreen() {
_currentScreenName.clear();
}
-void AGDSEngine::runProcess(Process &process, bool &destroy, bool &suspend) {
- suspend = false;
- const Common::String &name = process.getName();
- if (process.getStatus() == Process::kStatusDone || process.getStatus() == Process::kStatusError) {
- debug("process %s finished", name.c_str());
- destroy = true;
- return;
- }
-
- destroy = false;
- ProcessExitCode code = process.execute();
- switch (code) {
- case kExitCodeDestroy:
- debug("process returned destroy exit code");
- destroy = true;
- break;
- case kExitCodeLoadScreenObjectAs:
- case kExitCodeLoadScreenObject:
- runObject(process.getExitArg1(), process.getExitArg2());
- break;
- case kExitCodeRunDialog:
- _dialogProcessName = process.getExitArg1();
- break;
- case kExitCodeSetNextScreen:
- _nextScreenName = process.getExitArg1();
- debug("process returned load screen/destroy exit code");
- destroy = true;
- break;
- case kExitCodeSetNextScreenSaveInHistory:
- if (_currentScreen) {
- _previousScreenName = _currentScreenName;
- }
- _nextScreenName = process.getExitArg1();
- destroy = true;
- break;
- case kExitCodeLoadPreviousScreenObject:
- if (!_previousScreenName.empty()) {
- _nextScreenName = _previousScreenName;
- _previousScreenName.clear();
- }
- break;
- case kExitCodeMouseAreaChange:
- changeMouseArea(process.getExitIntArg1(), process.getExitIntArg2());
- break;
- case kExitCodeLoadInventoryObject:
- _inventory.add(loadObject(process.getExitArg1()));
- break;
- case kExitCodeSuspend:
- suspend = true;
- break;
- case kExitCodeCreatePatchLoadResources:
- {
- debug("exitProcessCreatePatch");
-
- SystemVariable *doneVar = getSystemVariable("done_resources");
- Common::String done = doneVar->getString();
- runObject(done);
-
- _patches.clear();
- _inventory.clear();
- _globals.clear();
-
- SystemVariable *initVar = getSystemVariable("init_resources");
- Common::String init = initVar->getString();
- runObject(init);
- }
- break;
- case kExitCodeLoadSaveGame:
- loadGameState(process.getExitIntArg1());
- break;
- default:
- error("unknown process exit code %d", code);
- }
-}
-
-void AGDSEngine::runProcesses() {
- if (_processes.empty())
- return;
+// void AGDSEngine::runProcesses() {
+// if (_processes.empty())
+// return;
+
+// bool destroy, suspend;
+// do {
+// for (ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
+// Process & process = *i;
+// runProcess(process, destroy, suspend);
+// if (destroy) {
+// debug("destroying process %s...", process.getName().c_str());
+// i = _processes.erase(i);
+// break;
+// } else if (suspend) {
+// break;
+// } else {
+// ++i;
+// }
+// }
+// } while (!_processes.empty() && !suspend);
+
+// while (!_nextScreenName.empty()) {
+// Common::String nextScreenName = _nextScreenName;
+// _nextScreenName.clear();
+// loadScreen(nextScreenName);
+// }
+// }
+
+void AGDSEngine::newGame() {
+ SystemVariable *doneVar = getSystemVariable("done_resources");
+ Common::String done = doneVar->getString();
+ runObject(done);
- bool destroy, suspend;
- do {
- for (ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
- Process & process = *i;
- runProcess(process, destroy, suspend);
- if (destroy) {
- debug("destroying process %s...", process.getName().c_str());
- i = _processes.erase(i);
- break;
- } else if (suspend) {
- break;
- } else {
- ++i;
- }
- }
- } while (!_processes.empty() && !suspend);
+ _patches.clear();
+ _inventory.clear();
+ _globals.clear();
- while (!_nextScreenName.empty()) {
- Common::String nextScreenName = _nextScreenName;
- _nextScreenName.clear();
- loadScreen(nextScreenName);
- }
+ SystemVariable *initVar = getSystemVariable("init_resources");
+ Common::String init = initVar->getString();
+ runObject(init);
}
-
void AGDSEngine::tick() {
if (tickDialog())
return;
tickInventory();
- runProcesses();
+ //runProcesses();
}
Animation *AGDSEngine::loadMouseCursor(const Common::String &name) {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 2b589bb1b24..c7b55ad1448 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -89,8 +89,7 @@ private:
void addSystemVar(const Common::String &name, SystemVariable *var);
bool initGraphics(int w, int h);
bool load();
- void runProcess(Process &process, bool &destroy, bool &suspend);
- void runProcesses();
+ //void runProcesses();
void tick();
public:
@@ -174,9 +173,27 @@ public:
return _userEnabled;
}
+ void newGame();
void initSystemVariables();
SystemVariable *getSystemVariable(const Common::String &name);
+ void setNextScreenName(const Common::String &nextScreenName, bool savePrev) {
+ if (_currentScreen && savePrev) {
+ _previousScreenName = _currentScreenName;
+ }
+ _nextScreenName = nextScreenName;
+ }
+
+ void returnToPreviousScreen() {
+ if (!_previousScreenName.empty()) {
+ _nextScreenName = _previousScreenName;
+ _previousScreenName.clear();
+ }
+ }
+
+ void runDialog(const Common::String &dialogProcess) {
+ _dialogProcessName = dialogProcess;
+ }
void runDialog(const Common::String &dialogScript, const Common::String & defs);
bool tickDialog();
void tickInventory();
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 1e1ae9f0c1f..5d5f33a8b70 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -100,4 +100,67 @@ Common::String Process::popText() {
return _engine->loadText(popString());
}
+void Process::run(bool &destroy, bool &suspend) {
+ suspend = false;
+
+ switch(getStatus()) {
+ case Process::kStatusDone:
+ case Process::kStatusError:
+ debug("process %s finished", getName().c_str());
+ destroy = true;
+ return;
+ default:
+ break;
+ }
+
+ destroy = false;
+ ProcessExitCode code = resume();
+ switch (code) {
+ case kExitCodeDestroy:
+ debug("process %s returned destroy exit code", getName().c_str());
+ destroy = true;
+ break;
+ case kExitCodeLoadScreenObjectAs:
+ case kExitCodeLoadScreenObject:
+ _engine->runObject(getExitArg1(), getExitArg2());
+ break;
+ case kExitCodeRunDialog:
+ _engine->runDialog(getExitArg1());
+ break;
+ case kExitCodeSetNextScreen:
+ debug("process %s launches screen: %s", getName().c_str(), getExitArg1().c_str());
+ _engine->setNextScreenName(getExitArg1(), false);
+ destroy = true;
+ break;
+ case kExitCodeSetNextScreenSaveInHistory:
+ _engine->setNextScreenName(getExitArg1(), true);
+ destroy = true;
+ break;
+ case kExitCodeLoadPreviousScreenObject:
+ _engine->returnToPreviousScreen();
+ break;
+ case kExitCodeMouseAreaChange:
+ _engine->changeMouseArea(getExitIntArg1(), getExitIntArg2());
+ break;
+ case kExitCodeLoadInventoryObject:
+ _engine->inventory().add(_engine->loadObject(getExitArg1()));
+ break;
+ case kExitCodeSuspend:
+ suspend = true;
+ break;
+ case kExitCodeCreatePatchLoadResources:
+ {
+ debug("exitProcessCreatePatch");
+ _engine->newGame();
+ }
+ break;
+ case kExitCodeLoadSaveGame:
+ _engine->loadGameState(getExitIntArg1());
+ break;
+ default:
+ error("unknown process exit code %d", code);
+ }
+}
+
+
} // namespace AGDS
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 5cab30719c2..cdd2060fcd2 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -333,7 +333,9 @@ public:
return _status;
}
- ProcessExitCode execute();
+ ProcessExitCode resume();
+
+ void run(bool &destroy, bool &suspend);
ProcessExitCode getExitCode() const {
return _exitCode;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 984e0aff4d2..5f0c33dd074 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1317,7 +1317,7 @@ void Process::stub244() {
METHOD(arg1 | (arg2 << 16)); \
} break
-ProcessExitCode Process::execute() {
+ProcessExitCode Process::resume() {
if (_timer > 0) {
debug("waiting for timer (%d)...", _timer);
--_timer;
Commit: f24362c1723b4baf298ac36f783fb1376d2d9262
https://github.com/scummvm/scummvm/commit/f24362c1723b4baf298ac36f783fb1376d2d9262
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:18+01:00
Commit Message:
AGDS: rewrite process handling to match original engine
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index d84c4ecf63a..301228d8d3b 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -164,6 +164,7 @@ void AGDSEngine::runProcess(ObjectPtr object, uint ip) {
warning("object %s has been loaded, but was not added to any screen", object->getName().c_str());
object->inScene(true);
_processes.push_front(Process(this, object, ip));
+ _processes.front().run();
}
void AGDSEngine::runObject(const Common::String &name, const Common::String &prototype) {
@@ -177,13 +178,12 @@ void AGDSEngine::loadScreen(const Common::String &name) {
debug("loadScreen %s", name.c_str());
_mouseMap.hideAll(this);
resetCurrentScreen();
- for(ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
+ for(ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ++i) {
Process &process = *i;
if (process.parentScreenName() != _currentScreenName) {
debug("process %s from different screen, destroy", process.getName().c_str());
- i = _processes.erase(i);
- } else
- ++i;
+ process.done();
+ }
}
_soundManager.stopAll();
@@ -233,33 +233,25 @@ void AGDSEngine::resetCurrentScreen() {
}
-// void AGDSEngine::runProcesses() {
-// if (_processes.empty())
-// return;
-
-// bool destroy, suspend;
-// do {
-// for (ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
-// Process & process = *i;
-// runProcess(process, destroy, suspend);
-// if (destroy) {
-// debug("destroying process %s...", process.getName().c_str());
-// i = _processes.erase(i);
-// break;
-// } else if (suspend) {
-// break;
-// } else {
-// ++i;
-// }
-// }
-// } while (!_processes.empty() && !suspend);
-
-// while (!_nextScreenName.empty()) {
-// Common::String nextScreenName = _nextScreenName;
-// _nextScreenName.clear();
-// loadScreen(nextScreenName);
-// }
-// }
+void AGDSEngine::runProcesses() {
+ for (ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
+ Process & process = *i;
+ if (process.active() || process.passive()) {
+ process.run();
+ ++i;
+ } else {
+ debug("deleting process %s", process.getName().c_str());
+ i = _processes.erase(i);
+ //FIXME: when the last process exits, remove object from scene
+ }
+ }
+
+ while (!_nextScreenName.empty()) {
+ Common::String nextScreenName = _nextScreenName;
+ _nextScreenName.clear();
+ loadScreen(nextScreenName);
+ }
+ }
void AGDSEngine::newGame() {
SystemVariable *doneVar = getSystemVariable("done_resources");
@@ -279,7 +271,7 @@ void AGDSEngine::tick() {
if (tickDialog())
return;
tickInventory();
- //runProcesses();
+ runProcesses();
}
Animation *AGDSEngine::loadMouseCursor(const Common::String &name) {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index c7b55ad1448..ffd7eeeab7e 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -89,7 +89,7 @@ private:
void addSystemVar(const Common::String &name, SystemVariable *var);
bool initGraphics(int w, int h);
bool load();
- //void runProcesses();
+ void runProcesses();
void tick();
public:
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 5d5f33a8b70..cc168be7289 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -100,65 +100,76 @@ Common::String Process::popText() {
return _engine->loadText(popString());
}
-void Process::run(bool &destroy, bool &suspend) {
- suspend = false;
-
- switch(getStatus()) {
- case Process::kStatusDone:
- case Process::kStatusError:
+void Process::activate() {
+ switch(status()) {
+ case kStatusPassive:
+ _status = Process::kStatusActive;
+ break;
+ case kStatusDone:
+ case kStatusError:
debug("process %s finished", getName().c_str());
- destroy = true;
- return;
+ break;
default:
break;
}
+}
- destroy = false;
- ProcessExitCode code = resume();
- switch (code) {
- case kExitCodeDestroy:
- debug("process %s returned destroy exit code", getName().c_str());
- destroy = true;
- break;
- case kExitCodeLoadScreenObjectAs:
- case kExitCodeLoadScreenObject:
- _engine->runObject(getExitArg1(), getExitArg2());
- break;
- case kExitCodeRunDialog:
- _engine->runDialog(getExitArg1());
- break;
- case kExitCodeSetNextScreen:
- debug("process %s launches screen: %s", getName().c_str(), getExitArg1().c_str());
- _engine->setNextScreenName(getExitArg1(), false);
- destroy = true;
- break;
- case kExitCodeSetNextScreenSaveInHistory:
- _engine->setNextScreenName(getExitArg1(), true);
- destroy = true;
- break;
- case kExitCodeLoadPreviousScreenObject:
- _engine->returnToPreviousScreen();
- break;
- case kExitCodeMouseAreaChange:
- _engine->changeMouseArea(getExitIntArg1(), getExitIntArg2());
- break;
- case kExitCodeLoadInventoryObject:
- _engine->inventory().add(_engine->loadObject(getExitArg1()));
- break;
- case kExitCodeSuspend:
- suspend = true;
- break;
- case kExitCodeCreatePatchLoadResources:
- {
- debug("exitProcessCreatePatch");
- _engine->newGame();
+
+void Process::run() {
+ activate();
+ while(status() == kStatusActive) {
+ ProcessExitCode code = resume();
+ switch (code) {
+ case kExitCodeDestroy:
+ debug("process %s returned destroy exit code", getName().c_str());
+ //_engine->getCurrentScreen()->remove(_object); //remove if the last process exits
+ done();
+ break;
+ case kExitCodeLoadScreenObjectAs:
+ case kExitCodeLoadScreenObject:
+ _engine->runObject(getExitArg1(), getExitArg2());
+ activate();
+ break;
+ case kExitCodeRunDialog:
+ _engine->runDialog(getExitArg1());
+ break;
+ case kExitCodeSetNextScreen:
+ debug("process %s launches screen: %s", getName().c_str(), getExitArg1().c_str());
+ _engine->setNextScreenName(getExitArg1(), false);
+ break;
+ case kExitCodeSetNextScreenSaveInHistory:
+ _engine->setNextScreenName(getExitArg1(), true);
+ break;
+ case kExitCodeLoadPreviousScreenObject:
+ _engine->returnToPreviousScreen();
+ break;
+ case kExitCodeMouseAreaChange:
+ _engine->changeMouseArea(getExitIntArg1(), getExitIntArg2());
+ activate();
+ break;
+ case kExitCodeLoadInventoryObject:
+ _engine->inventory().add(_engine->loadObject(getExitArg1()));
+ activate();
+ break;
+ case kExitCodeSuspend:
+ break;
+ case kExitCodeCreatePatchLoadResources:
+ {
+ debug("exitProcessCreatePatch");
+ _engine->newGame();
+ }
+ break;
+ case kExitCodeLoadSaveGame:
+ if (_engine->loadGameState(getExitIntArg1()).getCode() == Common::kNoError) {
+ done();
+ } else {
+ debug("save loading failed, resuming execution...");
+ activate(); //continue
+ }
+ break;
+ default:
+ error("unknown process exit code %d", code);
}
- break;
- case kExitCodeLoadSaveGame:
- _engine->loadGameState(getExitIntArg1());
- break;
- default:
- error("unknown process exit code %d", code);
}
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index cdd2060fcd2..8551b7ef815 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -294,7 +294,7 @@ private:
void suspend(ProcessExitCode exitCode, const Common::String &arg1, const Common::String &arg2 = Common::String()) {
debug("suspend %d", exitCode);
- if (_status == kStatusActive)
+ if (active())
_status = kStatusPassive;
_exitCode = exitCode;
_exitIntArg1 = 0;
@@ -305,7 +305,7 @@ private:
void suspend(ProcessExitCode exitCode = kExitCodeSuspend, int arg1 = 0, int arg2 = 0) {
debug("suspend %d", exitCode);
- if (_status == kStatusActive)
+ if (active())
_status = kStatusPassive;
_exitCode = exitCode;
_exitIntArg1 = arg1;
@@ -314,6 +314,8 @@ private:
_exitArg2.clear();
}
+ ProcessExitCode resume();
+
public:
Process(AGDSEngine *engine, ObjectPtr object, unsigned ip = 0);
@@ -329,13 +331,25 @@ public:
return _parentScreen;
}
- Status getStatus() const {
+ Status status() const {
return _status;
}
- ProcessExitCode resume();
+ bool active() const {
+ return _status == kStatusActive;
+ }
+ bool passive() const {
+ return _status == kStatusPassive;
+ }
+ void activate();
+ void done() {
+ _status = kStatusDone;
+ }
+ void fail() {
+ _status = kStatusError;
+ }
- void run(bool &destroy, bool &suspend);
+ void run();
ProcessExitCode getExitCode() const {
return _exitCode;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 5f0c33dd074..39607c45167 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -836,7 +836,7 @@ void Process::setObjectText() {
void Process::exitProcess() {
debug("exitProcess");
- _status = kStatusDone;
+ done();
_exitCode = kExitCodeDestroy;
}
@@ -1038,7 +1038,8 @@ void Process::call(uint16 addr) {
debug("call %04x", addr);
//original engine just create new process, save exit code in screen object
//and on stack, then just ignore return code, fixme?
- _engine->runProcess(_object, _ip + addr);
+ Process process(_engine, _object, _ip + addr);
+ process.run();
suspend();
}
@@ -1325,11 +1326,10 @@ ProcessExitCode Process::resume() {
_exitCode = kExitCodeSuspend;
return _exitCode;
}
- _status = kStatusActive;
_exitCode = kExitCodeDestroy;
const Object::CodeType &code = _object->getCode();
- while (_status == kStatusActive && _ip < code.size()) {
+ while (active() && _ip < code.size()) {
_lastIp = _ip;
uint8 op = next();
switch (op) {
@@ -1513,12 +1513,12 @@ ProcessExitCode Process::resume() {
OP(kSetDialogForNextFilm, setDialogForNextFilm);
default:
error("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _ip - 1, (unsigned)op, (unsigned)op);
- _status = kStatusError;
+ fail();
break;
}
}
- if (_status == kStatusActive) {
+ if (active()) {
debug("code ended, exiting...");
}
Commit: 6bfb0f46b57e518a92dcd1eda190870f61da5369
https://github.com/scummvm/scummvm/commit/6bfb0f46b57e518a92dcd1eda190870f61da5369
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:18+01:00
Commit Message:
AGDS: more stubs
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 06757e5bcfc..680fb9a9195 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -83,8 +83,8 @@ enum Opcode {
kObjectRegisterUseHandler = 61,
kObjectRegisterHandlerC1 = 62,
kObjectRegisterUseObjectHandler = 63,
- kScreenRegisterHandlerBD = 64,
- kStub65 = 65,
+ kObjectRegisterHandlerBD = 64,
+ kObjectRegisterHandlerB9 = 65,
kLoadMouseCursorFromObject = 66,
kLoadRegionFromObject = 68,
kLoadPictureFromObject = 69,
@@ -224,7 +224,7 @@ enum Opcode {
kStub204 = 204,
kAddMouseArea = 205,
kModifyMouseArea = 206,
- kStub207 = 207,
+ kSetRain = 207,
kFogOnCharacter = 208,
kStub209 = 209,
kStub210 = 210,
@@ -235,8 +235,8 @@ enum Opcode {
kStub215 = 215,
kStub216 = 216,
kStub217 = 217,
- kStub218 = 218,
- kStub219 = 219,
+ kSetRainDensity = 218,
+ kLeaveCharacterEx = 219,
kStopCharacter = 220,
kPlayAnimationWithPhaseVar = 221,
kStub222 = 222,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 8551b7ef815..beb01966237 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -167,7 +167,10 @@ private:
void moveCharacter(bool usermove);
void showCharacter();
void fogOnCharacter();
+ void setRain();
+ void setRainDensity();
void leaveCharacter();
+ void leaveCharacterEx();
void setCharacter();
void pointCharacter();
void animateCharacter();
@@ -220,7 +223,8 @@ private:
void onUse(unsigned size);
void onLook(unsigned size);
void onObjectC1(unsigned size);
- void onScreenBD(unsigned size);
+ void onObjectB9(unsigned size);
+ void onObjectBD(unsigned size);
void onObjectUse(unsigned size);
void stub82();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 39607c45167..540eb070d66 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1067,8 +1067,13 @@ void Process::onLook(unsigned size) {
_ip += size;
}
-void Process::onScreenBD(unsigned size) {
- debug("onScreen(+BD) [handler], %u instructions", size);
+void Process::onObjectB9(unsigned size) {
+ debug("onObject(+B9) [handler], %u instructions", size);
+ _ip += size;
+}
+
+void Process::onObjectBD(unsigned size) {
+ debug("onObject(+BD) [handler], %u instructions", size);
_ip += size;
}
@@ -1147,6 +1152,12 @@ void Process::leaveCharacter() {
RegionPtr region = _engine->loadRegion(arg2);
debug("region: %s", region->toString().c_str());
}
+void Process::leaveCharacterEx() {
+ int arg3 = pop();
+ Common::String arg2 = popString();
+ Common::String arg1 = popString();
+ debug("leaveCharacterEx %s %s %d", arg1.c_str(), arg2.c_str(), arg3);
+}
void Process::setCharacter() {
Common::String object = popString();
@@ -1190,6 +1201,17 @@ void Process::fogOnCharacter() {
enableUser();
}
+void Process::setRain() {
+ Common::String name = popString();
+ debug("setRain stub: %s", name.c_str());
+}
+
+void Process::setRainDensity() {
+ int density = pop();
+ debug("setRainDensity stub: %d", density);
+
+}
+
void Process::loadRegionFromObject() {
Common::String name = popString();
debug("loadRegionFromObject %s", name.c_str());
@@ -1381,7 +1403,8 @@ ProcessExitCode Process::resume() {
OP_U(kObjectRegisterLookHandler, onLook);
OP_U(kObjectRegisterUseHandler, onUse);
OP_U(kObjectRegisterHandlerC1, onObjectC1);
- OP_U(kScreenRegisterHandlerBD, onScreenBD);
+ OP_U(kObjectRegisterHandlerB9, onObjectB9);
+ OP_U(kObjectRegisterHandlerBD, onObjectBD);
OP(kLoadMouseCursorFromObject, loadMouseCursorFromObject);
OP(kLoadRegionFromObject, loadRegionFromObject);
OP(kLoadPictureFromObject, loadPictureFromObject);
@@ -1486,6 +1509,7 @@ ProcessExitCode Process::resume() {
OP(kStub216, stub216);
OP(kStub217, stub217);
OP(kStopCharacter, stopCharacter);
+ OP(kLeaveCharacterEx, leaveCharacterEx);
OP(kPlayAnimationWithPhaseVar, playAnimationWithPhaseVar);
OP(kStub223, stub223);
OP(kStub225, stub225);
@@ -1495,6 +1519,8 @@ ProcessExitCode Process::resume() {
OP_U(kStub202ScreenHandler, stub202);
OP(kPlayFilm, playFilm);
OP(kAddMouseArea, addMouseArea);
+ OP(kSetRain, setRain);
+ OP(kSetRainDensity, setRainDensity);
OP(kFogOnCharacter, fogOnCharacter);
OP(kSetTileIndex, setTileIndex);
OP(kModifyMouseArea, modifyMouseArea);
Commit: ed4a10465f3965b887d79a6ffb7a418d66beb52e
https://github.com/scummvm/scummvm/commit/ed4a10465f3965b887d79a6ffb7a418d66beb52e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:18+01:00
Commit Message:
AGDS: implement getting mouse position
Changed paths:
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index ffd7eeeab7e..6dd4133237f 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -206,6 +206,10 @@ public:
return _fastMode;
}
+ Common::Point mousePosition() const {
+ return _mouse;
+ }
+
private:
void parseDialogDefs(const Common::String &defs);
void loadPatches(Common::SeekableReadStream *file, Database & db);
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 680fb9a9195..cf3b3754e77 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -161,8 +161,8 @@ enum Opcode {
kGetFreeInventorySpace = 141,
kSetStringSystemVariable = 142,
kSetSystemIntegerVariable = 143,
- kStub144 = 144,
- kStub145 = 145,
+ kGetSavedMouseX = 144,
+ kGetSavedMouseY = 145,
kGetRegionCenterX = 146,
kGetRegionCenterY = 147,
kGetCharacterAnimationPhase = 148,
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index cc168be7289..46aad5ae8a6 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -100,6 +100,10 @@ Common::String Process::popText() {
return _engine->loadText(popString());
}
+void Process::updateWithCurrentMousePosition() {
+ setMousePosition(_engine->mousePosition());
+}
+
void Process::activate() {
switch(status()) {
case kStatusPassive:
@@ -152,6 +156,7 @@ void Process::run() {
activate();
break;
case kExitCodeSuspend:
+ updateWithCurrentMousePosition();
break;
case kExitCodeCreatePatchLoadResources:
{
diff --git a/engines/agds/process.h b/engines/agds/process.h
index beb01966237..cef8a3c44b2 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -61,6 +61,7 @@ private:
int _animationZ;
bool _animationPaused;
int _animationSpeed;
+ Common::Point _mousePosition;
private:
uint8 next() {
@@ -239,6 +240,8 @@ private:
void getPictureBaseY();
void getObjectSurfaceX();
void getObjectSurfaceY();
+ void getSavedMouseX();
+ void getSavedMouseY();
void loadGame();
void loadSaveSlotNamePicture();
void stub166();
@@ -375,6 +378,11 @@ public:
return _exitIntArg2;
}
+ void setMousePosition(Common::Point mousePosition) {
+ _mousePosition = mousePosition;
+ }
+ void updateWithCurrentMousePosition();
+
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 540eb070d66..e2645d166f9 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -607,6 +607,16 @@ void Process::getObjectSurfaceY() {
push(y);
}
+void Process::getSavedMouseX() {
+ debug("saved mouse position x -> %d", _mousePosition.x);
+ push(_mousePosition.x);
+}
+
+void Process::getSavedMouseY() {
+ debug("saved mouse position y -> %d", _mousePosition.y);
+ push(_mousePosition.y);
+}
+
void Process::loadGame() {
int saveSlot = pop();
debug("loadGame %d", saveSlot);
@@ -1455,6 +1465,8 @@ ProcessExitCode Process::resume() {
OP(kSetAnimationLoop, setAnimationLoop);
OP(kSetAnimationSpeed, setAnimationSpeed);
OP(kStub138, stub138);
+ OP(kGetSavedMouseX, getSavedMouseX);
+ OP(kGetSavedMouseY, getSavedMouseY);
OP(kScreenChangeScreenPatch, changeScreenPatch);
OP(kGetFreeInventorySpace, getInventoryFreeSpace);
OP(kSetStringSystemVariable, setStringSystemVariable);
Commit: 00c4df9add581e35381988852d43456244ed32f7
https://github.com/scummvm/scummvm/commit/00c4df9add581e35381988852d43456244ed32f7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:19+01:00
Commit Message:
AGDS: add comment regarding stub174
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index e2645d166f9..743bc0c72d6 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -671,7 +671,7 @@ void Process::stub173() {
}
void Process::stub174() {
- debug("stub174: mouse pointer mode 1?");
+ debug("stub174: set mouse relative mode");
}
void Process::stub192() {
Commit: 41089e0e6d1ce3ffeb2ba0f804943b8caf77ba5a
https://github.com/scummvm/scummvm/commit/41089e0e6d1ce3ffeb2ba0f804943b8caf77ba5a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:19+01:00
Commit Message:
AGDS: moved patch load/save to Screen
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 301228d8d3b..a7e2ffe7463 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -176,6 +176,13 @@ void AGDSEngine::runObject(const Common::String &name, const Common::String &pro
void AGDSEngine::loadScreen(const Common::String &name) {
debug("loadScreen %s", name.c_str());
+ if (_currentScreen && !_currentScreenName.empty())
+ {
+ PatchPtr &patch = _patches[_currentScreenName];
+ if (!patch)
+ patch = PatchPtr(new Patch());
+ _currentScreen->save(*this, patch);
+ }
_mouseMap.hideAll(this);
resetCurrentScreen();
for(ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ++i) {
@@ -192,33 +199,11 @@ void AGDSEngine::loadScreen(const Common::String &name) {
runProcess(_currentScreen->getObject());
PatchesType::const_iterator it = _patches.find(name);
- if (it == _patches.end())
- return;
-
- PatchPtr patch = it->_value;
- const Common::Array<Patch::Object> &objects = patch->objects;
- debug("found patch with %u objects", objects.size());
- for(uint i = 0; i < objects.size(); ++i) {
- const Patch::Object &object = objects[i];
- debug("patch object %s %d", object.name.c_str(), object.flag);
- if (object.flag <= 0)
- _currentScreen->remove(object.name);
- else if (!_currentScreen->find(object.name)) {
- runObject(object.name);
- }
+ if (it != _patches.end()) {
+ const PatchPtr &patch = it->_value;
+ _currentScreen->load(*this, patch);
+ loadDefaultMouseCursor(patch->defaultMouseCursor);
}
- loadDefaultMouseCursor(patch->defaultMouseCursor);
-}
-
-void AGDSEngine::setCurrentScreen(Screen *screen) {
- if (!screen)
- error("no previous screen");
-
- resetCurrentScreen();
-
- _currentScreenName = screen->getName();
- _currentScreen = screen;
- _previousScreenName.clear();
}
void AGDSEngine::resetCurrentScreen() {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 6dd4133237f..bb032586c17 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -107,7 +107,6 @@ public:
void resetCurrentScreen();
void loadScreen(const Common::String & name);
- void setCurrentScreen(Screen *screen);
RegionPtr loadRegion(const Common::String &name);
Common::String loadText(const Common::String &name);
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index c15a89d8dcf..334b92ea8c6 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -21,8 +21,10 @@
*/
#include "agds/screen.h"
+#include "agds/agds.h"
#include "agds/animation.h"
#include "agds/object.h"
+#include "agds/patch.h"
#include "agds/region.h"
namespace AGDS {
@@ -145,4 +147,22 @@ Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
return keyHandler;
}
+void Screen::load(AGDSEngine & engine, const PatchPtr &patch) {
+ debug("applying patch with %u objects", patch->objects.size());
+ for(uint i = 0; i < patch->objects.size(); ++i) {
+ const Patch::Object &object = patch->objects[i];
+ debug("patch object %s %d", object.name.c_str(), object.flag);
+ if (object.flag <= 0)
+ remove(object.name);
+ else if (!find(object.name)) {
+ engine.runObject(object.name);
+ }
+ }
+}
+
+void Screen::save(AGDSEngine & engine, const PatchPtr &patch) {
+
+}
+
+
} // namespace AGDS
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 5dbadf08071..d709209af01 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -41,6 +41,8 @@ class Animation;
typedef Common::SharedPtr<Object> ObjectPtr;
struct Region;
typedef Common::SharedPtr<Region> RegionPtr;
+struct Patch;
+typedef Common::SharedPtr<Patch> PatchPtr;
class Screen {
static int ObjectZCompare(const ObjectPtr & a, const ObjectPtr & b);
@@ -100,6 +102,9 @@ public:
ObjectPtr find(Common::Point pos) const;
ObjectPtr find(const Common::String &name);
KeyHandler findKeyHandler(const Common::String &keyName);
+
+ void load(AGDSEngine & engine, const PatchPtr &patch);
+ void save(AGDSEngine & engine, const PatchPtr &patch);
};
Commit: f659cefedafac0b8a5e998672c0c2a774d879fe3
https://github.com/scummvm/scummvm/commit/f659cefedafac0b8a5e998672c0c2a774d879fe3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:19+01:00
Commit Message:
AGDS: use inScene flag to add/remove objects from/to scene
Changed paths:
engines/agds/agds.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index a7e2ffe7463..c368372f3c1 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -162,7 +162,6 @@ void AGDSEngine::runProcess(ObjectPtr object, uint ip) {
_currentScreen->add(object);
else
warning("object %s has been loaded, but was not added to any screen", object->getName().c_str());
- object->inScene(true);
_processes.push_front(Process(this, object, ip));
_processes.front().run();
}
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 334b92ea8c6..14f5907bb0f 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -50,49 +50,50 @@ bool Screen::add(ObjectPtr object) {
warning("refusing to add null to scene");
return false;
}
- for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
+ for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ) {
if (*i == object) {
- debug("double adding object %s", (*i)->getName().c_str());
- return false;
- }
+ if ((*i)->inScene()) {
+ debug("double adding object %s", (*i)->getName().c_str());
+ return false;
+ } else {
+ i = _children.erase(i);
+ }
+ } else
+ ++i;
}
+ object->inScene(true);
_children.insert(object);
return true;
}
ObjectPtr Screen::find(const Common::String &name) {
for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
- if ((*i)->getName() == name)
+ ObjectPtr &object = *i;
+ if (object->getName() == name && object->inScene())
return *i;
}
return ObjectPtr();
}
bool Screen::remove(const ObjectPtr &object) {
- bool found = false;
- for (ChildrenType::iterator i = _children.begin(); i != _children.end();) {
- if (*i == object) {
- i = _children.erase(i);
+ for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
+ if (*i == object && object->inScene()) {
object->inScene(false);
- found = true;
- } else
- ++i;
+ return true;
+ }
}
- return found;
+ return false;
}
bool Screen::remove(const Common::String &name) {
- bool found = false;
- for (ChildrenType::iterator i = _children.begin(); i != _children.end();) {
+ for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
const ObjectPtr & object = *i;
- if (object->getName() == name) {
+ if (object->getName() == name && object->inScene()) {
object->inScene(false);
- i = _children.erase(i);
- found = true;
- } else
- ++i;
+ return true;
+ }
}
- return found;
+ return false;
}
void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
@@ -104,7 +105,8 @@ void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
if (child_valid && animation_valid) {
if ((*child)->z() > (*animation)->z()) {
//debug("object %d, z: %d", idx++, (*child)->z());
- (*child)->paint(engine, backbuffer);
+ if ((*child)->inScene())
+ (*child)->paint(engine, backbuffer);
++child;
} else {
//debug("animation %d, z: %d", idx++, (*animation)->z());
@@ -113,7 +115,8 @@ void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
}
} else if (child_valid) {
//debug("object %d, z: %d", idx++, (*child)->z());
- (*child)->paint(engine, backbuffer);
+ if ((*child)->inScene())
+ (*child)->paint(engine, backbuffer);
++child;
} else {
//debug("animation %d, z: %d", idx++, (*animation)->z());
@@ -126,6 +129,9 @@ void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
ObjectPtr Screen::find(Common::Point pos) const {
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
+ if (!object->inScene())
+ continue;
+
RegionPtr region = object->region();
if (region && region->pointIn(pos))
return object;
@@ -137,6 +143,9 @@ Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
KeyHandler keyHandler;
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
+ if (!object->inScene())
+ continue;
+
uint ip = object->getKeyHandler(keyName);
if (ip) {
keyHandler.ip = ip;
@@ -161,7 +170,12 @@ void Screen::load(AGDSEngine & engine, const PatchPtr &patch) {
}
void Screen::save(AGDSEngine & engine, const PatchPtr &patch) {
-
+ patch->objects.clear();
+ for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
+ ObjectPtr object = *i;
+ debug("saving patch object %s %d", object->getName().c_str(), object->inScene());
+ patch->objects.push_back(Patch::Object(object->getName(), object->inScene()));
+ }
}
Commit: 5e05840a07e5cc642b38faec463c1bfa3f5acfc9
https://github.com/scummvm/scummvm/commit/5e05840a07e5cc642b38faec463c1bfa3f5acfc9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:19+01:00
Commit Message:
AGDS: save/load default mouse cursor in patch
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c368372f3c1..a9d434c87a8 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -181,6 +181,7 @@ void AGDSEngine::loadScreen(const Common::String &name) {
if (!patch)
patch = PatchPtr(new Patch());
_currentScreen->save(*this, patch);
+ patch->defaultMouseCursor = _defaultMouseCursorName;
}
_mouseMap.hideAll(this);
resetCurrentScreen();
@@ -201,7 +202,8 @@ void AGDSEngine::loadScreen(const Common::String &name) {
if (it != _patches.end()) {
const PatchPtr &patch = it->_value;
_currentScreen->load(*this, patch);
- loadDefaultMouseCursor(patch->defaultMouseCursor);
+ if (!patch->defaultMouseCursor.empty())
+ loadDefaultMouseCursor(patch->defaultMouseCursor);
}
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index bb032586c17..1d9f746e98c 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -160,6 +160,7 @@ public:
Character * getCharacter(const Common::String &name) const;
void loadDefaultMouseCursor(const Common::String &name) {
+ _defaultMouseCursorName = name;
_defaultMouseCursor = loadMouseCursor(name);
}
@@ -248,6 +249,7 @@ private:
Common::String _currentScreenName;
Common::String _nextScreenName;
Common::String _previousScreenName;
+ Common::String _defaultMouseCursorName;
Animation * _defaultMouseCursor;
Common::Point _mouse;
MouseRegion * _currentRegion;
Commit: 23f737aa9f121176f80e0c114aebf1362d6bec9c
https://github.com/scummvm/scummvm/commit/23f737aa9f121176f80e0c114aebf1362d6bec9c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:19+01:00
Commit Message:
AGDS: remove debug(OFFSET)
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 9b54cd19acb..12a29e55b07 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -141,7 +141,6 @@ void Object::setPicture(Graphics::TransparentSurface *picture) {
}
}
}
- debug("OFFSET %d, %d", _offset.x, _offset.y);
}
void Object::region(RegionPtr region) {
Commit: 6cb6c5d9ba40045fff9cbfed5c3b10fbb1a7a7bf
https://github.com/scummvm/scummvm/commit/6cb6c5d9ba40045fff9cbfed5c3b10fbb1a7a7bf
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:19+01:00
Commit Message:
AGDS: fix id
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 12a29e55b07..6f6b0f5bd6e 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -39,7 +39,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_pos(), _z(10),
_clickHandler(0), _examineHandler(0),
_alpha(255), _inScene(false) {
- byte id = stream->readUint16LE();
+ uint16 id = stream->readUint16LE();
debug("id: 0x%02x %u", id, id);
uint16 dataSize = stream->readUint16LE();
Commit: eb56d3fbf09270e209dfc53fe9338c820ff52e01
https://github.com/scummvm/scummvm/commit/eb56d3fbf09270e209dfc53fe9338c820ff52e01
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:19+01:00
Commit Message:
AGDS: solved mistery with region extended entries, allow multiple regions per Region instance
Changed paths:
engines/agds/region.cpp
engines/agds/region.h
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index 5da0d57457e..60098b646a1 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -36,9 +36,12 @@ Region::Region(const Common::String &resourceName, Common::SeekableReadStream *s
center.y = stream->readUint16LE();
flags = stream->readUint16LE();
debug("region %s at (%d,%d) %04x", name.c_str(), center.x, center.y, flags);
- if (stream->pos() < size) {
+ while (stream->pos() + 2 <= size) {
uint16 ext = stream->readUint16LE();
- //debug("extended entries %u", ext);
+ if (ext)
+ debug("extended entries %u", ext);
+
+ PointsType points;
while (ext--) {
int16 a = stream->readSint16LE();
int16 b = stream->readSint16LE();
@@ -49,26 +52,35 @@ Region::Region(const Common::String &resourceName, Common::SeekableReadStream *s
debug("extended entry: %d %d", a, b);
points.push_back(Common::Point(a, b));
}
- if (stream->pos() != size)
- warning("region data left: %u", size - stream->pos());
+ regions.push_back(points);
}
}
Region::Region(const Common::Rect rect) : flags(0) {
+ PointsType points;
points.push_back(Common::Point(rect.left, rect.top));
points.push_back(Common::Point(rect.right, rect.top));
points.push_back(Common::Point(rect.right, rect.bottom));
points.push_back(Common::Point(rect.left, rect.bottom));
+ regions.push_back(points);
+
center.x = (rect.left + rect.right) / 2;
center.y = (rect.top + rect.bottom) / 2;
}
Common::String Region::toString() const {
Common::String str = Common::String::format("region(%d, %d, [", center.x, center.y);
- for (size_t i = 0; i < points.size(); ++i) {
+ for (size_t i = 0; i < regions.size(); ++i) {
if (i != 0)
str += ", ";
- str += Common::String::format("(%d, %d)", points[i].x, points[i].y);
+ str += "Region {";
+ const PointsType &points = regions[i];
+ for (size_t j = 0; j < points.size(); ++j) {
+ if (j != 0)
+ str += ", ";
+ str += Common::String::format("(%d, %d)", points[j].x, points[j].y);
+ }
+ str += "}";
}
str += "]";
return str;
@@ -79,21 +91,28 @@ void Region::move(Common::Point rel) {
return;
center += rel;
- for (uint i = 0; i < points.size(); ++i)
- points[i] += rel;
+ for (uint i = 0; i < regions.size(); ++i) {
+ PointsType &points = regions[i];
+ for (uint j = 0; j < points.size(); ++j)
+ points[j] += rel;
+ }
}
Common::Point Region::topLeft() const {
- if (points.empty())
+ if (regions.empty())
return Common::Point();
- Common::Point p = points[0];
- for(uint i = 1; i < points.size(); ++i) {
- Common::Point point = points[i];
- if (point.x < p.x)
- p.x = point.x;
- if (point.y < p.y)
- p.y = point.y;
+ Common::Point p = regions[0][0];
+ for(uint i = 0; i < regions.size(); ++i) {
+ const PointsType &points = regions[i];
+
+ for(uint j = 0; j < points.size(); ++j) {
+ Common::Point point = points[j];
+ if (point.x < p.x)
+ p.x = point.x;
+ if (point.y < p.y)
+ p.y = point.y;
+ }
}
return p;
}
@@ -105,45 +124,49 @@ typedef struct {
} dPoint;
bool Region::pointIn(Common::Point point) const {
- uint32 size = points.size();
- if (size < 3) {
- return false;
- }
+ for(uint r = 0; r < regions.size(); ++r) {
+ const PointsType &points = regions[r];
+ uint32 size = points.size();
+ if (size < 3) {
+ continue;
+ }
- int counter = 0;
- double xinters;
- dPoint p, p1, p2;
+ int counter = 0;
+ double xinters;
+ dPoint p, p1, p2;
- p.x = (double)point.x;
- p.y = (double)point.y;
+ p.x = (double)point.x;
+ p.y = (double)point.y;
- p1.x = (double)points[0].x;
- p1.y = (double)points[0].y;
+ p1.x = (double)points[0].x;
+ p1.y = (double)points[0].y;
- for (uint32 i = 1; i <= size; i++) {
- p2.x = (double)points[i % size].x;
- p2.y = (double)points[i % size].y;
+ for (uint32 i = 1; i <= size; i++) {
+ p2.x = (double)points[i % size].x;
+ p2.y = (double)points[i % size].y;
- if (p.y > MIN(p1.y, p2.y)) {
- if (p.y <= MAX(p1.y, p2.y)) {
- if (p.x <= MAX(p1.x, p2.x)) {
- if (p1.y != p2.y) {
- xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
- if (p1.x == p2.x || p.x <= xinters) {
- counter++;
+ if (p.y > MIN(p1.y, p2.y)) {
+ if (p.y <= MAX(p1.y, p2.y)) {
+ if (p.x <= MAX(p1.x, p2.x)) {
+ if (p1.y != p2.y) {
+ xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
+ if (p1.x == p2.x || p.x <= xinters) {
+ counter++;
+ }
}
}
}
}
+ p1 = p2;
}
- p1 = p2;
- }
- if (counter % 2 == 0) {
- return false;
- } else {
- return true;
+ if (counter % 2 == 0) {
+ continue;
+ } else {
+ return true;
+ }
}
+ return false;
}
} // namespace AGDS
diff --git a/engines/agds/region.h b/engines/agds/region.h
index d6de9a80fa3..68087ae418d 100644
--- a/engines/agds/region.h
+++ b/engines/agds/region.h
@@ -36,7 +36,7 @@ struct Region {
Common::String name;
Common::Point center;
uint16 flags;
- PointsType points;
+ Common::Array<PointsType> regions;
Region(const Common::String &resourceName, Common::SeekableReadStream * stream);
Region(const Common::Rect rect);
Commit: c6b6f371cd8034ef696aa3ca5ce6ad699be6a909
https://github.com/scummvm/scummvm/commit/c6b6f371cd8034ef696aa3ca5ce6ad699be6a909
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:19+01:00
Commit Message:
AGDS: save opcode 209 (user use?) handler
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 6f6b0f5bd6e..8503b07cee7 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -38,6 +38,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_animation(), _mouseCursor(),
_pos(), _z(10),
_clickHandler(0), _examineHandler(0),
+ _userUseHandler(0),
_alpha(255), _inScene(false) {
uint16 id = stream->readUint16LE();
debug("id: 0x%02x %u", id, id);
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 42bd9bb7738..e273398cf2a 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -73,6 +73,7 @@ private:
Common::String _text;
uint _clickHandler;
uint _examineHandler;
+ uint _userUseHandler;
int _alpha;
bool _inScene;
@@ -153,6 +154,10 @@ public:
_useHandlers[name] = ip;
}
+ void setUserUseHandler(uint ip) {
+ _userUseHandler = ip;
+ }
+
void paint(AGDSEngine &engine, Graphics::Surface &backbuffer);
void moveTo(Common::Point pos);
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index cf3b3754e77..f841d7e47b4 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -226,7 +226,7 @@ enum Opcode {
kModifyMouseArea = 206,
kSetRain = 207,
kFogOnCharacter = 208,
- kStub209 = 209,
+ kObjectRegisterUserUseHandler = 209,
kStub210 = 210,
kStub211 = 211,
kSetSampleVolumeAndPan = 212,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index cef8a3c44b2..56eade32862 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -227,6 +227,8 @@ private:
void onObjectB9(unsigned size);
void onObjectBD(unsigned size);
void onObjectUse(unsigned size);
+ void onObjectUserUse(unsigned size);
+
void stub82();
void stub83();
@@ -255,7 +257,6 @@ private:
void stub199();
void stub201(unsigned size);
void stub202(unsigned size);
- void stub209(unsigned size);
void stub215();
void stub216();
void stub217();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 743bc0c72d6..09d96dcac4f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -481,6 +481,12 @@ void Process::onObjectUse(unsigned size) {
_ip += size;
}
+void Process::onObjectUserUse(unsigned size) {
+ debug("register user use handler %u", _ip);
+ _object->setUserUseHandler(_ip);
+ _ip += size;
+}
+
void Process::setScreenHeight() {
int arg2 = pop();
int arg1 = pop();
@@ -720,11 +726,6 @@ void Process::stub202(unsigned size) {
_ip += size;
}
-void Process::stub209(unsigned size) {
- debug("stub209, [handler] %u instructions", size);
- _ip += size;
-}
-
void Process::modifyMouseArea() {
int enabled = pop();
int id = pop();
@@ -1536,7 +1537,7 @@ ProcessExitCode Process::resume() {
OP(kFogOnCharacter, fogOnCharacter);
OP(kSetTileIndex, setTileIndex);
OP(kModifyMouseArea, modifyMouseArea);
- OP_U(kStub209, stub209);
+ OP_U(kObjectRegisterUserUseHandler, onObjectUserUse);
OP_I(kMoveCharacterNoUserMove, moveCharacter, false);
OP_U(kOnKey, onKey);
OP(kGetSampleVolume, getSampleVolume);
Commit: c6a35102bd6219bdf420bd817ad4d2abb9cfa6c9
https://github.com/scummvm/scummvm/commit/c6a35102bd6219bdf420bd817ad4d2abb9cfa6c9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:19+01:00
Commit Message:
AGDS: fix constant reloading of inventory region
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index a9d434c87a8..611400faecb 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -702,10 +702,16 @@ void AGDSEngine::tickInventory() {
}
const Common::String &inv_region_name = getSystemVariable("inv_region")->getString();
- if (inv_region_name.empty())
- return;
+ if (!inv_region_name.empty()) {
+ if (!_inventoryRegion || _inventoryRegionName != inv_region_name) {
+ _inventoryRegionName = inv_region_name;
+ _inventoryRegion = loadRegion(inv_region_name);
+ }
+ } else {
+ _inventoryRegionName.clear();
+ _inventoryRegion.reset();
+ }
- _inventoryRegion = loadRegion(inv_region_name);
}
bool AGDSEngine::tickDialog() {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 1d9f746e98c..3c47c4f83b9 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -257,6 +257,7 @@ private:
MouseMap _mouseMap;
Common::RandomSource _random;
Inventory _inventory;
+ Common::String _inventoryRegionName;
RegionPtr _inventoryRegion;
bool _fastMode;
DialogDefsType _dialogDefs;
Commit: d10f369c954864b050941bea3ba199d9a505e3e9
https://github.com/scummvm/scummvm/commit/d10f369c954864b050941bea3ba199d9a505e3e9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:19+01:00
Commit Message:
AGDS: rip dialog off the engine
Changed paths:
A engines/agds/dialog.cpp
A engines/agds/dialog.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/module.mk
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 611400faecb..5a16fd5345c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -52,8 +52,8 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_random("agds"),
_inventoryRegion(),
_soundManager(this, system->getMixer()),
- _fastMode(false),
- _dialogScriptPos(0) {
+ _dialog(this),
+ _fastMode(true) {
}
AGDSEngine::~AGDSEngine() {
@@ -254,7 +254,7 @@ void AGDSEngine::newGame() {
}
void AGDSEngine::tick() {
- if (tickDialog())
+ if (_dialog.tick())
return;
tickInventory();
runProcesses();
@@ -648,44 +648,6 @@ SystemVariable *AGDSEngine::getSystemVariable(const Common::String &name) {
error("no system variable %s", name.c_str());
}
-void AGDSEngine::runDialog(const Common::String &dialogScript, const Common::String &defs) {
- parseDialogDefs(defs);
- _dialogScript = dialogScript;
- _dialogScriptPos = 0;
- getSystemVariable("dialog_var")->setInteger(-1);
-}
-
-void AGDSEngine::parseDialogDefs(const Common::String &defs) {
- Common::String name, value;
- bool readName = true;
- for (uint32 p = 0, size = defs.size(); p < size; ++p) {
- char ch = defs[p];
- if (ch == ' ') {
- continue;
- } else if (ch == '\n' || ch == '\r') {
- //debug("dialog definition: '%s' = '%s'", name.c_str(), value.c_str());
- if (!name.empty() && !value.empty()) {
- _dialogDefs[name] = atoi(value.c_str());
- }
- readName = true;
- name.clear();
- value.clear();
- continue;
- } else if (ch == '=') {
- if (readName) {
- readName = false;
- } else {
- warning("equal sign in value, skipping");
- }
- } else {
- if (readName)
- name += ch;
- else
- value += ch;
- }
- }
-}
-
void AGDSEngine::tickInventory() {
if (!_inventory.enabled() && _inventory.visible()) {
debug("closing inventory...");
@@ -714,64 +676,6 @@ void AGDSEngine::tickInventory() {
}
-bool AGDSEngine::tickDialog() {
- if (_dialogProcessName.empty())
- return false;
-
- int dialog_var = getSystemVariable("dialog_var")->getInteger();
- if (dialog_var > 0) {
- getSystemVariable("dialog_var")->setInteger(-3);
- return false;
- } else if (dialog_var < 0) {
- getSystemVariable("dialog_var")->setInteger(0);
- return true;
- }
-
- uint n = _dialogScript.size();
- if (_dialogScriptPos >= n)
- return false;
-
- Common::String line;
- while (_dialogScriptPos < n && _dialogScript[_dialogScriptPos] != '\n' && _dialogScript[_dialogScriptPos] != '\r') {
- line += _dialogScript[_dialogScriptPos++];
- }
- ++_dialogScriptPos;
-
- if (line.empty())
- return true;
-
- if (line[0] == '@') {
- if (line[1] == '@') //comment
- return true;
-
- line.erase(0, 1);
-
- if (line.hasPrefix("sound")) {
- debug("sound: %s", line.c_str());
- } else {
- DialogDefsType::const_iterator it = _dialogDefs.find(line);
- if (it != _dialogDefs.end()) {
- int value = it->_value;
- debug("dialog value %d (0x%04x)", value, value);
- getSystemVariable("dialog_var")->setInteger(value);
- } else
- warning("invalid dialog directive: %s", line.c_str());
- }
- } else if (line[0] == ' ') {
- debug("text: %s", line.c_str() + 1);
- }
- if (_dialogScriptPos >= n && !_dialogProcessName.empty()) {
- Common::String process = _dialogProcessName;
- _dialogProcessName.clear();
-
- debug("end of dialog, running %s", process.c_str());
- runObject(process);
- getSystemVariable("dialog_var")->setInteger(-2);
- return false;
- }
- return true;
-}
-
bool AGDSEngine::hasFeature(EngineFeature f) const {
switch (f) {
case kSupportsSubtitleOptions:
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 3c47c4f83b9..78cc0db0831 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -31,6 +31,7 @@
#include "engines/advancedDetector.h"
#include "agds/soundManager.h"
#include "agds/database.h"
+#include "agds/dialog.h"
#include "agds/inventory.h"
#include "agds/mouseMap.h"
#include "agds/processExitCode.h"
@@ -192,10 +193,11 @@ public:
}
void runDialog(const Common::String &dialogProcess) {
- _dialogProcessName = dialogProcess;
+ _dialog.run(dialogProcess);
+ }
+ void loadDialog(const Common::String &dialogScript, const Common::String & defs) {
+ _dialog.load(dialogScript, defs);
}
- void runDialog(const Common::String &dialogScript, const Common::String & defs);
- bool tickDialog();
void tickInventory();
void playSound(const Common::String &resource, const Common::String &phaseVar) {
@@ -211,7 +213,6 @@ public:
}
private:
- void parseDialogDefs(const Common::String &defs);
void loadPatches(Common::SeekableReadStream *file, Database & db);
typedef Common::HashMap<int, Graphics::TransparentSurface *> PictureCacheType;
@@ -223,7 +224,6 @@ private:
typedef Common::HashMap<Common::String, Animation *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> AnimationsType;
typedef Common::HashMap<Common::String, Character *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> CharactersType;
typedef Common::HashMap<int, Font *> FontsType;
- typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> DialogDefsType;
typedef Common::HashMap<Common::String, PatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PatchesType;
const ADGameDescription * _gameDescription;
@@ -259,11 +259,8 @@ private:
Inventory _inventory;
Common::String _inventoryRegionName;
RegionPtr _inventoryRegion;
+ Dialog _dialog;
bool _fastMode;
- DialogDefsType _dialogDefs;
- Common::String _dialogScript;
- uint32 _dialogScriptPos;
- Common::String _dialogProcessName;
};
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
new file mode 100644
index 00000000000..23e82103349
--- /dev/null
+++ b/engines/agds/dialog.cpp
@@ -0,0 +1,113 @@
+#include "agds/dialog.h"
+#include "agds/agds.h"
+#include "agds/systemVariable.h"
+#include "agds/object.h"
+#include "common/debug.h"
+
+namespace AGDS {
+
+void Dialog::run(const Common::String & dialogProcess) {
+ _dialogProcessName = dialogProcess;
+}
+
+void Dialog::parseDialogDefs(const Common::String &defs) {
+ _dialogDefs.clear();
+ Common::String name, value;
+ bool readName = true;
+ for (uint32 p = 0, size = defs.size(); p < size; ++p) {
+ char ch = defs[p];
+ if (ch == ' ') {
+ continue;
+ } else if (ch == '\n' || ch == '\r') {
+ //debug("dialog definition: '%s' = '%s'", name.c_str(), value.c_str());
+ if (!name.empty() && !value.empty()) {
+ _dialogDefs[name] = atoi(value.c_str());
+ }
+ readName = true;
+ name.clear();
+ value.clear();
+ continue;
+ } else if (ch == '=') {
+ if (readName) {
+ readName = false;
+ } else {
+ warning("equal sign in value, skipping");
+ }
+ } else {
+ if (readName)
+ name += ch;
+ else
+ value += ch;
+ }
+ }
+}
+
+void Dialog::load(const Common::String &dialogScript, const Common::String &defs) {
+ parseDialogDefs(defs);
+ _dialogScript = dialogScript;
+ _dialogScriptPos = 0;
+ _engine->getSystemVariable("dialog_var")->setInteger(-1);
+}
+
+
+
+bool Dialog::tick() {
+ if (_dialogProcessName.empty())
+ return false;
+
+ int dialog_var = _engine->getSystemVariable("dialog_var")->getInteger();
+ if (dialog_var > 0) {
+ _engine->getSystemVariable("dialog_var")->setInteger(-3);
+ return false;
+ } else if (dialog_var < 0) {
+ _engine->getSystemVariable("dialog_var")->setInteger(0);
+ return true;
+ }
+
+ uint n = _dialogScript.size();
+ if (_dialogScriptPos >= n)
+ return false;
+
+ Common::String line;
+ while (_dialogScriptPos < n && _dialogScript[_dialogScriptPos] != '\n' && _dialogScript[_dialogScriptPos] != '\r') {
+ line += _dialogScript[_dialogScriptPos++];
+ }
+ ++_dialogScriptPos;
+
+ if (line.empty())
+ return true;
+
+ if (line[0] == '@') {
+ if (line[1] == '@') //comment
+ return true;
+
+ line.erase(0, 1);
+
+ if (line.hasPrefix("sound")) {
+ debug("sound: %s", line.c_str());
+ } else {
+ DialogDefsType::const_iterator it = _dialogDefs.find(line);
+ if (it != _dialogDefs.end()) {
+ int value = it->_value;
+ debug("dialog value %d (0x%04x)", value, value);
+ _engine->getSystemVariable("dialog_var")->setInteger(value);
+ } else
+ warning("invalid dialog directive: %s", line.c_str());
+ }
+ } else if (line[0] == ' ') {
+ debug("text: %s", line.c_str() + 1);
+ }
+ if (_dialogScriptPos >= n && !_dialogProcessName.empty()) {
+ Common::String process = _dialogProcessName;
+ _dialogProcessName.clear();
+
+ debug("end of dialog, running %s", process.c_str());
+ _engine->runObject(process);
+ _engine->getSystemVariable("dialog_var")->setInteger(-2);
+ return false;
+ }
+ return true;
+}
+
+
+}
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
new file mode 100644
index 00000000000..59586fabe29
--- /dev/null
+++ b/engines/agds/dialog.h
@@ -0,0 +1,57 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_DIALOG_H
+#define AGDS_DIALOG_H
+
+#include "common/scummsys.h"
+#include "common/hash-str.h"
+#include "common/hashmap.h"
+#include "common/str.h"
+
+namespace AGDS {
+class AGDSEngine;
+
+class Dialog {
+ typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> DialogDefsType;
+
+private:
+ AGDSEngine * _engine;
+ DialogDefsType _dialogDefs;
+ Common::String _dialogScript;
+ uint32 _dialogScriptPos;
+ Common::String _dialogProcessName;
+
+ void parseDialogDefs(const Common::String &defs);
+
+public:
+ Dialog(AGDSEngine *engine): _engine(engine), _dialogScriptPos(0) { }
+ void run(const Common::String &dialogProcess);
+
+ void load(const Common::String &dialogScript, const Common::String & defs);
+ bool tick();
+};
+
+
+} // End of namespace AGDS
+
+#endif /* AGDS_DIALOG_H */
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index e70cc3dffbb..72fe950ef21 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS := \
character.o \
database.o \
detection.o \
+ dialog.o \
font.o \
inventory.o \
mjpgPlayer.o \
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index f841d7e47b4..e12dab08cfc 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -257,7 +257,7 @@ enum Opcode {
kStub237 = 237,
kInventoryFindObjectByName = 238,
kStub239 = 239,
- kRunDialog = 240,
+ kLoadDialog = 240,
kStub241 = 241,
kHasGlobal = 242,
kStub243 = 243,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 56eade32862..cb795416275 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -182,7 +182,7 @@ private:
void setDialogForNextFilm();
void npcSay();
void playerSay();
- void runDialog();
+ void loadDialog();
void setObjectText();
void getRandomNumber();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 09d96dcac4f..b0316328d09 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -899,15 +899,15 @@ void Process::playerSay() {
//close inventory here if close flag was set
}
-void Process::runDialog() {
+void Process::loadDialog() {
Common::String arg3 = popString();
Common::String arg2 = popString();
Common::String arg1 = popString();
- debug("runDialog %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
+ debug("loadDialog %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
arg2 = _engine->loadText(arg2);
arg3 = _engine->loadText(arg3);
- _engine->runDialog(arg2, arg3);
+ _engine->loadDialog(arg2, arg3);
suspend(kExitCodeRunDialog, arg1);
}
@@ -1547,7 +1547,7 @@ ProcessExitCode Process::resume() {
OP(kUserEnabled, userEnabled);
OP(kStub244, stub244);
OP(kInventoryFindObjectByName, inventoryFindObjectByName);
- OP(kRunDialog, runDialog);
+ OP(kLoadDialog, loadDialog);
OP(kHasGlobal, hasGlobal);
OP(kSetDialogForNextFilm, setDialogForNextFilm);
default:
Commit: 0bb1d7ff146fe5cdd26f21d55127dd931f62955e
https://github.com/scummvm/scummvm/commit/0bb1d7ff146fe5cdd26f21d55127dd931f62955e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:20+01:00
Commit Message:
AGDS: kick processes when dialog is active
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 5a16fd5345c..ce752f87d3c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -254,8 +254,10 @@ void AGDSEngine::newGame() {
}
void AGDSEngine::tick() {
- if (_dialog.tick())
+ if (_dialog.tick()) {
+ runProcesses();
return;
+ }
tickInventory();
runProcesses();
}
Commit: 970c7137d2bdf8aa9f7777d0091cca9b1eb571df
https://github.com/scummvm/scummvm/commit/970c7137d2bdf8aa9f7777d0091cca9b1eb571df
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:20+01:00
Commit Message:
AGDS: add two notification opcodes
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index e12dab08cfc..31aef93d6dc 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -241,7 +241,7 @@ enum Opcode {
kPlayAnimationWithPhaseVar = 221,
kStub222 = 222,
kStub223 = 223,
- kStub224 = 224,
+ kSetNPCTellNotifyVar = 224,
kStub225 = 225,
kFadeObject = 226,
kLoadFont = 227,
@@ -261,7 +261,7 @@ enum Opcode {
kStub241 = 241,
kHasGlobal = 242,
kStub243 = 243,
- kStub244 = 244,
+ kSetCharacterNotifyVars = 244,
kStub245 = 245,
kStub246 = 246,
kSetDialogForNextFilm = 247
diff --git a/engines/agds/process.h b/engines/agds/process.h
index cb795416275..d1f8162ad7c 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -271,7 +271,7 @@ private:
void stub233();
void stub235();
void userEnabled();
- void stub244();
+ void setCharacterNotifyVars();
void debug(const char *str, ...);
void error(const char *str, ...);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b0316328d09..d4fae91e185 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1292,14 +1292,13 @@ void Process::stub235() {
suspend();
}
-void Process::stub244() {
+void Process::setCharacterNotifyVars() {
Common::String arg2 = popString();
Common::String arg1 = popString();
- debug("stub244 [text tell status?] %s %s", arg1.c_str(), arg2.c_str());
- _engine->setGlobal(arg1, 1);
- _engine->setGlobal(arg2, 1);
- _engine->getSystemVariable("dialog_var")->setInteger(1);
+ debug("setCharacterNotifyVars, tell: %s, direction: %s", arg1.c_str(), arg2.c_str());
+ _engine->setGlobal(arg1, 0);
+ _engine->setGlobal(arg2, 1); //FIXME: pass current direction
}
//fixme: add trace here
@@ -1545,7 +1544,7 @@ ProcessExitCode Process::resume() {
OP(kStub233, stub233);
OP(kStub235, stub235);
OP(kUserEnabled, userEnabled);
- OP(kStub244, stub244);
+ OP(kSetCharacterNotifyVars, setCharacterNotifyVars);
OP(kInventoryFindObjectByName, inventoryFindObjectByName);
OP(kLoadDialog, loadDialog);
OP(kHasGlobal, hasGlobal);
Commit: 016d59a62f4781d8d8f1cbd4d384fba6f5eba513
https://github.com/scummvm/scummvm/commit/016d59a62f4781d8d8f1cbd4d384fba6f5eba513
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:20+01:00
Commit Message:
AGDS: run dialog object
Changed paths:
engines/agds/dialog.cpp
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 23e82103349..9dfc6889490 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -8,6 +8,7 @@ namespace AGDS {
void Dialog::run(const Common::String & dialogProcess) {
_dialogProcessName = dialogProcess;
+ _engine->runObject(dialogProcess);
}
void Dialog::parseDialogDefs(const Common::String &defs) {
Commit: 12117fb65ffc810f38a0ebe8d8bfd1be5a0b7ba4
https://github.com/scummvm/scummvm/commit/12117fb65ffc810f38a0ebe8d8bfd1be5a0b7ba4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:20+01:00
Commit Message:
AGDS: implement dialog notification stubs
Changed paths:
engines/agds/agds.h
engines/agds/dialog.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 78cc0db0831..f3361cf9ccb 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -127,6 +127,10 @@ public:
return _inventory;
}
+ Dialog & dialog() {
+ return _dialog;
+ }
+
Screen * getCurrentScreen() {
return _currentScreen;
}
@@ -195,9 +199,7 @@ public:
void runDialog(const Common::String &dialogProcess) {
_dialog.run(dialogProcess);
}
- void loadDialog(const Common::String &dialogScript, const Common::String & defs) {
- _dialog.load(dialogScript, defs);
- }
+
void tickInventory();
void playSound(const Common::String &resource, const Common::String &phaseVar) {
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
index 59586fabe29..696aa252b6b 100644
--- a/engines/agds/dialog.h
+++ b/engines/agds/dialog.h
@@ -41,12 +41,28 @@ private:
uint32 _dialogScriptPos;
Common::String _dialogProcessName;
+ Common::String _charNotifyVar;
+ Common::String _charDirectionNotifyVar;
+ Common::String _npcNotifyVar;
+
void parseDialogDefs(const Common::String &defs);
public:
Dialog(AGDSEngine *engine): _engine(engine), _dialogScriptPos(0) { }
void run(const Common::String &dialogProcess);
+ void setCharNotifyVar(const Common::String &name) {
+ _charNotifyVar = name;
+ }
+
+ void setCharDirectionNotifyVar(const Common::String &name) {
+ _charDirectionNotifyVar = name;
+ }
+
+ void setNPCNotifyVar(const Common::String &name) {
+ _npcNotifyVar = name;
+ }
+
void load(const Common::String &dialogScript, const Common::String & defs);
bool tick();
};
diff --git a/engines/agds/process.h b/engines/agds/process.h
index d1f8162ad7c..70e69236458 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -184,6 +184,7 @@ private:
void playerSay();
void loadDialog();
void setObjectText();
+ void setNPCTellNotifyVar();
void getRandomNumber();
void setStringSystemVariable();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d4fae91e185..ed3ed66bb96 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -907,11 +907,17 @@ void Process::loadDialog() {
arg2 = _engine->loadText(arg2);
arg3 = _engine->loadText(arg3);
- _engine->loadDialog(arg2, arg3);
+ _engine->dialog().load(arg2, arg3);
suspend(kExitCodeRunDialog, arg1);
}
+void Process::setNPCTellNotifyVar() {
+ Common::String name = popString();
+ debug("setNPCTellNotifyVar %s", name.c_str());
+ _engine->dialog().setNPCNotifyVar(name);
+}
+
void Process::getObjectPictureWidth() {
Common::String name = popString();
debug("getObjectPictureWidth %s", name.c_str());
@@ -1524,6 +1530,7 @@ ProcessExitCode Process::resume() {
OP(kLeaveCharacterEx, leaveCharacterEx);
OP(kPlayAnimationWithPhaseVar, playAnimationWithPhaseVar);
OP(kStub223, stub223);
+ OP(kSetNPCTellNotifyVar, setNPCTellNotifyVar);
OP(kStub225, stub225);
OP(kFadeObject, fadeObject);
OP(kLoadFont, loadFont);
Commit: 02678b219d73087250a2534c0d1e266dbcf887e2
https://github.com/scummvm/scummvm/commit/02678b219d73087250a2534c0d1e266dbcf887e2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:20+01:00
Commit Message:
AGDS: support sound id
Changed paths:
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 50fb521019e..f7b4ba4e3fe 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -56,7 +56,7 @@ void SoundManager::stopAll() {
}
}
-void SoundManager::play(const Common::String &resource, const Common::String &phaseVar) {
+int SoundManager::play(const Common::String &resource, const Common::String &phaseVar) {
Common::File *file = new Common::File();
if (!file->open(resource))
error("no sound %s", resource.c_str());
@@ -73,12 +73,14 @@ void SoundManager::play(const Common::String &resource, const Common::String &ph
if (!stream) {
warning("could not play sound %s", resource.c_str());
delete file;
- return;
+ return -1;
}
Audio::SoundHandle handle;
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, stream);
+ int id = _nextId++;
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, stream, id);
- _sounds.push_back(Sound(resource, phaseVar, handle));
+ _sounds.push_back(Sound(id, resource, phaseVar, handle));
+ return id;
}
} // namespace AGDS
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index 7112448a3b1..e7d0ecc5886 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -36,25 +36,27 @@ namespace AGDS {
class AGDSEngine;
struct Sound {
+ int id;
Common::String name;
Common::String phaseVar;
Audio::SoundHandle handle;
int group;
- Sound(const Common::String & res, const Common::String & var, Audio::SoundHandle h, int g = 0):
- name(res), phaseVar(var), handle(h), group(g) {
+ Sound(int id_, const Common::String & res, const Common::String & var, Audio::SoundHandle h, int g = 0):
+ id(id_), name(res), phaseVar(var), handle(h), group(g) {
}
};
class SoundManager {
typedef Common::List<Sound> SoundList;
+ int _nextId;
AGDSEngine * _engine;
Audio::Mixer * _mixer;
SoundList _sounds;
public:
- SoundManager(AGDSEngine *engine, Audio::Mixer *mixer): _engine(engine), _mixer(mixer) { }
+ SoundManager(AGDSEngine *engine, Audio::Mixer *mixer): _nextId(1), _engine(engine), _mixer(mixer) { }
void tick();
- void play(const Common::String &file, const Common::String &phaseVar);
+ int play(const Common::String &file, const Common::String &phaseVar);
void stopAll();
};
Commit: 8634ac1d3170111bd67f8a7587bfdeae405120e1
https://github.com/scummvm/scummvm/commit/8634ac1d3170111bd67f8a7587bfdeae405120e1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:20+01:00
Commit Message:
AGDS: replace stub133 with setPanAndVolume
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 31aef93d6dc..62235cbadd9 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -150,7 +150,7 @@ enum Opcode {
kSetCycles = 130,
kSetRandom = 131,
kSetPeriodic = 132,
- kStub133 = 133,
+ kSetPanAndVolume = 133,
kSetAnimationPosition = 134,
kSetPhaseVar = 135,
kSetAnimationLoop = 136,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 70e69236458..3d086501409 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -237,7 +237,7 @@ private:
void resetState();
void setCycles();
void setRandom();
- void stub133();
+ void setPanAndVolume();
void stub138();
void getPictureBaseX();
void getPictureBaseY();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index ed3ed66bb96..b43b6037211 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -552,10 +552,10 @@ void Process::setAnimationZ() {
_animationZ = z;
}
-void Process::stub133() {
+void Process::setPanAndVolume() {
int pan = pop();
int volume = pop();
- debug("stub133: pan? %d volume? %d", pan, volume);
+ debug("setPanAndVolume: pan %d volume %d", pan, volume);
}
void Process::setAnimationLoop() {
@@ -1465,7 +1465,7 @@ ProcessExitCode Process::resume() {
OP(kSetAnimationZ, setAnimationZ);
OP(kSetCycles, setCycles);
OP(kSetRandom, setRandom);
- OP(kStub133, stub133);
+ OP(kSetPanAndVolume, setPanAndVolume);
OP(kSetAnimationPosition, setAnimationPosition);
OP(kSetPhaseVar, setPhaseVar);
OP(kSetAnimationLoop, setAnimationLoop);
Commit: c1d8a003a50f015b9f1e9b5ef441b21ee660eb15
https://github.com/scummvm/scummvm/commit/c1d8a003a50f015b9f1e9b5ef441b21ee660eb15
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:20+01:00
Commit Message:
AGDS: initial tell support
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ce752f87d3c..0a9418cb266 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -595,6 +595,10 @@ void AGDSEngine::addSystemVar(const Common::String &name, SystemVariable *var) {
_systemVars[name] = var;
}
+void AGDSEngine::tell(const Common::String ®ion, const Common::String &text, const Common::String &sound, bool npc) {
+
+}
+
void AGDSEngine::initSystemVariables() {
addSystemVar("inventory_scr", new StringSystemVariable());
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index f3361cf9ccb..667704dc01d 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -206,6 +206,8 @@ public:
_soundManager.play(resource, phaseVar);
}
+ void tell(const Common::String ®ion, const Common::String &text, const Common::String &sound, bool npc);
+
bool fastMode() const {
return _fastMode;
}
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 46aad5ae8a6..1d76f771f6a 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -155,6 +155,10 @@ void Process::run() {
_engine->inventory().add(_engine->loadObject(getExitArg1()));
activate();
break;
+ case kExitCodeCloseInventory:
+ _engine->inventory().enable(false);
+ updateWithCurrentMousePosition();
+ break;
case kExitCodeSuspend:
updateWithCurrentMousePosition();
break;
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 3d086501409..da833d3b613 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -182,6 +182,7 @@ private:
void setDialogForNextFilm();
void npcSay();
void playerSay();
+ void tell(bool npc);
void loadDialog();
void setObjectText();
void setNPCTellNotifyVar();
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index cee83e5d224..3d17b1fcd6a 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -38,6 +38,7 @@ namespace AGDS {
kExitCodeCreatePatchLoadResources = 13,
kExitCodeLoadSaveGame = 14,
kExitCodeExitScreen = 15,
+ kExitCodeCloseInventory = 16,
kExitCodeLoadPreviousScreenObject = 99
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b43b6037211..dac4a7fc73e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -145,6 +145,7 @@ void Process::loadSample() {
return;
}
_engine->playSound(name, _phaseVar);
+ suspend();
}
void Process::getSampleVolume() {
@@ -884,19 +885,26 @@ void Process::setDialogForNextFilm() {
debug("setDialogForNextFilm %d", value);
}
-void Process::npcSay() {
- debug("npcSay -> playerSay");
- playerSay();
-}
-
-void Process::playerSay() {
+void Process::tell(bool npc) {
Common::String sound = popText();
- Common::String arg2 = popText();
- Common::String arg1 = popString();
- debug("playerSay '%s' '%s' '%s'", arg1.c_str(), arg2.c_str(), sound.c_str());
+ Common::String text = popText();
+ Common::String region = popString();
+ debug("%s '%s' '%s' '%s'", npc? "npcSay": "playerSay", region.c_str(), text.c_str(), sound.c_str());
+ _engine->tell(region, text, sound, npc);
+
if (!sound.empty())
_engine->playSound(sound, _phaseVar);
//close inventory here if close flag was set
+ Common::String inventoryClose = _engine->getSystemVariable("inv_close")->getString();
+ suspend(!inventoryClose.empty()? kExitCodeCloseInventory: kExitCodeSuspend);
+}
+
+void Process::npcSay() {
+ tell(true);
+}
+
+void Process::playerSay() {
+ tell(false);
}
void Process::loadDialog() {
Commit: 4c7f566078e7a558a59f8f6322f0abea7270c34a
https://github.com/scummvm/scummvm/commit/4c7f566078e7a558a59f8f6322f0abea7270c34a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:20+01:00
Commit Message:
AGDS: add text output to engine
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 0a9418cb266..8eb46502fce 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -53,6 +53,10 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_inventoryRegion(),
_soundManager(this, system->getMixer()),
_dialog(this),
+ _tellPlayer(true),
+ _tellFontId(0),
+ _tellTextTimer(0),
+ _syncSoundId(-1),
_fastMode(true) {
}
@@ -444,6 +448,12 @@ Common::Error AGDSEngine::run() {
for (CharactersType::iterator i = _characters.begin(); i != _characters.end(); ++i)
i->_value->paint(*this, *backbuffer);
+ if (!_tellText.empty()) {
+ Font *font = getFont(_tellFontId);
+ int w = getSystemVariable("subtitle_width")->getInteger();
+ font->drawString(backbuffer, _tellText, _tellPos.x, _tellPos.y, backbuffer->w, 0);
+ }
+
_system->unlockScreen();
_system->updateScreen();
@@ -466,8 +476,15 @@ void AGDSEngine::playFilm(const Common::String &video, const Common::String &aud
}
void AGDSEngine::skipFilm() {
+ debug("skip");
delete _mjpgPlayer;
_mjpgPlayer = NULL;
+ if (_syncSoundId >= 0) {
+ debug("skip: stopping sound %d", _syncSoundId);
+ _mixer->stopID(_syncSoundId);
+ _syncSoundId = -1;
+ }
+ _tellText.clear();
}
int AGDSEngine::appendToSharedStorage(const Common::String &value) {
@@ -595,8 +612,25 @@ void AGDSEngine::addSystemVar(const Common::String &name, SystemVariable *var) {
_systemVars[name] = var;
}
-void AGDSEngine::tell(const Common::String ®ion, const Common::String &text, const Common::String &sound, bool npc) {
-
+void AGDSEngine::tell(const Common::String ®ionName, const Common::String &text, const Common::String &sound, const Common::String &soundPhaseVar, bool npc) {
+ _tellPlayer = !npc;
+ _tellText = text;
+ _tellFontId = getSystemVariable(npc? "npc_tell_font": "tell_font")->getInteger();
+ int cx, cy;
+ if (regionName.empty()) {
+ cx = getSystemVariable("subtitle_x")->getInteger();
+ cy = getSystemVariable("subtitle_y")->getInteger();
+ } else {
+ RegionPtr region = loadRegion(regionName);
+ cx = region->center.x;
+ cy = region->center.y;
+ }
+ Font *font = getFont(_tellFontId);
+ int w = font->getStringWidth(text), h = font->getFontHeight();
+ _tellPos.x = (cx - w / 2);
+ _tellPos.y = (cy - h / 2);
+ if (!sound.empty())
+ playSoundSync(sound, soundPhaseVar);
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 667704dc01d..e0e50e5ba9c 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -115,7 +115,7 @@ public:
int appendToSharedStorage(const Common::String &value);
const Common::String & getSharedStorage(int id) const;
- bool active() const { return !_mjpgPlayer; }
+ bool active() const { return !_mjpgPlayer && !(_soundManager.playing(_syncSoundId) || _tellTextTimer > 0); }
void playFilm(const Common::String &video, const Common::String &audio);
void skipFilm();
@@ -202,11 +202,15 @@ public:
void tickInventory();
- void playSound(const Common::String &resource, const Common::String &phaseVar) {
- _soundManager.play(resource, phaseVar);
+ int playSound(const Common::String &resource, const Common::String &phaseVar) {
+ return _soundManager.play(resource, phaseVar);
}
- void tell(const Common::String ®ion, const Common::String &text, const Common::String &sound, bool npc);
+ void playSoundSync(const Common::String &resource, const Common::String &phaseVar) {
+ _syncSoundId = playSound(resource, phaseVar);
+ }
+
+ void tell(const Common::String ®ion, const Common::String &text, const Common::String &sound, const Common::String &soundPhaseVar, bool npc);
bool fastMode() const {
return _fastMode;
@@ -264,6 +268,16 @@ private:
Common::String _inventoryRegionName;
RegionPtr _inventoryRegion;
Dialog _dialog;
+
+ // Original engine use weird names for the vars, I keep them.
+ Common::Point _tellPos;
+ Common::String _tellText;
+ int _tellTextTimer;
+ bool _tellPlayer;
+ int _tellFontId;
+
+ int _syncSoundId;
+
bool _fastMode;
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index dac4a7fc73e..d95e10d0012 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -890,10 +890,8 @@ void Process::tell(bool npc) {
Common::String text = popText();
Common::String region = popString();
debug("%s '%s' '%s' '%s'", npc? "npcSay": "playerSay", region.c_str(), text.c_str(), sound.c_str());
- _engine->tell(region, text, sound, npc);
+ _engine->tell(region, text, sound, _phaseVar, npc);
- if (!sound.empty())
- _engine->playSound(sound, _phaseVar);
//close inventory here if close flag was set
Common::String inventoryClose = _engine->getSystemVariable("inv_close")->getString();
suspend(!inventoryClose.empty()? kExitCodeCloseInventory: kExitCodeSuspend);
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index f7b4ba4e3fe..b8d698260b0 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -83,4 +83,8 @@ int SoundManager::play(const Common::String &resource, const Common::String &pha
return id;
}
+bool SoundManager::playing(int id) const {
+ return _mixer->isSoundIDActive(id);
+}
+
} // namespace AGDS
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index e7d0ecc5886..2f133fdc6d3 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -57,6 +57,7 @@ namespace AGDS {
SoundManager(AGDSEngine *engine, Audio::Mixer *mixer): _nextId(1), _engine(engine), _mixer(mixer) { }
void tick();
int play(const Common::String &file, const Common::String &phaseVar);
+ bool playing(int id) const;
void stopAll();
};
Commit: 949c876e8b0e46cfdf1f8ff018083e856a23550a
https://github.com/scummvm/scummvm/commit/949c876e8b0e46cfdf1f8ff018083e856a23550a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:20+01:00
Commit Message:
AGDS: implement text layout to handle multiline aligned layouts
Changed paths:
A engines/agds/textLayout.cpp
A engines/agds/textLayout.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/module.mk
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 8eb46502fce..69fab22e689 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -54,7 +54,6 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_soundManager(this, system->getMixer()),
_dialog(this),
_tellPlayer(true),
- _tellFontId(0),
_tellTextTimer(0),
_syncSoundId(-1),
_fastMode(true) {
@@ -448,10 +447,8 @@ Common::Error AGDSEngine::run() {
for (CharactersType::iterator i = _characters.begin(); i != _characters.end(); ++i)
i->_value->paint(*this, *backbuffer);
- if (!_tellText.empty()) {
- Font *font = getFont(_tellFontId);
- int w = getSystemVariable("subtitle_width")->getInteger();
- font->drawString(backbuffer, _tellText, _tellPos.x, _tellPos.y, backbuffer->w, 0);
+ if (_textLayout.valid()) {
+ _textLayout.paint(*this, *backbuffer);
}
_system->unlockScreen();
@@ -484,7 +481,7 @@ void AGDSEngine::skipFilm() {
_mixer->stopID(_syncSoundId);
_syncSoundId = -1;
}
- _tellText.clear();
+ _textLayout.reset();
}
int AGDSEngine::appendToSharedStorage(const Common::String &value) {
@@ -614,21 +611,17 @@ void AGDSEngine::addSystemVar(const Common::String &name, SystemVariable *var) {
void AGDSEngine::tell(const Common::String ®ionName, const Common::String &text, const Common::String &sound, const Common::String &soundPhaseVar, bool npc) {
_tellPlayer = !npc;
- _tellText = text;
- _tellFontId = getSystemVariable(npc? "npc_tell_font": "tell_font")->getInteger();
- int cx, cy;
+ int font_id = getSystemVariable(npc? "npc_tell_font": "tell_font")->getInteger();
+ Common::Point pos;
+
if (regionName.empty()) {
- cx = getSystemVariable("subtitle_x")->getInteger();
- cy = getSystemVariable("subtitle_y")->getInteger();
+ pos.x = getSystemVariable("subtitle_x")->getInteger();
+ pos.y = getSystemVariable("subtitle_y")->getInteger();
} else {
RegionPtr region = loadRegion(regionName);
- cx = region->center.x;
- cy = region->center.y;
+ pos = region->center;
}
- Font *font = getFont(_tellFontId);
- int w = font->getStringWidth(text), h = font->getFontHeight();
- _tellPos.x = (cx - w / 2);
- _tellPos.y = (cy - h / 2);
+ _textLayout.layout(*this, text, pos, font_id);
if (!sound.empty())
playSoundSync(sound, soundPhaseVar);
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index e0e50e5ba9c..1bb5f7767d7 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -37,6 +37,7 @@
#include "agds/processExitCode.h"
#include "agds/resourceManager.h"
#include "agds/screen.h"
+#include "agds/textLayout.h"
#include "graphics/pixelformat.h"
#include "video/flic_decoder.h"
@@ -270,11 +271,9 @@ private:
Dialog _dialog;
// Original engine use weird names for the vars, I keep them.
- Common::Point _tellPos;
- Common::String _tellText;
int _tellTextTimer;
bool _tellPlayer;
- int _tellFontId;
+ TextLayout _textLayout;
int _syncSoundId;
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index 72fe950ef21..d04b79d541f 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -19,7 +19,8 @@ MODULE_OBJS := \
resourceManager.o \
screen.o \
soundManager.o \
- systemVariable.o
+ systemVariable.o \
+ textLayout.o
# This module can be built as a plugin
ifeq ($(ENABLE_AGDS), DYNAMIC_PLUGIN)
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
new file mode 100644
index 00000000000..91ad9e00147
--- /dev/null
+++ b/engines/agds/textLayout.cpp
@@ -0,0 +1,68 @@
+#include "agds/textLayout.h"
+#include "agds/font.h"
+#include "agds/agds.h"
+#include "agds/object.h"
+#include "common/debug.h"
+
+namespace AGDS {
+
+void TextLayout::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
+ if (!_valid)
+ return;
+ Font *font = engine.getFont(_fontId);
+ for(uint i = 0; i < _lines.size(); ++i) {
+ Line & line = _lines[i];
+ font->drawString(&backbuffer, line.text, line.pos.x, line.pos.y, line.size.x, 0);
+ }
+}
+
+void TextLayout::layout(AGDSEngine &engine, const Common::String &text, Common::Point pos, int fontId) {
+ if (text.empty()) {
+ _valid = false;
+ return;
+ }
+
+ _fontId = fontId;
+ Font *font = engine.getFont(fontId);
+
+ _lines.clear();
+ int w = 0;
+
+ Common::Point basePos;
+ size_t begin = 0;
+ while(begin < text.size()) {
+ while(begin < text.size() && text[begin]== '\r')
+ ++begin;
+ size_t end = text.find('\n', begin);
+ if (end == text.npos)
+ end = text.size();
+
+ Common::String line = text.substr(begin, end - begin);
+ debug("parsed line: %s", line.c_str());
+ begin = end + 1;
+ Common::Point size;
+ size.x = font->getStringWidth(line);
+ size.y = font->getFontHeight();
+ _lines.push_back(Line());
+
+ Line & l = _lines.back();
+ l.pos = basePos;
+ l.text = line;
+ l.size = size;
+
+ basePos.y += size.y;
+ if (size.x > w)
+ w = size.x;
+ }
+
+ int dy = -basePos.y / 2;
+ for(uint i = 0; i < _lines.size(); ++i) {
+ Line & line = _lines[i];
+ line.pos.x += pos.x - line.size.x / 2;
+ line.pos.y += pos.y + dy;
+ }
+
+ _valid = true;
+}
+
+}
diff --git a/engines/agds/textLayout.h b/engines/agds/textLayout.h
new file mode 100644
index 00000000000..96df6caa812
--- /dev/null
+++ b/engines/agds/textLayout.h
@@ -0,0 +1,68 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_TEXT_LAYOUT_H
+#define AGDS_TEXT_LAYOUT_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+#include "common/str.h"
+#include "common/rect.h"
+
+namespace Graphics {
+ class Surface;
+}
+
+namespace AGDS {
+
+class AGDSEngine;
+
+class TextLayout {
+ int _fontId;
+ Common::Point _pos;
+ bool _valid;
+
+ struct Line {
+ Common::Point pos;
+ Common::String text;
+ Common::Point size;
+ };
+
+ Common::Array<Line> _lines;
+
+public:
+ TextLayout(): _fontId(-1), _valid(false) {}
+
+ bool valid() const {
+ return _valid;
+ }
+ void reset() {
+ _valid = false;
+ _lines.clear();
+ }
+ void paint(AGDSEngine &engine, Graphics::Surface &backbuffer);
+ void layout(AGDSEngine &engine, const Common::String &text, Common::Point pos, int fontId);
+};
+
+} // End of namespace AGDS
+
+#endif /* AGDS_TEXT_LAYOUT_H */
Commit: 40016b9cdfcb341955fcc662eda343c394c02661
https://github.com/scummvm/scummvm/commit/40016b9cdfcb341955fcc662eda343c394c02661
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:20+01:00
Commit Message:
AGDS: add flag for resetting text after sync sound stops
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 69fab22e689..07c761c1394 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -55,6 +55,7 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_dialog(this),
_tellPlayer(true),
_tellTextTimer(0),
+ _resetTextLayoutIfSyncSoundStops(false),
_syncSoundId(-1),
_fastMode(true) {
}
@@ -447,6 +448,9 @@ Common::Error AGDSEngine::run() {
for (CharactersType::iterator i = _characters.begin(); i != _characters.end(); ++i)
i->_value->paint(*this, *backbuffer);
+ if (_resetTextLayoutIfSyncSoundStops && _textLayout.valid() && !_soundManager.playing(_syncSoundId))
+ _textLayout.reset();
+
if (_textLayout.valid()) {
_textLayout.paint(*this, *backbuffer);
}
@@ -622,8 +626,10 @@ void AGDSEngine::tell(const Common::String ®ionName, const Common::String &te
pos = region->center;
}
_textLayout.layout(*this, text, pos, font_id);
- if (!sound.empty())
+ if (!sound.empty()) {
playSoundSync(sound, soundPhaseVar);
+ _resetTextLayoutIfSyncSoundStops = true;
+ }
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 1bb5f7767d7..7a28d060d70 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -275,6 +275,7 @@ private:
bool _tellPlayer;
TextLayout _textLayout;
+ bool _resetTextLayoutIfSyncSoundStops;
int _syncSoundId;
bool _fastMode;
Commit: 9292639980dccaa252f2686afc1ae13d42bbff79
https://github.com/scummvm/scummvm/commit/9292639980dccaa252f2686afc1ae13d42bbff79
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:21+01:00
Commit Message:
AGDS: move text notification code to TextLayout, it used for both texts/dialogs
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/dialog.cpp
engines/agds/dialog.h
engines/agds/process_opcodes.cpp
engines/agds/textLayout.cpp
engines/agds/textLayout.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 07c761c1394..ba29a6faa7c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -53,7 +53,6 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_inventoryRegion(),
_soundManager(this, system->getMixer()),
_dialog(this),
- _tellPlayer(true),
_tellTextTimer(0),
_resetTextLayoutIfSyncSoundStops(false),
_syncSoundId(-1),
@@ -449,7 +448,7 @@ Common::Error AGDSEngine::run() {
i->_value->paint(*this, *backbuffer);
if (_resetTextLayoutIfSyncSoundStops && _textLayout.valid() && !_soundManager.playing(_syncSoundId))
- _textLayout.reset();
+ _textLayout.reset(*this);
if (_textLayout.valid()) {
_textLayout.paint(*this, *backbuffer);
@@ -485,7 +484,7 @@ void AGDSEngine::skipFilm() {
_mixer->stopID(_syncSoundId);
_syncSoundId = -1;
}
- _textLayout.reset();
+ _textLayout.reset(*this);
}
int AGDSEngine::appendToSharedStorage(const Common::String &value) {
@@ -614,7 +613,6 @@ void AGDSEngine::addSystemVar(const Common::String &name, SystemVariable *var) {
}
void AGDSEngine::tell(const Common::String ®ionName, const Common::String &text, const Common::String &sound, const Common::String &soundPhaseVar, bool npc) {
- _tellPlayer = !npc;
int font_id = getSystemVariable(npc? "npc_tell_font": "tell_font")->getInteger();
Common::Point pos;
@@ -625,7 +623,7 @@ void AGDSEngine::tell(const Common::String ®ionName, const Common::String &te
RegionPtr region = loadRegion(regionName);
pos = region->center;
}
- _textLayout.layout(*this, text, pos, font_id);
+ _textLayout.layout(*this, text, pos, font_id, npc);
if (!sound.empty()) {
playSoundSync(sound, soundPhaseVar);
_resetTextLayoutIfSyncSoundStops = true;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 7a28d060d70..e215cfed496 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -132,6 +132,10 @@ public:
return _dialog;
}
+ TextLayout & textLayout() {
+ return _textLayout;
+ }
+
Screen * getCurrentScreen() {
return _currentScreen;
}
@@ -272,7 +276,6 @@ private:
// Original engine use weird names for the vars, I keep them.
int _tellTextTimer;
- bool _tellPlayer;
TextLayout _textLayout;
bool _resetTextLayoutIfSyncSoundStops;
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 9dfc6889490..6541b0623a1 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -7,6 +7,7 @@
namespace AGDS {
void Dialog::run(const Common::String & dialogProcess) {
+ debug("runDialog: %s", dialogProcess.c_str());
_dialogProcessName = dialogProcess;
_engine->runObject(dialogProcess);
}
@@ -103,7 +104,6 @@ bool Dialog::tick() {
_dialogProcessName.clear();
debug("end of dialog, running %s", process.c_str());
- _engine->runObject(process);
_engine->getSystemVariable("dialog_var")->setInteger(-2);
return false;
}
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
index 696aa252b6b..59586fabe29 100644
--- a/engines/agds/dialog.h
+++ b/engines/agds/dialog.h
@@ -41,28 +41,12 @@ private:
uint32 _dialogScriptPos;
Common::String _dialogProcessName;
- Common::String _charNotifyVar;
- Common::String _charDirectionNotifyVar;
- Common::String _npcNotifyVar;
-
void parseDialogDefs(const Common::String &defs);
public:
Dialog(AGDSEngine *engine): _engine(engine), _dialogScriptPos(0) { }
void run(const Common::String &dialogProcess);
- void setCharNotifyVar(const Common::String &name) {
- _charNotifyVar = name;
- }
-
- void setCharDirectionNotifyVar(const Common::String &name) {
- _charDirectionNotifyVar = name;
- }
-
- void setNPCNotifyVar(const Common::String &name) {
- _npcNotifyVar = name;
- }
-
void load(const Common::String &dialogScript, const Common::String & defs);
bool tick();
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d95e10d0012..2cd6063229a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -921,7 +921,8 @@ void Process::loadDialog() {
void Process::setNPCTellNotifyVar() {
Common::String name = popString();
debug("setNPCTellNotifyVar %s", name.c_str());
- _engine->dialog().setNPCNotifyVar(name);
+ _engine->textLayout().setNPCNotifyVar(name);
+ _engine->setGlobal(name, 0);
}
void Process::getObjectPictureWidth() {
@@ -1310,7 +1311,9 @@ void Process::setCharacterNotifyVars() {
debug("setCharacterNotifyVars, tell: %s, direction: %s", arg1.c_str(), arg2.c_str());
_engine->setGlobal(arg1, 0);
- _engine->setGlobal(arg2, 1); //FIXME: pass current direction
+ _engine->setGlobal(arg2, 0); //FIXME: pass current direction
+ _engine->textLayout().setCharNotifyVar(arg1);
+ _engine->textLayout().setCharDirectionNotifyVar(arg2);
}
//fixme: add trace here
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 91ad9e00147..7a7f66f3a70 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -16,13 +16,26 @@ void TextLayout::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
}
}
-void TextLayout::layout(AGDSEngine &engine, const Common::String &text, Common::Point pos, int fontId) {
+void TextLayout::reset(AGDSEngine &engine) {
+ bool valid = _valid;
+ _valid = false;
+ _lines.clear();
+ if (valid) {
+ Common::String &var = _npc? _npcNotifyVar: _charNotifyVar;
+ if (!var.empty()) {
+ engine.setGlobal(var, 0);
+ }
+ }
+}
+
+void TextLayout::layout(AGDSEngine &engine, const Common::String &text, Common::Point pos, int fontId, bool npc) {
if (text.empty()) {
_valid = false;
return;
}
_fontId = fontId;
+ _npc = npc;
Font *font = engine.getFont(fontId);
_lines.clear();
@@ -63,6 +76,11 @@ void TextLayout::layout(AGDSEngine &engine, const Common::String &text, Common::
}
_valid = true;
+
+ Common::String &var = _npc? _npcNotifyVar: _charNotifyVar;
+ if (!var.empty()) {
+ engine.setGlobal(var, 1);
+ }
}
}
diff --git a/engines/agds/textLayout.h b/engines/agds/textLayout.h
index 96df6caa812..89ac9e91a1d 100644
--- a/engines/agds/textLayout.h
+++ b/engines/agds/textLayout.h
@@ -39,6 +39,7 @@ class AGDSEngine;
class TextLayout {
int _fontId;
Common::Point _pos;
+ bool _npc;
bool _valid;
struct Line {
@@ -49,18 +50,33 @@ class TextLayout {
Common::Array<Line> _lines;
+ Common::String _charNotifyVar;
+ Common::String _charDirectionNotifyVar;
+ Common::String _npcNotifyVar;
+
public:
- TextLayout(): _fontId(-1), _valid(false) {}
+ TextLayout(): _fontId(-1), _npc(true), _valid(false) {}
bool valid() const {
return _valid;
}
- void reset() {
- _valid = false;
- _lines.clear();
+
+ void reset(AGDSEngine &engine);
+
+ void setCharNotifyVar(const Common::String &name) {
+ _charNotifyVar = name;
+ }
+
+ void setCharDirectionNotifyVar(const Common::String &name) {
+ _charDirectionNotifyVar = name;
+ }
+
+ void setNPCNotifyVar(const Common::String &name) {
+ _npcNotifyVar = name;
}
+
void paint(AGDSEngine &engine, Graphics::Surface &backbuffer);
- void layout(AGDSEngine &engine, const Common::String &text, Common::Point pos, int fontId);
+ void layout(AGDSEngine &engine, const Common::String &text, Common::Point pos, int fontId, bool npc);
};
} // End of namespace AGDS
Commit: 90c5654150eb5444a5801963dd12b89a4b35ee14
https://github.com/scummvm/scummvm/commit/90c5654150eb5444a5801963dd12b89a4b35ee14
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:21+01:00
Commit Message:
AGDS: implement explicit activation, do not automatically activate any suspended process
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ba29a6faa7c..75f1a890b38 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -224,14 +224,18 @@ void AGDSEngine::resetCurrentScreen() {
void AGDSEngine::runProcesses() {
for (ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
- Process & process = *i;
- if (process.active() || process.passive()) {
+ Process &process = *i;
+ process.checkTimers();
+ if (process.active()) {
process.run();
++i;
- } else {
+ } else if (process.finished()) {
debug("deleting process %s", process.getName().c_str());
i = _processes.erase(i);
//FIXME: when the last process exits, remove object from scene
+ } else {
+ debug("suspended process %s", process.getName().c_str());
+ ++i;
}
}
@@ -432,6 +436,7 @@ Common::Error AGDSEngine::run() {
if (_mjpgPlayer->eos()) {
delete _mjpgPlayer;
_mjpgPlayer = NULL;
+ reactivate(_filmProcess);
}
} else if (_currentScreen) {
_currentScreen->paint(*this, *backbuffer);
@@ -470,8 +475,15 @@ Common::Error AGDSEngine::run() {
return Common::kNoError;
}
-void AGDSEngine::playFilm(const Common::String &video, const Common::String &audio) {
+void AGDSEngine::playFilm(Process &process, const Common::String &video, const Common::String &audio) {
delete _mjpgPlayer;
+ if (_fastMode) {
+ debug("fast mode, skipping film");
+ process.activate();
+ return;
+ }
+
+ _filmProcess = process.getName();
_mjpgPlayer = new MJPGPlayer(_resourceManager.getResource(video));
}
@@ -485,6 +497,7 @@ void AGDSEngine::skipFilm() {
_syncSoundId = -1;
}
_textLayout.reset(*this);
+ reactivate(_filmProcess);
}
int AGDSEngine::appendToSharedStorage(const Common::String &value) {
@@ -853,6 +866,15 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
return Common::kNoError;
}
+void AGDSEngine::reactivate(const Common::String &name) {
+ for(ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ++i) {
+ Process &process = *i;
+ if (process.getName() == name) {
+ process.activate();
+ }
+ }
+}
+
Common::Error AGDSEngine::saveGameStream(Common::WriteStream *file, bool isAutosave) { return Common::Error(Common::kNoError); }
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index e215cfed496..40cdefbb530 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -117,7 +117,7 @@ public:
const Common::String & getSharedStorage(int id) const;
bool active() const { return !_mjpgPlayer && !(_soundManager.playing(_syncSoundId) || _tellTextTimer > 0); }
- void playFilm(const Common::String &video, const Common::String &audio);
+ void playFilm(Process &process, const Common::String &video, const Common::String &audio);
void skipFilm();
ResourceManager & resourceManager() {
@@ -225,6 +225,8 @@ public:
return _mouse;
}
+ void reactivate(const Common::String &name);
+
private:
void loadPatches(Common::SeekableReadStream *file, Database & db);
@@ -258,6 +260,7 @@ private:
SystemVariablesType _systemVars;
Graphics::PixelFormat _pixelFormat;
MJPGPlayer * _mjpgPlayer;
+ Common::String _filmProcess;
Screen * _currentScreen;
Common::String _currentScreenName;
Common::String _nextScreenName;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 62235cbadd9..de7d1cc8660 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -211,7 +211,7 @@ enum Opcode {
kStub191 = 191,
kStub192 = 192,
kStub193 = 193,
- kStub194 = 194,
+ kMute = 194,
kGetObjectPictureWidth = 195,
kGetObjectPictureHeight = 196,
kStub197 = 197,
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 1d76f771f6a..ba7be5f6cb5 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -120,7 +120,6 @@ void Process::activate() {
void Process::run() {
- activate();
while(status() == kStatusActive) {
ProcessExitCode code = resume();
switch (code) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index da833d3b613..d098ffb364b 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -352,6 +352,7 @@ public:
return _status == kStatusPassive;
}
void activate();
+ void checkTimers();
void done() {
_status = kStatusDone;
}
@@ -359,6 +360,10 @@ public:
_status = kStatusError;
}
+ bool finished() const {
+ return _status == kStatusDone || _status == kStatusError;
+ }
+
void run();
ProcessExitCode getExitCode() const {
@@ -386,6 +391,9 @@ public:
}
void updateWithCurrentMousePosition();
+ const Common::String & phaseVar() const {
+ return _phaseVar;
+ }
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 2cd6063229a..e503b7cdc64 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -139,13 +139,10 @@ void Process::loadAnimation() {
void Process::loadSample() {
Common::String name = popText();
- debug("loadSample %s", name.c_str());
- if (_phaseVar.empty()) {
- warning("playing sample %s without phase var", _phaseVar.c_str());
- return;
- }
+ debug("loadSample %s, phaseVar: %s", name.c_str(), _phaseVar.c_str());
_engine->playSound(name, _phaseVar);
- suspend();
+ if (!_phaseVar.empty())
+ suspend();
}
void Process::getSampleVolume() {
@@ -703,7 +700,7 @@ void Process::disableMouseAreas() {
}
void Process::stub194() {
- debug("stub194: mute?");
+ debug("stub194: mute");
}
void Process::stub199() {
@@ -960,10 +957,8 @@ void Process::playFilm() {
Common::String video = popText();
debug("playFilm %s %s", video.c_str(), audio.c_str());
- if (!_engine->fastMode()) {
- _engine->playFilm(video, audio);
- }
suspend();
+ _engine->playFilm(*this, video, audio);
}
void Process::inventoryClear() {
@@ -1062,9 +1057,9 @@ void Process::call(uint16 addr) {
debug("call %04x", addr);
//original engine just create new process, save exit code in screen object
//and on stack, then just ignore return code, fixme?
- Process process(_engine, _object, _ip + addr);
- process.run();
suspend();
+ _engine->runProcess(_object, _ip + addr);
+ activate();
}
void Process::onKey(unsigned size) {
@@ -1365,14 +1360,17 @@ void Process::setCharacterNotifyVars() {
METHOD(arg1 | (arg2 << 16)); \
} break
-ProcessExitCode Process::resume() {
+
+void Process::checkTimers() {
if (_timer > 0) {
debug("waiting for timer (%d)...", _timer);
--_timer;
- _status = kStatusPassive;
- _exitCode = kExitCodeSuspend;
- return _exitCode;
+ if (_timer == 0)
+ activate();
}
+}
+
+ProcessExitCode Process::resume() {
_exitCode = kExitCodeDestroy;
const Object::CodeType &code = _object->getCode();
@@ -1525,7 +1523,7 @@ ProcessExitCode Process::resume() {
OP(kSetObjectScale, setObjectScale);
OP(kStub191, disableMouseAreas);
OP(kStub193, stub193);
- OP(kStub194, stub194);
+ OP(kMute, stub194);
OP(kGetObjectPictureWidth, getObjectPictureWidth);
OP(kGetObjectPictureHeight, getObjectPictureHeight);
OP(kLoadPicture, loadPicture);
Commit: 07d37e9eaef1dc17a93fbf5e4be3992fbf63daae
https://github.com/scummvm/scummvm/commit/07d37e9eaef1dc17a93fbf5e4be3992fbf63daae
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:21+01:00
Commit Message:
AGDS: process next screen name from tick (as per original)
Changed paths:
engines/agds/agds.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 75f1a890b38..9f852c35dab 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -238,12 +238,6 @@ void AGDSEngine::runProcesses() {
++i;
}
}
-
- while (!_nextScreenName.empty()) {
- Common::String nextScreenName = _nextScreenName;
- _nextScreenName.clear();
- loadScreen(nextScreenName);
- }
}
void AGDSEngine::newGame() {
@@ -261,6 +255,11 @@ void AGDSEngine::newGame() {
}
void AGDSEngine::tick() {
+ while (!_nextScreenName.empty()) {
+ Common::String nextScreenName = _nextScreenName;
+ _nextScreenName.clear();
+ loadScreen(nextScreenName);
+ }
if (_dialog.tick()) {
runProcesses();
return;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index e503b7cdc64..50bc4967408 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1055,11 +1055,7 @@ void Process::loadTextFromObject() {
void Process::call(uint16 addr) {
debug("call %04x", addr);
- //original engine just create new process, save exit code in screen object
- //and on stack, then just ignore return code, fixme?
- suspend();
_engine->runProcess(_object, _ip + addr);
- activate();
}
void Process::onKey(unsigned size) {
Commit: f764ee0eb3fee5600a48dd5976d3b50cd761af6f
https://github.com/scummvm/scummvm/commit/f764ee0eb3fee5600a48dd5976d3b50cd761af6f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:21+01:00
Commit Message:
AGDS: add Screen::applyingPatch() for check patch routine
Changed paths:
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 14f5907bb0f..692df9ebb90 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -37,7 +37,8 @@ int Screen::AnimationZCompare(const Animation *a, const Animation *b) {
return b->z() - a->z();
}
-Screen::Screen(ObjectPtr object) : _object(object), _name(object->getName()), _children(&ObjectZCompare), _animations(&AnimationZCompare) {
+Screen::Screen(ObjectPtr object) : _object(object), _name(object->getName()),
+ _children(&ObjectZCompare), _animations(&AnimationZCompare), _applyingPatch(false) {
add(object);
}
@@ -158,6 +159,7 @@ Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
void Screen::load(AGDSEngine & engine, const PatchPtr &patch) {
debug("applying patch with %u objects", patch->objects.size());
+ _applyingPatch = true;
for(uint i = 0; i < patch->objects.size(); ++i) {
const Patch::Object &object = patch->objects[i];
debug("patch object %s %d", object.name.c_str(), object.flag);
@@ -167,6 +169,7 @@ void Screen::load(AGDSEngine & engine, const PatchPtr &patch) {
engine.runObject(object.name);
}
}
+ _applyingPatch = false;
}
void Screen::save(AGDSEngine & engine, const PatchPtr &patch) {
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index d709209af01..5695cabbce8 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -56,6 +56,7 @@ class Screen {
ChildrenType _children;
AnimationsType _animations;
RegionPtr _region;
+ bool _applyingPatch;
public:
struct KeyHandler {
@@ -69,6 +70,10 @@ public:
Screen(ObjectPtr object);
~Screen();
+ bool applyingPatch() const {
+ return _applyingPatch;
+ }
+
ObjectPtr getObject() {
return _object;
}
Commit: 67379575f7bcfb8d8d1119ae982493e77cfbbb6f
https://github.com/scummvm/scummvm/commit/67379575f7bcfb8d8d1119ae982493e77cfbbb6f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:21+01:00
Commit Message:
AGDS: instantly restart process for some exit codes
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index ba7be5f6cb5..d394665cd13 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -132,7 +132,7 @@ void Process::run() {
case kExitCodeLoadScreenObject:
_engine->runObject(getExitArg1(), getExitArg2());
activate();
- break;
+ continue;
case kExitCodeRunDialog:
_engine->runDialog(getExitArg1());
break;
@@ -149,11 +149,11 @@ void Process::run() {
case kExitCodeMouseAreaChange:
_engine->changeMouseArea(getExitIntArg1(), getExitIntArg2());
activate();
- break;
+ continue;
case kExitCodeLoadInventoryObject:
_engine->inventory().add(_engine->loadObject(getExitArg1()));
activate();
- break;
+ continue;
case kExitCodeCloseInventory:
_engine->inventory().enable(false);
updateWithCurrentMousePosition();
Commit: 69b1d69868d5af4752f1937fa1fafc41d113f674
https://github.com/scummvm/scummvm/commit/69b1d69868d5af4752f1937fa1fafc41d113f674
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:21+01:00
Commit Message:
AGDS: remove old Objects typedef
Changed paths:
engines/agds/agds.h
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 40cdefbb530..2fc39464aac 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -232,7 +232,6 @@ private:
typedef Common::HashMap<int, Graphics::TransparentSurface *> PictureCacheType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PictureCacheLookup;
- typedef Common::HashMap<Common::String, Object *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectsType;
typedef Common::Array<Common::String> SystemVariablesListType;
typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
Commit: 04dc57b49da0c484d4f89f614e4e669a974e2527
https://github.com/scummvm/scummvm/commit/04dc57b49da0c484d4f89f614e4e669a974e2527
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:21+01:00
Commit Message:
AGDS: cleaned up screen changed
Changed paths:
engines/agds/agds.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 9f852c35dab..3e77253546d 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -115,7 +115,7 @@ bool AGDSEngine::load() {
return false;
initSystemVariables();
- loadScreen("main");
+ _nextScreenName = "main";
Common::File file;
file.open("patch.adb");
@@ -156,15 +156,20 @@ ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::Strin
}
void AGDSEngine::runObject(ObjectPtr object) {
+ if (object->inScene()) {
+ debug("object is %s scene, skip running...", object->getName().c_str());
+ return;
+ }
+ if (_currentScreen)
+ _currentScreen->add(object);
+ else
+ warning("object %s has been loaded, but was not added to any screen", object->getName().c_str());
+
runProcess(object);
}
void AGDSEngine::runProcess(ObjectPtr object, uint ip) {
debug("starting process %s:%04x", object->getName().c_str(), ip);
- if (_currentScreen)
- _currentScreen->add(object);
- else
- warning("object %s has been loaded, but was not added to any screen", object->getName().c_str());
_processes.push_front(Process(this, object, ip));
_processes.front().run();
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 50bc4967408..a917dd1b564 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -121,7 +121,7 @@ void Process::loadPicture() {
void Process::loadAnimation() {
Common::String name = popText();
- debug("loadAnimation %s", name.c_str());
+ debug("loadAnimation %s (phase: %s)", name.c_str(), _phaseVar.c_str());
Animation *animation = _engine->loadAnimation(name);
if (animation) {
animation->position(_animationPosition);
@@ -441,16 +441,15 @@ void Process::changeScreenPatch() {
}
if (!screenName.empty()) {
- debug("stub, returning 0");
+ debug("changeScreenPatch: stub, returning 0");
//check that patch exist
push(0);
return;
} else {
//change screen patch (load and return 1)
ObjectPtr object = screen->find(objectName);
- int value = object && object->inScene();
- debug("\t%d", value);
- push(value);
+ debug("changeScreenPatch: recover/inventory stub, returning 0");
+ push(0);
}
}
Commit: 19fedd20dbc42fa052641bdb9267a084fc3284ad
https://github.com/scummvm/scummvm/commit/19fedd20dbc42fa052641bdb9267a084fc3284ad
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:21+01:00
Commit Message:
AGDS: implement process reactivation on sound (if no phase var)
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3e77253546d..cd3a20fe651 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -830,7 +830,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
uint unk0 = agds_a->readUint32LE();
uint unk1 = agds_a->readUint32LE();
debug("saved audio state: sample: %s, var: %s %u %u", sample.c_str(), phaseVar.c_str(), unk0, unk1);
- playSound(sample, phaseVar);
+ playSound(Common::String(), sample, phaseVar); //fixme: double check
}
{
@@ -871,6 +871,10 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
}
void AGDSEngine::reactivate(const Common::String &name) {
+ if (name.empty())
+ return;
+
+ debug("reactivate %s", name.c_str());
for(ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ++i) {
Process &process = *i;
if (process.getName() == name) {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 2fc39464aac..dee635b6867 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -207,12 +207,12 @@ public:
void tickInventory();
- int playSound(const Common::String &resource, const Common::String &phaseVar) {
- return _soundManager.play(resource, phaseVar);
+ int playSound(const Common::String &process, const Common::String &resource, const Common::String &phaseVar) {
+ return _soundManager.play(process, resource, phaseVar);
}
void playSoundSync(const Common::String &resource, const Common::String &phaseVar) {
- _syncSoundId = playSound(resource, phaseVar);
+ _syncSoundId = playSound(Common::String(), resource, phaseVar);
}
void tell(const Common::String ®ion, const Common::String &text, const Common::String &sound, const Common::String &soundPhaseVar, bool npc);
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index de7d1cc8660..bd1e3022570 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -231,7 +231,7 @@ enum Opcode {
kStub211 = 211,
kSetSampleVolumeAndPan = 212,
kStub213 = 213,
- kPlaySound = 214,
+ kAddSampleToSoundGroup = 214,
kStub215 = 215,
kStub216 = 216,
kStub217 = 217,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index d098ffb364b..4de11384c07 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -147,7 +147,7 @@ private:
void loadAnimation();
void setAnimationPosition();
void loadSample();
- void playSound();
+ void addSampleToSoundGroup();
void playFilm();
void getSampleVolume();
void setSampleVolumeAndPan();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index a917dd1b564..85c0ec89011 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -140,7 +140,7 @@ void Process::loadAnimation() {
void Process::loadSample() {
Common::String name = popText();
debug("loadSample %s, phaseVar: %s", name.c_str(), _phaseVar.c_str());
- _engine->playSound(name, _phaseVar);
+ _engine->playSound(getName(), name, _phaseVar);
if (!_phaseVar.empty())
suspend();
}
@@ -158,11 +158,10 @@ void Process::setSampleVolumeAndPan() {
debug("setSampleVolumeAndPan %s %d %d", name.c_str(), volume, pan);
}
-void Process::playSound() {
+void Process::addSampleToSoundGroup() {
Common::String name = popText();
int arg = pop();
- debug("playSound %s %d", name.c_str(), arg);
- _engine->playSound(name, _phaseVar);
+ debug("addSampleToSoundGroup stub: %s sound group: %d", name.c_str(), arg);
}
void Process::updatePhaseVarOr2() {
@@ -1524,7 +1523,7 @@ ProcessExitCode Process::resume() {
OP(kLoadPicture, loadPicture);
OP(kStub199, stub199);
OP(kSetSampleVolumeAndPan, setSampleVolumeAndPan);
- OP(kPlaySound, playSound);
+ OP(kAddSampleToSoundGroup, addSampleToSoundGroup);
OP(kStub215, stub215);
OP(kStub216, stub216);
OP(kStub217, stub217);
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index b8d698260b0..dc521243fe0 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -36,13 +36,15 @@ void SoundManager::tick() {
for (SoundList::iterator i = _sounds.begin(); i != _sounds.end();) {
Sound &sound = *i;
if (!_mixer->isSoundHandleActive(sound.handle)) {
- //FIXME: re-enable me later
- // if (!sound.phaseVar.empty())
- // _engine->setGlobal(sound.phaseVar, -1);
+ if (!sound.phaseVar.empty())
+ _engine->setGlobal(sound.phaseVar, 0);
+ else if (!sound.process.empty()) {
+ _engine->reactivate(sound.process);
+ }
i = _sounds.erase(i);
} else {
- // if (!sound.phaseVar.empty())
- // _engine->setGlobal(sound.phaseVar, _engine->getGlobal(sound.phaseVar) + 1);
+ if (!sound.phaseVar.empty())
+ _engine->setGlobal(sound.phaseVar, 1);
++i;
}
}
@@ -56,7 +58,7 @@ void SoundManager::stopAll() {
}
}
-int SoundManager::play(const Common::String &resource, const Common::String &phaseVar) {
+int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &phaseVar) {
Common::File *file = new Common::File();
if (!file->open(resource))
error("no sound %s", resource.c_str());
@@ -73,13 +75,14 @@ int SoundManager::play(const Common::String &resource, const Common::String &pha
if (!stream) {
warning("could not play sound %s", resource.c_str());
delete file;
+ _engine->reactivate(process);
return -1;
}
Audio::SoundHandle handle;
int id = _nextId++;
_mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, stream, id);
- _sounds.push_back(Sound(id, resource, phaseVar, handle));
+ _sounds.push_back(Sound(id, process, resource, phaseVar, handle));
return id;
}
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index 2f133fdc6d3..49bb97cd6c9 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -37,12 +37,13 @@ namespace AGDS {
struct Sound {
int id;
+ Common::String process;
Common::String name;
Common::String phaseVar;
Audio::SoundHandle handle;
int group;
- Sound(int id_, const Common::String & res, const Common::String & var, Audio::SoundHandle h, int g = 0):
- id(id_), name(res), phaseVar(var), handle(h), group(g) {
+ Sound(int id_, const Common::String &p, const Common::String & res, const Common::String & var, Audio::SoundHandle h, int g = 0):
+ id(id_), process(p), name(res), phaseVar(var), handle(h), group(g) {
}
};
@@ -56,7 +57,7 @@ namespace AGDS {
public:
SoundManager(AGDSEngine *engine, Audio::Mixer *mixer): _nextId(1), _engine(engine), _mixer(mixer) { }
void tick();
- int play(const Common::String &file, const Common::String &phaseVar);
+ int play(const Common::String &process, const Common::String &file, const Common::String &phaseVar);
bool playing(int id) const;
void stopAll();
};
Commit: 121dbfb2d0e39b4bb1df57cfc881fd730bdd6d1c
https://github.com/scummvm/scummvm/commit/121dbfb2d0e39b4bb1df57cfc881fd730bdd6d1c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:21+01:00
Commit Message:
AGDS: pass process to animation to reactivate if no phase var
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index f9513518280..d78e40f93d6 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -54,6 +54,8 @@ bool Animation::load(Common::SeekableReadStream *stream) {
void Animation::updatePhaseVar(AGDSEngine &engine) {
if (!_phaseVar.empty())
engine.setGlobal(_phaseVar, _phase);
+ else if (_phase == -1)
+ engine.reactivate(_process);
}
void Animation::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point dst) {
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index b90cc65283b..c8728dc7443 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -39,6 +39,7 @@ class Animation {
Video::FlicDecoder *_flic;
int _frames;
Common::Point _position;
+ Common::String _process;
Common::String _phaseVar;
bool _loop;
int _cycles;
@@ -63,6 +64,10 @@ public:
_phaseVar = phaseVar;
}
+ void process(const Common::String & process) {
+ _process = process;
+ }
+
void loop(bool loop) {
_loop = loop;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 85c0ec89011..127cab20b04 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -126,6 +126,7 @@ void Process::loadAnimation() {
if (animation) {
animation->position(_animationPosition);
animation->z(_animationZ);
+ animation->process(getName());
animation->phaseVar(_phaseVar);
animation->loop(_animationLoop);
animation->cycles(_animationCycles);
@@ -1248,6 +1249,7 @@ void Process::loadAnimationFromObject() {
Animation *animation = _engine->loadAnimation(name);
if (animation) {
animation->phaseVar(_phaseVar);
+ animation->process(getName());
animation->loop(_animationLoop);
animation->cycles(_animationCycles);
if (_animationPaused)
Commit: 081b3f664f4740ea8b01fe27b64215f188f13c57
https://github.com/scummvm/scummvm/commit/081b3f664f4740ea8b01fe27b64215f188f13c57
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:21+01:00
Commit Message:
AGDS: reworked phase vars
Changed paths:
engines/agds/animation.cpp
engines/agds/dialog.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index d78e40f93d6..a0235bd9973 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -52,8 +52,12 @@ bool Animation::load(Common::SeekableReadStream *stream) {
}
void Animation::updatePhaseVar(AGDSEngine &engine) {
- if (!_phaseVar.empty())
+ if (_phase == -1)
+ debug("animation ended, phase var: %s, process: %s", _phaseVar.c_str(), _process.c_str());
+
+ if (!_phaseVar.empty()) {
engine.setGlobal(_phaseVar, _phase);
+ }
else if (_phase == -1)
engine.reactivate(_process);
}
@@ -62,6 +66,11 @@ void Animation::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common:
if (_paused || _phase == -1) {
return;
}
+ if (!_phaseVar.empty() && engine.getGlobal(_phaseVar) == -2) {
+ _phase = -1;
+ updatePhaseVar(engine);
+ return;
+ }
const Graphics::Surface *frame = _flic->decodeNextFrame();
if (!frame) {
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 6541b0623a1..73057a734b2 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -58,13 +58,8 @@ bool Dialog::tick() {
return false;
int dialog_var = _engine->getSystemVariable("dialog_var")->getInteger();
- if (dialog_var > 0) {
- _engine->getSystemVariable("dialog_var")->setInteger(-3);
+ if (dialog_var != 0)
return false;
- } else if (dialog_var < 0) {
- _engine->getSystemVariable("dialog_var")->setInteger(0);
- return true;
- }
uint n = _dialogScript.size();
if (_dialogScriptPos >= n)
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 127cab20b04..d08ca6b0985 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -261,7 +261,7 @@ void Process::hasGlobal() {
void Process::postIncrementGlobal() {
Common::String name = popString();
int value = _engine->getGlobal(name);
- debug("increment global %s %d", name.c_str(), value);
+ debug("post-increment global %s %d", name.c_str(), value);
push(value);
_engine->setGlobal(name, value + 1);
}
@@ -269,7 +269,7 @@ void Process::postIncrementGlobal() {
void Process::postDecrementGlobal() {
Common::String name = popString();
int value = _engine->getGlobal(name);
- debug("decrement global %s %d", name.c_str(), value);
+ debug("post-decrement global %s %d", name.c_str(), value);
push(value);
_engine->setGlobal(name, value - 1);
}
@@ -277,14 +277,14 @@ void Process::postDecrementGlobal() {
void Process::incrementGlobal(int inc) {
Common::String name = popString();
int value = _engine->getGlobal(name);
- debug("increment global %s %d", name.c_str(), value);
+ debug("increment global %s %d by %d", name.c_str(), value, inc);
_engine->setGlobal(name, value + inc);
}
void Process::decrementGlobal(int dec) {
Common::String name = popString();
int value = _engine->getGlobal(name);
- debug("decrement global %s %d", name.c_str(), value);
+ debug("decrement global %s %d by %d", name.c_str(), value, dec);
_engine->setGlobal(name, value - dec);
}
@@ -355,7 +355,7 @@ void Process::xorGlobalByTop() {
void Process::appendToSharedStorage() {
Common::String value = popString();
int index = _engine->appendToSharedStorage(value);
- debug("appendToSharedStorage %s -> %d", value.c_str(), index);
+ //debug("appendToSharedStorage %s -> %d", value.c_str(), index);
push(index);
}
Commit: 32a25cde5731104e262c6c3cf23b12bbe1d945cd
https://github.com/scummvm/scummvm/commit/32a25cde5731104e262c6c3cf23b12bbe1d945cd
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:22+01:00
Commit Message:
AGDS: move some ObjectPtr usage to cpp file
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/inventory.cpp
engines/agds/inventory.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index cd3a20fe651..8b4820dedc0 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -155,7 +155,7 @@ ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::Strin
return object;
}
-void AGDSEngine::runObject(ObjectPtr object) {
+void AGDSEngine::runObject(const ObjectPtr &object) {
if (object->inScene()) {
debug("object is %s scene, skip running...", object->getName().c_str());
return;
@@ -168,12 +168,17 @@ void AGDSEngine::runObject(ObjectPtr object) {
runProcess(object);
}
-void AGDSEngine::runProcess(ObjectPtr object, uint ip) {
+void AGDSEngine::runProcess(const ObjectPtr &object, uint ip) {
debug("starting process %s:%04x", object->getName().c_str(), ip);
_processes.push_front(Process(this, object, ip));
_processes.front().run();
}
+ObjectPtr AGDSEngine::getCurrentScreenObject(const Common::String &name) {
+ return _currentScreen? _currentScreen->find(name): ObjectPtr();
+}
+
+
void AGDSEngine::runObject(const Common::String &name, const Common::String &prototype) {
ObjectPtr object = getCurrentScreenObject(name);
if (!object)
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index dee635b6867..53f3bae4f90 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -103,9 +103,9 @@ public:
bool canSaveGameStateCurrently() { return _userEnabled; }
ObjectPtr loadObject(const Common::String & name, const Common::String & prototype = Common::String());
- void runObject(ObjectPtr object);
+ void runObject(const ObjectPtr &object);
void runObject(const Common::String & name, const Common::String &prototype = Common::String());
- void runProcess(ObjectPtr object, uint ip = 0);
+ void runProcess(const ObjectPtr &object, uint ip = 0);
void resetCurrentScreen();
void loadScreen(const Common::String & name);
@@ -140,13 +140,10 @@ public:
return _currentScreen;
}
- ObjectPtr getCurrentScreenObject(const Common::String &name) {
- return _currentScreen? _currentScreen->find(name): ObjectPtr();
- }
-
Common::String & getCurrentScreenName() {
return _currentScreenName;
}
+ ObjectPtr getCurrentScreenObject(const Common::String &name);
const Graphics::PixelFormat & pixelFormat() const {
return _pixelFormat;
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 02d72935924..497548fc68d 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -38,7 +38,11 @@ int Inventory::free() const {
return free;
}
-int Inventory::add(ObjectPtr object) {
+ObjectPtr Inventory::get(int index) const {
+ return index >= 0 && index < kMaxSize? _entries[index]: ObjectPtr();
+}
+
+int Inventory::add(const ObjectPtr & object) {
for (uint i = 0; i < _entries.size(); ++i) {
if (!_entries[i]) {
_entries[i] = object;
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index 322bbd2f841..20b0b43e427 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -58,11 +58,9 @@ public:
_visible = visible;
}
- int add(ObjectPtr object);
+ int add(const ObjectPtr & object);
- ObjectPtr get(int index) const {
- return index >= 0 && index < kMaxSize? _entries[index]: ObjectPtr();
- }
+ ObjectPtr get(int index) const;
int find(const Common::String &name) const;
int free() const;
Commit: 37d8b491e3ff00479ef22f27a16f278ea329d99d
https://github.com/scummvm/scummvm/commit/37d8b491e3ff00479ef22f27a16f278ea329d99d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:22+01:00
Commit Message:
AGDS: add debug console with run command
Changed paths:
A engines/agds/console.cpp
A engines/agds/console.h
engines/agds/agds.cpp
engines/agds/module.mk
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 8b4820dedc0..af53526aa03 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -23,6 +23,7 @@
#include "agds/agds.h"
#include "agds/animation.h"
#include "agds/character.h"
+#include "agds/console.h"
#include "agds/database.h"
#include "agds/font.h"
#include "agds/mjpgPlayer.h"
@@ -156,10 +157,6 @@ ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::Strin
}
void AGDSEngine::runObject(const ObjectPtr &object) {
- if (object->inScene()) {
- debug("object is %s scene, skip running...", object->getName().c_str());
- return;
- }
if (_currentScreen)
_currentScreen->add(object);
else
@@ -326,6 +323,8 @@ Common::Error AGDSEngine::run() {
if (!load())
return Common::kNoGameDataFoundError;
+ setDebugger(new Console(this));
+
int loadSlot = ConfMan.getInt("save_slot");
if (loadSlot >= 0)
loadGameState(loadSlot);
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
new file mode 100644
index 00000000000..72e7d8466fb
--- /dev/null
+++ b/engines/agds/console.cpp
@@ -0,0 +1,48 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agds/console.h"
+#include "agds/agds.h"
+#include "agds/object.h"
+
+namespace AGDS {
+
+Console::Console(AGDSEngine *engine) : _engine(engine) {
+ registerCmd("run", WRAP_METHOD(Console, run));
+}
+
+bool Console::run(int argc, const char **argv) {
+ if (argc < 2) {
+ debugPrintf("usage: %s object_id\n", argv[0]);
+ return true;
+ }
+ ObjectPtr object = _engine->getCurrentScreenObject(argv[1]);
+ if (!object) {
+ debugPrintf("no object %s", argv[1]);
+ return true;
+ }
+ _engine->runObject(object);
+ detach();
+ return false;
+}
+
+}
diff --git a/engines/agds/console.h b/engines/agds/console.h
new file mode 100644
index 00000000000..c4bf5e33a67
--- /dev/null
+++ b/engines/agds/console.h
@@ -0,0 +1,44 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_CONSOLE_H
+#define AGDS_CONSOLE_H
+
+#include "gui/debugger.h"
+
+namespace AGDS {
+
+class AGDSEngine;
+
+class Console : public GUI::Debugger {
+public:
+ Console(AGDSEngine *engine);
+
+private:
+ bool run(int argc, const char **argv);
+
+ AGDSEngine *_engine;
+};
+
+} // End of namespace TeenAgent
+
+#endif
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index d04b79d541f..7ffcb442c64 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -4,6 +4,7 @@ MODULE_OBJS := \
agds.o \
animation.o \
character.o \
+ console.o \
database.o \
detection.o \
dialog.o \
Commit: 9c506b19a96c5949a881ef49c4a2e79988924fb4
https://github.com/scummvm/scummvm/commit/9c506b19a96c5949a881ef49c4a2e79988924fb4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:22+01:00
Commit Message:
AGDS: add unpack-db and unpack-grp scripts
Changed paths:
A engines/agds/tools/decrypt.py
A engines/agds/tools/unpack-db
A engines/agds/tools/unpack-grp
diff --git a/engines/agds/tools/decrypt.py b/engines/agds/tools/decrypt.py
new file mode 100644
index 00000000000..a924315de99
--- /dev/null
+++ b/engines/agds/tools/decrypt.py
@@ -0,0 +1,8 @@
+key = bytes(map(lambda c: ord(c), 'Vyvojovy tym AGDS varuje: Hackerovani skodi obchodu!'))
+key_n = len(key)
+
+def decrypt(src):
+ r = bytearray()
+ for i in range(len(src)):
+ r.append(src[i] ^ key[i % key_n] ^ 0xff)
+ return r
diff --git a/engines/agds/tools/unpack-db b/engines/agds/tools/unpack-db
new file mode 100755
index 00000000000..6544f3993e5
--- /dev/null
+++ b/engines/agds/tools/unpack-db
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+
+from argparse import ArgumentParser
+from struct import unpack
+import sys
+import os.path
+from decrypt import decrypt
+
+argparser = ArgumentParser('Unpack ADB file')
+argparser.add_argument('file')
+args = argparser.parse_args()
+
+with open(args.file, "rb") as f:
+ data = bytearray(f.read())
+
+size = len(data)
+magic, h1, h2, h3, h4 = unpack('<IIIII', data[:0x14])
+if magic != 666:
+ raise Exception('invalid db magic', magic)
+
+db_name, _ = os.path.splitext(os.path.basename(args.file))
+try:
+ os.makedirs(db_name)
+except:
+ pass
+
+print('header', h1, h2, h3, h4)
+
+data_offset = h2 * 0x28 + 0x14
+print('data offset: 0x%08x' %(data_offset))
+for i in range(h3):
+ offset = 0x14 + i * 0x28
+ entry = data[offset: offset + 0x28]
+ name_end = entry.index(bytes([0]), 4)
+ name = str(entry[4: name_end], 'utf-8')
+ index, = unpack('<I', entry[0:4])
+ size, = unpack('<I', entry[0x24:])
+ print(repr(name), hex(index), hex(data_offset + index), size)
+
+ entry_data = data[data_offset + index: data_offset + index + size]
+ with open(os.path.join(db_name, name + '.dec'), 'wb') as fo:
+ fo.write(decrypt(entry_data))
+
+ with open(os.path.join(db_name, name), 'wb') as fo:
+ fo.write(entry_data)
+
diff --git a/engines/agds/tools/unpack-grp b/engines/agds/tools/unpack-grp
new file mode 100755
index 00000000000..598a0c664bf
--- /dev/null
+++ b/engines/agds/tools/unpack-grp
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+
+from argparse import ArgumentParser
+from struct import unpack
+from decrypt import decrypt
+
+import sys
+import os.path
+
+argparser = ArgumentParser('unpack GRP file')
+argparser.add_argument('file')
+args = argparser.parse_args()
+
+
+f = open(args.file, "rb")
+
+header = bytes(f.read(0x2c))
+grp_dir = bytes(f.read(0x31))
+
+id = decrypt(header[0:0x10])
+if id != bytes('AGDS group file\x1a', 'ascii'):
+ raise Exception('invalid header', id)
+
+version1, magic, version2 = unpack('<III', header[0x10:0x1c])
+if magic != 0x1a03c9e6 or version1 != 44 or version2 != 2:
+ raise Exception("unsupported version")
+dir_count, _dc2, _unk14, _unk18 = unpack('<IIII', header[0x1c:])
+
+dir_data = bytearray(f.read(0x31 * dir_count))
+
+gfx_name, _ = os.path.splitext(os.path.basename(args.file))
+try:
+ os.makedirs(gfx_name)
+except:
+ pass
+
+for offset in range(0, dir_count * 0x31, 0x31):
+ entry = dir_data[offset: offset + 0x31]
+ name_len = entry.index(bytes([0]))
+ if name_len == 0:
+ break
+ name = str(decrypt(entry[:name_len]), "utf-8")
+ offset, size, _unk1, _unk2 = unpack('<IIII', entry[0x21:])
+ f.seek(offset)
+
+ print("writing file %s" %name)
+ with open(os.path.join(gfx_name, name), "wb") as fo:
+ fo.write(f.read(size))
Commit: f7fcf18de9daa742d929e0c59877ad9739cdffec
https://github.com/scummvm/scummvm/commit/f7fcf18de9daa742d929e0c59877ad9739cdffec
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:22+01:00
Commit Message:
AGDS: add reactivate command, export vars to debugger
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/console.cpp
engines/agds/console.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index af53526aa03..c93192711c0 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -245,7 +245,12 @@ void AGDSEngine::runProcesses() {
++i;
}
}
- }
+}
+
+Console *AGDSEngine::getConsole() {
+ return static_cast<Console *>(getDebugger());
+}
+
void AGDSEngine::newGame() {
SystemVariable *doneVar = getSystemVariable("done_resources");
@@ -255,6 +260,9 @@ void AGDSEngine::newGame() {
_patches.clear();
_inventory.clear();
_globals.clear();
+ Console *console = getConsole();
+ if (console)
+ console->clearVars();
SystemVariable *initVar = getSystemVariable("init_resources");
Common::String init = initVar->getString();
@@ -523,6 +531,16 @@ const Common::String &AGDSEngine::getSharedStorage(int id) const {
return _sharedStorage[index];
}
+void AGDSEngine::setGlobal(const Common::String &name, int value) {
+ bool create = !_globals.contains(name);
+ _globals.setVal(name, value);
+ if (create) {
+ Console *console = getConsole();
+ if (console)
+ console->registerVar(name, &_globals[name]);
+ }
+}
+
int AGDSEngine::getGlobal(const Common::String &name) const {
GlobalsType::const_iterator i = _globals.find(name);
if (i != _globals.end())
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 53f3bae4f90..fe9675d77af 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -68,6 +68,7 @@ struct MouseRegion;
class MJPGPlayer;
class Screen;
class SystemVariable;
+class Console;
class AGDSEngine : public Engine {
friend class Process;
@@ -79,13 +80,11 @@ public:
Common::Error run() override;
- void setGlobal(const Common::String &name, int value) {
- _globals.setVal(name, value);
- }
+ void setGlobal(const Common::String &name, int value);
+ int getGlobal(const Common::String &name) const;
bool hasGlobal(const Common::String &name) const {
- return _globals.find(name) != _globals.end();
+ return _globals.contains(name);
}
- int getGlobal(const Common::String &name) const;
private:
void addSystemVar(const Common::String &name, SystemVariable *var);
@@ -139,6 +138,7 @@ public:
Screen * getCurrentScreen() {
return _currentScreen;
}
+ Console * getConsole();
Common::String & getCurrentScreenName() {
return _currentScreenName;
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index 72e7d8466fb..f51326247f6 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -28,6 +28,7 @@ namespace AGDS {
Console::Console(AGDSEngine *engine) : _engine(engine) {
registerCmd("run", WRAP_METHOD(Console, run));
+ registerCmd("activate", WRAP_METHOD(Console, activate));
}
bool Console::run(int argc, const char **argv) {
@@ -45,4 +46,14 @@ bool Console::run(int argc, const char **argv) {
return false;
}
+bool Console::activate(int argc, const char **argv) {
+ if (argc < 2) {
+ debugPrintf("usage: %s object_id\n", argv[0]);
+ return true;
+ }
+ _engine->reactivate(argv[1]);
+ detach();
+ return false;
+}
+
}
diff --git a/engines/agds/console.h b/engines/agds/console.h
index c4bf5e33a67..d321cb6e782 100644
--- a/engines/agds/console.h
+++ b/engines/agds/console.h
@@ -32,9 +32,12 @@ class AGDSEngine;
class Console : public GUI::Debugger {
public:
Console(AGDSEngine *engine);
+ using GUI::Debugger::registerVar;
+ using GUI::Debugger::clearVars;
private:
bool run(int argc, const char **argv);
+ bool activate(int argc, const char **argv);
AGDSEngine *_engine;
};
Commit: e8e290412d0437cca2109b3f40502965a4e50088
https://github.com/scummvm/scummvm/commit/e8e290412d0437cca2109b3f40502965a4e50088
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:22+01:00
Commit Message:
AGDS: reactivate sound processes and update phasevar
Changed paths:
engines/agds/soundManager.cpp
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index dc521243fe0..21d33e7e1a9 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -36,15 +36,18 @@ void SoundManager::tick() {
for (SoundList::iterator i = _sounds.begin(); i != _sounds.end();) {
Sound &sound = *i;
if (!_mixer->isSoundHandleActive(sound.handle)) {
+ debug("sound %s stopped", sound.name.c_str());
if (!sound.phaseVar.empty())
_engine->setGlobal(sound.phaseVar, 0);
- else if (!sound.process.empty()) {
- _engine->reactivate(sound.process);
- }
+
+ _engine->reactivate(sound.process);
i = _sounds.erase(i);
} else {
+ debug("sound %s playing", sound.name.c_str());
if (!sound.phaseVar.empty())
_engine->setGlobal(sound.phaseVar, 1);
+
+ _engine->reactivate(sound.process);
++i;
}
}
@@ -56,9 +59,11 @@ void SoundManager::stopAll() {
Sound &sound = *i;
_engine->setGlobal(sound.phaseVar, 0);
}
+ _sounds.clear();
}
int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &phaseVar) {
+ debug("SoundMan::play %s %s %s", process.c_str(), resource.c_str(), phaseVar.c_str());
Common::File *file = new Common::File();
if (!file->open(resource))
error("no sound %s", resource.c_str());
@@ -76,6 +81,8 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
warning("could not play sound %s", resource.c_str());
delete file;
_engine->reactivate(process);
+ if (!phaseVar.empty())
+ _engine->setGlobal(phaseVar, 0);
return -1;
}
Audio::SoundHandle handle;
Commit: 58d4e1c0e7cc83da3241b0191439bd316250985a
https://github.com/scummvm/scummvm/commit/58d4e1c0e7cc83da3241b0191439bd316250985a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:22+01:00
Commit Message:
AGDS: remove all processes before loading screen
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c93192711c0..c1e3e79c712 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -195,13 +195,7 @@ void AGDSEngine::loadScreen(const Common::String &name) {
}
_mouseMap.hideAll(this);
resetCurrentScreen();
- for(ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ++i) {
- Process &process = *i;
- if (process.parentScreenName() != _currentScreenName) {
- debug("process %s from different screen, destroy", process.getName().c_str());
- process.done();
- }
- }
+ _processes.clear();
_soundManager.stopAll();
_currentScreenName = name;
Commit: f57cc4c7a4eb018a2c42842d686845ee278d2aea
https://github.com/scummvm/scummvm/commit/f57cc4c7a4eb018a2c42842d686845ee278d2aea
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:22+01:00
Commit Message:
AGDS: implement mod opcode
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index bd1e3022570..d7379a762ab 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -51,7 +51,7 @@ enum Opcode {
kSub = 29,
kMul = 30,
kDiv = 31,
- kStub32 = 32,
+ kMod = 32,
kAnd = 33,
kOr = 34,
kXor = 35,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 4de11384c07..442434f0463 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -295,6 +295,7 @@ private:
BINARY_OP(sub, -)
BINARY_OP(mul, *)
BINARY_OP(div, /)
+ BINARY_OP(mod, %)
BINARY_OP(bitAnd, &)
BINARY_OP(bitOr, |)
BINARY_OP(bitXor, ^)
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d08ca6b0985..60d58b3f9a9 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1409,6 +1409,7 @@ ProcessExitCode Process::resume() {
OP(kSub, sub);
OP(kMul, mul);
OP(kDiv, div);
+ OP(kMod, mod);
OP(kSetGlobal, setGlobal);
OP(kBoolOr, boolOr);
OP(kBoolAnd, boolAnd);
Commit: 08a882a11102b3adbb6321bee435f66a985268e5
https://github.com/scummvm/scummvm/commit/08a882a11102b3adbb6321bee435f66a985268e5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:22+01:00
Commit Message:
AGDS: signal animation frame and wake up process
Changed paths:
engines/agds/animation.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index a0235bd9973..4a23b21105c 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -52,18 +52,19 @@ bool Animation::load(Common::SeekableReadStream *stream) {
}
void Animation::updatePhaseVar(AGDSEngine &engine) {
+ debug("animation %d, phase var: %s, process: %s", _phase, _phaseVar.c_str(), _process.c_str());
if (_phase == -1)
debug("animation ended, phase var: %s, process: %s", _phaseVar.c_str(), _process.c_str());
- if (!_phaseVar.empty()) {
+ if (!_phaseVar.empty())
engine.setGlobal(_phaseVar, _phase);
- }
- else if (_phase == -1)
+ else
engine.reactivate(_process);
}
void Animation::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point dst) {
if (_paused || _phase == -1) {
+ updatePhaseVar(engine);
return;
}
if (!_phaseVar.empty() && engine.getGlobal(_phaseVar) == -2) {
Commit: 80817d72c18b3fb205aadffc7350a0ebe5d42fe6
https://github.com/scummvm/scummvm/commit/80817d72c18b3fb205aadffc7350a0ebe5d42fe6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:22+01:00
Commit Message:
AGDS: implemented GetCharacterX/Y
Changed paths:
engines/agds/character.h
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 0f7701cdee9..4102c57b518 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -36,8 +36,9 @@ class AGDSEngine;
class Object;
class Character {
- Common::String _name;
- Common::String _object;
+ Common::String _name;
+ Common::String _object;
+ Common::Point _pos;
bool _enabled;
int _phase;
int _frames;
@@ -66,6 +67,10 @@ public:
return _object;
}
+ Common::Point position() const {
+ return _pos;
+ }
+
void load(Common::SeekableReadStream* stream);
void enable(bool enabled = true) {
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index d7379a762ab..a1d49994b87 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -166,8 +166,8 @@ enum Opcode {
kGetRegionCenterX = 146,
kGetRegionCenterY = 147,
kGetCharacterAnimationPhase = 148,
- kStub149 = 149,
- kStub150 = 150,
+ kGetCharacterX = 149,
+ kGetCharacterY = 150,
kStub151 = 151,
kGetPictureBaseX = 152,
kGetPictureBaseY = 153,
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 442434f0463..e2ad64d3825 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -176,6 +176,8 @@ private:
void pointCharacter();
void animateCharacter();
void getCharacterAnimationPhase();
+ void getCharacterX();
+ void getCharacterY();
void stopCharacter();
void quit();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 60d58b3f9a9..12e46f6fd2a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1194,6 +1194,24 @@ void Process::getCharacterAnimationPhase() {
debug("animation phase = %d", phase);
push(phase);
}
+void Process::getCharacterX() {
+ Common::String name = popString();
+ debug("getCharacterX: %s", name.c_str());
+ Character *character = _engine->getCharacter(name);
+ if (!character)
+ warning("no character %s", name.c_str());
+ int value = character? character->position().x: -1;
+ push(value);
+}
+void Process::getCharacterY() {
+ Common::String name = popString();
+ debug("getCharacterY: %s", name.c_str());
+ Character *character = _engine->getCharacter(name);
+ if (!character)
+ warning("no character %s", name.c_str());
+ int value = character? character->position().y: -1;
+ push(value);
+}
void Process::stopCharacter() {
int arg = pop();
Commit: 86ac1009025001dbbdc8b583ccfc8e4db0825388
https://github.com/scummvm/scummvm/commit/86ac1009025001dbbdc8b583ccfc8e4db0825388
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:23+01:00
Commit Message:
AGDS: generate switch/header declaration of the single source, AGDS_OPCODE_LIST
Changed paths:
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index a1d49994b87..8153923676b 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -267,6 +267,196 @@ enum Opcode {
kSetDialogForNextFilm = 247
};
+#define AGDS_OPCODE_LIST(OP, OP_C, OP_B, OP_W, OP_U, OP_UD, OP_UU) \
+ OP_UU(kEnter, enter) \
+ OP_W(kJumpZImm16, jumpz) \
+ OP_W(kJumpImm16, jump) \
+ OP(kPop, popNoResult) \
+ OP(kDup, dup) \
+ OP(kExitProcess, exitProcess) \
+ OP(kSuspendProcess, suspend) \
+ OP_UD(kPushImm32, push) \
+ OP_C(kPushImm8, push) \
+ OP_W(kPushImm16, push) \
+ OP_C(kPushImm8_2, push2) \
+ OP_W(kPushImm16_2, push2) \
+ OP_B(kGetGlobalImm8, getGlobal) \
+ OP(kPostIncrementGlobal, postIncrementGlobal) \
+ OP(kPostDecrementGlobal, postDecrementGlobal) \
+ OP(kIncrementGlobalByTop, incrementGlobalByTop) \
+ OP(kDecrementGlobalByTop, decrementGlobalByTop) \
+ OP(kMultiplyGlobalByTop, multiplyGlobalByTop) \
+ OP(kDivideGlobalByTop, divideGlobalByTop) \
+ OP(kModGlobalByTop, modGlobalByTop) \
+ OP(kShlGlobalByTop, shlGlobalByTop) \
+ OP(kShrGlobalByTop, shrGlobalByTop) \
+ OP(kAndGlobalByTop, andGlobalByTop) \
+ OP(kOrGlobalByTop, orGlobalByTop) \
+ OP(kXorGlobalByTop, xorGlobalByTop) \
+ OP(kEquals, equals) \
+ OP(kNotEquals, notEquals) \
+ OP(kGreater, greater) \
+ OP(kLess, less) \
+ OP(kGreaterOrEquals, greaterOrEquals) \
+ OP(kLessOrEquals, lessOrEquals) \
+ OP(kAdd, add) \
+ OP(kSub, sub) \
+ OP(kMul, mul) \
+ OP(kDiv, div) \
+ OP(kMod, mod) \
+ OP(kSetGlobal, setGlobal) \
+ OP(kBoolOr, boolOr) \
+ OP(kBoolAnd, boolAnd) \
+ OP(kAnd, bitAnd) \
+ OP(kOr, bitOr) \
+ OP(kXor, bitXor) \
+ OP(kNot, bitNot) \
+ OP(kBoolNot, boolNot) \
+ OP(kNegate, negate) \
+ OP_U(kCallImm16, call) \
+ OP_U(kObjectRegisterLookHandler, onLook) \
+ OP_U(kObjectRegisterUseHandler, onUse) \
+ OP_U(kObjectRegisterHandlerC1, onObjectC1) \
+ OP_U(kObjectRegisterHandlerB9, onObjectB9) \
+ OP_U(kObjectRegisterHandlerBD, onObjectBD) \
+ OP(kLoadMouseCursorFromObject, loadMouseCursorFromObject) \
+ OP(kLoadRegionFromObject, loadRegionFromObject) \
+ OP(kLoadPictureFromObject, loadPictureFromObject) \
+ OP(kLoadAnimationFromObject, loadAnimationFromObject) \
+ OP(kShowCharacter, showCharacter) \
+ OP(kEnableCharacter, enableCharacter) \
+ OP(kMoveCharacterUserMove, moveCharacterUserMove) \
+ OP(kLeaveCharacter, leaveCharacter) \
+ OP(kSetCharacter, setCharacter) \
+ OP(kPointCharacter, pointCharacter) \
+ OP(kDisableUser, disableUser) \
+ OP(kEnableUser, enableUser) \
+ OP(kUpdatePhaseVarOr2, updatePhaseVarOr2) \
+ OP(kUpdatePhaseVarOr4, updatePhaseVarOr4) \
+ OP(kStub102, stub102) \
+ OP(kClearScreen, clearScreen) \
+ OP(kInventoryClear, inventoryClear) \
+ OP(kLoadMouse, loadMouse) \
+ OP(kInventoryAddObject, inventoryAddObject) \
+ OP(kSetNextScreenSaveInHistory, setNextScreenSaveInHistory) \
+ OP_U(kObjectRegisterUseObjectHandler, onObjectUse) \
+ OP(kStub82, stub82) \
+ OP(kStub83, stub83) \
+ OP(kAnimateCharacter, animateCharacter) \
+ OP(kLoadCharacter, loadCharacter) \
+ OP(kSetObjectZ, setObjectZ) \
+ OP(kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay) \
+ OP(kLoadTextFromObject, loadTextFromObject) \
+ OP(kScreenSetHeight, setScreenHeight) \
+ OP(kScreenLoadObject, loadScreenObject) \
+ OP(kScreenLoadRegion, loadScreenRegion) \
+ OP(kScreenCloneObject, cloneObject) \
+ OP(kSetNextScreen, setNextScreen) \
+ OP(kScreenRemoveObject, removeScreenObject) \
+ OP(kLoadAnimation, loadAnimation) \
+ OP(kLoadSample, loadSample) \
+ OP(kSetAnimationPaused, setAnimationPaused) \
+ OP(kPlayerSay, playerSay) \
+ OP(kNPCSay, npcSay) \
+ OP(kSetTimer, setTimer) \
+ OP(kProcessResetState, resetState) \
+ OP(kSetAnimationZ, setAnimationZ) \
+ OP(kSetCycles, setCycles) \
+ OP(kSetRandom, setRandom) \
+ OP(kSetPanAndVolume, setPanAndVolume) \
+ OP(kSetAnimationPosition, setAnimationPosition) \
+ OP(kSetPhaseVar, setPhaseVar) \
+ OP(kSetAnimationLoop, setAnimationLoop) \
+ OP(kSetAnimationSpeed, setAnimationSpeed) \
+ OP(kStub138, stub138) \
+ OP(kGetSavedMouseX, getSavedMouseX) \
+ OP(kGetSavedMouseY, getSavedMouseY) \
+ OP(kScreenChangeScreenPatch, changeScreenPatch) \
+ OP(kGetFreeInventorySpace, getInventoryFreeSpace) \
+ OP(kSetStringSystemVariable, setStringSystemVariable) \
+ OP(kSetSystemIntegerVariable, setIntegerSystemVariable) \
+ OP(kGetRegionCenterX, getRegionCenterX) \
+ OP(kGetRegionCenterY, getRegionCenterY) \
+ OP(kGetCharacterAnimationPhase, getCharacterAnimationPhase) \
+ OP(kGetCharacterX, getCharacterX) \
+ OP(kGetCharacterY, getCharacterY) \
+ OP(kGetIntegerSystemVariable, getIntegerSystemVariable) \
+ OP(kGetRandomNumber, getRandomNumber) \
+ OP(kAppendToSharedStorage, appendToSharedStorage) \
+ OP(kAppendNameToSharedStorage, appendNameToSharedStorage) \
+ OP(kCloneName, cloneName) \
+ OP(kGetCloneVar, getCloneVar) \
+ OP(kSetCloneVar, setCloneVar) \
+ OP(kGetPictureBaseX, getPictureBaseX) \
+ OP(kGetPictureBaseY, getPictureBaseY) \
+ OP(kGetObjectSurfaceX, getObjectSurfaceX) \
+ OP(kGetObjectSurfaceY, getObjectSurfaceY) \
+ OP(kLoadGame, loadGame) \
+ OP(kLoadSaveSlotNamePicture, loadSaveSlotNamePicture) \
+ OP(kStub166, stub166) \
+ OP(kSetDelay, setDelay) \
+ OP(kStub172, stub172) \
+ OP(kStub173, stub173) \
+ OP(kStub174, stub174) \
+ OP(kStub192, stub192) \
+ OP(kQuit, quit) \
+ OP(kExitProcessCreatePatch, exitProcessCreatePatch) \
+ OP(kDisableInventory, disableInventory) \
+ OP(kEnableInventory, enableInventory) \
+ OP(kLoadPreviousScreen, loadPreviousScreen) \
+ OP(kMoveScreenObject, moveScreenObject) \
+ OP(kGetObjectId, getObjectId) \
+ OP(kSetTileSize, setTileSize) \
+ OP(kGenerateRegion, generateRegion) \
+ OP(kGetMaxInventorySize, getMaxInventorySize) \
+ OP(kAppendInventoryObjectNameToSharedSpace, appendInventoryObjectNameToSharedSpace) \
+ OP(kSetObjectTile, setObjectTile) \
+ OP(kInventoryHasObject, inventoryHasObject) \
+ OP(kSetObjectText, setObjectText) \
+ OP(kSetObjectScale, setObjectScale) \
+ OP(kStub191, disableMouseAreas) \
+ OP(kStub193, stub193) \
+ OP(kMute, stub194) \
+ OP(kGetObjectPictureWidth, getObjectPictureWidth) \
+ OP(kGetObjectPictureHeight, getObjectPictureHeight) \
+ OP(kLoadPicture, loadPicture) \
+ OP(kStub199, stub199) \
+ OP(kSetSampleVolumeAndPan, setSampleVolumeAndPan) \
+ OP(kAddSampleToSoundGroup, addSampleToSoundGroup) \
+ OP(kStub215, stub215) \
+ OP(kStub216, stub216) \
+ OP(kStub217, stub217) \
+ OP(kStopCharacter, stopCharacter) \
+ OP(kLeaveCharacterEx, leaveCharacterEx) \
+ OP(kPlayAnimationWithPhaseVar, playAnimationWithPhaseVar) \
+ OP(kStub223, stub223) \
+ OP(kSetNPCTellNotifyVar, setNPCTellNotifyVar) \
+ OP(kStub225, stub225) \
+ OP(kFadeObject, fadeObject) \
+ OP(kLoadFont, loadFont) \
+ OP_U(kStub201Handler, stub201) \
+ OP_U(kStub202ScreenHandler, stub202) \
+ OP(kPlayFilm, playFilm) \
+ OP(kAddMouseArea, addMouseArea) \
+ OP(kSetRain, setRain) \
+ OP(kSetRainDensity, setRainDensity) \
+ OP(kFogOnCharacter, fogOnCharacter) \
+ OP(kSetTileIndex, setTileIndex) \
+ OP(kModifyMouseArea, modifyMouseArea) \
+ OP_U(kObjectRegisterUserUseHandler, onObjectUserUse) \
+ OP(kMoveCharacterNoUserMove, moveCharacterNoUserMove) \
+ OP_U(kOnKey, onKey) \
+ OP(kGetSampleVolume, getSampleVolume) \
+ OP(kStub231, stub231) \
+ OP(kStub233, stub233) \
+ OP(kStub235, stub235) \
+ OP(kUserEnabled, userEnabled) \
+ OP(kSetCharacterNotifyVars, setCharacterNotifyVars) \
+ OP(kInventoryFindObjectByName, inventoryFindObjectByName) \
+ OP(kLoadDialog, loadDialog) \
+ OP(kHasGlobal, hasGlobal) \
+ OP(kSetDialogForNextFilm, setDialogForNextFilm)
+
}
#endif
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index d394665cd13..77557e5ae72 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -67,8 +67,29 @@ void Process::error(const char *str, ...) {
_status = kStatusError;
}
-void Process::push(int32 value) {
- _stack.push(value);
+void Process::jump(int16 delta) {
+ debug("jump %+d", delta);
+ _ip += delta;
+}
+
+void Process::jumpz(int16 delta) {
+ int value = pop();
+ if (value == 0) {
+ debug("jumpz %d %+d", value, delta);
+ _ip += delta;
+ }
+}
+
+void Process::incrementGlobalByTop() {
+ incrementGlobal(top());
+}
+void Process::decrementGlobalByTop() {
+ decrementGlobal(top());
+}
+
+
+void Process::suspend() {
+ suspend(kExitCodeSuspend);
}
int32 Process::pop() {
@@ -181,5 +202,31 @@ void Process::run() {
}
}
+#define UNARY_OP(NAME, OP) void Process:: NAME () { int arg = pop(); debug(#NAME " %d", arg); push( OP arg ); }
+#define BINARY_OP(NAME, OP) void Process:: NAME () { int arg2 = pop(); int arg1 = pop(); debug(#NAME " %d " #OP " %d", arg1, arg2); push(arg1 OP arg2); }
+
+ UNARY_OP(boolNot, !)
+ UNARY_OP(bitNot, ~)
+ UNARY_OP(negate, -)
+ BINARY_OP(boolOr, ||)
+ BINARY_OP(boolAnd, &&)
+ BINARY_OP(equals, ==)
+ BINARY_OP(notEquals, !=)
+ BINARY_OP(greater, >)
+ BINARY_OP(greaterOrEquals, >=)
+ BINARY_OP(less, <)
+ BINARY_OP(lessOrEquals, <=)
+ BINARY_OP(add, +)
+ BINARY_OP(sub, -)
+ BINARY_OP(mul, *)
+ BINARY_OP(div, /)
+ BINARY_OP(mod, %)
+ BINARY_OP(bitAnd, &)
+ BINARY_OP(bitOr, |)
+ BINARY_OP(bitXor, ^)
+
+#undef UNARY_OP
+#undef BINARY_OP
+
} // namespace AGDS
diff --git a/engines/agds/process.h b/engines/agds/process.h
index e2ad64d3825..50a8e53860e 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -24,6 +24,7 @@
#define AGDS_PROCESS_H
#include "agds/object.h"
+#include "agds/opcode.h"
#include "agds/processExitCode.h"
#include "common/scummsys.h"
#include "common/stack.h"
@@ -64,6 +65,11 @@ private:
Common::Point _mousePosition;
private:
+ void debug(const char *str, ...);
+ void error(const char *str, ...);
+
+ void push(bool);
+
uint8 next() {
const Object::CodeType & code = _object->getCode();
if (_ip < code.size()) {
@@ -80,230 +86,41 @@ private:
return (h << 8) | l;
}
- void push(int32 value);
int32 pop();
int32 top();
- void dup() {
- push(top());
- }
-
- void jump(int delta)
- { debug("jump %+d", delta); _ip += delta; }
-
- void jumpz(int delta)
- {
- int value = pop();
- if (value == 0) {
- debug("jumpz %d %+d", value, delta);
- _ip += delta;
- }
- }
-
Common::String getString(int id);
Common::String popString() {
return getString(pop());
}
Common::String popText();
- void enter(uint16 magic, uint16 size);
- void exitProcess();
- void exitProcessCreatePatch();
- void setNextScreen();
- void setNextScreenSaveInHistory();
- void loadPreviousScreen();
- void call(uint16 addr);
-
- void disableInventory();
- void enableInventory();
- void inventoryClear();
- void inventoryAddObject();
- void inventoryHasObject();
- void inventoryFindObjectByName();
- void getMaxInventorySize();
- void getInventoryFreeSpace();
- void appendInventoryObjectNameToSharedSpace();
-
- void getObjectId();
- void clearScreen();
- void loadPicture();
- void loadMouse();
- void loadMouseCursorFromObject();
- void loadScreenRegion();
- void loadScreenObject();
- void loadFont();
- void removeScreenObject();
- void changeScreenPatch();
- void setObjectZ();
- void setScreenHeight();
- void updateScreenHeightToDisplay();
- void addMouseArea();
- void loadRegionFromObject();
- void generateRegion();
- void loadPictureFromObject();
- void setObjectTile();
- void loadAnimationFromObject();
- void loadTextFromObject();
- void loadAnimation();
- void setAnimationPosition();
- void loadSample();
- void addSampleToSoundGroup();
- void playFilm();
- void getSampleVolume();
- void setSampleVolumeAndPan();
- void updatePhaseVarOr2();
- void updatePhaseVarOr4();
- void cloneObject();
- void setTimer();
- void getRegionCenterX();
- void getRegionCenterY();
- void fadeObject();
- void moveScreenObject();
- void setTileSize();
- void setTileIndex();
- void getObjectPictureWidth();
- void getObjectPictureHeight();
- void loadCharacter();
- void enableCharacter();
+#define AGDS_PROCESS_METHOD(opcode, method) \
+ void method () ;
+#define AGDS_PROCESS_METHOD_C(opcode, method) \
+ void method (int8) ;
+#define AGDS_PROCESS_METHOD_B(opcode, method) \
+ void method (uint8) ;
+#define AGDS_PROCESS_METHOD_W(opcode, method) \
+ void method (int16) ;
+#define AGDS_PROCESS_METHOD_U(opcode, method) \
+ void method (uint16) ;
+#define AGDS_PROCESS_METHOD_UD(opcode, method) \
+ void method (int32) ;
+#define AGDS_PROCESS_METHOD_UU(opcode, method) \
+ void method (uint16, uint16) ;
+
+ void incrementGlobal(int inc);
+ void decrementGlobal(int inc);
+
+ AGDS_OPCODE_LIST(AGDS_PROCESS_METHOD,
+ AGDS_PROCESS_METHOD_C, AGDS_PROCESS_METHOD_B, AGDS_PROCESS_METHOD_W,
+ AGDS_PROCESS_METHOD_U, AGDS_PROCESS_METHOD_UD, AGDS_PROCESS_METHOD_UU)
+
void moveCharacter(bool usermove);
- void showCharacter();
- void fogOnCharacter();
- void setRain();
- void setRainDensity();
- void leaveCharacter();
- void leaveCharacterEx();
- void setCharacter();
- void pointCharacter();
- void animateCharacter();
- void getCharacterAnimationPhase();
- void getCharacterX();
- void getCharacterY();
- void stopCharacter();
- void quit();
-
- void setDialogForNextFilm();
- void npcSay();
- void playerSay();
void tell(bool npc);
- void loadDialog();
- void setObjectText();
- void setNPCTellNotifyVar();
-
- void getRandomNumber();
- void setStringSystemVariable();
- void getIntegerSystemVariable();
- void setIntegerSystemVariable();
- void getGlobal(unsigned index);
- void setGlobal();
- void setPhaseVar();
- void hasGlobal();
- void postIncrementGlobal();
- void postDecrementGlobal();
- void incrementGlobal(int value);
- void incrementGlobalByTop() { incrementGlobal(top()); }
- void decrementGlobal(int value);
- void decrementGlobalByTop() { decrementGlobal(top()); }
- void multiplyGlobalByTop();
- void divideGlobalByTop();
- void modGlobalByTop();
- void shlGlobalByTop();
- void shrGlobalByTop();
- void andGlobalByTop();
- void orGlobalByTop();
- void xorGlobalByTop();
-
- void appendToSharedStorage();
- void appendNameToSharedStorage();
- Common::String getCloneVarName(const Common::String & arg1, const Common::String & arg2);
- void getCloneVar();
- void setCloneVar();
- void cloneName();
- void setDelay();
-
- void disableUser();
- void enableUser();
- void disableMouseAreas();
- void modifyMouseArea();
- void onKey(unsigned size);
- void onUse(unsigned size);
- void onLook(unsigned size);
- void onObjectC1(unsigned size);
- void onObjectB9(unsigned size);
- void onObjectBD(unsigned size);
- void onObjectUse(unsigned size);
- void onObjectUserUse(unsigned size);
-
-
- void stub82();
- void stub83();
- void stub102();
- void resetState();
- void setCycles();
- void setRandom();
- void setPanAndVolume();
- void stub138();
- void getPictureBaseX();
- void getPictureBaseY();
- void getObjectSurfaceX();
- void getObjectSurfaceY();
- void getSavedMouseX();
- void getSavedMouseY();
- void loadGame();
- void loadSaveSlotNamePicture();
- void stub166();
- void stub172();
- void stub173();
- void stub174();
- void setObjectScale();
- void stub192();
- void stub193();
- void stub194();
- void stub199();
- void stub201(unsigned size);
- void stub202(unsigned size);
- void stub215();
- void stub216();
- void stub217();
- void playAnimationWithPhaseVar();
- void setAnimationLoop();
- void setAnimationPaused();
- void setAnimationSpeed();
- void setAnimationZ();
- void stub223();
- void stub225();
- void stub231();
- void stub233();
- void stub235();
- void userEnabled();
- void setCharacterNotifyVars();
- void debug(const char *str, ...);
- void error(const char *str, ...);
-#define UNARY_OP(NAME, OP) void NAME () { int arg = pop(); debug(#NAME " %d", arg); push( OP arg ); }
-#define BINARY_OP(NAME, OP) void NAME () { int arg2 = pop(); int arg1 = pop(); debug(#NAME " %d " #OP " %d", arg1, arg2); push(arg1 OP arg2); }
-
- UNARY_OP(boolNot, !)
- UNARY_OP(bitNot, ~)
- UNARY_OP(negate, -)
- BINARY_OP(boolOr, ||)
- BINARY_OP(boolAnd, &&)
- BINARY_OP(equals, ==)
- BINARY_OP(notEquals, !=)
- BINARY_OP(greater, >)
- BINARY_OP(greaterOrEquals, >=)
- BINARY_OP(less, <)
- BINARY_OP(lessOrEquals, <=)
- BINARY_OP(add, +)
- BINARY_OP(sub, -)
- BINARY_OP(mul, *)
- BINARY_OP(div, /)
- BINARY_OP(mod, %)
- BINARY_OP(bitAnd, &)
- BINARY_OP(bitOr, |)
- BINARY_OP(bitXor, ^)
-
-#undef UNARY_OP
-#undef BINARY_OP
+ Common::String getCloneVarName(const Common::String & arg1, const Common::String & arg2);
void suspend(ProcessExitCode exitCode, const Common::String &arg1, const Common::String &arg2 = Common::String()) {
debug("suspend %d", exitCode);
@@ -316,7 +133,7 @@ private:
_exitArg2 = arg2;
}
- void suspend(ProcessExitCode exitCode = kExitCodeSuspend, int arg1 = 0, int arg2 = 0) {
+ void suspend(ProcessExitCode exitCode, int arg1 = 0, int arg2 = 0) {
debug("suspend %d", exitCode);
if (active())
_status = kStatusPassive;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 12e46f6fd2a..86a233a3a71 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -36,6 +36,38 @@
namespace AGDS {
+void Process::dup() {
+ push(top());
+}
+
+void Process::popNoResult() {
+ pop();
+}
+
+void Process::push(bool value) {
+ _stack.push(value);
+}
+
+void Process::push(int8 value) {
+ _stack.push(value);
+}
+
+void Process::push(int16 value) {
+ _stack.push(value);
+}
+
+void Process::push(int32 value) {
+ _stack.push(value);
+}
+
+void Process::push2(int8 value) {
+ _stack.push(value);
+}
+
+void Process::push2(int16 value) {
+ _stack.push(value);
+}
+
void Process::enter(uint16 magic, uint16 size) {
if (magic != 0xdead || size != 0x0c)
error("invalid enter() magic: 0x%04x or size: %u", magic, size);
@@ -244,7 +276,7 @@ void Process::setPhaseVar() {
debug("setPhaseVar %s", name.c_str());
}
-void Process::getGlobal(unsigned index) {
+void Process::getGlobal(uint8 index) {
const Common::String &name = _object->getString(index).string;
int value = _engine->getGlobal(name);
debug("get global %u %s -> %d", index, name.c_str(), value);
@@ -471,14 +503,14 @@ void Process::fadeObject() {
warning("fadeObject: object %s not found", name.c_str());
}
-void Process::onObjectUse(unsigned size) {
+void Process::onObjectUse(uint16 size) {
Common::String arg = popString();
debug("register use object handler %s -> %u", arg.c_str(), _ip);
_object->setUseHandler(arg, _ip);
_ip += size;
}
-void Process::onObjectUserUse(unsigned size) {
+void Process::onObjectUserUse(uint16 size) {
debug("register user use handler %u", _ip);
_object->setUserUseHandler(_ip);
_ip += size;
@@ -713,12 +745,12 @@ void Process::setTileIndex() {
debug("setTileIndex: index: %d, resource id: %d ", _tileIndex, _tileResource);
}
-void Process::stub201(unsigned size) {
+void Process::stub201(uint16 size) {
debug("stub201, [handler] %u instructions", size);
_ip += size;
}
-void Process::stub202(unsigned size) {
+void Process::stub202(uint16 size) {
debug("stub202, [handler] %u instructions", size);
_ip += size;
}
@@ -1057,36 +1089,36 @@ void Process::call(uint16 addr) {
_engine->runProcess(_object, _ip + addr);
}
-void Process::onKey(unsigned size) {
+void Process::onKey(uint16 size) {
Common::String key = popString();
debug("onKey %s [handler], %u instructions", key.c_str(), size);
_object->setKeyHandler(key, _ip);
_ip += size;
}
-void Process::onUse(unsigned size) {
+void Process::onUse(uint16 size) {
debug("lclick [handler], %u instructions", size);
_object->setClickHandler(_ip);
_ip += size;
}
-void Process::onObjectC1(unsigned size) {
+void Process::onObjectC1(uint16 size) {
debug("unknown (0xc1) [handler], %u instructions", size);
_ip += size;
}
-void Process::onLook(unsigned size) {
+void Process::onLook(uint16 size) {
debug("look? [handler], %u instructions", size);
_object->setExamineHandler(_ip);
_ip += size;
}
-void Process::onObjectB9(unsigned size) {
+void Process::onObjectB9(uint16 size) {
debug("onObject(+B9) [handler], %u instructions", size);
_ip += size;
}
-void Process::onObjectBD(unsigned size) {
+void Process::onObjectBD(uint16 size) {
debug("onObject(+BD) [handler], %u instructions", size);
_ip += size;
}
@@ -1137,6 +1169,14 @@ void Process::moveCharacter(bool usermove) {
suspend();
}
+void Process::moveCharacterUserMove() {
+ moveCharacter(true);
+}
+
+void Process::moveCharacterNoUserMove() {
+ moveCharacter(false);
+}
+
void Process::animateCharacter() {
int arg2 = pop();
Common::String name = popString();
@@ -1326,53 +1366,48 @@ void Process::setCharacterNotifyVars() {
}
//fixme: add trace here
-#define OP(NAME, METHOD) \
+#define AGDS_OP(NAME, METHOD) \
case NAME: \
METHOD(); \
- break
-
-#define OP_I(NAME, METHOD, IMM) \
- case NAME: { \
- METHOD(IMM); \
- } break
+ break;
-#define OP_C(NAME, METHOD) \
+#define AGDS_OP_C(NAME, METHOD) \
case NAME: { \
int8 arg = next(); \
METHOD(arg); \
- } break
+ } break;
-#define OP_B(NAME, METHOD) \
+#define AGDS_OP_B(NAME, METHOD) \
case NAME: { \
uint8 arg = next(); \
METHOD(arg); \
- } break
+ } break;
-#define OP_W(NAME, METHOD) \
+#define AGDS_OP_W(NAME, METHOD) \
case NAME: { \
int16 arg = next16(); \
METHOD(arg); \
- } break
+ } break;
-#define OP_U(NAME, METHOD) \
+#define AGDS_OP_U(NAME, METHOD) \
case NAME: { \
uint16 arg = next16(); \
METHOD(arg); \
- } break
+ } break;
-#define OP_UU(NAME, METHOD) \
+#define AGDS_OP_UU(NAME, METHOD) \
case NAME: { \
uint16 arg1 = next16(); \
uint16 arg2 = next16(); \
METHOD(arg1, arg2); \
- } break
+ } break;
-#define OP_D(NAME, METHOD) \
+#define AGDS_OP_UD(NAME, METHOD) \
case NAME: { \
uint16 arg1 = next16(); \
uint32 arg2 = next16(); \
- METHOD(arg1 | (arg2 << 16)); \
- } break
+ METHOD(static_cast<int32>(arg1 | (arg2 << 16))); \
+ } break;
void Process::checkTimers() {
@@ -1391,193 +1426,14 @@ ProcessExitCode Process::resume() {
while (active() && _ip < code.size()) {
_lastIp = _ip;
uint8 op = next();
+ //debug("CODE %04x: %u", _lastIp, (uint)op);
switch (op) {
- OP_UU(kEnter, enter);
- OP_W(kJumpZImm16, jumpz);
- OP_W(kJumpImm16, jump);
- OP(kPop, pop);
- OP(kDup, dup);
- OP(kExitProcess, exitProcess);
- OP(kSuspendProcess, suspend);
- OP_D(kPushImm32, push);
- OP_C(kPushImm8, push);
- OP_W(kPushImm16, push);
- OP_C(kPushImm8_2, push);
- OP_W(kPushImm16_2, push);
- OP_B(kGetGlobalImm8, getGlobal);
- OP(kPostIncrementGlobal, postIncrementGlobal);
- OP(kPostDecrementGlobal, postDecrementGlobal);
- OP(kIncrementGlobalByTop, incrementGlobalByTop);
- OP(kDecrementGlobalByTop, decrementGlobalByTop);
- OP(kMultiplyGlobalByTop, multiplyGlobalByTop);
- OP(kDivideGlobalByTop, divideGlobalByTop);
- OP(kModGlobalByTop, modGlobalByTop);
- OP(kShlGlobalByTop, shlGlobalByTop);
- OP(kShrGlobalByTop, shrGlobalByTop);
- OP(kAndGlobalByTop, andGlobalByTop);
- OP(kOrGlobalByTop, orGlobalByTop);
- OP(kXorGlobalByTop, xorGlobalByTop);
- OP(kEquals, equals);
- OP(kNotEquals, notEquals);
- OP(kGreater, greater);
- OP(kLess, less);
- OP(kGreaterOrEquals, greaterOrEquals);
- OP(kLessOrEquals, lessOrEquals);
- OP(kAdd, add);
- OP(kSub, sub);
- OP(kMul, mul);
- OP(kDiv, div);
- OP(kMod, mod);
- OP(kSetGlobal, setGlobal);
- OP(kBoolOr, boolOr);
- OP(kBoolAnd, boolAnd);
- OP(kAnd, bitAnd);
- OP(kOr, bitOr);
- OP(kXor, bitXor);
- OP(kNot, bitNot);
- OP(kBoolNot, boolNot);
- OP(kNegate, negate);
- OP_U(kCallImm16, call);
- OP_U(kObjectRegisterLookHandler, onLook);
- OP_U(kObjectRegisterUseHandler, onUse);
- OP_U(kObjectRegisterHandlerC1, onObjectC1);
- OP_U(kObjectRegisterHandlerB9, onObjectB9);
- OP_U(kObjectRegisterHandlerBD, onObjectBD);
- OP(kLoadMouseCursorFromObject, loadMouseCursorFromObject);
- OP(kLoadRegionFromObject, loadRegionFromObject);
- OP(kLoadPictureFromObject, loadPictureFromObject);
- OP(kLoadAnimationFromObject, loadAnimationFromObject);
- OP(kShowCharacter, showCharacter);
- OP(kEnableCharacter, enableCharacter);
- OP_I(kMoveCharacterUserMove, moveCharacter, true);
- OP(kLeaveCharacter, leaveCharacter);
- OP(kSetCharacter, setCharacter);
- OP(kPointCharacter, pointCharacter);
- OP(kDisableUser, disableUser);
- OP(kEnableUser, enableUser);
- OP(kUpdatePhaseVarOr2, updatePhaseVarOr2);
- OP(kUpdatePhaseVarOr4, updatePhaseVarOr4);
- OP(kStub102, stub102);
- OP(kClearScreen, clearScreen);
- OP(kInventoryClear, inventoryClear);
- OP(kLoadMouse, loadMouse);
- OP(kInventoryAddObject, inventoryAddObject);
- OP(kSetNextScreenSaveInHistory, setNextScreenSaveInHistory);
- OP_U(kObjectRegisterUseObjectHandler, onObjectUse);
- OP(kStub82, stub82);
- OP(kStub83, stub83);
- OP(kAnimateCharacter, animateCharacter);
- OP(kLoadCharacter, loadCharacter);
- OP(kSetObjectZ, setObjectZ);
- OP(kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay);
- OP(kLoadTextFromObject, loadTextFromObject);
- OP(kScreenSetHeight, setScreenHeight);
- OP(kScreenLoadObject, loadScreenObject);
- OP(kScreenLoadRegion, loadScreenRegion);
- OP(kScreenCloneObject, cloneObject);
- OP(kSetNextScreen, setNextScreen);
- OP(kScreenRemoveObject, removeScreenObject);
- OP(kLoadAnimation, loadAnimation);
- OP(kLoadSample, loadSample);
- OP(kSetAnimationPaused, setAnimationPaused);
- OP(kPlayerSay, playerSay);
- OP(kNPCSay, npcSay);
- OP(kSetTimer, setTimer);
- OP(kProcessResetState, resetState);
- OP(kSetAnimationZ, setAnimationZ);
- OP(kSetCycles, setCycles);
- OP(kSetRandom, setRandom);
- OP(kSetPanAndVolume, setPanAndVolume);
- OP(kSetAnimationPosition, setAnimationPosition);
- OP(kSetPhaseVar, setPhaseVar);
- OP(kSetAnimationLoop, setAnimationLoop);
- OP(kSetAnimationSpeed, setAnimationSpeed);
- OP(kStub138, stub138);
- OP(kGetSavedMouseX, getSavedMouseX);
- OP(kGetSavedMouseY, getSavedMouseY);
- OP(kScreenChangeScreenPatch, changeScreenPatch);
- OP(kGetFreeInventorySpace, getInventoryFreeSpace);
- OP(kSetStringSystemVariable, setStringSystemVariable);
- OP(kSetSystemIntegerVariable, setIntegerSystemVariable);
- OP(kGetRegionCenterX, getRegionCenterX);
- OP(kGetRegionCenterY, getRegionCenterY);
- OP(kGetCharacterAnimationPhase, getCharacterAnimationPhase);
- OP(kGetIntegerSystemVariable, getIntegerSystemVariable);
- OP(kGetRandomNumber, getRandomNumber);
- OP(kAppendToSharedStorage, appendToSharedStorage);
- OP(kAppendNameToSharedStorage, appendNameToSharedStorage);
- OP(kCloneName, cloneName);
- OP(kGetCloneVar, getCloneVar);
- OP(kSetCloneVar, setCloneVar);
- OP(kGetPictureBaseX, getPictureBaseX);
- OP(kGetPictureBaseY, getPictureBaseY);
- OP(kGetObjectSurfaceX, getObjectSurfaceX);
- OP(kGetObjectSurfaceY, getObjectSurfaceX);
- OP(kLoadGame, loadGame);
- OP(kLoadSaveSlotNamePicture, loadSaveSlotNamePicture);
- OP(kStub166, stub166);
- OP(kSetDelay, setDelay);
- OP(kStub172, stub172);
- OP(kStub173, stub173);
- OP(kStub174, stub174);
- OP(kStub192, stub192);
- OP(kQuit, quit);
- OP(kExitProcessCreatePatch, exitProcessCreatePatch);
- OP(kDisableInventory, disableInventory);
- OP(kEnableInventory, enableInventory);
- OP(kLoadPreviousScreen, loadPreviousScreen);
- OP(kMoveScreenObject, moveScreenObject);
- OP(kGetObjectId, getObjectId);
- OP(kSetTileSize, setTileSize);
- OP(kGenerateRegion, generateRegion);
- OP(kGetMaxInventorySize, getMaxInventorySize);
- OP(kAppendInventoryObjectNameToSharedSpace, appendInventoryObjectNameToSharedSpace);
- OP(kSetObjectTile, setObjectTile);
- OP(kInventoryHasObject, inventoryHasObject);
- OP(kSetObjectText, setObjectText);
- OP(kSetObjectScale, setObjectScale);
- OP(kStub191, disableMouseAreas);
- OP(kStub193, stub193);
- OP(kMute, stub194);
- OP(kGetObjectPictureWidth, getObjectPictureWidth);
- OP(kGetObjectPictureHeight, getObjectPictureHeight);
- OP(kLoadPicture, loadPicture);
- OP(kStub199, stub199);
- OP(kSetSampleVolumeAndPan, setSampleVolumeAndPan);
- OP(kAddSampleToSoundGroup, addSampleToSoundGroup);
- OP(kStub215, stub215);
- OP(kStub216, stub216);
- OP(kStub217, stub217);
- OP(kStopCharacter, stopCharacter);
- OP(kLeaveCharacterEx, leaveCharacterEx);
- OP(kPlayAnimationWithPhaseVar, playAnimationWithPhaseVar);
- OP(kStub223, stub223);
- OP(kSetNPCTellNotifyVar, setNPCTellNotifyVar);
- OP(kStub225, stub225);
- OP(kFadeObject, fadeObject);
- OP(kLoadFont, loadFont);
- OP_U(kStub201Handler, stub201);
- OP_U(kStub202ScreenHandler, stub202);
- OP(kPlayFilm, playFilm);
- OP(kAddMouseArea, addMouseArea);
- OP(kSetRain, setRain);
- OP(kSetRainDensity, setRainDensity);
- OP(kFogOnCharacter, fogOnCharacter);
- OP(kSetTileIndex, setTileIndex);
- OP(kModifyMouseArea, modifyMouseArea);
- OP_U(kObjectRegisterUserUseHandler, onObjectUserUse);
- OP_I(kMoveCharacterNoUserMove, moveCharacter, false);
- OP_U(kOnKey, onKey);
- OP(kGetSampleVolume, getSampleVolume);
- OP(kStub231, stub231);
- OP(kStub233, stub233);
- OP(kStub235, stub235);
- OP(kUserEnabled, userEnabled);
- OP(kSetCharacterNotifyVars, setCharacterNotifyVars);
- OP(kInventoryFindObjectByName, inventoryFindObjectByName);
- OP(kLoadDialog, loadDialog);
- OP(kHasGlobal, hasGlobal);
- OP(kSetDialogForNextFilm, setDialogForNextFilm);
+ AGDS_OPCODE_LIST(
+ AGDS_OP,
+ AGDS_OP_C, AGDS_OP_B,
+ AGDS_OP_W, AGDS_OP_U,
+ AGDS_OP_UD, AGDS_OP_UU
+ )
default:
error("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _ip - 1, (unsigned)op, (unsigned)op);
fail();
Commit: 3bf682b47975854f1cd35c62e6612445eaa230d5
https://github.com/scummvm/scummvm/commit/3bf682b47975854f1cd35c62e6612445eaa230d5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:23+01:00
Commit Message:
AGDS: clear animation from loadScreen
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c1e3e79c712..d6411231b40 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -196,6 +196,7 @@ void AGDSEngine::loadScreen(const Common::String &name) {
_mouseMap.hideAll(this);
resetCurrentScreen();
_processes.clear();
+ _animations.clear();
_soundManager.stopAll();
_currentScreenName = name;
Commit: bd6b4efeb1bf0db5dc995353bfd0140734173b0f
https://github.com/scummvm/scummvm/commit/bd6b4efeb1bf0db5dc995353bfd0140734173b0f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:23+01:00
Commit Message:
AGDS: add screen patch comment
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index d6411231b40..1519e491db9 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -200,6 +200,7 @@ void AGDSEngine::loadScreen(const Common::String &name) {
_soundManager.stopAll();
_currentScreenName = name;
+ //SAVE CURRENT OBJECTS IN PATCH see save_screen_patch
_currentScreen = new Screen(loadObject(name));
runProcess(_currentScreen->getObject());
Commit: bde8923b2365b9efc3cf23ebec3c4479714f74f6
https://github.com/scummvm/scummvm/commit/bde8923b2365b9efc3cf23ebec3c4479714f74f6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:23+01:00
Commit Message:
AGDS: add console info command stub + accessor for processes
Changed paths:
engines/agds/agds.h
engines/agds/console.cpp
engines/agds/console.h
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index fe9675d77af..6929cc28b12 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -131,6 +131,10 @@ public:
return _dialog;
}
+ const ProcessListType & processes() const {
+ return _processes;
+ }
+
TextLayout & textLayout() {
return _textLayout;
}
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index f51326247f6..5217e91c59d 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -27,8 +27,9 @@
namespace AGDS {
Console::Console(AGDSEngine *engine) : _engine(engine) {
- registerCmd("run", WRAP_METHOD(Console, run));
registerCmd("activate", WRAP_METHOD(Console, activate));
+ registerCmd("info", WRAP_METHOD(Console, info));
+ registerCmd("run", WRAP_METHOD(Console, run));
}
bool Console::run(int argc, const char **argv) {
@@ -56,4 +57,9 @@ bool Console::activate(int argc, const char **argv) {
return false;
}
+bool Console::info(int argc, const char **argv) {
+ debugPrintf("processes:");
+ return true;
+}
+
}
diff --git a/engines/agds/console.h b/engines/agds/console.h
index d321cb6e782..85a908c25cc 100644
--- a/engines/agds/console.h
+++ b/engines/agds/console.h
@@ -38,6 +38,7 @@ public:
private:
bool run(int argc, const char **argv);
bool activate(int argc, const char **argv);
+ bool info(int argc, const char **argv);
AGDSEngine *_engine;
};
Commit: 530df0343eba5a88ee48d7be19631dbd34cd24a1
https://github.com/scummvm/scummvm/commit/530df0343eba5a88ee48d7be19631dbd34cd24a1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:23+01:00
Commit Message:
AGDS: remove noisy logs
Changed paths:
engines/agds/agds.cpp
engines/agds/animation.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 1519e491db9..7b6104bd8f3 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -237,7 +237,7 @@ void AGDSEngine::runProcesses() {
i = _processes.erase(i);
//FIXME: when the last process exits, remove object from scene
} else {
- debug("suspended process %s", process.getName().c_str());
+ //debug("suspended process %s", process.getName().c_str());
++i;
}
}
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 4a23b21105c..e2a808f1a04 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -53,8 +53,6 @@ bool Animation::load(Common::SeekableReadStream *stream) {
void Animation::updatePhaseVar(AGDSEngine &engine) {
debug("animation %d, phase var: %s, process: %s", _phase, _phaseVar.c_str(), _process.c_str());
- if (_phase == -1)
- debug("animation ended, phase var: %s, process: %s", _phaseVar.c_str(), _process.c_str());
if (!_phaseVar.empty())
engine.setGlobal(_phaseVar, _phase);
Commit: 50138cde1ab6beb4450e77b547e339447da6031b
https://github.com/scummvm/scummvm/commit/50138cde1ab6beb4450e77b547e339447da6031b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:23+01:00
Commit Message:
AGDS: delete flic instance before load
Changed paths:
engines/agds/animation.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index e2a808f1a04..d5a24b01cb6 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -38,6 +38,7 @@ Animation::~Animation() {
}
bool Animation::load(Common::SeekableReadStream *stream) {
+ delete _flic;
Video::FlicDecoder *flic = new Video::FlicDecoder;
if (flic->loadStream(stream)) {
_frames = flic->getFrameCount();
Commit: 63d0c0c0221e42ea364decf2817889b593fee832
https://github.com/scummvm/scummvm/commit/63d0c0c0221e42ea364decf2817889b593fee832
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:23+01:00
Commit Message:
AGDS: add 'info' command for console debugger
Changed paths:
engines/agds/console.cpp
engines/agds/screen.h
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index 5217e91c59d..d4de21ce4c2 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -23,6 +23,8 @@
#include "agds/console.h"
#include "agds/agds.h"
#include "agds/object.h"
+#include "agds/process.h"
+#include "agds/screen.h"
namespace AGDS {
@@ -39,7 +41,7 @@ bool Console::run(int argc, const char **argv) {
}
ObjectPtr object = _engine->getCurrentScreenObject(argv[1]);
if (!object) {
- debugPrintf("no object %s", argv[1]);
+ debugPrintf("no object %s\n", argv[1]);
return true;
}
_engine->runObject(object);
@@ -58,7 +60,20 @@ bool Console::activate(int argc, const char **argv) {
}
bool Console::info(int argc, const char **argv) {
- debugPrintf("processes:");
+ auto screen = _engine->getCurrentScreen();
+ if (screen) {
+ debugPrintf("screen %s:\n", screen->getName().c_str());
+ auto & children = screen->children();
+ for(auto & object : children) {
+ auto pos = object->getPosition();
+ debugPrintf("object %s [inscene: %d] at %d,%d\n", object->getName().c_str(), object->inScene(), pos.x, pos.y);
+ }
+ }
+ debugPrintf("processes:\n");
+ auto & processes = _engine->processes();
+ for(auto & process : processes) {
+ debugPrintf("%s\n", process.getName().c_str());
+ }
return true;
}
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 5695cabbce8..29eb8c48537 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -90,6 +90,10 @@ public:
_region = region;
}
+ const ChildrenType & children() const {
+ return _children;
+ }
+
bool add(ObjectPtr object);
void add(Animation * animation) {
_animations.insert(animation);
Commit: 1807939469036179685289284bff386b402d8b66
https://github.com/scummvm/scummvm/commit/1807939469036179685289284bff386b402d8b66
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:23+01:00
Commit Message:
AGDS: activate process after new game exit code
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 77557e5ae72..88f815e1a5d 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -186,6 +186,7 @@ void Process::run() {
{
debug("exitProcessCreatePatch");
_engine->newGame();
+ activate();
}
break;
case kExitCodeLoadSaveGame:
Commit: cad0050e1e45f0fd7ea00939a888c0852a9fd63a
https://github.com/scummvm/scummvm/commit/cad0050e1e45f0fd7ea00939a888c0852a9fd63a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:23+01:00
Commit Message:
AGDS: remodel phase update code in sound manager
Changed paths:
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 86a233a3a71..a377803361c 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -174,8 +174,6 @@ void Process::loadSample() {
Common::String name = popText();
debug("loadSample %s, phaseVar: %s", name.c_str(), _phaseVar.c_str());
_engine->playSound(getName(), name, _phaseVar);
- if (!_phaseVar.empty())
- suspend();
}
void Process::getSampleVolume() {
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 21d33e7e1a9..17c5da958bb 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -32,23 +32,42 @@
namespace AGDS {
+void SoundManager::setPhaseVar(const Sound &sound, int value) {
+ if (!sound.phaseVar.empty())
+ _engine->setGlobal(sound.phaseVar, value);
+}
+
void SoundManager::tick() {
for (SoundList::iterator i = _sounds.begin(); i != _sounds.end();) {
Sound &sound = *i;
- if (!_mixer->isSoundHandleActive(sound.handle)) {
- debug("sound %s stopped", sound.name.c_str());
- if (!sound.phaseVar.empty())
- _engine->setGlobal(sound.phaseVar, 0);
+ _engine->reactivate(sound.process);
- _engine->reactivate(sound.process);
- i = _sounds.erase(i);
+ bool active = _mixer->isSoundHandleActive(sound.handle);
+ if (sound.phaseVar.empty()) {
+ if (!active) {
+ i = _sounds.erase(i);
+ } else {
+ ++i;
+ }
} else {
- debug("sound %s playing", sound.name.c_str());
- if (!sound.phaseVar.empty())
- _engine->setGlobal(sound.phaseVar, 1);
-
- _engine->reactivate(sound.process);
- ++i;
+ int value = _engine->getGlobal(sound.phaseVar);
+ if (value <= 1) {
+ if (value == 1 && !active)
+ setPhaseVar(sound, 0);
+ if (!active)
+ i = _sounds.erase(i);
+ else
+ ++i;
+ } else if (value & 2) {
+ setPhaseVar(sound, 1);
+ _mixer->stopID(sound.id);
+ play(sound.process, sound.name, sound.phaseVar, sound.id);
+ i = _sounds.erase(i);
+ } else if (value & 4) {
+ _mixer->stopID(sound.id);
+ setPhaseVar(sound, 0);
+ i = _sounds.erase(i);
+ }
}
}
}
@@ -57,16 +76,20 @@ void SoundManager::stopAll() {
_mixer->stopAll();
for (SoundList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) {
Sound &sound = *i;
- _engine->setGlobal(sound.phaseVar, 0);
+ setPhaseVar(sound, 0);
}
_sounds.clear();
}
-int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &phaseVar) {
+int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &phaseVar, int id) {
debug("SoundMan::play %s %s %s", process.c_str(), resource.c_str(), phaseVar.c_str());
Common::File *file = new Common::File();
- if (!file->open(resource))
- error("no sound %s", resource.c_str());
+ if (!file->open(resource)) {
+ if (!phaseVar.empty())
+ _engine->setGlobal(phaseVar, 0);
+ warning("no sound %s", resource.c_str());
+ return -1;
+ }
Common::String lname(resource);
lname.toLowercase();
@@ -86,10 +109,13 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
return -1;
}
Audio::SoundHandle handle;
- int id = _nextId++;
+ if (id == -1)
+ id = _nextId++;
_mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, stream, id);
_sounds.push_back(Sound(id, process, resource, phaseVar, handle));
+ //if (sound_off)
+ // setPhaseVar(_sounds.back(), 1);
return id;
}
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index 49bb97cd6c9..681697772c1 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -57,9 +57,11 @@ namespace AGDS {
public:
SoundManager(AGDSEngine *engine, Audio::Mixer *mixer): _nextId(1), _engine(engine), _mixer(mixer) { }
void tick();
- int play(const Common::String &process, const Common::String &file, const Common::String &phaseVar);
+ int play(const Common::String &process, const Common::String &file, const Common::String &phaseVar, int id = -1);
bool playing(int id) const;
void stopAll();
+ private:
+ void setPhaseVar(const Sound &sound, int value);
};
} // End of namespace AGDS
Commit: e7177aba3aa75bc9dec09959b9278257ae45bd92
https://github.com/scummvm/scummvm/commit/e7177aba3aa75bc9dec09959b9278257ae45bd92
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:23+01:00
Commit Message:
AGDS: slightly changed animation log
Changed paths:
engines/agds/animation.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index d5a24b01cb6..f79f455e79f 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -53,7 +53,7 @@ bool Animation::load(Common::SeekableReadStream *stream) {
}
void Animation::updatePhaseVar(AGDSEngine &engine) {
- debug("animation %d, phase var: %s, process: %s", _phase, _phaseVar.c_str(), _process.c_str());
+ debug("animation %s %d, phase var: %s", _process.c_str(), _phase, _phaseVar.c_str());
if (!_phaseVar.empty())
engine.setGlobal(_phaseVar, _phase);
Commit: 7ec64636dc6794446222f860ba89de067a4382b5
https://github.com/scummvm/scummvm/commit/7ec64636dc6794446222f860ba89de067a4382b5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:24+01:00
Commit Message:
AGDS: fix more phase var logic
Changed paths:
engines/agds/agds.cpp
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 7b6104bd8f3..6c990ba1c0b 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -528,6 +528,7 @@ const Common::String &AGDSEngine::getSharedStorage(int id) const {
}
void AGDSEngine::setGlobal(const Common::String &name, int value) {
+ debug("setting global %s -> %d", name.c_str(), value);
bool create = !_globals.contains(name);
_globals.setVal(name, value);
if (create) {
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index f79f455e79f..0e40fd84979 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -53,12 +53,13 @@ bool Animation::load(Common::SeekableReadStream *stream) {
}
void Animation::updatePhaseVar(AGDSEngine &engine) {
- debug("animation %s %d, phase var: %s", _process.c_str(), _phase, _phaseVar.c_str());
+ debug("animation %s %s %d, phase var: %s", _process.c_str(), _paused? "paused": "playing", _phase, _phaseVar.c_str());
- if (!_phaseVar.empty())
- engine.setGlobal(_phaseVar, _phase);
- else
- engine.reactivate(_process);
+ if (!_phaseVar.empty()) {
+ if (!_paused)
+ engine.setGlobal(_phaseVar, _phase);
+ }
+ engine.reactivate(_process);
}
void Animation::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point dst) {
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index c8728dc7443..08d73a0b41a 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -85,7 +85,12 @@ public:
_phase = 0;
}
+ void pause() {
+ _paused = true;
+ }
+
void stop() {
+ _phase = -1;
_paused = true;
}
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 8153923676b..962cbade9a8 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -238,7 +238,7 @@ enum Opcode {
kSetRainDensity = 218,
kLeaveCharacterEx = 219,
kStopCharacter = 220,
- kPlayAnimationWithPhaseVar = 221,
+ kSyncAnimationWithPhaseVar = 221,
kStub222 = 222,
kStub223 = 223,
kSetNPCTellNotifyVar = 224,
@@ -428,7 +428,7 @@ enum Opcode {
OP(kStub217, stub217) \
OP(kStopCharacter, stopCharacter) \
OP(kLeaveCharacterEx, leaveCharacterEx) \
- OP(kPlayAnimationWithPhaseVar, playAnimationWithPhaseVar) \
+ OP(kSyncAnimationWithPhaseVar, syncAnimationWithPhaseVar) \
OP(kStub223, stub223) \
OP(kSetNPCTellNotifyVar, setNPCTellNotifyVar) \
OP(kStub225, stub225) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index a377803361c..e68543e3b0c 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -163,7 +163,7 @@ void Process::loadAnimation() {
animation->loop(_animationLoop);
animation->cycles(_animationCycles);
if (_animationPaused)
- animation->stop();
+ animation->pause();
else
animation->play();
_engine->getCurrentScreen()->add(animation);
@@ -263,7 +263,6 @@ void Process::getRandomNumber() {
void Process::setGlobal() {
Common::String name = popString();
int value = pop();
- debug("setting global %s -> %d", name.c_str(), value);
_engine->setGlobal(name, value);
}
@@ -779,16 +778,23 @@ void Process::stub217() {
debug("stub217: animation? id: %d, frame: %d, soundGroup: %d", id, frame, soundGroup);
}
-void Process::playAnimationWithPhaseVar() {
+void Process::syncAnimationWithPhaseVar() {
Common::String phaseVar = popString();
- debug("playAnimationWithPhaseVar %s", phaseVar.c_str());
+ debug("syncAnimationWithPhaseVar %s", phaseVar.c_str());
+ if (phaseVar.empty()) {
+ warning("no phaseVar");
+ return;
+ }
Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
if (animation) {
- animation->phaseVar(phaseVar);
- animation->play();
- _engine->setGlobal(phaseVar, 0);
- } else
+ if (_engine->getGlobal(phaseVar) == -1) {
+ animation->stop();
+ }
+ _engine->setGlobal(phaseVar, animation->phase());
+ } else {
warning("no animation with phase var %s found", phaseVar.c_str());
+ _engine->setGlobal(phaseVar, -1);
+ }
}
void Process::stub223() {
@@ -1309,7 +1315,7 @@ void Process::loadAnimationFromObject() {
animation->loop(_animationLoop);
animation->cycles(_animationCycles);
if (_animationPaused)
- animation->stop();
+ animation->pause();
}
}
@@ -1338,8 +1344,9 @@ void Process::stub233() {
Common::String name = popString();
debug("stub233 %s unload picture?", name.c_str());
ObjectPtr object = _engine->getCurrentScreenObject(name);
- if (object)
+ if (object) {
object->setPicture(NULL);
+ }
}
void Process::stub235() {
Commit: 326b6d74a44a16756a416ace4022c4c56bfee2c5
https://github.com/scummvm/scummvm/commit/326b6d74a44a16756a416ace4022c4c56bfee2c5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:24+01:00
Commit Message:
AGDS: more opcodes implemented: pan/volume, restart/stop sample
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/console.cpp
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 6c990ba1c0b..6007de8a355 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -448,7 +448,7 @@ Common::Error AGDSEngine::run() {
if (_mjpgPlayer->eos()) {
delete _mjpgPlayer;
_mjpgPlayer = NULL;
- reactivate(_filmProcess);
+ reactivate(_filmProcess, false);
}
} else if (_currentScreen) {
_currentScreen->paint(*this, *backbuffer);
@@ -509,7 +509,7 @@ void AGDSEngine::skipFilm() {
_syncSoundId = -1;
}
_textLayout.reset(*this);
- reactivate(_filmProcess);
+ reactivate(_filmProcess, false);
}
int AGDSEngine::appendToSharedStorage(const Common::String &value) {
@@ -889,15 +889,17 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
return Common::kNoError;
}
-void AGDSEngine::reactivate(const Common::String &name) {
+void AGDSEngine::reactivate(const Common::String &name, bool runNow) {
if (name.empty())
return;
- debug("reactivate %s", name.c_str());
for(ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ++i) {
Process &process = *i;
if (process.getName() == name) {
+ debug("reactivate %s %s", name.c_str(), runNow? "(now)": "");
process.activate();
+ if (runNow)
+ process.run();
}
}
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 6929cc28b12..f05a18094e2 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -123,6 +123,10 @@ public:
return _resourceManager;
}
+ SoundManager & soundManager() {
+ return _soundManager;
+ }
+
Inventory & inventory() {
return _inventory;
}
@@ -226,7 +230,7 @@ public:
return _mouse;
}
- void reactivate(const Common::String &name);
+ void reactivate(const Common::String &name, bool runNow);
private:
void loadPatches(Common::SeekableReadStream *file, Database & db);
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 0e40fd84979..acefde387ef 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -53,13 +53,14 @@ bool Animation::load(Common::SeekableReadStream *stream) {
}
void Animation::updatePhaseVar(AGDSEngine &engine) {
- debug("animation %s %s %d, phase var: %s", _process.c_str(), _paused? "paused": "playing", _phase, _phaseVar.c_str());
+ if (!_process.empty() || !_phaseVar.empty()) //ignore mouse cursors
+ debug("animation %s %s %d, phase var: %s", _process.c_str(), _paused? "paused": "playing", _phase, _phaseVar.c_str());
if (!_phaseVar.empty()) {
if (!_paused)
engine.setGlobal(_phaseVar, _phase);
}
- engine.reactivate(_process);
+ engine.reactivate(_process, true);
}
void Animation::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point dst) {
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 08d73a0b41a..0bb2124e684 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -85,6 +85,10 @@ public:
_phase = 0;
}
+ void resume() {
+ _paused = false;
+ }
+
void pause() {
_paused = true;
}
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index d4de21ce4c2..af4e607e5d1 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -54,7 +54,7 @@ bool Console::activate(int argc, const char **argv) {
debugPrintf("usage: %s object_id\n", argv[0]);
return true;
}
- _engine->reactivate(argv[1]);
+ _engine->reactivate(argv[1], false);
detach();
return false;
}
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 962cbade9a8..9b9d9dddc25 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -117,8 +117,8 @@ enum Opcode {
kPointCharacter = 97,
kDisableUser = 98,
kEnableUser = 99,
- kUpdatePhaseVarOr2 = 100,
- kUpdatePhaseVarOr4 = 101,
+ kRestartSample = 100,
+ kStopSample = 101,
kStub102 = 102,
kStub103 = 103,
kStub104 = 104,
@@ -232,7 +232,7 @@ enum Opcode {
kSetSampleVolumeAndPan = 212,
kStub213 = 213,
kAddSampleToSoundGroup = 214,
- kStub215 = 215,
+ kClearSoundGroup = 215,
kStub216 = 216,
kStub217 = 217,
kSetRainDensity = 218,
@@ -242,7 +242,7 @@ enum Opcode {
kStub222 = 222,
kStub223 = 223,
kSetNPCTellNotifyVar = 224,
- kStub225 = 225,
+ kModifyAnimationWithPhaseVar = 225,
kFadeObject = 226,
kLoadFont = 227,
kMoveCharacterNoUserMove = 228,
@@ -331,8 +331,8 @@ enum Opcode {
OP(kPointCharacter, pointCharacter) \
OP(kDisableUser, disableUser) \
OP(kEnableUser, enableUser) \
- OP(kUpdatePhaseVarOr2, updatePhaseVarOr2) \
- OP(kUpdatePhaseVarOr4, updatePhaseVarOr4) \
+ OP(kRestartSample, restartSample) \
+ OP(kStopSample, stopSample) \
OP(kStub102, stub102) \
OP(kClearScreen, clearScreen) \
OP(kInventoryClear, inventoryClear) \
@@ -423,7 +423,7 @@ enum Opcode {
OP(kStub199, stub199) \
OP(kSetSampleVolumeAndPan, setSampleVolumeAndPan) \
OP(kAddSampleToSoundGroup, addSampleToSoundGroup) \
- OP(kStub215, stub215) \
+ OP(kClearSoundGroup, clearSoundGroup) \
OP(kStub216, stub216) \
OP(kStub217, stub217) \
OP(kStopCharacter, stopCharacter) \
@@ -431,7 +431,7 @@ enum Opcode {
OP(kSyncAnimationWithPhaseVar, syncAnimationWithPhaseVar) \
OP(kStub223, stub223) \
OP(kSetNPCTellNotifyVar, setNPCTellNotifyVar) \
- OP(kStub225, stub225) \
+ OP(kModifyAnimationWithPhaseVar, modifyAnimationWithPhaseVar) \
OP(kFadeObject, fadeObject) \
OP(kLoadFont, loadFont) \
OP_U(kStub201Handler, stub201) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index e68543e3b0c..86c566d1a0f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -153,7 +153,7 @@ void Process::loadPicture() {
void Process::loadAnimation() {
Common::String name = popText();
- debug("loadAnimation %s (phase: %s)", name.c_str(), _phaseVar.c_str());
+ debug("loadAnimation %s (phase: %s) %s", name.c_str(), _phaseVar.c_str(), _animationPaused? "(paused)": "");
Animation *animation = _engine->loadAnimation(name);
if (animation) {
animation->position(_animationPosition);
@@ -178,15 +178,47 @@ void Process::loadSample() {
void Process::getSampleVolume() {
Common::String name = popString();
- debug("getSampleVolume: stub %s", name.c_str());
- push(100);
+ debug("getSampleVolume: %s", name.c_str());
+ auto sound = _engine->soundManager().findSampleByPhaseVar(name);
+ if (sound) {
+ debug("\treturning %d", sound->leftVolume);
+ push(sound->leftVolume);
+ } else {
+ warning("could not find sample %s", name.c_str());
+ push(-1);
+ }
}
void Process::setSampleVolumeAndPan() {
int pan = pop();
int volume = pop();
+ if (volume < 0)
+ volume = 0;
+ else if (volume > 100)
+ volume = 100;
+ if (pan < -100)
+ pan = -100;
+ if (pan > 100)
+ pan = 100;
Common::String name = popString();
- debug("setSampleVolumeAndPan %s %d %d", name.c_str(), volume, pan);
+ auto sound = _engine->soundManager().findSampleByPhaseVar(name);
+ if (!sound) {
+ warning("can't find sample with phase var %s", name.c_str());
+ return;
+ }
+
+ debug("setSampleVolumeAndPan %s, volume: %d, pan: %d", name.c_str(), volume, pan);
+ int l, r;
+ if (pan < 0) {
+ l = volume;
+ r = volume * (100 + pan) / 100;
+ } else {
+ l = volume * (100 - pan) / 100;
+ r = volume;
+ }
+ debug("\tleft: %d, right: %d", l, r);
+ sound->leftVolume = l;
+ sound->rightVolume = r;
}
void Process::addSampleToSoundGroup() {
@@ -195,18 +227,30 @@ void Process::addSampleToSoundGroup() {
debug("addSampleToSoundGroup stub: %s sound group: %d", name.c_str(), arg);
}
-void Process::updatePhaseVarOr2() {
+void Process::restartSample() {
Common::String name = popString();
- debug("updatePhaseVarOr2 stub %s", name.c_str());
- int value = _engine->getGlobal(name);
- _engine->setGlobal(name, value | 2);
+ debug("restartSample %s", name.c_str());
+ auto sound = _engine->soundManager().findSampleByPhaseVar(name);
+ if (sound) {
+ debug("sample found (%s)", sound->name.c_str());
+ int value = _engine->getGlobal(name);
+ _engine->setGlobal(name, value | 2);
+ } else {
+ debug("sample not found");
+ }
}
-void Process::updatePhaseVarOr4() {
+void Process::stopSample() {
Common::String name = popString();
- debug("updatePhaseVarOr4 stub %s", name.c_str());
- int value = _engine->getGlobal(name);
- _engine->setGlobal(name, value | 4);
+ debug("restartSample %s", name.c_str());
+ auto sound = _engine->soundManager().findSampleByPhaseVar(name);
+ if (sound) {
+ debug("sample found (%s)", sound->name.c_str());
+ int value = _engine->getGlobal(name);
+ _engine->setGlobal(name, value | 4);
+ } else {
+ debug("sample not found");
+ }
}
void Process::loadScreenObject() {
@@ -695,7 +739,7 @@ void Process::stub166() {
void Process::stub172() {
int value = pop();
- debug("stub172: %d", value);
+ debug("stub172: setMusicVolume? %d", value);
}
void Process::stub173() {
@@ -733,7 +777,7 @@ void Process::stub194() {
void Process::stub199() {
int value = pop();
- debug("stub199: %d", value);
+ debug("stub199: (free cached surface?) %d", value);
}
void Process::setTileIndex() {
@@ -759,16 +803,16 @@ void Process::modifyMouseArea() {
suspend(kExitCodeMouseAreaChange, id, enabled);
}
-void Process::stub215() {
+void Process::clearSoundGroup() {
int id = pop();
- debug("stub215: sound group %d", id);
+ debug("clearSoundGroup stub: %d", id);
}
void Process::stub216() {
int soundGroup = pop();
int frame = pop();
int id = pop();
- debug("stub216: animation? id: %d, frame: %d, soundGroup: %d", id, frame, soundGroup);
+ debug("stub216: setCharacterWalkSound? id: %d, frame: %d, soundGroup: %d", id, frame, soundGroup);
}
void Process::stub217() {
@@ -802,10 +846,20 @@ void Process::stub223() {
debug("stub223: %d", value);
}
-void Process::stub225() {
+void Process::modifyAnimationWithPhaseVar() {
int arg = pop();
Common::String phaseVar = popString();
- debug("stub225: animation related, phaseVar %s, arg %d", phaseVar.c_str(), arg);
+ Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
+ debug("modifyAnimationWithPhaseVar: phaseVar %s, arg %d", phaseVar.c_str(), arg);
+ if (animation) {
+ if (arg > 0) {
+ //1, 2 stop (2 with rewind?)
+ animation->stop();
+ _engine->setGlobal(phaseVar, 0);
+ }
+ else
+ animation->resume();
+ }
}
void Process::setTileSize() {
@@ -1273,8 +1327,6 @@ void Process::fogOnCharacter() {
int arg1 = pop();
Common::String name = popText();
debug("fogOnCharacter %s %d %d", name.c_str(), arg1, arg2);
- debug("fixme: some script commands call enableUser again");
- enableUser();
}
void Process::setRain() {
@@ -1304,7 +1356,7 @@ void Process::loadPictureFromObject() {
void Process::loadAnimationFromObject() {
Common::String name = popText();
- debug("loadAnimationFromObject %s", name.c_str());
+ debug("loadAnimationFromObject %s %s", name.c_str(), _animationPaused? "(paused)": "");
if (!_phaseVar.empty()) {
_engine->setGlobal(_phaseVar, -2);
}
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 17c5da958bb..2bdef90ef8f 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -35,47 +35,50 @@ namespace AGDS {
void SoundManager::setPhaseVar(const Sound &sound, int value) {
if (!sound.phaseVar.empty())
_engine->setGlobal(sound.phaseVar, value);
+ _engine->reactivate(sound.process, true);
}
void SoundManager::tick() {
- for (SoundList::iterator i = _sounds.begin(); i != _sounds.end();) {
+ for (SoundList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) {
Sound &sound = *i;
- _engine->reactivate(sound.process);
bool active = _mixer->isSoundHandleActive(sound.handle);
- if (sound.phaseVar.empty()) {
- if (!active) {
- i = _sounds.erase(i);
- } else {
- ++i;
- }
- } else {
+ if (!sound.phaseVar.empty()) {
int value = _engine->getGlobal(sound.phaseVar);
if (value <= 1) {
- if (value == 1 && !active)
+ if (value == 1 && !active) {
setPhaseVar(sound, 0);
- if (!active)
- i = _sounds.erase(i);
- else
- ++i;
+ } else if (value == 0 && active)
+ setPhaseVar(sound, 1);
} else if (value & 2) {
+ debug("sample %s restarts (via phase var)", sound.name.c_str());
setPhaseVar(sound, 1);
_mixer->stopID(sound.id);
play(sound.process, sound.name, sound.phaseVar, sound.id);
- i = _sounds.erase(i);
} else if (value & 4) {
+ debug("sample %s stops (via phase var)", sound.name.c_str());
_mixer->stopID(sound.id);
setPhaseVar(sound, 0);
- i = _sounds.erase(i);
}
}
}
}
+Sound *SoundManager::findSampleByPhaseVar(const Common::String &phaseVar) {
+ for (auto i = _sounds.begin(); i != _sounds.end(); ++i) {
+ auto &sound = *i;
+ if (sound.phaseVar == phaseVar) {
+ return &sound;
+ }
+ }
+ return nullptr;
+}
+
+
void SoundManager::stopAll() {
_mixer->stopAll();
- for (SoundList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) {
- Sound &sound = *i;
+ for (auto i = _sounds.begin(); i != _sounds.end(); ++i) {
+ auto &sound = *i;
setPhaseVar(sound, 0);
}
_sounds.clear();
@@ -103,9 +106,9 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
if (!stream) {
warning("could not play sound %s", resource.c_str());
delete file;
- _engine->reactivate(process);
if (!phaseVar.empty())
_engine->setGlobal(phaseVar, 0);
+ _engine->reactivate(process, true);
return -1;
}
Audio::SoundHandle handle;
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index 681697772c1..4a1df988e07 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -42,8 +42,10 @@ namespace AGDS {
Common::String phaseVar;
Audio::SoundHandle handle;
int group;
+ int leftVolume;
+ int rightVolume;
Sound(int id_, const Common::String &p, const Common::String & res, const Common::String & var, Audio::SoundHandle h, int g = 0):
- id(id_), process(p), name(res), phaseVar(var), handle(h), group(g) {
+ id(id_), process(p), name(res), phaseVar(var), handle(h), group(g), leftVolume(100), rightVolume(100) {
}
};
@@ -60,6 +62,7 @@ namespace AGDS {
int play(const Common::String &process, const Common::String &file, const Common::String &phaseVar, int id = -1);
bool playing(int id) const;
void stopAll();
+ Sound *findSampleByPhaseVar(const Common::String &phaseVar);
private:
void setPhaseVar(const Sound &sound, int value);
};
Commit: 894f08a8f702951ba6b554eacb445c2e1af638a9
https://github.com/scummvm/scummvm/commit/894f08a8f702951ba6b554eacb445c2e1af638a9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:24+01:00
Commit Message:
AGDS: modelled timers after original logic
Changed paths:
engines/agds/agds.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 6007de8a355..8b6eea76123 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -228,7 +228,6 @@ void AGDSEngine::resetCurrentScreen() {
void AGDSEngine::runProcesses() {
for (ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
Process &process = *i;
- process.checkTimers();
if (process.active()) {
process.run();
++i;
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 50a8e53860e..d254d7aa901 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -172,7 +172,6 @@ public:
return _status == kStatusPassive;
}
void activate();
- void checkTimers();
void done() {
_status = kStatusDone;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 86c566d1a0f..5925bd495de 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1467,20 +1467,18 @@ void Process::setCharacterNotifyVars() {
} break;
-void Process::checkTimers() {
- if (_timer > 0) {
- debug("waiting for timer (%d)...", _timer);
- --_timer;
- if (_timer == 0)
- activate();
- }
-}
-
ProcessExitCode Process::resume() {
_exitCode = kExitCodeDestroy;
+ if (_timer) {
+ --_timer;
+ return kExitCodeSuspend;
+ }
const Object::CodeType &code = _object->getCode();
while (active() && _ip < code.size()) {
+ if (_timer) {
+ return kExitCodeSuspend;
+ }
_lastIp = _ip;
uint8 op = next();
//debug("CODE %04x: %u", _lastIp, (uint)op);
Commit: f2794385ea5c495792f5d8ef50feaefa2e4c97ba
https://github.com/scummvm/scummvm/commit/f2794385ea5c495792f5d8ef50feaefa2e4c97ba
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:24+01:00
Commit Message:
AGDS: add decription for remove mouse cursor stub, add more of fadeScreen stub (global var update)
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 5925bd495de..57f08f9b70c 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -743,7 +743,7 @@ void Process::stub172() {
}
void Process::stub173() {
- debug("stub173: delAnimations?");
+ debug("stub173: remove currentCursor");
}
void Process::stub174() {
@@ -1402,13 +1402,13 @@ void Process::stub233() {
}
void Process::stub235() {
- int arg3 = pop();
- int arg2 = pop();
- int arg1 = pop();
- debug("stub235 (fadeScreen?) %d %d %d", arg1, arg2, arg3);
- enableUser();
- if (_status == kStatusPassive)
- suspend();
+ int fadeMusic = pop();
+ int fadeSound = pop();
+ int fadeScreen = pop();
+ debug("stub235 (fadeScreen) screen: %d, sound: %d music: %d", fadeScreen, fadeSound, fadeMusic);
+ _engine->getSystemVariable("screen_curtain")->setInteger(fadeScreen);
+ _engine->getSystemVariable("sound_curtain")->setInteger(fadeSound);
+ _engine->getSystemVariable("music_curtain")->setInteger(fadeMusic);
}
void Process::setCharacterNotifyVars() {
Commit: 1e391b094b81fa7d37d653ab8b539d96841610f9
https://github.com/scummvm/scummvm/commit/1e391b094b81fa7d37d653ab8b539d96841610f9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:24+01:00
Commit Message:
AGDS: run the latest process if idle
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 8b6eea76123..d7e5e0f0fd0 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -226,10 +226,12 @@ void AGDSEngine::resetCurrentScreen() {
void AGDSEngine::runProcesses() {
+ bool idle = true;
for (ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
Process &process = *i;
if (process.active()) {
process.run();
+ idle = false;
++i;
} else if (process.finished()) {
debug("deleting process %s", process.getName().c_str());
@@ -240,6 +242,11 @@ void AGDSEngine::runProcesses() {
++i;
}
}
+ if (idle && !_processes.empty()) {
+ auto & last = _processes.front();
+ last.activate();
+ last.run();
+ }
}
Console *AGDSEngine::getConsole() {
Commit: 56261ca41ee298afe5c871683a1afe7e837158ca
https://github.com/scummvm/scummvm/commit/56261ca41ee298afe5c871683a1afe7e837158ca
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:24+01:00
Commit Message:
AGDS: do not run processes instantly (fixme: original engine does it)
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index d7e5e0f0fd0..1c2287b731c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -904,8 +904,8 @@ void AGDSEngine::reactivate(const Common::String &name, bool runNow) {
if (process.getName() == name) {
debug("reactivate %s %s", name.c_str(), runNow? "(now)": "");
process.activate();
- if (runNow)
- process.run();
+ // if (runNow)
+ // process.run();
}
}
}
Commit: 43d6863b704bc91e21d6de3b481c63f83f02081f
https://github.com/scummvm/scummvm/commit/43d6863b704bc91e21d6de3b481c63f83f02081f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:24+01:00
Commit Message:
AGDS: cleaning up process reactivation
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/animation.cpp
engines/agds/console.cpp
engines/agds/dialog.cpp
engines/agds/soundManager.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 1c2287b731c..f050ebe865d 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -454,7 +454,7 @@ Common::Error AGDSEngine::run() {
if (_mjpgPlayer->eos()) {
delete _mjpgPlayer;
_mjpgPlayer = NULL;
- reactivate(_filmProcess, false);
+ reactivate(_filmProcess);
}
} else if (_currentScreen) {
_currentScreen->paint(*this, *backbuffer);
@@ -515,7 +515,7 @@ void AGDSEngine::skipFilm() {
_syncSoundId = -1;
}
_textLayout.reset(*this);
- reactivate(_filmProcess, false);
+ reactivate(_filmProcess);
}
int AGDSEngine::appendToSharedStorage(const Common::String &value) {
@@ -895,17 +895,15 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
return Common::kNoError;
}
-void AGDSEngine::reactivate(const Common::String &name, bool runNow) {
+void AGDSEngine::reactivate(const Common::String &name) {
if (name.empty())
return;
for(ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ++i) {
Process &process = *i;
if (process.getName() == name) {
- debug("reactivate %s %s", name.c_str(), runNow? "(now)": "");
+ debug("reactivate %s %s", name.c_str());
process.activate();
- // if (runNow)
- // process.run();
}
}
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index f05a18094e2..1da9e0912d7 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -230,7 +230,7 @@ public:
return _mouse;
}
- void reactivate(const Common::String &name, bool runNow);
+ void reactivate(const Common::String &name);
private:
void loadPatches(Common::SeekableReadStream *file, Database & db);
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index acefde387ef..2ee4f1a2277 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -53,14 +53,16 @@ bool Animation::load(Common::SeekableReadStream *stream) {
}
void Animation::updatePhaseVar(AGDSEngine &engine) {
- if (!_process.empty() || !_phaseVar.empty()) //ignore mouse cursors
- debug("animation %s %s %d, phase var: %s", _process.c_str(), _paused? "paused": "playing", _phase, _phaseVar.c_str());
-
if (!_phaseVar.empty()) {
- if (!_paused)
- engine.setGlobal(_phaseVar, _phase);
+ if (!_paused) {
+ int phase = engine.getGlobal(_phaseVar);
+ if (phase != _phase) {
+ debug("%s: animation (%s) %d setting phase var: %s", _process.c_str(), _paused? "paused": "playing", _phase, _phaseVar.c_str());
+ engine.setGlobal(_phaseVar, _phase);
+ engine.reactivate(_process);
+ }
+ }
}
- engine.reactivate(_process, true);
}
void Animation::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point dst) {
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index af4e607e5d1..d4de21ce4c2 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -54,7 +54,7 @@ bool Console::activate(int argc, const char **argv) {
debugPrintf("usage: %s object_id\n", argv[0]);
return true;
}
- _engine->reactivate(argv[1], false);
+ _engine->reactivate(argv[1]);
detach();
return false;
}
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 73057a734b2..f1b516aa7fe 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -58,8 +58,10 @@ bool Dialog::tick() {
return false;
int dialog_var = _engine->getSystemVariable("dialog_var")->getInteger();
- if (dialog_var != 0)
+ if (dialog_var != 0) {
+ debug("dialog_var = %d, skipping tick", dialog_var);
return false;
+ }
uint n = _dialogScript.size();
if (_dialogScriptPos >= n)
@@ -74,6 +76,7 @@ bool Dialog::tick() {
if (line.empty())
return true;
+ debug("dialog line: %s", line.c_str());
if (line[0] == '@') {
if (line[1] == '@') //comment
return true;
@@ -88,6 +91,7 @@ bool Dialog::tick() {
int value = it->_value;
debug("dialog value %d (0x%04x)", value, value);
_engine->getSystemVariable("dialog_var")->setInteger(value);
+ _engine->reactivate(_dialogProcessName);
} else
warning("invalid dialog directive: %s", line.c_str());
}
@@ -100,6 +104,7 @@ bool Dialog::tick() {
debug("end of dialog, running %s", process.c_str());
_engine->getSystemVariable("dialog_var")->setInteger(-2);
+ _engine->reactivate(_dialogProcessName);
return false;
}
return true;
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 2bdef90ef8f..4f789824450 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -35,7 +35,7 @@ namespace AGDS {
void SoundManager::setPhaseVar(const Sound &sound, int value) {
if (!sound.phaseVar.empty())
_engine->setGlobal(sound.phaseVar, value);
- _engine->reactivate(sound.process, true);
+ _engine->reactivate(sound.process);
}
void SoundManager::tick() {
@@ -46,10 +46,8 @@ void SoundManager::tick() {
if (!sound.phaseVar.empty()) {
int value = _engine->getGlobal(sound.phaseVar);
if (value <= 1) {
- if (value == 1 && !active) {
+ if (value == 1 && !active)
setPhaseVar(sound, 0);
- } else if (value == 0 && active)
- setPhaseVar(sound, 1);
} else if (value & 2) {
debug("sample %s restarts (via phase var)", sound.name.c_str());
setPhaseVar(sound, 1);
@@ -108,7 +106,7 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
delete file;
if (!phaseVar.empty())
_engine->setGlobal(phaseVar, 0);
- _engine->reactivate(process, true);
+ _engine->reactivate(process);
return -1;
}
Audio::SoundHandle handle;
Commit: c765a94eafab03d7d99bb89170132ccdd29a5f56
https://github.com/scummvm/scummvm/commit/c765a94eafab03d7d99bb89170132ccdd29a5f56
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:24+01:00
Commit Message:
AGDS: log name for enter/leave processes
Changed paths:
engines/agds/agds.cpp
engines/agds/mouseMap.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index f050ebe865d..606e7963212 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -902,7 +902,7 @@ void AGDSEngine::reactivate(const Common::String &name) {
for(ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ++i) {
Process &process = *i;
if (process.getName() == name) {
- debug("reactivate %s %s", name.c_str());
+ debug("reactivate %s", name.c_str());
process.activate();
}
}
diff --git a/engines/agds/mouseMap.cpp b/engines/agds/mouseMap.cpp
index 2e55dd258fc..c78c861a8f2 100644
--- a/engines/agds/mouseMap.cpp
+++ b/engines/agds/mouseMap.cpp
@@ -48,7 +48,7 @@ void MouseRegion::show(AGDSEngine *engine) {
return;
visible = true;
- debug("calling mouseArea[%d].onEnter...", id);
+ debug("calling mouseArea[%d].onEnter: %s", id, onEnter.c_str());
engine->runObject(onEnter);
}
@@ -57,7 +57,7 @@ void MouseRegion::hide(AGDSEngine *engine) {
return;
visible = false;
- debug("calling mouseArea[%d].onLeave...", id);
+ debug("calling mouseArea[%d].onLeave: %s...", id, onLeave.c_str());
engine->runObject(onLeave);
}
Commit: 8fa9c76a08417d3531107d47adab6a54a013daee
https://github.com/scummvm/scummvm/commit/8fa9c76a08417d3531107d47adab6a54a013daee
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:24+01:00
Commit Message:
AGDS: implement object recovering logic
Changed paths:
engines/agds/agds.cpp
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 606e7963212..0ab9a3c793a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -158,11 +158,17 @@ ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::Strin
void AGDSEngine::runObject(const ObjectPtr &object) {
if (_currentScreen)
- _currentScreen->add(object);
+ if (_currentScreen->add(object)) {
+ runProcess(object);
+ } else {
+ debug("marking object %s as recovering...", object->getName().c_str());
+ object->recovering(true);
+ runProcess(object);
+ object->recovering(false);
+ debug("unmarking object %s as recovering...", object->getName().c_str());
+ }
else
warning("object %s has been loaded, but was not added to any screen", object->getName().c_str());
-
- runProcess(object);
}
void AGDSEngine::runProcess(const ObjectPtr &object, uint ip) {
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 8503b07cee7..fe864be9333 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -39,7 +39,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_pos(), _z(10),
_clickHandler(0), _examineHandler(0),
_userUseHandler(0),
- _alpha(255), _inScene(false) {
+ _alpha(255), _inScene(false), _recovering(false) {
uint16 id = stream->readUint16LE();
debug("id: 0x%02x %u", id, id);
diff --git a/engines/agds/object.h b/engines/agds/object.h
index e273398cf2a..16aa79fef8a 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -76,6 +76,7 @@ private:
uint _userUseHandler;
int _alpha;
bool _inScene;
+ bool _recovering;
public:
Object(const Common::String &name, Common::SeekableReadStream * stream);
@@ -200,6 +201,12 @@ public:
void inScene(bool value)
{ _inScene = value; }
+
+ bool recovering() const
+ { return _recovering; }
+
+ void recovering(bool value)
+ { _recovering = value; }
};
typedef Common::SharedPtr<Object> ObjectPtr;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 57f08f9b70c..7a3dfc67f2f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -519,10 +519,10 @@ void Process::changeScreenPatch() {
push(0);
return;
} else {
- //change screen patch (load and return 1)
ObjectPtr object = screen->find(objectName);
- debug("changeScreenPatch: recover/inventory stub, returning 0");
- push(0);
+ int value = object && object->recovering();
+ debug("changeScreenPatch: current screen object recovering: %d", value);
+ push(value);
}
}
Commit: eddc35d982a1907150529444c240aad6e95bf6f8
https://github.com/scummvm/scummvm/commit/eddc35d982a1907150529444c240aad6e95bf6f8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:24+01:00
Commit Message:
AGDS: suspend and close inventory does not modify process status, fixing this
Changed paths:
engines/agds/agds.cpp
engines/agds/process.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 0ab9a3c793a..25ee0c66481 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -232,12 +232,10 @@ void AGDSEngine::resetCurrentScreen() {
void AGDSEngine::runProcesses() {
- bool idle = true;
for (ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
Process &process = *i;
if (process.active()) {
process.run();
- idle = false;
++i;
} else if (process.finished()) {
debug("deleting process %s", process.getName().c_str());
@@ -248,11 +246,6 @@ void AGDSEngine::runProcesses() {
++i;
}
}
- if (idle && !_processes.empty()) {
- auto & last = _processes.front();
- last.activate();
- last.run();
- }
}
Console *AGDSEngine::getConsole() {
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 88f815e1a5d..0af789d4eb5 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -160,9 +160,11 @@ void Process::run() {
case kExitCodeSetNextScreen:
debug("process %s launches screen: %s", getName().c_str(), getExitArg1().c_str());
_engine->setNextScreenName(getExitArg1(), false);
+ done();
break;
case kExitCodeSetNextScreenSaveInHistory:
_engine->setNextScreenName(getExitArg1(), true);
+ done();
break;
case kExitCodeLoadPreviousScreenObject:
_engine->returnToPreviousScreen();
@@ -178,10 +180,12 @@ void Process::run() {
case kExitCodeCloseInventory:
_engine->inventory().enable(false);
updateWithCurrentMousePosition();
- break;
+ activate();
+ return; //some codes are special, they needed to exit loop and keep process active
case kExitCodeSuspend:
updateWithCurrentMousePosition();
- break;
+ activate();
+ return; //some codes are special, they needed to exit loop and keep process active
case kExitCodeCreatePatchLoadResources:
{
debug("exitProcessCreatePatch");
Commit: 4190bf7d4e26b93ca3328fabb9307a160ef3e657
https://github.com/scummvm/scummvm/commit/4190bf7d4e26b93ca3328fabb9307a160ef3e657
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:25+01:00
Commit Message:
AGDS: log if animation stopped via script
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 7a3dfc67f2f..463dbadee59 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -832,6 +832,7 @@ void Process::syncAnimationWithPhaseVar() {
Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
if (animation) {
if (_engine->getGlobal(phaseVar) == -1) {
+ debug("stopping animation...");
animation->stop();
}
_engine->setGlobal(phaseVar, animation->phase());
Commit: 33bb105e242bd59877d00cadf60296d55db0ee1f
https://github.com/scummvm/scummvm/commit/33bb105e242bd59877d00cadf60296d55db0ee1f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:25+01:00
Commit Message:
AGDS: list animations in console info commands
Changed paths:
engines/agds/animation.h
engines/agds/console.cpp
engines/agds/screen.h
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 0bb2124e684..8e8a77901d8 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -52,6 +52,10 @@ public:
Animation();
~Animation();
+ const Common::Point & position() const {
+ return _position;
+ }
+
void position(Common::Point position) {
_position = position;
}
@@ -64,6 +68,10 @@ public:
_phaseVar = phaseVar;
}
+ const Common::String & process() const {
+ return _process;
+ }
+
void process(const Common::String & process) {
_process = process;
}
@@ -89,6 +97,10 @@ public:
_paused = false;
}
+ bool paused() const {
+ return _paused;
+ }
+
void pause() {
_paused = true;
}
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index d4de21ce4c2..dd3dd6bff49 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -22,6 +22,7 @@
#include "agds/console.h"
#include "agds/agds.h"
+#include "agds/animation.h"
#include "agds/object.h"
#include "agds/process.h"
#include "agds/screen.h"
@@ -63,11 +64,16 @@ bool Console::info(int argc, const char **argv) {
auto screen = _engine->getCurrentScreen();
if (screen) {
debugPrintf("screen %s:\n", screen->getName().c_str());
- auto & children = screen->children();
- for(auto & object : children) {
+ for(auto & object : screen->children()) {
auto pos = object->getPosition();
debugPrintf("object %s [inscene: %d] at %d,%d\n", object->getName().c_str(), object->inScene(), pos.x, pos.y);
}
+ for(auto & animation : screen->animations()) {
+ auto pos = animation->position();
+ debugPrintf("animation %s (process: %s, %s) at %d,%d,%d, frame: %d\n",
+ animation->phaseVar().c_str(), animation->process().c_str(), animation->paused()? "paused": "running",
+ pos.x, pos.y, animation->z(), animation->phase());
+ }
}
debugPrintf("processes:\n");
auto & processes = _engine->processes();
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 29eb8c48537..4d2410914eb 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -94,6 +94,10 @@ public:
return _children;
}
+ const AnimationsType & animations() const {
+ return _animations;
+ }
+
bool add(ObjectPtr object);
void add(Animation * animation) {
_animations.insert(animation);
Commit: 080c3faf015ff630db1e4ca8086140ea269a2974
https://github.com/scummvm/scummvm/commit/080c3faf015ff630db1e4ca8086140ea269a2974
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:25+01:00
Commit Message:
AGDS: implement more animation logic
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 2ee4f1a2277..31a4f16b1b8 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -30,13 +30,23 @@
namespace AGDS {
-Animation::Animation() : _flic(), _frames(0), _loop(false), _cycles(1), _phase(0), _paused(true), _speed(100), _z(0) {
+Animation::Animation() : _flic(), _frame(), _frames(0), _loop(false), _cycles(1), _phase(0), _paused(true), _speed(100), _z(0) {
}
Animation::~Animation() {
+ freeFrame();
delete _flic;
}
+void Animation::freeFrame() {
+ if (_frame) {
+ _frame->free();
+ delete _frame;
+ _frame = nullptr;
+ }
+}
+
+
bool Animation::load(Common::SeekableReadStream *stream) {
delete _flic;
Video::FlicDecoder *flic = new Video::FlicDecoder;
@@ -54,51 +64,59 @@ bool Animation::load(Common::SeekableReadStream *stream) {
void Animation::updatePhaseVar(AGDSEngine &engine) {
if (!_phaseVar.empty()) {
+ int phase = engine.getGlobal(_phaseVar);
if (!_paused) {
- int phase = engine.getGlobal(_phaseVar);
if (phase != _phase) {
debug("%s: animation (%s) %d setting phase var: %s", _process.c_str(), _paused? "paused": "playing", _phase, _phaseVar.c_str());
- engine.setGlobal(_phaseVar, _phase);
+ if (!_loop && _phase + 1 == _frames)
+ engine.setGlobal(_phaseVar, -1);
+ else
+ engine.setGlobal(_phaseVar, _phase);
engine.reactivate(_process);
}
+ } else if (phase != 0) {
+ debug("%s: animation (%s) %d setting phase var: %s", _process.c_str(), _paused? "paused": "playing", _phase, _phaseVar.c_str());
+ engine.setGlobal(_phaseVar, 0);
}
}
}
-void Animation::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point dst) {
- if (_paused || _phase == -1) {
- updatePhaseVar(engine);
- return;
- }
- if (!_phaseVar.empty() && engine.getGlobal(_phaseVar) == -2) {
- _phase = -1;
- updatePhaseVar(engine);
+void Animation::decodeNextFrame(AGDSEngine &engine) {
+ if (_paused)
return;
- }
- const Graphics::Surface *frame = _flic->decodeNextFrame();
+ auto frame = _flic->decodeNextFrame();
if (!frame) {
if (!_loop && _phase >= _cycles * _frames) {
- _phase = -1; //end of animation
updatePhaseVar(engine);
return;
}
- _flic->rewind();
+ rewind();
frame = _flic->decodeNextFrame();
if (!frame)
error("failed decoding frame after rewind");
}
-
++_phase;
+ freeFrame();
+ _frame = engine.convertToTransparent(frame->convertTo(engine.pixelFormat(), _flic->getPalette()));
updatePhaseVar(engine);
+}
+
+void Animation::rewind() {
+ freeFrame();
+ _phase = 0;
+ _flic->rewind();
+}
- Graphics::TransparentSurface *c = engine.convertToTransparent(frame->convertTo(engine.pixelFormat(), _flic->getPalette()));
+
+void Animation::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point dst) {
+ decodeNextFrame(engine);
dst += _position;
- Common::Rect srcRect = c->getRect();
- if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
- c->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
- c->free();
- delete c;
+ if (_frame) {
+ Common::Rect srcRect = _frame->getRect();
+ if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
+ _frame->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
+ }
}
int Animation::width() const {
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 8e8a77901d8..0cf82a68600 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -27,7 +27,7 @@
#include "common/rect.h"
namespace Common { class SeekableReadStream; }
-namespace Graphics { struct Surface; }
+namespace Graphics { struct Surface; struct TransparentSurface; }
namespace Video { class FlicDecoder; }
namespace AGDS {
@@ -37,6 +37,7 @@ class Object;
class Animation {
Video::FlicDecoder *_flic;
+ Graphics::TransparentSurface *_frame;
int _frames;
Common::Point _position;
Common::String _process;
@@ -52,6 +53,9 @@ public:
Animation();
~Animation();
+ void freeFrame();
+ void decodeNextFrame(AGDSEngine &engine);
+
const Common::Point & position() const {
return _position;
}
@@ -105,10 +109,7 @@ public:
_paused = true;
}
- void stop() {
- _phase = -1;
- _paused = true;
- }
+ void rewind();
void speed(int speed) {
_speed = speed;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 9b9d9dddc25..86e126c29d8 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -238,7 +238,7 @@ enum Opcode {
kSetRainDensity = 218,
kLeaveCharacterEx = 219,
kStopCharacter = 220,
- kSyncAnimationWithPhaseVar = 221,
+ kRestartAnimation = 221,
kStub222 = 222,
kStub223 = 223,
kSetNPCTellNotifyVar = 224,
@@ -428,7 +428,7 @@ enum Opcode {
OP(kStub217, stub217) \
OP(kStopCharacter, stopCharacter) \
OP(kLeaveCharacterEx, leaveCharacterEx) \
- OP(kSyncAnimationWithPhaseVar, syncAnimationWithPhaseVar) \
+ OP(kRestartAnimation, restartAnimation) \
OP(kStub223, stub223) \
OP(kSetNPCTellNotifyVar, setNPCTellNotifyVar) \
OP(kModifyAnimationWithPhaseVar, modifyAnimationWithPhaseVar) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 463dbadee59..39f734e607e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -162,10 +162,12 @@ void Process::loadAnimation() {
animation->phaseVar(_phaseVar);
animation->loop(_animationLoop);
animation->cycles(_animationCycles);
- if (_animationPaused)
+ if (_phaseVar.empty()) {
+ suspend();
+ } else if (_animationPaused) {
animation->pause();
- else
- animation->play();
+ _engine->setGlobal(_phaseVar, 0);
+ }
_engine->getCurrentScreen()->add(animation);
}
}
@@ -822,20 +824,17 @@ void Process::stub217() {
debug("stub217: animation? id: %d, frame: %d, soundGroup: %d", id, frame, soundGroup);
}
-void Process::syncAnimationWithPhaseVar() {
+void Process::restartAnimation() {
Common::String phaseVar = popString();
- debug("syncAnimationWithPhaseVar %s", phaseVar.c_str());
+ debug("restartAnimation %s", phaseVar.c_str());
if (phaseVar.empty()) {
warning("no phaseVar");
return;
}
Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
if (animation) {
- if (_engine->getGlobal(phaseVar) == -1) {
- debug("stopping animation...");
- animation->stop();
- }
- _engine->setGlobal(phaseVar, animation->phase());
+ animation->rewind();
+ animation->updatePhaseVar(*_engine);
} else {
warning("no animation with phase var %s found", phaseVar.c_str());
_engine->setGlobal(phaseVar, -1);
@@ -853,13 +852,15 @@ void Process::modifyAnimationWithPhaseVar() {
Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
debug("modifyAnimationWithPhaseVar: phaseVar %s, arg %d", phaseVar.c_str(), arg);
if (animation) {
+ animation->resume();
if (arg > 0) {
//1, 2 stop (2 with rewind?)
- animation->stop();
- _engine->setGlobal(phaseVar, 0);
+ animation->freeFrame();
+ if (arg == 2) {
+ animation->rewind();
+ _engine->setGlobal(phaseVar, 0);
+ }
}
- else
- animation->resume();
}
}
Commit: a461816525a52b25ee51fc10e7b4387274c5190e
https://github.com/scummvm/scummvm/commit/a461816525a52b25ee51fc10e7b4387274c5190e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:25+01:00
Commit Message:
AGDS: implemented user/sysuser disable/enable
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 25ee0c66481..29efc7d1f04 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -49,7 +49,9 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_gameDescription(gameDesc), _pictureCacheId(1), _sharedStorageIndex(-2),
_mjpgPlayer(), _currentScreen(),
_defaultMouseCursor(),
- _mouse(400, 300), _userEnabled(false), _currentRegion(),
+ _mouse(400, 300),
+ _userEnabled(true), _systemUserEnabled(true),
+ _currentRegion(),
_random("agds"),
_inventoryRegion(),
_soundManager(this, system->getMixer()),
@@ -373,7 +375,7 @@ Common::Error AGDSEngine::run() {
if (event.kbd.ascii)
key = Common::String(static_cast<char>(event.kbd.ascii));
};
- if (_userEnabled && !key.empty()) {
+ if (userEnabled() && !key.empty()) {
Screen::KeyHandler handler = _currentScreen->findKeyHandler(key);
if (handler.object) {
debug("found handler for key %s: %s %08x", key.c_str(), handler.object->getName().c_str(), handler.ip + 7);
@@ -383,7 +385,7 @@ Common::Error AGDSEngine::run() {
} break;
case Common::EVENT_MOUSEMOVE:
_mouse = event.mouse;
- if (_userEnabled) {
+ if (userEnabled()) {
MouseRegion *region = _mouseMap.find(_mouse);
if (region != _currentRegion) {
if (_currentRegion) {
@@ -403,7 +405,7 @@ Common::Error AGDSEngine::run() {
case Common::EVENT_LBUTTONDOWN:
case Common::EVENT_RBUTTONDOWN:
_mouse = event.mouse;
- if (_userEnabled) {
+ if (userEnabled()) {
bool lclick = event.type == Common::EVENT_LBUTTONDOWN;
debug("%s %d, %d", lclick ? "lclick" : "rclick", _mouse.x, _mouse.y);
ObjectPtr object = _currentScreen->find(_mouse);
@@ -423,7 +425,7 @@ Common::Error AGDSEngine::run() {
Animation *mouseCursor = NULL;
- if (_userEnabled && _currentScreen) {
+ if (userEnabled() && _currentScreen) {
ObjectPtr object = _currentScreen->find(_mouse);
Animation *cursor = object ? object->getMouseCursor() : NULL;
if (cursor)
@@ -462,7 +464,7 @@ Common::Error AGDSEngine::run() {
if (!mouseCursor)
mouseCursor = _defaultMouseCursor;
- if (_userEnabled && mouseCursor) {
+ if (userEnabled() && mouseCursor) {
mouseCursor->paint(*this, *backbuffer, _mouse);
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 1da9e0912d7..c27df2b567a 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -184,8 +184,11 @@ public:
void enableUser(bool enabled) {
_userEnabled = enabled;
}
+ void enableSystemUser(bool enabled) {
+ _systemUserEnabled = enabled;
+ }
bool userEnabled() const {
- return _userEnabled;
+ return _userEnabled && _systemUserEnabled;
}
void newGame();
@@ -274,6 +277,7 @@ private:
Common::Point _mouse;
MouseRegion * _currentRegion;
bool _userEnabled;
+ bool _systemUserEnabled;
MouseMap _mouseMap;
Common::RandomSource _random;
Inventory _inventory;
Commit: 088f6748f5a2f31c1dabadee5b1ff622c86d808e
https://github.com/scummvm/scummvm/commit/088f6748f5a2f31c1dabadee5b1ff622c86d808e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:25+01:00
Commit Message:
AGDS: signal dialog text with dialog_var == -3
Changed paths:
engines/agds/dialog.cpp
engines/agds/dialog.h
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index f1b516aa7fe..a72c7b8859a 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -57,9 +57,10 @@ bool Dialog::tick() {
if (_dialogProcessName.empty())
return false;
- int dialog_var = _engine->getSystemVariable("dialog_var")->getInteger();
- if (dialog_var != 0) {
- debug("dialog_var = %d, skipping tick", dialog_var);
+ auto dialog_var = _engine->getSystemVariable("dialog_var");
+ int dialog_var_value = dialog_var->getInteger();
+ if (dialog_var_value != 0) {
+ debug("dialog_var = %d, skipping tick", dialog_var_value);
return false;
}
@@ -67,7 +68,8 @@ bool Dialog::tick() {
if (_dialogScriptPos >= n)
return false;
- Common::String line;
+ Common::String &line = _dialogLine;
+ line.clear();
while (_dialogScriptPos < n && _dialogScript[_dialogScriptPos] != '\n' && _dialogScript[_dialogScriptPos] != '\r') {
line += _dialogScript[_dialogScriptPos++];
}
@@ -97,6 +99,7 @@ bool Dialog::tick() {
}
} else if (line[0] == ' ') {
debug("text: %s", line.c_str() + 1);
+ dialog_var->setInteger(-3);
}
if (_dialogScriptPos >= n && !_dialogProcessName.empty()) {
Common::String process = _dialogProcessName;
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
index 59586fabe29..24f6e322cd7 100644
--- a/engines/agds/dialog.h
+++ b/engines/agds/dialog.h
@@ -40,6 +40,7 @@ private:
Common::String _dialogScript;
uint32 _dialogScriptPos;
Common::String _dialogProcessName;
+ Common::String _dialogLine;
void parseDialogDefs(const Common::String &defs);
Commit: 0071129f80e53a9842ad75bcd95fdac82e06e52f
https://github.com/scummvm/scummvm/commit/0071129f80e53a9842ad75bcd95fdac82e06e52f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:25+01:00
Commit Message:
AGDS: allow empty text resource
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 29efc7d1f04..2fdf4ae19f3 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -143,6 +143,8 @@ RegionPtr AGDSEngine::loadRegion(const Common::String &name) {
}
Common::String AGDSEngine::loadText(const Common::String &entryName) {
+ if (entryName.empty())
+ return Common::String();
return ResourceManager::loadText(_data.getEntry(entryName));
}
Commit: c662822a686c7f0472b545c77cd599a4eaade698
https://github.com/scummvm/scummvm/commit/c662822a686c7f0472b545c77cd599a4eaade698
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:25+01:00
Commit Message:
AGDS: allow ncpSayNoSound and signal npc var
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
engines/agds/textLayout.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 86e126c29d8..278cfa67bff 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -140,7 +140,7 @@ enum Opcode {
kStub120 = 120,
kStub121 = 121,
kPlayerSay = 122,
- kStub123 = 123,
+ kNPCSayNoSound = 123,
kNPCSay = 124,
kStub125 = 125,
kStub126 = 126,
@@ -358,6 +358,7 @@ enum Opcode {
OP(kSetAnimationPaused, setAnimationPaused) \
OP(kPlayerSay, playerSay) \
OP(kNPCSay, npcSay) \
+ OP(kNPCSayNoSound, npcSayNoSound) \
OP(kSetTimer, setTimer) \
OP(kProcessResetState, resetState) \
OP(kSetAnimationZ, setAnimationZ) \
diff --git a/engines/agds/process.h b/engines/agds/process.h
index d254d7aa901..2b6b7015a67 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -118,7 +118,8 @@ private:
AGDS_PROCESS_METHOD_U, AGDS_PROCESS_METHOD_UD, AGDS_PROCESS_METHOD_UU)
void moveCharacter(bool usermove);
- void tell(bool npc);
+ void tell(bool npc, const Common::String &sound);
+ void tell(bool npc) { tell(npc, Common::String()); }
Common::String getCloneVarName(const Common::String & arg1, const Common::String & arg2);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 39f734e607e..a1a8922aa0e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -973,8 +973,7 @@ void Process::setDialogForNextFilm() {
debug("setDialogForNextFilm %d", value);
}
-void Process::tell(bool npc) {
- Common::String sound = popText();
+void Process::tell(bool npc, const Common::String &sound) {
Common::String text = popText();
Common::String region = popString();
debug("%s '%s' '%s' '%s'", npc? "npcSay": "playerSay", region.c_str(), text.c_str(), sound.c_str());
@@ -986,11 +985,15 @@ void Process::tell(bool npc) {
}
void Process::npcSay() {
+ tell(true, popText());
+}
+
+void Process::npcSayNoSound() {
tell(true);
}
void Process::playerSay() {
- tell(false);
+ tell(false, popText());
}
void Process::loadDialog() {
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 7a7f66f3a70..1bfe8ce2bd4 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -29,11 +29,6 @@ void TextLayout::reset(AGDSEngine &engine) {
}
void TextLayout::layout(AGDSEngine &engine, const Common::String &text, Common::Point pos, int fontId, bool npc) {
- if (text.empty()) {
- _valid = false;
- return;
- }
-
_fontId = fontId;
_npc = npc;
Font *font = engine.getFont(fontId);
@@ -41,41 +36,43 @@ void TextLayout::layout(AGDSEngine &engine, const Common::String &text, Common::
_lines.clear();
int w = 0;
- Common::Point basePos;
- size_t begin = 0;
- while(begin < text.size()) {
- while(begin < text.size() && text[begin]== '\r')
- ++begin;
- size_t end = text.find('\n', begin);
- if (end == text.npos)
- end = text.size();
+ if (!text.empty()) {
+ Common::Point basePos;
+ size_t begin = 0;
+ while(begin < text.size()) {
+ while(begin < text.size() && text[begin]== '\r')
+ ++begin;
+ size_t end = text.find('\n', begin);
+ if (end == text.npos)
+ end = text.size();
- Common::String line = text.substr(begin, end - begin);
- debug("parsed line: %s", line.c_str());
- begin = end + 1;
- Common::Point size;
- size.x = font->getStringWidth(line);
- size.y = font->getFontHeight();
- _lines.push_back(Line());
+ Common::String line = text.substr(begin, end - begin);
+ debug("parsed line: %s", line.c_str());
+ begin = end + 1;
+ Common::Point size;
+ size.x = font->getStringWidth(line);
+ size.y = font->getFontHeight();
+ _lines.push_back(Line());
- Line & l = _lines.back();
- l.pos = basePos;
- l.text = line;
- l.size = size;
+ Line & l = _lines.back();
+ l.pos = basePos;
+ l.text = line;
+ l.size = size;
- basePos.y += size.y;
- if (size.x > w)
- w = size.x;
- }
+ basePos.y += size.y;
+ if (size.x > w)
+ w = size.x;
+ }
- int dy = -basePos.y / 2;
- for(uint i = 0; i < _lines.size(); ++i) {
- Line & line = _lines[i];
- line.pos.x += pos.x - line.size.x / 2;
- line.pos.y += pos.y + dy;
- }
+ int dy = -basePos.y / 2;
+ for(uint i = 0; i < _lines.size(); ++i) {
+ Line & line = _lines[i];
+ line.pos.x += pos.x - line.size.x / 2;
+ line.pos.y += pos.y + dy;
+ }
- _valid = true;
+ _valid = true;
+ }
Common::String &var = _npc? _npcNotifyVar: _charNotifyVar;
if (!var.empty()) {
Commit: ffd187b6846ccea0eb4e39c29b7dc6174c3ac09b
https://github.com/scummvm/scummvm/commit/ffd187b6846ccea0eb4e39c29b7dc6174c3ac09b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:25+01:00
Commit Message:
AGDS: implement getTextDelay()
Changed paths:
engines/agds/dialog.cpp
engines/agds/dialog.h
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index a72c7b8859a..25dae965207 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -51,6 +51,28 @@ void Dialog::load(const Common::String &dialogScript, const Common::String &defs
_engine->getSystemVariable("dialog_var")->setInteger(-1);
}
+int Dialog::textDelay(const Common::String &str) {
+ int speed = _engine->getSystemVariable("text_speed")->getInteger();
+ if (speed < 0)
+ speed = 0;
+ else if (speed > 100)
+ speed = 100;
+ speed /= 10;
+
+ int delay = str.size();
+ if (delay < 20)
+ delay = 20;
+
+ //this looks like an error in original code
+ //original first value in this table is 0x0FFFFFEB4 (-332)
+ //0x0FFFFFEB4 * 20 and then 16-to-32 conversion gives 0xffffe610
+ // 0xe610 / 20 = 2944
+ static const int delays[] = {
+ 2944, 631, 398, 251, 158,
+ 100, 63, 40, 25, 16, 10
+ };
+ return delays[speed] * delay / 41 + 1;
+}
bool Dialog::tick() {
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
index 24f6e322cd7..cf2c9cfdce8 100644
--- a/engines/agds/dialog.h
+++ b/engines/agds/dialog.h
@@ -47,6 +47,7 @@ private:
public:
Dialog(AGDSEngine *engine): _engine(engine), _dialogScriptPos(0) { }
void run(const Common::String &dialogProcess);
+ int textDelay(const Common::String &str);
void load(const Common::String &dialogScript, const Common::String & defs);
bool tick();
Commit: 2db918d07195a6dbc884e390e1b034b5c27e8ff9
https://github.com/scummvm/scummvm/commit/2db918d07195a6dbc884e390e1b034b5c27e8ff9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:25+01:00
Commit Message:
AGDS: add support for default text (which is actually used by dialog only)
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/dialog.h
engines/agds/textLayout.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 2fdf4ae19f3..f27c36b66c7 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -57,7 +57,6 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_soundManager(this, system->getMixer()),
_dialog(this),
_tellTextTimer(0),
- _resetTextLayoutIfSyncSoundStops(false),
_syncSoundId(-1),
_fastMode(true) {
}
@@ -473,8 +472,20 @@ Common::Error AGDSEngine::run() {
for (CharactersType::iterator i = _characters.begin(); i != _characters.end(); ++i)
i->_value->paint(*this, *backbuffer);
- if (_resetTextLayoutIfSyncSoundStops && _textLayout.valid() && !_soundManager.playing(_syncSoundId))
- _textLayout.reset(*this);
+ if (_textLayout.valid()) {
+ if (_syncSoundId >= 0) {
+ if (!_soundManager.playing(_syncSoundId)) {
+ _textLayout.reset(*this);
+ _syncSoundId = -1;
+ _tellTextTimer = 0;
+ }
+ } else if (_tellTextTimer > 0) {
+ --_tellTextTimer;
+ } else {
+ _tellTextTimer = 0;
+ _textLayout.reset(*this);
+ }
+ }
if (_textLayout.valid()) {
_textLayout.paint(*this, *backbuffer);
@@ -517,6 +528,7 @@ void AGDSEngine::skipFilm() {
_mixer->stopID(_syncSoundId);
_syncSoundId = -1;
}
+ _tellTextTimer = 0;
_textLayout.reset(*this);
reactivate(_filmProcess);
}
@@ -657,7 +669,7 @@ void AGDSEngine::addSystemVar(const Common::String &name, SystemVariable *var) {
_systemVars[name] = var;
}
-void AGDSEngine::tell(const Common::String ®ionName, const Common::String &text, const Common::String &sound, const Common::String &soundPhaseVar, bool npc) {
+void AGDSEngine::tell(const Common::String ®ionName, const Common::String &text_, const Common::String &sound, const Common::String &soundPhaseVar, bool npc) {
int font_id = getSystemVariable(npc? "npc_tell_font": "tell_font")->getInteger();
Common::Point pos;
@@ -668,10 +680,13 @@ void AGDSEngine::tell(const Common::String ®ionName, const Common::String &te
RegionPtr region = loadRegion(regionName);
pos = region->center;
}
+ auto text = text_.empty()? _dialog.getNextDialogLine(): text_;
+ _tellTextTimer = _dialog.textDelay(text);
_textLayout.layout(*this, text, pos, font_id, npc);
if (!sound.empty()) {
playSoundSync(sound, soundPhaseVar);
- _resetTextLayoutIfSyncSoundStops = true;
+ } else {
+ _syncSoundId = -1;
}
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index c27df2b567a..3d97f443020 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -289,7 +289,6 @@ private:
int _tellTextTimer;
TextLayout _textLayout;
- bool _resetTextLayoutIfSyncSoundStops;
int _syncSoundId;
bool _fastMode;
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
index cf2c9cfdce8..68f8e62bb29 100644
--- a/engines/agds/dialog.h
+++ b/engines/agds/dialog.h
@@ -48,6 +48,9 @@ public:
Dialog(AGDSEngine *engine): _engine(engine), _dialogScriptPos(0) { }
void run(const Common::String &dialogProcess);
int textDelay(const Common::String &str);
+ const Common::String &getNextDialogLine() const {
+ return _dialogLine;
+ }
void load(const Common::String &dialogScript, const Common::String & defs);
bool tick();
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 1bfe8ce2bd4..82af2c76418 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -29,6 +29,11 @@ void TextLayout::reset(AGDSEngine &engine) {
}
void TextLayout::layout(AGDSEngine &engine, const Common::String &text, Common::Point pos, int fontId, bool npc) {
+ if (text.empty()) {
+ _valid = false;
+ return;
+ }
+
_fontId = fontId;
_npc = npc;
Font *font = engine.getFont(fontId);
@@ -36,47 +41,46 @@ void TextLayout::layout(AGDSEngine &engine, const Common::String &text, Common::
_lines.clear();
int w = 0;
- if (!text.empty()) {
- Common::Point basePos;
- size_t begin = 0;
- while(begin < text.size()) {
- while(begin < text.size() && text[begin]== '\r')
- ++begin;
- size_t end = text.find('\n', begin);
- if (end == text.npos)
- end = text.size();
+ Common::Point basePos;
+ size_t begin = 0;
+ while(begin < text.size()) {
+ while(begin < text.size() && text[begin]== '\r')
+ ++begin;
+ size_t end = text.find('\n', begin);
+ if (end == text.npos)
+ end = text.size();
- Common::String line = text.substr(begin, end - begin);
- debug("parsed line: %s", line.c_str());
- begin = end + 1;
- Common::Point size;
- size.x = font->getStringWidth(line);
- size.y = font->getFontHeight();
- _lines.push_back(Line());
+ Common::String line = text.substr(begin, end - begin);
+ debug("parsed line: %s", line.c_str());
+ begin = end + 1;
+ Common::Point size;
+ size.x = font->getStringWidth(line);
+ size.y = font->getFontHeight();
+ _lines.push_back(Line());
- Line & l = _lines.back();
- l.pos = basePos;
- l.text = line;
- l.size = size;
-
- basePos.y += size.y;
- if (size.x > w)
- w = size.x;
- }
+ Line & l = _lines.back();
+ l.pos = basePos;
+ l.text = line;
+ l.size = size;
- int dy = -basePos.y / 2;
- for(uint i = 0; i < _lines.size(); ++i) {
- Line & line = _lines[i];
- line.pos.x += pos.x - line.size.x / 2;
- line.pos.y += pos.y + dy;
- }
+ basePos.y += size.y;
+ if (size.x > w)
+ w = size.x;
+ }
- _valid = true;
+ int dy = -basePos.y / 2;
+ for(uint i = 0; i < _lines.size(); ++i) {
+ Line & line = _lines[i];
+ line.pos.x += pos.x - line.size.x / 2;
+ line.pos.y += pos.y + dy;
}
+ _valid = true;
+
Common::String &var = _npc? _npcNotifyVar: _charNotifyVar;
if (!var.empty()) {
- engine.setGlobal(var, 1);
+ if (!engine.getGlobal(var))
+ engine.setGlobal(var, 1);
}
}
Commit: 7d57964a8ae2290b82e502f5da5a479cc4250de7
https://github.com/scummvm/scummvm/commit/7d57964a8ae2290b82e502f5da5a479cc4250de7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:25+01:00
Commit Message:
AGDS: add delay/random values for animation
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 31a4f16b1b8..309021a634f 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -30,7 +30,7 @@
namespace AGDS {
-Animation::Animation() : _flic(), _frame(), _frames(0), _loop(false), _cycles(1), _phase(0), _paused(true), _speed(100), _z(0) {
+Animation::Animation() : _flic(), _frame(), _frames(0), _loop(false), _cycles(1), _phase(0), _paused(true), _speed(100), _z(0), _delay(-1), _random(0) {
}
Animation::~Animation() {
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 0cf82a68600..0822737211f 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -48,6 +48,8 @@ class Animation {
bool _paused;
int _speed;
int _z;
+ int _delay;
+ int _random;
public:
Animation();
@@ -88,6 +90,14 @@ public:
_cycles = cycles;
}
+ void delay(int delay) {
+ _delay = delay;
+ }
+
+ void setRandom(int value) { //can't declare random() because of stupid macro
+ _random = value;
+ }
+
int phase() const {
return _phase;
}
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 0af789d4eb5..d32b0c1fb2a 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -31,7 +31,7 @@ Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) : _engine(en
_status(kStatusActive), _exitCode(kExitCodeDestroy),
_tileWidth(16), _tileHeight(16), _tileResource(0), _tileIndex(0),
_timer(0),
- _animationCycles(1), _animationLoop(false), _animationZ(0), _animationPaused(false), _animationSpeed(100)
+ _animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0), _animationPaused(false), _animationSpeed(100)
{
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 2b6b7015a67..e93a7502804 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -60,6 +60,8 @@ private:
bool _animationLoop;
Common::Point _animationPosition;
int _animationZ;
+ int _animationDelay;
+ int _animationRandom;
bool _animationPaused;
int _animationSpeed;
Common::Point _mousePosition;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index a1a8922aa0e..9187c45730a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -162,6 +162,8 @@ void Process::loadAnimation() {
animation->phaseVar(_phaseVar);
animation->loop(_animationLoop);
animation->cycles(_animationCycles);
+ animation->delay(_animationDelay);
+ animation->setRandom(_animationRandom);
if (_phaseVar.empty()) {
suspend();
} else if (_animationPaused) {
@@ -567,7 +569,8 @@ void Process::setScreenHeight() {
void Process::setDelay() {
int delay = pop();
- debug("setDelay stub %d", delay);
+ debug("setDelay %d", delay);
+ _animationDelay = delay;
}
void Process::setCycles() {
@@ -578,7 +581,8 @@ void Process::setCycles() {
void Process::setRandom() {
int value = pop();
- debug("setRandom stub %d", value);
+ debug("setRandom %d", value);
+ _animationRandom = value;
}
void Process::stub82() {
@@ -611,6 +615,8 @@ void Process::resetState() {
_animationPosition = Common::Point();
_animationPaused = false;
_animationZ = 0;
+ _animationRandom = 0;
+ _animationDelay = -1;
_tileWidth = 16;
_tileHeight = 16;
@@ -1371,6 +1377,8 @@ void Process::loadAnimationFromObject() {
animation->process(getName());
animation->loop(_animationLoop);
animation->cycles(_animationCycles);
+ animation->delay(_animationDelay);
+ animation->setRandom(_animationRandom);
if (_animationPaused)
animation->pause();
}
Commit: 8fd4f9e439e63e6a5b87e0010a535d195e1668dc
https://github.com/scummvm/scummvm/commit/8fd4f9e439e63e6a5b87e0010a535d195e1668dc
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:26+01:00
Commit Message:
AGDS: finally fixed pause/resume
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 278cfa67bff..46010553468 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -242,7 +242,7 @@ enum Opcode {
kStub222 = 222,
kStub223 = 223,
kSetNPCTellNotifyVar = 224,
- kModifyAnimationWithPhaseVar = 225,
+ kPauseAnimation = 225,
kFadeObject = 226,
kLoadFont = 227,
kMoveCharacterNoUserMove = 228,
@@ -432,7 +432,7 @@ enum Opcode {
OP(kRestartAnimation, restartAnimation) \
OP(kStub223, stub223) \
OP(kSetNPCTellNotifyVar, setNPCTellNotifyVar) \
- OP(kModifyAnimationWithPhaseVar, modifyAnimationWithPhaseVar) \
+ OP(kPauseAnimation, pauseAnimation) \
OP(kFadeObject, fadeObject) \
OP(kLoadFont, loadFont) \
OP_U(kStub201Handler, stub201) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 9187c45730a..87b0610e057 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -839,8 +839,11 @@ void Process::restartAnimation() {
}
Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
if (animation) {
- animation->rewind();
- animation->updatePhaseVar(*_engine);
+ if (_engine->getGlobal(phaseVar) == 1 && !animation->paused()) {
+ animation->rewind();
+ }
+ animation->resume();
+ _engine->setGlobal(phaseVar, animation->phase());
} else {
warning("no animation with phase var %s found", phaseVar.c_str());
_engine->setGlobal(phaseVar, -1);
@@ -852,15 +855,15 @@ void Process::stub223() {
debug("stub223: %d", value);
}
-void Process::modifyAnimationWithPhaseVar() {
+void Process::pauseAnimation() {
int arg = pop();
Common::String phaseVar = popString();
Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
- debug("modifyAnimationWithPhaseVar: phaseVar %s, arg %d", phaseVar.c_str(), arg);
+ debug("pauseAnimation: phaseVar %s, arg %d", phaseVar.c_str(), arg);
if (animation) {
- animation->resume();
+ animation->pause();
if (arg > 0) {
- //1, 2 stop (2 with rewind?)
+ //1, 2 stop (2 with rewind)
animation->freeFrame();
if (arg == 2) {
animation->rewind();
Commit: a3cd0c088b07ccb36b298a678a90724ccabe75b8
https://github.com/scummvm/scummvm/commit/a3cd0c088b07ccb36b298a678a90724ccabe75b8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:26+01:00
Commit Message:
AGDS: animation refactoring
Changed paths:
engines/agds/agds.cpp
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/console.cpp
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index f27c36b66c7..5d626abb69e 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -291,7 +291,6 @@ Animation *AGDSEngine::loadMouseCursor(const Common::String &name) {
Animation *animation = loadAnimation(name);
animation->loop(true);
animation->phaseVar(Common::String());
- animation->play();
return animation;
}
@@ -466,6 +465,7 @@ Common::Error AGDSEngine::run() {
mouseCursor = _defaultMouseCursor;
if (userEnabled() && mouseCursor) {
+ mouseCursor->tick(*this);
mouseCursor->paint(*this, *backbuffer, _mouse);
}
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 309021a634f..748fe6e67fa 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -30,7 +30,7 @@
namespace AGDS {
-Animation::Animation() : _flic(), _frame(), _frames(0), _loop(false), _cycles(1), _phase(0), _paused(true), _speed(100), _z(0), _delay(-1), _random(0) {
+Animation::Animation() : _flic(), _frame(), _frames(0), _loop(false), _cycles(1), _startPaused(false), _frameIndex(0), _paused(false), _speed(100), _z(0), _delay(-1), _random(0) {
}
Animation::~Animation() {
@@ -62,55 +62,56 @@ bool Animation::load(Common::SeekableReadStream *stream) {
}
}
-void Animation::updatePhaseVar(AGDSEngine &engine) {
- if (!_phaseVar.empty()) {
- int phase = engine.getGlobal(_phaseVar);
- if (!_paused) {
- if (phase != _phase) {
- debug("%s: animation (%s) %d setting phase var: %s", _process.c_str(), _paused? "paused": "playing", _phase, _phaseVar.c_str());
- if (!_loop && _phase + 1 == _frames)
- engine.setGlobal(_phaseVar, -1);
- else
- engine.setGlobal(_phaseVar, _phase);
- engine.reactivate(_process);
- }
- } else if (phase != 0) {
- debug("%s: animation (%s) %d setting phase var: %s", _process.c_str(), _paused? "paused": "playing", _phase, _phaseVar.c_str());
- engine.setGlobal(_phaseVar, 0);
- }
- }
-}
-
void Animation::decodeNextFrame(AGDSEngine &engine) {
- if (_paused)
- return;
-
auto frame = _flic->decodeNextFrame();
if (!frame) {
- if (!_loop && _phase >= _cycles * _frames) {
- updatePhaseVar(engine);
- return;
- }
rewind();
frame = _flic->decodeNextFrame();
if (!frame)
error("failed decoding frame after rewind");
}
- ++_phase;
freeFrame();
_frame = engine.convertToTransparent(frame->convertTo(engine.pixelFormat(), _flic->getPalette()));
- updatePhaseVar(engine);
+ ++_frameIndex;
}
void Animation::rewind() {
freeFrame();
- _phase = 0;
+ _frameIndex = 0;
_flic->rewind();
}
+bool Animation::tick(AGDSEngine &engine) {
+ if (_paused)
+ return true;
-void Animation::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point dst) {
+ if (_delay > 0) {
+ --_delay;
+ return true;
+ }
+
+ if (_startPaused && !_phaseVar.empty() && engine.getGlobal(_phaseVar) == -2) {
+ debug("phase var %s signalled deleting of animation", _phaseVar.c_str());
+ return false;
+ }
+ if (_frameIndex >= _frames && !_loop) {
+ if (!_phaseVar.empty()) {
+ engine.setGlobal(_phaseVar, -1);
+ } else {
+ engine.reactivate(_process);
+ }
+ return false;
+ }
decodeNextFrame(engine);
+ if (!_process.empty()) {
+ if (!_phaseVar.empty()) {
+ engine.setGlobal(_phaseVar, _frameIndex - 1);
+ }
+ }
+ return true;
+}
+
+void Animation::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point dst) {
dst += _position;
if (_frame) {
Common::Rect srcRect = _frame->getRect();
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 0822737211f..75aec348903 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -44,7 +44,8 @@ class Animation {
Common::String _phaseVar;
bool _loop;
int _cycles;
- int _phase;
+ bool _startPaused;
+ int _frameIndex;
bool _paused;
int _speed;
int _z;
@@ -56,7 +57,6 @@ public:
~Animation();
void freeFrame();
- void decodeNextFrame(AGDSEngine &engine);
const Common::Point & position() const {
return _position;
@@ -73,6 +73,9 @@ public:
void phaseVar(const Common::String & phaseVar) {
_phaseVar = phaseVar;
}
+ int frameIndex() const {
+ return _frameIndex;
+ }
const Common::String & process() const {
return _process;
@@ -98,17 +101,9 @@ public:
_random = value;
}
- int phase() const {
- return _phase;
- }
-
- void play() {
- _paused = false;
- _phase = 0;
- }
-
- void resume() {
- _paused = false;
+ void startPaused(bool paused) {
+ _startPaused = paused;
+ _paused = paused;
}
bool paused() const {
@@ -119,6 +114,10 @@ public:
_paused = true;
}
+ void resume() {
+ _paused = false;
+ }
+
void rewind();
void speed(int speed) {
@@ -134,10 +133,12 @@ public:
}
bool load(Common::SeekableReadStream *stream);
- void updatePhaseVar(AGDSEngine & engine);
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Common::Point dst);
int width() const;
int height() const;
+ bool tick(AGDSEngine &engine);
+private:
+ void decodeNextFrame(AGDSEngine &engine);
};
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index dd3dd6bff49..0f87a5b2a63 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -72,7 +72,7 @@ bool Console::info(int argc, const char **argv) {
auto pos = animation->position();
debugPrintf("animation %s (process: %s, %s) at %d,%d,%d, frame: %d\n",
animation->phaseVar().c_str(), animation->process().c_str(), animation->paused()? "paused": "running",
- pos.x, pos.y, animation->z(), animation->phase());
+ pos.x, pos.y, animation->z(), animation->frameIndex());
}
}
debugPrintf("processes:\n");
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 87b0610e057..fc8fae2422d 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -164,12 +164,11 @@ void Process::loadAnimation() {
animation->cycles(_animationCycles);
animation->delay(_animationDelay);
animation->setRandom(_animationRandom);
- if (_phaseVar.empty()) {
+ animation->startPaused(_animationPaused);
+ if (_phaseVar.empty())
suspend();
- } else if (_animationPaused) {
- animation->pause();
+ else if (_animationPaused)
_engine->setGlobal(_phaseVar, 0);
- }
_engine->getCurrentScreen()->add(animation);
}
}
@@ -843,7 +842,7 @@ void Process::restartAnimation() {
animation->rewind();
}
animation->resume();
- _engine->setGlobal(phaseVar, animation->phase());
+ _engine->setGlobal(phaseVar, animation->frameIndex());
} else {
warning("no animation with phase var %s found", phaseVar.c_str());
_engine->setGlobal(phaseVar, -1);
@@ -1371,19 +1370,14 @@ void Process::loadPictureFromObject() {
void Process::loadAnimationFromObject() {
Common::String name = popText();
debug("loadAnimationFromObject %s %s", name.c_str(), _animationPaused? "(paused)": "");
- if (!_phaseVar.empty()) {
- _engine->setGlobal(_phaseVar, -2);
- }
Animation *animation = _engine->loadAnimation(name);
if (animation) {
- animation->phaseVar(_phaseVar);
- animation->process(getName());
- animation->loop(_animationLoop);
- animation->cycles(_animationCycles);
- animation->delay(_animationDelay);
- animation->setRandom(_animationRandom);
- if (_animationPaused)
- animation->pause();
+ if (_animationPaused) {
+ animation->phaseVar(_phaseVar);
+ animation->process(getName());
+ animation->startPaused(_animationPaused);
+ _object->setAnimation(animation);
+ }
}
}
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 692df9ebb90..386779c7f0a 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -98,6 +98,16 @@ bool Screen::remove(const Common::String &name) {
}
void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
+ for(uint i = 0; i < _animations.size(); ++i) {
+ Animation *animation = _animations.data()[i];
+ if (animation->tick(engine))
+ ++i;
+ else {
+ debug("removing animation %s:%s", animation->process().c_str(), animation->phaseVar().c_str());
+ _animations.erase(_animations.begin() + i);
+ }
+ }
+
ChildrenType::iterator child = _children.begin();
AnimationsType::iterator animation = _animations.begin();
while(child != _children.end() || animation != _animations.end()) {
Commit: 8f1086dc2e9ca27452200c4edcaebf262b721867
https://github.com/scummvm/scummvm/commit/8f1086dc2e9ca27452200c4edcaebf262b721867
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:26+01:00
Commit Message:
AGDS: implement rolling sample index for dialog sounds
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/dialog.cpp
engines/agds/dialog.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 5d626abb69e..45a8b794711 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -669,7 +669,7 @@ void AGDSEngine::addSystemVar(const Common::String &name, SystemVariable *var) {
_systemVars[name] = var;
}
-void AGDSEngine::tell(const Common::String ®ionName, const Common::String &text_, const Common::String &sound, const Common::String &soundPhaseVar, bool npc) {
+void AGDSEngine::tell(const Common::String ®ionName, Common::String text, Common::String sound, const Common::String &soundPhaseVar, bool npc) {
int font_id = getSystemVariable(npc? "npc_tell_font": "tell_font")->getInteger();
Common::Point pos;
@@ -680,7 +680,12 @@ void AGDSEngine::tell(const Common::String ®ionName, const Common::String &te
RegionPtr region = loadRegion(regionName);
pos = region->center;
}
- auto text = text_.empty()? _dialog.getNextDialogLine(): text_;
+
+ if (text.empty())
+ text = _dialog.getNextDialogLine();
+ if (sound.empty())
+ sound = _dialog.getNextDialogSound();
+
_tellTextTimer = _dialog.textDelay(text);
_textLayout.layout(*this, text, pos, font_id, npc);
if (!sound.empty()) {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 3d97f443020..fe8c27b1c69 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -223,7 +223,7 @@ public:
_syncSoundId = playSound(Common::String(), resource, phaseVar);
}
- void tell(const Common::String ®ion, const Common::String &text, const Common::String &sound, const Common::String &soundPhaseVar, bool npc);
+ void tell(const Common::String ®ion, Common::String text, Common::String sound, const Common::String &soundPhaseVar, bool npc);
bool fastMode() const {
return _fastMode;
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 25dae965207..094622ea921 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -45,6 +45,8 @@ void Dialog::parseDialogDefs(const Common::String &defs) {
}
void Dialog::load(const Common::String &dialogScript, const Common::String &defs) {
+ _currentDef.clear();
+ _sounds.clear();
parseDialogDefs(defs);
_dialogScript = dialogScript;
_dialogScriptPos = 0;
@@ -109,11 +111,40 @@ bool Dialog::tick() {
if (line.hasPrefix("sound")) {
debug("sound: %s", line.c_str());
+ auto arg1 = line.find('(');
+ if (arg1 == line.npos) {
+ warning("invalid sound directive");
+ return true;
+ }
+ ++arg1;
+
+ auto comma1 = line.find(',', arg1);
+ if (comma1 == line.npos) {
+ warning("invalid sound directive, missing arg2");
+ return true;
+ }
+ auto comma2 = line.find(',', comma1 + 1);
+ if (comma2 == line.npos) {
+ warning("invalid sound directive, missing arg3");
+ return true;
+ }
+ auto end = line.find(')', comma2 + 1);
+ if (end == line.npos) {
+ warning("invalid sound directive");
+ return true;
+ }
+ --end;
+ Common::String name = line.substr(arg1, comma1 - arg1 - 1);
+ Common::String sample = line.substr(comma1 + 1, comma2 - comma1 - 1);
+ Common::String step = line.substr(comma2 + 1, end - comma2);
+ debug("sound args = %s,%s,%s", name.c_str(), sample.c_str(), step.c_str());
+ _sounds.push_back(Sound(name, sample, atoi(step.c_str())));
} else {
DialogDefsType::const_iterator it = _dialogDefs.find(line);
if (it != _dialogDefs.end()) {
int value = it->_value;
- debug("dialog value %d (0x%04x)", value, value);
+ debug("dialog value %s = %d (0x%04x)", line.c_str(), value, value);
+ _currentDef = line;
_engine->getSystemVariable("dialog_var")->setInteger(value);
_engine->reactivate(_dialogProcessName);
} else
@@ -135,5 +166,37 @@ bool Dialog::tick() {
return true;
}
+Common::String Dialog::getNextDialogSound() {
+ if (_currentDef.empty())
+ return Common::String();
+
+ uint it;
+ for(it = 0; it < _sounds.size(); ++it) {
+ auto & sound = _sounds[it];
+ if (_currentDef.hasPrefix(sound.Name))
+ break;
+ }
+ if (it == _sounds.size())
+ return Common::String();
+
+ auto &sound = _sounds[it];
+ auto &sample = sound.Sample;
+ auto currentSample = sample;
+
+ int carry = sound.Step;
+ for(auto pos = sample.size() - 1; pos > 0 && sample[pos] >= '0' && sample[pos] <= '9'; --pos) {
+ int d = sample[pos] - '0';
+ d += carry;
+ carry = d / 10;
+ sample.setChar('0' + (d % 10), pos);
+ if (carry == 0)
+ break;
+ }
+ if (carry != 0)
+ warning("sample index overflow, %s", sample.c_str());
+
+ debug("returning sample name %s", sample.c_str());
+ return currentSample + ".ogg";
+}
}
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
index 68f8e62bb29..e08718016e2 100644
--- a/engines/agds/dialog.h
+++ b/engines/agds/dialog.h
@@ -35,6 +35,19 @@ class Dialog {
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> DialogDefsType;
private:
+ struct Sound {
+ Common::String Name;
+ Common::String Sample;
+ int Step;
+
+ Sound(): Step(1) {
+ }
+
+ Sound(const Common::String &name, const Common::String &sample, int step): Name(name), Sample(sample), Step(step) {
+ }
+ };
+ typedef Common::Array<Sound> SoundsType;
+
AGDSEngine * _engine;
DialogDefsType _dialogDefs;
Common::String _dialogScript;
@@ -42,6 +55,9 @@ private:
Common::String _dialogProcessName;
Common::String _dialogLine;
+ SoundsType _sounds;
+ Common::String _currentDef;
+
void parseDialogDefs(const Common::String &defs);
public:
@@ -51,6 +67,7 @@ public:
const Common::String &getNextDialogLine() const {
return _dialogLine;
}
+ Common::String getNextDialogSound();
void load(const Common::String &dialogScript, const Common::String & defs);
bool tick();
Commit: 5aa9dc298673872fce9ba44e2604076938284154
https://github.com/scummvm/scummvm/commit/5aa9dc298673872fce9ba44e2604076938284154
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:26+01:00
Commit Message:
AGDS: revised sound manager phase var/activations
Changed paths:
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 4f789824450..79fafbfd247 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -32,33 +32,29 @@
namespace AGDS {
-void SoundManager::setPhaseVar(const Sound &sound, int value) {
- if (!sound.phaseVar.empty())
- _engine->setGlobal(sound.phaseVar, value);
- _engine->reactivate(sound.process);
-}
-
void SoundManager::tick() {
for (SoundList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) {
Sound &sound = *i;
+ auto &phaseVar = sound.phaseVar;
bool active = _mixer->isSoundHandleActive(sound.handle);
if (!sound.phaseVar.empty()) {
int value = _engine->getGlobal(sound.phaseVar);
if (value <= 1) {
if (value == 1 && !active)
- setPhaseVar(sound, 0);
+ _engine->setGlobal(phaseVar, 0);
} else if (value & 2) {
debug("sample %s restarts (via phase var)", sound.name.c_str());
- setPhaseVar(sound, 1);
+ _engine->setGlobal(phaseVar, 1);
_mixer->stopID(sound.id);
play(sound.process, sound.name, sound.phaseVar, sound.id);
} else if (value & 4) {
debug("sample %s stops (via phase var)", sound.name.c_str());
_mixer->stopID(sound.id);
- setPhaseVar(sound, 0);
+ _engine->setGlobal(phaseVar, 0);
}
- }
+ } else if (!active)
+ _engine->reactivate(sound.process);
}
}
@@ -77,7 +73,8 @@ void SoundManager::stopAll() {
_mixer->stopAll();
for (auto i = _sounds.begin(); i != _sounds.end(); ++i) {
auto &sound = *i;
- setPhaseVar(sound, 0);
+ if (!sound.phaseVar.empty())
+ _engine->setGlobal(sound.phaseVar, 0);
}
_sounds.clear();
}
@@ -106,7 +103,8 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
delete file;
if (!phaseVar.empty())
_engine->setGlobal(phaseVar, 0);
- _engine->reactivate(process);
+ else
+ _engine->reactivate(process);
return -1;
}
Audio::SoundHandle handle;
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index 4a1df988e07..43732620cbc 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -63,8 +63,6 @@ namespace AGDS {
bool playing(int id) const;
void stopAll();
Sound *findSampleByPhaseVar(const Common::String &phaseVar);
- private:
- void setPhaseVar(const Sound &sound, int value);
};
} // End of namespace AGDS
Commit: 993680807abcdcb95cffbb0d6dbafd887616ad7d
https://github.com/scummvm/scummvm/commit/993680807abcdcb95cffbb0d6dbafd887616ad7d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:26+01:00
Commit Message:
AGDS: reactivate process when text layout resets
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
engines/agds/textLayout.cpp
engines/agds/textLayout.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 45a8b794711..54569293750 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -669,7 +669,7 @@ void AGDSEngine::addSystemVar(const Common::String &name, SystemVariable *var) {
_systemVars[name] = var;
}
-void AGDSEngine::tell(const Common::String ®ionName, Common::String text, Common::String sound, const Common::String &soundPhaseVar, bool npc) {
+void AGDSEngine::tell(Process &process, const Common::String ®ionName, Common::String text, Common::String sound, bool npc) {
int font_id = getSystemVariable(npc? "npc_tell_font": "tell_font")->getInteger();
Common::Point pos;
@@ -687,9 +687,9 @@ void AGDSEngine::tell(const Common::String ®ionName, Common::String text, Com
sound = _dialog.getNextDialogSound();
_tellTextTimer = _dialog.textDelay(text);
- _textLayout.layout(*this, text, pos, font_id, npc);
+ _textLayout.layout(*this, process.getName(), text, pos, font_id, npc);
if (!sound.empty()) {
- playSoundSync(sound, soundPhaseVar);
+ playSoundSync(sound, process.phaseVar());
} else {
_syncSoundId = -1;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index fe8c27b1c69..c5e08db9d32 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -223,7 +223,7 @@ public:
_syncSoundId = playSound(Common::String(), resource, phaseVar);
}
- void tell(const Common::String ®ion, Common::String text, Common::String sound, const Common::String &soundPhaseVar, bool npc);
+ void tell(Process &process, const Common::String ®ion, Common::String text, Common::String sound, bool npc);
bool fastMode() const {
return _fastMode;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index fc8fae2422d..ab1c889606a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -985,7 +985,7 @@ void Process::tell(bool npc, const Common::String &sound) {
Common::String text = popText();
Common::String region = popString();
debug("%s '%s' '%s' '%s'", npc? "npcSay": "playerSay", region.c_str(), text.c_str(), sound.c_str());
- _engine->tell(region, text, sound, _phaseVar, npc);
+ _engine->tell(*this, region, text, sound, npc);
//close inventory here if close flag was set
Common::String inventoryClose = _engine->getSystemVariable("inv_close")->getString();
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 82af2c76418..9ab8378cf3b 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -20,20 +20,23 @@ void TextLayout::reset(AGDSEngine &engine) {
bool valid = _valid;
_valid = false;
_lines.clear();
+
if (valid) {
Common::String &var = _npc? _npcNotifyVar: _charNotifyVar;
if (!var.empty()) {
engine.setGlobal(var, 0);
}
+ engine.reactivate(_process);
}
}
-void TextLayout::layout(AGDSEngine &engine, const Common::String &text, Common::Point pos, int fontId, bool npc) {
+void TextLayout::layout(AGDSEngine &engine, const Common::String &process, const Common::String &text, Common::Point pos, int fontId, bool npc) {
if (text.empty()) {
_valid = false;
return;
}
+ _process = process;
_fontId = fontId;
_npc = npc;
Font *font = engine.getFont(fontId);
diff --git a/engines/agds/textLayout.h b/engines/agds/textLayout.h
index 89ac9e91a1d..d9b32e6abd5 100644
--- a/engines/agds/textLayout.h
+++ b/engines/agds/textLayout.h
@@ -50,6 +50,7 @@ class TextLayout {
Common::Array<Line> _lines;
+ Common::String _process;
Common::String _charNotifyVar;
Common::String _charDirectionNotifyVar;
Common::String _npcNotifyVar;
@@ -76,7 +77,7 @@ public:
}
void paint(AGDSEngine &engine, Graphics::Surface &backbuffer);
- void layout(AGDSEngine &engine, const Common::String &text, Common::Point pos, int fontId, bool npc);
+ void layout(AGDSEngine &engine, const Common::String &process, const Common::String &text, Common::Point pos, int fontId, bool npc);
};
} // End of namespace AGDS
Commit: b84fcf5e74b0f1729c43e8bc5cb8c8aafcb71af5
https://github.com/scummvm/scummvm/commit/b84fcf5e74b0f1729c43e8bc5cb8c8aafcb71af5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:26+01:00
Commit Message:
AGDS: move common animation code to Process::setupAnimation()
Changed paths:
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index d32b0c1fb2a..0cd002d9d9b 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -22,6 +22,7 @@
#include "agds/process.h"
#include "agds/agds.h"
+#include "agds/animation.h"
#include "common/debug.h"
#include "common/system.h"
@@ -125,6 +126,25 @@ void Process::updateWithCurrentMousePosition() {
setMousePosition(_engine->mousePosition());
}
+
+void Process::setupAnimation(Animation *animation) {
+ animation->position(_animationPosition);
+ animation->z(_animationZ);
+ animation->process(getName());
+ animation->phaseVar(_phaseVar);
+ animation->loop(_animationLoop);
+ animation->cycles(_animationCycles);
+ animation->delay(_animationDelay);
+ animation->setRandom(_animationRandom);
+ animation->startPaused(_animationPaused);
+ if (_phaseVar.empty())
+ suspend();
+ else if (_animationPaused)
+ _engine->setGlobal(_phaseVar, 0);
+ _engine->getCurrentScreen()->add(animation);
+
+}
+
void Process::activate() {
switch(status()) {
case kStatusPassive:
diff --git a/engines/agds/process.h b/engines/agds/process.h
index e93a7502804..236c8891ee1 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -148,6 +148,7 @@ private:
}
ProcessExitCode resume();
+ void setupAnimation(Animation *animation);
public:
Process(AGDSEngine *engine, ObjectPtr object, unsigned ip = 0);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index ab1c889606a..da50a200339 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -156,20 +156,13 @@ void Process::loadAnimation() {
debug("loadAnimation %s (phase: %s) %s", name.c_str(), _phaseVar.c_str(), _animationPaused? "(paused)": "");
Animation *animation = _engine->loadAnimation(name);
if (animation) {
- animation->position(_animationPosition);
- animation->z(_animationZ);
- animation->process(getName());
- animation->phaseVar(_phaseVar);
- animation->loop(_animationLoop);
- animation->cycles(_animationCycles);
- animation->delay(_animationDelay);
- animation->setRandom(_animationRandom);
- animation->startPaused(_animationPaused);
- if (_phaseVar.empty())
- suspend();
- else if (_animationPaused)
- _engine->setGlobal(_phaseVar, 0);
- _engine->getCurrentScreen()->add(animation);
+ if (_animationPaused) {
+ _animationLoop = false;
+ _animationCycles = 0;
+ _animationRandom = 0;
+ _animationDelay = 0;
+ }
+ setupAnimation(animation);
}
}
@@ -1372,12 +1365,11 @@ void Process::loadAnimationFromObject() {
debug("loadAnimationFromObject %s %s", name.c_str(), _animationPaused? "(paused)": "");
Animation *animation = _engine->loadAnimation(name);
if (animation) {
- if (_animationPaused) {
- animation->phaseVar(_phaseVar);
- animation->process(getName());
- animation->startPaused(_animationPaused);
- _object->setAnimation(animation);
- }
+ _animationCycles = 0;
+ _animationLoop = true;
+ _phaseVar.clear();
+ _object->setAnimation(animation);
+ setupAnimation(animation);
}
}
Commit: b1399e3ad7fdffa40b63c959aaa1bf435151b92c
https://github.com/scummvm/scummvm/commit/b1399e3ad7fdffa40b63c959aaa1bf435151b92c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:26+01:00
Commit Message:
AGDS: decode/show first frame
Changed paths:
engines/agds/animation.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 748fe6e67fa..b2365a499ec 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -82,8 +82,12 @@ void Animation::rewind() {
}
bool Animation::tick(AGDSEngine &engine) {
- if (_paused)
+ if (_paused) {
+ if (_frameIndex == 0 && !_frame) {
+ decodeNextFrame(engine);
+ }
return true;
+ }
if (_delay > 0) {
--_delay;
Commit: 236af478df909c215f402b9a01510e6f614ec8ac
https://github.com/scummvm/scummvm/commit/236af478df909c215f402b9a01510e6f614ec8ac
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:26+01:00
Commit Message:
AGDS: rename _animationPaused to _phaseVarControlled
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index b2365a499ec..1e245afc168 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -30,7 +30,7 @@
namespace AGDS {
-Animation::Animation() : _flic(), _frame(), _frames(0), _loop(false), _cycles(1), _startPaused(false), _frameIndex(0), _paused(false), _speed(100), _z(0), _delay(-1), _random(0) {
+Animation::Animation() : _flic(), _frame(), _frames(0), _loop(false), _cycles(1), _phaseVarControlled(false), _frameIndex(0), _paused(false), _speed(100), _z(0), _delay(-1), _random(0) {
}
Animation::~Animation() {
@@ -83,9 +83,6 @@ void Animation::rewind() {
bool Animation::tick(AGDSEngine &engine) {
if (_paused) {
- if (_frameIndex == 0 && !_frame) {
- decodeNextFrame(engine);
- }
return true;
}
@@ -94,7 +91,7 @@ bool Animation::tick(AGDSEngine &engine) {
return true;
}
- if (_startPaused && !_phaseVar.empty() && engine.getGlobal(_phaseVar) == -2) {
+ if (_phaseVarControlled && !_phaseVar.empty() && engine.getGlobal(_phaseVar) == -2) {
debug("phase var %s signalled deleting of animation", _phaseVar.c_str());
return false;
}
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 75aec348903..8eaab87daa1 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -44,7 +44,7 @@ class Animation {
Common::String _phaseVar;
bool _loop;
int _cycles;
- bool _startPaused;
+ bool _phaseVarControlled;
int _frameIndex;
bool _paused;
int _speed;
@@ -101,9 +101,8 @@ public:
_random = value;
}
- void startPaused(bool paused) {
- _startPaused = paused;
- _paused = paused;
+ void phaseVarControlled(bool controlled) {
+ _phaseVarControlled = controlled;
}
bool paused() const {
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 0cd002d9d9b..c79d927e28c 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -32,7 +32,7 @@ Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) : _engine(en
_status(kStatusActive), _exitCode(kExitCodeDestroy),
_tileWidth(16), _tileHeight(16), _tileResource(0), _tileIndex(0),
_timer(0),
- _animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0), _animationPaused(false), _animationSpeed(100)
+ _animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0), _phaseVarControlled(false), _animationSpeed(100)
{
}
@@ -136,10 +136,10 @@ void Process::setupAnimation(Animation *animation) {
animation->cycles(_animationCycles);
animation->delay(_animationDelay);
animation->setRandom(_animationRandom);
- animation->startPaused(_animationPaused);
+ animation->phaseVarControlled(_phaseVarControlled);
if (_phaseVar.empty())
suspend();
- else if (_animationPaused)
+ else if (_phaseVarControlled)
_engine->setGlobal(_phaseVar, 0);
_engine->getCurrentScreen()->add(animation);
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 236c8891ee1..5fc4f3a8578 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -62,7 +62,7 @@ private:
int _animationZ;
int _animationDelay;
int _animationRandom;
- bool _animationPaused;
+ bool _phaseVarControlled;
int _animationSpeed;
Common::Point _mousePosition;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index da50a200339..06a13f506fe 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -153,10 +153,10 @@ void Process::loadPicture() {
void Process::loadAnimation() {
Common::String name = popText();
- debug("loadAnimation %s (phase: %s) %s", name.c_str(), _phaseVar.c_str(), _animationPaused? "(paused)": "");
+ debug("loadAnimation %s (phase: %s) %s", name.c_str(), _phaseVar.c_str(), _phaseVarControlled? "(paused)": "");
Animation *animation = _engine->loadAnimation(name);
if (animation) {
- if (_animationPaused) {
+ if (_phaseVarControlled) {
_animationLoop = false;
_animationCycles = 0;
_animationRandom = 0;
@@ -596,7 +596,7 @@ void Process::stub102() {
void Process::setAnimationPaused() {
debug("setAnimationPaused");
- _animationPaused = true;
+ _phaseVarControlled = true;
}
void Process::resetState() {
@@ -605,7 +605,7 @@ void Process::resetState() {
_animationCycles = 1;
_animationLoop = false;
_animationPosition = Common::Point();
- _animationPaused = false;
+ _phaseVarControlled = false;
_animationZ = 0;
_animationRandom = 0;
_animationDelay = -1;
@@ -1362,7 +1362,7 @@ void Process::loadPictureFromObject() {
void Process::loadAnimationFromObject() {
Common::String name = popText();
- debug("loadAnimationFromObject %s %s", name.c_str(), _animationPaused? "(paused)": "");
+ debug("loadAnimationFromObject %s %s", name.c_str(), _phaseVarControlled? "(paused)": "");
Animation *animation = _engine->loadAnimation(name);
if (animation) {
_animationCycles = 0;
Commit: 5243e004f15c6296ca4efecf8119342f9aed843c
https://github.com/scummvm/scummvm/commit/5243e004f15c6296ca4efecf8119342f9aed843c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:26+01:00
Commit Message:
AGDS: skip phaseVarControlled animations with no frame, allow resume
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 1e245afc168..a1ddafdbcf7 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -30,7 +30,7 @@
namespace AGDS {
-Animation::Animation() : _flic(), _frame(), _frames(0), _loop(false), _cycles(1), _phaseVarControlled(false), _frameIndex(0), _paused(false), _speed(100), _z(0), _delay(-1), _random(0) {
+Animation::Animation() : _flic(), _frame(), _frames(0), _loop(false), _cycles(1), _phaseVarControlled(false), _frameIndex(0), _paused(false), _resumed(false), _speed(100), _z(0), _delay(-1), _random(0) {
}
Animation::~Animation() {
@@ -86,6 +86,11 @@ bool Animation::tick(AGDSEngine &engine) {
return true;
}
+ if (!_frame && _phaseVarControlled && !_resumed)
+ return true;
+
+ _resumed = false;
+
if (_delay > 0) {
--_delay;
return true;
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 8eaab87daa1..db204ca20bf 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -47,6 +47,7 @@ class Animation {
bool _phaseVarControlled;
int _frameIndex;
bool _paused;
+ bool _resumed;
int _speed;
int _z;
int _delay;
@@ -115,6 +116,7 @@ public:
void resume() {
_paused = false;
+ _resumed = true;
}
void rewind();
Commit: fda9eda54a09165319372c3f7893a882acd2a6bb
https://github.com/scummvm/scummvm/commit/fda9eda54a09165319372c3f7893a882acd2a6bb
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:27+01:00
Commit Message:
AGDS: use (phase-var) instead of (paused)
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 06a13f506fe..7555309c31f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -153,7 +153,7 @@ void Process::loadPicture() {
void Process::loadAnimation() {
Common::String name = popText();
- debug("loadAnimation %s (phase: %s) %s", name.c_str(), _phaseVar.c_str(), _phaseVarControlled? "(paused)": "");
+ debug("loadAnimation %s (phase: %s) %s", name.c_str(), _phaseVar.c_str(), _phaseVarControlled? "(phase-var)": "");
Animation *animation = _engine->loadAnimation(name);
if (animation) {
if (_phaseVarControlled) {
@@ -1362,7 +1362,7 @@ void Process::loadPictureFromObject() {
void Process::loadAnimationFromObject() {
Common::String name = popText();
- debug("loadAnimationFromObject %s %s", name.c_str(), _phaseVarControlled? "(paused)": "");
+ debug("loadAnimationFromObject %s %s", name.c_str(), _phaseVarControlled? "(phase-var)": "");
Animation *animation = _engine->loadAnimation(name);
if (animation) {
_animationCycles = 0;
Commit: a3073ceb47468cd0169fe5341d2828318c43513d
https://github.com/scummvm/scummvm/commit/a3073ceb47468cd0169fe5341d2828318c43513d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:27+01:00
Commit Message:
AGDS: fix typo
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 7555309c31f..552a20c04f3 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -831,7 +831,7 @@ void Process::restartAnimation() {
}
Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
if (animation) {
- if (_engine->getGlobal(phaseVar) == 1 && !animation->paused()) {
+ if (_engine->getGlobal(phaseVar) == -1 && !animation->paused()) {
animation->rewind();
}
animation->resume();
Commit: a65a19b081b4369bb776aa62a20a00fac4d61d3d
https://github.com/scummvm/scummvm/commit/a65a19b081b4369bb776aa62a20a00fac4d61d3d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:27+01:00
Commit Message:
AGDS: do not ++i twice in animation tick loop
Changed paths:
engines/agds/screen.cpp
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 386779c7f0a..e45695c3b7f 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -98,7 +98,7 @@ bool Screen::remove(const Common::String &name) {
}
void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
- for(uint i = 0; i < _animations.size(); ++i) {
+ for(uint i = 0; i < _animations.size(); ) {
Animation *animation = _animations.data()[i];
if (animation->tick(engine))
++i;
Commit: bcbc9bc887050934dbdfd6eb9a4c360200a09f56
https://github.com/scummvm/scummvm/commit/bcbc9bc887050934dbdfd6eb9a4c360200a09f56
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:27+01:00
Commit Message:
AGDS: fix animation so intro sequence partially works now
Changed paths:
engines/agds/agds.cpp
engines/agds/animation.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 54569293750..d34c3f0a985 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -587,12 +587,7 @@ Animation *AGDSEngine::loadAnimation(const Common::String &name) {
}
Animation *AGDSEngine::findAnimationByPhaseVar(const Common::String &phaseVar) {
- for (AnimationsType::iterator i = _animations.begin(); i != _animations.end(); ++i) {
- Animation *animation = i->_value;
- if (animation->phaseVar() == phaseVar)
- return animation;
- }
- return NULL;
+ return _currentScreen? _currentScreen->findAnimationByPhaseVar(phaseVar): nullptr;
}
Character *AGDSEngine::loadCharacter(const Common::String &id, const Common::String &filename, const Common::String &object) {
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index a1ddafdbcf7..7157378059e 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -106,6 +106,10 @@ bool Animation::tick(AGDSEngine &engine) {
} else {
engine.reactivate(_process);
}
+ if (_phaseVarControlled) {
+ freeFrame();
+ return true;
+ }
return false;
}
decodeNextFrame(engine);
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index e45695c3b7f..3703d822ccf 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -97,6 +97,15 @@ bool Screen::remove(const Common::String &name) {
return false;
}
+Animation *Screen::findAnimationByPhaseVar(const Common::String &phaseVar) {
+ for (auto i = _animations.begin(); i != _animations.end(); ++i) {
+ Animation *animation = *i;
+ if (animation->phaseVar() == phaseVar)
+ return animation;
+ }
+ return NULL;
+}
+
void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
for(uint i = 0; i < _animations.size(); ) {
Animation *animation = _animations.data()[i];
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 4d2410914eb..0462c326700 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -115,6 +115,7 @@ public:
ObjectPtr find(Common::Point pos) const;
ObjectPtr find(const Common::String &name);
KeyHandler findKeyHandler(const Common::String &keyName);
+ Animation * findAnimationByPhaseVar(const Common::String &phaseVar);
void load(AGDSEngine & engine, const PatchPtr &patch);
void save(AGDSEngine & engine, const PatchPtr &patch);
Commit: a344c0e05c4a265b54b20ea1e605a6e441c7e1fd
https://github.com/scummvm/scummvm/commit/a344c0e05c4a265b54b20ea1e605a6e441c7e1fd
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:27+01:00
Commit Message:
AGDS: implement opcodes 120, 125
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 46010553468..ccc83c13cfe 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -137,12 +137,12 @@ enum Opcode {
kLoadAnimation = 117,
kLoadSample = 118,
kSetAnimationPaused = 119,
- kStub120 = 120,
+ kPlayerSay120 = 120,
kStub121 = 121,
- kPlayerSay = 122,
+ kPlayerSay122 = 122,
kNPCSayNoSound = 123,
kNPCSay = 124,
- kStub125 = 125,
+ kPlayerSay125 = 125,
kStub126 = 126,
kSetTimer = 127,
kProcessResetState = 128,
@@ -356,7 +356,9 @@ enum Opcode {
OP(kLoadAnimation, loadAnimation) \
OP(kLoadSample, loadSample) \
OP(kSetAnimationPaused, setAnimationPaused) \
- OP(kPlayerSay, playerSay) \
+ OP(kPlayerSay120, playerSay120) \
+ OP(kPlayerSay122, playerSay122) \
+ OP(kPlayerSay125, playerSay125) \
OP(kNPCSay, npcSay) \
OP(kNPCSayNoSound, npcSayNoSound) \
OP(kSetTimer, setTimer) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 552a20c04f3..ce5c4a2cf25 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -993,10 +993,18 @@ void Process::npcSayNoSound() {
tell(true);
}
-void Process::playerSay() {
+void Process::playerSay122() {
tell(false, popText());
}
+void Process::playerSay120() {
+ tell(false, Common::String());
+}
+
+void Process::playerSay125() {
+ playerSay120(); //same case
+}
+
void Process::loadDialog() {
Common::String arg3 = popString();
Common::String arg2 = popString();
Commit: afb6c85b9119c05b60fed389bd9eff9e73b7ccf1
https://github.com/scummvm/scummvm/commit/afb6c85b9119c05b60fed389bd9eff9e73b7ccf1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:27+01:00
Commit Message:
AGDS: implement opcode 96, setCharacterDirection
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index ccc83c13cfe..21c7b4c8755 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -113,7 +113,7 @@ enum Opcode {
kMoveCharacterUserMove = 93,
kLeaveCharacter = 94,
kSetCharacter = 95,
- kStub96 = 96,
+ kSetCharacterDirection = 96,
kPointCharacter = 97,
kDisableUser = 98,
kEnableUser = 99,
@@ -328,6 +328,7 @@ enum Opcode {
OP(kMoveCharacterUserMove, moveCharacterUserMove) \
OP(kLeaveCharacter, leaveCharacter) \
OP(kSetCharacter, setCharacter) \
+ OP(kSetCharacterDirection, setCharacterDirection) \
OP(kPointCharacter, pointCharacter) \
OP(kDisableUser, disableUser) \
OP(kEnableUser, enableUser) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index ce5c4a2cf25..9b11c98c803 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1288,13 +1288,19 @@ void Process::leaveCharacterEx() {
void Process::setCharacter() {
Common::String object = popString();
Common::String region = popString();
- debug("setCharacter %s %s", region.c_str(), object.c_str());
+ debug("setCharacter stub %s %s", region.c_str(), object.c_str());
+}
+
+void Process::setCharacterDirection() {
+ int dir = pop();
+ Common::String name = popString();
+ debug("setCharacterDirection stub %s %d", name.c_str(), dir);
}
void Process::pointCharacter() {
Common::String arg2 = popString();
Common::String arg1 = popString();
- debug("pointCharacter %s %s", arg1.c_str(), arg2.c_str());
+ debug("pointCharacter stub %s %s", arg1.c_str(), arg2.c_str());
suspend();
}
Commit: eebc96ece6b39afcab2dbcbe5e074eb546ce0db7
https://github.com/scummvm/scummvm/commit/eebc96ece6b39afcab2dbcbe5e074eb546ce0db7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:27+01:00
Commit Message:
AGDS: port engine to the new API
Changed paths:
A engines/agds/metaengine.cpp
engines/agds/detection.cpp
engines/agds/module.mk
diff --git a/engines/agds/detection.cpp b/engines/agds/detection.cpp
index d4253186e45..e2400fe16aa 100644
--- a/engines/agds/detection.cpp
+++ b/engines/agds/detection.cpp
@@ -20,9 +20,6 @@
*
*/
-#include "agds/agds.h"
-#include "agds/object.h"
-
#include "engines/advancedDetector.h"
static const PlainGameDescriptor agdsGames[] = {
@@ -32,53 +29,23 @@ static const PlainGameDescriptor agdsGames[] = {
#include "agds/detection_tables.h"
-class AGDSMetaEngine : public AdvancedMetaEngine {
+class AGDSMetaEngineDetection : public AdvancedMetaEngineDetection {
public:
- AGDSMetaEngine() : AdvancedMetaEngine(AGDS::gameDescriptions, sizeof(ADGameDescription), agdsGames) {
+ AGDSMetaEngineDetection() : AdvancedMetaEngineDetection(AGDS::gameDescriptions, sizeof(ADGameDescription), agdsGames) {
_maxScanDepth = 3;
}
- const char *getEngineId() const {
+ const char *getEngineId() const override {
return "agds";
}
- const char *getName() const {
+ const char *getName() const override {
return "AGDS Engine";
}
- const char *getOriginalCopyright() const override{
+ const char *getOriginalCopyright() const override {
return "AGDS (C) Future Games";
}
-
- bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
- bool hasFeature(MetaEngineFeature f) const {
- switch (f) {
- case kSupportsListSaves:
- case kSupportsLoadingDuringStartup:
- case kSupportsDeleteSave:
- case kSavesSupportMetaInfo:
- case kSavesSupportThumbnail:
- case kSimpleSavesNames:
- return true;
- default:
- return AdvancedMetaEngine::hasFeature(f);
- }
- }
-
- int getMaximumSaveSlot() const {
- return 99;
- }
};
-bool AGDSMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
- if (desc) {
- *engine = new AGDS::AGDSEngine(syst, desc);
- }
- return *engine;
-}
-
-#if PLUGIN_ENABLED_DYNAMIC(AGDS)
-REGISTER_PLUGIN_DYNAMIC(AGDS, PLUGIN_TYPE_ENGINE, AGDSMetaEngine);
-#else
-REGISTER_PLUGIN_STATIC(AGDS, PLUGIN_TYPE_ENGINE, AGDSMetaEngine);
-#endif
+REGISTER_PLUGIN_STATIC(AGDS_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, AGDSMetaEngineDetection);
diff --git a/engines/agds/metaengine.cpp b/engines/agds/metaengine.cpp
new file mode 100644
index 00000000000..a92414f8480
--- /dev/null
+++ b/engines/agds/metaengine.cpp
@@ -0,0 +1,66 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+#include "agds/agds.h"
+#include "agds/object.h"
+
+namespace AGDS {
+
+class AGDSMetaEngine : public AdvancedMetaEngine {
+public:
+ bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
+ bool hasFeature(MetaEngineFeature f) const override {
+ switch (f) {
+ case kSupportsListSaves:
+ case kSupportsLoadingDuringStartup:
+ case kSupportsDeleteSave:
+ case kSavesSupportMetaInfo:
+ case kSavesSupportThumbnail:
+ case kSimpleSavesNames:
+ return true;
+ default:
+ return AdvancedMetaEngine::hasFeature(f);
+ }
+ }
+
+ const char *getName() const override {
+ return "agds";
+ }
+
+ int getMaximumSaveSlot() const override {
+ return 99;
+ }
+};
+
+bool AGDSMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ if (desc) {
+ *engine = new AGDS::AGDSEngine(syst, desc);
+ }
+ return *engine;
+}
+
+}
+
+#if PLUGIN_ENABLED_DYNAMIC(AGDS)
+ REGISTER_PLUGIN_DYNAMIC(AGDS, PLUGIN_TYPE_ENGINE, AGDS::AGDSMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(AGDS, PLUGIN_TYPE_ENGINE, AGDS::AGDSMetaEngine);
+#endif
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index 7ffcb442c64..8254ed7d65a 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -1,15 +1,19 @@
MODULE := engines/agds
+# Detection objects
+DETECT_OBJS += \
+ $(MODULE)/detection.o
+
MODULE_OBJS := \
agds.o \
animation.o \
character.o \
console.o \
database.o \
- detection.o \
dialog.o \
font.o \
inventory.o \
+ metaengine.o \
mjpgPlayer.o \
mouseMap.o \
object.o \
Commit: 872530477422f46570e01dea1a353ab7be0af2a2
https://github.com/scummvm/scummvm/commit/872530477422f46570e01dea1a353ab7be0af2a2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:27+01:00
Commit Message:
AGDS: initial refactoring of character
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/character.cpp
engines/agds/character.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index d34c3f0a985..181db4abfff 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -47,7 +47,7 @@ namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Engine(system),
_gameDescription(gameDesc), _pictureCacheId(1), _sharedStorageIndex(-2),
- _mjpgPlayer(), _currentScreen(),
+ _mjpgPlayer(), _currentScreen(), _currentCharacter(),
_defaultMouseCursor(),
_mouse(400, 300),
_userEnabled(true), _systemUserEnabled(true),
@@ -62,6 +62,7 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
}
AGDSEngine::~AGDSEngine() {
+ delete _currentCharacter;
delete _currentScreen;
for (PictureCacheType::iterator i = _pictureCache.begin(); i != _pictureCache.end(); ++i) {
i->_value->free();
@@ -469,8 +470,8 @@ Common::Error AGDSEngine::run() {
mouseCursor->paint(*this, *backbuffer, _mouse);
}
- for (CharactersType::iterator i = _characters.begin(); i != _characters.end(); ++i)
- i->_value->paint(*this, *backbuffer);
+ if (_currentCharacter)
+ _currentCharacter->paint(*backbuffer);
if (_textLayout.valid()) {
if (_syncSoundId >= 0) {
@@ -590,21 +591,14 @@ Animation *AGDSEngine::findAnimationByPhaseVar(const Common::String &phaseVar) {
return _currentScreen? _currentScreen->findAnimationByPhaseVar(phaseVar): nullptr;
}
-Character *AGDSEngine::loadCharacter(const Common::String &id, const Common::String &filename, const Common::String &object) {
+void AGDSEngine::loadCharacter(const Common::String &id, const Common::String &filename, const Common::String &object) {
debug("loadCharacter %s %s %s", id.c_str(), filename.c_str(), object.c_str());
- CharactersType::iterator i = _characters.find(id);
- if (i != _characters.end())
- return i->_value;
-
- Character *character = new Character(id, object);
- character->load(_resourceManager.getResource(filename));
- _characters[id] = character;
- return character;
-}
-Character *AGDSEngine::getCharacter(const Common::String &name) const {
- CharactersType::const_iterator i = _characters.find(name);
- return i != _characters.end() ? i->_value : NULL;
+ delete _currentCharacter;
+ _currentCharacterName = id;
+ _currentCharacter = new Character(this, id, loadObject(object));
+ _currentCharacter->load(_resourceManager.getResource(filename));
+ runObject(_currentCharacter->object());
}
Graphics::TransparentSurface *AGDSEngine::loadPicture(const Common::String &name) { return convertToTransparent(_resourceManager.loadPicture(name, _pixelFormat)); }
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index c5e08db9d32..6b1c0238574 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -171,8 +171,10 @@ public:
Animation * loadAnimation(const Common::String &name);
Animation * loadMouseCursor(const Common::String &name);
Animation * findAnimationByPhaseVar(const Common::String &phaseVar);
- Character * loadCharacter(const Common::String &id, const Common::String &name, const Common::String &object);
- Character * getCharacter(const Common::String &name) const;
+ void loadCharacter(const Common::String &id, const Common::String &name, const Common::String &object);
+ Character * getCharacter(const Common::String &name) {
+ return _currentCharacterName == name? _currentCharacter: nullptr;
+ }
void loadDefaultMouseCursor(const Common::String &name) {
_defaultMouseCursorName = name;
@@ -244,7 +246,6 @@ private:
typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
typedef Common::HashMap<Common::String, Animation *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> AnimationsType;
- typedef Common::HashMap<Common::String, Character *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> CharactersType;
typedef Common::HashMap<int, Font *> FontsType;
typedef Common::HashMap<Common::String, PatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PatchesType;
@@ -257,7 +258,6 @@ private:
int _pictureCacheId;
FontsType _fonts;
AnimationsType _animations;
- CharactersType _characters;
ProcessListType _processes;
PatchesType _patches;
int _sharedStorageIndex;
@@ -270,6 +270,8 @@ private:
Common::String _filmProcess;
Screen * _currentScreen;
Common::String _currentScreenName;
+ Character * _currentCharacter;
+ Common::String _currentCharacterName;
Common::String _nextScreenName;
Common::String _previousScreenName;
Common::String _defaultMouseCursorName;
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 0c3d22cedda..9042b04505a 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -76,4 +76,15 @@ void Character::load(Common::SeekableReadStream* stream) {
delete stream;
}
+void Character::setDirection(int dir) {
+ debug("setDirection %d", dir);
+ _direction = dir;
+}
+
+
+void Character::paint(Graphics::Surface & backbuffer) {
+ if (_enabled && _phase <= _frames)
+ ++_phase;
+}
+
}
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 4102c57b518..3cf9afd1178 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/array.h"
+#include "common/ptr.h"
#include "common/rect.h"
namespace Common { class SeekableReadStream; }
@@ -33,15 +34,19 @@ namespace Graphics { struct Surface; }
namespace AGDS {
class AGDSEngine;
+class Process;
class Object;
+typedef Common::SharedPtr<Object> ObjectPtr;
class Character {
+ AGDSEngine * _engine;
+ ObjectPtr _object;
Common::String _name;
- Common::String _object;
Common::Point _pos;
bool _enabled;
int _phase;
int _frames;
+ int _direction;
struct AnimationDescription {
struct Frame {
@@ -55,22 +60,18 @@ class Character {
Common::Array<AnimationDescription> _animations;
public:
- Character(const Common::String & name, const Common::String & object):
- _name(name), _object(object), _enabled(true), _phase(0), _frames(0) {
+ Character(AGDSEngine * engine, const Common::String & name, const ObjectPtr & object):
+ _engine(engine), _name(name), _object(object), _enabled(false), _phase(0), _frames(0), _direction(-1) {
}
const Common::String & name() const {
return _name;
}
- const Common::String & object() const {
+ const ObjectPtr & object() const {
return _object;
}
- Common::Point position() const {
- return _pos;
- }
-
void load(Common::SeekableReadStream* stream);
void enable(bool enabled = true) {
@@ -90,11 +91,18 @@ public:
return _phase <= _frames? _phase + 1: -1;
}
- void paint(AGDSEngine & engine, Graphics::Surface & backbuffer) {
- if (_enabled && _phase <= _frames)
- ++_phase;
+ void position(Common::Point pos) {
+ _pos = pos;
+ }
+
+ Common::Point position() const {
+ return _pos;
}
+ void setDirection(int dir);
+
+ void paint(Graphics::Surface & backbuffer);
+
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 9b11c98c803..74529cc4e71 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1286,9 +1286,20 @@ void Process::leaveCharacterEx() {
}
void Process::setCharacter() {
- Common::String object = popString();
- Common::String region = popString();
- debug("setCharacter stub %s %s", region.c_str(), object.c_str());
+ int dir = pop();
+ Common::String regionName = popString();
+ Common::String id = popString();
+ debug("setCharacter %s %s %d", id.c_str(), regionName.c_str(), dir);
+ auto character = _engine->getCharacter(id);
+ if (character) {
+ auto region = _engine->loadRegion(regionName);
+ if (region)
+ character->position(region->center);
+ else
+ warning("no region %s", regionName.c_str());
+ character->setDirection(dir);
+ } else
+ warning("no character %s", id.c_str());
}
void Process::setCharacterDirection() {
@@ -1308,6 +1319,8 @@ void Process::getCharacterAnimationPhase() {
Common::String name = popString();
debug("getCharacterAnimationPhase: %s", name.c_str());
Character *character = _engine->getCharacter(name);
+ if (!character)
+ warning("no character %s", name.c_str());
int phase = character ? character->getPhase() : -1;
debug("animation phase = %d", phase);
push(phase);
Commit: c79b114327b4309f9f1818bc38af6cdba992f488
https://github.com/scummvm/scummvm/commit/c79b114327b4309f9f1818bc38af6cdba992f488
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:27+01:00
Commit Message:
AGDS: implement Character::moveTo stub
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 9042b04505a..94b9dd31476 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -81,6 +81,12 @@ void Character::setDirection(int dir) {
_direction = dir;
}
+void Character::moveTo(Common::Point dst, int frames) {
+ debug("move to %d,%d", dst.x, dst.y);
+ _dst = dst;
+ _frames = frames;
+}
+
void Character::paint(Graphics::Surface & backbuffer) {
if (_enabled && _phase <= _frames)
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 3cf9afd1178..c7a4e898bf2 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -43,6 +43,7 @@ class Character {
ObjectPtr _object;
Common::String _name;
Common::Point _pos;
+ Common::Point _dst;
bool _enabled;
int _phase;
int _frames;
@@ -99,6 +100,8 @@ public:
return _pos;
}
+ void moveTo(Common::Point dst, int frames);
+
void setDirection(int dir);
void paint(Graphics::Surface & backbuffer);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 74529cc4e71..0cb5e99c867 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1233,10 +1233,18 @@ void Process::enableCharacter() {
}
void Process::moveCharacter(bool usermove) {
- int arg3 = pop();
- Common::String arg2 = popString();
- Common::String arg1 = popString();
- debug("moveCharacter %s %s %d, usermove: %d", arg1.c_str(), arg2.c_str(), arg3, usermove);
+ int frames = pop();
+ Common::String regionName = popString();
+ Common::String id = popString();
+ debug("moveCharacter %s %s, frames: %d, usermove: %d", id.c_str(), regionName.c_str(), frames, usermove);
+ Character *character = _engine->getCharacter(id);
+ if (character) {
+ auto region = _engine->loadRegion(regionName);
+ if (region) {
+ character->moveTo(region->center, frames);
+ }
+ } else
+ warning("character %s could not be found", id.c_str());
if (_status == kStatusPassive)
suspend();
}
@@ -1293,9 +1301,10 @@ void Process::setCharacter() {
auto character = _engine->getCharacter(id);
if (character) {
auto region = _engine->loadRegion(regionName);
- if (region)
+ if (region) {
+ debug("setting character position to %d,%d", region->center.x, region->center.y);
character->position(region->center);
- else
+ } else
warning("no region %s", regionName.c_str());
character->setDirection(dir);
} else
Commit: 8399f0e1863e23ccfbc8b7df0803e3e81242e759
https://github.com/scummvm/scummvm/commit/8399f0e1863e23ccfbc8b7df0803e3e81242e759
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:27+01:00
Commit Message:
AGDS: implement animateCharacter
Changed paths:
engines/agds/agds.cpp
engines/agds/character.cpp
engines/agds/character.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 181db4abfff..75d8f30edd9 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -598,7 +598,6 @@ void AGDSEngine::loadCharacter(const Common::String &id, const Common::String &f
_currentCharacterName = id;
_currentCharacter = new Character(this, id, loadObject(object));
_currentCharacter->load(_resourceManager.getResource(filename));
- runObject(_currentCharacter->object());
}
Graphics::TransparentSurface *AGDSEngine::loadPicture(const Common::String &name) { return convertToTransparent(_resourceManager.loadPicture(name, _pixelFormat)); }
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 94b9dd31476..76117375ebe 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -21,6 +21,9 @@
*/
#include "agds/character.h"
+#include "agds/agds.h"
+#include "agds/animation.h"
+#include "agds/object.h"
#include "agds/resourceManager.h"
#include "common/array.h"
#include "common/debug.h"
@@ -79,18 +82,57 @@ void Character::load(Common::SeekableReadStream* stream) {
void Character::setDirection(int dir) {
debug("setDirection %d", dir);
_direction = dir;
+ _animation = _engine->loadAnimation(_animations[dir].filename);
+ if (!_animation) {
+ debug("no animation?");
+ _phase = -1;
+ _frames = 0;
+ }
+ _animation->loop(true);
}
void Character::moveTo(Common::Point dst, int frames) {
debug("move to %d,%d", dst.x, dst.y);
_dst = dst;
+ _phase = 0;
_frames = frames;
}
+void Character::animate(Common::Point pos, int frames, int speed) {
+ _animation = _engine->loadAnimation(_animations[_direction].filename);
+ if (!_animation) {
+ debug("no animation?");
+ _phase = -1;
+ _frames = 0;
+ }
+ _animation->loop(true);
+ _phase = 0;
+ _frames = frames;
+ _pos = pos;
+}
void Character::paint(Graphics::Surface & backbuffer) {
- if (_enabled && _phase <= _frames)
- ++_phase;
+ if (!_enabled || !_animation)
+ return;
+
+ Common::Point pos = _pos;
+ if (_phase >= 0 && _phase < _frames) {
+ _animation->tick(*_engine);
+ if (_phase + 1 >= _frames) {
+ _phase = -1;
+ _frames = 0;
+ _pos = _dst = pos;
+ } else {
+ float dx = _dst.x - _pos.x;
+ float dy = _dst.y - _pos.y;
+ float t = 1.0f * _phase / _frames;
+ pos.x += dx * t;
+ pos.y += dy * t;
+ ++_phase;
+ }
+ }
+
+ _animation->paint(*_engine, backbuffer, pos);
}
}
diff --git a/engines/agds/character.h b/engines/agds/character.h
index c7a4e898bf2..a2b08f90e47 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -37,10 +37,12 @@ class AGDSEngine;
class Process;
class Object;
typedef Common::SharedPtr<Object> ObjectPtr;
+class Animation;
class Character {
AGDSEngine * _engine;
ObjectPtr _object;
+ Animation * _animation;
Common::String _name;
Common::Point _pos;
Common::Point _dst;
@@ -62,7 +64,7 @@ class Character {
public:
Character(AGDSEngine * engine, const Common::String & name, const ObjectPtr & object):
- _engine(engine), _name(name), _object(object), _enabled(false), _phase(0), _frames(0), _direction(-1) {
+ _engine(engine), _name(name), _object(object), _animation(nullptr), _enabled(false), _phase(-1), _frames(0), _direction(-1) {
}
const Common::String & name() const {
@@ -79,9 +81,7 @@ public:
_enabled = enabled;
}
- void animate(int frames) {
- _frames += frames;
- }
+ void animate(Common::Point pos, int frames, int speed);
void stop() {
_phase = 0;
@@ -89,7 +89,7 @@ public:
}
int getPhase() const {
- return _phase <= _frames? _phase + 1: -1;
+ return _phase;
}
void position(Common::Point pos) {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 0cb5e99c867..92a56b14854 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1258,13 +1258,13 @@ void Process::moveCharacterNoUserMove() {
}
void Process::animateCharacter() {
- int arg2 = pop();
+ int frames = pop();
Common::String name = popString();
- debug("animateCharacter: %s %d", name.c_str(), arg2);
+ debug("animateCharacter: %s %d %d", name.c_str(), frames, _animationSpeed);
Character *character = _engine->getCharacter(name);
if (character)
- character->animate(arg2 * 100 / _animationSpeed);
+ character->animate(_animationPosition, frames, _animationSpeed);
else
warning("character %s could not be found", name.c_str());
}
Commit: 6455ea27054b895b93acf2e43b4fca5f0ec4e850
https://github.com/scummvm/scummvm/commit/6455ea27054b895b93acf2e43b4fca5f0ec4e850
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:28+01:00
Commit Message:
AGDS: enable character by default
Changed paths:
engines/agds/character.h
diff --git a/engines/agds/character.h b/engines/agds/character.h
index a2b08f90e47..98e051c8f90 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -64,7 +64,7 @@ class Character {
public:
Character(AGDSEngine * engine, const Common::String & name, const ObjectPtr & object):
- _engine(engine), _name(name), _object(object), _animation(nullptr), _enabled(false), _phase(-1), _frames(0), _direction(-1) {
+ _engine(engine), _name(name), _object(object), _animation(nullptr), _enabled(true), _phase(-1), _frames(0), _direction(-1) {
}
const Common::String & name() const {
Commit: 509becef2e7c0c326a690c8474831c26b743bc57
https://github.com/scummvm/scummvm/commit/509becef2e7c0c326a690c8474831c26b743bc57
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:28+01:00
Commit Message:
AGDS: do not add all animations to screen
Changed paths:
engines/agds/object.cpp
engines/agds/process.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index fe864be9333..5ef309d8892 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -180,6 +180,7 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
}
}
if (_animation) {
+ _animation->tick(engine);
_animation->paint(engine, backbuffer, _animationPos);
}
if (!_text.empty()) {
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index c79d927e28c..e819ba81e50 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -141,8 +141,6 @@ void Process::setupAnimation(Animation *animation) {
suspend();
else if (_phaseVarControlled)
_engine->setGlobal(_phaseVar, 0);
- _engine->getCurrentScreen()->add(animation);
-
}
void Process::activate() {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 92a56b14854..6989ca09814 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -163,6 +163,7 @@ void Process::loadAnimation() {
_animationDelay = 0;
}
setupAnimation(animation);
+ _engine->getCurrentScreen()->add(animation);
}
}
Commit: da4c7622fa5da92fff873a0b3a31367ed5b31873
https://github.com/scummvm/scummvm/commit/da4c7622fa5da92fff873a0b3a31367ed5b31873
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:28+01:00
Commit Message:
AGDS: implement show/hideCharacter (+opcode for hide), set x,y,dir from savegame
Changed paths:
engines/agds/agds.cpp
engines/agds/character.cpp
engines/agds/character.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 75d8f30edd9..db69d8d7be1 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -829,8 +829,15 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
loadCharacter(id, filename, object);
int x = agds_c->readUint16LE();
int y = agds_c->readUint16LE();
- debug("character at %d, %d", x, y);
- int n = 3;
+ int dir = agds_c->readUint16LE();
+ debug("character at %d, %d, dir: %d", x, y, dir);
+ auto character = getCharacter(id);
+ if (character) {
+ character->position(Common::Point(x, y));
+ character->setDirection(dir);
+ } else
+ warning("no character");
+ int n = 2;
while(n--) {
int v = agds_c->readUint16LE();
debug("savegame character leftover: %d", v);
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 76117375ebe..0eb2d5074d7 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -112,7 +112,7 @@ void Character::animate(Common::Point pos, int frames, int speed) {
}
void Character::paint(Graphics::Surface & backbuffer) {
- if (!_enabled || !_animation)
+ if (!_enabled || !_visible || !_animation)
return;
Common::Point pos = _pos;
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 98e051c8f90..ba1b95d6f6e 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -47,6 +47,7 @@ class Character {
Common::Point _pos;
Common::Point _dst;
bool _enabled;
+ bool _visible;
int _phase;
int _frames;
int _direction;
@@ -64,7 +65,7 @@ class Character {
public:
Character(AGDSEngine * engine, const Common::String & name, const ObjectPtr & object):
- _engine(engine), _name(name), _object(object), _animation(nullptr), _enabled(true), _phase(-1), _frames(0), _direction(-1) {
+ _engine(engine), _name(name), _object(object), _animation(nullptr), _enabled(true), _visible(true), _phase(-1), _frames(0), _direction(-1) {
}
const Common::String & name() const {
@@ -81,6 +82,10 @@ public:
_enabled = enabled;
}
+ void visible(bool visible) {
+ _visible = visible;
+ }
+
void animate(Common::Point pos, int frames, int speed);
void stop() {
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 21c7b4c8755..bee1082f5c9 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -106,7 +106,7 @@ enum Opcode {
kStub86 = 86,
kStub87 = 87,
kAnimateCharacter = 88,
- kStub89 = 89,
+ kHideCharacter = 89,
kShowCharacter = 90,
kStub91 = 91,
kEnableCharacter = 92,
@@ -323,6 +323,7 @@ enum Opcode {
OP(kLoadRegionFromObject, loadRegionFromObject) \
OP(kLoadPictureFromObject, loadPictureFromObject) \
OP(kLoadAnimationFromObject, loadAnimationFromObject) \
+ OP(kHideCharacter, hideCharacter) \
OP(kShowCharacter, showCharacter) \
OP(kEnableCharacter, enableCharacter) \
OP(kMoveCharacterUserMove, moveCharacterUserMove) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 6989ca09814..9252e3a1f9b 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1274,9 +1274,20 @@ void Process::showCharacter() {
Common::String name = popString();
debug("showCharacter %s", name.c_str());
Character *character = _engine->getCharacter(name);
- if (character)
+ if (character) {
+ character->visible(true);
_engine->runObject(character->object());
- else
+ } else
+ warning("character %s could not be found", name.c_str());
+}
+
+void Process::hideCharacter() {
+ Common::String name = popString();
+ debug("hideCharacter %s", name.c_str());
+ Character *character = _engine->getCharacter(name);
+ if (character) {
+ character->visible(false);
+ } else
warning("character %s could not be found", name.c_str());
}
Commit: beb72eb9a01894c120a2e625895306f083e4cc09
https://github.com/scummvm/scummvm/commit/beb72eb9a01894c120a2e625895306f083e4cc09
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:28+01:00
Commit Message:
AGDS: fix wrong move coordinates
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 0eb2d5074d7..4c5258621c7 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -121,7 +121,7 @@ void Character::paint(Graphics::Surface & backbuffer) {
if (_phase + 1 >= _frames) {
_phase = -1;
_frames = 0;
- _pos = _dst = pos;
+ pos = _pos = _dst;
} else {
float dx = _dst.x - _pos.x;
float dy = _dst.y - _pos.y;
Commit: 0d80e505e3f743a9da1d119466cb3bc1a901fe02
https://github.com/scummvm/scummvm/commit/0d80e505e3f743a9da1d119466cb3bc1a901fe02
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:28+01:00
Commit Message:
AGDS: clear _nextScreenName in loadScreen
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index db69d8d7be1..82d60ef493f 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -194,6 +194,7 @@ void AGDSEngine::runObject(const Common::String &name, const Common::String &pro
}
void AGDSEngine::loadScreen(const Common::String &name) {
+ _nextScreenName.clear();
debug("loadScreen %s", name.c_str());
if (_currentScreen && !_currentScreenName.empty())
{
@@ -277,7 +278,6 @@ void AGDSEngine::newGame() {
void AGDSEngine::tick() {
while (!_nextScreenName.empty()) {
Common::String nextScreenName = _nextScreenName;
- _nextScreenName.clear();
loadScreen(nextScreenName);
}
if (_dialog.tick()) {
Commit: 9d08a34cc3330ad2db2d185c1ace09313f658366
https://github.com/scummvm/scummvm/commit/9d08a34cc3330ad2db2d185c1ace09313f658366
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:28+01:00
Commit Message:
AGDS: use ProcessPtr instead of Process
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/console.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 82d60ef493f..4000521f1a9 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -177,8 +177,8 @@ void AGDSEngine::runObject(const ObjectPtr &object) {
void AGDSEngine::runProcess(const ObjectPtr &object, uint ip) {
debug("starting process %s:%04x", object->getName().c_str(), ip);
- _processes.push_front(Process(this, object, ip));
- _processes.front().run();
+ _processes.push_front(ProcessPtr(new Process(this, object, ip)));
+ _processes.front()->run();
}
ObjectPtr AGDSEngine::getCurrentScreenObject(const Common::String &name) {
@@ -238,16 +238,16 @@ void AGDSEngine::resetCurrentScreen() {
void AGDSEngine::runProcesses() {
for (ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
- Process &process = *i;
- if (process.active()) {
- process.run();
+ ProcessPtr process = *i;
+ if (process->active()) {
+ process->run();
++i;
- } else if (process.finished()) {
- debug("deleting process %s", process.getName().c_str());
+ } else if (process->finished()) {
+ debug("deleting process %s", process->getName().c_str());
i = _processes.erase(i);
//FIXME: when the last process exits, remove object from scene
} else {
- //debug("suspended process %s", process.getName().c_str());
+ //debug("suspended process %s", process->getName().c_str());
++i;
}
}
@@ -338,6 +338,7 @@ Common::Error AGDSEngine::run() {
setDebugger(new Console(this));
int loadSlot = ConfMan.getInt("save_slot");
+ debug("save_slot = %d", loadSlot);
if (loadSlot >= 0)
loadGameState(loadSlot);
@@ -918,10 +919,10 @@ void AGDSEngine::reactivate(const Common::String &name) {
return;
for(ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ++i) {
- Process &process = *i;
- if (process.getName() == name) {
+ ProcessPtr process = *i;
+ if (process->getName() == name) {
debug("reactivate %s", name.c_str());
- process.activate();
+ process->activate();
}
}
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 6b1c0238574..a1c26cf4523 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -62,6 +62,7 @@ typedef Common::SharedPtr<Object> ObjectPtr;
struct Patch;
typedef Common::SharedPtr<Patch> PatchPtr;
class Process;
+typedef Common::SharedPtr<Process> ProcessPtr;
struct Region;
typedef Common::SharedPtr<Region> RegionPtr;
struct MouseRegion;
@@ -72,7 +73,7 @@ class Console;
class AGDSEngine : public Engine {
friend class Process;
- typedef Common::List<Process> ProcessListType;
+ typedef Common::List<ProcessPtr> ProcessListType;
public:
AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc);
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index 0f87a5b2a63..a32aad05f2e 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -78,7 +78,7 @@ bool Console::info(int argc, const char **argv) {
debugPrintf("processes:\n");
auto & processes = _engine->processes();
for(auto & process : processes) {
- debugPrintf("%s\n", process.getName().c_str());
+ debugPrintf("%s\n", process->getName().c_str());
}
return true;
}
Commit: 2283af4938fcb77571e8b622fb3266781daeaf33
https://github.com/scummvm/scummvm/commit/2283af4938fcb77571e8b622fb3266781daeaf33
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:28+01:00
Commit Message:
AGDS: implement process table to mimic original behaviour + fix lifetime issues
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 4000521f1a9..805a2d998d0 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -47,6 +47,7 @@ namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Engine(system),
_gameDescription(gameDesc), _pictureCacheId(1), _sharedStorageIndex(-2),
+ _processes(MaxProcesses),
_mjpgPlayer(), _currentScreen(), _currentCharacter(),
_defaultMouseCursor(),
_mouse(400, 300),
@@ -177,8 +178,15 @@ void AGDSEngine::runObject(const ObjectPtr &object) {
void AGDSEngine::runProcess(const ObjectPtr &object, uint ip) {
debug("starting process %s:%04x", object->getName().c_str(), ip);
- _processes.push_front(ProcessPtr(new Process(this, object, ip)));
- _processes.front()->run();
+ for(uint i = 0; i < _processes.size(); ++i) {
+ auto &process = _processes[i];
+ if (!process) {
+ process = ProcessPtr(new Process(this, object, ip));
+ process->run();
+ return;
+ }
+ }
+ error("process table exhausted");
}
ObjectPtr AGDSEngine::getCurrentScreenObject(const Common::String &name) {
@@ -206,7 +214,9 @@ void AGDSEngine::loadScreen(const Common::String &name) {
}
_mouseMap.hideAll(this);
resetCurrentScreen();
- _processes.clear();
+ for(uint i = 0; i < _processes.size(); ++i) {
+ _processes[i].reset();
+ }
_animations.clear();
_soundManager.stopAll();
@@ -237,18 +247,20 @@ void AGDSEngine::resetCurrentScreen() {
void AGDSEngine::runProcesses() {
- for (ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ) {
- ProcessPtr process = *i;
+ for (uint i = 0; i < _processes.size(); ++i) {
+ ProcessPtr &process = _processes[i];
+ if (!process)
+ continue;
+
if (process->active()) {
process->run();
- ++i;
- } else if (process->finished()) {
+ }
+ if (process->finished()) {
debug("deleting process %s", process->getName().c_str());
- i = _processes.erase(i);
+ process.reset();
//FIXME: when the last process exits, remove object from scene
} else {
//debug("suspended process %s", process->getName().c_str());
- ++i;
}
}
}
@@ -918,9 +930,9 @@ void AGDSEngine::reactivate(const Common::String &name) {
if (name.empty())
return;
- for(ProcessListType::iterator i = _processes.begin(); i != _processes.end(); ++i) {
- ProcessPtr process = *i;
- if (process->getName() == name) {
+ for(uint i = 0; i < _processes.size(); ++i) {
+ ProcessPtr &process = _processes[i];
+ if (process && process->getName() == name) {
debug("reactivate %s", name.c_str());
process->activate();
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index a1c26cf4523..dd93df57447 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -24,6 +24,7 @@
#define AGDS_AGDS_H
#include "common/scummsys.h"
+#include "common/array.h"
#include "common/hashmap.h"
#include "common/ptr.h"
#include "common/random.h"
@@ -73,7 +74,8 @@ class Console;
class AGDSEngine : public Engine {
friend class Process;
- typedef Common::List<ProcessPtr> ProcessListType;
+ typedef Common::Array<ProcessPtr> ProcessListType;
+ static constexpr uint MaxProcesses = 100;
public:
AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc);
Commit: 5642d2add5342e2127ef98dd986a25d3b7d4528d
https://github.com/scummvm/scummvm/commit/5642d2add5342e2127ef98dd986a25d3b7d4528d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:28+01:00
Commit Message:
AGDS: output unknown header fields of CHR file
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 4c5258621c7..17e4e03add3 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -71,7 +71,25 @@ void Character::load(Common::SeekableReadStream* stream) {
AnimationDescription::Frame frame = { x, y, w, h };
animation.frames.push_back(frame);
debug("frame %d, %d, %dx%d", x, y, w, h);
- stream->skip(50);
+ uint unk1 = stream->readUint32LE();
+ uint unk2 = stream->readUint32LE();
+ uint unk3 = stream->readUint32LE();
+ uint unk4 = stream->readUint32LE(); //GRP file offset?
+ uint unk5 = stream->readUint32LE();
+ uint unk6 = stream->readByte();
+ uint unk7 = stream->readUint32LE();
+ uint unk8 = stream->readUint32LE();
+ stream->readUint32LE(); //CDCDCDCD
+ uint unk9 = stream->readUint32LE();
+ uint unk10 = stream->readUint32LE();
+ stream->readUint32LE(); //CDCDCDCD
+ uint unk11 = stream->readByte();
+ stream->readUint32LE(); //CDCDCDCD
+ debug("unknown: %u %u %u 0x%08x - %u %u %u %u - %u %u %u",
+ unk1, unk2, unk3, unk4,
+ unk5, unk6, unk7, unk8,
+ unk9, unk10, unk11
+ );
}
_animations.push_back(animation);
}
Commit: c973a81a8f60aedc749ea1b82e0f76a47ffbb320
https://github.com/scummvm/scummvm/commit/c973a81a8f60aedc749ea1b82e0f76a47ffbb320
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:28+01:00
Commit Message:
AGDS: add _movementDirection
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 17e4e03add3..ab4e19e1867 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -38,13 +38,12 @@ void Character::load(Common::SeekableReadStream* stream) {
debug("loading character...");
stream->readUint32LE(); //unk
uint16 magic = stream->readUint16LE();
- uint n;
switch(magic) {
case 0xdead:
- n = 16;
+ _movementDirections = 16;
break;
case 0x8888:
- n = 8;
+ _movementDirections = 8;
break;
default:
error("invalid magic %04x", magic);
diff --git a/engines/agds/character.h b/engines/agds/character.h
index ba1b95d6f6e..4e2bfbf28d9 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -51,6 +51,7 @@ class Character {
int _phase;
int _frames;
int _direction;
+ int _movementDirections;
struct AnimationDescription {
struct Frame {
@@ -65,7 +66,7 @@ class Character {
public:
Character(AGDSEngine * engine, const Common::String & name, const ObjectPtr & object):
- _engine(engine), _name(name), _object(object), _animation(nullptr), _enabled(true), _visible(true), _phase(-1), _frames(0), _direction(-1) {
+ _engine(engine), _name(name), _object(object), _animation(nullptr), _enabled(true), _visible(true), _phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
}
const Common::String & name() const {
Commit: 25519ff10d7661dfee3f04d65f01ca15e33c00a1
https://github.com/scummvm/scummvm/commit/25519ff10d7661dfee3f04d65f01ca15e33c00a1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:28+01:00
Commit Message:
AGDS: add Character::getDirectionForMovement
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index ab4e19e1867..25596fcc228 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -32,25 +32,27 @@
#include "common/textconsole.h"
#include "common/util.h"
+#include <math.h>
+
namespace AGDS {
-void Character::load(Common::SeekableReadStream* stream) {
+void Character::load(Common::SeekableReadStream *stream) {
debug("loading character...");
stream->readUint32LE(); //unk
uint16 magic = stream->readUint16LE();
- switch(magic) {
- case 0xdead:
- _movementDirections = 16;
- break;
- case 0x8888:
- _movementDirections = 8;
- break;
- default:
- error("invalid magic %04x", magic);
+ switch (magic) {
+ case 0xdead:
+ _movementDirections = 16;
+ break;
+ case 0x8888:
+ _movementDirections = 8;
+ break;
+ default:
+ error("invalid magic %04x", magic);
}
_animations.clear();
- while(stream->pos() < stream->size()) {
+ while (stream->pos() < stream->size()) {
uint size = stream->readUint32LE();
uint index = stream->readUint16LE();
debug("header size %u, index: %u", size, index);
@@ -62,12 +64,12 @@ void Character::load(Common::SeekableReadStream* stream) {
AnimationDescription animation;
animation.filename = filename;
debug("animation %s, frames: %d, format: %d", animation.filename.c_str(), frames, format);
- while(frames--) {
+ while (frames--) {
int x = stream->readSint16LE();
int y = stream->readSint16LE();
int w = stream->readUint32LE();
int h = stream->readUint32LE();
- AnimationDescription::Frame frame = { x, y, w, h };
+ AnimationDescription::Frame frame = {x, y, w, h};
animation.frames.push_back(frame);
debug("frame %d, %d, %dx%d", x, y, w, h);
uint unk1 = stream->readUint32LE();
@@ -85,10 +87,9 @@ void Character::load(Common::SeekableReadStream* stream) {
uint unk11 = stream->readByte();
stream->readUint32LE(); //CDCDCDCD
debug("unknown: %u %u %u 0x%08x - %u %u %u %u - %u %u %u",
- unk1, unk2, unk3, unk4,
- unk5, unk6, unk7, unk8,
- unk9, unk10, unk11
- );
+ unk1, unk2, unk3, unk4,
+ unk5, unk6, unk7, unk8,
+ unk9, unk10, unk11);
}
_animations.push_back(animation);
}
@@ -128,7 +129,7 @@ void Character::animate(Common::Point pos, int frames, int speed) {
_pos = pos;
}
-void Character::paint(Graphics::Surface & backbuffer) {
+void Character::paint(Graphics::Surface &backbuffer) {
if (!_enabled || !_visible || !_animation)
return;
@@ -152,4 +153,100 @@ void Character::paint(Graphics::Surface & backbuffer) {
_animation->paint(*_engine, backbuffer, pos);
}
+int Character::getDirectionForMovement(int dx, int dy) {
+ auto angle = atan2(dy, dx);
+ if (angle < 0)
+ angle += M_PI * 2;
+
+ if (_movementDirections == 16) {
+ if (angle < 6.1850053125 && angle > 0.0981746875) {
+ if (angle > 0.5235983333333333) {
+ if (angle > 0.9490219791666666) {
+ if (angle > 1.374445625) {
+ if (angle > 1.767144375) {
+ if (angle > 2.192568020833333) {
+ if (angle > 2.617991666666666) {
+ if (angle > 3.0434153125) {
+ if (angle > 3.2397646875) {
+ if (angle > 3.665188333333333) {
+ if (angle > 4.090611979166667) {
+ if (angle > 4.516035625) {
+ if (angle > 4.908734375) {
+ if (angle > 5.334158020833333) {
+ if (angle > 5.759581666666667)
+ return 3;
+ else
+ return 2;
+ } else {
+ return 1;
+ }
+ } else {
+ return 0;
+ }
+ } else {
+ return 15;
+ }
+ } else {
+ return 14;
+ }
+ } else {
+ return 13;
+ }
+ } else {
+ return 12;
+ }
+ } else {
+ return 11;
+ }
+ } else {
+ return 10;
+ }
+ } else {
+ return 9;
+ }
+ } else {
+ return 8;
+ }
+ } else {
+ return 7;
+ }
+ } else {
+ return 6;
+ }
+ } else {
+ return 5;
+ }
+ } else {
+ return 4;
+ }
+ } else if (angle < 5.89048125 && angle > 0.39269875) {
+ if (angle > 1.17809625) {
+ if (angle > 1.96349375) {
+ if (angle > 2.74889125) {
+ if (angle > 3.53428875) {
+ if (angle > 4.31968625) {
+ if (angle > 5.105083749999999)
+ return 2;
+ else
+ return 0;
+ } else {
+ return 14;
+ }
+ } else {
+ return 12;
+ }
+ } else {
+ return 10;
+ }
+ } else {
+ return 8;
+ }
+ } else {
+ return 6;
+ }
+ } else {
+ return 4;
+ }
}
+
+} // namespace AGDS
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 4e2bfbf28d9..fe0e07ad107 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -112,6 +112,7 @@ public:
void paint(Graphics::Surface & backbuffer);
+ int getDirectionForMovement(int dx, int dy);
};
Commit: a0ce0dd3cfe9c2c109c33b266dd0876c09f55bb3
https://github.com/scummvm/scummvm/commit/a0ce0dd3cfe9c2c109c33b266dd0876c09f55bb3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:29+01:00
Commit Message:
AGDS: better resume/restart handling
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 7157378059e..d151342d207 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -30,7 +30,7 @@
namespace AGDS {
-Animation::Animation() : _flic(), _frame(), _frames(0), _loop(false), _cycles(1), _phaseVarControlled(false), _frameIndex(0), _paused(false), _resumed(false), _speed(100), _z(0), _delay(-1), _random(0) {
+Animation::Animation() : _flic(), _frame(), _frames(0), _loop(false), _cycles(1), _phaseVarControlled(false), _frameIndex(0), _paused(false), _speed(100), _z(0), _delay(-1), _random(0) {
}
Animation::~Animation() {
@@ -86,11 +86,9 @@ bool Animation::tick(AGDSEngine &engine) {
return true;
}
- if (!_frame && _phaseVarControlled && !_resumed)
+ if (!_frame && _phaseVarControlled)
return true;
- _resumed = false;
-
if (_delay > 0) {
--_delay;
return true;
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index db204ca20bf..f21d2af23fc 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -47,7 +47,6 @@ class Animation {
bool _phaseVarControlled;
int _frameIndex;
bool _paused;
- bool _resumed;
int _speed;
int _z;
int _delay;
@@ -116,7 +115,6 @@ public:
void resume() {
_paused = false;
- _resumed = true;
}
void rewind();
@@ -138,6 +136,12 @@ public:
int width() const;
int height() const;
bool tick(AGDSEngine &engine);
+
+ void decodeNextFrameIfNoFrame(AGDSEngine &engine) {
+ if (!_frame)
+ decodeNextFrame(engine);
+ }
+
private:
void decodeNextFrame(AGDSEngine &engine);
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 9252e3a1f9b..0a1a49f044d 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -836,6 +836,7 @@ void Process::restartAnimation() {
animation->rewind();
}
animation->resume();
+ animation->decodeNextFrameIfNoFrame(*_engine);
_engine->setGlobal(phaseVar, animation->frameIndex());
} else {
warning("no animation with phase var %s found", phaseVar.c_str());
Commit: 20e3b2dfc368549dde89ea4eb32b6e0a01496310
https://github.com/scummvm/scummvm/commit/20e3b2dfc368549dde89ea4eb32b6e0a01496310
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:29+01:00
Commit Message:
AGDS: add Screen::setCharacterZNearFar
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index bee1082f5c9..f7396c3a388 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -92,7 +92,7 @@ enum Opcode {
kSetObjectZ = 71,
kUpdateScreenHeightToDisplay = 72,
kLoadTextFromObject = 73,
- kScreenSetHeight = 74,
+ kScreenSetZNearFar = 74,
kScreenLoadRegion = 75,
kScreenLoadObject = 76,
kScreenCloneObject = 77,
@@ -349,7 +349,7 @@ enum Opcode {
OP(kSetObjectZ, setObjectZ) \
OP(kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay) \
OP(kLoadTextFromObject, loadTextFromObject) \
- OP(kScreenSetHeight, setScreenHeight) \
+ OP(kScreenSetZNearFar, screenSetZNearFar) \
OP(kScreenLoadObject, loadScreenObject) \
OP(kScreenLoadRegion, loadScreenRegion) \
OP(kScreenCloneObject, cloneObject) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 0a1a49f044d..e3b886baf47 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -554,10 +554,11 @@ void Process::onObjectUserUse(uint16 size) {
_ip += size;
}
-void Process::setScreenHeight() {
+void Process::screenSetZNearFar() {
int arg2 = pop();
int arg1 = pop();
- debug("setScreenHeight: %d %d", arg1, arg2);
+ debug("screenSetCharacterZNearFar: %d %d", arg1, arg2);
+ _engine->getCurrentScreen()->setCharacterNearFar(arg1, arg2);
}
void Process::setDelay() {
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 3703d822ccf..1503913f093 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -26,6 +26,7 @@
#include "agds/object.h"
#include "agds/patch.h"
#include "agds/region.h"
+#include "common/system.h"
namespace AGDS {
@@ -38,7 +39,8 @@ int Screen::AnimationZCompare(const Animation *a, const Animation *b) {
}
Screen::Screen(ObjectPtr object) : _object(object), _name(object->getName()),
- _children(&ObjectZCompare), _animations(&AnimationZCompare), _applyingPatch(false) {
+ _children(&ObjectZCompare), _animations(&AnimationZCompare), _applyingPatch(false),
+ _characterNear(g_system->getHeight()), _characterFar(g_system->getHeight()) {
add(object);
}
@@ -46,6 +48,19 @@ Screen::~Screen() {
_children.clear();
}
+float Screen::getZScale(int y) const
+{
+ int dy = g_system->getHeight() - y;
+ if (dy > _characterNear) {
+ if (dy < _characterFar)
+ return 1.0f * (_characterFar - y) / (_characterFar - _characterNear);
+ else
+ return 0.0f;
+ } else
+ return 1.0f;
+}
+
+
bool Screen::add(ObjectPtr object) {
if (object == NULL) {
warning("refusing to add null to scene");
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 0462c326700..df5a09886a2 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -57,6 +57,7 @@ class Screen {
AnimationsType _animations;
RegionPtr _region;
bool _applyingPatch;
+ int _characterNear, _characterFar;
public:
struct KeyHandler {
@@ -70,6 +71,13 @@ public:
Screen(ObjectPtr object);
~Screen();
+ void setCharacterNearFar(int near, int far) {
+ _characterNear = near;
+ _characterFar = far;
+ }
+
+ float getZScale(int y) const;
+
bool applyingPatch() const {
return _applyingPatch;
}
Commit: 0810dd577780cb0d01b82ded6bcbf51811b40218
https://github.com/scummvm/scummvm/commit/0810dd577780cb0d01b82ded6bcbf51811b40218
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:29+01:00
Commit Message:
AGDS: implement z-scaling for character
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/character.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index d151342d207..1f094e6b2c6 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -30,7 +30,10 @@
namespace AGDS {
-Animation::Animation() : _flic(), _frame(), _frames(0), _loop(false), _cycles(1), _phaseVarControlled(false), _frameIndex(0), _paused(false), _speed(100), _z(0), _delay(-1), _random(0) {
+Animation::Animation() :
+ _flic(), _frame(), _frames(0), _loop(false), _cycles(1), _phaseVarControlled(false),
+ _frameIndex(0), _paused(false), _speed(100), _z(0),
+ _delay(-1), _random(0), _scale(1) {
}
Animation::~Animation() {
@@ -72,6 +75,13 @@ void Animation::decodeNextFrame(AGDSEngine &engine) {
}
freeFrame();
_frame = engine.convertToTransparent(frame->convertTo(engine.pixelFormat(), _flic->getPalette()));
+ if (_scale != 1) {
+ auto f = _frame->scale(_frame->w * _scale, _frame->h * _scale, true);
+ if (f) {
+ delete _frame;
+ _frame = f;
+ }
+ }
++_frameIndex;
}
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index f21d2af23fc..a01fc0de344 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -51,6 +51,7 @@ class Animation {
int _z;
int _delay;
int _random;
+ float _scale;
public:
Animation();
@@ -131,6 +132,10 @@ public:
return _z;
}
+ void scale(float scale) {
+ _scale = scale;
+ }
+
bool load(Common::SeekableReadStream *stream);
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Common::Point dst);
int width() const;
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 25596fcc228..8b2a2946f36 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -135,6 +135,8 @@ void Character::paint(Graphics::Surface &backbuffer) {
Common::Point pos = _pos;
if (_phase >= 0 && _phase < _frames) {
+ auto screen = _engine->getCurrentScreen();
+ _animation->scale(screen? screen->getZScale(_pos.y): 1);
_animation->tick(*_engine);
if (_phase + 1 >= _frames) {
_phase = -1;
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 1503913f093..a4d69ec6e14 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -53,7 +53,7 @@ float Screen::getZScale(int y) const
int dy = g_system->getHeight() - y;
if (dy > _characterNear) {
if (dy < _characterFar)
- return 1.0f * (_characterFar - y) / (_characterFar - _characterNear);
+ return 1.0f * (_characterFar - dy) / (_characterFar - _characterNear);
else
return 0.0f;
} else
Commit: 4a32865afcfd6df765eea57a17bfadf16ab40d4e
https://github.com/scummvm/scummvm/commit/4a32865afcfd6df765eea57a17bfadf16ab40d4e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:29+01:00
Commit Message:
AGDS: implement animation speed
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/character.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 1f094e6b2c6..50eab5e7da9 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -32,7 +32,7 @@ namespace AGDS {
Animation::Animation() :
_flic(), _frame(), _frames(0), _loop(false), _cycles(1), _phaseVarControlled(false),
- _frameIndex(0), _paused(false), _speed(100), _z(0),
+ _phase(0), _paused(false), _speed(100), _z(0),
_delay(-1), _random(0), _scale(1) {
}
@@ -82,12 +82,11 @@ void Animation::decodeNextFrame(AGDSEngine &engine) {
_frame = f;
}
}
- ++_frameIndex;
}
void Animation::rewind() {
freeFrame();
- _frameIndex = 0;
+ _phase = 0;
_flic->rewind();
}
@@ -108,7 +107,9 @@ bool Animation::tick(AGDSEngine &engine) {
debug("phase var %s signalled deleting of animation", _phaseVar.c_str());
return false;
}
- if (_frameIndex >= _frames && !_loop) {
+
+ int frame = frameIndex();
+ if (frame >= _frames && !_loop) {
if (!_phaseVar.empty()) {
engine.setGlobal(_phaseVar, -1);
} else {
@@ -120,12 +121,17 @@ bool Animation::tick(AGDSEngine &engine) {
}
return false;
}
- decodeNextFrame(engine);
+
+ for(int begin = frame, end = frameIndex(1); begin < end; ++begin) {
+ decodeNextFrame(engine);
+ }
+
if (!_process.empty()) {
if (!_phaseVar.empty()) {
- engine.setGlobal(_phaseVar, _frameIndex - 1);
+ engine.setGlobal(_phaseVar, _phase);
}
}
+ ++_phase;
return true;
}
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index a01fc0de344..d249be84d46 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -45,7 +45,7 @@ class Animation {
bool _loop;
int _cycles;
bool _phaseVarControlled;
- int _frameIndex;
+ int _phase;
bool _paused;
int _speed;
int _z;
@@ -74,9 +74,6 @@ public:
void phaseVar(const Common::String & phaseVar) {
_phaseVar = phaseVar;
}
- int frameIndex() const {
- return _frameIndex;
- }
const Common::String & process() const {
return _process;
@@ -136,6 +133,14 @@ public:
_scale = scale;
}
+ int phase() const {
+ return _phase;
+ }
+
+ int frameIndex(int delta = 0) const {
+ return (_phase + delta) * _speed / 100;
+ }
+
bool load(Common::SeekableReadStream *stream);
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Common::Point dst);
int width() const;
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 8b2a2946f36..5158e2de740 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -123,7 +123,9 @@ void Character::animate(Common::Point pos, int frames, int speed) {
_phase = -1;
_frames = 0;
}
+ _animation->speed(speed);
_animation->loop(true);
+ _animation->rewind();
_phase = 0;
_frames = frames;
_pos = pos;
Commit: e42dbeb7509e09985085b23ff860847aa1431685
https://github.com/scummvm/scummvm/commit/e42dbeb7509e09985085b23ff860847aa1431685
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:29+01:00
Commit Message:
AGDS: ignore case while checking prefix for dialog sounds
Changed paths:
engines/agds/dialog.cpp
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 094622ea921..75ff6e79969 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -173,7 +173,7 @@ Common::String Dialog::getNextDialogSound() {
uint it;
for(it = 0; it < _sounds.size(); ++it) {
auto & sound = _sounds[it];
- if (_currentDef.hasPrefix(sound.Name))
+ if (_currentDef.hasPrefixIgnoreCase(sound.Name))
break;
}
if (it == _sounds.size())
Commit: f7c27550472e61ee162a5d0738332295878cef60
https://github.com/scummvm/scummvm/commit/f7c27550472e61ee162a5d0738332295878cef60
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:29+01:00
Commit Message:
AGDS: output proper sample name to logs
Changed paths:
engines/agds/dialog.cpp
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 75ff6e79969..c558814fbcf 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -195,7 +195,7 @@ Common::String Dialog::getNextDialogSound() {
if (carry != 0)
warning("sample index overflow, %s", sample.c_str());
- debug("returning sample name %s", sample.c_str());
+ debug("returning sample name %s", currentSample.c_str());
return currentSample + ".ogg";
}
Commit: 111c4a567b3f86b7e4c4a9b8c8e09ebf38e026c0
https://github.com/scummvm/scummvm/commit/111c4a567b3f86b7e4c4a9b8c8e09ebf38e026c0
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:29+01:00
Commit Message:
AGDS: implement direction notification
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/character.cpp
engines/agds/character.h
engines/agds/process_opcodes.cpp
engines/agds/textLayout.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 805a2d998d0..44e00d538a1 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -847,7 +847,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
auto character = getCharacter(id);
if (character) {
character->position(Common::Point(x, y));
- character->setDirection(dir);
+ character->direction(dir);
} else
warning("no character");
int n = 2;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index dd93df57447..db9ed610611 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -178,6 +178,9 @@ public:
Character * getCharacter(const Common::String &name) {
return _currentCharacterName == name? _currentCharacter: nullptr;
}
+ Character * currentCharacter() const {
+ return _currentCharacter;
+ }
void loadDefaultMouseCursor(const Common::String &name) {
_defaultMouseCursorName = name;
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 5158e2de740..8ea1652071d 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -97,7 +97,7 @@ void Character::load(Common::SeekableReadStream *stream) {
delete stream;
}
-void Character::setDirection(int dir) {
+void Character::direction(int dir) {
debug("setDirection %d", dir);
_direction = dir;
_animation = _engine->loadAnimation(_animations[dir].filename);
diff --git a/engines/agds/character.h b/engines/agds/character.h
index fe0e07ad107..dc9d8582a25 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -108,7 +108,11 @@ public:
void moveTo(Common::Point dst, int frames);
- void setDirection(int dir);
+ void direction(int dir);
+
+ int direction() const {
+ return _direction;
+ }
void paint(Graphics::Surface & backbuffer);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index e3b886baf47..4a9818284cb 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1320,7 +1320,7 @@ void Process::setCharacter() {
character->position(region->center);
} else
warning("no region %s", regionName.c_str());
- character->setDirection(dir);
+ character->direction(dir);
} else
warning("no character %s", id.c_str());
}
@@ -1468,8 +1468,9 @@ void Process::setCharacterNotifyVars() {
Common::String arg1 = popString();
debug("setCharacterNotifyVars, tell: %s, direction: %s", arg1.c_str(), arg2.c_str());
+ auto character = _engine->currentCharacter();
_engine->setGlobal(arg1, 0);
- _engine->setGlobal(arg2, 0); //FIXME: pass current direction
+ _engine->setGlobal(arg2, character? character->direction(): 0);
_engine->textLayout().setCharNotifyVar(arg1);
_engine->textLayout().setCharDirectionNotifyVar(arg2);
}
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 9ab8378cf3b..4ada68738fe 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -1,6 +1,7 @@
#include "agds/textLayout.h"
#include "agds/font.h"
#include "agds/agds.h"
+#include "agds/character.h"
#include "agds/object.h"
#include "common/debug.h"
@@ -26,6 +27,9 @@ void TextLayout::reset(AGDSEngine &engine) {
if (!var.empty()) {
engine.setGlobal(var, 0);
}
+ if (!_charDirectionNotifyVar.empty()) {
+ engine.setGlobal(_charDirectionNotifyVar, 0);
+ }
engine.reactivate(_process);
}
}
@@ -85,6 +89,16 @@ void TextLayout::layout(AGDSEngine &engine, const Common::String &process, const
if (!engine.getGlobal(var))
engine.setGlobal(var, 1);
}
+ auto character = engine.currentCharacter();
+ if (character) {
+ if (!_charDirectionNotifyVar.empty()) {
+ if (!engine.getGlobal(_charDirectionNotifyVar))
+ engine.setGlobal(_charDirectionNotifyVar, character->direction());
+ } else {
+ warning("fixme: playing jokes.chr animation for direction %d", character->direction());
+ }
+ } else
+ warning("no current character, skipping direction notification");
}
}
Commit: dd9ec5827ddc487f6ba8f9fe90941665c105173f
https://github.com/scummvm/scummvm/commit/dd9ec5827ddc487f6ba8f9fe90941665c105173f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:29+01:00
Commit Message:
AGDS: load jokes.chr/animateCharacter
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/animation.h
engines/agds/character.cpp
engines/agds/character.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 44e00d538a1..51f794d0316 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -63,6 +63,7 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
}
AGDSEngine::~AGDSEngine() {
+ delete _jokes;
delete _currentCharacter;
delete _currentScreen;
for (PictureCacheType::iterator i = _pictureCache.begin(); i != _pictureCache.end(); ++i) {
@@ -121,12 +122,20 @@ bool AGDSEngine::load() {
initSystemVariables();
_nextScreenName = "main";
- Common::File file;
- file.open("patch.adb");
- Database patch;
- patch.open("patch.adb");
+ {
+ Common::File file;
+ file.open("patch.adb");
+ Database patch;
+ patch.open("patch.adb");
- loadPatches(&file, patch);
+ loadPatches(&file, patch);
+ }
+ {
+ Common::File * file = new Common::File();
+ file->open("jokes.chr");
+ _jokes = new Character(this, "jokes", ObjectPtr());
+ _jokes->load(file);
+ }
return true;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index db9ed610611..08f9feeb727 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -181,6 +181,9 @@ public:
Character * currentCharacter() const {
return _currentCharacter;
}
+ Character * jokes() const {
+ return _jokes;
+ }
void loadDefaultMouseCursor(const Common::String &name) {
_defaultMouseCursorName = name;
@@ -277,6 +280,7 @@ private:
Screen * _currentScreen;
Common::String _currentScreenName;
Character * _currentCharacter;
+ Character * _jokes;
Common::String _currentCharacterName;
Common::String _nextScreenName;
Common::String _previousScreenName;
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index d249be84d46..0b3c421e03d 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -59,6 +59,10 @@ public:
void freeFrame();
+ int frames() const {
+ return _frames;
+ }
+
const Common::Point & position() const {
return _position;
}
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 8ea1652071d..ce4f24524e1 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -63,7 +63,7 @@ void Character::load(Common::SeekableReadStream *stream) {
AnimationDescription animation;
animation.filename = filename;
- debug("animation %s, frames: %d, format: %d", animation.filename.c_str(), frames, format);
+ debug("%u: animation %s, frames: %d, format: %d", _animations.size(), animation.filename.c_str(), frames, format);
while (frames--) {
int x = stream->readSint16LE();
int y = stream->readSint16LE();
@@ -110,24 +110,26 @@ void Character::direction(int dir) {
}
void Character::moveTo(Common::Point dst, int frames) {
- debug("move to %d,%d", dst.x, dst.y);
_dst = dst;
_phase = 0;
_frames = frames;
}
-void Character::animate(Common::Point pos, int frames, int speed) {
- _animation = _engine->loadAnimation(_animations[_direction].filename);
+void Character::animate(Common::Point pos, int direction, int speed) {
+ auto jokes = _engine->jokes();
+ auto animationDescription = jokes->animationDescription(direction);
+ _animation = animationDescription? _engine->loadAnimation(animationDescription->filename): nullptr;
if (!_animation) {
- debug("no animation?");
+ warning("no jokes animation %d", direction);
_phase = -1;
_frames = 0;
+ return;
}
_animation->speed(speed);
_animation->loop(true);
_animation->rewind();
_phase = 0;
- _frames = frames;
+ _frames = speed * _animation->frames() / 100;
_pos = pos;
}
diff --git a/engines/agds/character.h b/engines/agds/character.h
index dc9d8582a25..c5e6d21f02e 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -69,6 +69,10 @@ public:
_engine(engine), _name(name), _object(object), _animation(nullptr), _enabled(true), _visible(true), _phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
}
+ const AnimationDescription * animationDescription(uint index) const {
+ return index < _animations.size()? &_animations[index]: nullptr;
+ }
+
const Common::String & name() const {
return _name;
}
@@ -87,7 +91,7 @@ public:
_visible = visible;
}
- void animate(Common::Point pos, int frames, int speed);
+ void animate(Common::Point pos, int direction, int speed);
void stop() {
_phase = 0;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4a9818284cb..cd1748dff8d 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1261,13 +1261,13 @@ void Process::moveCharacterNoUserMove() {
}
void Process::animateCharacter() {
- int frames = pop();
+ int direction = pop();
Common::String name = popString();
- debug("animateCharacter: %s %d %d", name.c_str(), frames, _animationSpeed);
+ debug("animateCharacter: %s %d %d", name.c_str(), direction, _animationSpeed);
Character *character = _engine->getCharacter(name);
if (character)
- character->animate(_animationPosition, frames, _animationSpeed);
+ character->animate(_animationPosition, direction, _animationSpeed);
else
warning("character %s could not be found", name.c_str());
}
Commit: 79404a0b4521f77471b79665803dec16be67c822
https://github.com/scummvm/scummvm/commit/79404a0b4521f77471b79665803dec16be67c822
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:29+01:00
Commit Message:
AGDS: add _animationPos and fix zeroing of character position
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index ce4f24524e1..66b664b1035 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -101,6 +101,7 @@ void Character::direction(int dir) {
debug("setDirection %d", dir);
_direction = dir;
_animation = _engine->loadAnimation(_animations[dir].filename);
+ _animationPos = Common::Point();
if (!_animation) {
debug("no animation?");
_phase = -1;
@@ -130,14 +131,14 @@ void Character::animate(Common::Point pos, int direction, int speed) {
_animation->rewind();
_phase = 0;
_frames = speed * _animation->frames() / 100;
- _pos = pos;
+ _animationPos = pos;
}
void Character::paint(Graphics::Surface &backbuffer) {
if (!_enabled || !_visible || !_animation)
return;
- Common::Point pos = _pos;
+ Common::Point pos = _pos + _animationPos;
if (_phase >= 0 && _phase < _frames) {
auto screen = _engine->getCurrentScreen();
_animation->scale(screen? screen->getZScale(_pos.y): 1);
diff --git a/engines/agds/character.h b/engines/agds/character.h
index c5e6d21f02e..33281114b59 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -45,6 +45,7 @@ class Character {
Animation * _animation;
Common::String _name;
Common::Point _pos;
+ Common::Point _animationPos;
Common::Point _dst;
bool _enabled;
bool _visible;
Commit: f02d4a0478f89ddf7691e57467add53ea3fcfc93
https://github.com/scummvm/scummvm/commit/f02d4a0478f89ddf7691e57467add53ea3fcfc93
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:29+01:00
Commit Message:
AGDS: implement direction check for default jokes animation
Changed paths:
engines/agds/textLayout.cpp
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 4ada68738fe..e10a6641a75 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -95,7 +95,18 @@ void TextLayout::layout(AGDSEngine &engine, const Common::String &process, const
if (!engine.getGlobal(_charDirectionNotifyVar))
engine.setGlobal(_charDirectionNotifyVar, character->direction());
} else {
- warning("fixme: playing jokes.chr animation for direction %d", character->direction());
+ switch(character->direction()) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 13:
+ case 14:
+ case 15:
+ break;
+ default:
+ warning("implement replaying current jokes animation");
+ }
}
} else
warning("no current character, skipping direction notification");
Commit: b6cc6bb87034bfddd92d8b0e917919acd143b368
https://github.com/scummvm/scummvm/commit/b6cc6bb87034bfddd92d8b0e917919acd143b368
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:30+01:00
Commit Message:
AGDS: remove loop flags from character animation
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 66b664b1035..644a04cccf4 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -107,7 +107,6 @@ void Character::direction(int dir) {
_phase = -1;
_frames = 0;
}
- _animation->loop(true);
}
void Character::moveTo(Common::Point dst, int frames) {
@@ -127,7 +126,6 @@ void Character::animate(Common::Point pos, int direction, int speed) {
return;
}
_animation->speed(speed);
- _animation->loop(true);
_animation->rewind();
_phase = 0;
_frames = speed * _animation->frames() / 100;
Commit: f71af6692fc51ac5d1c6313b5b9c1cc8343b6dad
https://github.com/scummvm/scummvm/commit/f71af6692fc51ac5d1c6313b5b9c1cc8343b6dad
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:30+01:00
Commit Message:
AGDS: calculate max frames for jokes based on speed
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 644a04cccf4..eb34c6e91af 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -128,7 +128,7 @@ void Character::animate(Common::Point pos, int direction, int speed) {
_animation->speed(speed);
_animation->rewind();
_phase = 0;
- _frames = speed * _animation->frames() / 100;
+ _frames = (100 * _animation->frames() + speed - 1) / speed;
_animationPos = pos;
}
Commit: 45641716cefd3010693b678d4bf064eb7bfc8932
https://github.com/scummvm/scummvm/commit/45641716cefd3010693b678d4bf064eb7bfc8932
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:30+01:00
Commit Message:
AGDS: do not reset character direction
Changed paths:
engines/agds/textLayout.cpp
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index e10a6641a75..04c623420a4 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -27,9 +27,6 @@ void TextLayout::reset(AGDSEngine &engine) {
if (!var.empty()) {
engine.setGlobal(var, 0);
}
- if (!_charDirectionNotifyVar.empty()) {
- engine.setGlobal(_charDirectionNotifyVar, 0);
- }
engine.reactivate(_process);
}
}
Commit: 12ece6aa19c32cd001851ae7b7e8a6b2656b9e37
https://github.com/scummvm/scummvm/commit/12ece6aa19c32cd001851ae7b7e8a6b2656b9e37
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:30+01:00
Commit Message:
AGDS: implement setPeriodic semi-stub
Changed paths:
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index f7396c3a388..db723eae640 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -368,6 +368,7 @@ enum Opcode {
OP(kSetAnimationZ, setAnimationZ) \
OP(kSetCycles, setCycles) \
OP(kSetRandom, setRandom) \
+ OP(kSetPeriodic, setPeriodic) \
OP(kSetPanAndVolume, setPanAndVolume) \
OP(kSetAnimationPosition, setAnimationPosition) \
OP(kSetPhaseVar, setPhaseVar) \
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index e819ba81e50..79b409a4940 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -32,7 +32,8 @@ Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) : _engine(en
_status(kStatusActive), _exitCode(kExitCodeDestroy),
_tileWidth(16), _tileHeight(16), _tileResource(0), _tileIndex(0),
_timer(0),
- _animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0), _phaseVarControlled(false), _animationSpeed(100)
+ _animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0),
+ _phaseVarControlled(false), _animationSpeed(100), _samplePeriodic(false)
{
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 5fc4f3a8578..89e2f349083 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -64,6 +64,7 @@ private:
int _animationRandom;
bool _phaseVarControlled;
int _animationSpeed;
+ bool _samplePeriodic;
Common::Point _mousePosition;
private:
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index cd1748dff8d..4ceba6a4651 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -579,6 +579,12 @@ void Process::setRandom() {
_animationRandom = value;
}
+void Process::setPeriodic() {
+ int value = pop();
+ debug("setPeriodic %d", value);
+ _samplePeriodic = value;
+}
+
void Process::stub82() {
Common::String arg2 = popString();
Common::String arg1 = popString();
@@ -611,6 +617,8 @@ void Process::resetState() {
_animationZ = 0;
_animationRandom = 0;
_animationDelay = -1;
+ _animationSpeed = 100;
+ _samplePeriodic = false;
_tileWidth = 16;
_tileHeight = 16;
Commit: 27c1e079b48e9ee41425506d54f198963de3ff27
https://github.com/scummvm/scummvm/commit/27c1e079b48e9ee41425506d54f198963de3ff27
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:30+01:00
Commit Message:
AGDS: remove rewind() from decodeNextFrame
Changed paths:
engines/agds/animation.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 50eab5e7da9..6695bfc886a 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -67,12 +67,9 @@ bool Animation::load(Common::SeekableReadStream *stream) {
void Animation::decodeNextFrame(AGDSEngine &engine) {
auto frame = _flic->decodeNextFrame();
- if (!frame) {
- rewind();
- frame = _flic->decodeNextFrame();
- if (!frame)
- error("failed decoding frame after rewind");
- }
+ if (!frame)
+ return;
+
freeFrame();
_frame = engine.convertToTransparent(frame->convertTo(engine.pixelFormat(), _flic->getPalette()));
if (_scale != 1) {
Commit: f519975c023866cd98543f7d36996bf7ace85295
https://github.com/scummvm/scummvm/commit/f519975c023866cd98543f7d36996bf7ace85295
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:30+01:00
Commit Message:
VIDEO: add VideoDecoder::getCurFrameDelay()
Changed paths:
video/flic_decoder.h
video/video_decoder.cpp
video/video_decoder.h
diff --git a/video/flic_decoder.h b/video/flic_decoder.h
index fd2a35b07d3..c0510d0e983 100644
--- a/video/flic_decoder.h
+++ b/video/flic_decoder.h
@@ -73,8 +73,9 @@ protected:
uint16 getWidth() const;
uint16 getHeight() const;
Graphics::PixelFormat getPixelFormat() const;
- int getCurFrame() const { return _curFrame; }
- int getFrameCount() const { return _frameCount; }
+ int getCurFrame() const override { return _curFrame; }
+ int getCurFrameDelay() const override { return _frameDelay; }
+ int getFrameCount() const override { return _frameCount; }
uint32 getNextFrameStartTime() const { return _nextFrameStartTime; }
virtual const Graphics::Surface *decodeNextFrame();
virtual void handleFrame();
diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp
index 6c5f81b1e0a..befb697a2cb 100644
--- a/video/video_decoder.cpp
+++ b/video/video_decoder.cpp
@@ -266,6 +266,17 @@ int VideoDecoder::getCurFrame() const {
return frame;
}
+int VideoDecoder::getCurFrameDelay() const {
+ int32 frame = -1;
+
+ for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo)
+ frame += ((VideoTrack *)*it)->getCurFrameDelay() + 1;
+
+ return frame;
+}
+
+
uint32 VideoDecoder::getFrameCount() const {
int count = 0;
diff --git a/video/video_decoder.h b/video/video_decoder.h
index 05262931c2d..50318286603 100644
--- a/video/video_decoder.h
+++ b/video/video_decoder.h
@@ -250,6 +250,12 @@ public:
*/
int getCurFrame() const;
+ /**
+ * Returns the current frame delay of the video.
+ * @return the last frame decoded by the video
+ */
+ int getCurFrameDelay() const;
+
/**
* Returns the number of frames in the video.
* @return the number of frames in the video
@@ -626,6 +632,15 @@ protected:
*/
virtual int getCurFrame() const = 0;
+ /**
+ * Get the current frame delay of this track
+ *
+ * @see VideoDecoder::getCurFrameDelay()
+ */
+ virtual int getCurFrameDelay() const {
+ return 0;
+ };
+
/**
* Get the frame count of this track
*
Commit: a62cd544731465bb0dfaa6ab26ba73a42ca97db2
https://github.com/scummvm/scummvm/commit/a62cd544731465bb0dfaa6ab26ba73a42ca97db2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:30+01:00
Commit Message:
AGDS: readd runNow flag for reactivate()
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 51f794d0316..55f5cf0f55f 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -935,7 +935,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
return Common::kNoError;
}
-void AGDSEngine::reactivate(const Common::String &name) {
+void AGDSEngine::reactivate(const Common::String &name, bool runNow) {
if (name.empty())
return;
@@ -944,6 +944,8 @@ void AGDSEngine::reactivate(const Common::String &name) {
if (process && process->getName() == name) {
debug("reactivate %s", name.c_str());
process->activate();
+ if (runNow)
+ process->run();
}
}
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 08f9feeb727..6f3146d06f5 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -244,7 +244,7 @@ public:
return _mouse;
}
- void reactivate(const Common::String &name);
+ void reactivate(const Common::String &name, bool runNow = false);
private:
void loadPatches(Common::SeekableReadStream *file, Database & db);
Commit: 3670df0bb22d3359d047cc046a0ab957fc625024
https://github.com/scummvm/scummvm/commit/3670df0bb22d3359d047cc046a0ab957fc625024
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:30+01:00
Commit Message:
AGDS: another feeble attempt to rewrite animation
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/console.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 6695bfc886a..b3afad61f94 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -33,7 +33,7 @@ namespace AGDS {
Animation::Animation() :
_flic(), _frame(), _frames(0), _loop(false), _cycles(1), _phaseVarControlled(false),
_phase(0), _paused(false), _speed(100), _z(0),
- _delay(-1), _random(0), _scale(1) {
+ _delay(0), _random(0), _scale(1) {
}
Animation::~Animation() {
@@ -51,6 +51,29 @@ void Animation::freeFrame() {
bool Animation::load(Common::SeekableReadStream *stream) {
+ if (_phaseVarControlled) {
+ if (_phaseVar.empty()) {
+ warning("phase var controlled animation with no phase var");
+ _phaseVarControlled = false;
+ return false;
+ }
+ if (_loop) {
+ warning("phase var controller animation with loop, resetting");
+ _loop = false;
+ }
+ if (_cycles > 1) {
+ warning("phase var controller animation with cycles, resetting");
+ _cycles = 1;
+ }
+ if (_random) {
+ warning("phase var controller animation with random, resetting");
+ _random = false;
+ }
+ if (_delay > 0) {
+ warning("phase var controller animation with delay, resetting");
+ _delay = 0;
+ }
+ }
delete _flic;
Video::FlicDecoder *flic = new Video::FlicDecoder;
if (flic->loadStream(stream)) {
@@ -67,10 +90,13 @@ bool Animation::load(Common::SeekableReadStream *stream) {
void Animation::decodeNextFrame(AGDSEngine &engine) {
auto frame = _flic->decodeNextFrame();
- if (!frame)
+ if (!frame) {
+ warning("frame couldn't be decoded");
return;
+ }
freeFrame();
+ _delay = _flic->getCurFrameDelay() * _speed / 4000; //40 == 1000 / 25, 25 fps
_frame = engine.convertToTransparent(frame->convertTo(engine.pixelFormat(), _flic->getPalette()));
if (_scale != 1) {
auto f = _frame->scale(_frame->w * _scale, _frame->h * _scale, true);
@@ -79,6 +105,7 @@ void Animation::decodeNextFrame(AGDSEngine &engine) {
_frame = f;
}
}
+ ++_phase;
}
void Animation::rewind() {
@@ -88,47 +115,41 @@ void Animation::rewind() {
}
bool Animation::tick(AGDSEngine &engine) {
- if (_paused) {
+ if (_paused || (_phaseVarControlled && !_frame)) {
return true;
}
- if (!_frame && _phaseVarControlled)
- return true;
+ if (_phaseVarControlled && engine.getGlobal(_phaseVar) == -2) {
+ debug("phase var %s signalled deleting of animation", _phaseVar.c_str());
+ return false;
+ }
if (_delay > 0) {
--_delay;
return true;
}
- if (_phaseVarControlled && !_phaseVar.empty() && engine.getGlobal(_phaseVar) == -2) {
- debug("phase var %s signalled deleting of animation", _phaseVar.c_str());
- return false;
- }
-
- int frame = frameIndex();
- if (frame >= _frames && !_loop) {
- if (!_phaseVar.empty()) {
- engine.setGlobal(_phaseVar, -1);
- } else {
- engine.reactivate(_process);
+ bool eov = _flic->endOfVideo();
+ if (eov) {
+ if (!_loop) {
+ if (!_phaseVar.empty())
+ engine.setGlobal(_phaseVar, -1);
}
+
if (_phaseVarControlled) {
freeFrame();
+ engine.reactivate(_process, true);
return true;
}
return false;
}
- for(int begin = frame, end = frameIndex(1); begin < end; ++begin) {
- decodeNextFrame(engine);
- }
-
+ decodeNextFrame(engine);
if (!_process.empty()) {
if (!_phaseVar.empty()) {
- engine.setGlobal(_phaseVar, _phase);
+ engine.setGlobal(_phaseVar, _phase - 1);
}
}
- ++_phase;
return true;
}
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 0b3c421e03d..9d63ec74efb 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -59,6 +59,10 @@ public:
void freeFrame();
+ bool hasFrame() const {
+ return _frame != nullptr;
+ }
+
int frames() const {
return _frames;
}
@@ -141,16 +145,11 @@ public:
return _phase;
}
- int frameIndex(int delta = 0) const {
- return (_phase + delta) * _speed / 100;
- }
-
bool load(Common::SeekableReadStream *stream);
void paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Common::Point dst);
int width() const;
int height() const;
bool tick(AGDSEngine &engine);
-
void decodeNextFrameIfNoFrame(AGDSEngine &engine) {
if (!_frame)
decodeNextFrame(engine);
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index a32aad05f2e..fa3135b1f2d 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -72,7 +72,7 @@ bool Console::info(int argc, const char **argv) {
auto pos = animation->position();
debugPrintf("animation %s (process: %s, %s) at %d,%d,%d, frame: %d\n",
animation->phaseVar().c_str(), animation->process().c_str(), animation->paused()? "paused": "running",
- pos.x, pos.y, animation->z(), animation->frameIndex());
+ pos.x, pos.y, animation->z(), animation->phase());
}
}
debugPrintf("processes:\n");
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4ceba6a4651..605f8fd0b17 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -156,12 +156,6 @@ void Process::loadAnimation() {
debug("loadAnimation %s (phase: %s) %s", name.c_str(), _phaseVar.c_str(), _phaseVarControlled? "(phase-var)": "");
Animation *animation = _engine->loadAnimation(name);
if (animation) {
- if (_phaseVarControlled) {
- _animationLoop = false;
- _animationCycles = 0;
- _animationRandom = 0;
- _animationDelay = 0;
- }
setupAnimation(animation);
_engine->getCurrentScreen()->add(animation);
}
@@ -846,7 +840,7 @@ void Process::restartAnimation() {
}
animation->resume();
animation->decodeNextFrameIfNoFrame(*_engine);
- _engine->setGlobal(phaseVar, animation->frameIndex());
+ _engine->setGlobal(phaseVar, animation->phase() - 1);
} else {
warning("no animation with phase var %s found", phaseVar.c_str());
_engine->setGlobal(phaseVar, -1);
Commit: 98c3f4bf849086eec62a5eaeeb598f669e685f6f
https://github.com/scummvm/scummvm/commit/98c3f4bf849086eec62a5eaeeb598f669e685f6f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:30+01:00
Commit Message:
AGDS: use local dialog_var
Changed paths:
engines/agds/dialog.cpp
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index c558814fbcf..3be4ddde5aa 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -145,7 +145,7 @@ bool Dialog::tick() {
int value = it->_value;
debug("dialog value %s = %d (0x%04x)", line.c_str(), value, value);
_currentDef = line;
- _engine->getSystemVariable("dialog_var")->setInteger(value);
+ dialog_var->setInteger(value);
_engine->reactivate(_dialogProcessName);
} else
warning("invalid dialog directive: %s", line.c_str());
@@ -159,7 +159,7 @@ bool Dialog::tick() {
_dialogProcessName.clear();
debug("end of dialog, running %s", process.c_str());
- _engine->getSystemVariable("dialog_var")->setInteger(-2);
+ dialog_var->setInteger(-2);
_engine->reactivate(_dialogProcessName);
return false;
}
Commit: 08ec0de6e16a23de6d9d3551a04c3fe21ffeac48
https://github.com/scummvm/scummvm/commit/08ec0de6e16a23de6d9d3551a04c3fe21ffeac48
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:30+01:00
Commit Message:
AGDS: add play jokes animation fallback
Changed paths:
engines/agds/character.cpp
engines/agds/textLayout.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index eb34c6e91af..0b2c01d50d2 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -116,6 +116,9 @@ void Character::moveTo(Common::Point dst, int frames) {
}
void Character::animate(Common::Point pos, int direction, int speed) {
+ debug("animate character: %d,%d %d %d", pos.x, pos.y, direction, speed);
+ if (direction == -1)
+ return;
auto jokes = _engine->jokes();
auto animationDescription = jokes->animationDescription(direction);
_animation = animationDescription? _engine->loadAnimation(animationDescription->filename): nullptr;
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 04c623420a4..2aebcddbf4f 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -102,7 +102,7 @@ void TextLayout::layout(AGDSEngine &engine, const Common::String &process, const
case 15:
break;
default:
- warning("implement replaying current jokes animation");
+ character->animate(Common::Point(), character->direction(), 100);
}
}
} else
Commit: 09516335620382c172b88823ea8033a15cb190af
https://github.com/scummvm/scummvm/commit/09516335620382c172b88823ea8033a15cb190af
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:31+01:00
Commit Message:
AGDS: fix multiline dialog lines parsing
Changed paths:
engines/agds/dialog.cpp
engines/agds/textLayout.cpp
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 3be4ddde5aa..b8bf85e0471 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -94,10 +94,24 @@ bool Dialog::tick() {
Common::String &line = _dialogLine;
line.clear();
- while (_dialogScriptPos < n && _dialogScript[_dialogScriptPos] != '\n' && _dialogScript[_dialogScriptPos] != '\r') {
- line += _dialogScript[_dialogScriptPos++];
+
+ bool command = _dialogScript[_dialogScriptPos] == '@';
+ while(_dialogScriptPos < n) {
+ if (!command && _dialogScript[_dialogScriptPos] == '@')
+ break;
+
+ while (_dialogScriptPos < n && _dialogScript[_dialogScriptPos] != '\n' && _dialogScript[_dialogScriptPos] != '\r') {
+ line += _dialogScript[_dialogScriptPos++];
+ }
+ if (!command)
+ line += '\n';
+
+ while(_dialogScriptPos < n && (_dialogScript[_dialogScriptPos] == '\n' || _dialogScript[_dialogScriptPos] == '\r'))
+ ++_dialogScriptPos;
+
+ if (command)
+ break;
}
- ++_dialogScriptPos;
if (line.empty())
return true;
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 2aebcddbf4f..5b7bea7f287 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -48,7 +48,7 @@ void TextLayout::layout(AGDSEngine &engine, const Common::String &process, const
Common::Point basePos;
size_t begin = 0;
while(begin < text.size()) {
- while(begin < text.size() && text[begin]== '\r')
+ while(begin < text.size() && (text[begin]== '\r' || text[begin]== ' '))
++begin;
size_t end = text.find('\n', begin);
if (end == text.npos)
Commit: f0090c9a887af3063d7fbf9b9c91fd9bd07323f5
https://github.com/scummvm/scummvm/commit/f0090c9a887af3063d7fbf9b9c91fd9bd07323f5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:31+01:00
Commit Message:
AGDS: restored old inScene() flag behaviour
Changed paths:
engines/agds/agds.cpp
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 55f5cf0f55f..e735efe4623 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -171,17 +171,15 @@ ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::Strin
}
void AGDSEngine::runObject(const ObjectPtr &object) {
- if (_currentScreen)
+ if (_currentScreen) {
if (_currentScreen->add(object)) {
runProcess(object);
- } else {
+ } else if (!object->inScene()) {
debug("marking object %s as recovering...", object->getName().c_str());
- object->recovering(true);
+ object->inScene(true);
runProcess(object);
- object->recovering(false);
- debug("unmarking object %s as recovering...", object->getName().c_str());
}
- else
+ } else
warning("object %s has been loaded, but was not added to any screen", object->getName().c_str());
}
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 5ef309d8892..b4b18752a1e 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -39,7 +39,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_pos(), _z(10),
_clickHandler(0), _examineHandler(0),
_userUseHandler(0),
- _alpha(255), _inScene(false), _recovering(false) {
+ _alpha(255), _inScene(false) {
uint16 id = stream->readUint16LE();
debug("id: 0x%02x %u", id, id);
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 16aa79fef8a..e273398cf2a 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -76,7 +76,6 @@ private:
uint _userUseHandler;
int _alpha;
bool _inScene;
- bool _recovering;
public:
Object(const Common::String &name, Common::SeekableReadStream * stream);
@@ -201,12 +200,6 @@ public:
void inScene(bool value)
{ _inScene = value; }
-
- bool recovering() const
- { return _recovering; }
-
- void recovering(bool value)
- { _recovering = value; }
};
typedef Common::SharedPtr<Object> ObjectPtr;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 605f8fd0b17..0f76b8e05c8 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -511,7 +511,7 @@ void Process::changeScreenPatch() {
return;
} else {
ObjectPtr object = screen->find(objectName);
- int value = object && object->recovering();
+ int value = object && object->inScene();
debug("changeScreenPatch: current screen object recovering: %d", value);
push(value);
}
Commit: 8bb0bc2e5a7be51b44a96f85327f07d503eb7acb
https://github.com/scummvm/scummvm/commit/8bb0bc2e5a7be51b44a96f85327f07d503eb7acb
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:31+01:00
Commit Message:
AGDS: fix animation position
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index b4b18752a1e..951c243654a 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -181,7 +181,7 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
}
if (_animation) {
_animation->tick(engine);
- _animation->paint(engine, backbuffer, _animationPos);
+ _animation->paint(engine, backbuffer, _pos + _animationPos);
}
if (!_text.empty()) {
Common::Point pos = _region ? _region->center : _pos;
Commit: 5194a0971ec5516b9d494ab64ac6301d46fca04e
https://github.com/scummvm/scummvm/commit/5194a0971ec5516b9d494ab64ac6301d46fca04e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:31+01:00
Commit Message:
AGDS: improve character positioning
Changed paths:
engines/agds/animation.cpp
engines/agds/character.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index b3afad61f94..bdcee580785 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -163,10 +163,10 @@ void Animation::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common:
}
int Animation::width() const {
- return _flic ? _flic->getWidth() : 0;
+ return _flic ? _flic->getWidth() * _scale: 0;
}
int Animation::height() const {
- return _flic ? _flic->getHeight() : 0;
+ return _flic ? _flic->getHeight() * _scale: 0;
}
} // namespace AGDS
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 0b2c01d50d2..e2712d52ef4 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -140,9 +140,12 @@ void Character::paint(Graphics::Surface &backbuffer) {
return;
Common::Point pos = _pos + _animationPos;
+
+ auto screen = _engine->getCurrentScreen();
+ auto scale = screen? screen->getZScale(_pos.y): 1;
+ _animation->scale(scale);
+
if (_phase >= 0 && _phase < _frames) {
- auto screen = _engine->getCurrentScreen();
- _animation->scale(screen? screen->getZScale(_pos.y): 1);
_animation->tick(*_engine);
if (_phase + 1 >= _frames) {
_phase = -1;
@@ -158,6 +161,8 @@ void Character::paint(Graphics::Surface &backbuffer) {
}
}
+ pos.y -= _animation->height();
+ pos.x -= _animation->width() / 2;
_animation->paint(*_engine, backbuffer, pos);
}
Commit: a307270a7ad2a09f809d7f08d40f6555d054e517
https://github.com/scummvm/scummvm/commit/a307270a7ad2a09f809d7f08d40f6555d054e517
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:31+01:00
Commit Message:
AGDS: fix animation loop
Changed paths:
engines/agds/animation.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index bdcee580785..39fca66ecee 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -141,7 +141,10 @@ bool Animation::tick(AGDSEngine &engine) {
engine.reactivate(_process, true);
return true;
}
- return false;
+ if (_loop)
+ rewind();
+ else
+ return false;
}
decodeNextFrame(engine);
Commit: 69ddaa1c9df4131fa8eba69d11a9534a2c14138f
https://github.com/scummvm/scummvm/commit/69ddaa1c9df4131fa8eba69d11a9534a2c14138f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:31+01:00
Commit Message:
AGDS: pass Common::Point as an argument to getDirectionForMovement
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index e2712d52ef4..e41e8561df7 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -166,8 +166,8 @@ void Character::paint(Graphics::Surface &backbuffer) {
_animation->paint(*_engine, backbuffer, pos);
}
-int Character::getDirectionForMovement(int dx, int dy) {
- auto angle = atan2(dy, dx);
+int Character::getDirectionForMovement(Common::Point delta) {
+ auto angle = atan2(delta.y, delta.x);
if (angle < 0)
angle += M_PI * 2;
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 33281114b59..ce156621d04 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -121,7 +121,7 @@ public:
void paint(Graphics::Surface & backbuffer);
- int getDirectionForMovement(int dx, int dy);
+ int getDirectionForMovement(Common::Point delta);
};
Commit: 310b0a4dd3c3d73c16300772c54b2e53ab322691
https://github.com/scummvm/scummvm/commit/310b0a4dd3c3d73c16300772c54b2e53ab322691
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:31+01:00
Commit Message:
AGDS: change argument to move character to direction
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index e41e8561df7..564581ced32 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -109,10 +109,12 @@ void Character::direction(int dir) {
}
}
-void Character::moveTo(Common::Point dst, int frames) {
+void Character::moveTo(Common::Point dst, int dir) {
+ debug("character move %d,%d %d", dst.x, dst.y, dir);
_dst = dst;
_phase = 0;
- _frames = frames;
+ _frames = 1 + sqrt(dst.sqrDist(_pos)) / 5;
+ direction(dir);
}
void Character::animate(Common::Point pos, int direction, int speed) {
diff --git a/engines/agds/character.h b/engines/agds/character.h
index ce156621d04..cf4f02b329a 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -111,7 +111,7 @@ public:
return _pos;
}
- void moveTo(Common::Point dst, int frames);
+ void moveTo(Common::Point dst, int direction);
void direction(int dir);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 0f76b8e05c8..4428b23492f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1238,15 +1238,15 @@ void Process::enableCharacter() {
}
void Process::moveCharacter(bool usermove) {
- int frames = pop();
+ int direction = pop();
Common::String regionName = popString();
Common::String id = popString();
- debug("moveCharacter %s %s, frames: %d, usermove: %d", id.c_str(), regionName.c_str(), frames, usermove);
+ debug("moveCharacter %s %s, direction: %d, usermove: %d", id.c_str(), regionName.c_str(), direction, usermove);
Character *character = _engine->getCharacter(id);
if (character) {
auto region = _engine->loadRegion(regionName);
if (region) {
- character->moveTo(region->center, frames);
+ character->moveTo(region->center, direction);
}
} else
warning("character %s could not be found", id.c_str());
Commit: 9e23f423aea9eb43e58a900f785975890241dbb7
https://github.com/scummvm/scummvm/commit/9e23f423aea9eb43e58a900f785975890241dbb7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:31+01:00
Commit Message:
AGDS: add set command
Changed paths:
engines/agds/console.cpp
engines/agds/console.h
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index fa3135b1f2d..a8d261d632b 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -33,6 +33,7 @@ Console::Console(AGDSEngine *engine) : _engine(engine) {
registerCmd("activate", WRAP_METHOD(Console, activate));
registerCmd("info", WRAP_METHOD(Console, info));
registerCmd("run", WRAP_METHOD(Console, run));
+ registerCmd("set", WRAP_METHOD(Console, setGlobal));
}
bool Console::run(int argc, const char **argv) {
@@ -83,4 +84,18 @@ bool Console::info(int argc, const char **argv) {
return true;
}
+bool Console::setGlobal(int argc, const char **argv) {
+ if (argc < 3) {
+ debugPrintf("usage: %s var value\n", argv[0]);
+ return true;
+ }
+ int value;
+ if (sscanf(argv[2], "%d", &value) != 1) {
+ debugPrintf("invalid value");
+ return true;
+ }
+ _engine->setGlobal(argv[1], value);
+ return true;
+}
+
}
diff --git a/engines/agds/console.h b/engines/agds/console.h
index 85a908c25cc..688b7faec56 100644
--- a/engines/agds/console.h
+++ b/engines/agds/console.h
@@ -39,6 +39,7 @@ private:
bool run(int argc, const char **argv);
bool activate(int argc, const char **argv);
bool info(int argc, const char **argv);
+ bool setGlobal(int argc, const char **argv);
AGDSEngine *_engine;
};
Commit: e82ebae3cfc1a222c42a88b91d5cc94c9fd26590
https://github.com/scummvm/scummvm/commit/e82ebae3cfc1a222c42a88b91d5cc94c9fd26590
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:31+01:00
Commit Message:
AGDS: fix stop phase value
Changed paths:
engines/agds/character.h
diff --git a/engines/agds/character.h b/engines/agds/character.h
index cf4f02b329a..4a249a5f128 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -95,7 +95,7 @@ public:
void animate(Common::Point pos, int direction, int speed);
void stop() {
- _phase = 0;
+ _phase = -1;
_frames = 0;
}
Commit: 01c2dddfc85e62c4c23a680151e5b20cab98fe83
https://github.com/scummvm/scummvm/commit/01c2dddfc85e62c4c23a680151e5b20cab98fe83
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:31+01:00
Commit Message:
AGDS: add Screen::remove(Animation)
Changed paths:
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index a4d69ec6e14..cd8e311b371 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -82,6 +82,18 @@ bool Screen::add(ObjectPtr object) {
return true;
}
+bool Screen::remove(Animation * animation) {
+ bool removed = false;
+ for(auto i = _animations.begin(); i != _animations.end(); ) {
+ if (*i == animation) {
+ _animations.erase(i++);
+ removed = true;
+ } else
+ ++i;
+ }
+ return removed;
+}
+
ObjectPtr Screen::find(const Common::String &name) {
for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr &object = *i;
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index df5a09886a2..8728c57a9d0 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -110,6 +110,7 @@ public:
void add(Animation * animation) {
_animations.insert(animation);
}
+ bool remove(Animation * animation);
void update(const ObjectPtr &object) {
bool found = remove(object);
Commit: 2efb19eed023dde3d6090603ef3e5b3cee125914
https://github.com/scummvm/scummvm/commit/2efb19eed023dde3d6090603ef3e5b3cee125914
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:32+01:00
Commit Message:
AGDS: implement z-sorting for char/child/animation
Changed paths:
engines/agds/agds.cpp
engines/agds/character.cpp
engines/agds/character.h
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index e735efe4623..b4d025c3bc5 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -490,9 +490,6 @@ Common::Error AGDSEngine::run() {
mouseCursor->paint(*this, *backbuffer, _mouse);
}
- if (_currentCharacter)
- _currentCharacter->paint(*backbuffer);
-
if (_textLayout.valid()) {
if (_syncSoundId >= 0) {
if (!_soundManager.playing(_syncSoundId)) {
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 564581ced32..3bf4a77bc96 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -168,6 +168,18 @@ void Character::paint(Graphics::Surface &backbuffer) {
_animation->paint(*_engine, backbuffer, pos);
}
+int Character::z() const {
+ int y = _pos.y + _animationPos.y;
+ //fixme: add temp var : _movePos?
+ if (_phase >= 0 && _phase < _frames) {
+ float dy = _dst.y - _pos.y;
+ float t = 1.0f * _phase / _frames;
+ y += dy * t;
+ }
+ return y;
+}
+
+
int Character::getDirectionForMovement(Common::Point delta) {
auto angle = atan2(delta.y, delta.x);
if (angle < 0)
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 4a249a5f128..8614cc44d73 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -122,6 +122,8 @@ public:
void paint(Graphics::Surface & backbuffer);
int getDirectionForMovement(Common::Point delta);
+
+ int z() const;
};
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index cd8e311b371..26afbadf683 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -23,6 +23,7 @@
#include "agds/screen.h"
#include "agds/agds.h"
#include "agds/animation.h"
+#include "agds/character.h"
#include "agds/object.h"
#include "agds/patch.h"
#include "agds/region.h"
@@ -144,31 +145,57 @@ void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
}
}
+ Character * character = engine.currentCharacter();
ChildrenType::iterator child = _children.begin();
AnimationsType::iterator animation = _animations.begin();
- while(child != _children.end() || animation != _animations.end()) {
+ while(child != _children.end() || animation != _animations.end() || character) {
bool child_valid = child != _children.end();
bool animation_valid = animation != _animations.end();
- if (child_valid && animation_valid) {
- if ((*child)->z() > (*animation)->z()) {
- //debug("object %d, z: %d", idx++, (*child)->z());
+
+ bool z_valid = false;
+ int z = 0;
+ int render_type = -1;
+ if (child_valid) {
+ if (!z_valid || (*child)->z() > z) {
+ z = (*child)->z();
+ z_valid = true;
+ render_type = 0;
+ }
+ }
+ if (animation_valid) {
+ if (!z_valid || (*animation)->z() > z) {
+ z = (*animation)->z();
+ z_valid = true;
+ render_type = 1;
+ }
+ }
+ if (character) {
+ if (!z_valid || character->z() > z) {
+ z = character->z();
+ z_valid = true;
+ render_type = 2;
+ }
+ }
+
+ switch (render_type) {
+ case 0:
+ //debug("object z: %d", (*child)->z());
if ((*child)->inScene())
(*child)->paint(engine, backbuffer);
++child;
- } else {
- //debug("animation %d, z: %d", idx++, (*animation)->z());
+ break;
+ case 1:
+ //debug("animation z: %d", (*animation)->z());
(*animation)->paint(engine, backbuffer, Common::Point());
++animation;
- }
- } else if (child_valid) {
- //debug("object %d, z: %d", idx++, (*child)->z());
- if ((*child)->inScene())
- (*child)->paint(engine, backbuffer);
- ++child;
- } else {
- //debug("animation %d, z: %d", idx++, (*animation)->z());
- (*animation)->paint(engine, backbuffer, Common::Point());
- ++animation;
+ break;
+ case 2:
+ //debug("character z: %d", character->z());
+ character->paint(backbuffer);
+ character = nullptr;
+ break;
+ default:
+ error("invalid logic in z-sort");
}
}
}
Commit: 24a24ea8c48a70e941e71b29ffc0eb2ccb33b814
https://github.com/scummvm/scummvm/commit/24a24ea8c48a70e941e71b29ffc0eb2ccb33b814
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:32+01:00
Commit Message:
AGDS: add 'load' console command (load + run)
Changed paths:
engines/agds/console.cpp
engines/agds/console.h
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index a8d261d632b..68147871add 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -32,10 +32,26 @@ namespace AGDS {
Console::Console(AGDSEngine *engine) : _engine(engine) {
registerCmd("activate", WRAP_METHOD(Console, activate));
registerCmd("info", WRAP_METHOD(Console, info));
+ registerCmd("load", WRAP_METHOD(Console, load));
registerCmd("run", WRAP_METHOD(Console, run));
registerCmd("set", WRAP_METHOD(Console, setGlobal));
}
+bool Console::load(int argc, const char **argv) {
+ if (argc < 2) {
+ debugPrintf("usage: %s object_id\n", argv[0]);
+ return true;
+ }
+ ObjectPtr object = _engine->loadObject(argv[1]);
+ if (!object) {
+ debugPrintf("no object %s\n", argv[1]);
+ return true;
+ }
+ _engine->runObject(object);
+ detach();
+ return false;
+}
+
bool Console::run(int argc, const char **argv) {
if (argc < 2) {
debugPrintf("usage: %s object_id\n", argv[0]);
diff --git a/engines/agds/console.h b/engines/agds/console.h
index 688b7faec56..d71b13fffe5 100644
--- a/engines/agds/console.h
+++ b/engines/agds/console.h
@@ -36,6 +36,7 @@ public:
using GUI::Debugger::clearVars;
private:
+ bool load(int argc, const char **argv);
bool run(int argc, const char **argv);
bool activate(int argc, const char **argv);
bool info(int argc, const char **argv);
Commit: b0c185ce027697a32765c95609625a583e6301ac
https://github.com/scummvm/scummvm/commit/b0c185ce027697a32765c95609625a583e6301ac
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:32+01:00
Commit Message:
AGDS: clear mouse map before calling resource init (fixes top-level menu and global mouse areas)
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index b4d025c3bc5..15bfa288914 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -901,11 +901,11 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
_systemVars[name]->read(agds_d.get());
}
}
+ _mouseMap.clear();
SystemVariable *initVar = getSystemVariable("init_resources");
runObject(initVar->getString());
- _mouseMap.clear();
loadPatches(file, db);
loadScreen(screenName);
Commit: 8b872b794bd47f7ff375f59305c0ba6f39496b3d
https://github.com/scummvm/scummvm/commit/8b872b794bd47f7ff375f59305c0ba6f39496b3d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:32+01:00
Commit Message:
AGDS: rename stub138
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index db723eae640..34a69018a8c 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -155,7 +155,7 @@ enum Opcode {
kSetPhaseVar = 135,
kSetAnimationLoop = 136,
kSetAnimationSpeed = 137,
- kStub138 = 138,
+ kScreenSaveScreenPatch = 138,
kStub139 = 139,
kScreenChangeScreenPatch = 140,
kGetFreeInventorySpace = 141,
@@ -374,7 +374,7 @@ enum Opcode {
OP(kSetPhaseVar, setPhaseVar) \
OP(kSetAnimationLoop, setAnimationLoop) \
OP(kSetAnimationSpeed, setAnimationSpeed) \
- OP(kStub138, stub138) \
+ OP(kScreenSaveScreenPatch, screenSaveScreenPatch) \
OP(kGetSavedMouseX, getSavedMouseX) \
OP(kGetSavedMouseY, getSavedMouseY) \
OP(kScreenChangeScreenPatch, changeScreenPatch) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4428b23492f..8a1e70fc4e7 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -644,11 +644,11 @@ void Process::setAnimationSpeed() {
_animationSpeed = value;
}
-void Process::stub138() {
- Common::String arg2 = popString();
- Common::String arg1 = popString();
- debug("stub138 %s %s", arg1.c_str(), arg2.c_str());
- suspend(kExitCodeLoadScreenObject, arg2);
+void Process::screenSaveScreenPatch() {
+ Common::String objectName = popString();
+ Common::String screenName = popString();
+ debug("saveScreenPatch stub %s %s", screenName.c_str(), objectName.c_str());
+ suspend(kExitCodeLoadScreenObject, objectName);
}
void Process::getPictureBaseX() {
Commit: 1f7a145ab6e811137a662e4858dad7fe7203efaa
https://github.com/scummvm/scummvm/commit/1f7a145ab6e811137a662e4858dad7fe7203efaa
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:32+01:00
Commit Message:
AGDS: add Process::disassemble stub
Changed paths:
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 89e2f349083..5a0ce19b71f 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -153,6 +153,7 @@ private:
public:
Process(AGDSEngine *engine, ObjectPtr object, unsigned ip = 0);
+ static Common::String disassemble(ObjectPtr object);
ObjectPtr getObject() const {
return _object;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 8a1e70fc4e7..c06b8489145 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1558,4 +1558,71 @@ ProcessExitCode Process::resume() {
return _exitCode;
}
+#define AGDS_DIS(NAME, METHOD) \
+ case NAME: \
+ source += Common::String::format("%s\n", #NAME); \
+ break;
+
+#define AGDS_DIS_C(NAME, METHOD) \
+ case NAME: { \
+ int8 arg = code[ip++]; \
+ source += Common::String::format("%s %d\n", #NAME, (int)arg); \
+ } break;
+
+#define AGDS_DIS_B(NAME, METHOD) \
+ case NAME: { \
+ uint8 arg = code[ip++]; \
+ source += Common::String::format("%s %u\n", #NAME, (uint)arg); \
+ } break;
+
+#define AGDS_DIS_W(NAME, METHOD) \
+ case NAME: { \
+ int16 arg = code[ip++]; arg |= ((int16)code[ip++]) << 8; \
+ source += Common::String::format("%s %d\n", #NAME, (int)arg); \
+ } break;
+
+#define AGDS_DIS_U(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg = code[ip++]; arg |= ((uint16)code[ip++]) << 8; \
+ source += Common::String::format("%s %u\n", #NAME, (uint)arg); \
+ } break;
+
+#define AGDS_DIS_UU(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg1 = code[ip++]; arg1 |= ((uint16)code[ip++]) << 8; \
+ uint16 arg2 = code[ip++]; arg2 |= ((uint16)code[ip++]) << 8; \
+ source += Common::String::format("%s %u %u\n", #NAME, (uint)arg1, (uint)arg2); \
+ } break;
+
+#define AGDS_DIS_UD(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg1 = code[ip++]; arg1 |= ((uint16)code[ip++]) << 8; \
+ uint16 arg2 = code[ip++]; arg2 |= ((uint16)code[ip++]) << 8; \
+ source += Common::String::format("%s %u\n", #NAME, (uint)(arg1 | (arg2 << 16))); \
+ } break;
+
+Common::String Process::disassemble(ObjectPtr object) {
+ Common::String source = Common::String::format("Object %s disassembly:\n", object->getName().c_str());
+
+ const auto &code = object->getCode();
+ uint ip = 0;
+ while (ip < code.size()) {
+ uint8 op = code[ip++];
+ source += Common::String::format("%04x: %02x: ", ip - 1, op);
+ switch (op) {
+ AGDS_OPCODE_LIST(
+ AGDS_DIS,
+ AGDS_DIS_C, AGDS_DIS_B,
+ AGDS_DIS_W, AGDS_DIS_U,
+ AGDS_DIS_UD, AGDS_DIS_UU
+ )
+ default:
+ source += Common::String::format("unknown opcode 0x%02x (%u)\n", (unsigned)op, (unsigned)op);
+ break;
+ }
+ }
+ source += Common::String::format("Object %s disassembly end\n", object->getName().c_str());
+ return source;
+}
+
} // namespace AGDS
Commit: 1dab8c2102987e76387965bb8526a03174edc580
https://github.com/scummvm/scummvm/commit/1dab8c2102987e76387965bb8526a03174edc580
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:32+01:00
Commit Message:
AGDS: rename change/checkscreenpatch
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 34a69018a8c..e13a0476d54 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -157,7 +157,7 @@ enum Opcode {
kSetAnimationSpeed = 137,
kScreenSaveScreenPatch = 138,
kStub139 = 139,
- kScreenChangeScreenPatch = 140,
+ kScreenCheckScreenPatch = 140,
kGetFreeInventorySpace = 141,
kSetStringSystemVariable = 142,
kSetSystemIntegerVariable = 143,
@@ -377,7 +377,7 @@ enum Opcode {
OP(kScreenSaveScreenPatch, screenSaveScreenPatch) \
OP(kGetSavedMouseX, getSavedMouseX) \
OP(kGetSavedMouseY, getSavedMouseY) \
- OP(kScreenChangeScreenPatch, changeScreenPatch) \
+ OP(kScreenCheckScreenPatch, checkScreenPatch) \
OP(kGetFreeInventorySpace, getInventoryFreeSpace) \
OP(kSetStringSystemVariable, setStringSystemVariable) \
OP(kSetSystemIntegerVariable, setIntegerSystemVariable) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c06b8489145..796bc33db43 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -491,11 +491,11 @@ void Process::userEnabled() {
push(enabled);
}
-void Process::changeScreenPatch() {
+void Process::checkScreenPatch() {
Common::String objectName = popString();
Common::String screenName = popString();
Common::String inventoryScr = _engine->getSystemVariable("inventory_scr")->getString();
- debug("changeScreenPatch: screen: %s, object: %s, inventory: %s",
+ debug("checkScreenPatch: screen: %s, object: %s, inventory: %s",
screenName.empty() ? "none" : screenName.c_str(), objectName.c_str(), inventoryScr.empty() ? "none" : inventoryScr.c_str());
Screen *screen = _engine->getCurrentScreen();
@@ -505,14 +505,14 @@ void Process::changeScreenPatch() {
}
if (!screenName.empty()) {
- debug("changeScreenPatch: stub, returning 0");
+ debug("checkScreenPatch: stub for screen != -1, returning 0");
//check that patch exist
push(0);
return;
} else {
ObjectPtr object = screen->find(objectName);
int value = object && object->inScene();
- debug("changeScreenPatch: current screen object recovering: %d", value);
+ debug("checkScreenPatch: current screen object present: %d", value);
push(value);
}
}
Commit: fbe7aecac360f30dd42f71c2e2b1d289d046cb63
https://github.com/scummvm/scummvm/commit/fbe7aecac360f30dd42f71c2e2b1d289d046cb63
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:32+01:00
Commit Message:
AGDS: clean process at the end of the dialog
Changed paths:
engines/agds/dialog.cpp
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index b8bf85e0471..5d3f96be27b 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -175,6 +175,7 @@ bool Dialog::tick() {
debug("end of dialog, running %s", process.c_str());
dialog_var->setInteger(-2);
_engine->reactivate(_dialogProcessName);
+ _dialogProcessName.clear();
return false;
}
return true;
Commit: 856889e91418b04612f4fb914b95216795f25d40
https://github.com/scummvm/scummvm/commit/856889e91418b04612f4fb914b95216795f25d40
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:32+01:00
Commit Message:
AGDS: add AGDSEngine::stopProcess()
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 15bfa288914..58f596918e5 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -945,6 +945,17 @@ void AGDSEngine::reactivate(const Common::String &name, bool runNow) {
}
}
+void AGDSEngine::stopProcess(const Common::String & name) {
+ for(uint i = 0; i < _processes.size(); ++i) {
+ ProcessPtr &process = _processes[i];
+ if (process && process->getName() == name) {
+ debug("stopping %s...", name.c_str());
+ process->done();
+ }
+ }
+}
+
+
Common::Error AGDSEngine::saveGameStream(Common::WriteStream *file, bool isAutosave) { return Common::Error(Common::kNoError); }
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 6f3146d06f5..5ce2c6d4a1d 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -108,6 +108,7 @@ public:
void runObject(const ObjectPtr &object);
void runObject(const Common::String & name, const Common::String &prototype = Common::String());
void runProcess(const ObjectPtr &object, uint ip = 0);
+ void stopProcess(const Common::String & name);
void resetCurrentScreen();
void loadScreen(const Common::String & name);
Commit: be583ebaf4f3e049aa691a7c54cb6bd5d26d73c4
https://github.com/scummvm/scummvm/commit/be583ebaf4f3e049aa691a7c54cb6bd5d26d73c4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:32+01:00
Commit Message:
AGDS: fix crash in console (allow empty process slots)
Changed paths:
engines/agds/console.cpp
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index 68147871add..f619844f442 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -95,7 +95,8 @@ bool Console::info(int argc, const char **argv) {
debugPrintf("processes:\n");
auto & processes = _engine->processes();
for(auto & process : processes) {
- debugPrintf("%s\n", process->getName().c_str());
+ if (process)
+ debugPrintf("%s\n", process->getName().c_str());
}
return true;
}
Commit: 3f016d402878dbb241387814cc60fbba5a8efb81
https://github.com/scummvm/scummvm/commit/3f016d402878dbb241387814cc60fbba5a8efb81
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:32+01:00
Commit Message:
AGDS: activate parent dialog process at the end of the dialog
Changed paths:
engines/agds/agds.h
engines/agds/dialog.cpp
engines/agds/dialog.h
engines/agds/process.cpp
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 5ce2c6d4a1d..6a2f8944fd6 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -221,8 +221,8 @@ public:
}
}
- void runDialog(const Common::String &dialogProcess) {
- _dialog.run(dialogProcess);
+ void runDialog(const Common::String &dialogParentProcess, const Common::String &dialogProcess) {
+ _dialog.run(dialogParentProcess, dialogProcess);
}
void tickInventory();
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 5d3f96be27b..c5757ed6c8c 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -6,8 +6,9 @@
namespace AGDS {
-void Dialog::run(const Common::String & dialogProcess) {
+void Dialog::run(const Common::String &dialogParentProcess, const Common::String & dialogProcess) {
debug("runDialog: %s", dialogProcess.c_str());
+ _dialogParentProcessName = dialogParentProcess;
_dialogProcessName = dialogProcess;
_engine->runObject(dialogProcess);
}
@@ -169,13 +170,12 @@ bool Dialog::tick() {
dialog_var->setInteger(-3);
}
if (_dialogScriptPos >= n && !_dialogProcessName.empty()) {
- Common::String process = _dialogProcessName;
_dialogProcessName.clear();
- debug("end of dialog, running %s", process.c_str());
+ debug("end of dialog, running %s", _dialogParentProcessName.c_str());
dialog_var->setInteger(-2);
- _engine->reactivate(_dialogProcessName);
- _dialogProcessName.clear();
+ _engine->reactivate(_dialogParentProcessName);
+ _dialogParentProcessName.clear();
return false;
}
return true;
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
index e08718016e2..53265d20c36 100644
--- a/engines/agds/dialog.h
+++ b/engines/agds/dialog.h
@@ -52,6 +52,7 @@ private:
DialogDefsType _dialogDefs;
Common::String _dialogScript;
uint32 _dialogScriptPos;
+ Common::String _dialogParentProcessName;
Common::String _dialogProcessName;
Common::String _dialogLine;
@@ -62,7 +63,7 @@ private:
public:
Dialog(AGDSEngine *engine): _engine(engine), _dialogScriptPos(0) { }
- void run(const Common::String &dialogProcess);
+ void run(const Common::String &dialogParent, const Common::String &dialogProcess);
int textDelay(const Common::String &str);
const Common::String &getNextDialogLine() const {
return _dialogLine;
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 79b409a4940..e95ae715b54 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -174,7 +174,7 @@ void Process::run() {
activate();
continue;
case kExitCodeRunDialog:
- _engine->runDialog(getExitArg1());
+ _engine->runDialog(getName(), getExitArg1());
break;
case kExitCodeSetNextScreen:
debug("process %s launches screen: %s", getName().c_str(), getExitArg1().c_str());
Commit: 72bde4f34dd60b3a6faa82ba1db03816e58eea0f
https://github.com/scummvm/scummvm/commit/72bde4f34dd60b3a6faa82ba1db03816e58eea0f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:33+01:00
Commit Message:
AGDS: small animation/direction fix
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 3bf4a77bc96..e2cc19d17da 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -100,6 +100,10 @@ void Character::load(Common::SeekableReadStream *stream) {
void Character::direction(int dir) {
debug("setDirection %d", dir);
_direction = dir;
+
+ if (dir < 0)
+ return;
+
_animation = _engine->loadAnimation(_animations[dir].filename);
_animationPos = Common::Point();
if (!_animation) {
@@ -107,6 +111,7 @@ void Character::direction(int dir) {
_phase = -1;
_frames = 0;
}
+ _animation->rewind();
}
void Character::moveTo(Common::Point dst, int dir) {
Commit: 3de298d1f20123949ea1c97bf55a401b673a041a
https://github.com/scummvm/scummvm/commit/3de298d1f20123949ea1c97bf55a401b673a041a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:33+01:00
Commit Message:
AGDS: treat @ as a comment
Changed paths:
engines/agds/dialog.cpp
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index c5757ed6c8c..a2a102e95c1 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -119,7 +119,7 @@ bool Dialog::tick() {
debug("dialog line: %s", line.c_str());
if (line[0] == '@') {
- if (line[1] == '@') //comment
+ if (line.size() < 2 || line[1] == '@') //comment
return true;
line.erase(0, 1);
Commit: 17b5498b0ddbb20cb56e10713ee1af8d5455d24a
https://github.com/scummvm/scummvm/commit/17b5498b0ddbb20cb56e10713ee1af8d5455d24a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:33+01:00
Commit Message:
AGDS: remove botched move
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index e2cc19d17da..e9af9ae575c 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -116,9 +116,7 @@ void Character::direction(int dir) {
void Character::moveTo(Common::Point dst, int dir) {
debug("character move %d,%d %d", dst.x, dst.y, dir);
- _dst = dst;
- _phase = 0;
- _frames = 1 + sqrt(dst.sqrDist(_pos)) / 5;
+ _pos = dst;
direction(dir);
}
@@ -157,13 +155,7 @@ void Character::paint(Graphics::Surface &backbuffer) {
if (_phase + 1 >= _frames) {
_phase = -1;
_frames = 0;
- pos = _pos = _dst;
} else {
- float dx = _dst.x - _pos.x;
- float dy = _dst.y - _pos.y;
- float t = 1.0f * _phase / _frames;
- pos.x += dx * t;
- pos.y += dy * t;
++_phase;
}
}
@@ -176,11 +168,6 @@ void Character::paint(Graphics::Surface &backbuffer) {
int Character::z() const {
int y = _pos.y + _animationPos.y;
//fixme: add temp var : _movePos?
- if (_phase >= 0 && _phase < _frames) {
- float dy = _dst.y - _pos.y;
- float t = 1.0f * _phase / _frames;
- y += dy * t;
- }
return y;
}
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 8614cc44d73..26c9a08babc 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -46,7 +46,6 @@ class Character {
Common::String _name;
Common::Point _pos;
Common::Point _animationPos;
- Common::Point _dst;
bool _enabled;
bool _visible;
int _phase;
Commit: d0b1210437449329083b8ce596f828f47b876b2c
https://github.com/scummvm/scummvm/commit/d0b1210437449329083b8ce596f828f47b876b2c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:33+01:00
Commit Message:
AGDS: implement opcode 139 (remove object and save patch)
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index e13a0476d54..0d0a6dd31c4 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -156,7 +156,7 @@ enum Opcode {
kSetAnimationLoop = 136,
kSetAnimationSpeed = 137,
kScreenSaveScreenPatch = 138,
- kStub139 = 139,
+ kScreenRemoveObjectSavePatch = 139,
kScreenCheckScreenPatch = 140,
kGetFreeInventorySpace = 141,
kSetStringSystemVariable = 142,
@@ -375,6 +375,7 @@ enum Opcode {
OP(kSetAnimationLoop, setAnimationLoop) \
OP(kSetAnimationSpeed, setAnimationSpeed) \
OP(kScreenSaveScreenPatch, screenSaveScreenPatch) \
+ OP(kScreenRemoveObjectSavePatch, screenRemoveObjectSavePatch) \
OP(kGetSavedMouseX, getSavedMouseX) \
OP(kGetSavedMouseY, getSavedMouseY) \
OP(kScreenCheckScreenPatch, checkScreenPatch) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 796bc33db43..07e1a265f2a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -651,6 +651,20 @@ void Process::screenSaveScreenPatch() {
suspend(kExitCodeLoadScreenObject, objectName);
}
+void Process::screenRemoveObjectSavePatch() {
+ Common::String objectName = popString();
+ Common::String screenName = popString();
+ if (screenName != _engine->getCurrentScreenName()) {
+ debug("screenRemoveObjectSavePatch semi-stub %s %s", screenName.c_str(), objectName.c_str());
+ } else {
+ Screen *screen = _engine->getCurrentScreen();
+ if (screen) {
+ if (!screen->remove(objectName))
+ warning("screenRemoveObjectSavePatch: object %s not found", objectName.c_str());
+ }
+ }
+}
+
void Process::getPictureBaseX() {
Common::String name = popString();
debug("getPictureBaseX: %s", name.c_str());
Commit: 6d86768fcc9147912f90f65a0e033e5756879f06
https://github.com/scummvm/scummvm/commit/6d86768fcc9147912f90f65a0e033e5756879f06
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:33+01:00
Commit Message:
AGDS: use proper font for object texts
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 951c243654a..41a8b1819d4 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -25,6 +25,7 @@
#include "agds/animation.h"
#include "agds/font.h"
#include "agds/region.h"
+#include "agds/systemVariable.h"
#include "common/debug.h"
#include "common/memstream.h"
#include "common/rect.h"
@@ -186,7 +187,7 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
if (!_text.empty()) {
Common::Point pos = _region ? _region->center : _pos;
int w = backbuffer.w - pos.x;
- engine.getFont(1)->drawString(&backbuffer, _text, pos.x, pos.y, w, 0);
+ engine.getFont(engine.getSystemVariable("objtext_font")->getInteger())->drawString(&backbuffer, _text, pos.x, pos.y, w, 0);
}
}
Commit: 4105384d27ea8e1314536efb0d9de787d2746302
https://github.com/scummvm/scummvm/commit/4105384d27ea8e1314536efb0d9de787d2746302
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:33+01:00
Commit Message:
AGDS: separate texts and titles, so objtext is displayed separately
Changed paths:
engines/agds/agds.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 58f596918e5..70a4fecc7cf 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -444,6 +444,13 @@ Common::Error AGDSEngine::run() {
}
}
+ _soundManager.tick();
+ if (active())
+ tick();
+
+ Graphics::Surface *backbuffer = _system->lockScreen();
+ backbuffer->fillRect(backbuffer->getRect(), 0);
+
Animation *mouseCursor = NULL;
if (userEnabled() && _currentScreen) {
@@ -451,14 +458,16 @@ Common::Error AGDSEngine::run() {
Animation *cursor = object ? object->getMouseCursor() : NULL;
if (cursor)
mouseCursor = cursor;
- }
- _soundManager.tick();
- if (active())
- tick();
-
- Graphics::Surface *backbuffer = _system->lockScreen();
- backbuffer->fillRect(backbuffer->getRect(), 0);
+ if (object && !object->title().empty()) {
+ auto & title = object->title();
+ auto font = getFont(getSystemVariable("objtext_font")->getInteger());
+ int w = font->getStringWidth(title);
+ int x = getSystemVariable("objtext_x")->getInteger() - w / 2;
+ int y = getSystemVariable("objtext_y")->getInteger();
+ font->drawString(backbuffer, title, x, y, backbuffer->w - x, 0);
+ }
+ }
if (_mjpgPlayer) {
const Graphics::Surface *surface = _mjpgPlayer->decodeFrame();
diff --git a/engines/agds/object.h b/engines/agds/object.h
index e273398cf2a..0223a0b734c 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -71,6 +71,7 @@ private:
Common::Point _pos, _animationPos, _offset;
int _z;
Common::String _text;
+ Common::String _title;
uint _clickHandler;
uint _examineHandler;
uint _userUseHandler;
@@ -178,6 +179,14 @@ public:
_text = text;
}
+ void title(const Common::String &title) {
+ _title = title;
+ }
+
+ const Common::String& title() const {
+ return _title;
+ }
+
Common::Point getPosition() const {
return _pos;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 07e1a265f2a..5da4b167886 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1172,7 +1172,7 @@ void Process::updateScreenHeightToDisplay() {
void Process::loadTextFromObject() {
Common::String text = popText();
debug("loadTextFromObject %s", text.c_str());
- _object->setText(text);
+ _object->title(text);
}
void Process::call(uint16 addr) {
Commit: f6b0fe9cd6787c7fba58c99a96bfe1ab53c8eb75
https://github.com/scummvm/scummvm/commit/f6b0fe9cd6787c7fba58c99a96bfe1ab53c8eb75
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:33+01:00
Commit Message:
AGDS: implement hint mode (left ctrl for now)
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/object.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 70a4fecc7cf..edcce010ce3 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -59,7 +59,8 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_dialog(this),
_tellTextTimer(0),
_syncSoundId(-1),
- _fastMode(true) {
+ _fastMode(true),
+ _hintMode(false) {
}
AGDSEngine::~AGDSEngine() {
@@ -392,6 +393,9 @@ Common::Error AGDSEngine::run() {
_fastMode = !_fastMode;
}
break;
+ case Common::KEYCODE_LCTRL:
+ _hintMode = true;
+ break;
default:
if (event.kbd.ascii)
key = Common::String(static_cast<char>(event.kbd.ascii));
@@ -404,6 +408,17 @@ Common::Error AGDSEngine::run() {
}
}
} break;
+
+ case Common::EVENT_KEYUP: {
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_LCTRL:
+ _hintMode = false;
+ break;
+ default:
+ break;
+ }
+ } break;
+
case Common::EVENT_MOUSEMOVE:
_mouse = event.mouse;
if (userEnabled()) {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 6a2f8944fd6..060b36fa65d 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -247,6 +247,10 @@ public:
void reactivate(const Common::String &name, bool runNow = false);
+ bool showHints() const {
+ return _hintMode;
+ }
+
private:
void loadPatches(Common::SeekableReadStream *file, Database & db);
@@ -305,6 +309,7 @@ private:
int _syncSoundId;
bool _fastMode;
+ bool _hintMode;
};
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 41a8b1819d4..e8bb2b49b09 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -180,15 +180,25 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
_picture->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
}
}
+
if (_animation) {
_animation->tick(engine);
_animation->paint(engine, backbuffer, _pos + _animationPos);
}
+
if (!_text.empty()) {
Common::Point pos = _region ? _region->center : _pos;
int w = backbuffer.w - pos.x;
engine.getFont(engine.getSystemVariable("objtext_font")->getInteger())->drawString(&backbuffer, _text, pos.x, pos.y, w, 0);
}
+
+ if (engine.showHints() && !_title.empty()) {
+ Common::Point pos = _region ? _region->center : _pos;
+ int w = backbuffer.w - pos.x;
+ auto font = engine.getFont(engine.getSystemVariable("edit_font")->getInteger());
+ pos.x -= font->getStringWidth(_title) / 2;
+ font->drawString(&backbuffer, _title, pos.x, pos.y, w, 0);
+ }
}
} // namespace AGDS
Commit: 5d28aec9b0d2cb7baf53c3474780255a0115f0bb
https://github.com/scummvm/scummvm/commit/5d28aec9b0d2cb7baf53c3474780255a0115f0bb
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:33+01:00
Commit Message:
AGDS: add Object::scale/_scale
Changed paths:
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 0223a0b734c..aecc88f2850 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -76,6 +76,7 @@ private:
uint _examineHandler;
uint _userUseHandler;
int _alpha;
+ int _scale;
bool _inScene;
public:
@@ -129,6 +130,14 @@ public:
_alpha = (100 - alpha) * 255 / 100;
}
+ void scale(int scale) {
+ _scale = scale;
+ }
+
+ int scale() const {
+ return _scale;
+ }
+
void region(RegionPtr region);
RegionPtr region() const {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 5da4b167886..9a9fa2ea99c 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -780,6 +780,7 @@ void Process::stub193() {
void Process::setObjectScale() {
int value = pop();
+ _object->scale(value);
debug("setObjectScale stub %d", value);
}
Commit: 38cd1299f7caa266d3fd920a3cff2020a73722c0
https://github.com/scummvm/scummvm/commit/38cd1299f7caa266d3fd920a3cff2020a73722c0
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:33+01:00
Commit Message:
AGDS: add Object::pointIn()
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
engines/agds/screen.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index e8bb2b49b09..4198da25994 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -171,6 +171,16 @@ void Object::generateRegion() {
debug("%s: generated region: %s", _name.c_str(), _region->toString().c_str());
}
+bool Object::pointIn(Common::Point pos) {
+ if (!_inScene)
+ return false;
+
+ if (_region && _region->pointIn(pos))
+ return true;
+
+ return false;
+}
+
void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
if (_picture) {
Common::Point dst = _pos - _offset;
diff --git a/engines/agds/object.h b/engines/agds/object.h
index aecc88f2850..2e4b82e9846 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -218,6 +218,8 @@ public:
void inScene(bool value)
{ _inScene = value; }
+
+ bool pointIn(Common::Point pos);
};
typedef Common::SharedPtr<Object> ObjectPtr;
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 26afbadf683..5b4ce91eb9d 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -203,11 +203,7 @@ void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
ObjectPtr Screen::find(Common::Point pos) const {
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
- if (!object->inScene())
- continue;
-
- RegionPtr region = object->region();
- if (region && region->pointIn(pos))
+ if (object->pointIn(pos))
return object;
}
return ObjectPtr();
Commit: fe276118f179508fcc60bb9eb40e9569eb1e1985
https://github.com/scummvm/scummvm/commit/fe276118f179508fcc60bb9eb40e9569eb1e1985
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:33+01:00
Commit Message:
AGDS: pass engine to screen objects
Changed paths:
engines/agds/agds.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index edcce010ce3..fdb251f867b 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -217,7 +217,7 @@ void AGDSEngine::loadScreen(const Common::String &name) {
PatchPtr &patch = _patches[_currentScreenName];
if (!patch)
patch = PatchPtr(new Patch());
- _currentScreen->save(*this, patch);
+ _currentScreen->save(patch);
patch->defaultMouseCursor = _defaultMouseCursorName;
}
_mouseMap.hideAll(this);
@@ -230,13 +230,13 @@ void AGDSEngine::loadScreen(const Common::String &name) {
_soundManager.stopAll();
_currentScreenName = name;
//SAVE CURRENT OBJECTS IN PATCH see save_screen_patch
- _currentScreen = new Screen(loadObject(name));
+ _currentScreen = new Screen(this, loadObject(name));
runProcess(_currentScreen->getObject());
PatchesType::const_iterator it = _patches.find(name);
if (it != _patches.end()) {
const PatchPtr &patch = it->_value;
- _currentScreen->load(*this, patch);
+ _currentScreen->load(patch);
if (!patch->defaultMouseCursor.empty())
loadDefaultMouseCursor(patch->defaultMouseCursor);
}
@@ -503,7 +503,7 @@ Common::Error AGDSEngine::run() {
reactivate(_filmProcess);
}
} else if (_currentScreen) {
- _currentScreen->paint(*this, *backbuffer);
+ _currentScreen->paint(*backbuffer);
}
if (!mouseCursor)
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 5b4ce91eb9d..c7444e4bdf0 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -39,7 +39,7 @@ int Screen::AnimationZCompare(const Animation *a, const Animation *b) {
return b->z() - a->z();
}
-Screen::Screen(ObjectPtr object) : _object(object), _name(object->getName()),
+Screen::Screen(AGDSEngine * engine, ObjectPtr object) : _engine(engine), _object(object), _name(object->getName()),
_children(&ObjectZCompare), _animations(&AnimationZCompare), _applyingPatch(false),
_characterNear(g_system->getHeight()), _characterFar(g_system->getHeight()) {
add(object);
@@ -134,10 +134,10 @@ Animation *Screen::findAnimationByPhaseVar(const Common::String &phaseVar) {
return NULL;
}
-void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
+void Screen::paint(Graphics::Surface &backbuffer) {
for(uint i = 0; i < _animations.size(); ) {
Animation *animation = _animations.data()[i];
- if (animation->tick(engine))
+ if (animation->tick(*_engine))
++i;
else {
debug("removing animation %s:%s", animation->process().c_str(), animation->phaseVar().c_str());
@@ -145,7 +145,7 @@ void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
}
}
- Character * character = engine.currentCharacter();
+ Character * character = _engine->currentCharacter();
ChildrenType::iterator child = _children.begin();
AnimationsType::iterator animation = _animations.begin();
while(child != _children.end() || animation != _animations.end() || character) {
@@ -181,12 +181,12 @@ void Screen::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
case 0:
//debug("object z: %d", (*child)->z());
if ((*child)->inScene())
- (*child)->paint(engine, backbuffer);
+ (*child)->paint(*_engine, backbuffer);
++child;
break;
case 1:
//debug("animation z: %d", (*animation)->z());
- (*animation)->paint(engine, backbuffer, Common::Point());
+ (*animation)->paint(*_engine, backbuffer, Common::Point());
++animation;
break;
case 2:
@@ -226,7 +226,7 @@ Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
return keyHandler;
}
-void Screen::load(AGDSEngine & engine, const PatchPtr &patch) {
+void Screen::load(const PatchPtr &patch) {
debug("applying patch with %u objects", patch->objects.size());
_applyingPatch = true;
for(uint i = 0; i < patch->objects.size(); ++i) {
@@ -235,13 +235,13 @@ void Screen::load(AGDSEngine & engine, const PatchPtr &patch) {
if (object.flag <= 0)
remove(object.name);
else if (!find(object.name)) {
- engine.runObject(object.name);
+ _engine->runObject(object.name);
}
}
_applyingPatch = false;
}
-void Screen::save(AGDSEngine & engine, const PatchPtr &patch) {
+void Screen::save(const PatchPtr &patch) {
patch->objects.clear();
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 8728c57a9d0..d69104f26cf 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -51,6 +51,7 @@ class Screen {
typedef Common::SortedArray<Animation *, const Animation *> AnimationsType;
typedef Common::SortedArray<ObjectPtr, const ObjectPtr &> ChildrenType;
+ AGDSEngine * _engine;
ObjectPtr _object;
Common::String _name;
ChildrenType _children;
@@ -68,7 +69,7 @@ public:
KeyHandler(Object *o, uint i): object(o), ip(i) { }
};
- Screen(ObjectPtr object);
+ Screen(AGDSEngine *engine, ObjectPtr object);
~Screen();
void setCharacterNearFar(int near, int far) {
@@ -120,14 +121,14 @@ public:
bool remove(const Common::String & name);
bool remove(const ObjectPtr & object);
- void paint(AGDSEngine & engine, Graphics::Surface & backbuffer);
+ void paint(Graphics::Surface & backbuffer);
ObjectPtr find(Common::Point pos) const;
ObjectPtr find(const Common::String &name);
KeyHandler findKeyHandler(const Common::String &keyName);
Animation * findAnimationByPhaseVar(const Common::String &phaseVar);
- void load(AGDSEngine & engine, const PatchPtr &patch);
- void save(AGDSEngine & engine, const PatchPtr &patch);
+ void load(const PatchPtr &patch);
+ void save(const PatchPtr &patch);
};
Commit: ae849797b238ef2be8657ec428edd77267401455
https://github.com/scummvm/scummvm/commit/ae849797b238ef2be8657ec428edd77267401455
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:34+01:00
Commit Message:
AGDS: stop all sounds before loading game state
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index fdb251f867b..317561c7d80 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -907,6 +907,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
}
{
+ _soundManager.stopAll();
// Audio samples
Common::ScopedPtr<Common::SeekableReadStream> agds_a(db.getEntry(file, "__agds_a"));
Common::String sample = loadText(readString(agds_a.get()));
Commit: ce1806f3d60f74a7e8170c61f9cfd1b125602c6d
https://github.com/scummvm/scummvm/commit/ce1806f3d60f74a7e8170c61f9cfd1b125602c6d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:34+01:00
Commit Message:
AGDS: slightly fixed logs in runObject(object)
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 317561c7d80..38c0e11efba 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -176,10 +176,11 @@ void AGDSEngine::runObject(const ObjectPtr &object) {
if (_currentScreen->add(object)) {
runProcess(object);
} else if (!object->inScene()) {
- debug("marking object %s as recovering...", object->getName().c_str());
+ debug("marking object %s as in-scene...", object->getName().c_str());
object->inScene(true);
runProcess(object);
- }
+ } else
+ debug("object %s is in scene, skip run", object->getName().c_str());
} else
warning("object %s has been loaded, but was not added to any screen", object->getName().c_str());
}
Commit: 50a26b6d6ef03ebe76f43c21829293a47227555d
https://github.com/scummvm/scummvm/commit/50a26b6d6ef03ebe76f43c21829293a47227555d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:34+01:00
Commit Message:
AGDS: return object from runObject(name), use it while loading game
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 38c0e11efba..2bccc543456 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -203,11 +203,12 @@ ObjectPtr AGDSEngine::getCurrentScreenObject(const Common::String &name) {
}
-void AGDSEngine::runObject(const Common::String &name, const Common::String &prototype) {
+ObjectPtr AGDSEngine::runObject(const Common::String &name, const Common::String &prototype) {
ObjectPtr object = getCurrentScreenObject(name);
if (!object)
object = loadObject(name, prototype);
runObject(object);
+ return object;
}
void AGDSEngine::loadScreen(const Common::String &name) {
@@ -946,8 +947,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
int present = agds_i->readUint32LE();
if (!name.empty() && present) {
debug("inventory: %s %d %d", name.c_str(), unk, present);
- ObjectPtr object = loadObject(name);
- runObject(name);
+ ObjectPtr object = runObject(name);
_inventory.add(object);
}
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 060b36fa65d..5af6cae75a3 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -105,8 +105,8 @@ public:
bool canSaveGameStateCurrently() { return _userEnabled; }
ObjectPtr loadObject(const Common::String & name, const Common::String & prototype = Common::String());
+ ObjectPtr runObject(const Common::String & name, const Common::String &prototype = Common::String());
void runObject(const ObjectPtr &object);
- void runObject(const Common::String & name, const Common::String &prototype = Common::String());
void runProcess(const ObjectPtr &object, uint ip = 0);
void stopProcess(const Common::String & name);
Commit: 4034228dbed1049372148c6bfceb56c4c3a22362
https://github.com/scummvm/scummvm/commit/4034228dbed1049372148c6bfceb56c4c3a22362
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:34+01:00
Commit Message:
AGDS: output handler ips in hex
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 9a9fa2ea99c..2c9483731a2 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -537,13 +537,13 @@ void Process::fadeObject() {
void Process::onObjectUse(uint16 size) {
Common::String arg = popString();
- debug("register use object handler %s -> %u", arg.c_str(), _ip);
+ debug("register use object handler %s -> 0x%04x", arg.c_str(), _ip);
_object->setUseHandler(arg, _ip);
_ip += size;
}
void Process::onObjectUserUse(uint16 size) {
- debug("register user use handler %u", _ip);
+ debug("register user use handler -> 0x%04x", _ip);
_object->setUserUseHandler(_ip);
_ip += size;
}
Commit: 73586595def5490e1793a152646b0cd42b8c87f0
https://github.com/scummvm/scummvm/commit/73586595def5490e1793a152646b0cd42b8c87f0
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:34+01:00
Commit Message:
AGDS: return object position adjusted with offset
Changed paths:
engines/agds/object.h
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 2e4b82e9846..871aa255747 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -197,7 +197,7 @@ public:
}
Common::Point getPosition() const {
- return _pos;
+ return _pos - _offset;
}
Common::Point getOffset() const {
Commit: a66bf2c7f6f330141997c6591d1a5c99b162d306
https://github.com/scummvm/scummvm/commit/a66bf2c7f6f330141997c6591d1a5c99b162d306
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:34+01:00
Commit Message:
AGDS: remove inScene check if looking up objects by name
Changed paths:
engines/agds/agds.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 2bccc543456..a5c2e6eefe4 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -204,6 +204,7 @@ ObjectPtr AGDSEngine::getCurrentScreenObject(const Common::String &name) {
ObjectPtr AGDSEngine::runObject(const Common::String &name, const Common::String &prototype) {
+ debug("runObject %s %s", name.c_str(), prototype.c_str());
ObjectPtr object = getCurrentScreenObject(name);
if (!object)
object = loadObject(name, prototype);
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index c7444e4bdf0..f28f4bc3c9d 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -98,7 +98,7 @@ bool Screen::remove(Animation * animation) {
ObjectPtr Screen::find(const Common::String &name) {
for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr &object = *i;
- if (object->getName() == name && object->inScene())
+ if (object->getName() == name)
return *i;
}
return ObjectPtr();
Commit: 40a7cdb94a6f3678f0b23f3ea16398dba8ab55c4
https://github.com/scummvm/scummvm/commit/40a7cdb94a6f3678f0b23f3ea16398dba8ab55c4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:34+01:00
Commit Message:
AGDS: use runObject instead of loadObject when adding inventory object
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index e95ae715b54..c007470b2d1 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -193,7 +193,7 @@ void Process::run() {
activate();
continue;
case kExitCodeLoadInventoryObject:
- _engine->inventory().add(_engine->loadObject(getExitArg1()));
+ _engine->inventory().add(_engine->runObject(getExitArg1()));
activate();
continue;
case kExitCodeCloseInventory:
Commit: 8ac1bf6ac1afa254ca1ff3034f0f974f8b828839
https://github.com/scummvm/scummvm/commit/8ac1bf6ac1afa254ca1ff3034f0f974f8b828839
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:34+01:00
Commit Message:
AGDS: add Inventory::find() and current object inventory querying
Changed paths:
engines/agds/agds.cpp
engines/agds/inventory.cpp
engines/agds/inventory.h
engines/agds/object.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index a5c2e6eefe4..d6e58c73fcd 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -473,6 +473,9 @@ Common::Error AGDSEngine::run() {
if (userEnabled() && _currentScreen) {
ObjectPtr object = _currentScreen->find(_mouse);
+ if (!object)
+ object = _inventory.find(_mouse);
+
Animation *cursor = object ? object->getMouseCursor() : NULL;
if (cursor)
mouseCursor = cursor;
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 497548fc68d..909d9094faa 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -24,6 +24,7 @@
#include "agds/object.h"
#include "common/debug.h"
#include "common/textconsole.h"
+#include "graphics/transparent_surface.h"
namespace AGDS {
@@ -59,6 +60,23 @@ int Inventory::find(const Common::String &name) const {
return -1;
}
+ObjectPtr Inventory::find(const Common::Point pos) const {
+ for (uint i = 0; i < _entries.size(); ++i) {
+ auto & object = _entries[i];
+ if (!object)
+ continue;
+
+ auto picture = object->getPicture();
+ if (picture) {
+ auto rect = picture->getRect();
+ rect.moveTo(object->getPosition());
+ if (rect.contains(pos))
+ return object;
+ }
+ }
+ return ObjectPtr();
+}
+
void Inventory::clear() {
for (uint i = 0; i < _entries.size(); ++i) {
_entries[i].reset();
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index 20b0b43e427..c20e779b1dd 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/array.h"
#include "common/ptr.h"
+#include "common/rect.h"
namespace AGDS {
class Object;
@@ -62,6 +63,7 @@ public:
ObjectPtr get(int index) const;
int find(const Common::String &name) const;
+ ObjectPtr find(const Common::Point pos) const;
int free() const;
void clear();
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 4198da25994..4ec3e26906e 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -183,7 +183,7 @@ bool Object::pointIn(Common::Point pos) {
void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
if (_picture) {
- Common::Point dst = _pos - _offset;
+ Common::Point dst = getPosition();
Common::Rect srcRect = _picture->getRect();
uint32 color = (_alpha << 24) | 0xffffff; //fixme: _picture->format.ARGBToColor(_alpha, 255, 255, 255); is not working
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect())) {
Commit: c81f277c5059e73867efcb514fedaff230901367
https://github.com/scummvm/scummvm/commit/c81f277c5059e73867efcb514fedaff230901367
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:34+01:00
Commit Message:
AGDS: add reAddInventory(), readd all objects on screen change
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/inventory.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index d6e58c73fcd..c9112a1d646 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -212,6 +212,16 @@ ObjectPtr AGDSEngine::runObject(const Common::String &name, const Common::String
return object;
}
+void AGDSEngine::reAddInventory() {
+ if (!_currentScreen)
+ return;
+
+ for(auto & object : _inventory.entries()) {
+ if (object)
+ runObject(object);
+ }
+}
+
void AGDSEngine::loadScreen(const Common::String &name) {
_nextScreenName.clear();
debug("loadScreen %s", name.c_str());
@@ -243,6 +253,7 @@ void AGDSEngine::loadScreen(const Common::String &name) {
if (!patch->defaultMouseCursor.empty())
loadDefaultMouseCursor(patch->defaultMouseCursor);
}
+ reAddInventory();
}
void AGDSEngine::resetCurrentScreen() {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 5af6cae75a3..7e325de7722 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -251,6 +251,8 @@ public:
return _hintMode;
}
+ void reAddInventory();
+
private:
void loadPatches(Common::SeekableReadStream *file, Database & db);
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index c20e779b1dd..bb1008c7e02 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -68,6 +68,10 @@ public:
int free() const;
void clear();
+ const EntriesType & entries() const {
+ return _entries;
+ }
+
int maxSize() const {
return _entries.size();
}
Commit: 87dafd429baa4407d8a5537846d9c827bba21469
https://github.com/scummvm/scummvm/commit/87dafd429baa4407d8a5537846d9c827bba21469
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:34+01:00
Commit Message:
AGDS: move reactivate to process API
Changed paths:
engines/agds/agds.h
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 7e325de7722..009c9417e6f 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -109,6 +109,7 @@ public:
void runObject(const ObjectPtr &object);
void runProcess(const ObjectPtr &object, uint ip = 0);
void stopProcess(const Common::String & name);
+ void reactivate(const Common::String &name, bool runNow = false);
void resetCurrentScreen();
void loadScreen(const Common::String & name);
@@ -245,7 +246,6 @@ public:
return _mouse;
}
- void reactivate(const Common::String &name, bool runNow = false);
bool showHints() const {
return _hintMode;
Commit: 4efc1a95c76ebffeaed35b1eab9505280a878558
https://github.com/scummvm/scummvm/commit/4efc1a95c76ebffeaed35b1eab9505280a878558
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:35+01:00
Commit Message:
AGDS: implement removing from inventory
Changed paths:
engines/agds/inventory.cpp
engines/agds/inventory.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 909d9094faa..de007c4084f 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -53,6 +53,18 @@ int Inventory::add(const ObjectPtr & object) {
error("inventory overflow");
}
+bool Inventory::remove(const Common::String &name) {
+ bool removed = false;
+ for (uint i = 0; i < _entries.size(); ++i) {
+ auto & object = _entries[i];
+ if (object && object->getName() == name) {
+ object.reset();
+ removed = true;
+ }
+ }
+ return removed;
+}
+
int Inventory::find(const Common::String &name) const {
for (uint i = 0; i < _entries.size(); ++i)
if (_entries[i] && _entries[i]->getName() == name)
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index bb1008c7e02..4fbd7d35e51 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -60,6 +60,7 @@ public:
}
int add(const ObjectPtr & object);
+ bool remove(const Common::String &name);
ObjectPtr get(int index) const;
int find(const Common::String &name) const;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 0d0a6dd31c4..97c4ff9688d 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -129,7 +129,7 @@ enum Opcode {
kStub109 = 109,
kStub110 = 110,
kInventoryAddObject = 111,
- kStub112 = 112,
+ kInventoryRemoveObject = 112,
kStub113 = 113,
kStub114 = 114,
kStub115 = 115,
@@ -340,6 +340,7 @@ enum Opcode {
OP(kInventoryClear, inventoryClear) \
OP(kLoadMouse, loadMouse) \
OP(kInventoryAddObject, inventoryAddObject) \
+ OP(kInventoryRemoveObject, inventoryRemoveObject) \
OP(kSetNextScreenSaveInHistory, setNextScreenSaveInHistory) \
OP_U(kObjectRegisterUseObjectHandler, onObjectUse) \
OP(kStub82, stub82) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 2c9483731a2..614da4487c0 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1095,6 +1095,12 @@ void Process::inventoryAddObject() {
suspend(kExitCodeLoadInventoryObject, name);
}
+void Process::inventoryRemoveObject() {
+ Common::String name = popString();
+ debug("inventoryRemoveObject %s", name.c_str());
+ _engine->inventory().remove(name);
+}
+
void Process::inventoryFindObjectByName() {
Common::String name = popString();
debug("inventoryFindObjectByName %s", name.c_str());
Commit: d98b5d08b4d6c9748b9b63e36710606190ae16d9
https://github.com/scummvm/scummvm/commit/d98b5d08b4d6c9748b9b63e36710606190ae16d9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:35+01:00
Commit Message:
AGDS: implement current object support and call 'use object with' handlers
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/object.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c9112a1d646..01c8e171c33 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -458,13 +458,36 @@ Common::Error AGDSEngine::run() {
if (userEnabled()) {
bool lclick = event.type == Common::EVENT_LBUTTONDOWN;
debug("%s %d, %d", lclick ? "lclick" : "rclick", _mouse.x, _mouse.y);
+ if (!lclick && _currentInventoryObject) {
+ auto object = _currentInventoryObject;
+ _currentInventoryObject.reset();
+
+ _inventory.add(object);
+ runObject(object);
+ break;
+ }
ObjectPtr object = _currentScreen->find(_mouse);
+
+ if (!object && !_currentInventoryObject) //allow inventory to be selected
+ object = _inventory.find(_mouse);
+
if (object) {
- uint ip = lclick ? object->getClickHandler() : object->getExamineHandler();
+ debug("found object %s", object->title().c_str());
+ uint ip;
+ if (lclick) {
+ if (_currentInventoryObject) {
+ debug("trying use handler for object %s", _currentInventoryObject->getName().c_str());
+ ip = object->getUseHandler(_currentInventoryObject->getName());
+ } else
+ ip = object->getClickHandler();
+ } else
+ ip = object->getExamineHandler();
+
if (ip) {
debug("found handler: %s %08x", object->getName().c_str(), ip + 7);
runProcess(object, ip);
- }
+ } else
+ debug("no handler found");
}
}
break;
@@ -526,9 +549,19 @@ Common::Error AGDSEngine::run() {
if (!mouseCursor)
mouseCursor = _defaultMouseCursor;
- if (userEnabled() && mouseCursor) {
- mouseCursor->tick(*this);
- mouseCursor->paint(*this, *backbuffer, _mouse);
+ if (userEnabled()) {
+ if (_currentInventoryObject) {
+ auto picture = _currentInventoryObject->getPicture();
+ Common::Point dst = _mouse;
+ Common::Rect srcRect = picture->getRect();
+ uint32 color = (_currentInventoryObject->alpha() << 24) | 0xffffff; //fixme: _picture->format.ARGBToColor(_alpha, 255, 255, 255); is not working
+ if (Common::Rect::getBlitRect(dst, srcRect, backbuffer->getRect())) {
+ picture->blit(*backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
+ }
+ } else {
+ mouseCursor->tick(*this);
+ mouseCursor->paint(*this, *backbuffer, _mouse);
+ }
}
if (_textLayout.valid()) {
@@ -999,4 +1032,12 @@ void AGDSEngine::stopProcess(const Common::String & name) {
Common::Error AGDSEngine::saveGameStream(Common::WriteStream *file, bool isAutosave) { return Common::Error(Common::kNoError); }
+void AGDSEngine::currentInventoryObject(const ObjectPtr & object) {
+ _currentInventoryObject = object;
+}
+
+void AGDSEngine::resetCurrentInventoryObject() {
+ _currentInventoryObject.reset();
+}
+
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 009c9417e6f..b672043e68f 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -246,6 +246,12 @@ public:
return _mouse;
}
+ void currentInventoryObject(const ObjectPtr & object);
+ void resetCurrentInventoryObject();
+
+ const ObjectPtr & currentInventoryObject() const {
+ return _currentInventoryObject;
+ }
bool showHints() const {
return _hintMode;
@@ -299,9 +305,12 @@ private:
bool _systemUserEnabled;
MouseMap _mouseMap;
Common::RandomSource _random;
+
Inventory _inventory;
Common::String _inventoryRegionName;
RegionPtr _inventoryRegion;
+ ObjectPtr _currentInventoryObject;
+
Dialog _dialog;
// Original engine use weird names for the vars, I keep them.
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 871aa255747..62ff277a5b3 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -130,6 +130,10 @@ public:
_alpha = (100 - alpha) * 255 / 100;
}
+ int alpha() const {
+ return _alpha;
+ }
+
void scale(int scale) {
_scale = scale;
}
@@ -164,9 +168,17 @@ public:
_useHandlers[name] = ip;
}
+ uint getUseHandler(const Common::String &name) const {
+ return _useHandlers.getVal(name, 0); //use handler can never be 0
+ }
+
void setUserUseHandler(uint ip) {
+ debug("OBJECT %s USER USE %04x", _name.c_str(), ip);
_userUseHandler = ip;
}
+ uint getUserUseHandler() const {
+ return _userUseHandler;
+ }
void paint(AGDSEngine &engine, Graphics::Surface &backbuffer);
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 97c4ff9688d..c1dac0e0f73 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -127,7 +127,7 @@ enum Opcode {
kStub107 = 107,
kLoadMouse = 108,
kStub109 = 109,
- kStub110 = 110,
+ kResetMousePointer = 110,
kInventoryAddObject = 111,
kInventoryRemoveObject = 112,
kStub113 = 113,
@@ -262,7 +262,7 @@ enum Opcode {
kHasGlobal = 242,
kStub243 = 243,
kSetCharacterNotifyVars = 244,
- kStub245 = 245,
+ kAttachInventoryObjectToMouse = 245,
kStub246 = 246,
kSetDialogForNextFilm = 247
};
@@ -339,6 +339,7 @@ enum Opcode {
OP(kClearScreen, clearScreen) \
OP(kInventoryClear, inventoryClear) \
OP(kLoadMouse, loadMouse) \
+ OP(kResetMousePointer, resetMousePointer) \
OP(kInventoryAddObject, inventoryAddObject) \
OP(kInventoryRemoveObject, inventoryRemoveObject) \
OP(kSetNextScreenSaveInHistory, setNextScreenSaveInHistory) \
@@ -463,6 +464,7 @@ enum Opcode {
OP(kInventoryFindObjectByName, inventoryFindObjectByName) \
OP(kLoadDialog, loadDialog) \
OP(kHasGlobal, hasGlobal) \
+ OP(kAttachInventoryObjectToMouse, attachInventoryObjectToMouse) \
OP(kSetDialogForNextFilm, setDialogForNextFilm)
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 614da4487c0..98127e51ca5 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -288,6 +288,10 @@ void Process::loadMouse() {
_engine->loadDefaultMouseCursor(name);
}
+void Process::resetMousePointer() {
+ _engine->currentInventoryObject(ObjectPtr());
+}
+
void Process::getRandomNumber() {
int max = pop();
int value = max > 0 ? _engine->_random.getRandomNumber(max - 1) : 0;
@@ -524,6 +528,16 @@ void Process::loadMouseCursorFromObject() {
_object->setMouseCursor(cursor); //overlay cursor
}
+void Process::attachInventoryObjectToMouse() {
+ Common::String name = popString();
+ debug("attachInventoryObjectToMouse %s", name.c_str());
+ auto object = _engine->getCurrentScreenObject(name);
+ if (object)
+ _engine->currentInventoryObject(object);
+ else
+ warning("cannot find object %s", name.c_str());
+}
+
void Process::fadeObject() {
int value = pop();
Common::String name = popString();
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index f28f4bc3c9d..e11eabd1ea0 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -135,6 +135,7 @@ Animation *Screen::findAnimationByPhaseVar(const Common::String &phaseVar) {
}
void Screen::paint(Graphics::Surface &backbuffer) {
+ auto & currentInventoryObject = _engine->currentInventoryObject();
for(uint i = 0; i < _animations.size(); ) {
Animation *animation = _animations.data()[i];
if (animation->tick(*_engine))
@@ -180,7 +181,7 @@ void Screen::paint(Graphics::Surface &backbuffer) {
switch (render_type) {
case 0:
//debug("object z: %d", (*child)->z());
- if ((*child)->inScene())
+ if ((*child) != currentInventoryObject && (*child)->inScene())
(*child)->paint(*_engine, backbuffer);
++child;
break;
Commit: b2e504092c8d315c3e2e38a1e4895fdfc2233abd
https://github.com/scummvm/scummvm/commit/b2e504092c8d315c3e2e38a1e4895fdfc2233abd
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:35+01:00
Commit Message:
AGDS: use skipFilm on film eos
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 01c8e171c33..e7933f2caa7 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -538,9 +538,7 @@ Common::Error AGDSEngine::run() {
}
if (_mjpgPlayer->eos()) {
- delete _mjpgPlayer;
- _mjpgPlayer = NULL;
- reactivate(_filmProcess);
+ skipFilm();
}
} else if (_currentScreen) {
_currentScreen->paint(*backbuffer);
Commit: 3822839c46beee6fb24130d39071b4c8c4fa7a24
https://github.com/scummvm/scummvm/commit/3822839c46beee6fb24130d39071b4c8c4fa7a24
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:35+01:00
Commit Message:
AGDS: play audio for films
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index e7933f2caa7..ee7005e64e0 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -607,6 +607,8 @@ void AGDSEngine::playFilm(Process &process, const Common::String &video, const C
_filmProcess = process.getName();
_mjpgPlayer = new MJPGPlayer(_resourceManager.getResource(video));
+ _soundManager.stopAll();
+ _syncSoundId = _soundManager.play(process.getName(), audio, Common::String());
}
void AGDSEngine::skipFilm() {
Commit: 1eb8f936e48c85bbbdf631be6dd15c98cf3eee0c
https://github.com/scummvm/scummvm/commit/1eb8f936e48c85bbbdf631be6dd15c98cf3eee0c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:35+01:00
Commit Message:
AGDS: implement subtitles for films
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/mjpgPlayer.cpp
engines/agds/mjpgPlayer.h
engines/agds/object.cpp
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ee7005e64e0..eca338baa28 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -525,17 +525,7 @@ Common::Error AGDSEngine::run() {
}
if (_mjpgPlayer) {
- const Graphics::Surface *surface = _mjpgPlayer->decodeFrame();
-
- if (surface) {
- Graphics::Surface *converted = surface->convertTo(_pixelFormat);
- Common::Point dst((backbuffer->w - converted->w) / 2, (backbuffer->h - converted->h) / 2);
- Common::Rect srcRect(converted->getRect());
- if (Common::Rect::getBlitRect(dst, srcRect, backbuffer->getRect()))
- backbuffer->copyRectToSurface(*converted, dst.x, dst.y, srcRect);
- converted->free();
- delete converted;
- }
+ _mjpgPlayer->paint(*this, *backbuffer);
if (_mjpgPlayer->eos()) {
skipFilm();
@@ -597,8 +587,9 @@ Common::Error AGDSEngine::run() {
return Common::kNoError;
}
-void AGDSEngine::playFilm(Process &process, const Common::String &video, const Common::String &audio) {
+void AGDSEngine::playFilm(Process &process, const Common::String &video, const Common::String &audio, const Common::String &subtitles) {
delete _mjpgPlayer;
+ _mjpgPlayer = nullptr;
if (_fastMode) {
debug("fast mode, skipping film");
process.activate();
@@ -606,7 +597,7 @@ void AGDSEngine::playFilm(Process &process, const Common::String &video, const C
}
_filmProcess = process.getName();
- _mjpgPlayer = new MJPGPlayer(_resourceManager.getResource(video));
+ _mjpgPlayer = new MJPGPlayer(_resourceManager.getResource(video), subtitles);
_soundManager.stopAll();
_syncSoundId = _soundManager.play(process.getName(), audio, Common::String());
}
@@ -691,7 +682,9 @@ void AGDSEngine::loadCharacter(const Common::String &id, const Common::String &f
_currentCharacter->load(_resourceManager.getResource(filename));
}
-Graphics::TransparentSurface *AGDSEngine::loadPicture(const Common::String &name) { return convertToTransparent(_resourceManager.loadPicture(name, _pixelFormat)); }
+Graphics::TransparentSurface *AGDSEngine::loadPicture(const Common::String &name) {
+ return convertToTransparent(_resourceManager.loadPicture(name, _pixelFormat));
+}
int AGDSEngine::loadFromCache(const Common::String &name) const {
PictureCacheLookup::const_iterator i = _pictureCacheLookup.find(name);
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index b672043e68f..3fdfebe8262 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -121,7 +121,7 @@ public:
const Common::String & getSharedStorage(int id) const;
bool active() const { return !_mjpgPlayer && !(_soundManager.playing(_syncSoundId) || _tellTextTimer > 0); }
- void playFilm(Process &process, const Common::String &video, const Common::String &audio);
+ void playFilm(Process &process, const Common::String &video, const Common::String &audio, const Common::String &subtitles);
void skipFilm();
ResourceManager & resourceManager() {
diff --git a/engines/agds/mjpgPlayer.cpp b/engines/agds/mjpgPlayer.cpp
index 9105cbdd229..598b2357287 100644
--- a/engines/agds/mjpgPlayer.cpp
+++ b/engines/agds/mjpgPlayer.cpp
@@ -21,11 +21,38 @@
*/
#include "agds/mjpgPlayer.h"
+#include "agds/agds.h"
+#include "agds/font.h"
+#include "agds/object.h"
+#include "agds/systemVariable.h"
#include "common/debug.h"
namespace AGDS {
-MJPGPlayer::MJPGPlayer(Common::SeekableReadStream *stream) : _stream(stream), _firstFramePos(_stream->pos()) {
+MJPGPlayer::MJPGPlayer(Common::SeekableReadStream *stream, const Common::String &subtitles) :
+ _stream(stream), _firstFramePos(_stream->pos()), _framesPlayed(0), _nextSubtitleIndex(0) {
+ uint pos = 0;
+ while(pos < subtitles.size()) {
+ auto next = subtitles.find('\n', pos);
+ if (next == subtitles.npos)
+ next = subtitles.size();
+ Common::String line = subtitles.substr(pos, next - pos);
+
+ uint begin, end;
+ int offset;
+ if (sscanf(line.c_str(), "{%u}{%u}%n", &begin, &end, &offset) != 2) {
+ warning("malformed subtitle line: %s", line.c_str());
+ pos = next + 1;
+ continue;
+ }
+ while(offset < static_cast<int>(line.size()) && line[offset] == ' ')
+ ++offset;
+
+ line = line.substr(offset);
+ debug("subtitle line: %d-%d: %s", begin, end, line.c_str());
+ _subtitles.push_back({begin, end, line});
+ pos = next + 1;
+ }
}
MJPGPlayer::~MJPGPlayer() {
@@ -33,6 +60,8 @@ MJPGPlayer::~MJPGPlayer() {
}
void MJPGPlayer::rewind() {
+ _framesPlayed = 0;
+ _nextSubtitleIndex = 0;
_stream->seek(_firstFramePos);
}
@@ -48,8 +77,40 @@ const Graphics::Surface *MJPGPlayer::decodeFrame() {
return NULL;
Common::SeekableReadStream *stream = _stream->readStream(size);
const Graphics::Surface *surface = _decoder.decodeFrame(*stream);
+ ++_framesPlayed;
delete stream;
return surface;
}
+void MJPGPlayer::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
+ auto *surface = decodeFrame();
+ if (surface) {
+ Graphics::Surface *converted = surface->convertTo(engine.pixelFormat());
+ Common::Point dst((backbuffer.w - converted->w) / 2, (backbuffer.h - converted->h) / 2);
+ Common::Rect srcRect(converted->getRect());
+ if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
+ backbuffer.copyRectToSurface(*converted, dst.x, dst.y, srcRect);
+ converted->free();
+ delete converted;
+ }
+
+ if (_subtitles.empty())
+ return;
+
+ while(_nextSubtitleIndex < _subtitles.size() && _framesPlayed > _subtitles[_nextSubtitleIndex].end)
+ ++_nextSubtitleIndex;
+
+ if (_nextSubtitleIndex >= _subtitles.size() || _framesPlayed < _subtitles[_nextSubtitleIndex].begin)
+ return;
+
+ auto font = engine.getFont(engine.getSystemVariable("tell_font")->getInteger());
+ int x = engine.getSystemVariable("subtitle_x")->getInteger();
+ int y = engine.getSystemVariable("subtitle_y")->getInteger();
+
+ auto & text = _subtitles[_nextSubtitleIndex].line;
+ x -= font->getStringWidth(text) / 2;
+ font->drawString(&backbuffer, text, x, y, backbuffer.w, 0);
+}
+
+
} // namespace AGDS
diff --git a/engines/agds/mjpgPlayer.h b/engines/agds/mjpgPlayer.h
index 4869e66e049..607aab2364a 100644
--- a/engines/agds/mjpgPlayer.h
+++ b/engines/agds/mjpgPlayer.h
@@ -24,19 +24,32 @@
#define AGDS_MJPG_PLAYER_H
#include "common/scummsys.h"
+#include "common/array.h"
#include "common/stream.h"
+#include "common/str.h"
#include "graphics/surface.h"
#include "image/jpeg.h"
namespace AGDS {
+class AGDSEngine;
class MJPGPlayer {
- Common::SeekableReadStream * _stream;
- int32 _firstFramePos;
- Image::JPEGDecoder _decoder;
+ Common::SeekableReadStream * _stream;
+ int32 _firstFramePos;
+ Image::JPEGDecoder _decoder;
+ uint _framesPlayed;
+
+ struct Text {
+ uint begin;
+ uint end;
+ Common::String line;
+ };
+
+ Common::Array<Text> _subtitles;
+ uint _nextSubtitleIndex;
public:
- MJPGPlayer(Common::SeekableReadStream * stream);
+ MJPGPlayer(Common::SeekableReadStream * stream, const Common::String &subtitles);
~MJPGPlayer();
bool eos() {
@@ -45,6 +58,7 @@ public:
void rewind();
const Graphics::Surface *decodeFrame();
+ void paint(AGDSEngine &engine, Graphics::Surface &backbuffer);
};
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 4ec3e26906e..75560bf4844 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -205,7 +205,7 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
if (engine.showHints() && !_title.empty()) {
Common::Point pos = _region ? _region->center : _pos;
int w = backbuffer.w - pos.x;
- auto font = engine.getFont(engine.getSystemVariable("edit_font")->getInteger());
+ auto font = engine.getFont(engine.getSystemVariable("tell_font")->getInteger());
pos.x -= font->getStringWidth(_title) / 2;
font->drawString(&backbuffer, _title, pos.x, pos.y, w, 0);
}
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index c007470b2d1..17bc2ee8374 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -33,7 +33,8 @@ Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) : _engine(en
_tileWidth(16), _tileHeight(16), _tileResource(0), _tileIndex(0),
_timer(0),
_animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0),
- _phaseVarControlled(false), _animationSpeed(100), _samplePeriodic(false)
+ _phaseVarControlled(false), _animationSpeed(100), _samplePeriodic(false),
+ _filmSubtitlesResource(-1)
{
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 5a0ce19b71f..90cf0313119 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -66,6 +66,7 @@ private:
int _animationSpeed;
bool _samplePeriodic;
Common::Point _mousePosition;
+ int _filmSubtitlesResource;
private:
void debug(const char *str, ...);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 98127e51ca5..4a29738a052 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -632,6 +632,8 @@ void Process::resetState() {
_tileHeight = 16;
_tileIndex = 0;
_tileResource = 0;
+
+ _filmSubtitlesResource = -1;
}
void Process::setAnimationZ() {
@@ -1004,8 +1006,8 @@ void Process::quit() {
}
void Process::setDialogForNextFilm() {
- int value = pop();
- debug("setDialogForNextFilm %d", value);
+ _filmSubtitlesResource = pop();
+ debug("setDialogForNextFilm %d", _filmSubtitlesResource);
}
void Process::tell(bool npc, const Common::String &sound) {
@@ -1092,10 +1094,11 @@ void Process::getObjectPictureHeight() {
void Process::playFilm() {
Common::String audio = popText();
Common::String video = popText();
+ Common::String subtitles = _engine->loadText(getString(_filmSubtitlesResource));
- debug("playFilm %s %s", video.c_str(), audio.c_str());
+ debug("playFilm %s %s %s", video.c_str(), audio.c_str(), subtitles.c_str());
suspend();
- _engine->playFilm(*this, video, audio);
+ _engine->playFilm(*this, video, audio, subtitles);
}
void Process::inventoryClear() {
Commit: 41214d417576a0657d66cf4ed3b306746e00b757
https://github.com/scummvm/scummvm/commit/41214d417576a0657d66cf4ed3b306746e00b757
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:35+01:00
Commit Message:
AGDS: implement proper video synchronisation
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/mjpgPlayer.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index eca338baa28..0e44c7c4c51 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -48,7 +48,8 @@ namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Engine(system),
_gameDescription(gameDesc), _pictureCacheId(1), _sharedStorageIndex(-2),
_processes(MaxProcesses),
- _mjpgPlayer(), _currentScreen(), _currentCharacter(),
+ _mjpgPlayer(), _filmStarted(0),
+ _currentScreen(), _currentCharacter(),
_defaultMouseCursor(),
_mouse(400, 300),
_userEnabled(true), _systemUserEnabled(true),
@@ -575,12 +576,19 @@ Common::Error AGDSEngine::run() {
_system->updateScreen();
if (!_fastMode) {
- static const uint32 kFPS = 25;
- static const uint32 kMaxTick = 1000 / kFPS;
+ if (_mjpgPlayer) {
+ uint32 elapsed = _system->getMillis() - _filmStarted;
+ uint32 expected = _mjpgPlayer->getNextFrameTimestamp();
+ if (expected > elapsed)
+ _system->delayMillis(expected - elapsed);
+ } else {
+ static const uint32 kFPS = 25;
+ static const uint32 kMaxTick = 1000 / kFPS;
- uint32 dt = _system->getMillis() - frameStarted;
- if (dt < kMaxTick)
- _system->delayMillis(kMaxTick - dt);
+ uint32 dt = _system->getMillis() - frameStarted;
+ if (dt < kMaxTick)
+ _system->delayMillis(kMaxTick - dt);
+ }
}
}
@@ -599,6 +607,7 @@ void AGDSEngine::playFilm(Process &process, const Common::String &video, const C
_filmProcess = process.getName();
_mjpgPlayer = new MJPGPlayer(_resourceManager.getResource(video), subtitles);
_soundManager.stopAll();
+ _filmStarted = _system->getMillis();
_syncSoundId = _soundManager.play(process.getName(), audio, Common::String());
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 3fdfebe8262..cd7c892d3b5 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -289,6 +289,7 @@ private:
SystemVariablesType _systemVars;
Graphics::PixelFormat _pixelFormat;
MJPGPlayer * _mjpgPlayer;
+ uint32 _filmStarted;
Common::String _filmProcess;
Screen * _currentScreen;
Common::String _currentScreenName;
diff --git a/engines/agds/mjpgPlayer.h b/engines/agds/mjpgPlayer.h
index 607aab2364a..66be3d0a710 100644
--- a/engines/agds/mjpgPlayer.h
+++ b/engines/agds/mjpgPlayer.h
@@ -59,6 +59,10 @@ public:
void rewind();
const Graphics::Surface *decodeFrame();
void paint(AGDSEngine &engine, Graphics::Surface &backbuffer);
+
+ uint32 getNextFrameTimestamp() const {
+ return _framesPlayed * 1000 / 24;
+ }
};
Commit: 6707b3d40e5a15627f766038380fd4c1c853a442
https://github.com/scummvm/scummvm/commit/6707b3d40e5a15627f766038380fd4c1c853a442
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:35+01:00
Commit Message:
AGDS: better frame delta (single getMillis call per frame)
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 0e44c7c4c51..9b88b451abf 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -379,9 +379,8 @@ Common::Error AGDSEngine::run() {
Common::EventManager *eventManager = _system->getEventManager();
+ uint32 frameStarted = _system->getMillis();
while (!shouldQuit()) {
- uint32 frameStarted = _system->getMillis();
-
Common::Event event;
while (eventManager->pollEvent(event)) {
if (!_currentScreen)
@@ -576,8 +575,9 @@ Common::Error AGDSEngine::run() {
_system->updateScreen();
if (!_fastMode) {
+ uint32 ts = _system->getMillis();
if (_mjpgPlayer) {
- uint32 elapsed = _system->getMillis() - _filmStarted;
+ uint32 elapsed = ts - _filmStarted;
uint32 expected = _mjpgPlayer->getNextFrameTimestamp();
if (expected > elapsed)
_system->delayMillis(expected - elapsed);
@@ -585,10 +585,11 @@ Common::Error AGDSEngine::run() {
static const uint32 kFPS = 25;
static const uint32 kMaxTick = 1000 / kFPS;
- uint32 dt = _system->getMillis() - frameStarted;
+ uint32 dt = ts - frameStarted;
if (dt < kMaxTick)
_system->delayMillis(kMaxTick - dt);
}
+ frameStarted = ts;
}
}
Commit: 48844cae1996b418cd9b51497ada1f05783ae73a
https://github.com/scummvm/scummvm/commit/48844cae1996b418cd9b51497ada1f05783ae73a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:35+01:00
Commit Message:
AGDS: add support for newline character in subtitles
Changed paths:
engines/agds/mjpgPlayer.cpp
engines/agds/mjpgPlayer.h
diff --git a/engines/agds/mjpgPlayer.cpp b/engines/agds/mjpgPlayer.cpp
index 598b2357287..f5365d0322c 100644
--- a/engines/agds/mjpgPlayer.cpp
+++ b/engines/agds/mjpgPlayer.cpp
@@ -50,7 +50,18 @@ MJPGPlayer::MJPGPlayer(Common::SeekableReadStream *stream, const Common::String
line = line.substr(offset);
debug("subtitle line: %d-%d: %s", begin, end, line.c_str());
- _subtitles.push_back({begin, end, line});
+ Text::Lines lines;
+ {
+ uint lineBegin = 0;
+ while(lineBegin < line.size()) {
+ uint lineEnd = line.find('|', lineBegin);
+ if (lineEnd == line.npos)
+ lineEnd = line.size();
+ lines.push_back(line.substr(lineBegin, lineEnd - lineBegin));
+ lineBegin = lineEnd + 1;
+ }
+ }
+ _subtitles.push_back({begin, end, lines});
pos = next + 1;
}
}
@@ -104,12 +115,16 @@ void MJPGPlayer::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
return;
auto font = engine.getFont(engine.getSystemVariable("tell_font")->getInteger());
- int x = engine.getSystemVariable("subtitle_x")->getInteger();
- int y = engine.getSystemVariable("subtitle_y")->getInteger();
-
- auto & text = _subtitles[_nextSubtitleIndex].line;
- x -= font->getStringWidth(text) / 2;
- font->drawString(&backbuffer, text, x, y, backbuffer.w, 0);
+ int baseX = engine.getSystemVariable("subtitle_x")->getInteger();
+ int baseY = engine.getSystemVariable("subtitle_y")->getInteger();
+
+ auto & lines = _subtitles[_nextSubtitleIndex].lines;
+ for(auto & line : lines) {
+ int w = font->getStringWidth(line);
+ int x = baseX - w / 2;
+ font->drawString(&backbuffer, line, x, baseY, backbuffer.w - x, 0);
+ baseY += font->getFontHeight();
+ }
}
diff --git a/engines/agds/mjpgPlayer.h b/engines/agds/mjpgPlayer.h
index 66be3d0a710..8131b20c199 100644
--- a/engines/agds/mjpgPlayer.h
+++ b/engines/agds/mjpgPlayer.h
@@ -40,9 +40,11 @@ class MJPGPlayer {
uint _framesPlayed;
struct Text {
+ using Lines = Common::Array<Common::String>;
+
uint begin;
uint end;
- Common::String line;
+ Lines lines;
};
Common::Array<Text> _subtitles;
Commit: 54f726adff961a1528e63366e393bb7f52d1aee8
https://github.com/scummvm/scummvm/commit/54f726adff961a1528e63366e393bb7f52d1aee8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:35+01:00
Commit Message:
AGDS: wrap long subtitle lines
Changed paths:
engines/agds/mjpgPlayer.cpp
diff --git a/engines/agds/mjpgPlayer.cpp b/engines/agds/mjpgPlayer.cpp
index f5365d0322c..7656a6de570 100644
--- a/engines/agds/mjpgPlayer.cpp
+++ b/engines/agds/mjpgPlayer.cpp
@@ -117,13 +117,18 @@ void MJPGPlayer::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
auto font = engine.getFont(engine.getSystemVariable("tell_font")->getInteger());
int baseX = engine.getSystemVariable("subtitle_x")->getInteger();
int baseY = engine.getSystemVariable("subtitle_y")->getInteger();
+ int maxWidth = engine.getSystemVariable("subtitle_width")->getInteger();
auto & lines = _subtitles[_nextSubtitleIndex].lines;
for(auto & line : lines) {
- int w = font->getStringWidth(line);
- int x = baseX - w / 2;
- font->drawString(&backbuffer, line, x, baseY, backbuffer.w - x, 0);
- baseY += font->getFontHeight();
+ Text::Lines sublines;
+ font->wordWrapText(line, maxWidth, sublines);
+ for(auto & subline : sublines) {
+ int w = font->getStringWidth(subline);
+ int x = baseX - w / 2;
+ font->drawString(&backbuffer, subline, x, baseY, backbuffer.w - x, 0);
+ baseY += font->getFontHeight();
+ }
}
}
Commit: e3140c3113fb8fac171f5ea71724399765f8e4a3
https://github.com/scummvm/scummvm/commit/e3140c3113fb8fac171f5ea71724399765f8e4a3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:35+01:00
Commit Message:
AGDS: fix audio disappearance on scene change
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 9b88b451abf..3cbf8c7cbd6 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -241,7 +241,6 @@ void AGDSEngine::loadScreen(const Common::String &name) {
}
_animations.clear();
- _soundManager.stopAll();
_currentScreenName = name;
//SAVE CURRENT OBJECTS IN PATCH see save_screen_patch
_currentScreen = new Screen(this, loadObject(name));
@@ -967,7 +966,8 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
Common::String phaseVar = readString(agds_a.get());
uint unk0 = agds_a->readUint32LE();
uint unk1 = agds_a->readUint32LE();
- debug("saved audio state: sample: %s, var: %s %u %u", sample.c_str(), phaseVar.c_str(), unk0, unk1);
+ debug("saved audio state: sample: '%s', var: '%s' %u %u", sample.c_str(), phaseVar.c_str(), unk0, unk1);
+ debug("phase var for sample -> %d", getGlobal(phaseVar));
playSound(Common::String(), sample, phaseVar); //fixme: double check
}
Commit: db6654f0570b13a7d8abe4bfdb19262dc562f2f7
https://github.com/scummvm/scummvm/commit/db6654f0570b13a7d8abe4bfdb19262dc562f2f7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:36+01:00
Commit Message:
AGDS: remove comment
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3cbf8c7cbd6..b65857fd1c9 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -242,7 +242,6 @@ void AGDSEngine::loadScreen(const Common::String &name) {
_animations.clear();
_currentScreenName = name;
- //SAVE CURRENT OBJECTS IN PATCH see save_screen_patch
_currentScreen = new Screen(this, loadObject(name));
runProcess(_currentScreen->getObject());
Commit: 1525da8bf56eb4dbad5b85aab3b7d657a02e2851
https://github.com/scummvm/scummvm/commit/1525da8bf56eb4dbad5b85aab3b7d657a02e2851
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:36+01:00
Commit Message:
AGDS: fixed object restart
Changed paths:
engines/agds/screen.cpp
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index e11eabd1ea0..11aeacc5fc2 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -235,8 +235,11 @@ void Screen::load(const PatchPtr &patch) {
debug("patch object %s %d", object.name.c_str(), object.flag);
if (object.flag <= 0)
remove(object.name);
- else if (!find(object.name)) {
- _engine->runObject(object.name);
+ else {
+ auto instance = find(object.name); //find by name finds removed objects too
+ if (!instance || !instance->inScene()) {
+ _engine->runObject(object.name);
+ }
}
}
_applyingPatch = false;
Commit: 7e9982cb83d94f02366fa40decd9e002bca1bbf9
https://github.com/scummvm/scummvm/commit/7e9982cb83d94f02366fa40decd9e002bca1bbf9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:36+01:00
Commit Message:
AGDS: do not return removed objects from Screen::find()
Changed paths:
engines/agds/screen.cpp
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 11aeacc5fc2..1b71596b26c 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -204,7 +204,7 @@ void Screen::paint(Graphics::Surface &backbuffer) {
ObjectPtr Screen::find(Common::Point pos) const {
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
- if (object->pointIn(pos))
+ if (object->pointIn(pos) && object->inScene())
return object;
}
return ObjectPtr();
Commit: 110a79c0cb7dd58823f84a212d4583246b0fad28
https://github.com/scummvm/scummvm/commit/110a79c0cb7dd58823f84a212d4583246b0fad28
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:36+01:00
Commit Message:
AGDS: split log to avoid confusion
Changed paths:
engines/agds/patch.cpp
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index ab095a7034b..c402f5d63e4 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -25,7 +25,8 @@ void Patch::load(Common::SeekableReadStream *stream) {
characterY = stream->readUint32LE();
characterDirection = stream->readUint32LE();
unk51 = stream->readUint32LE();
- debug("unknown entries: %u (character at %u,%u with dir: %u) %u", unk41, characterX, characterY, characterDirection, unk51);
+ debug("character at %u,%u with dir: %u", characterX, characterY, characterDirection);
+ debug("unknown entries: %u %u", unk41, unk51);
uint object_count = stream->readUint32LE();
debug("objects in this patch: %u", object_count);
if (stream->read(palette, sizeof(palette)) != sizeof(palette)) {
Commit: c346a72047e7c5d73344eb0d9de5e42ef282a777
https://github.com/scummvm/scummvm/commit/c346a72047e7c5d73344eb0d9de5e42ef282a777
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:36+01:00
Commit Message:
AGDS: load/store character position/direction in patch
Changed paths:
engines/agds/agds.cpp
engines/agds/patch.cpp
engines/agds/patch.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index b65857fd1c9..1007f3857cd 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -232,6 +232,11 @@ void AGDSEngine::loadScreen(const Common::String &name) {
if (!patch)
patch = PatchPtr(new Patch());
_currentScreen->save(patch);
+ patch->characterPresent = _currentCharacter != nullptr;
+ if (_currentCharacter) {
+ patch->characterPosition = _currentCharacter->position();
+ patch->characterDirection = _currentCharacter->direction();
+ }
patch->defaultMouseCursor = _defaultMouseCursorName;
}
_mouseMap.hideAll(this);
@@ -249,6 +254,10 @@ void AGDSEngine::loadScreen(const Common::String &name) {
if (it != _patches.end()) {
const PatchPtr &patch = it->_value;
_currentScreen->load(patch);
+ if (_currentCharacter && patch->characterPresent) {
+ _currentCharacter->position(patch->characterPosition);
+ _currentCharacter->direction(patch->characterDirection);
+ }
if (!patch->defaultMouseCursor.empty())
loadDefaultMouseCursor(patch->defaultMouseCursor);
}
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index c402f5d63e4..f920624013e 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -21,12 +21,12 @@ void Patch::load(Common::SeekableReadStream *stream) {
return;
unk41 = stream->readUint32LE();
- characterX = stream->readUint32LE();
- characterY = stream->readUint32LE();
+ characterPosition.x = stream->readUint32LE();
+ characterPosition.y = stream->readUint32LE();
characterDirection = stream->readUint32LE();
- unk51 = stream->readUint32LE();
- debug("character at %u,%u with dir: %u", characterX, characterY, characterDirection);
- debug("unknown entries: %u %u", unk41, unk51);
+ characterPresent = stream->readUint32LE();
+ debug("character %s at %u,%u with dir: %u", characterPresent? "[present]": "[absent]", characterPosition.x, characterPosition.y, characterDirection);
+ debug("some screen loading flag: %u", unk41);
uint object_count = stream->readUint32LE();
debug("objects in this patch: %u", object_count);
if (stream->read(palette, sizeof(palette)) != sizeof(palette)) {
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index 35fb1e318b8..74d75b68c2a 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/array.h"
+#include "common/rect.h"
#include "common/str.h"
namespace Common { class SeekableReadStream; }
@@ -46,10 +47,9 @@ struct Patch {
Common::String prevScreenName;
uint unk41;
- uint characterX;
- uint characterY;
+ Common::Point characterPosition;
uint characterDirection;
- uint unk51;
+ bool characterPresent;
byte palette[0x300];
Common::String defaultMouseCursor;
Commit: 932aed9d7b9d58cd5769ba1bdf52b33cf5e3a874
https://github.com/scummvm/scummvm/commit/932aed9d7b9d58cd5769ba1bdf52b33cf5e3a874
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:36+01:00
Commit Message:
AGDS: fully implemented checkScreenPatch opcode
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/patch.cpp
engines/agds/patch.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 1007f3857cd..f6bd0a8740f 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -223,6 +223,11 @@ void AGDSEngine::reAddInventory() {
}
}
+PatchPtr AGDSEngine::getPatch(const Common::String &screenName) const {
+ auto it = _patches.find(screenName);
+ return it != _patches.end()? it->_value: PatchPtr();
+}
+
void AGDSEngine::loadScreen(const Common::String &name) {
_nextScreenName.clear();
debug("loadScreen %s", name.c_str());
@@ -250,9 +255,8 @@ void AGDSEngine::loadScreen(const Common::String &name) {
_currentScreen = new Screen(this, loadObject(name));
runProcess(_currentScreen->getObject());
- PatchesType::const_iterator it = _patches.find(name);
- if (it != _patches.end()) {
- const PatchPtr &patch = it->_value;
+ auto patch = getPatch(name);
+ if (patch) {
_currentScreen->load(patch);
if (_currentCharacter && patch->characterPresent) {
_currentCharacter->position(patch->characterPosition);
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index cd7c892d3b5..13adbf23b48 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -258,6 +258,7 @@ public:
}
void reAddInventory();
+ PatchPtr getPatch(const Common::String &screenName) const;
private:
void loadPatches(Common::SeekableReadStream *file, Database & db);
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index f920624013e..a0e849f7a97 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -43,4 +43,13 @@ void Patch::load(Common::SeekableReadStream *stream) {
}
}
+int Patch::getFlag(const Common::String & name) const {
+ for(auto & object : objects) {
+ if (object.name == name)
+ return object.flag;
+ }
+ return 0;
+}
+
+
}
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index 74d75b68c2a..830cfbf61f1 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -56,6 +56,7 @@ struct Patch {
Common::Array<Object> objects;
void load(Common::SeekableReadStream *stream);
+ int getFlag(const Common::String & name) const;
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4a29738a052..b072edc97c1 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -25,6 +25,7 @@
#include "agds/character.h"
#include "agds/font.h"
#include "agds/opcode.h"
+#include "agds/patch.h"
#include "agds/process.h"
#include "agds/region.h"
#include "agds/screen.h"
@@ -508,11 +509,17 @@ void Process::checkScreenPatch() {
return;
}
- if (!screenName.empty()) {
- debug("checkScreenPatch: stub for screen != -1, returning 0");
- //check that patch exist
- push(0);
- return;
+ if (!screenName.empty() && screenName != screen->getName()) {
+ if (objectName != _engine->getSystemVariable("inventory_scr")->getString()) {
+ debug("checkScreenPatch for object %s %s");
+ auto patch = _engine->getPatch(screenName);
+ push(patch? patch->getFlag(objectName): 0);
+ } else {
+ push(_engine->inventory().find(objectName) >= 0);
+ }
+ } if (screen && screen->applyingPatch()) {
+ debug("checkScreenPatch: attempt to change screen patch (%s) in patching process %s", screen->getName().c_str(), getName().c_str());
+ push(-1);
} else {
ObjectPtr object = screen->find(objectName);
int value = object && object->inScene();
Commit: cecb756efb6d3393ed48ebc8342950d7c9a57dd5
https://github.com/scummvm/scummvm/commit/cecb756efb6d3393ed48ebc8342950d7c9a57dd5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:36+01:00
Commit Message:
AGDS: do not save inventory/cloned objects
Changed paths:
engines/agds/agds.cpp
engines/agds/inventory.cpp
engines/agds/object.cpp
engines/agds/object.h
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index f6bd0a8740f..7e41f4fe9dd 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -168,6 +168,9 @@ ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::Strin
error("no database entry for %s\n", clone.c_str());
ObjectPtr object(new Object(name, stream));
+ if (!prototype.empty()) {
+ object->persistent(false);
+ }
delete stream;
return object;
}
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index de007c4084f..41dbc61856a 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -44,6 +44,7 @@ ObjectPtr Inventory::get(int index) const {
}
int Inventory::add(const ObjectPtr & object) {
+ object->persistent(false);
for (uint i = 0; i < _entries.size(); ++i) {
if (!_entries[i]) {
_entries[i] = object;
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 75560bf4844..4e2888689f7 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -40,7 +40,8 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_pos(), _z(10),
_clickHandler(0), _examineHandler(0),
_userUseHandler(0),
- _alpha(255), _inScene(false) {
+ _alpha(255), _inScene(false),
+ _persistent(true) {
uint16 id = stream->readUint16LE();
debug("id: 0x%02x %u", id, id);
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 62ff277a5b3..d793a6a217b 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -78,11 +78,20 @@ private:
int _alpha;
int _scale;
bool _inScene;
+ bool _persistent;
public:
Object(const Common::String &name, Common::SeekableReadStream * stream);
~Object();
+ void persistent(bool persistent) {
+ _persistent = persistent;
+ }
+
+ bool persistent() const {
+ return _persistent;
+ }
+
void readStringTable(unsigned resOffset, uint16 resCount);
const StringEntry & getString(uint16 index) const;
uint getStringTableSize() const
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 1b71596b26c..bce77d2bdcd 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -249,6 +249,8 @@ void Screen::save(const PatchPtr &patch) {
patch->objects.clear();
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
+ if (!object->persistent())
+ continue;
debug("saving patch object %s %d", object->getName().c_str(), object->inScene());
patch->objects.push_back(Patch::Object(object->getName(), object->inScene()));
}
Commit: cd6b209e9acb514b2d8bbad63896ee887813dd58
https://github.com/scummvm/scummvm/commit/cd6b209e9acb514b2d8bbad63896ee887813dd58
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:36+01:00
Commit Message:
AGDS: do not execute call if object was recovered
Changed paths:
engines/agds/agds.cpp
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 7e41f4fe9dd..46f898e9fa4 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -182,6 +182,7 @@ void AGDSEngine::runObject(const ObjectPtr &object) {
} else if (!object->inScene()) {
debug("marking object %s as in-scene...", object->getName().c_str());
object->inScene(true);
+ object->allowCalls(false);
runProcess(object);
} else
debug("object %s is in scene, skip run", object->getName().c_str());
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 4e2888689f7..51dc6128da1 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -41,7 +41,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_clickHandler(0), _examineHandler(0),
_userUseHandler(0),
_alpha(255), _inScene(false),
- _persistent(true) {
+ _persistent(true), _allowCalls(true) {
uint16 id = stream->readUint16LE();
debug("id: 0x%02x %u", id, id);
diff --git a/engines/agds/object.h b/engines/agds/object.h
index d793a6a217b..eabde8e1071 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -79,15 +79,22 @@ private:
int _scale;
bool _inScene;
bool _persistent;
+ bool _allowCalls;
public:
Object(const Common::String &name, Common::SeekableReadStream * stream);
~Object();
+ bool allowCalls() const {
+ return _allowCalls;
+ }
+ void allowCalls(bool allow) {
+ _allowCalls = allow;
+ }
+
void persistent(bool persistent) {
_persistent = persistent;
}
-
bool persistent() const {
return _persistent;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b072edc97c1..51042786c93 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1208,7 +1208,10 @@ void Process::loadTextFromObject() {
void Process::call(uint16 addr) {
debug("call %04x", addr);
- _engine->runProcess(_object, _ip + addr);
+ if (_object->allowCalls()) {
+ _engine->runProcess(_object, _ip + addr);
+ } else
+ debug("call skipped (recovered object)");
}
void Process::onKey(uint16 size) {
Commit: 206e02a9e214aac946ed355125b8313c51e6930f
https://github.com/scummvm/scummvm/commit/206e02a9e214aac946ed355125b8313c51e6930f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:36+01:00
Commit Message:
AGDS: call outputs dst address, not offset now
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 51042786c93..53503053597 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1207,7 +1207,7 @@ void Process::loadTextFromObject() {
}
void Process::call(uint16 addr) {
- debug("call %04x", addr);
+ debug("call %04x", _ip + addr);
if (_object->allowCalls()) {
_engine->runProcess(_object, _ip + addr);
} else
Commit: 5adcf6647b7d9ff26933389e64260b67c5ef38f2
https://github.com/scummvm/scummvm/commit/5adcf6647b7d9ff26933389e64260b67c5ef38f2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:36+01:00
Commit Message:
AGDS: fix moveObject and implement stub166
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 51dc6128da1..bf0c54769fe 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -148,15 +148,9 @@ void Object::setPicture(Graphics::TransparentSurface *picture) {
void Object::region(RegionPtr region) {
_region = region;
- _pos = region->topLeft();
}
-void Object::moveTo(Common::Point pos)
-{
- Common::Point delta = pos - _pos;
- debug("moving object %+d,%+d", delta.x, delta.y);
- if (_region)
- _region->move(delta);
+void Object::moveTo(Common::Point pos) {
_pos = pos;
}
@@ -176,6 +170,9 @@ bool Object::pointIn(Common::Point pos) {
if (!_inScene)
return false;
+ pos -= _pos;
+ pos -= _regionOffset;
+
if (_region && _region->pointIn(pos))
return true;
diff --git a/engines/agds/object.h b/engines/agds/object.h
index eabde8e1071..41dfd7b0823 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -69,6 +69,7 @@ private:
Animation * _animation;
Animation * _mouseCursor;
Common::Point _pos, _animationPos, _offset;
+ Common::Point _regionOffset;
int _z;
Common::String _text;
Common::String _title;
@@ -138,6 +139,10 @@ public:
void generateRegion();
+ void regionOffset(Common::Point offset) {
+ _regionOffset = offset;
+ }
+
void setAlpha(int alpha) {
if (alpha < 0)
alpha = 0;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index c1dac0e0f73..13a4513a3a0 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -183,7 +183,7 @@ enum Opcode {
kEnableInventory = 163,
kLoadPreviousScreen = 164,
kMoveScreenObject = 165,
- kStub166 = 166,
+ kSetObjectRegionOffset = 166,
kStub167 = 167,
kStub168 = 168,
kGetIntegerSystemVariable = 169,
@@ -402,7 +402,7 @@ enum Opcode {
OP(kGetObjectSurfaceY, getObjectSurfaceY) \
OP(kLoadGame, loadGame) \
OP(kLoadSaveSlotNamePicture, loadSaveSlotNamePicture) \
- OP(kStub166, stub166) \
+ OP(kSetObjectRegionOffset, setObjectRegionOffset) \
OP(kSetDelay, setDelay) \
OP(kStub172, stub172) \
OP(kStub173, stub173) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 53503053597..4096d9ea9fc 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -771,11 +771,16 @@ void Process::loadSaveSlotNamePicture() {
delete save;
}
-void Process::stub166() {
- int arg3 = pop();
- int arg2 = pop();
- Common::String arg1 = popString();
- debug("stub166 %s %d %d", arg1.c_str(), arg2, arg3);
+void Process::setObjectRegionOffset() {
+ int dy = pop();
+ int dx = pop();
+ Common::String objectName = popString();
+ debug("setObjectRegionOffset %s %d %d", objectName.c_str(), dx, dy);
+ auto object = _engine->getCurrentScreenObject(objectName);
+ if (object)
+ object->regionOffset(Common::Point(dx, dy));
+ else
+ warning("setObjectRegionOffset: object %s not found", objectName.c_str());
}
void Process::stub172() {
@@ -998,12 +1003,9 @@ void Process::moveScreenObject() {
Common::String name = popString();
debug("moveScreenObject %s %d %d", name.c_str(), x, y);
ObjectPtr object = _engine->getCurrentScreenObject(name);
- if (object) {
- RegionPtr region = object->region();
- if (region)
- debug("object region %s", region->toString().c_str());
+ if (object)
object->moveTo(Common::Point(x, y));
- } else
+ else
warning("moveScreenObject: object %s not found", name.c_str());
}
Commit: 281c29161c0b19f38fe1cdb6b122df8a8639c013
https://github.com/scummvm/scummvm/commit/281c29161c0b19f38fe1cdb6b122df8a8639c013
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:37+01:00
Commit Message:
AGDS: remove runtime load/save because it's not supported
Changed paths:
engines/agds/agds.cpp
engines/agds/metaengine.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 46f898e9fa4..891e359f22a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -879,8 +879,6 @@ bool AGDSEngine::hasFeature(EngineFeature f) const {
switch (f) {
case kSupportsSubtitleOptions:
case kSupportsReturnToLauncher:
- case kSupportsLoadingDuringRuntime:
- case kSupportsSavingDuringRuntime:
case kSupportsChangingOptionsDuringRuntime:
return true;
default:
diff --git a/engines/agds/metaengine.cpp b/engines/agds/metaengine.cpp
index a92414f8480..5df1ba535f6 100644
--- a/engines/agds/metaengine.cpp
+++ b/engines/agds/metaengine.cpp
@@ -21,6 +21,8 @@
*/
#include "agds/agds.h"
#include "agds/object.h"
+#include "common/savefile.h"
+#include "common/system.h"
namespace AGDS {
@@ -29,13 +31,10 @@ public:
bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
bool hasFeature(MetaEngineFeature f) const override {
switch (f) {
- case kSupportsListSaves:
- case kSupportsLoadingDuringStartup:
- case kSupportsDeleteSave:
- case kSavesSupportMetaInfo:
- case kSavesSupportThumbnail:
case kSimpleSavesNames:
return true;
+ case kSupportsLoadingDuringStartup:
+ return false;
default:
return AdvancedMetaEngine::hasFeature(f);
}
@@ -46,7 +45,36 @@ public:
}
int getMaximumSaveSlot() const override {
- return 99;
+ return 24;
+ }
+
+ SaveStateList listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringArray filenames;
+ Common::String pattern(getSavegameFilePattern(target));
+
+ filenames = saveFileMan->listSavefiles(pattern);
+
+ SaveStateList saveList;
+ for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Obtain the last 2 digits of the filename, since they correspond to the save slot
+ int slotNum = atoi(file->c_str() + file->size() - 2);
+
+ if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) {
+ SaveStateDescriptor desc;
+
+ desc.setSaveSlot(slotNum);
+ desc.setDescription(*file);
+ if (slotNum == getAutosaveSlot())
+ desc.setWriteProtectedFlag(true);
+
+ saveList.push_back(desc);
+ }
+ }
+
+ // Sort saves based on slot number.
+ Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator());
+ return saveList;
}
};
Commit: 4857d1785886f90938b347937039b555e1e152ed
https://github.com/scummvm/scummvm/commit/4857d1785886f90938b347937039b555e1e152ed
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:37+01:00
Commit Message:
AGDS: reset save name picture if no save found
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4096d9ea9fc..238fcad81c9 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -749,6 +749,7 @@ void Process::loadSaveSlotNamePicture() {
Common::InSaveFile * save = saveMan->openForLoading(saveSlotName);
if (!save) {
debug("no save in slot %d", saveSlot);
+ _object->setPicture(nullptr);
return;
}
Commit: 53e4403ad7a79f72730da8a00beab76a5d71f8b8
https://github.com/scummvm/scummvm/commit/53e4403ad7a79f72730da8a00beab76a5d71f8b8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:37+01:00
Commit Message:
AGDS: add missing else
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 238fcad81c9..c7d8522b92c 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -517,7 +517,7 @@ void Process::checkScreenPatch() {
} else {
push(_engine->inventory().find(objectName) >= 0);
}
- } if (screen && screen->applyingPatch()) {
+ } else if (screen && screen->applyingPatch()) {
debug("checkScreenPatch: attempt to change screen patch (%s) in patching process %s", screen->getName().c_str(), getName().c_str());
push(-1);
} else {
Commit: 9c8094936ec1328c7718e3818cae19203f4ad864
https://github.com/scummvm/scummvm/commit/9c8094936ec1328c7718e3818cae19203f4ad864
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:37+01:00
Commit Message:
AGDS: add createPatch()
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/patch.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 891e359f22a..1cc5c847cb8 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -232,6 +232,13 @@ PatchPtr AGDSEngine::getPatch(const Common::String &screenName) const {
return it != _patches.end()? it->_value: PatchPtr();
}
+PatchPtr AGDSEngine::createPatch(const Common::String &screenName) {
+ auto & patch = _patches[screenName];
+ if (!patch)
+ patch = PatchPtr(new Patch());
+ return patch;
+}
+
void AGDSEngine::loadScreen(const Common::String &name) {
_nextScreenName.clear();
debug("loadScreen %s", name.c_str());
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 13adbf23b48..45a20fabeeb 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -259,6 +259,7 @@ public:
void reAddInventory();
PatchPtr getPatch(const Common::String &screenName) const;
+ PatchPtr createPatch(const Common::String &screenName);
private:
void loadPatches(Common::SeekableReadStream *file, Database & db);
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index 830cfbf61f1..303a495f23f 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -46,12 +46,12 @@ struct Patch {
Common::String screenRegionName;
Common::String prevScreenName;
- uint unk41;
+ uint unk41 = 0;
Common::Point characterPosition;
- uint characterDirection;
- bool characterPresent;
+ uint characterDirection = 0;
+ bool characterPresent = false;
- byte palette[0x300];
+ byte palette[0x300] = {};
Common::String defaultMouseCursor;
Common::Array<Object> objects;
Commit: c25798e03cf8f3fddfd237a545be0241693d494b
https://github.com/scummvm/scummvm/commit/c25798e03cf8f3fddfd237a545be0241693d494b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:37+01:00
Commit Message:
AGDS: implement incref/decref for screen patches
Changed paths:
engines/agds/opcode.h
engines/agds/patch.cpp
engines/agds/patch.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 13a4513a3a0..93e3e6f5a86 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -155,8 +155,8 @@ enum Opcode {
kSetPhaseVar = 135,
kSetAnimationLoop = 136,
kSetAnimationSpeed = 137,
- kScreenSaveScreenPatch = 138,
- kScreenRemoveObjectSavePatch = 139,
+ kScreenObjectPatchIncRef = 138,
+ kScreenObjectPatchDecRef = 139,
kScreenCheckScreenPatch = 140,
kGetFreeInventorySpace = 141,
kSetStringSystemVariable = 142,
@@ -376,8 +376,8 @@ enum Opcode {
OP(kSetPhaseVar, setPhaseVar) \
OP(kSetAnimationLoop, setAnimationLoop) \
OP(kSetAnimationSpeed, setAnimationSpeed) \
- OP(kScreenSaveScreenPatch, screenSaveScreenPatch) \
- OP(kScreenRemoveObjectSavePatch, screenRemoveObjectSavePatch) \
+ OP(kScreenObjectPatchIncRef, screenObjectPatchIncRef) \
+ OP(kScreenObjectPatchDecRef, screenObjectPatchDecRef) \
OP(kGetSavedMouseX, getSavedMouseX) \
OP(kGetSavedMouseY, getSavedMouseY) \
OP(kScreenCheckScreenPatch, checkScreenPatch) \
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index a0e849f7a97..baf3861e14b 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -51,5 +51,26 @@ int Patch::getFlag(const Common::String & name) const {
return 0;
}
+int Patch::incRef(const Common::String & name) {
+ for(auto & object : objects) {
+ if (object.name == name) {
+ return ++object.flag;
+ }
+ }
+ objects.push_back({name, 1});
+ return 1;
+}
+
+int Patch::decRef(const Common::String & name) {
+ for(auto & object : objects) {
+ if (object.name == name) {
+ //this is original code lol
+ object.flag = 0;
+ return 0;
+ }
+ }
+ objects.push_back({name, 0});
+ return 0;
+}
}
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index 303a495f23f..4016ae5b53a 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -57,6 +57,8 @@ struct Patch {
void load(Common::SeekableReadStream *stream);
int getFlag(const Common::String & name) const;
+ int incRef(const Common::String & name);
+ int decRef(const Common::String & name);
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c7d8522b92c..3470a87a501 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -667,18 +667,41 @@ void Process::setAnimationSpeed() {
_animationSpeed = value;
}
-void Process::screenSaveScreenPatch() {
+void Process::screenObjectPatchIncRef() {
Common::String objectName = popString();
Common::String screenName = popString();
- debug("saveScreenPatch stub %s %s", screenName.c_str(), objectName.c_str());
- suspend(kExitCodeLoadScreenObject, objectName);
+ debug("screenObjectPatchIncRef: %s %s", screenName.c_str(), objectName.c_str());
+ if (!screenName.empty() && screenName != _engine->getCurrentScreenName()) {
+ if (_engine->getCurrentScreen()->applyingPatch()) {
+ debug("attempt to change screen patch (%s) in patching process (%s)", objectName.c_str(), screenName.c_str());
+ } else {
+ //fixme: add non-existent screen check?
+ auto patch = _engine->createPatch(screenName);
+ int refs = patch->incRef(objectName);
+ debug("increment refcount for object %s, result: %d", objectName.c_str(), refs);
+ }
+ } else {
+ debug("screenObjectPatchIncRef: current screen, loading object");
+ suspend(kExitCodeLoadScreenObject, objectName);
+ }
}
-void Process::screenRemoveObjectSavePatch() {
+void Process::screenObjectPatchDecRef() {
Common::String objectName = popString();
Common::String screenName = popString();
- if (screenName != _engine->getCurrentScreenName()) {
- debug("screenRemoveObjectSavePatch semi-stub %s %s", screenName.c_str(), objectName.c_str());
+ if (!screenName.empty() && screenName != _engine->getCurrentScreenName()) {
+ debug("screenObjectPatchDecRef %s %s", screenName.c_str(), objectName.c_str());
+ if (_engine->getCurrentScreen()->applyingPatch()) {
+ debug("attempt to change screen patch (%s) in patching process (%s)", objectName.c_str(), screenName.c_str());
+ } else {
+ //fixme: add non-existent screen check?
+ auto patch = _engine->getPatch(screenName);
+ if (patch) {
+ int refs = patch->decRef(objectName);
+ debug("decrement refcount for object %s, result: %d", objectName.c_str(), refs);
+ } else
+ debug("decrement refcount for object %s, no patch for screen %s", objectName.c_str(), screenName.c_str());
+ }
} else {
Screen *screen = _engine->getCurrentScreen();
if (screen) {
Commit: eee67d1310843717f0ce783474938d232e0f8246
https://github.com/scummvm/scummvm/commit/eee67d1310843717f0ce783474938d232e0f8246
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:37+01:00
Commit Message:
AGDS: add stub197
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 93e3e6f5a86..7d85976510b 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -429,6 +429,7 @@ enum Opcode {
OP(kGetObjectPictureWidth, getObjectPictureWidth) \
OP(kGetObjectPictureHeight, getObjectPictureHeight) \
OP(kLoadPicture, loadPicture) \
+ OP(kStub197, stub197) \
OP(kStub199, stub199) \
OP(kSetSampleVolumeAndPan, setSampleVolumeAndPan) \
OP(kAddSampleToSoundGroup, addSampleToSoundGroup) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3470a87a501..24abc210e1b 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -846,6 +846,12 @@ void Process::stub194() {
debug("stub194: mute");
}
+void Process::stub197() {
+ int flag = pop();
+ auto objectName = popString();
+ debug("stub197: %s %d", objectName.c_str(), flag);
+}
+
void Process::stub199() {
int value = pop();
debug("stub199: (free cached surface?) %d", value);
Commit: e9ec21aa9b88393341e0b88ba7afa5d18d2bf41f
https://github.com/scummvm/scummvm/commit/e9ec21aa9b88393341e0b88ba7afa5d18d2bf41f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:37+01:00
Commit Message:
AGDS: implement opcode 151, compareScreenName
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 7d85976510b..a87b26bb603 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -168,7 +168,7 @@ enum Opcode {
kGetCharacterAnimationPhase = 148,
kGetCharacterX = 149,
kGetCharacterY = 150,
- kStub151 = 151,
+ kCompareScreenName = 151,
kGetPictureBaseX = 152,
kGetPictureBaseY = 153,
kGetObjectSurfaceX = 154,
@@ -351,6 +351,7 @@ enum Opcode {
OP(kSetObjectZ, setObjectZ) \
OP(kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay) \
OP(kLoadTextFromObject, loadTextFromObject) \
+ OP(kCompareScreenName, compareScreenName) \
OP(kScreenSetZNearFar, screenSetZNearFar) \
OP(kScreenLoadObject, loadScreenObject) \
OP(kScreenLoadRegion, loadScreenRegion) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 24abc210e1b..bfd1590f4c9 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -667,6 +667,13 @@ void Process::setAnimationSpeed() {
_animationSpeed = value;
}
+void Process::compareScreenName() {
+ auto name = popString();
+ auto currentScreenName = _engine->getCurrentScreenName();
+ debug("compareScreenName %s (currentScreen: %s)", name.c_str(), currentScreenName.c_str());
+ push(name == currentScreenName? 1: 0);
+}
+
void Process::screenObjectPatchIncRef() {
Common::String objectName = popString();
Common::String screenName = popString();
Commit: 16b8e8416f56ec68c12aaeb937143f14d85df647
https://github.com/scummvm/scummvm/commit/16b8e8416f56ec68c12aaeb937143f14d85df647
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:37+01:00
Commit Message:
AGDS: implement save game stubs
Changed paths:
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index a87b26bb603..2bbb61404f8 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -174,11 +174,11 @@ enum Opcode {
kGetObjectSurfaceX = 154,
kGetObjectSurfaceY = 155,
kLoadGame = 156,
- kStub157 = 157,
+ kSaveGame = 157,
kQuit = 158,
kExitProcessCreatePatch = 159,
kLoadSaveSlotNamePicture = 160,
- kStub161 = 161,
+ kGetSaveGameName = 161,
kDisableInventory = 162,
kEnableInventory = 163,
kLoadPreviousScreen = 164,
@@ -402,7 +402,9 @@ enum Opcode {
OP(kGetObjectSurfaceX, getObjectSurfaceX) \
OP(kGetObjectSurfaceY, getObjectSurfaceY) \
OP(kLoadGame, loadGame) \
+ OP(kSaveGame, saveGame) \
OP(kLoadSaveSlotNamePicture, loadSaveSlotNamePicture) \
+ OP(kGetSaveGameName, getSaveGameName) \
OP(kSetObjectRegionOffset, setObjectRegionOffset) \
OP(kSetDelay, setDelay) \
OP(kStub172, stub172) \
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 17bc2ee8374..387976626c6 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -213,7 +213,7 @@ void Process::run() {
activate();
}
break;
- case kExitCodeLoadSaveGame:
+ case kExitCodeLoadGame:
if (_engine->loadGameState(getExitIntArg1()).getCode() == Common::kNoError) {
done();
} else {
@@ -221,6 +221,10 @@ void Process::run() {
activate(); //continue
}
break;
+ case kExitCodeSaveGame:
+ _engine->returnToPreviousScreen();
+ activate();
+ break;
default:
error("unknown process exit code %d", code);
}
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index 3d17b1fcd6a..85ad53c5ca0 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -36,9 +36,10 @@ namespace AGDS {
kExitCodeMouseAreaChange = 11,
kExitCodeRunDialog = 12,
kExitCodeCreatePatchLoadResources = 13,
- kExitCodeLoadSaveGame = 14,
+ kExitCodeLoadGame = 14,
kExitCodeExitScreen = 15,
kExitCodeCloseInventory = 16,
+ kExitCodeSaveGame = 17,
kExitCodeLoadPreviousScreenObject = 99
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index bfd1590f4c9..aef6e348c51 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -767,7 +767,20 @@ void Process::getSavedMouseY() {
void Process::loadGame() {
int saveSlot = pop();
debug("loadGame %d", saveSlot);
- suspend(kExitCodeLoadSaveGame, saveSlot);
+ suspend(kExitCodeLoadGame, saveSlot);
+}
+
+void Process::saveGame() {
+ int saveSlot = pop();
+ debug("saveGame stub %d", saveSlot);
+ suspend(kExitCodeSaveGame, saveSlot);
+}
+
+void Process::getSaveGameName() {
+ int flag = pop();
+ int saveSlot = pop();
+ debug("getSaveGameName stub %d %d", saveSlot, flag);
+ push(1);
}
void Process::loadSaveSlotNamePicture() {
Commit: 9adfd5794eca9e80ceb4a66e2322b4632d315a31
https://github.com/scummvm/scummvm/commit/9adfd5794eca9e80ceb4a66e2322b4632d315a31
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:37+01:00
Commit Message:
AGDS: add writeString()
Changed paths:
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 06ea8188535..eb976a280bc 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -230,9 +230,15 @@ Common::String readString(Common::SeekableReadStream * stream, uint size) {
if (stream->read(text.data(), text.size()) != text.size())
error("readString: short read");
- uint len;
- for(len = 0; len < text.size() && text[len]; ++len);
- return Common::String(text.data(), len);
+ return Common::String(text.data(), strlen(text.data()));
+}
+
+void writeString(Common::SeekableWriteStream * stream, const Common::String &string, uint size) {
+ Common::Array<char> text(size);
+ memcpy(text.data(), string.c_str(), MIN(string.size(), size));
+
+ if (stream->write(text.data(), text.size()) != text.size())
+ error("writeString: short write");
}
} // End of namespace AGDS
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index d008a43bd8d..f24ebd6c345 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -95,6 +95,7 @@ public:
};
Common::String readString(Common::SeekableReadStream * stream, uint size = 32);
+void writeString(Common::SeekableWriteStream * stream, const Common::String &string, uint size = 32);
} // End of namespace AGDS
Commit: 683e88903f1c34510af4d6cbb38e90f7e2660579
https://github.com/scummvm/scummvm/commit/683e88903f1c34510af4d6cbb38e90f7e2660579
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:37+01:00
Commit Message:
AGDS: add Patch::save
Changed paths:
engines/agds/patch.cpp
engines/agds/patch.h
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index baf3861e14b..04152ad1200 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -43,6 +43,33 @@ void Patch::load(Common::SeekableReadStream *stream) {
}
}
+void Patch::save(Common::SeekableWriteStream *stream) {
+ int extended = 1;
+ stream->writeByte(extended);
+ writeString(stream, screenRegionName);
+ writeString(stream, prevScreenName);
+
+ if (extended == 0)
+ return;
+
+ stream->writeUint32LE(unk41);
+ stream->writeUint32LE(characterPosition.x);
+ stream->writeUint32LE(characterPosition.y);
+ stream->writeUint32LE(characterDirection);
+ stream->writeUint32LE(characterPresent);
+
+ stream->writeUint32LE(objects.size());
+ if (stream->write(palette, sizeof(palette)) != sizeof(palette)) {
+ error("short write, can't write palette");
+ }
+
+ writeString(stream, defaultMouseCursor);
+ for(auto &object: objects) {
+ stream->writeSint16LE(object.flag);
+ writeString(stream, object.name);
+ }
+}
+
int Patch::getFlag(const Common::String & name) const {
for(auto & object : objects) {
if (object.name == name)
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index 4016ae5b53a..a693a56e579 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -28,7 +28,7 @@
#include "common/rect.h"
#include "common/str.h"
-namespace Common { class SeekableReadStream; }
+namespace Common { class SeekableReadStream; class SeekableWriteStream; }
namespace AGDS {
@@ -56,6 +56,7 @@ struct Patch {
Common::Array<Object> objects;
void load(Common::SeekableReadStream *stream);
+ void save(Common::SeekableWriteStream *stream);
int getFlag(const Common::String & name) const;
int incRef(const Common::String & name);
int decRef(const Common::String & name);
Commit: bf5bf1ed451bd05fc96d490fe9b0d2b4170c53d6
https://github.com/scummvm/scummvm/commit/bf5bf1ed451bd05fc96d490fe9b0d2b4170c53d6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:38+01:00
Commit Message:
AGDS: use tell_close_inv in AGDSEngine::tell
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 1cc5c847cb8..72845f5c5d8 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -774,6 +774,9 @@ void AGDSEngine::addSystemVar(const Common::String &name, SystemVariable *var) {
}
void AGDSEngine::tell(Process &process, const Common::String ®ionName, Common::String text, Common::String sound, bool npc) {
+ if (getSystemVariable("tell_close_inv")->getInteger())
+ _inventory.enable(false);
+
int font_id = getSystemVariable(npc? "npc_tell_font": "tell_font")->getInteger();
Common::Point pos;
Commit: ad70e0a1deef1c7f6a1cd40e42361dd5ac3a568f
https://github.com/scummvm/scummvm/commit/ad70e0a1deef1c7f6a1cd40e42361dd5ac3a568f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:38+01:00
Commit Message:
AGDS: do not play samples with given phaseVar more than once
Changed paths:
engines/agds/soundManager.cpp
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 79fafbfd247..cfe70a0fd72 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -59,6 +59,9 @@ void SoundManager::tick() {
}
Sound *SoundManager::findSampleByPhaseVar(const Common::String &phaseVar) {
+ if (phaseVar.empty())
+ return nullptr;
+
for (auto i = _sounds.begin(); i != _sounds.end(); ++i) {
auto &sound = *i;
if (sound.phaseVar == phaseVar) {
@@ -81,6 +84,13 @@ void SoundManager::stopAll() {
int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &phaseVar, int id) {
debug("SoundMan::play %s %s %s", process.c_str(), resource.c_str(), phaseVar.c_str());
+ {
+ auto sample = findSampleByPhaseVar(phaseVar);
+ if (sample && playing(sample->id)) {
+ debug("already playing");
+ return sample->id;
+ }
+ }
Common::File *file = new Common::File();
if (!file->open(resource)) {
if (!phaseVar.empty())
Commit: 41098938e9ad35a3801a47f3ffaf741c0e251e01
https://github.com/scummvm/scummvm/commit/41098938e9ad35a3801a47f3ffaf741c0e251e01
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:38+01:00
Commit Message:
AGDS: reset object position when picture loads
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index bf0c54769fe..db7bfaebd56 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -111,6 +111,7 @@ const Object::StringEntry &Object::getString(uint16 index) const {
}
void Object::setPicture(Graphics::TransparentSurface *picture) {
+ _pos = Common::Point();
if (_picture) {
_picture->free();
delete _picture;
Commit: 8d2efc204500a6734ff51f9db1e606d2b77dbdeb
https://github.com/scummvm/scummvm/commit/8d2efc204500a6734ff51f9db1e606d2b77dbdeb
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:38+01:00
Commit Message:
AGDS: return multiple objects from Screen::find(pos)
Changed paths:
engines/agds/agds.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 72845f5c5d8..fee144b1188 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -488,13 +488,16 @@ Common::Error AGDSEngine::run() {
runObject(object);
break;
}
- ObjectPtr object = _currentScreen->find(_mouse);
- if (!object && !_currentInventoryObject) //allow inventory to be selected
- object = _inventory.find(_mouse);
+ auto objects = _currentScreen->find(_mouse);
+ if (objects.empty() && !_currentInventoryObject) { //allow inventory to be selected
+ auto object = _inventory.find(_mouse);
+ if (object)
+ objects.push_back(object);
+ }
- if (object) {
- debug("found object %s", object->title().c_str());
+ for(auto & object : objects) {
+ debug("found object %s", object->getName().c_str());
uint ip;
if (lclick) {
if (_currentInventoryObject) {
@@ -502,12 +505,13 @@ Common::Error AGDSEngine::run() {
ip = object->getUseHandler(_currentInventoryObject->getName());
} else
ip = object->getClickHandler();
- } else
+ } else
ip = object->getExamineHandler();
if (ip) {
debug("found handler: %s %08x", object->getName().c_str(), ip + 7);
runProcess(object, ip);
+ break;
} else
debug("no handler found");
}
@@ -528,21 +532,33 @@ Common::Error AGDSEngine::run() {
Animation *mouseCursor = NULL;
if (userEnabled() && _currentScreen) {
- ObjectPtr object = _currentScreen->find(_mouse);
- if (!object)
- object = _inventory.find(_mouse);
+ auto objects = _currentScreen->find(_mouse);
+ if (objects.empty()) {
+ auto object = _inventory.find(_mouse);
+ if (object)
+ objects.push_back(object);
+ }
+
+
+ Animation *cursor = nullptr;
+ for(auto & object : objects) {
+ cursor = object->getMouseCursor();
+ if (cursor)
+ break;
+ }
- Animation *cursor = object ? object->getMouseCursor() : NULL;
if (cursor)
mouseCursor = cursor;
- if (object && !object->title().empty()) {
- auto & title = object->title();
- auto font = getFont(getSystemVariable("objtext_font")->getInteger());
- int w = font->getStringWidth(title);
- int x = getSystemVariable("objtext_x")->getInteger() - w / 2;
- int y = getSystemVariable("objtext_y")->getInteger();
- font->drawString(backbuffer, title, x, y, backbuffer->w - x, 0);
+ for(auto & object : objects) {
+ if (!object->title().empty()) {
+ auto & title = object->title();
+ auto font = getFont(getSystemVariable("objtext_font")->getInteger());
+ int w = font->getStringWidth(title);
+ int x = getSystemVariable("objtext_x")->getInteger() - w / 2;
+ int y = getSystemVariable("objtext_y")->getInteger();
+ font->drawString(backbuffer, title, x, y, backbuffer->w - x, 0);
+ }
}
}
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index bce77d2bdcd..45c2b0984a1 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -201,13 +201,15 @@ void Screen::paint(Graphics::Surface &backbuffer) {
}
}
-ObjectPtr Screen::find(Common::Point pos) const {
+Common::Array<ObjectPtr> Screen::find(Common::Point pos) const {
+ Common::Array<ObjectPtr> objects;
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
- if (object->pointIn(pos) && object->inScene())
- return object;
+ if (object->pointIn(pos) && object->inScene()) {
+ objects.push_back(object);
+ }
}
- return ObjectPtr();
+ return objects;
}
Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index d69104f26cf..76682cc4bfd 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -122,7 +122,7 @@ public:
bool remove(const Common::String & name);
bool remove(const ObjectPtr & object);
void paint(Graphics::Surface & backbuffer);
- ObjectPtr find(Common::Point pos) const;
+ Common::Array<ObjectPtr> find(Common::Point pos) const;
ObjectPtr find(const Common::String &name);
KeyHandler findKeyHandler(const Common::String &keyName);
Animation * findAnimationByPhaseVar(const Common::String &phaseVar);
Commit: 0529cffb655032afefcb6ac8022ffea0f4c8967b
https://github.com/scummvm/scummvm/commit/0529cffb655032afefcb6ac8022ffea0f4c8967b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:38+01:00
Commit Message:
AGDS: store engine to animation object
Changed paths:
engines/agds/agds.cpp
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/character.cpp
engines/agds/object.cpp
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index fee144b1188..3c2773b4f75 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -585,8 +585,8 @@ Common::Error AGDSEngine::run() {
picture->blit(*backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
}
} else {
- mouseCursor->tick(*this);
- mouseCursor->paint(*this, *backbuffer, _mouse);
+ mouseCursor->tick();
+ mouseCursor->paint(*backbuffer, _mouse);
}
}
@@ -709,8 +709,8 @@ Animation *AGDSEngine::loadAnimation(const Common::String &name) {
Common::SeekableReadStream *stream = _resourceManager.getResource(name);
if (!stream)
error("could not load animation from %s", name.c_str());
- Animation *animation = new Animation();
- if (!animation->load(stream))
+ Animation *animation = new Animation(this);
+ if (!animation->load(stream, name))
error("could not load animation from %s", name.c_str());
_animations[name] = animation;
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 39fca66ecee..640de00a085 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -30,8 +30,9 @@
namespace AGDS {
-Animation::Animation() :
- _flic(), _frame(), _frames(0), _loop(false), _cycles(1), _phaseVarControlled(false),
+Animation::Animation(AGDSEngine *engine) :
+ _engine(engine), _flic(), _frame(),
+ _frames(0), _loop(false), _cycles(1), _phaseVarControlled(false),
_phase(0), _paused(false), _speed(100), _z(0),
_delay(0), _random(0), _scale(1) {
}
@@ -50,7 +51,7 @@ void Animation::freeFrame() {
}
-bool Animation::load(Common::SeekableReadStream *stream) {
+bool Animation::load(Common::SeekableReadStream *stream, const Common::String &fname) {
if (_phaseVarControlled) {
if (_phaseVar.empty()) {
warning("phase var controlled animation with no phase var");
@@ -75,20 +76,26 @@ bool Animation::load(Common::SeekableReadStream *stream) {
}
}
delete _flic;
+ _flic = nullptr;
+
+ if (fname.hasSuffixIgnoreCase(".bmp")) {
+ _frame = _engine->loadPicture(fname);
+ _frames = 1;
+ return true;
+ }
+
Video::FlicDecoder *flic = new Video::FlicDecoder;
if (flic->loadStream(stream)) {
_frames = flic->getFrameCount();
- delete _flic;
_flic = flic;
return true;
} else {
_frames = 0;
- delete flic;
return false;
}
}
-void Animation::decodeNextFrame(AGDSEngine &engine) {
+void Animation::decodeNextFrame() {
auto frame = _flic->decodeNextFrame();
if (!frame) {
warning("frame couldn't be decoded");
@@ -97,7 +104,7 @@ void Animation::decodeNextFrame(AGDSEngine &engine) {
freeFrame();
_delay = _flic->getCurFrameDelay() * _speed / 4000; //40 == 1000 / 25, 25 fps
- _frame = engine.convertToTransparent(frame->convertTo(engine.pixelFormat(), _flic->getPalette()));
+ _frame = _engine->convertToTransparent(frame->convertTo(_engine->pixelFormat(), _flic->getPalette()));
if (_scale != 1) {
auto f = _frame->scale(_frame->w * _scale, _frame->h * _scale, true);
if (f) {
@@ -114,12 +121,16 @@ void Animation::rewind() {
_flic->rewind();
}
-bool Animation::tick(AGDSEngine &engine) {
+bool Animation::tick() {
+ if (!_flic && _frame) { //static frame
+ return true;
+ }
+
if (_paused || (_phaseVarControlled && !_frame)) {
return true;
}
- if (_phaseVarControlled && engine.getGlobal(_phaseVar) == -2) {
+ if (_phaseVarControlled && _engine->getGlobal(_phaseVar) == -2) {
debug("phase var %s signalled deleting of animation", _phaseVar.c_str());
return false;
}
@@ -133,12 +144,12 @@ bool Animation::tick(AGDSEngine &engine) {
if (eov) {
if (!_loop) {
if (!_phaseVar.empty())
- engine.setGlobal(_phaseVar, -1);
+ _engine->setGlobal(_phaseVar, -1);
}
if (_phaseVarControlled) {
freeFrame();
- engine.reactivate(_process, true);
+ _engine->reactivate(_process, true);
return true;
}
if (_loop)
@@ -147,16 +158,16 @@ bool Animation::tick(AGDSEngine &engine) {
return false;
}
- decodeNextFrame(engine);
+ decodeNextFrame();
if (!_process.empty()) {
if (!_phaseVar.empty()) {
- engine.setGlobal(_phaseVar, _phase - 1);
+ _engine->setGlobal(_phaseVar, _phase - 1);
}
}
return true;
}
-void Animation::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point dst) {
+void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst) {
dst += _position;
if (_frame) {
Common::Rect srcRect = _frame->getRect();
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 9d63ec74efb..aabf5baa135 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -36,6 +36,7 @@ class AGDSEngine;
class Object;
class Animation {
+ AGDSEngine * _engine;
Video::FlicDecoder *_flic;
Graphics::TransparentSurface *_frame;
int _frames;
@@ -54,7 +55,7 @@ class Animation {
float _scale;
public:
- Animation();
+ Animation(AGDSEngine *engine);
~Animation();
void freeFrame();
@@ -145,18 +146,19 @@ public:
return _phase;
}
- bool load(Common::SeekableReadStream *stream);
- void paint(AGDSEngine & engine, Graphics::Surface & backbuffer, Common::Point dst);
+ bool load(Common::SeekableReadStream *stream, const Common::String &fname);
+ void paint(Graphics::Surface & backbuffer, Common::Point dst);
int width() const;
int height() const;
- bool tick(AGDSEngine &engine);
- void decodeNextFrameIfNoFrame(AGDSEngine &engine) {
+ bool tick();
+
+ void decodeNextFrameIfNoFrame() {
if (!_frame)
- decodeNextFrame(engine);
+ decodeNextFrame();
}
private:
- void decodeNextFrame(AGDSEngine &engine);
+ void decodeNextFrame();
};
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index e9af9ae575c..a2f2b762fde 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -151,7 +151,7 @@ void Character::paint(Graphics::Surface &backbuffer) {
_animation->scale(scale);
if (_phase >= 0 && _phase < _frames) {
- _animation->tick(*_engine);
+ _animation->tick();
if (_phase + 1 >= _frames) {
_phase = -1;
_frames = 0;
@@ -162,7 +162,7 @@ void Character::paint(Graphics::Surface &backbuffer) {
pos.y -= _animation->height();
pos.x -= _animation->width() / 2;
- _animation->paint(*_engine, backbuffer, pos);
+ _animation->paint(backbuffer, pos);
}
int Character::z() const {
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index db7bfaebd56..246ca9531f7 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -191,8 +191,8 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
}
if (_animation) {
- _animation->tick(engine);
- _animation->paint(engine, backbuffer, _pos + _animationPos);
+ _animation->tick();
+ _animation->paint(backbuffer, _pos + _animationPos);
}
if (!_text.empty()) {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index aef6e348c51..3a6964fe5bc 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -932,7 +932,7 @@ void Process::restartAnimation() {
animation->rewind();
}
animation->resume();
- animation->decodeNextFrameIfNoFrame(*_engine);
+ animation->decodeNextFrameIfNoFrame();
_engine->setGlobal(phaseVar, animation->phase() - 1);
} else {
warning("no animation with phase var %s found", phaseVar.c_str());
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 45c2b0984a1..103cb85be23 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -138,7 +138,7 @@ void Screen::paint(Graphics::Surface &backbuffer) {
auto & currentInventoryObject = _engine->currentInventoryObject();
for(uint i = 0; i < _animations.size(); ) {
Animation *animation = _animations.data()[i];
- if (animation->tick(*_engine))
+ if (animation->tick())
++i;
else {
debug("removing animation %s:%s", animation->process().c_str(), animation->phaseVar().c_str());
@@ -187,7 +187,7 @@ void Screen::paint(Graphics::Surface &backbuffer) {
break;
case 1:
//debug("animation z: %d", (*animation)->z());
- (*animation)->paint(*_engine, backbuffer, Common::Point());
+ (*animation)->paint(backbuffer, Common::Point());
++animation;
break;
case 2:
Commit: cd32cff2b10e13abbc7b305c6cdb994c388f449f
https://github.com/scummvm/scummvm/commit/cd32cff2b10e13abbc7b305c6cdb994c388f449f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:38+01:00
Commit Message:
AGDS: implement opcode 109
Changed paths:
engines/agds/opcode.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 2bbb61404f8..21a227cfcdb 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -126,7 +126,7 @@ enum Opcode {
kInventoryClear = 106,
kStub107 = 107,
kLoadMouse = 108,
- kStub109 = 109,
+ kAttachInventoryObjectToMouse0 = 109,
kResetMousePointer = 110,
kInventoryAddObject = 111,
kInventoryRemoveObject = 112,
@@ -262,7 +262,7 @@ enum Opcode {
kHasGlobal = 242,
kStub243 = 243,
kSetCharacterNotifyVars = 244,
- kAttachInventoryObjectToMouse = 245,
+ kAttachInventoryObjectToMouse1 = 245,
kStub246 = 246,
kSetDialogForNextFilm = 247
};
@@ -468,7 +468,8 @@ enum Opcode {
OP(kInventoryFindObjectByName, inventoryFindObjectByName) \
OP(kLoadDialog, loadDialog) \
OP(kHasGlobal, hasGlobal) \
- OP(kAttachInventoryObjectToMouse, attachInventoryObjectToMouse) \
+ OP(kAttachInventoryObjectToMouse0, attachInventoryObjectToMouse0) \
+ OP(kAttachInventoryObjectToMouse1, attachInventoryObjectToMouse1) \
OP(kSetDialogForNextFilm, setDialogForNextFilm)
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 90cf0313119..91482fe2def 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -151,6 +151,7 @@ private:
ProcessExitCode resume();
void setupAnimation(Animation *animation);
+ void attachInventoryObjectToMouse(bool flag);
public:
Process(AGDSEngine *engine, ObjectPtr object, unsigned ip = 0);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3a6964fe5bc..b69658e390d 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -535,9 +535,9 @@ void Process::loadMouseCursorFromObject() {
_object->setMouseCursor(cursor); //overlay cursor
}
-void Process::attachInventoryObjectToMouse() {
+void Process::attachInventoryObjectToMouse(bool flag) {
Common::String name = popString();
- debug("attachInventoryObjectToMouse %s", name.c_str());
+ debug("attachInventoryObjectToMouse %s %d", name.c_str(), flag);
auto object = _engine->getCurrentScreenObject(name);
if (object)
_engine->currentInventoryObject(object);
@@ -545,6 +545,14 @@ void Process::attachInventoryObjectToMouse() {
warning("cannot find object %s", name.c_str());
}
+void Process::attachInventoryObjectToMouse0() {
+ attachInventoryObjectToMouse(false);
+}
+
+void Process::attachInventoryObjectToMouse1() {
+ attachInventoryObjectToMouse(true);
+}
+
void Process::fadeObject() {
int value = pop();
Common::String name = popString();
Commit: 9292af434cfd38279a91523e9d7d67db71221de8
https://github.com/scummvm/scummvm/commit/9292af434cfd38279a91523e9d7d67db71221de8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:38+01:00
Commit Message:
AGDS: fix animation ids
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index a2f2b762fde..606abea67f4 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -91,7 +91,7 @@ void Character::load(Common::SeekableReadStream *stream) {
unk5, unk6, unk7, unk8,
unk9, unk10, unk11);
}
- _animations.push_back(animation);
+ _animations[index] = animation;
}
delete stream;
@@ -104,7 +104,8 @@ void Character::direction(int dir) {
if (dir < 0)
return;
- _animation = _engine->loadAnimation(_animations[dir].filename);
+ auto desc = animationDescription(dir);
+ _animation = desc? _engine->loadAnimation(desc->filename): nullptr;
_animationPos = Common::Point();
if (!_animation) {
debug("no animation?");
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 26c9a08babc..ab799400ae8 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -24,7 +24,7 @@
#define AGDS_CHARACTER_H
#include "common/scummsys.h"
-#include "common/array.h"
+#include "common/hashmap.h"
#include "common/ptr.h"
#include "common/rect.h"
@@ -62,7 +62,7 @@ class Character {
Common::String filename;
Common::Array<Frame> frames;
};
- Common::Array<AnimationDescription> _animations;
+ Common::HashMap<int, AnimationDescription> _animations;
public:
Character(AGDSEngine * engine, const Common::String & name, const ObjectPtr & object):
@@ -70,7 +70,8 @@ public:
}
const AnimationDescription * animationDescription(uint index) const {
- return index < _animations.size()? &_animations[index]: nullptr;
+ auto it = _animations.find(index);
+ return it != _animations.end()? &it->_value: nullptr;
}
const Common::String & name() const {
Commit: 811693fd3ea99dad1235c0e8a2eb7017c90db556
https://github.com/scummvm/scummvm/commit/811693fd3ea99dad1235c0e8a2eb7017c90db556
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:38+01:00
Commit Message:
AGDS: read color key, min/max shadow color from config, rename stub 223
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3c2773b4f75..407471d3074 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -75,7 +75,6 @@ AGDSEngine::~AGDSEngine() {
}
bool AGDSEngine::initGraphics(int w, int h) {
- //fixme: get mode from config?
typedef Common::List<Graphics::PixelFormat> FormatsType;
FormatsType formats = _system->getSupportedFormats();
@@ -92,6 +91,22 @@ bool AGDSEngine::initGraphics(int w, int h) {
return false;
}
+void AGDSEngine::Color::FromString(const Common::String &rgb) {
+ uint cr, cg, cb;
+ if (sscanf(rgb.c_str(), "%u,%u,%u", &cr, &cg, &cb) == 3) {
+ r = cr;
+ g = cg;
+ b = cb;
+ }
+}
+
+uint32 AGDSEngine::Color::map(const Graphics::PixelFormat &format) const {
+ return format.RGBToColor(r, g, b);
+}
+Common::String AGDSEngine::Color::ToString() const {
+ return Common::String::format("#%02x%02x%02x", r, g, b);
+}
+
bool AGDSEngine::load() {
Common::INIFile config;
Common::File configFile;
@@ -109,8 +124,28 @@ bool AGDSEngine::load() {
debug("config videomode = %dx%d", w, h);
}
- if (!initGraphics(w, h))
- error("no video mode found");
+ {
+ Common::String transparency, shadowMin, shadowMax;
+ if (config.getKey("transparency", "core", transparency)) {
+ _colorKey.FromString(transparency);
+ }
+ debug("transparent color: %s", _colorKey.ToString().c_str());
+
+ if (config.getKey("shadow_min", "core", shadowMin)) {
+ _minShadowColor.FromString(shadowMin);
+ }
+ debug("shadow color min: %s", _minShadowColor.ToString().c_str());
+
+ if (config.getKey("shadow_max", "core", shadowMax)) {
+ _maxShadowColor.FromString(shadowMax);
+ }
+ debug("shadow color max: %s", _maxShadowColor.ToString().c_str());
+ }
+
+ if (!initGraphics(w, h)) {
+ warning("no video mode found");
+ return false;
+ }
Common::INIFile::SectionKeyList values = config.getKeys("core");
for (Common::INIFile::SectionKeyList::iterator i = values.begin(); i != values.end(); ++i) {
@@ -118,6 +153,7 @@ bool AGDSEngine::load() {
if (!_resourceManager.addPath(i->value))
return false;
}
+
if (!_data.open("data.adb"))
return false;
@@ -778,7 +814,7 @@ Graphics::TransparentSurface *AGDSEngine::convertToTransparent(Graphics::Surface
if (!surface)
return NULL;
Graphics::TransparentSurface *t = new Graphics::TransparentSurface(*surface, true);
- t->applyColorKey(0xff, 0, 0xff);
+ t->applyColorKey(_colorKey.r, _colorKey.g, _colorKey.b);
surface->free();
delete surface;
return t;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 45a20fabeeb..3b28787cc3b 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -78,6 +78,17 @@ class AGDSEngine : public Engine {
static constexpr uint MaxProcesses = 100;
public:
+
+ struct Color {
+ uint8 r = 0;
+ uint8 g = 0;
+ uint8 b = 0;
+
+ void FromString(const Common::String &rgb);
+ Common::String ToString() const;
+
+ uint32 map(const Graphics::PixelFormat &format) const;
+ };
AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc);
~AGDSEngine();
@@ -290,6 +301,9 @@ private:
SystemVariablesListType _systemVarList;
SystemVariablesType _systemVars;
Graphics::PixelFormat _pixelFormat;
+ Color _colorKey;
+ Color _minShadowColor;
+ Color _maxShadowColor;
MJPGPlayer * _mjpgPlayer;
uint32 _filmStarted;
Common::String _filmProcess;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 21a227cfcdb..024b61d0bf4 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -240,7 +240,7 @@ enum Opcode {
kStopCharacter = 220,
kRestartAnimation = 221,
kStub222 = 222,
- kStub223 = 223,
+ kSetShadowIntensity = 223,
kSetNPCTellNotifyVar = 224,
kPauseAnimation = 225,
kFadeObject = 226,
@@ -442,7 +442,7 @@ enum Opcode {
OP(kStopCharacter, stopCharacter) \
OP(kLeaveCharacterEx, leaveCharacterEx) \
OP(kRestartAnimation, restartAnimation) \
- OP(kStub223, stub223) \
+ OP(kSetShadowIntensity, setShadowIntensity) \
OP(kSetNPCTellNotifyVar, setNPCTellNotifyVar) \
OP(kPauseAnimation, pauseAnimation) \
OP(kFadeObject, fadeObject) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b69658e390d..f009022abb4 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -948,9 +948,9 @@ void Process::restartAnimation() {
}
}
-void Process::stub223() {
+void Process::setShadowIntensity() {
int value = pop();
- debug("stub223: %d", value);
+ debug("setShadowIntensity: %d", value);
}
void Process::pauseAnimation() {
Commit: fc8863f2915044ad9ce8fe9da3c14663d5422805
https://github.com/scummvm/scummvm/commit/fc8863f2915044ad9ce8fe9da3c14663d5422805
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:38+01:00
Commit Message:
AGDS: implement colorkeying and shadow effect
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 407471d3074..c05eae81efa 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -47,6 +47,7 @@ namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Engine(system),
_gameDescription(gameDesc), _pictureCacheId(1), _sharedStorageIndex(-2),
+ _shadowIntensity(0),
_processes(MaxProcesses),
_mjpgPlayer(), _filmStarted(0),
_currentScreen(), _currentCharacter(),
@@ -814,7 +815,26 @@ Graphics::TransparentSurface *AGDSEngine::convertToTransparent(Graphics::Surface
if (!surface)
return NULL;
Graphics::TransparentSurface *t = new Graphics::TransparentSurface(*surface, true);
- t->applyColorKey(_colorKey.r, _colorKey.g, _colorKey.b);
+ assert(t->format.bytesPerPixel == 4);
+ uint32* pixels = static_cast<uint32 *>(t->getPixels());
+ for (int i = 0; i < t->h; i++) {
+ for (int j = 0; j < t->w; j++) {
+ uint32 pix = pixels[i * t->w + j];
+ uint8 r, g, b, a;
+ t->format.colorToARGB(pix, a, r, g, b);
+ if (r == _colorKey.r && g == _colorKey.g && b == _colorKey.b) {
+ r = g = b = a = 0;
+ } else if (
+ r >= _minShadowColor.r && r <= _maxShadowColor.r &&
+ g >= _minShadowColor.g && g <= _maxShadowColor.g &&
+ b >= _minShadowColor.b && b <= _maxShadowColor.b
+ ) {
+ r = g = b = 0;
+ a = (255 * _shadowIntensity / 100);
+ }
+ pixels[i * t->w + j] = t->format.ARGBToColor(a, r, g, b);
+ }
+ }
surface->free();
delete surface;
return t;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 3b28787cc3b..07c627b92a3 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -272,6 +272,10 @@ public:
PatchPtr getPatch(const Common::String &screenName) const;
PatchPtr createPatch(const Common::String &screenName);
+ void shadowIntensity(int intensity) {
+ _shadowIntensity = intensity;
+ }
+
private:
void loadPatches(Common::SeekableReadStream *file, Database & db);
@@ -304,6 +308,7 @@ private:
Color _colorKey;
Color _minShadowColor;
Color _maxShadowColor;
+ int _shadowIntensity;
MJPGPlayer * _mjpgPlayer;
uint32 _filmStarted;
Common::String _filmProcess;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f009022abb4..14f1e570d55 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -951,6 +951,7 @@ void Process::restartAnimation() {
void Process::setShadowIntensity() {
int value = pop();
debug("setShadowIntensity: %d", value);
+ _engine->shadowIntensity(value);
}
void Process::pauseAnimation() {
Commit: 141bf240b197f932c08abfb8c0a19813a3220a56
https://github.com/scummvm/scummvm/commit/141bf240b197f932c08abfb8c0a19813a3220a56
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:39+01:00
Commit Message:
AGDS: use proper name of setObjectZtoDisplayHeight op
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 024b61d0bf4..1d1d5ea4be2 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -90,7 +90,7 @@ enum Opcode {
kLoadPictureFromObject = 69,
kLoadAnimationFromObject = 70,
kSetObjectZ = 71,
- kUpdateScreenHeightToDisplay = 72,
+ kUpdateObjectZToDisplay = 72,
kLoadTextFromObject = 73,
kScreenSetZNearFar = 74,
kScreenLoadRegion = 75,
@@ -349,7 +349,7 @@ enum Opcode {
OP(kAnimateCharacter, animateCharacter) \
OP(kLoadCharacter, loadCharacter) \
OP(kSetObjectZ, setObjectZ) \
- OP(kUpdateScreenHeightToDisplay, updateScreenHeightToDisplay) \
+ OP(kUpdateObjectZToDisplay, updateObjectZToDisplay) \
OP(kLoadTextFromObject, loadTextFromObject) \
OP(kCompareScreenName, compareScreenName) \
OP(kScreenSetZNearFar, screenSetZNearFar) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 14f1e570d55..4ff2d604e3e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1255,7 +1255,7 @@ void Process::setObjectZ() {
_engine->getCurrentScreen()->update(_object);
}
-void Process::updateScreenHeightToDisplay() {
+void Process::updateObjectZToDisplay() {
debug("updateObjectZtoDisplayHeight");
_object->z(g_system->getHeight());
_engine->getCurrentScreen()->update(_object);
Commit: 17fc1ac85da609ef82f53240baa48e79e0501ab6
https://github.com/scummvm/scummvm/commit/17fc1ac85da609ef82f53240baa48e79e0501ab6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:39+01:00
Commit Message:
AGDS: slightly fix inventory load object logic
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c05eae81efa..2ce7c5b70b9 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1090,12 +1090,11 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
int n = 34;
while(n--) {
Common::String name = readString(agds_i.get());
- int unk = agds_i->readUint32LE();
- int present = agds_i->readUint32LE();
- if (!name.empty() && present) {
- debug("inventory: %s %d %d", name.c_str(), unk, present);
- ObjectPtr object = runObject(name);
- _inventory.add(object);
+ int refcount = agds_i->readUint32LE();
+ int objectPtr = agds_i->readUint32LE();
+ if (!name.empty() && refcount) {
+ debug("inventory: %s %d %d", name.c_str(), refcount, objectPtr);
+ _inventory.add(runObject(name));
}
}
}
Commit: c25609bda556fca9ccb478eddcb02f64b6d61a79
https://github.com/scummvm/scummvm/commit/c25609bda556fca9ccb478eddcb02f64b6d61a79
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:39+01:00
Commit Message:
AGDS: do not allow calls for screens with patch
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 2ce7c5b70b9..b75a279dfab 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -299,11 +299,16 @@ void AGDSEngine::loadScreen(const Common::String &name) {
}
_animations.clear();
+ auto patch = getPatch(name);
+
_currentScreenName = name;
- _currentScreen = new Screen(this, loadObject(name));
- runProcess(_currentScreen->getObject());
+ auto screenObject = loadObject(name);
+ _currentScreen = new Screen(this, screenObject);
+ if (patch)
+ screenObject->allowCalls(false);
+
+ runProcess(screenObject);
- auto patch = getPatch(name);
if (patch) {
_currentScreen->load(patch);
if (_currentCharacter && patch->characterPresent) {
Commit: 5e2cd379aa8cb74dc1e819d0a15117b95cfb7937
https://github.com/scummvm/scummvm/commit/5e2cd379aa8cb74dc1e819d0a15117b95cfb7937
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:39+01:00
Commit Message:
AGDS: rename stub 193 to removeGapsFromInventory
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 1d1d5ea4be2..e6920912f7a 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -210,7 +210,7 @@ enum Opcode {
kSetObjectScale = 190,
kStub191 = 191,
kStub192 = 192,
- kStub193 = 193,
+ kRemoveGapsFromInventory = 193,
kMute = 194,
kGetObjectPictureWidth = 195,
kGetObjectPictureHeight = 196,
@@ -427,7 +427,7 @@ enum Opcode {
OP(kSetObjectText, setObjectText) \
OP(kSetObjectScale, setObjectScale) \
OP(kStub191, disableMouseAreas) \
- OP(kStub193, stub193) \
+ OP(kRemoveGapsFromInventory, removeGapsFromInventory) \
OP(kMute, stub194) \
OP(kGetObjectPictureWidth, getObjectPictureWidth) \
OP(kGetObjectPictureHeight, getObjectPictureHeight) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4ff2d604e3e..fbb0545ebef 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -854,8 +854,8 @@ void Process::stub192() {
debug("stub192: %s: set some object flag to %d", name.c_str(), value);
}
-void Process::stub193() {
- debug("stub193: removing inventory object 0?");
+void Process::removeGapsFromInventory() {
+ debug("removeGapsFromInventory: stub");
}
void Process::setObjectScale() {
Commit: 1906451c39903f294860e1df2ca071f71fe18344
https://github.com/scummvm/scummvm/commit/1906451c39903f294860e1df2ca071f71fe18344
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:39+01:00
Commit Message:
AGDS: show _lastIp without +7
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 387976626c6..ec5fa01f0ad 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -42,7 +42,7 @@ void Process::debug(const char *str, ...) {
va_list va;
va_start(va, str);
- Common::String format = Common::String::format("%s %04x[%u]: %s", _object->getName().c_str(), _lastIp + 7, _stack.size(), str);
+ Common::String format = Common::String::format("%s %04x[%u]: %s", _object->getName().c_str(), _lastIp, _stack.size(), str);
Common::String buf = Common::String::vformat(format.c_str(), va);
buf += '\n';
Commit: 88c6820d851e16ee6a13cc096c1ffb48bb16b1be
https://github.com/scummvm/scummvm/commit/88c6820d851e16ee6a13cc096c1ffb48bb16b1be
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:39+01:00
Commit Message:
AGDS: move Process::next to cpp file
Changed paths:
engines/agds/process.cpp
engines/agds/process.h
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index ec5fa01f0ad..1947a881fd0 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -70,6 +70,16 @@ void Process::error(const char *str, ...) {
_status = kStatusError;
}
+uint8 Process::next() {
+ const Object::CodeType & code = _object->getCode();
+ if (_ip < code.size()) {
+ return code[_ip++];
+ } else {
+ _status = kStatusError;
+ return 0;
+ }
+}
+
void Process::jump(int16 delta) {
debug("jump %+d", delta);
_ip += delta;
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 91482fe2def..9cce40b7338 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -74,16 +74,7 @@ private:
void push(bool);
- uint8 next() {
- const Object::CodeType & code = _object->getCode();
- if (_ip < code.size()) {
- return code[_ip++];
- } else {
- _status = kStatusError;
- return 0;
- }
- }
-
+ uint8 next();
uint16 next16() {
uint8 l = next();
uint16 h = next();
Commit: 962211b537d44a8d233f6e6f0d8bea570299bb9f
https://github.com/scummvm/scummvm/commit/962211b537d44a8d233f6e6f0d8bea570299bb9f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:39+01:00
Commit Message:
AGDS: add debug if jumpz didn't take conditional branch
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 1947a881fd0..9f08fd7b1b3 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -90,7 +90,8 @@ void Process::jumpz(int16 delta) {
if (value == 0) {
debug("jumpz %d %+d", value, delta);
_ip += delta;
- }
+ } else
+ debug("jumpz ignored %d %+d", value, delta);
}
void Process::incrementGlobalByTop() {
Commit: 0b96df7ddadaf229972b8de05791a669e86815e7
https://github.com/scummvm/scummvm/commit/0b96df7ddadaf229972b8de05791a669e86815e7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:39+01:00
Commit Message:
AGDS: rename stub 194 to samplePaused
Changed paths:
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 07c627b92a3..71039984b68 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -239,8 +239,8 @@ public:
void tickInventory();
- int playSound(const Common::String &process, const Common::String &resource, const Common::String &phaseVar) {
- return _soundManager.play(process, resource, phaseVar);
+ int playSound(const Common::String &process, const Common::String &resource, const Common::String &phaseVar, bool playing = true) {
+ return _soundManager.play(process, resource, phaseVar, playing);
}
void playSoundSync(const Common::String &resource, const Common::String &phaseVar) {
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index e6920912f7a..27621cc8c66 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -211,7 +211,7 @@ enum Opcode {
kStub191 = 191,
kStub192 = 192,
kRemoveGapsFromInventory = 193,
- kMute = 194,
+ kSamplePaused = 194,
kGetObjectPictureWidth = 195,
kGetObjectPictureHeight = 196,
kStub197 = 197,
@@ -428,7 +428,7 @@ enum Opcode {
OP(kSetObjectScale, setObjectScale) \
OP(kStub191, disableMouseAreas) \
OP(kRemoveGapsFromInventory, removeGapsFromInventory) \
- OP(kMute, stub194) \
+ OP(kSamplePaused, samplePaused) \
OP(kGetObjectPictureWidth, getObjectPictureWidth) \
OP(kGetObjectPictureHeight, getObjectPictureHeight) \
OP(kLoadPicture, loadPicture) \
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 9f08fd7b1b3..83885448800 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -33,7 +33,8 @@ Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) : _engine(en
_tileWidth(16), _tileHeight(16), _tileResource(0), _tileIndex(0),
_timer(0),
_animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0),
- _phaseVarControlled(false), _animationSpeed(100), _samplePeriodic(false),
+ _phaseVarControlled(false), _animationSpeed(100),
+ _samplePeriodic(false), _samplePaused(false),
_filmSubtitlesResource(-1)
{
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 9cce40b7338..70f6bbd0891 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -65,6 +65,7 @@ private:
bool _phaseVarControlled;
int _animationSpeed;
bool _samplePeriodic;
+ bool _samplePaused;
Common::Point _mousePosition;
int _filmSubtitlesResource;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index fbb0545ebef..7325eaa7036 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -642,6 +642,7 @@ void Process::resetState() {
_animationDelay = -1;
_animationSpeed = 100;
_samplePeriodic = false;
+ _samplePaused = false;
_tileWidth = 16;
_tileHeight = 16;
@@ -870,8 +871,9 @@ void Process::disableMouseAreas() {
_engine->_mouseMap.disable(_engine, value > 0);
}
-void Process::stub194() {
- debug("stub194: mute");
+void Process::samplePaused() {
+ debug("samplePaused: stub");
+ _samplePaused = true;
}
void Process::stub197() {
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index cfe70a0fd72..4533ead6211 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -47,7 +47,7 @@ void SoundManager::tick() {
debug("sample %s restarts (via phase var)", sound.name.c_str());
_engine->setGlobal(phaseVar, 1);
_mixer->stopID(sound.id);
- play(sound.process, sound.name, sound.phaseVar, sound.id);
+ play(sound.process, sound.name, sound.phaseVar, true, sound.id);
} else if (value & 4) {
debug("sample %s stops (via phase var)", sound.name.c_str());
_mixer->stopID(sound.id);
@@ -82,8 +82,8 @@ void SoundManager::stopAll() {
_sounds.clear();
}
-int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &phaseVar, int id) {
- debug("SoundMan::play %s %s %s", process.c_str(), resource.c_str(), phaseVar.c_str());
+int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &phaseVar, bool startPlaying, int id) {
+ debug("SoundMan::play %s %s %s %d %d", process.c_str(), resource.c_str(), phaseVar.c_str(), startPlaying, id);
{
auto sample = findSampleByPhaseVar(phaseVar);
if (sample && playing(sample->id)) {
@@ -120,9 +120,9 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
Audio::SoundHandle handle;
if (id == -1)
id = _nextId++;
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, stream, id);
_sounds.push_back(Sound(id, process, resource, phaseVar, handle));
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, stream, id);
//if (sound_off)
// setPhaseVar(_sounds.back(), 1);
return id;
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index 43732620cbc..d1693391865 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -44,8 +44,9 @@ namespace AGDS {
int group;
int leftVolume;
int rightVolume;
+ bool paused;
Sound(int id_, const Common::String &p, const Common::String & res, const Common::String & var, Audio::SoundHandle h, int g = 0):
- id(id_), process(p), name(res), phaseVar(var), handle(h), group(g), leftVolume(100), rightVolume(100) {
+ id(id_), process(p), name(res), phaseVar(var), handle(h), group(g), leftVolume(100), rightVolume(100), paused(false) {
}
};
@@ -59,7 +60,7 @@ namespace AGDS {
public:
SoundManager(AGDSEngine *engine, Audio::Mixer *mixer): _nextId(1), _engine(engine), _mixer(mixer) { }
void tick();
- int play(const Common::String &process, const Common::String &file, const Common::String &phaseVar, int id = -1);
+ int play(const Common::String &process, const Common::String &file, const Common::String &phaseVar, bool startPlaying = true, int id = -1);
bool playing(int id) const;
void stopAll();
Sound *findSampleByPhaseVar(const Common::String &phaseVar);
Commit: 07cbf16b383df53ad99ecef3cf83d49cec8fef55
https://github.com/scummvm/scummvm/commit/07cbf16b383df53ad99ecef3cf83d49cec8fef55
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:39+01:00
Commit Message:
AGDS: store only currently present objects in patch
Changed paths:
engines/agds/agds.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index b75a279dfab..dbea6c24aee 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -214,7 +214,10 @@ ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::Strin
void AGDSEngine::runObject(const ObjectPtr &object) {
if (_currentScreen) {
- if (_currentScreen->add(object)) {
+ auto patch = getPatch(_currentScreenName);
+ if (patch && patch->getFlag(object->getName()) <= 0) {
+ debug("object %s is not present in the patch", object->getName().c_str());
+ } else if (_currentScreen->add(object)) {
runProcess(object);
} else if (!object->inScene()) {
debug("marking object %s as in-scene...", object->getName().c_str());
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 103cb85be23..1f8e31a05c5 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -251,10 +251,10 @@ void Screen::save(const PatchPtr &patch) {
patch->objects.clear();
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
- if (!object->persistent())
+ if (!object->persistent() || !object->inScene())
continue;
debug("saving patch object %s %d", object->getName().c_str(), object->inScene());
- patch->objects.push_back(Patch::Object(object->getName(), object->inScene()));
+ patch->objects.push_back(Patch::Object(object->getName(), 1));
}
}
Commit: 07a7abe52d51aab91f17c0efa7d0a9b270c30480
https://github.com/scummvm/scummvm/commit/07a7abe52d51aab91f17c0efa7d0a9b270c30480
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:39+01:00
Commit Message:
AGDS: loadScreen only loads patches object
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index dbea6c24aee..c104227fbce 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -50,7 +50,8 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_shadowIntensity(0),
_processes(MaxProcesses),
_mjpgPlayer(), _filmStarted(0),
- _currentScreen(), _currentCharacter(),
+ _currentScreen(), _loadingScreen(false),
+ _currentCharacter(),
_defaultMouseCursor(),
_mouse(400, 300),
_userEnabled(true), _systemUserEnabled(true),
@@ -215,7 +216,7 @@ ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::Strin
void AGDSEngine::runObject(const ObjectPtr &object) {
if (_currentScreen) {
auto patch = getPatch(_currentScreenName);
- if (patch && patch->getFlag(object->getName()) <= 0) {
+ if (_loadingScreen && patch && patch->getFlag(object->getName()) <= 0) {
debug("object %s is not present in the patch", object->getName().c_str());
} else if (_currentScreen->add(object)) {
runProcess(object);
@@ -280,6 +281,7 @@ PatchPtr AGDSEngine::createPatch(const Common::String &screenName) {
}
void AGDSEngine::loadScreen(const Common::String &name) {
+ _loadingScreen = true;
_nextScreenName.clear();
debug("loadScreen %s", name.c_str());
if (_currentScreen && !_currentScreenName.empty())
@@ -322,6 +324,7 @@ void AGDSEngine::loadScreen(const Common::String &name) {
loadDefaultMouseCursor(patch->defaultMouseCursor);
}
reAddInventory();
+ _loadingScreen = false;
}
void AGDSEngine::resetCurrentScreen() {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 71039984b68..851ede229b0 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -314,6 +314,7 @@ private:
Common::String _filmProcess;
Screen * _currentScreen;
Common::String _currentScreenName;
+ bool _loadingScreen;
Character * _currentCharacter;
Character * _jokes;
Common::String _currentCharacterName;
Commit: 6c32395823f10c6af26dccd396c3aa3e20f9779f
https://github.com/scummvm/scummvm/commit/6c32395823f10c6af26dccd396c3aa3e20f9779f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:40+01:00
Commit Message:
AGDS: remove noisy char z log
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 606abea67f4..213bd031ffe 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -169,6 +169,7 @@ void Character::paint(Graphics::Surface &backbuffer) {
int Character::z() const {
int y = _pos.y + _animationPos.y;
//fixme: add temp var : _movePos?
+ //debug("char z = %d", y);
return y;
}
Commit: 14f86e95e8d1a9552f37fe3221208a583cf58fef
https://github.com/scummvm/scummvm/commit/14f86e95e8d1a9552f37fe3221208a583cf58fef
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:40+01:00
Commit Message:
AGDS: do not start all objects from the patch
Changed paths:
engines/agds/screen.cpp
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 1f8e31a05c5..567d480f0ad 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -238,10 +238,10 @@ void Screen::load(const PatchPtr &patch) {
if (object.flag <= 0)
remove(object.name);
else {
- auto instance = find(object.name); //find by name finds removed objects too
- if (!instance || !instance->inScene()) {
- _engine->runObject(object.name);
- }
+ // auto instance = find(object.name); //find by name finds removed objects too
+ // if (!instance || !instance->inScene()) {
+ // _engine->runObject(object.name);
+ // }
}
}
_applyingPatch = false;
Commit: bafd9576fab3394aa4cc1afdc8306680b8ece145
https://github.com/scummvm/scummvm/commit/bafd9576fab3394aa4cc1afdc8306680b8ece145
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:40+01:00
Commit Message:
AGDS: optimised colorKey/shadow (no multiplications inside loop)
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c104227fbce..8f5c1a7b006 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -828,9 +828,11 @@ Graphics::TransparentSurface *AGDSEngine::convertToTransparent(Graphics::Surface
Graphics::TransparentSurface *t = new Graphics::TransparentSurface(*surface, true);
assert(t->format.bytesPerPixel == 4);
uint32* pixels = static_cast<uint32 *>(t->getPixels());
- for (int i = 0; i < t->h; i++) {
- for (int j = 0; j < t->w; j++) {
- uint32 pix = pixels[i * t->w + j];
+ uint8 shadowAlpha = 255 * _shadowIntensity / 100;
+ uint delta = t->pitch - t->w * t->format.bytesPerPixel;
+ for (uint16 i = 0; i < t->h; ++i, pixels = reinterpret_cast<uint32*>((reinterpret_cast<uint8*>(pixels) + delta))) {
+ for (uint16 j = 0; j < t->w; ++j, ++pixels) {
+ uint32 pix = *pixels;
uint8 r, g, b, a;
t->format.colorToARGB(pix, a, r, g, b);
if (r == _colorKey.r && g == _colorKey.g && b == _colorKey.b) {
@@ -841,9 +843,11 @@ Graphics::TransparentSurface *AGDSEngine::convertToTransparent(Graphics::Surface
b >= _minShadowColor.b && b <= _maxShadowColor.b
) {
r = g = b = 0;
- a = (255 * _shadowIntensity / 100);
- }
- pixels[i * t->w + j] = t->format.ARGBToColor(a, r, g, b);
+ a = shadowAlpha;
+ } else
+ continue;
+
+ *pixels = t->format.ARGBToColor(a, r, g, b);
}
}
surface->free();
Commit: 879c57bb3a41f08d1475588d0090ac910c345d6a
https://github.com/scummvm/scummvm/commit/879c57bb3a41f08d1475588d0090ac910c345d6a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:40+01:00
Commit Message:
AGDS: remove returnToPreviousScreen hack
Changed paths:
engines/agds/process.cpp
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 83885448800..259054dbbb2 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -198,9 +198,6 @@ void Process::run() {
_engine->setNextScreenName(getExitArg1(), true);
done();
break;
- case kExitCodeLoadPreviousScreenObject:
- _engine->returnToPreviousScreen();
- break;
case kExitCodeMouseAreaChange:
_engine->changeMouseArea(getExitIntArg1(), getExitIntArg2());
activate();
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index 85ad53c5ca0..5a65265e720 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -40,8 +40,6 @@ namespace AGDS {
kExitCodeExitScreen = 15,
kExitCodeCloseInventory = 16,
kExitCodeSaveGame = 17,
-
- kExitCodeLoadPreviousScreenObject = 99
};
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 7325eaa7036..f923f0f18a3 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1237,7 +1237,8 @@ void Process::setNextScreenSaveInHistory() {
void Process::loadPreviousScreen() {
debug("loadPreviousScreen");
- suspend(kExitCodeLoadPreviousScreenObject);
+ _engine->returnToPreviousScreen();
+ suspend();
}
void Process::disableInventory() {
Commit: e094bd63722746b0b28b97e91e6006e5928f2668
https://github.com/scummvm/scummvm/commit/e094bd63722746b0b28b97e91e6006e5928f2668
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:40+01:00
Commit Message:
AGDS: loadScreen should load patches immediately only if returning to previous screen
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 8f5c1a7b006..227c1de66e3 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -52,6 +52,7 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_mjpgPlayer(), _filmStarted(0),
_currentScreen(), _loadingScreen(false),
_currentCharacter(),
+ _navigatedToPreviousScreen(false),
_defaultMouseCursor(),
_mouse(400, 300),
_userEnabled(true), _systemUserEnabled(true),
@@ -283,7 +284,7 @@ PatchPtr AGDSEngine::createPatch(const Common::String &screenName) {
void AGDSEngine::loadScreen(const Common::String &name) {
_loadingScreen = true;
_nextScreenName.clear();
- debug("loadScreen %s", name.c_str());
+ debug("loadScreen %s [return to previous: %d]", name.c_str(), _navigatedToPreviousScreen);
if (_currentScreen && !_currentScreenName.empty())
{
PatchPtr &patch = _patches[_currentScreenName];
@@ -314,7 +315,7 @@ void AGDSEngine::loadScreen(const Common::String &name) {
runProcess(screenObject);
- if (patch) {
+ if (patch &&_navigatedToPreviousScreen) {
_currentScreen->load(patch);
if (_currentCharacter && patch->characterPresent) {
_currentCharacter->position(patch->characterPosition);
@@ -324,6 +325,7 @@ void AGDSEngine::loadScreen(const Common::String &name) {
loadDefaultMouseCursor(patch->defaultMouseCursor);
}
reAddInventory();
+ _navigatedToPreviousScreen = false;
_loadingScreen = false;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 851ede229b0..869be0f35c8 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -220,6 +220,7 @@ public:
SystemVariable *getSystemVariable(const Common::String &name);
void setNextScreenName(const Common::String &nextScreenName, bool savePrev) {
+ _navigatedToPreviousScreen = false;
if (_currentScreen && savePrev) {
_previousScreenName = _currentScreenName;
}
@@ -228,6 +229,7 @@ public:
void returnToPreviousScreen() {
if (!_previousScreenName.empty()) {
+ _navigatedToPreviousScreen = true;
_nextScreenName = _previousScreenName;
_previousScreenName.clear();
}
@@ -321,6 +323,7 @@ private:
Common::String _nextScreenName;
Common::String _previousScreenName;
Common::String _defaultMouseCursorName;
+ bool _navigatedToPreviousScreen;
Animation * _defaultMouseCursor;
Common::Point _mouse;
MouseRegion * _currentRegion;
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 567d480f0ad..1f8e31a05c5 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -238,10 +238,10 @@ void Screen::load(const PatchPtr &patch) {
if (object.flag <= 0)
remove(object.name);
else {
- // auto instance = find(object.name); //find by name finds removed objects too
- // if (!instance || !instance->inScene()) {
- // _engine->runObject(object.name);
- // }
+ auto instance = find(object.name); //find by name finds removed objects too
+ if (!instance || !instance->inScene()) {
+ _engine->runObject(object.name);
+ }
}
}
_applyingPatch = false;
Commit: dd714dffb1b8ddbbdd302bf10e74b1e03a30419a
https://github.com/scummvm/scummvm/commit/dd714dffb1b8ddbbdd302bf10e74b1e03a30419a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:40+01:00
Commit Message:
AGDS: implemented hasPreviousScreenName flag
Changed paths:
engines/agds/agds.cpp
engines/agds/patch.cpp
engines/agds/patch.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 227c1de66e3..c4e5cc893ce 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -291,6 +291,10 @@ void AGDSEngine::loadScreen(const Common::String &name) {
if (!patch)
patch = PatchPtr(new Patch());
_currentScreen->save(patch);
+ if (!_previousScreenName.empty()) {
+ patch->prevScreenName = _previousScreenName;
+ patch->hasPreviousScreen = 1;
+ }
patch->characterPresent = _currentCharacter != nullptr;
if (_currentCharacter) {
patch->characterPosition = _currentCharacter->position();
@@ -323,6 +327,8 @@ void AGDSEngine::loadScreen(const Common::String &name) {
}
if (!patch->defaultMouseCursor.empty())
loadDefaultMouseCursor(patch->defaultMouseCursor);
+ if (patch->hasPreviousScreen)
+ _previousScreenName = patch->prevScreenName;
}
reAddInventory();
_navigatedToPreviousScreen = false;
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index 04152ad1200..b8b6cad1a5d 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -20,13 +20,12 @@ void Patch::load(Common::SeekableReadStream *stream) {
if (extended == 0)
return;
- unk41 = stream->readUint32LE();
+ hasPreviousScreen = stream->readUint32LE();
characterPosition.x = stream->readUint32LE();
characterPosition.y = stream->readUint32LE();
characterDirection = stream->readUint32LE();
characterPresent = stream->readUint32LE();
debug("character %s at %u,%u with dir: %u", characterPresent? "[present]": "[absent]", characterPosition.x, characterPosition.y, characterDirection);
- debug("some screen loading flag: %u", unk41);
uint object_count = stream->readUint32LE();
debug("objects in this patch: %u", object_count);
if (stream->read(palette, sizeof(palette)) != sizeof(palette)) {
@@ -52,7 +51,7 @@ void Patch::save(Common::SeekableWriteStream *stream) {
if (extended == 0)
return;
- stream->writeUint32LE(unk41);
+ stream->writeUint32LE(hasPreviousScreen);
stream->writeUint32LE(characterPosition.x);
stream->writeUint32LE(characterPosition.y);
stream->writeUint32LE(characterDirection);
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index a693a56e579..aebaf842c95 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -46,7 +46,7 @@ struct Patch {
Common::String screenRegionName;
Common::String prevScreenName;
- uint unk41 = 0;
+ uint hasPreviousScreen = 0;
Common::Point characterPosition;
uint characterDirection = 0;
bool characterPresent = false;
Commit: bd10b2c9e952e36cb49ee52caba6d283037babd7
https://github.com/scummvm/scummvm/commit/bd10b2c9e952e36cb49ee52caba6d283037babd7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:40+01:00
Commit Message:
AGDS: disallow calls only if patch present
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c4e5cc893ce..75ae03a33d8 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -310,16 +310,17 @@ void AGDSEngine::loadScreen(const Common::String &name) {
_animations.clear();
auto patch = getPatch(name);
+ auto screenObject = loadObject(name);
+ bool doPatch = patch && _navigatedToPreviousScreen;
_currentScreenName = name;
- auto screenObject = loadObject(name);
_currentScreen = new Screen(this, screenObject);
- if (patch)
+ if (doPatch)
screenObject->allowCalls(false);
runProcess(screenObject);
- if (patch &&_navigatedToPreviousScreen) {
+ if (doPatch) {
_currentScreen->load(patch);
if (_currentCharacter && patch->characterPresent) {
_currentCharacter->position(patch->characterPosition);
Commit: a008e8795ef9d9453021178711e625d1ebf578c0
https://github.com/scummvm/scummvm/commit/a008e8795ef9d9453021178711e625d1ebf578c0
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:40+01:00
Commit Message:
AGDS: disable calls for object restored from screen->load(patch)
Changed paths:
engines/agds/screen.cpp
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 1f8e31a05c5..d197e4517d4 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -240,7 +240,9 @@ void Screen::load(const PatchPtr &patch) {
else {
auto instance = find(object.name); //find by name finds removed objects too
if (!instance || !instance->inScene()) {
- _engine->runObject(object.name);
+ instance = _engine->loadObject(object.name);
+ instance->allowCalls(false);
+ _engine->runObject(instance);
}
}
}
Commit: c30a001191cd103f051107a257475de6f432261f
https://github.com/scummvm/scummvm/commit/c30a001191cd103f051107a257475de6f432261f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:40+01:00
Commit Message:
AGDS: fix character z
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 213bd031ffe..bbd581711e8 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -29,6 +29,7 @@
#include "common/debug.h"
#include "common/error.h"
#include "common/stream.h"
+#include "common/system.h"
#include "common/textconsole.h"
#include "common/util.h"
@@ -170,7 +171,7 @@ int Character::z() const {
int y = _pos.y + _animationPos.y;
//fixme: add temp var : _movePos?
//debug("char z = %d", y);
- return y;
+ return g_system->getHeight() - y;
}
Commit: 3ef1a1f68b31ffb497530b9e7b86b50594f6c0a1
https://github.com/scummvm/scummvm/commit/3ef1a1f68b31ffb497530b9e7b86b50594f6c0a1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:40+01:00
Commit Message:
AGDS: port to the newest upstream
Changed paths:
engines/agds/metaengine.cpp
diff --git a/engines/agds/metaengine.cpp b/engines/agds/metaengine.cpp
index 5df1ba535f6..ec4d2c04a50 100644
--- a/engines/agds/metaengine.cpp
+++ b/engines/agds/metaengine.cpp
@@ -28,7 +28,7 @@ namespace AGDS {
class AGDSMetaEngine : public AdvancedMetaEngine {
public:
- bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
+ Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
bool hasFeature(MetaEngineFeature f) const override {
switch (f) {
case kSimpleSavesNames:
@@ -78,11 +78,9 @@ public:
}
};
-bool AGDSMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
- if (desc) {
- *engine = new AGDS::AGDSEngine(syst, desc);
- }
- return *engine;
+Common::Error AGDSMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+ *engine = new AGDS::AGDSEngine(syst, desc);
+ return Common::Error(Common::kNoError);
}
}
Commit: 0ef9aeff3413b9ec4f4214fc7194b9298f05fc09
https://github.com/scummvm/scummvm/commit/0ef9aeff3413b9ec4f4214fc7194b9298f05fc09
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:41+01:00
Commit Message:
AGDS: use getValOrDefault()
Changed paths:
engines/agds/object.h
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 41dfd7b0823..c448b8ad722 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -190,7 +190,7 @@ public:
}
uint getUseHandler(const Common::String &name) const {
- return _useHandlers.getVal(name, 0); //use handler can never be 0
+ return _useHandlers.getValOrDefault(name, 0); //use handler can never be 0
}
void setUserUseHandler(uint ip) {
Commit: 2a866351da27e76725e9d739d7c2d99c7358f9f1
https://github.com/scummvm/scummvm/commit/2a866351da27e76725e9d739d7c2d99c7358f9f1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:41+01:00
Commit Message:
AGDS: add opcodes for throw/use-on handlers
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 246ca9531f7..a44e2a40dd4 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -38,8 +38,8 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_picture(), _region(),
_animation(), _mouseCursor(),
_pos(), _z(10),
- _clickHandler(0), _examineHandler(0),
- _userUseHandler(0),
+ _clickHandler(0), _examineHandler(0), _userUseHandler(0),
+ _throwHandler(0), _useOnHandler(0),
_alpha(255), _inScene(false),
_persistent(true), _allowCalls(true) {
uint16 id = stream->readUint16LE();
diff --git a/engines/agds/object.h b/engines/agds/object.h
index c448b8ad722..30fcc4bfc47 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -76,6 +76,8 @@ private:
uint _clickHandler;
uint _examineHandler;
uint _userUseHandler;
+ uint _throwHandler;
+ uint _useOnHandler;
int _alpha;
int _scale;
bool _inScene;
@@ -197,6 +199,15 @@ public:
debug("OBJECT %s USER USE %04x", _name.c_str(), ip);
_userUseHandler = ip;
}
+
+ void setThrowHandler(uint ip) {
+ _throwHandler = ip;
+ }
+
+ void setUseOnHandler(uint ip) {
+ _useOnHandler = ip;
+ }
+
uint getUserUseHandler() const {
return _userUseHandler;
}
@@ -246,6 +257,14 @@ public:
return i != _keyHandlers.end()? i->_value: 0;
}
+ uint throwHandler() const {
+ return _throwHandler;
+ }
+
+ uint useOnHandler() const {
+ return _useOnHandler;
+ }
+
bool inScene() const
{ return _inScene; }
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f923f0f18a3..9cbda5cb42c 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -894,12 +894,14 @@ void Process::setTileIndex() {
}
void Process::stub201(uint16 size) {
- debug("stub201, [handler] %u instructions", size);
+ debug("setThrowHandler, [handler] %u instructions", size);
+ _object->setThrowHandler(_ip);
_ip += size;
}
void Process::stub202(uint16 size) {
- debug("stub202, [handler] %u instructions", size);
+ debug("setUseOnHandler %u instructions", size);
+ _object->setUseOnHandler(_ip);
_ip += size;
}
Commit: 170d7267c6255f72ed5e00a0b05c4cc406fefc3e
https://github.com/scummvm/scummvm/commit/170d7267c6255f72ed5e00a0b05c4cc406fefc3e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:41+01:00
Commit Message:
AGDS: rename opcode197 to setRotation
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 27621cc8c66..b32447bca87 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -214,7 +214,7 @@ enum Opcode {
kSamplePaused = 194,
kGetObjectPictureWidth = 195,
kGetObjectPictureHeight = 196,
- kStub197 = 197,
+ kSetRotation = 197,
kLoadPicture = 198,
kStub199 = 199,
kSetTileIndex = 200,
@@ -432,7 +432,7 @@ enum Opcode {
OP(kGetObjectPictureWidth, getObjectPictureWidth) \
OP(kGetObjectPictureHeight, getObjectPictureHeight) \
OP(kLoadPicture, loadPicture) \
- OP(kStub197, stub197) \
+ OP(kSetRotation, setRotation) \
OP(kStub199, stub199) \
OP(kSetSampleVolumeAndPan, setSampleVolumeAndPan) \
OP(kAddSampleToSoundGroup, addSampleToSoundGroup) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 9cbda5cb42c..50c833e809f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -876,10 +876,10 @@ void Process::samplePaused() {
_samplePaused = true;
}
-void Process::stub197() {
- int flag = pop();
+void Process::setRotation() {
+ int rotate = pop();
auto objectName = popString();
- debug("stub197: %s %d", objectName.c_str(), flag);
+ debug("setRotation: object: %s %d", objectName.c_str(), rotate);
}
void Process::stub199() {
Commit: 06b3100a89d7507fd9ebb2b3bbf02689f0ab1930
https://github.com/scummvm/scummvm/commit/06b3100a89d7507fd9ebb2b3bbf02689f0ab1930
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:41+01:00
Commit Message:
AGDS: add Region::empty()
Changed paths:
engines/agds/region.h
diff --git a/engines/agds/region.h b/engines/agds/region.h
index 68087ae418d..3b41c40e9c8 100644
--- a/engines/agds/region.h
+++ b/engines/agds/region.h
@@ -45,6 +45,10 @@ struct Region {
Common::String toString() const;
void move(Common::Point rel);
Common::Point topLeft() const;
+
+ bool empty() const {
+ return regions.empty();
+ }
};
Commit: 165c2a7428c29600c109116fd760ff8ab2893234
https://github.com/scummvm/scummvm/commit/165c2a7428c29600c109116fd760ff8ab2893234
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:41+01:00
Commit Message:
AGDS: rename stub201/202
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index b32447bca87..acbf768dd87 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -218,8 +218,8 @@ enum Opcode {
kLoadPicture = 198,
kStub199 = 199,
kSetTileIndex = 200,
- kStub201Handler = 201,
- kStub202ScreenHandler = 202,
+ kSetThrowHandler = 201,
+ kSetUseOnHandler = 202,
kPlayFilm = 203,
kStub204 = 204,
kAddMouseArea = 205,
@@ -447,8 +447,8 @@ enum Opcode {
OP(kPauseAnimation, pauseAnimation) \
OP(kFadeObject, fadeObject) \
OP(kLoadFont, loadFont) \
- OP_U(kStub201Handler, stub201) \
- OP_U(kStub202ScreenHandler, stub202) \
+ OP_U(kSetThrowHandler, setThrowHandler) \
+ OP_U(kSetUseOnHandler, setUseOnHandler) \
OP(kPlayFilm, playFilm) \
OP(kAddMouseArea, addMouseArea) \
OP(kSetRain, setRain) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 50c833e809f..28983b2ae13 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -893,13 +893,13 @@ void Process::setTileIndex() {
debug("setTileIndex: index: %d, resource id: %d ", _tileIndex, _tileResource);
}
-void Process::stub201(uint16 size) {
+void Process::setThrowHandler(uint16 size) {
debug("setThrowHandler, [handler] %u instructions", size);
_object->setThrowHandler(_ip);
_ip += size;
}
-void Process::stub202(uint16 size) {
+void Process::setUseOnHandler(uint16 size) {
debug("setUseOnHandler %u instructions", size);
_object->setUseOnHandler(_ip);
_ip += size;
Commit: d30cda07ff1c99930289a68e401383469ebc813e
https://github.com/scummvm/scummvm/commit/d30cda07ff1c99930289a68e401383469ebc813e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:41+01:00
Commit Message:
AGDS: use throw handler if use didn't work, use UseOn as a fallback for UseOn(object)
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 75ae03a33d8..a50004b6327 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -560,8 +560,14 @@ Common::Error AGDSEngine::run() {
if (_currentInventoryObject) {
debug("trying use handler for object %s", _currentInventoryObject->getName().c_str());
ip = object->getUseHandler(_currentInventoryObject->getName());
- } else
+ if (!ip)
+ ip = object->useOnHandler();
+ } else {
ip = object->getClickHandler();
+ if (ip == 0) {
+ ip = object->useOnHandler();
+ }
+ }
} else
ip = object->getExamineHandler();
Commit: 3c56994e9af57bca15be9f043694636a7a0e2156
https://github.com/scummvm/scummvm/commit/3c56994e9af57bca15be9f043694636a7a0e2156
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:41+01:00
Commit Message:
AGDS: sync mouse position when process starts
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 259054dbbb2..1851d58605e 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -37,6 +37,7 @@ Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) : _engine(en
_samplePeriodic(false), _samplePaused(false),
_filmSubtitlesResource(-1)
{
+ updateWithCurrentMousePosition();
}
void Process::debug(const char *str, ...) {
Commit: 819836dc24aa11ce300bf76234a8a8287e1b0a39
https://github.com/scummvm/scummvm/commit/819836dc24aa11ce300bf76234a8a8287e1b0a39
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:41+01:00
Commit Message:
AGDS: add debug log when mouse animation is empty (removal)
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 28983b2ae13..46596d40446 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -530,7 +530,11 @@ void Process::checkScreenPatch() {
void Process::loadMouseCursorFromObject() {
Common::String name = popText();
- debug("loadMouseCursorFromObject %s", name.c_str());
+ debug("loadMouseCursorFromObject %s", !name.empty()? name.c_str(): "<remove>");
+ if (name.empty()) {
+ debug("loadMouseCursorFromObject: stub: should remove picture/animation from object here (if not current inventory)");
+ return;
+ }
Animation *cursor = _engine->loadMouseCursor(name);
_object->setMouseCursor(cursor); //overlay cursor
}
Commit: 4f0a255cf07fbec01b4582a82901fed9e1a8f8c0
https://github.com/scummvm/scummvm/commit/4f0a255cf07fbec01b4582a82901fed9e1a8f8c0
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:41+01:00
Commit Message:
AGDS: remove region when object goes off screen
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index a44e2a40dd4..4155b7ce2bb 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -147,6 +147,14 @@ void Object::setPicture(Graphics::TransparentSurface *picture) {
}
}
+void Object::inScene(bool value)
+{
+ _inScene = value;
+ if (!_inScene)
+ _region.reset();
+}
+
+
void Object::region(RegionPtr region) {
_region = region;
}
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 30fcc4bfc47..d7307d6fe8f 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -268,8 +268,7 @@ public:
bool inScene() const
{ return _inScene; }
- void inScene(bool value)
- { _inScene = value; }
+ void inScene(bool value);
bool pointIn(Common::Point pos);
};
Commit: a2ccb432f2f40130d2cf6e8cf983818fa002e051
https://github.com/scummvm/scummvm/commit/a2ccb432f2f40130d2cf6e8cf983818fa002e051
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:41+01:00
Commit Message:
AGDS: add Object::getRect()
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 4155b7ce2bb..ae121594349 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -169,12 +169,21 @@ void Object::generateRegion() {
return;
}
- Common::Rect rect = _picture->getRect();
- rect.moveTo(_pos.x, _pos.y);
+ auto rect = getRect();
_region = RegionPtr(new Region(rect));
debug("%s: generated region: %s", _name.c_str(), _region->toString().c_str());
}
+Common::Rect Object::getRect() const {
+ if (!_picture) {
+ warning("getRect called on null picture");
+ return Common::Rect();
+ }
+ Common::Rect rect = _picture->getRect();
+ rect.moveTo(_pos.x, _pos.y);
+ return rect;
+}
+
bool Object::pointIn(Common::Point pos) {
if (!_inScene)
return false;
Commit: 9ffa1968f6a3cc04d66b2e153e4b4d672011f03b
https://github.com/scummvm/scummvm/commit/9ffa1968f6a3cc04d66b2e153e4b4d672011f03b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:42+01:00
Commit Message:
AGDS: add throw/useOn handlers
Changed paths:
engines/agds/agds.cpp
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index a50004b6327..55d67b4c0b7 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -537,7 +537,7 @@ Common::Error AGDSEngine::run() {
if (userEnabled()) {
bool lclick = event.type == Common::EVENT_LBUTTONDOWN;
debug("%s %d, %d", lclick ? "lclick" : "rclick", _mouse.x, _mouse.y);
- if (!lclick && _currentInventoryObject) {
+ if (!lclick && _currentInventoryObject && !_currentInventoryObject->useOnHandler()) {
auto object = _currentInventoryObject;
_currentInventoryObject.reset();
@@ -564,12 +564,14 @@ Common::Error AGDSEngine::run() {
ip = object->useOnHandler();
} else {
ip = object->getClickHandler();
- if (ip == 0) {
- ip = object->useOnHandler();
- }
}
- } else
+ } else {
ip = object->getExamineHandler();
+ }
+ if (!ip && _currentInventoryObject) {
+ ip = lclick? _currentInventoryObject->useOnHandler(): _currentInventoryObject->throwHandler();
+ object = _currentInventoryObject;
+ }
if (ip) {
debug("found handler: %s %08x", object->getName().c_str(), ip + 7);
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index ae121594349..b6630b287d9 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -188,7 +188,14 @@ bool Object::pointIn(Common::Point pos) {
if (!_inScene)
return false;
- pos -= _pos;
+ if (_picture) {
+ auto rect = getRect();
+ if (rect.contains(pos)) {
+ return true;
+ }
+ }
+
+ // pos -= _pos;
pos -= _regionOffset;
if (_region && _region->pointIn(pos))
diff --git a/engines/agds/object.h b/engines/agds/object.h
index d7307d6fe8f..9cdabd59ebc 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -248,6 +248,8 @@ public:
return _offset;
}
+ Common::Rect getRect() const;
+
void setKeyHandler(const Common::String &name, uint ip) {
_keyHandlers[name] = ip;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 46596d40446..55fd7301e19 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -898,7 +898,7 @@ void Process::setTileIndex() {
}
void Process::setThrowHandler(uint16 size) {
- debug("setThrowHandler, [handler] %u instructions", size);
+ debug("setThrowHandler %u instructions", size);
_object->setThrowHandler(_ip);
_ip += size;
}
Commit: 0eec5e26bf2b3f0c3a8a9dd0927aba5ba455af09
https://github.com/scummvm/scummvm/commit/0eec5e26bf2b3f0c3a8a9dd0927aba5ba455af09
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:42+01:00
Commit Message:
AGDS: implement mouse cursor removal
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 55fd7301e19..085a730e2f0 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -531,11 +531,7 @@ void Process::checkScreenPatch() {
void Process::loadMouseCursorFromObject() {
Common::String name = popText();
debug("loadMouseCursorFromObject %s", !name.empty()? name.c_str(): "<remove>");
- if (name.empty()) {
- debug("loadMouseCursorFromObject: stub: should remove picture/animation from object here (if not current inventory)");
- return;
- }
- Animation *cursor = _engine->loadMouseCursor(name);
+ Animation *cursor = !name.empty()? _engine->loadMouseCursor(name): nullptr;
_object->setMouseCursor(cursor); //overlay cursor
}
Commit: 096218f87c3c233277a70910570377d680b85f96
https://github.com/scummvm/scummvm/commit/096218f87c3c233277a70910570377d680b85f96
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:42+01:00
Commit Message:
AGDS: fix increment/decrement global by top instructions
Changed paths:
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 1851d58605e..6a7e9789dde 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -96,14 +96,6 @@ void Process::jumpz(int16 delta) {
debug("jumpz ignored %d %+d", value, delta);
}
-void Process::incrementGlobalByTop() {
- incrementGlobal(top());
-}
-void Process::decrementGlobalByTop() {
- decrementGlobal(top());
-}
-
-
void Process::suspend() {
suspend(kExitCodeSuspend);
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 70f6bbd0891..569a1892535 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -106,9 +106,6 @@ private:
#define AGDS_PROCESS_METHOD_UU(opcode, method) \
void method (uint16, uint16) ;
- void incrementGlobal(int inc);
- void decrementGlobal(int inc);
-
AGDS_OPCODE_LIST(AGDS_PROCESS_METHOD,
AGDS_PROCESS_METHOD_C, AGDS_PROCESS_METHOD_B, AGDS_PROCESS_METHOD_W,
AGDS_PROCESS_METHOD_U, AGDS_PROCESS_METHOD_UD, AGDS_PROCESS_METHOD_UU)
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 085a730e2f0..7bc34827998 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -343,16 +343,18 @@ void Process::postDecrementGlobal() {
_engine->setGlobal(name, value - 1);
}
-void Process::incrementGlobal(int inc) {
+void Process::incrementGlobalByTop() {
Common::String name = popString();
int value = _engine->getGlobal(name);
+ auto inc = top();
debug("increment global %s %d by %d", name.c_str(), value, inc);
_engine->setGlobal(name, value + inc);
}
-void Process::decrementGlobal(int dec) {
+void Process::decrementGlobalByTop() {
Common::String name = popString();
int value = _engine->getGlobal(name);
+ auto dec = top();
debug("decrement global %s %d by %d", name.c_str(), value, dec);
_engine->setGlobal(name, value - dec);
}
Commit: c0c77888ab174574bf9a140908b4518e4df6911b
https://github.com/scummvm/scummvm/commit/c0c77888ab174574bf9a140908b4518e4df6911b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:42+01:00
Commit Message:
AGDS: correct pointIn for object with animation
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index b6630b287d9..b2b7e1b6ca8 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -195,6 +195,14 @@ bool Object::pointIn(Common::Point pos) {
}
}
+ if (_animation) {
+ Common::Rect rect(0, 0, _animation->width(), _animation->height());
+ rect.moveTo(_pos + _animationPos);
+ if (rect.contains(pos)) {
+ return true;
+ }
+ }
+
// pos -= _pos;
pos -= _regionOffset;
Commit: 437876fc4afc532b10233df27d34cd5662ca7dfb
https://github.com/scummvm/scummvm/commit/437876fc4afc532b10233df27d34cd5662ca7dfb
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:42+01:00
Commit Message:
AGDS: add _rotatePicture
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index b2b7e1b6ca8..4b6241e190d 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -35,7 +35,7 @@
namespace AGDS {
Object::Object(const Common::String &name, Common::SeekableReadStream *stream) : _name(name), _stringTableLoaded(false),
- _picture(), _region(),
+ _picture(), _rotatedPicture(), _region(),
_animation(), _mouseCursor(),
_pos(), _z(10),
_clickHandler(0), _examineHandler(0), _userUseHandler(0),
@@ -59,6 +59,10 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
}
Object::~Object() {
+ if (_rotatedPicture) {
+ _rotatedPicture->free();
+ delete _rotatedPicture;
+ }
if (_picture) {
_picture->free();
delete _picture;
@@ -116,6 +120,11 @@ void Object::setPicture(Graphics::TransparentSurface *picture) {
_picture->free();
delete _picture;
}
+ if (_rotatedPicture) {
+ _rotatedPicture->free();
+ delete _rotatedPicture;
+ _rotatedPicture = nullptr;
+ }
_picture = picture;
if (!picture) {
@@ -175,11 +184,12 @@ void Object::generateRegion() {
}
Common::Rect Object::getRect() const {
- if (!_picture) {
+ auto picture = getPicture();
+ if (!picture) {
warning("getRect called on null picture");
return Common::Rect();
}
- Common::Rect rect = _picture->getRect();
+ Common::Rect rect = picture->getRect();
rect.moveTo(_pos.x, _pos.y);
return rect;
}
@@ -188,7 +198,8 @@ bool Object::pointIn(Common::Point pos) {
if (!_inScene)
return false;
- if (_picture) {
+ auto picture = getPicture();
+ if (picture) {
auto rect = getRect();
if (rect.contains(pos)) {
return true;
@@ -213,12 +224,13 @@ bool Object::pointIn(Common::Point pos) {
}
void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
- if (_picture) {
+ auto picture = getPicture();
+ if (picture) {
Common::Point dst = getPosition();
- Common::Rect srcRect = _picture->getRect();
+ Common::Rect srcRect = picture->getRect();
uint32 color = (_alpha << 24) | 0xffffff; //fixme: _picture->format.ARGBToColor(_alpha, 255, 255, 255); is not working
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect())) {
- _picture->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
+ picture->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
}
}
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 9cdabd59ebc..e3808202d8f 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -65,6 +65,7 @@ private:
KeyHandlersType _keyHandlers;
UseHandlersType _useHandlers;
Graphics::TransparentSurface * _picture;
+ Graphics::TransparentSurface * _rotatedPicture;
RegionPtr _region;
Animation * _animation;
Animation * _mouseCursor;
@@ -136,7 +137,7 @@ public:
void setPicture(Graphics::TransparentSurface *);
Graphics::TransparentSurface *getPicture() const {
- return _picture;
+ return _rotatedPicture? _rotatedPicture: _picture;
}
void generateRegion();
Commit: 82e916a9be992a3f995304aba6564daf6bd4dc60
https://github.com/scummvm/scummvm/commit/82e916a9be992a3f995304aba6564daf6bd4dc60
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:42+01:00
Commit Message:
AGDS: implement rotation
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 4b6241e190d..59a0c559d66 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -59,16 +59,22 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
}
Object::~Object() {
- if (_rotatedPicture) {
- _rotatedPicture->free();
- delete _rotatedPicture;
- }
+ freeRotated();
if (_picture) {
_picture->free();
delete _picture;
}
}
+void Object::freeRotated() {
+ if (_rotatedPicture) {
+ _rotatedPicture->free();
+ delete _rotatedPicture;
+ }
+ _rotatedPicture = nullptr;
+}
+
+
void Object::readStringTable(unsigned resOffset, uint16 resCount) {
if (_stringTableLoaded)
return;
@@ -120,11 +126,7 @@ void Object::setPicture(Graphics::TransparentSurface *picture) {
_picture->free();
delete _picture;
}
- if (_rotatedPicture) {
- _rotatedPicture->free();
- delete _rotatedPicture;
- _rotatedPicture = nullptr;
- }
+ freeRotated();
_picture = picture;
if (!picture) {
@@ -156,6 +158,22 @@ void Object::setPicture(Graphics::TransparentSurface *picture) {
}
}
+void Object::rotate(int rot) {
+ if (rot == 0)
+ return;
+
+ if (!_picture) {
+ warning("no picture for rotation");
+ return;
+ }
+
+ Graphics::TransformStruct transform(100, 100, 90 * rot, _picture->w / 2, _picture->h / 2);
+ auto rotated = _picture->rotoscale(transform);
+ freeRotated();
+ _rotatedPicture = rotated;
+}
+
+
void Object::inScene(bool value)
{
_inScene = value;
diff --git a/engines/agds/object.h b/engines/agds/object.h
index e3808202d8f..feed151edda 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -85,6 +85,9 @@ private:
bool _persistent;
bool _allowCalls;
+private:
+ void freeRotated();
+
public:
Object(const Common::String &name, Common::SeekableReadStream * stream);
~Object();
@@ -140,6 +143,8 @@ public:
return _rotatedPicture? _rotatedPicture: _picture;
}
+ void rotate(int rot);
+
void generateRegion();
void regionOffset(Common::Point offset) {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 7bc34827998..4cee5cef1f3 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -882,6 +882,11 @@ void Process::setRotation() {
int rotate = pop();
auto objectName = popString();
debug("setRotation: object: %s %d", objectName.c_str(), rotate);
+ ObjectPtr object = _engine->getCurrentScreenObject(objectName);
+ if (object)
+ object->rotate(rotate);
+ else
+ warning("setRotation: object: %s not found in scene", objectName.c_str());
}
void Process::stub199() {
Commit: 4067dd5cb73e98b5eda52c626b7ec0dd29524d0e
https://github.com/scummvm/scummvm/commit/4067dd5cb73e98b5eda52c626b7ec0dd29524d0e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:42+01:00
Commit Message:
AGDS: correct text position by region offset
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 59a0c559d66..5958ad4e0e9 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -258,7 +258,7 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
}
if (!_text.empty()) {
- Common::Point pos = _region ? _region->center : _pos;
+ Common::Point pos = _region ? _region->center + _regionOffset : _pos;
int w = backbuffer.w - pos.x;
engine.getFont(engine.getSystemVariable("objtext_font")->getInteger())->drawString(&backbuffer, _text, pos.x, pos.y, w, 0);
}
Commit: b6cb6addd3b593ce7269a3b8e355d743c5d9ba99
https://github.com/scummvm/scummvm/commit/b6cb6addd3b593ce7269a3b8e355d743c5d9ba99
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:42+01:00
Commit Message:
AGDS: implement opcode 167 - return current inventory object
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 55d67b4c0b7..ad218b42875 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -538,11 +538,7 @@ Common::Error AGDSEngine::run() {
bool lclick = event.type == Common::EVENT_LBUTTONDOWN;
debug("%s %d, %d", lclick ? "lclick" : "rclick", _mouse.x, _mouse.y);
if (!lclick && _currentInventoryObject && !_currentInventoryObject->useOnHandler()) {
- auto object = _currentInventoryObject;
- _currentInventoryObject.reset();
-
- _inventory.add(object);
- runObject(object);
+ returnCurrentInventoryObject();
break;
}
@@ -1170,4 +1166,13 @@ void AGDSEngine::resetCurrentInventoryObject() {
_currentInventoryObject.reset();
}
+void AGDSEngine::returnCurrentInventoryObject() {
+ auto object = _currentInventoryObject;
+ _currentInventoryObject.reset();
+
+ _inventory.add(object);
+ runObject(object);
+}
+
+
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 869be0f35c8..2dea673b8d8 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -261,6 +261,7 @@ public:
void currentInventoryObject(const ObjectPtr & object);
void resetCurrentInventoryObject();
+ void returnCurrentInventoryObject();
const ObjectPtr & currentInventoryObject() const {
return _currentInventoryObject;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index acbf768dd87..8dbd81b0bf8 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -184,7 +184,7 @@ enum Opcode {
kLoadPreviousScreen = 164,
kMoveScreenObject = 165,
kSetObjectRegionOffset = 166,
- kStub167 = 167,
+ kReturnCurrentInventoryObject = 167,
kStub168 = 168,
kGetIntegerSystemVariable = 169,
kSetDelay = 170,
@@ -424,6 +424,7 @@ enum Opcode {
OP(kAppendInventoryObjectNameToSharedSpace, appendInventoryObjectNameToSharedSpace) \
OP(kSetObjectTile, setObjectTile) \
OP(kInventoryHasObject, inventoryHasObject) \
+ OP(kReturnCurrentInventoryObject, returnCurrentInventoryObject) \
OP(kSetObjectText, setObjectText) \
OP(kSetObjectScale, setObjectScale) \
OP(kStub191, disableMouseAreas) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4cee5cef1f3..e9ebb7ca95c 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -547,6 +547,11 @@ void Process::attachInventoryObjectToMouse(bool flag) {
warning("cannot find object %s", name.c_str());
}
+void Process::returnCurrentInventoryObject() {
+ debug("returnCurrentInventoryObject");
+ _engine->returnCurrentInventoryObject();
+}
+
void Process::attachInventoryObjectToMouse0() {
attachInventoryObjectToMouse(false);
}
Commit: af84f21406879ceb5b82f364f98e0cec5557f53d
https://github.com/scummvm/scummvm/commit/af84f21406879ceb5b82f364f98e0cec5557f53d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:42+01:00
Commit Message:
AGDS: fix findInventoryObjectByName, add hasInventoryObjectByName
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 8dbd81b0bf8..3ffd175885c 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -206,7 +206,7 @@ enum Opcode {
kInventoryHasObject = 186,
kAppendInventoryObjectNameToSharedSpace = 187,
kSetObjectText = 188,
- kStub189 = 189,
+ kInventoryFindObjectByName = 189,
kSetObjectScale = 190,
kStub191 = 191,
kStub192 = 192,
@@ -255,7 +255,7 @@ enum Opcode {
kStub235 = 235,
kUserEnabled = 236,
kStub237 = 237,
- kInventoryFindObjectByName = 238,
+ kInventoryHasObjectByName = 238,
kStub239 = 239,
kLoadDialog = 240,
kStub241 = 241,
@@ -467,6 +467,7 @@ enum Opcode {
OP(kUserEnabled, userEnabled) \
OP(kSetCharacterNotifyVars, setCharacterNotifyVars) \
OP(kInventoryFindObjectByName, inventoryFindObjectByName) \
+ OP(kInventoryHasObjectByName, inventoryHasObjectByName) \
OP(kLoadDialog, loadDialog) \
OP(kHasGlobal, hasGlobal) \
OP(kAttachInventoryObjectToMouse0, attachInventoryObjectToMouse0) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index e9ebb7ca95c..ce6dee16282 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1210,6 +1210,14 @@ void Process::inventoryFindObjectByName() {
push(index);
}
+void Process::inventoryHasObjectByName() {
+ Common::String name = popString();
+ debug("inventoryHasObjectByName %s", name.c_str());
+ bool hasObject = _engine->inventory().find(name) >= 0;
+ debug("\t->%d", hasObject);
+ push(hasObject);
+}
+
void Process::inventoryHasObject() {
int index = pop();
debug("inventoryHasObject %d", index);
Commit: fa7c684bf3c68f643ca0aa40306baba6c71649e3
https://github.com/scummvm/scummvm/commit/fa7c684bf3c68f643ca0aa40306baba6c71649e3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:42+01:00
Commit Message:
AGDS: rotate current rotated picture
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 5958ad4e0e9..73629aaab13 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -168,7 +168,7 @@ void Object::rotate(int rot) {
}
Graphics::TransformStruct transform(100, 100, 90 * rot, _picture->w / 2, _picture->h / 2);
- auto rotated = _picture->rotoscale(transform);
+ auto rotated = getPicture()->rotoscale(transform);
freeRotated();
_rotatedPicture = rotated;
}
@@ -191,7 +191,7 @@ void Object::moveTo(Common::Point pos) {
}
void Object::generateRegion() {
- if (!_picture) {
+ if (!getPicture()) {
warning("generateRegion called on null picture");
return;
}
Commit: 745c9b077e08f51bf206d7d771b4afa8cca15517
https://github.com/scummvm/scummvm/commit/745c9b077e08f51bf206d7d771b4afa8cca15517
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:43+01:00
Commit Message:
AGDS: minor log cleanup, add setGlobal log
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index ce6dee16282..bde46a5b813 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -303,14 +303,15 @@ void Process::getRandomNumber() {
void Process::setGlobal() {
Common::String name = popString();
int value = pop();
+ debug("setGlobal %s %d", name.c_str(), value);
_engine->setGlobal(name, value);
}
void Process::setPhaseVar() {
Common::String name = popString();
+ debug("setPhaseVar %s", name.c_str());
_engine->setGlobal(name, 0);
_phaseVar = name;
- debug("setPhaseVar %s", name.c_str());
}
void Process::getGlobal(uint8 index) {
Commit: 440fb93070f2a950105ec90ed6b72d4ed6c5b494
https://github.com/scummvm/scummvm/commit/440fb93070f2a950105ec90ed6b72d4ed6c5b494
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:43+01:00
Commit Message:
AGDS: handler logic finding cleanup and better logs
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ad218b42875..ab7adbf121d 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -554,18 +554,23 @@ Common::Error AGDSEngine::run() {
uint ip;
if (lclick) {
if (_currentInventoryObject) {
- debug("trying use handler for object %s", _currentInventoryObject->getName().c_str());
ip = object->getUseHandler(_currentInventoryObject->getName());
- if (!ip)
- ip = object->useOnHandler();
+ if (ip)
+ debug("found use handler for current inventory object %s", _currentInventoryObject->getName().c_str());
} else {
ip = object->getClickHandler();
+ if (ip)
+ debug("found click handler");
}
} else {
ip = object->getExamineHandler();
+ if (ip)
+ debug("found examine handler");
}
if (!ip && _currentInventoryObject) {
ip = lclick? _currentInventoryObject->useOnHandler(): _currentInventoryObject->throwHandler();
+ if (ip)
+ debug("found current inventory fallback action");
object = _currentInventoryObject;
}
Commit: 1c97aedf3c27ad8c1b7cb70d492c56e3b3139ec9
https://github.com/scummvm/scummvm/commit/1c97aedf3c27ad8c1b7cb70d492c56e3b3139ec9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:43+01:00
Commit Message:
AGDS: massage lines a bit
Changed paths:
engines/agds/object.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 73629aaab13..e8f108a93b5 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -126,8 +126,8 @@ void Object::setPicture(Graphics::TransparentSurface *picture) {
_picture->free();
delete _picture;
}
- freeRotated();
_picture = picture;
+ freeRotated();
if (!picture) {
_offset = Common::Point();
Commit: e7468ac6553af828144a57b7eb71530a9785eab2
https://github.com/scummvm/scummvm/commit/e7468ac6553af828144a57b7eb71530a9785eab2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:43+01:00
Commit Message:
AGDS: free rotate picture cache in case of loading static mouse cursor
Changed paths:
engines/agds/object.h
diff --git a/engines/agds/object.h b/engines/agds/object.h
index feed151edda..4860e6dcdf6 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -132,6 +132,7 @@ public:
void setMouseCursor(Animation *mouseCursor) {
_mouseCursor = mouseCursor;
+ freeRotated();
}
Animation *getMouseCursor() const {
return _mouseCursor;
Commit: c670440fa0e3078e3bff05ab0f27ab3a1439faff
https://github.com/scummvm/scummvm/commit/c670440fa0e3078e3bff05ab0f27ab3a1439faff
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:43+01:00
Commit Message:
AGDS: center current inventory object
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ab7adbf121d..357b64edbd6 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -644,8 +644,10 @@ Common::Error AGDSEngine::run() {
if (userEnabled()) {
if (_currentInventoryObject) {
auto picture = _currentInventoryObject->getPicture();
- Common::Point dst = _mouse;
Common::Rect srcRect = picture->getRect();
+ Common::Point dst = _mouse;
+ dst.x -= srcRect.width() / 2;
+ dst.y -= srcRect.height() / 2;
uint32 color = (_currentInventoryObject->alpha() << 24) | 0xffffff; //fixme: _picture->format.ARGBToColor(_alpha, 255, 255, 255); is not working
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer->getRect())) {
picture->blit(*backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
Commit: 3e8c72a784561069db9471e9bf091120c110a17c
https://github.com/scummvm/scummvm/commit/3e8c72a784561069db9471e9bf091120c110a17c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:43+01:00
Commit Message:
AGDS: do not save patch if loadScreen called from loadGameStream
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 357b64edbd6..3a5e1e30646 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -281,11 +281,11 @@ PatchPtr AGDSEngine::createPatch(const Common::String &screenName) {
return patch;
}
-void AGDSEngine::loadScreen(const Common::String &name) {
+void AGDSEngine::loadScreen(const Common::String &name, bool savePatch) {
_loadingScreen = true;
_nextScreenName.clear();
debug("loadScreen %s [return to previous: %d]", name.c_str(), _navigatedToPreviousScreen);
- if (_currentScreen && !_currentScreenName.empty())
+ if (savePatch && _currentScreen && !_currentScreenName.empty())
{
PatchPtr &patch = _patches[_currentScreenName];
if (!patch)
@@ -1116,7 +1116,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
runObject(initVar->getString());
loadPatches(file, db);
- loadScreen(screenName);
+ loadScreen(screenName, false);
{
// Inventory
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 2dea673b8d8..38f53f41f77 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -123,7 +123,7 @@ public:
void reactivate(const Common::String &name, bool runNow = false);
void resetCurrentScreen();
- void loadScreen(const Common::String & name);
+ void loadScreen(const Common::String & name, bool savePatch = true);
RegionPtr loadRegion(const Common::String &name);
Common::String loadText(const Common::String &name);
Commit: 7106b380a6e582355b74ac52e593c4af01799f15
https://github.com/scummvm/scummvm/commit/7106b380a6e582355b74ac52e593c4af01799f15
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:43+01:00
Commit Message:
AGDS: rename inScene to alive
Changed paths:
engines/agds/agds.cpp
engines/agds/console.cpp
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3a5e1e30646..5c2fffa59b9 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -221,9 +221,9 @@ void AGDSEngine::runObject(const ObjectPtr &object) {
debug("object %s is not present in the patch", object->getName().c_str());
} else if (_currentScreen->add(object)) {
runProcess(object);
- } else if (!object->inScene()) {
+ } else if (!object->alive()) {
debug("marking object %s as in-scene...", object->getName().c_str());
- object->inScene(true);
+ object->alive(true);
object->allowCalls(false);
runProcess(object);
} else
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index f619844f442..b15fef1be17 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -83,7 +83,7 @@ bool Console::info(int argc, const char **argv) {
debugPrintf("screen %s:\n", screen->getName().c_str());
for(auto & object : screen->children()) {
auto pos = object->getPosition();
- debugPrintf("object %s [inscene: %d] at %d,%d\n", object->getName().c_str(), object->inScene(), pos.x, pos.y);
+ debugPrintf("object %s [alive: %d] at %d,%d\n", object->getName().c_str(), object->alive(), pos.x, pos.y);
}
for(auto & animation : screen->animations()) {
auto pos = animation->position();
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index e8f108a93b5..63d1d035f60 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -40,7 +40,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_pos(), _z(10),
_clickHandler(0), _examineHandler(0), _userUseHandler(0),
_throwHandler(0), _useOnHandler(0),
- _alpha(255), _inScene(false),
+ _alpha(255), _alive(false),
_persistent(true), _allowCalls(true) {
uint16 id = stream->readUint16LE();
debug("id: 0x%02x %u", id, id);
@@ -174,10 +174,10 @@ void Object::rotate(int rot) {
}
-void Object::inScene(bool value)
+void Object::alive(bool value)
{
- _inScene = value;
- if (!_inScene)
+ _alive = value;
+ if (!_alive)
_region.reset();
}
@@ -213,7 +213,7 @@ Common::Rect Object::getRect() const {
}
bool Object::pointIn(Common::Point pos) {
- if (!_inScene)
+ if (!_alive)
return false;
auto picture = getPicture();
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 4860e6dcdf6..2cf29f2f4a4 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -81,7 +81,7 @@ private:
uint _useOnHandler;
int _alpha;
int _scale;
- bool _inScene;
+ bool _alive;
bool _persistent;
bool _allowCalls;
@@ -274,10 +274,10 @@ public:
return _useOnHandler;
}
- bool inScene() const
- { return _inScene; }
+ bool alive() const
+ { return _alive; }
- void inScene(bool value);
+ void alive(bool value);
bool pointIn(Common::Point pos);
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index bde46a5b813..04a444adb3c 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -525,7 +525,7 @@ void Process::checkScreenPatch() {
push(-1);
} else {
ObjectPtr object = screen->find(objectName);
- int value = object && object->inScene();
+ int value = object && object->alive();
debug("checkScreenPatch: current screen object present: %d", value);
push(value);
}
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index d197e4517d4..bb9b25451fe 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -69,7 +69,7 @@ bool Screen::add(ObjectPtr object) {
}
for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ) {
if (*i == object) {
- if ((*i)->inScene()) {
+ if ((*i)->alive()) {
debug("double adding object %s", (*i)->getName().c_str());
return false;
} else {
@@ -78,7 +78,7 @@ bool Screen::add(ObjectPtr object) {
} else
++i;
}
- object->inScene(true);
+ object->alive(true);
_children.insert(object);
return true;
}
@@ -106,8 +106,8 @@ ObjectPtr Screen::find(const Common::String &name) {
bool Screen::remove(const ObjectPtr &object) {
for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
- if (*i == object && object->inScene()) {
- object->inScene(false);
+ if (*i == object && object->alive()) {
+ object->alive(false);
return true;
}
}
@@ -117,8 +117,8 @@ bool Screen::remove(const ObjectPtr &object) {
bool Screen::remove(const Common::String &name) {
for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
const ObjectPtr & object = *i;
- if (object->getName() == name && object->inScene()) {
- object->inScene(false);
+ if (object->getName() == name && object->alive()) {
+ object->alive(false);
return true;
}
}
@@ -181,7 +181,7 @@ void Screen::paint(Graphics::Surface &backbuffer) {
switch (render_type) {
case 0:
//debug("object z: %d", (*child)->z());
- if ((*child) != currentInventoryObject && (*child)->inScene())
+ if ((*child) != currentInventoryObject && (*child)->alive())
(*child)->paint(*_engine, backbuffer);
++child;
break;
@@ -205,7 +205,7 @@ Common::Array<ObjectPtr> Screen::find(Common::Point pos) const {
Common::Array<ObjectPtr> objects;
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
- if (object->pointIn(pos) && object->inScene()) {
+ if (object->pointIn(pos) && object->alive()) {
objects.push_back(object);
}
}
@@ -216,7 +216,7 @@ Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
KeyHandler keyHandler;
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
- if (!object->inScene())
+ if (!object->alive())
continue;
uint ip = object->getKeyHandler(keyName);
@@ -239,7 +239,7 @@ void Screen::load(const PatchPtr &patch) {
remove(object.name);
else {
auto instance = find(object.name); //find by name finds removed objects too
- if (!instance || !instance->inScene()) {
+ if (!instance || !instance->alive()) {
instance = _engine->loadObject(object.name);
instance->allowCalls(false);
_engine->runObject(instance);
@@ -253,9 +253,9 @@ void Screen::save(const PatchPtr &patch) {
patch->objects.clear();
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
- if (!object->persistent() || !object->inScene())
+ if (!object->persistent() || !object->alive())
continue;
- debug("saving patch object %s %d", object->getName().c_str(), object->inScene());
+ debug("saving patch object %s %d", object->getName().c_str(), object->alive());
patch->objects.push_back(Patch::Object(object->getName(), 1));
}
}
Commit: 89fc87bb47959833dc497721e448fb9152417da2
https://github.com/scummvm/scummvm/commit/89fc87bb47959833dc497721e448fb9152417da2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:43+01:00
Commit Message:
AGDS: use original engine removal logic (current -> alive = false)
Changed paths:
engines/agds/agds.cpp
engines/agds/object.cpp
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 5c2fffa59b9..24f1d7c8aab 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -284,9 +284,8 @@ PatchPtr AGDSEngine::createPatch(const Common::String &screenName) {
void AGDSEngine::loadScreen(const Common::String &name, bool savePatch) {
_loadingScreen = true;
_nextScreenName.clear();
- debug("loadScreen %s [return to previous: %d]", name.c_str(), _navigatedToPreviousScreen);
- if (savePatch && _currentScreen && !_currentScreenName.empty())
- {
+ debug("loadScreen %s [return to previous: %d, save patch: %d]", name.c_str(), _navigatedToPreviousScreen, savePatch);
+ if (savePatch && _currentScreen && !_currentScreenName.empty()) {
PatchPtr &patch = _patches[_currentScreenName];
if (!patch)
patch = PatchPtr(new Patch());
@@ -302,7 +301,10 @@ void AGDSEngine::loadScreen(const Common::String &name, bool savePatch) {
}
patch->defaultMouseCursor = _defaultMouseCursorName;
}
+ returnCurrentInventoryObject();
+ _inventory.enable(false);
_mouseMap.hideAll(this);
+
resetCurrentScreen();
for(uint i = 0; i < _processes.size(); ++i) {
_processes[i].reset();
@@ -1175,6 +1177,9 @@ void AGDSEngine::resetCurrentInventoryObject() {
void AGDSEngine::returnCurrentInventoryObject() {
auto object = _currentInventoryObject;
+ if (!object)
+ return;
+
_currentInventoryObject.reset();
_inventory.add(object);
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 63d1d035f60..c3f0a82c746 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -40,7 +40,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_pos(), _z(10),
_clickHandler(0), _examineHandler(0), _userUseHandler(0),
_throwHandler(0), _useOnHandler(0),
- _alpha(255), _alive(false),
+ _alpha(255), _alive(true),
_persistent(true), _allowCalls(true) {
uint16 id = stream->readUint16LE();
debug("id: 0x%02x %u", id, id);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 04a444adb3c..3045319b254 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -269,11 +269,24 @@ void Process::cloneObject() {
void Process::removeScreenObject() {
Common::String name = popString();
debug("removeScreenObject: %s", name.c_str());
- Screen *screen = _engine->getCurrentScreen();
- if (screen) {
- if (!screen->remove(name))
- warning("removeScreenObject: object %s not found", name.c_str());
+ auto screen = _engine->getCurrentScreen();
+ if (!screen) {
+ warning("no current screen");
+ return;
}
+
+ auto object = screen->find(name);
+ if (object) {
+ if (object->alive()) {
+ if (name == _object->getName()) {
+ debug("removeScreenObject: %s: removing object from its own body (sic)", name.c_str());
+ object->alive(false);
+ } else if (!screen || !screen->remove(name))
+ warning("removeScreenObject: object %s not found", name.c_str());
+ } else
+ warning("removeScreenObject: object %s already removed", name.c_str());
+ } else
+ warning("cannot find object %s", name.c_str());
}
void Process::loadFont() {
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index bb9b25451fe..64172d03b4d 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -106,8 +106,8 @@ ObjectPtr Screen::find(const Common::String &name) {
bool Screen::remove(const ObjectPtr &object) {
for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
- if (*i == object && object->alive()) {
- object->alive(false);
+ if (*i == object) {
+ _children.erase(i);
return true;
}
}
@@ -117,8 +117,8 @@ bool Screen::remove(const ObjectPtr &object) {
bool Screen::remove(const Common::String &name) {
for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
const ObjectPtr & object = *i;
- if (object->getName() == name && object->alive()) {
- object->alive(false);
+ if (object->getName() == name) {
+ _children.erase(i);
return true;
}
}
Commit: 8c2a79b669984655629e486e258171b5efef659a
https://github.com/scummvm/scummvm/commit/8c2a79b669984655629e486e258171b5efef659a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:43+01:00
Commit Message:
AGDS: share logic for loading patch object
Changed paths:
engines/agds/agds.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 24f1d7c8aab..da79c487c4e 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -253,9 +253,15 @@ ObjectPtr AGDSEngine::getCurrentScreenObject(const Common::String &name) {
ObjectPtr AGDSEngine::runObject(const Common::String &name, const Common::String &prototype) {
debug("runObject %s %s", name.c_str(), prototype.c_str());
ObjectPtr object = getCurrentScreenObject(name);
- if (!object)
+ if (!object) {
object = loadObject(name, prototype);
- runObject(object);
+ runObject(object);
+ } else if (!object->alive()) {
+ debug("recovering object...");
+ object->alive(true);
+ object->allowCalls(false);
+ runObject(object);
+ }
return object;
}
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 64172d03b4d..c82f1b0a1fd 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -237,14 +237,8 @@ void Screen::load(const PatchPtr &patch) {
debug("patch object %s %d", object.name.c_str(), object.flag);
if (object.flag <= 0)
remove(object.name);
- else {
- auto instance = find(object.name); //find by name finds removed objects too
- if (!instance || !instance->alive()) {
- instance = _engine->loadObject(object.name);
- instance->allowCalls(false);
- _engine->runObject(instance);
- }
- }
+ else
+ _engine->runObject(object.name);
}
_applyingPatch = false;
}
Commit: dbbf27c5ab3f6a1de1274129bfc64e43fcaf8015
https://github.com/scummvm/scummvm/commit/dbbf27c5ab3f6a1de1274129bfc64e43fcaf8015
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:43+01:00
Commit Message:
AGDS: console.run removes object from screen or it won't start
Changed paths:
engines/agds/console.cpp
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index b15fef1be17..40cce836068 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -62,6 +62,7 @@ bool Console::run(int argc, const char **argv) {
debugPrintf("no object %s\n", argv[1]);
return true;
}
+ _engine->getCurrentScreen()->remove(object);
_engine->runObject(object);
detach();
return false;
Commit: 26d1a8b66cebde530cc1312e73aaa60257546dc3
https://github.com/scummvm/scummvm/commit/26d1a8b66cebde530cc1312e73aaa60257546dc3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:44+01:00
Commit Message:
AGDS: simplify getGlobal
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3045319b254..356a0db1058 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -328,7 +328,7 @@ void Process::setPhaseVar() {
}
void Process::getGlobal(uint8 index) {
- const Common::String &name = _object->getString(index).string;
+ auto name = getString(index);
int value = _engine->getGlobal(name);
debug("get global %u %s -> %d", index, name.c_str(), value);
push(value);
Commit: 306a0a44e98142002c921d0a8a8c4a641ca23a50
https://github.com/scummvm/scummvm/commit/306a0a44e98142002c921d0a8a8c4a641ca23a50
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:44+01:00
Commit Message:
AGDS: pass allowCalls to load/runObject, don't allow calls for object loaded from patch
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index da79c487c4e..93b3430c489 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -199,7 +199,7 @@ Common::String AGDSEngine::loadText(const Common::String &entryName) {
return ResourceManager::loadText(_data.getEntry(entryName));
}
-ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::String &prototype) {
+ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::String &prototype, bool allowCalls) {
debug("loadObject %s %s", name.c_str(), prototype.c_str());
Common::String clone = prototype.empty() ? name : prototype;
Common::SeekableReadStream *stream = _data.getEntry(clone);
@@ -207,6 +207,7 @@ ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::Strin
error("no database entry for %s\n", clone.c_str());
ObjectPtr object(new Object(name, stream));
+ object->allowCalls(allowCalls);
if (!prototype.empty()) {
object->persistent(false);
}
@@ -250,11 +251,11 @@ ObjectPtr AGDSEngine::getCurrentScreenObject(const Common::String &name) {
}
-ObjectPtr AGDSEngine::runObject(const Common::String &name, const Common::String &prototype) {
+ObjectPtr AGDSEngine::runObject(const Common::String &name, const Common::String &prototype, bool allowCalls) {
debug("runObject %s %s", name.c_str(), prototype.c_str());
ObjectPtr object = getCurrentScreenObject(name);
if (!object) {
- object = loadObject(name, prototype);
+ object = loadObject(name, prototype, allowCalls);
runObject(object);
} else if (!object->alive()) {
debug("recovering object...");
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 38f53f41f77..5af3ff90a61 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -115,8 +115,8 @@ public:
bool canLoadGameStateCurrently() { return true; }
bool canSaveGameStateCurrently() { return _userEnabled; }
- ObjectPtr loadObject(const Common::String & name, const Common::String & prototype = Common::String());
- ObjectPtr runObject(const Common::String & name, const Common::String &prototype = Common::String());
+ ObjectPtr loadObject(const Common::String & name, const Common::String & prototype = Common::String(), bool allowCalls = true);
+ ObjectPtr runObject(const Common::String & name, const Common::String &prototype = Common::String(), bool allowCalls = true);
void runObject(const ObjectPtr &object);
void runProcess(const ObjectPtr &object, uint ip = 0);
void stopProcess(const Common::String & name);
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index c82f1b0a1fd..281cda7926b 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -238,7 +238,7 @@ void Screen::load(const PatchPtr &patch) {
if (object.flag <= 0)
remove(object.name);
else
- _engine->runObject(object.name);
+ _engine->runObject(object.name, Common::String(), false);
}
_applyingPatch = false;
}
Commit: 2487e426379908aaddb408d4e0cb6ca7b81e9589
https://github.com/scummvm/scummvm/commit/2487e426379908aaddb408d4e0cb6ca7b81e9589
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:44+01:00
Commit Message:
AGDS: remove doPatch logic for now
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 93b3430c489..61b2968caf5 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -320,7 +320,7 @@ void AGDSEngine::loadScreen(const Common::String &name, bool savePatch) {
auto patch = getPatch(name);
auto screenObject = loadObject(name);
- bool doPatch = patch && _navigatedToPreviousScreen;
+ bool doPatch = patch;
_currentScreenName = name;
_currentScreen = new Screen(this, screenObject);
Commit: 8cedbffc5c3d0a7bedfccd2a5aaf4c08ae3b1ac2
https://github.com/scummvm/scummvm/commit/8cedbffc5c3d0a7bedfccd2a5aaf4c08ae3b1ac2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:44+01:00
Commit Message:
AGDS: solved long-time mystery, "call" is actually initialisation handler
Remove no-object-in-patch-no-object-in-screen stub
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 61b2968caf5..52479ccc740 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -199,7 +199,7 @@ Common::String AGDSEngine::loadText(const Common::String &entryName) {
return ResourceManager::loadText(_data.getEntry(entryName));
}
-ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::String &prototype, bool allowCalls) {
+ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::String &prototype, bool allowInitialise) {
debug("loadObject %s %s", name.c_str(), prototype.c_str());
Common::String clone = prototype.empty() ? name : prototype;
Common::SeekableReadStream *stream = _data.getEntry(clone);
@@ -207,7 +207,7 @@ ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::Strin
error("no database entry for %s\n", clone.c_str());
ObjectPtr object(new Object(name, stream));
- object->allowCalls(allowCalls);
+ object->allowInitialise(allowInitialise);
if (!prototype.empty()) {
object->persistent(false);
}
@@ -217,15 +217,12 @@ ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::Strin
void AGDSEngine::runObject(const ObjectPtr &object) {
if (_currentScreen) {
- auto patch = getPatch(_currentScreenName);
- if (_loadingScreen && patch && patch->getFlag(object->getName()) <= 0) {
- debug("object %s is not present in the patch", object->getName().c_str());
- } else if (_currentScreen->add(object)) {
+ if (_currentScreen->add(object)) {
runProcess(object);
} else if (!object->alive()) {
debug("marking object %s as in-scene...", object->getName().c_str());
object->alive(true);
- object->allowCalls(false);
+ object->allowInitialise(false);
runProcess(object);
} else
debug("object %s is in scene, skip run", object->getName().c_str());
@@ -251,16 +248,16 @@ ObjectPtr AGDSEngine::getCurrentScreenObject(const Common::String &name) {
}
-ObjectPtr AGDSEngine::runObject(const Common::String &name, const Common::String &prototype, bool allowCalls) {
+ObjectPtr AGDSEngine::runObject(const Common::String &name, const Common::String &prototype, bool allowInitialise) {
debug("runObject %s %s", name.c_str(), prototype.c_str());
ObjectPtr object = getCurrentScreenObject(name);
if (!object) {
- object = loadObject(name, prototype, allowCalls);
+ object = loadObject(name, prototype, allowInitialise);
runObject(object);
} else if (!object->alive()) {
debug("recovering object...");
object->alive(true);
- object->allowCalls(false);
+ object->allowInitialise(false);
runObject(object);
}
return object;
@@ -325,7 +322,7 @@ void AGDSEngine::loadScreen(const Common::String &name, bool savePatch) {
_currentScreenName = name;
_currentScreen = new Screen(this, screenObject);
if (doPatch)
- screenObject->allowCalls(false);
+ screenObject->allowInitialise(false);
runProcess(screenObject);
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 5af3ff90a61..ed872282767 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -115,8 +115,8 @@ public:
bool canLoadGameStateCurrently() { return true; }
bool canSaveGameStateCurrently() { return _userEnabled; }
- ObjectPtr loadObject(const Common::String & name, const Common::String & prototype = Common::String(), bool allowCalls = true);
- ObjectPtr runObject(const Common::String & name, const Common::String &prototype = Common::String(), bool allowCalls = true);
+ ObjectPtr loadObject(const Common::String & name, const Common::String & prototype = Common::String(), bool allowInitialise = true);
+ ObjectPtr runObject(const Common::String & name, const Common::String &prototype = Common::String(), bool allowInitialise = true);
void runObject(const ObjectPtr &object);
void runProcess(const ObjectPtr &object, uint ip = 0);
void stopProcess(const Common::String & name);
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index c3f0a82c746..2c81abfae67 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -41,7 +41,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_clickHandler(0), _examineHandler(0), _userUseHandler(0),
_throwHandler(0), _useOnHandler(0),
_alpha(255), _alive(true),
- _persistent(true), _allowCalls(true) {
+ _persistent(true), _allowInitialise(true) {
uint16 id = stream->readUint16LE();
debug("id: 0x%02x %u", id, id);
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 2cf29f2f4a4..dadb68a17c6 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -83,7 +83,7 @@ private:
int _scale;
bool _alive;
bool _persistent;
- bool _allowCalls;
+ bool _allowInitialise;
private:
void freeRotated();
@@ -92,11 +92,11 @@ public:
Object(const Common::String &name, Common::SeekableReadStream * stream);
~Object();
- bool allowCalls() const {
- return _allowCalls;
+ bool allowInitialise() const {
+ return _allowInitialise;
}
- void allowCalls(bool allow) {
- _allowCalls = allow;
+ void allowInitialise(bool allow) {
+ _allowInitialise = allow;
}
void persistent(bool persistent) {
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 3ffd175885c..47b6a5b0f67 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -78,7 +78,7 @@ enum Opcode {
kAndGlobalByTop = 56,
kOrGlobalByTop = 57,
kXorGlobalByTop = 58,
- kCallImm16 = 59,
+ kObjectInitialise = 59,
kObjectRegisterLookHandler = 60,
kObjectRegisterUseHandler = 61,
kObjectRegisterHandlerC1 = 62,
@@ -313,7 +313,7 @@ enum Opcode {
OP(kNot, bitNot) \
OP(kBoolNot, boolNot) \
OP(kNegate, negate) \
- OP_U(kCallImm16, call) \
+ OP_U(kObjectInitialise, initialise) \
OP_U(kObjectRegisterLookHandler, onLook) \
OP_U(kObjectRegisterUseHandler, onUse) \
OP_U(kObjectRegisterHandlerC1, onObjectC1) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 356a0db1058..b6bc99bca67 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1306,12 +1306,13 @@ void Process::loadTextFromObject() {
_object->title(text);
}
-void Process::call(uint16 addr) {
- debug("call %04x", _ip + addr);
- if (_object->allowCalls()) {
- _engine->runProcess(_object, _ip + addr);
+void Process::initialise(uint16 addr) {
+ debug("initialise %04x", _ip);
+ if (_object->allowInitialise()) {
+ _engine->runProcess(_object, _ip);
} else
- debug("call skipped (recovered object)");
+ debug("initialise skipped (recovered object)");
+ _ip += addr;
}
void Process::onKey(uint16 size) {
Commit: e3848970f82830a0f36b7f271227f7e23313f5fa
https://github.com/scummvm/scummvm/commit/e3848970f82830a0f36b7f271227f7e23313f5fa
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:44+01:00
Commit Message:
AGDS: fixed object lifetime cycle
Changed paths:
engines/agds/agds.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 52479ccc740..7eb74f70d34 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -219,11 +219,6 @@ void AGDSEngine::runObject(const ObjectPtr &object) {
if (_currentScreen) {
if (_currentScreen->add(object)) {
runProcess(object);
- } else if (!object->alive()) {
- debug("marking object %s as in-scene...", object->getName().c_str());
- object->alive(true);
- object->allowInitialise(false);
- runProcess(object);
} else
debug("object %s is in scene, skip run", object->getName().c_str());
} else
@@ -253,13 +248,8 @@ ObjectPtr AGDSEngine::runObject(const Common::String &name, const Common::String
ObjectPtr object = getCurrentScreenObject(name);
if (!object) {
object = loadObject(name, prototype, allowInitialise);
- runObject(object);
- } else if (!object->alive()) {
- debug("recovering object...");
- object->alive(true);
- object->allowInitialise(false);
- runObject(object);
}
+ runObject(object);
return object;
}
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 281cda7926b..faebdd2ed46 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -69,16 +69,18 @@ bool Screen::add(ObjectPtr object) {
}
for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ) {
if (*i == object) {
- if ((*i)->alive()) {
- debug("double adding object %s", (*i)->getName().c_str());
+ if (object->alive()) {
+ debug("double adding object %s", object->getName().c_str());
return false;
} else {
- i = _children.erase(i);
+ debug("recovering object %s", object->getName().c_str());
+ object->alive(true);
+ object->allowInitialise(false);
+ return true;
}
} else
++i;
}
- object->alive(true);
_children.insert(object);
return true;
}
Commit: 85e3447006cfced045061fa79c936da494731391
https://github.com/scummvm/scummvm/commit/85e3447006cfced045061fa79c936da494731391
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:44+01:00
Commit Message:
AGDS: add Object::generateRegion(rect)
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 2c81abfae67..8e85edd8e21 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -190,15 +190,18 @@ void Object::moveTo(Common::Point pos) {
_pos = pos;
}
+void Object::generateRegion(Common::Rect rect) {
+ _region = RegionPtr(new Region(rect));
+ debug("%s: generated region: %s", _name.c_str(), _region->toString().c_str());
+}
+
void Object::generateRegion() {
if (!getPicture()) {
warning("generateRegion called on null picture");
return;
}
- auto rect = getRect();
- _region = RegionPtr(new Region(rect));
- debug("%s: generated region: %s", _name.c_str(), _region->toString().c_str());
+ generateRegion(getRect());
}
Common::Rect Object::getRect() const {
diff --git a/engines/agds/object.h b/engines/agds/object.h
index dadb68a17c6..0187c93d61d 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -147,6 +147,7 @@ public:
void rotate(int rot);
void generateRegion();
+ void generateRegion(Common::Rect rect);
void regionOffset(Common::Point offset) {
_regionOffset = offset;
Commit: bff7da3c3ea1be82ba4977295463e8331d2eea01
https://github.com/scummvm/scummvm/commit/bff7da3c3ea1be82ba4977295463e8331d2eea01
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:44+01:00
Commit Message:
AGDS: generate transparent surface for empty saves
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b6bc99bca67..daa383f99fc 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -820,16 +820,10 @@ void Process::loadSaveSlotNamePicture() {
Common::String saveSlotName = _engine->getSaveStateName(saveSlot);
Common::SaveFileManager * saveMan = _engine->getSaveFileManager();
Common::InSaveFile * save = saveMan->openForLoading(saveSlotName);
- if (!save) {
- debug("no save in slot %d", saveSlot);
- _object->setPicture(nullptr);
- return;
- }
debug("save state name: %s", saveSlotName.c_str());
int fontId = _engine->getSystemVariable("edit_font")->getInteger();
- debug("font id = %d", fontId);
Font * font = _engine->getFont(fontId);
int h = font->getFontHeight();
static const int w = 400;
@@ -837,7 +831,7 @@ void Process::loadSaveSlotNamePicture() {
Graphics::Surface * label = _engine->createSurface(w, h);
uint32 color = _engine->pixelFormat().RGBToColor(255, 0, 255);
label->fillRect(label->getRect(), color);
- font->drawString(label, saveSlotName, 0, 0, w, color);
+ font->drawString(label, save? saveSlotName: "", 0, 0, w, color);
Graphics::TransparentSurface *transparentLabel = _engine->convertToTransparent(label);
_object->setPicture(transparentLabel);
_object->generateRegion();
Commit: fd2cb6545b6b4970554b6eb459183d1cfd0f7d4b
https://github.com/scummvm/scummvm/commit/fd2cb6545b6b4970554b6eb459183d1cfd0f7d4b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:44+01:00
Commit Message:
AGDS: remove stub from saveGame
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index daa383f99fc..95bfea79429 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -802,7 +802,7 @@ void Process::loadGame() {
void Process::saveGame() {
int saveSlot = pop();
- debug("saveGame stub %d", saveSlot);
+ debug("saveGame %d", saveSlot);
suspend(kExitCodeSaveGame, saveSlot);
}
Commit: 68f99e2c441d9b9f6fd947b9bf626657bc80eb16
https://github.com/scummvm/scummvm/commit/68f99e2c441d9b9f6fd947b9bf626657bc80eb16
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:44+01:00
Commit Message:
AGDS: return false for all metaengine/engine features
Changed paths:
engines/agds/agds.cpp
engines/agds/metaengine.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 7eb74f70d34..7b2dc19ac3a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -995,7 +995,7 @@ bool AGDSEngine::hasFeature(EngineFeature f) const {
case kSupportsChangingOptionsDuringRuntime:
return true;
default:
- return Engine::hasFeature(f);
+ return false;
}
}
diff --git a/engines/agds/metaengine.cpp b/engines/agds/metaengine.cpp
index ec4d2c04a50..5a100ee9b53 100644
--- a/engines/agds/metaengine.cpp
+++ b/engines/agds/metaengine.cpp
@@ -29,14 +29,13 @@ namespace AGDS {
class AGDSMetaEngine : public AdvancedMetaEngine {
public:
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
+
bool hasFeature(MetaEngineFeature f) const override {
switch (f) {
case kSimpleSavesNames:
return true;
- case kSupportsLoadingDuringStartup:
- return false;
default:
- return AdvancedMetaEngine::hasFeature(f);
+ return false;
}
}
Commit: f44df99cefab87d8e8bfedd2cdf01c7178a27cda
https://github.com/scummvm/scummvm/commit/f44df99cefab87d8e8bfedd2cdf01c7178a27cda
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:45+01:00
Commit Message:
AGDS: output warning if save has failed
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 6a7e9789dde..d08b9ba7f68 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -224,7 +224,9 @@ void Process::run() {
}
break;
case kExitCodeSaveGame:
- _engine->returnToPreviousScreen();
+ if (_engine->saveGameState(getExitIntArg1(), "").getCode() != Common::kNoError) {
+ warning("failed to save game");
+ }
activate();
break;
default:
Commit: 4492f784d4df45749af7b22a0c91f90cc29eb3f6
https://github.com/scummvm/scummvm/commit/4492f784d4df45749af7b22a0c91f90cc29eb3f6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:45+01:00
Commit Message:
AGDS: overload load/saveGameState
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 7b2dc19ac3a..5bf4e8d43fd 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -39,6 +39,7 @@
#include "common/events.h"
#include "common/file.h"
#include "common/ini-file.h"
+#include "common/savefile.h"
#include "common/system.h"
#include "engines/util.h"
#include "graphics/transparent_surface.h"
@@ -1017,14 +1018,22 @@ void AGDSEngine::loadPatches(Common::SeekableReadStream *file, Database & db) {
}
-Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
+Common::Error AGDSEngine::loadGameState(int slot) {
+ saveAutosaveIfEnabled();
+
+ auto fileName = getSaveStateName(slot);
+ Common::InSaveFile *saveFile = _saveFileMan->openForLoading(fileName);
+
+ if (!saveFile)
+ return Common::kReadingFailed;
+
Database db;
- if (!db.open("savefile", file))
+ if (!db.open(fileName, saveFile))
return Common::kReadingFailed;
{
// Compiled version (should be 2)
- Common::ScopedPtr<Common::SeekableReadStream> agds_ver(db.getEntry(file, "__agds_ver"));
+ Common::ScopedPtr<Common::SeekableReadStream> agds_ver(db.getEntry(saveFile, "__agds_ver"));
int version = agds_ver->readUint32LE();
debug("version: %d", version);
if (version != 2) {
@@ -1040,7 +1049,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
{
// Current character
- Common::ScopedPtr<Common::SeekableReadStream> agds_c(db.getEntry(file, "__agds_c"));
+ Common::ScopedPtr<Common::SeekableReadStream> agds_c(db.getEntry(saveFile, "__agds_c"));
Common::String object = readString(agds_c.get());
Common::String name = readString(agds_c.get());
Common::String id = readString(agds_c.get());
@@ -1067,14 +1076,14 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
Common::String screenName;
{
// Screenshot and screen name
- Common::ScopedPtr<Common::SeekableReadStream> agds_s(db.getEntry(file, "__agds_s"));
+ Common::ScopedPtr<Common::SeekableReadStream> agds_s(db.getEntry(saveFile, "__agds_s"));
screenName = readString(agds_s.get());
}
{
// Global vars
_globals.clear();
- Common::ScopedPtr<Common::SeekableReadStream> agds_v(db.getEntry(file, "__agds_v"));
+ Common::ScopedPtr<Common::SeekableReadStream> agds_v(db.getEntry(saveFile, "__agds_v"));
uint32 n = agds_v->readUint32LE();
debug("reading %u vars...", n);
while(n--) {
@@ -1088,7 +1097,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
{
_soundManager.stopAll();
// Audio samples
- Common::ScopedPtr<Common::SeekableReadStream> agds_a(db.getEntry(file, "__agds_a"));
+ Common::ScopedPtr<Common::SeekableReadStream> agds_a(db.getEntry(saveFile, "__agds_a"));
Common::String sample = loadText(readString(agds_a.get()));
Common::String phaseVar = readString(agds_a.get());
uint unk0 = agds_a->readUint32LE();
@@ -1100,7 +1109,7 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
{
// System vars
- Common::ScopedPtr<Common::SeekableReadStream> agds_d(db.getEntry(file, "__agds_d"));
+ Common::ScopedPtr<Common::SeekableReadStream> agds_d(db.getEntry(saveFile, "__agds_d"));
for(uint i = 0, n = _systemVarList.size(); i < n; ++i) {
Common::String & name = _systemVarList[i];
_systemVars[name]->read(agds_d.get());
@@ -1111,13 +1120,13 @@ Common::Error AGDSEngine::loadGameStream(Common::SeekableReadStream *file) {
SystemVariable *initVar = getSystemVariable("init_resources");
runObject(initVar->getString());
- loadPatches(file, db);
+ loadPatches(saveFile, db);
loadScreen(screenName, false);
{
// Inventory
_inventory.clear();
- Common::ScopedPtr<Common::SeekableReadStream> agds_i(db.getEntry(file, "__agds_i"));
+ Common::ScopedPtr<Common::SeekableReadStream> agds_i(db.getEntry(saveFile, "__agds_i"));
int n = 34;
while(n--) {
Common::String name = readString(agds_i.get());
@@ -1159,7 +1168,15 @@ void AGDSEngine::stopProcess(const Common::String & name) {
}
-Common::Error AGDSEngine::saveGameStream(Common::WriteStream *file, bool isAutosave) { return Common::Error(Common::kNoError); }
+Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
+ auto fileName = getSaveStateName(slot);
+ Common::OutSaveFile *saveFile = getSaveFileManager()->openForSaving(fileName);
+
+ if (!saveFile)
+ return Common::kWritingFailed;
+
+ return Common::Error(Common::kNoError);
+}
void AGDSEngine::currentInventoryObject(const ObjectPtr & object) {
_currentInventoryObject = object;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index ed872282767..4d99f7ef4a7 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -110,8 +110,8 @@ private:
public:
bool hasFeature(EngineFeature f) const;
- Common::Error loadGameStream(Common::SeekableReadStream *file);
- Common::Error saveGameStream(Common::WriteStream *file, bool isAutosave);
+ Common::Error loadGameState(int slot) override;
+ Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
bool canLoadGameStateCurrently() { return true; }
bool canSaveGameStateCurrently() { return _userEnabled; }
Commit: 430d682201cc5ce1d07bdc33053ce11d81b63fd9
https://github.com/scummvm/scummvm/commit/430d682201cc5ce1d07bdc33053ce11d81b63fd9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:45+01:00
Commit Message:
AGDS: add getDataOffset method
Changed paths:
engines/agds/database.cpp
engines/agds/database.h
diff --git a/engines/agds/database.cpp b/engines/agds/database.cpp
index d15b750aa2e..79c94364c56 100644
--- a/engines/agds/database.cpp
+++ b/engines/agds/database.cpp
@@ -35,9 +35,17 @@ bool Database::open(const Common::String &filename) {
return open(filename, &file);
}
-bool Database::open(const Common::String &filename, Common::SeekableReadStream *stream) {
+namespace {
static const uint32 kMagic = 666;
+ static const uint32 kHeaderFieldSize = 0x09;
+ static const uint32 kHeaderSize = 0x14;
+}
+
+uint32 Database::getDataOffset(uint32 maxNameSize, uint32 totalEntries) {
+ return kHeaderSize + (maxNameSize + kHeaderFieldSize) * totalEntries;
+}
+bool Database::open(const Common::String &filename, Common::SeekableReadStream *stream) {
_filename = filename;
uint32 magic = stream->readUint32LE();
if (magic != kMagic) {
@@ -53,10 +61,7 @@ bool Database::open(const Common::String &filename, Common::SeekableReadStream *
return false;
}
- static const uint32 kHeaderFieldSize = 0x09;
- static const uint32 kHeaderSize = 0x14;
-
- uint32 dataOffset = kHeaderSize + (_maxNameSize + kHeaderFieldSize) * _totalEntries;
+ uint32 dataOffset = getDataOffset(_maxNameSize, _totalEntries);
Common::Array<char> nameBuffer(_maxNameSize + 1);
for (uint32 i = 0; i < _usedEntries; ++i) {
uint32 offset = stream->readUint32LE();
diff --git a/engines/agds/database.h b/engines/agds/database.h
index 51f7764f0b8..1c572d7fadb 100644
--- a/engines/agds/database.h
+++ b/engines/agds/database.h
@@ -52,6 +52,9 @@ private:
EntriesType _entries;
+private:
+ static uint32 getDataOffset(uint32 maxNameSize, uint32 totalEntries);
+
public:
bool open(const Common::String &filename);
bool open(const Common::String &filename, Common::SeekableReadStream *stream);
Commit: 19b0c61049dc38fb73d926b484ac7caa48e9cf00
https://github.com/scummvm/scummvm/commit/19b0c61049dc38fb73d926b484ac7caa48e9cf00
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:45+01:00
Commit Message:
AGDS: lowered stream interface requirements to ReadStream/WriteStream
Changed paths:
engines/agds/patch.cpp
engines/agds/patch.h
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index b8b6cad1a5d..648b628e0c0 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -6,7 +6,7 @@
namespace AGDS {
-void Patch::load(Common::SeekableReadStream *stream) {
+void Patch::load(Common::ReadStream *stream) {
byte extended = stream->readByte();
if (extended != 1 && extended != 0) {
Common::String prototype = (char)extended + readString(stream, 31);
@@ -42,7 +42,7 @@ void Patch::load(Common::SeekableReadStream *stream) {
}
}
-void Patch::save(Common::SeekableWriteStream *stream) {
+void Patch::save(Common::WriteStream *stream) {
int extended = 1;
stream->writeByte(extended);
writeString(stream, screenRegionName);
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index aebaf842c95..2a74c27c7b6 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -28,7 +28,7 @@
#include "common/rect.h"
#include "common/str.h"
-namespace Common { class SeekableReadStream; class SeekableWriteStream; }
+namespace Common { class ReadStream; class WriteStream; }
namespace AGDS {
@@ -55,8 +55,8 @@ struct Patch {
Common::String defaultMouseCursor;
Common::Array<Object> objects;
- void load(Common::SeekableReadStream *stream);
- void save(Common::SeekableWriteStream *stream);
+ void load(Common::ReadStream *stream);
+ void save(Common::WriteStream *stream);
int getFlag(const Common::String & name) const;
int incRef(const Common::String & name);
int decRef(const Common::String & name);
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index eb976a280bc..3c6507b8073 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -225,7 +225,7 @@ Common::String ResourceManager::loadText(const Common::String &name) const {
return loadText(stream);
}
-Common::String readString(Common::SeekableReadStream * stream, uint size) {
+Common::String readString(Common::ReadStream *stream, uint size) {
Common::Array<char> text(size);
if (stream->read(text.data(), text.size()) != text.size())
error("readString: short read");
@@ -233,7 +233,7 @@ Common::String readString(Common::SeekableReadStream * stream, uint size) {
return Common::String(text.data(), strlen(text.data()));
}
-void writeString(Common::SeekableWriteStream * stream, const Common::String &string, uint size) {
+void writeString(Common::WriteStream *stream, const Common::String &string, uint size) {
Common::Array<char> text(size);
memcpy(text.data(), string.c_str(), MIN(string.size(), size));
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index f24ebd6c345..4ff8f001cd9 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -74,9 +74,9 @@ private:
virtual bool hasFile(const Common::String &name) const
{ return _members.find(name) != _members.end(); }
- virtual int listMembers(Common::ArchiveMemberList &list) const;
- virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
- virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
+ int listMembers(Common::ArchiveMemberList &list) const override;
+ const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
+ Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
};
public:
@@ -94,8 +94,8 @@ public:
Common::String loadText(const Common::String & name) const;
};
-Common::String readString(Common::SeekableReadStream * stream, uint size = 32);
-void writeString(Common::SeekableWriteStream * stream, const Common::String &string, uint size = 32);
+Common::String readString(Common::ReadStream *stream, uint size = 32);
+void writeString(Common::WriteStream *stream, const Common::String &string, uint size = 32);
} // End of namespace AGDS
Commit: 8a01d5e4b8e8640479dd8a21ad2cf082ec3ee7a7
https://github.com/scummvm/scummvm/commit/8a01d5e4b8e8640479dd8a21ad2cf082ec3ee7a7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:45+01:00
Commit Message:
AGDS: implement Database::write and save stub
Changed paths:
engines/agds/agds.cpp
engines/agds/database.cpp
engines/agds/database.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 5bf4e8d43fd..9a0b9b2d264 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1139,9 +1139,25 @@ Common::Error AGDSEngine::loadGameState(int slot) {
}
}
+ delete saveFile;
return Common::kNoError;
}
+Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
+ auto fileName = getSaveStateName(slot);
+ Common::OutSaveFile *saveFile = getSaveFileManager()->openForSaving(fileName);
+
+ if (!saveFile)
+ return Common::kWritingFailed;
+
+ Common::HashMap<Common::String, Common::Array<uint8>> entries;
+ Database::write(saveFile, entries);
+
+ delete saveFile;
+ return Common::kNoError;
+}
+
+
void AGDSEngine::reactivate(const Common::String &name, bool runNow) {
if (name.empty())
return;
@@ -1167,17 +1183,6 @@ void AGDSEngine::stopProcess(const Common::String & name) {
}
}
-
-Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
- auto fileName = getSaveStateName(slot);
- Common::OutSaveFile *saveFile = getSaveFileManager()->openForSaving(fileName);
-
- if (!saveFile)
- return Common::kWritingFailed;
-
- return Common::Error(Common::kNoError);
-}
-
void AGDSEngine::currentInventoryObject(const ObjectPtr & object) {
_currentInventoryObject = object;
}
diff --git a/engines/agds/database.cpp b/engines/agds/database.cpp
index 79c94364c56..db2d43ab6d4 100644
--- a/engines/agds/database.cpp
+++ b/engines/agds/database.cpp
@@ -39,6 +39,7 @@ namespace {
static const uint32 kMagic = 666;
static const uint32 kHeaderFieldSize = 0x09;
static const uint32 kHeaderSize = 0x14;
+ static const uint32 kDefaultNameSize = 0x1f;
}
uint32 Database::getDataOffset(uint32 maxNameSize, uint32 totalEntries) {
@@ -76,6 +77,29 @@ bool Database::open(const Common::String &filename, Common::SeekableReadStream *
return true;
}
+void Database::write(Common::WriteStream *stream, const Common::HashMap<Common::String, Common::Array<uint8>> & entries) {
+ auto n = entries.size();
+ stream->writeUint32LE(kMagic);
+ stream->writeUint32LE(1);
+ stream->writeUint32LE(n);
+ stream->writeUint32LE(n);
+ stream->writeUint32LE(kDefaultNameSize);
+ auto dataOffset = getDataOffset(kDefaultNameSize, n);
+ auto offset = dataOffset;
+ for(auto entry: entries) {
+ stream->writeUint32LE(offset);
+ Common::Array<char> text(kDefaultNameSize);
+ auto &key = entry._key;
+ memcpy(text.data(), key.c_str(), MIN(key.size(), text.size()));
+ offset += entry._value.size();
+ stream->writeUint32LE(entry._value.size());
+ }
+ for(auto entry: entries) {
+ auto & data = entry._value;
+ stream->write(data.data(), data.size());
+ }
+}
+
Common::Array<Common::String> Database::getEntries() const {
Common::Array<Common::String> names;
for(EntriesType::const_iterator i = _entries.begin(); i != _entries.end(); ++i) {
diff --git a/engines/agds/database.h b/engines/agds/database.h
index 1c572d7fadb..18c35023373 100644
--- a/engines/agds/database.h
+++ b/engines/agds/database.h
@@ -62,6 +62,8 @@ public:
Common::SeekableReadStream * getEntry(const Common::String &name) const;
Common::SeekableReadStream *getEntry(Common::SeekableReadStream *parent, const Common::String &name) const;
+
+ static void write(Common::WriteStream *stream, const Common::HashMap<Common::String, Common::Array<uint8>> & entries);
};
Commit: c0f851fcdc4b07fba376a754f214e644bb98d66a
https://github.com/scummvm/scummvm/commit/c0f851fcdc4b07fba376a754f214e644bb98d66a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:45+01:00
Commit Message:
AGDS: load game state cleanups, volume/type discovered
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 9a0b9b2d264..31fe06f9a60 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1075,7 +1075,7 @@ Common::Error AGDSEngine::loadGameState(int slot) {
Common::String screenName;
{
- // Screenshot and screen name
+ // Palette and screen name
Common::ScopedPtr<Common::SeekableReadStream> agds_s(db.getEntry(saveFile, "__agds_s"));
screenName = readString(agds_s.get());
}
@@ -1100,9 +1100,9 @@ Common::Error AGDSEngine::loadGameState(int slot) {
Common::ScopedPtr<Common::SeekableReadStream> agds_a(db.getEntry(saveFile, "__agds_a"));
Common::String sample = loadText(readString(agds_a.get()));
Common::String phaseVar = readString(agds_a.get());
- uint unk0 = agds_a->readUint32LE();
- uint unk1 = agds_a->readUint32LE();
- debug("saved audio state: sample: '%s', var: '%s' %u %u", sample.c_str(), phaseVar.c_str(), unk0, unk1);
+ uint volume = agds_a->readUint32LE();
+ uint type = agds_a->readUint32LE();
+ debug("saved audio state: sample: '%s', var: '%s' %u %u", sample.c_str(), phaseVar.c_str(), volume, type);
debug("phase var for sample -> %d", getGlobal(phaseVar));
playSound(Common::String(), sample, phaseVar); //fixme: double check
}
Commit: b93cc1aa5596b1c25f218ce9d0a448bcca6a50ee
https://github.com/scummvm/scummvm/commit/b93cc1aa5596b1c25f218ce9d0a448bcca6a50ee
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:45+01:00
Commit Message:
AGDS: add ambient sound flag
Changed paths:
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 47b6a5b0f67..17160371402 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -211,7 +211,7 @@ enum Opcode {
kStub191 = 191,
kStub192 = 192,
kRemoveGapsFromInventory = 193,
- kSamplePaused = 194,
+ kSampleAmbient = 194,
kGetObjectPictureWidth = 195,
kGetObjectPictureHeight = 196,
kSetRotation = 197,
@@ -429,7 +429,7 @@ enum Opcode {
OP(kSetObjectScale, setObjectScale) \
OP(kStub191, disableMouseAreas) \
OP(kRemoveGapsFromInventory, removeGapsFromInventory) \
- OP(kSamplePaused, samplePaused) \
+ OP(kSampleAmbient, sampleAmbient) \
OP(kGetObjectPictureWidth, getObjectPictureWidth) \
OP(kGetObjectPictureHeight, getObjectPictureHeight) \
OP(kLoadPicture, loadPicture) \
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index d08b9ba7f68..c443c19a619 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -34,7 +34,7 @@ Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) : _engine(en
_timer(0),
_animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0),
_phaseVarControlled(false), _animationSpeed(100),
- _samplePeriodic(false), _samplePaused(false),
+ _samplePeriodic(false), _sampleAmbient(false),
_filmSubtitlesResource(-1)
{
updateWithCurrentMousePosition();
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 569a1892535..b42e675bdd7 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -65,7 +65,7 @@ private:
bool _phaseVarControlled;
int _animationSpeed;
bool _samplePeriodic;
- bool _samplePaused;
+ bool _sampleAmbient;
Common::Point _mousePosition;
int _filmSubtitlesResource;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 95bfea79429..6e2ae25b749 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -663,7 +663,7 @@ void Process::resetState() {
_animationDelay = -1;
_animationSpeed = 100;
_samplePeriodic = false;
- _samplePaused = false;
+ _sampleAmbient = false;
_tileWidth = 16;
_tileHeight = 16;
@@ -886,9 +886,9 @@ void Process::disableMouseAreas() {
_engine->_mouseMap.disable(_engine, value > 0);
}
-void Process::samplePaused() {
- debug("samplePaused: stub");
- _samplePaused = true;
+void Process::sampleAmbient() {
+ debug("sampleAmbient: stub");
+ _sampleAmbient = true;
}
void Process::setRotation() {
Commit: 1e6202f51fa80e27d1ddb7c8bb203cb4b91ce738
https://github.com/scummvm/scummvm/commit/1e6202f51fa80e27d1ddb7c8bb203cb4b91ce738
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:45+01:00
Commit Message:
AGDS: reimplemented Database::write
Changed paths:
engines/agds/database.cpp
diff --git a/engines/agds/database.cpp b/engines/agds/database.cpp
index db2d43ab6d4..5701aaf38c8 100644
--- a/engines/agds/database.cpp
+++ b/engines/agds/database.cpp
@@ -86,17 +86,22 @@ void Database::write(Common::WriteStream *stream, const Common::HashMap<Common::
stream->writeUint32LE(kDefaultNameSize);
auto dataOffset = getDataOffset(kDefaultNameSize, n);
auto offset = dataOffset;
+
for(auto entry: entries) {
- stream->writeUint32LE(offset);
- Common::Array<char> text(kDefaultNameSize);
auto &key = entry._key;
- memcpy(text.data(), key.c_str(), MIN(key.size(), text.size()));
- offset += entry._value.size();
- stream->writeUint32LE(entry._value.size());
+ auto &value = entry._value;
+
+ stream->writeUint32LE(offset);
+ Common::Array<char> text(kDefaultNameSize + 1);
+ strncpy(text.data(), key.c_str(), kDefaultNameSize);
+ stream->write(text.data(), text.size());
+ offset += value.size();
+ stream->writeUint32LE(value.size());
}
+
for(auto entry: entries) {
- auto & data = entry._value;
- stream->write(data.data(), data.size());
+ auto & value = entry._value;
+ stream->write(value.data(), value.size());
}
}
Commit: e11ee7b579b130c0c4555b7522de3166ff523778
https://github.com/scummvm/scummvm/commit/e11ee7b579b130c0c4555b7522de3166ff523778
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:45+01:00
Commit Message:
AGDS: add Character::load/saveState
Changed paths:
engines/agds/agds.cpp
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 31fe06f9a60..ffe8181d0ef 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1056,21 +1056,11 @@ Common::Error AGDSEngine::loadGameState(int slot) {
Common::String filename = loadText(name);
debug("savegame character %s %s -> %s %s", object.c_str(), name.c_str(), filename.c_str(), id.c_str());
loadCharacter(id, filename, object);
- int x = agds_c->readUint16LE();
- int y = agds_c->readUint16LE();
- int dir = agds_c->readUint16LE();
- debug("character at %d, %d, dir: %d", x, y, dir);
auto character = getCharacter(id);
if (character) {
- character->position(Common::Point(x, y));
- character->direction(dir);
+ character->loadState(agds_c.get());
} else
warning("no character");
- int n = 2;
- while(n--) {
- int v = agds_c->readUint16LE();
- debug("savegame character leftover: %d", v);
- }
}
Common::String screenName;
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index bbd581711e8..5d5a122593e 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -98,6 +98,29 @@ void Character::load(Common::SeekableReadStream *stream) {
delete stream;
}
+void Character::loadState(Common::ReadStream* stream) {
+ int x = stream->readUint16LE();
+ int y = stream->readUint16LE();
+ int dir = stream->readUint16LE();
+ debug("character at %d, %d, dir: %d", x, y, dir);
+ position(Common::Point(x, y));
+ direction(dir);
+ int n = 2;
+ while(n--) {
+ int v = stream->readUint16LE();
+ debug("savegame character leftover: %d", v);
+ }
+}
+
+void Character::saveState(Common::WriteStream* stream) {
+ stream->writeUint16LE(_pos.x);
+ stream->writeUint16LE(_pos.y);
+ stream->writeUint16LE(_direction);
+ stream->writeUint16LE(1);
+ stream->writeUint16LE(1);
+}
+
+
void Character::direction(int dir) {
debug("setDirection %d", dir);
_direction = dir;
diff --git a/engines/agds/character.h b/engines/agds/character.h
index ab799400ae8..6e55885365d 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -28,7 +28,7 @@
#include "common/ptr.h"
#include "common/rect.h"
-namespace Common { class SeekableReadStream; }
+namespace Common { class SeekableReadStream; class ReadStream; class WriteStream; }
namespace Graphics { struct Surface; }
namespace AGDS {
@@ -83,6 +83,8 @@ public:
}
void load(Common::SeekableReadStream* stream);
+ void loadState(Common::ReadStream* stream);
+ void saveState(Common::WriteStream* stream);
void enable(bool enabled = true) {
_enabled = enabled;
Commit: 48f23dbb3628d9011012546c0a9899b74148b09f
https://github.com/scummvm/scummvm/commit/48f23dbb3628d9011012546c0a9899b74148b09f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:45+01:00
Commit Message:
AGDS: save char id/resource name/object name in engine to save it later
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ffe8181d0ef..9b2eebd5a7b 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -790,9 +790,13 @@ void AGDSEngine::loadCharacter(const Common::String &id, const Common::String &f
debug("loadCharacter %s %s %s", id.c_str(), filename.c_str(), object.c_str());
delete _currentCharacter;
+
_currentCharacterName = id;
+ _currentCharacterFilename = filename;
+ _currentCharacterObject = object;
+
_currentCharacter = new Character(this, id, loadObject(object));
- _currentCharacter->load(_resourceManager.getResource(filename));
+ _currentCharacter->load(_resourceManager.getResource(loadText(filename)));
}
Graphics::TransparentSurface *AGDSEngine::loadPicture(const Common::String &name) {
@@ -1051,10 +1055,9 @@ Common::Error AGDSEngine::loadGameState(int slot) {
// Current character
Common::ScopedPtr<Common::SeekableReadStream> agds_c(db.getEntry(saveFile, "__agds_c"));
Common::String object = readString(agds_c.get());
- Common::String name = readString(agds_c.get());
+ Common::String filename = readString(agds_c.get());
Common::String id = readString(agds_c.get());
- Common::String filename = loadText(name);
- debug("savegame character %s %s -> %s %s", object.c_str(), name.c_str(), filename.c_str(), id.c_str());
+ debug("savegame character %s %s -> %s %s", object.c_str(), filename.c_str(), filename.c_str(), id.c_str());
loadCharacter(id, filename, object);
auto character = getCharacter(id);
if (character) {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 4d99f7ef4a7..2e5866abefc 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -320,7 +320,7 @@ private:
bool _loadingScreen;
Character * _currentCharacter;
Character * _jokes;
- Common::String _currentCharacterName;
+ Common::String _currentCharacterName, _currentCharacterFilename, _currentCharacterObject;
Common::String _nextScreenName;
Common::String _previousScreenName;
Common::String _defaultMouseCursorName;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 6e2ae25b749..b65fa1940e0 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1365,9 +1365,9 @@ void Process::addMouseArea() {
void Process::loadCharacter() {
Common::String object = popString();
- Common::String chrFilename = popText();
+ Common::String filename = popString();
Common::String id = popString();
- _engine->loadCharacter(id, chrFilename, object);
+ _engine->loadCharacter(id, filename, object);
}
void Process::enableCharacter() {
Commit: 124c5817c0238d573fbfdb95dcd834e56a6c2996
https://github.com/scummvm/scummvm/commit/124c5817c0238d573fbfdb95dcd834e56a6c2996
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:46+01:00
Commit Message:
AGDS: move inventory load/save to inventory class
Changed paths:
engines/agds/agds.cpp
engines/agds/inventory.cpp
engines/agds/inventory.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 9b2eebd5a7b..ddd4f05b1bb 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -61,6 +61,7 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_random("agds"),
_inventoryRegion(),
_soundManager(this, system->getMixer()),
+ _inventory(this),
_dialog(this),
_tellTextTimer(0),
_syncSoundId(-1),
@@ -1117,19 +1118,8 @@ Common::Error AGDSEngine::loadGameState(int slot) {
loadScreen(screenName, false);
{
- // Inventory
- _inventory.clear();
Common::ScopedPtr<Common::SeekableReadStream> agds_i(db.getEntry(saveFile, "__agds_i"));
- int n = 34;
- while(n--) {
- Common::String name = readString(agds_i.get());
- int refcount = agds_i->readUint32LE();
- int objectPtr = agds_i->readUint32LE();
- if (!name.empty() && refcount) {
- debug("inventory: %s %d %d", name.c_str(), refcount, objectPtr);
- _inventory.add(runObject(name));
- }
- }
+ _inventory.load(agds_i.get());
}
delete saveFile;
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 41dbc61856a..1a060c13e7d 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -22,13 +22,15 @@
#include "agds/inventory.h"
#include "agds/object.h"
+#include "agds/resourceManager.h"
+#include "agds/agds.h"
#include "common/debug.h"
#include "common/textconsole.h"
#include "graphics/transparent_surface.h"
namespace AGDS {
-Inventory::Inventory() : _entries(kMaxSize), _enabled(false) {}
+Inventory::Inventory(AGDSEngine* engine): _engine(engine), _entries(kMaxSize), _enabled(false) {}
Inventory::~Inventory() {}
int Inventory::free() const {
@@ -96,4 +98,32 @@ void Inventory::clear() {
}
}
+void Inventory::load(Common::ReadStream* stream) {
+ clear();
+ int n = kMaxSize;
+ while(n--) {
+ Common::String name = readString(stream);
+ int refcount = stream->readUint32LE();
+ int objectPtr = stream->readUint32LE();
+ if (!name.empty() && refcount) {
+ debug("inventory: %s %d %d", name.c_str(), refcount, objectPtr);
+ add(_engine->runObject(name));
+ }
+ }
+}
+
+void Inventory::save(Common::WriteStream* stream) const {
+ for(auto & entry : _entries) {
+ if (entry) {
+ writeString(stream, entry->getName());
+ stream->writeUint32LE(1);
+ stream->writeSint32LE(-1);
+ } else {
+ writeString(stream, Common::String());
+ stream->writeUint32LE(0);
+ stream->writeSint32LE(0);
+ }
+ }
+}
+
} // namespace AGDS
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index 4fbd7d35e51..cf8fb3d309e 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -28,11 +28,14 @@
#include "common/ptr.h"
#include "common/rect.h"
+namespace Common { class ReadStream; class WriteStream; }
+
namespace AGDS {
class Object;
typedef Common::SharedPtr<Object> ObjectPtr;
class Inventory {
+ class AGDSEngine* _engine;
typedef Common::Array<ObjectPtr> EntriesType;
EntriesType _entries;
bool _enabled;
@@ -41,9 +44,12 @@ class Inventory {
public:
static const int kMaxSize = 35;
- Inventory();
+ Inventory(AGDSEngine* _engine);
~Inventory();
+ void load(Common::ReadStream* stream);
+ void save(Common::WriteStream* stream) const;
+
bool enabled() const {
return _enabled;
}
Commit: c9c22ece828748a057834619e1be11fe9ab3246b
https://github.com/scummvm/scummvm/commit/c9c22ece828748a057834619e1be11fe9ab3246b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:46+01:00
Commit Message:
AGDS: disable autosave
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ddd4f05b1bb..0c5cfc1e86e 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1024,7 +1024,7 @@ void AGDSEngine::loadPatches(Common::SeekableReadStream *file, Database & db) {
Common::Error AGDSEngine::loadGameState(int slot) {
- saveAutosaveIfEnabled();
+ //saveAutosaveIfEnabled();
auto fileName = getSaveStateName(slot);
Common::InSaveFile *saveFile = _saveFileMan->openForLoading(fileName);
Commit: 42a1f6d32025497d496d8b7a9c2622b19af6213c
https://github.com/scummvm/scummvm/commit/42a1f6d32025497d496d8b7a9c2622b19af6213c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:46+01:00
Commit Message:
AGDS: made Character::saveState const
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 5d5a122593e..d25665ba3f7 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -112,7 +112,7 @@ void Character::loadState(Common::ReadStream* stream) {
}
}
-void Character::saveState(Common::WriteStream* stream) {
+void Character::saveState(Common::WriteStream* stream) const {
stream->writeUint16LE(_pos.x);
stream->writeUint16LE(_pos.y);
stream->writeUint16LE(_direction);
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 6e55885365d..00008d103de 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -84,7 +84,7 @@ public:
void load(Common::SeekableReadStream* stream);
void loadState(Common::ReadStream* stream);
- void saveState(Common::WriteStream* stream);
+ void saveState(Common::WriteStream* stream) const;
void enable(bool enabled = true) {
_enabled = enabled;
Commit: c2883b2883759cf162a2b580ec60f0da2aabb0d6
https://github.com/scummvm/scummvm/commit/c2883b2883759cf162a2b580ec60f0da2aabb0d6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:46+01:00
Commit Message:
AGDS: implement/load object patch
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/patch.cpp
engines/agds/patch.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 0c5cfc1e86e..62a4cab009f 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1008,6 +1008,7 @@ bool AGDSEngine::hasFeature(EngineFeature f) const {
void AGDSEngine::loadPatches(Common::SeekableReadStream *file, Database & db) {
debug("loading patches");
_patches.clear();
+ _objectPatches.clear();
Common::Array<Common::String> entries = db.getEntries();
for (uint i = 0; i < entries.size(); ++i) {
const Common::String & name = entries[i];
@@ -1015,9 +1016,15 @@ void AGDSEngine::loadPatches(Common::SeekableReadStream *file, Database & db) {
continue;
debug("loading patch for %s", name.c_str());
Common::ScopedPtr<Common::SeekableReadStream> patchStream(db.getEntry(file, name));
- PatchPtr patch(new Patch());
- patch->load(patchStream.get());
- _patches[name] = patch;
+ if (patchStream->size() != ObjectPatch::Size) {
+ PatchPtr patch(new Patch());
+ patch->load(patchStream.get());
+ _patches[name] = patch;
+ } else {
+ ObjectPatchPtr patch(new ObjectPatch());
+ patch->load(patchStream.get());
+ _objectPatches[name] = patch;
+ }
}
debug("done loading patches");
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 2e5866abefc..4fe1600bdee 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -60,6 +60,8 @@ class Character;
class Font;
class Object;
typedef Common::SharedPtr<Object> ObjectPtr;
+struct ObjectPatch;
+typedef Common::SharedPtr<ObjectPatch> ObjectPatchPtr;
struct Patch;
typedef Common::SharedPtr<Patch> PatchPtr;
class Process;
@@ -89,7 +91,9 @@ public:
uint32 map(const Graphics::PixelFormat &format) const;
};
+
AGDSEngine(OSystem *syst, const ADGameDescription *gameDesc);
+ AGDSEngine(const AGDSEngine &) = delete;
~AGDSEngine();
Common::Error run() override;
@@ -290,6 +294,7 @@ private:
typedef Common::HashMap<Common::String, Animation *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> AnimationsType;
typedef Common::HashMap<int, Font *> FontsType;
typedef Common::HashMap<Common::String, PatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PatchesType;
+ typedef Common::HashMap<Common::String, ObjectPatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectPatchesType;
const ADGameDescription * _gameDescription;
ResourceManager _resourceManager;
@@ -302,6 +307,7 @@ private:
AnimationsType _animations;
ProcessListType _processes;
PatchesType _patches;
+ ObjectPatchesType _objectPatches;
int _sharedStorageIndex;
Common::String _sharedStorage[10];
GlobalsType _globals;
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index 648b628e0c0..df928b55238 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -6,15 +6,20 @@
namespace AGDS {
+void ObjectPatch::load(Common::ReadStream *stream) {
+ text = readString(stream);
+ region = readString(stream);
+ z = stream->readUint16LE();
+}
+
+void ObjectPatch::save(Common::WriteStream *stream) const {
+ writeString(stream, text);
+ writeString(stream, region);
+ stream->writeUint16LE(z);
+}
+
void Patch::load(Common::ReadStream *stream) {
byte extended = stream->readByte();
- if (extended != 1 && extended != 0) {
- Common::String prototype = (char)extended + readString(stream, 31);
- Common::String unk = readString(stream);
- debug("patch for object: %s %s", prototype.c_str(), unk.c_str());
- return;
- }
-
screenRegionName = readString(stream);
prevScreenName = readString(stream);
if (extended == 0)
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index 2a74c27c7b6..4004515104d 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -35,6 +35,16 @@ namespace AGDS {
class AGDSEngine;
class Object;
+struct ObjectPatch {
+ static constexpr unsigned Size = 66;
+
+ Common::String text;
+ Common::String region;
+ int z;
+ void load(Common::ReadStream *stream);
+ void save(Common::WriteStream *stream) const;
+};
+
struct Patch {
struct Object {
Common::String name;
Commit: e7513b5c51097099f80fa9b6722c20823d8f313a
https://github.com/scummvm/scummvm/commit/e7513b5c51097099f80fa9b6722c20823d8f313a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:46+01:00
Commit Message:
AGDS: patch object if there's a patch for it
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 62a4cab009f..98daffeac7a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -221,6 +221,22 @@ void AGDSEngine::runObject(const ObjectPtr &object) {
if (_currentScreen) {
if (_currentScreen->add(object)) {
runProcess(object);
+
+ auto it = _objectPatches.find(object->getName());
+ if (it != _objectPatches.end()) {
+ auto& patch = *it->_value;
+ if (!patch.region.empty()) {
+ RegionPtr region = loadRegion(patch.region);
+ debug("runObject: patch region: %s", region->toString().c_str());
+ object->region(region);
+ }
+ if (!patch.text.empty()) {
+ auto text = loadText(patch.text);
+ debug("runObject: patch title: %s -> %s", patch.text.c_str(), text.c_str());
+ object->title(text);
+ }
+ object->z(patch.z);
+ }
} else
debug("object %s is in scene, skip run", object->getName().c_str());
} else
Commit: 469f9b6353d101ab71c34a2da2ac7a60db1d7189
https://github.com/scummvm/scummvm/commit/469f9b6353d101ab71c34a2da2ac7a60db1d7189
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:46+01:00
Commit Message:
AGDS: rename stub172 to setSampleType
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 17160371402..dc801516383 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -189,7 +189,7 @@ enum Opcode {
kGetIntegerSystemVariable = 169,
kSetDelay = 170,
kGetRandomNumber = 171,
- kStub172 = 172,
+ kSetSampleType = 172,
kStub173 = 173,
kStub174 = 174,
kAppendToSharedStorage = 175,
@@ -407,7 +407,7 @@ enum Opcode {
OP(kGetSaveGameName, getSaveGameName) \
OP(kSetObjectRegionOffset, setObjectRegionOffset) \
OP(kSetDelay, setDelay) \
- OP(kStub172, stub172) \
+ OP(kSetSampleType, setSampleType) \
OP(kStub173, stub173) \
OP(kStub174, stub174) \
OP(kStub192, stub192) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b65fa1940e0..f79701318db 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -851,9 +851,9 @@ void Process::setObjectRegionOffset() {
warning("setObjectRegionOffset: object %s not found", objectName.c_str());
}
-void Process::stub172() {
+void Process::setSampleType() {
int value = pop();
- debug("stub172: setMusicVolume? %d", value);
+ debug("setSampleType: %d stub", value);
}
void Process::stub173() {
Commit: 1f6cffbf6fc479d98f46d93a6c49002edb6bcb36
https://github.com/scummvm/scummvm/commit/1f6cffbf6fc479d98f46d93a6c49002edb6bcb36
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:46+01:00
Commit Message:
AGDS: add ambient sample implementation + SoundManager::find(id)
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 98daffeac7a..56192ac8921 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -65,6 +65,7 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_dialog(this),
_tellTextTimer(0),
_syncSoundId(-1),
+ _ambientSoundId(-1),
_fastMode(true),
_hintMode(false) {
}
@@ -322,6 +323,7 @@ void AGDSEngine::loadScreen(const Common::String &name, bool savePatch) {
_processes[i].reset();
}
_animations.clear();
+ _ambientSoundId = -1;
auto patch = getPatch(name);
auto screenObject = loadObject(name);
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 4fe1600bdee..6d87fec4dcc 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -252,6 +252,7 @@ public:
void playSoundSync(const Common::String &resource, const Common::String &phaseVar) {
_syncSoundId = playSound(Common::String(), resource, phaseVar);
}
+ void setAmbientSoundId(int id) { _ambientSoundId = id; }
void tell(Process &process, const Common::String ®ion, Common::String text, Common::String sound, bool npc);
@@ -351,6 +352,7 @@ private:
TextLayout _textLayout;
int _syncSoundId;
+ int _ambientSoundId;
bool _fastMode;
bool _hintMode;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f79701318db..360e0bbf58b 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -164,8 +164,10 @@ void Process::loadAnimation() {
void Process::loadSample() {
Common::String name = popText();
- debug("loadSample %s, phaseVar: %s", name.c_str(), _phaseVar.c_str());
- _engine->playSound(getName(), name, _phaseVar);
+ debug("loadSample %s, phaseVar: %s, ambient: %d", name.c_str(), _phaseVar.c_str(), _sampleAmbient);
+ int id = _engine->playSound(getName(), name, _phaseVar);
+ if (_sampleAmbient)
+ _engine->setAmbientSoundId(id);
}
void Process::getSampleVolume() {
@@ -887,7 +889,7 @@ void Process::disableMouseAreas() {
}
void Process::sampleAmbient() {
- debug("sampleAmbient: stub");
+ debug("setAmbientSample");
_sampleAmbient = true;
}
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 4533ead6211..60c9c16019c 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -58,6 +58,15 @@ void SoundManager::tick() {
}
}
+const Sound *SoundManager::find(int id) const {
+ for (auto i = _sounds.begin(); i != _sounds.end(); ++i) {
+ auto &sound = *i;
+ if (sound.id == id)
+ return &sound;
+ }
+ return nullptr;
+}
+
Sound *SoundManager::findSampleByPhaseVar(const Common::String &phaseVar) {
if (phaseVar.empty())
return nullptr;
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index d1693391865..ea7997bfc01 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -63,6 +63,7 @@ namespace AGDS {
int play(const Common::String &process, const Common::String &file, const Common::String &phaseVar, bool startPlaying = true, int id = -1);
bool playing(int id) const;
void stopAll();
+ const Sound *find(int id) const;
Sound *findSampleByPhaseVar(const Common::String &phaseVar);
};
Commit: b07003b437f63c082c4855bd34fac2cab6ce4315
https://github.com/scummvm/scummvm/commit/b07003b437f63c082c4855bd34fac2cab6ce4315
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:46+01:00
Commit Message:
AGDS: implement game saving
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/database.cpp
engines/agds/soundManager.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 56192ac8921..dd2621eb5de 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -39,6 +39,7 @@
#include "common/events.h"
#include "common/file.h"
#include "common/ini-file.h"
+#include "common/memstream.h"
#include "common/savefile.h"
#include "common/system.h"
#include "engines/util.h"
@@ -323,7 +324,6 @@ void AGDSEngine::loadScreen(const Common::String &name, bool savePatch) {
_processes[i].reset();
}
_animations.clear();
- _ambientSoundId = -1;
auto patch = getPatch(name);
auto screenObject = loadObject(name);
@@ -1061,6 +1061,8 @@ Common::Error AGDSEngine::loadGameState(int slot) {
if (!db.open(fileName, saveFile))
return Common::kReadingFailed;
+ _soundManager.stopAll();
+
{
// Compiled version (should be 2)
Common::ScopedPtr<Common::SeekableReadStream> agds_ver(db.getEntry(saveFile, "__agds_ver"));
@@ -1113,19 +1115,6 @@ Common::Error AGDSEngine::loadGameState(int slot) {
}
}
- {
- _soundManager.stopAll();
- // Audio samples
- Common::ScopedPtr<Common::SeekableReadStream> agds_a(db.getEntry(saveFile, "__agds_a"));
- Common::String sample = loadText(readString(agds_a.get()));
- Common::String phaseVar = readString(agds_a.get());
- uint volume = agds_a->readUint32LE();
- uint type = agds_a->readUint32LE();
- debug("saved audio state: sample: '%s', var: '%s' %u %u", sample.c_str(), phaseVar.c_str(), volume, type);
- debug("phase var for sample -> %d", getGlobal(phaseVar));
- playSound(Common::String(), sample, phaseVar); //fixme: double check
- }
-
{
// System vars
Common::ScopedPtr<Common::SeekableReadStream> agds_d(db.getEntry(saveFile, "__agds_d"));
@@ -1142,6 +1131,18 @@ Common::Error AGDSEngine::loadGameState(int slot) {
loadPatches(saveFile, db);
loadScreen(screenName, false);
+ {
+ // Saved ambient sound
+ Common::ScopedPtr<Common::SeekableReadStream> agds_a(db.getEntry(saveFile, "__agds_a"));
+ Common::String sample = loadText(readString(agds_a.get()));
+ Common::String phaseVar = readString(agds_a.get());
+ uint volume = agds_a->readUint32LE();
+ uint type = agds_a->readUint32LE();
+ debug("saved audio state: sample: '%s', var: '%s' %u %u", sample.c_str(), phaseVar.c_str(), volume, type);
+ debug("phase var for sample -> %d", getGlobal(phaseVar));
+ _ambientSoundId = playSound(Common::String(), sample, phaseVar); //fixme: double check
+ debug("ambient sound id = %d", _ambientSoundId);
+ }
{
Common::ScopedPtr<Common::SeekableReadStream> agds_i(db.getEntry(saveFile, "__agds_i"));
_inventory.load(agds_i.get());
@@ -1153,12 +1154,103 @@ Common::Error AGDSEngine::loadGameState(int slot) {
Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
auto fileName = getSaveStateName(slot);
- Common::OutSaveFile *saveFile = getSaveFileManager()->openForSaving(fileName);
+ Common::OutSaveFile *saveFile = getSaveFileManager()->openForSaving(fileName, false);
if (!saveFile)
return Common::kWritingFailed;
Common::HashMap<Common::String, Common::Array<uint8>> entries;
+
+ {
+ Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
+ stream.writeUint32LE(2);
+ entries["__agds_ver"].assign(stream.getData(), stream.getData() + stream.size());
+ }
+
+ {
+ Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
+ writeString(&stream, _currentCharacterObject);
+ writeString(&stream, _currentCharacterFilename);
+ writeString(&stream, _currentCharacterName);
+ auto character = getCharacter(_currentCharacterName);
+ if (character) {
+ character->saveState(&stream);
+ } else
+ warning("no character to save");
+
+ auto size = stream.size();
+ if (size < 106) {
+ Common::Array<unsigned char> filler(106 - size);
+ stream.write(filler.data(), filler.size());
+ }
+ entries["__agds_c"].assign(stream.getData(), stream.getData() + stream.size());
+ }
+
+ {
+ Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
+ writeString(&stream, _currentScreenName);
+ char palette[0x300];
+ memset(palette, 0xaa, sizeof(palette));
+ stream.write(palette, sizeof(palette));
+ entries["__agds_s"].assign(stream.getData(), stream.getData() + stream.size());
+ }
+
+ {
+ Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
+ for(uint i = 0, n = _systemVarList.size(); i < n; ++i) {
+ Common::String & name = _systemVarList[i];
+ _systemVars[name]->write(&stream);
+ }
+ entries["__agds_d"].assign(stream.getData(), stream.getData() + stream.size());
+ }
+
+ {
+ Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
+ auto n = _globals.size();
+ stream.writeUint32LE(n);
+ debug("saving %u vars...", n);
+ for(auto & global : _globals) {
+ writeString(&stream, global._key);
+ stream.writeUint32LE(global._value);
+ }
+ entries["__agds_v"].assign(stream.getData(), stream.getData() + stream.size());
+ }
+
+ {
+ Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
+ _inventory.save(&stream);
+ entries["__agds_i"].assign(stream.getData(), stream.getData() + stream.size());
+ }
+
+ {
+ Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
+ debug("ambient sound id: %d", _ambientSoundId);
+ auto sound = _soundManager.find(_ambientSoundId);
+ if (sound) {
+ writeString(&stream, sound->name);
+ writeString(&stream, sound->phaseVar);
+ } else {
+ writeString(&stream, Common::String());
+ writeString(&stream, Common::String());
+ }
+ stream.writeUint32LE(70); //volume
+ stream.writeUint32LE(30); //type
+
+ entries["__agds_a"].assign(stream.getData(), stream.getData() + stream.size());
+ }
+
+ for(auto & objectPatch : _objectPatches) {
+ Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
+ objectPatch._value->save(&stream);
+ entries[objectPatch._key].assign(stream.getData(), stream.getData() + stream.size());
+ }
+
+ for(auto & patch : _patches) {
+ Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
+ patch._value->save(&stream);
+ entries[patch._key].assign(stream.getData(), stream.getData() + stream.size());
+ }
+
Database::write(saveFile, entries);
delete saveFile;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 6d87fec4dcc..1adcc118ab0 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -296,6 +296,7 @@ private:
typedef Common::HashMap<int, Font *> FontsType;
typedef Common::HashMap<Common::String, PatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PatchesType;
typedef Common::HashMap<Common::String, ObjectPatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectPatchesType;
+ typedef Common::HashMap<Common::String, Common::Array<uint8>> PatchDatabase;
const ADGameDescription * _gameDescription;
ResourceManager _resourceManager;
diff --git a/engines/agds/database.cpp b/engines/agds/database.cpp
index 5701aaf38c8..801b430eafa 100644
--- a/engines/agds/database.cpp
+++ b/engines/agds/database.cpp
@@ -85,7 +85,8 @@ void Database::write(Common::WriteStream *stream, const Common::HashMap<Common::
stream->writeUint32LE(n);
stream->writeUint32LE(kDefaultNameSize);
auto dataOffset = getDataOffset(kDefaultNameSize, n);
- auto offset = dataOffset;
+ debug("database data offset: 0x%06x", dataOffset);
+ auto offset = 0;
for(auto entry: entries) {
auto &key = entry._key;
@@ -95,6 +96,7 @@ void Database::write(Common::WriteStream *stream, const Common::HashMap<Common::
Common::Array<char> text(kDefaultNameSize + 1);
strncpy(text.data(), key.c_str(), kDefaultNameSize);
stream->write(text.data(), text.size());
+ debug("database entry %s: 0x%06x", key.c_str(), offset);
offset += value.size();
stream->writeUint32LE(value.size());
}
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 60c9c16019c..9373656e5fc 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -93,6 +93,9 @@ void SoundManager::stopAll() {
int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &phaseVar, bool startPlaying, int id) {
debug("SoundMan::play %s %s %s %d %d", process.c_str(), resource.c_str(), phaseVar.c_str(), startPlaying, id);
+ if (resource.empty())
+ return -1;
+
{
auto sample = findSampleByPhaseVar(phaseVar);
if (sample && playing(sample->id)) {
Commit: 922e3caaa70552fd17de8abee29b88ea1cdb1b1f
https://github.com/scummvm/scummvm/commit/922e3caaa70552fd17de8abee29b88ea1cdb1b1f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:46+01:00
Commit Message:
AGDS: pass sample resource to playSound to properly save/restore it later
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index dd2621eb5de..8ff407fcc9c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -731,7 +731,7 @@ void AGDSEngine::playFilm(Process &process, const Common::String &video, const C
_mjpgPlayer = new MJPGPlayer(_resourceManager.getResource(video), subtitles);
_soundManager.stopAll();
_filmStarted = _system->getMillis();
- _syncSoundId = _soundManager.play(process.getName(), audio, Common::String());
+ _syncSoundId = _soundManager.play(process.getName(), Common::String(), audio, Common::String());
}
void AGDSEngine::skipFilm() {
@@ -1134,13 +1134,14 @@ Common::Error AGDSEngine::loadGameState(int slot) {
{
// Saved ambient sound
Common::ScopedPtr<Common::SeekableReadStream> agds_a(db.getEntry(saveFile, "__agds_a"));
- Common::String sample = loadText(readString(agds_a.get()));
- Common::String phaseVar = readString(agds_a.get());
+ auto resource = readString(agds_a.get());
+ auto filename = loadText(resource);
+ auto phaseVar = readString(agds_a.get());
uint volume = agds_a->readUint32LE();
uint type = agds_a->readUint32LE();
- debug("saved audio state: sample: '%s', var: '%s' %u %u", sample.c_str(), phaseVar.c_str(), volume, type);
+ debug("saved audio state: sample: '%s:%s', var: '%s' %u %u", resource.c_str(), filename.c_str(), phaseVar.c_str(), volume, type);
debug("phase var for sample -> %d", getGlobal(phaseVar));
- _ambientSoundId = playSound(Common::String(), sample, phaseVar); //fixme: double check
+ _ambientSoundId = playSound(Common::String(), resource, filename, phaseVar); //fixme: double check
debug("ambient sound id = %d", _ambientSoundId);
}
{
@@ -1227,7 +1228,7 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
debug("ambient sound id: %d", _ambientSoundId);
auto sound = _soundManager.find(_ambientSoundId);
if (sound) {
- writeString(&stream, sound->name);
+ writeString(&stream, sound->resource);
writeString(&stream, sound->phaseVar);
} else {
writeString(&stream, Common::String());
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 1adcc118ab0..6b981e05321 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -245,12 +245,12 @@ public:
void tickInventory();
- int playSound(const Common::String &process, const Common::String &resource, const Common::String &phaseVar, bool playing = true) {
- return _soundManager.play(process, resource, phaseVar, playing);
+ int playSound(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool playing = true) {
+ return _soundManager.play(process, resource, filename, phaseVar, playing);
}
- void playSoundSync(const Common::String &resource, const Common::String &phaseVar) {
- _syncSoundId = playSound(Common::String(), resource, phaseVar);
+ void playSoundSync(const Common::String &filename, const Common::String &phaseVar) {
+ _syncSoundId = playSound(Common::String(), Common::String(), filename, phaseVar);
}
void setAmbientSoundId(int id) { _ambientSoundId = id; }
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 360e0bbf58b..3977754391e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -163,9 +163,9 @@ void Process::loadAnimation() {
}
void Process::loadSample() {
- Common::String name = popText();
+ Common::String name = popString();
debug("loadSample %s, phaseVar: %s, ambient: %d", name.c_str(), _phaseVar.c_str(), _sampleAmbient);
- int id = _engine->playSound(getName(), name, _phaseVar);
+ int id = _engine->playSound(getName(), name, _engine->loadText(name), _phaseVar);
if (_sampleAmbient)
_engine->setAmbientSoundId(id);
}
@@ -226,7 +226,7 @@ void Process::restartSample() {
debug("restartSample %s", name.c_str());
auto sound = _engine->soundManager().findSampleByPhaseVar(name);
if (sound) {
- debug("sample found (%s)", sound->name.c_str());
+ debug("sample found (%s:%s)", sound->resource.c_str(), sound->filename.c_str());
int value = _engine->getGlobal(name);
_engine->setGlobal(name, value | 2);
} else {
@@ -239,7 +239,7 @@ void Process::stopSample() {
debug("restartSample %s", name.c_str());
auto sound = _engine->soundManager().findSampleByPhaseVar(name);
if (sound) {
- debug("sample found (%s)", sound->name.c_str());
+ debug("sample found (%s:%s)", sound->resource.c_str(), sound->filename.c_str());
int value = _engine->getGlobal(name);
_engine->setGlobal(name, value | 4);
} else {
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 9373656e5fc..6f6ab9f1912 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -44,12 +44,12 @@ void SoundManager::tick() {
if (value == 1 && !active)
_engine->setGlobal(phaseVar, 0);
} else if (value & 2) {
- debug("sample %s restarts (via phase var)", sound.name.c_str());
+ debug("sample %s:%s restarts (via phase var)", sound.resource.c_str(), sound.filename.c_str());
_engine->setGlobal(phaseVar, 1);
_mixer->stopID(sound.id);
- play(sound.process, sound.name, sound.phaseVar, true, sound.id);
+ play(sound.process, sound.resource, sound.filename, sound.phaseVar, true, sound.id);
} else if (value & 4) {
- debug("sample %s stops (via phase var)", sound.name.c_str());
+ debug("sample %s:%s stops (via phase var)", sound.resource.c_str(), sound.filename.c_str());
_mixer->stopID(sound.id);
_engine->setGlobal(phaseVar, 0);
}
@@ -91,9 +91,9 @@ void SoundManager::stopAll() {
_sounds.clear();
}
-int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &phaseVar, bool startPlaying, int id) {
- debug("SoundMan::play %s %s %s %d %d", process.c_str(), resource.c_str(), phaseVar.c_str(), startPlaying, id);
- if (resource.empty())
+int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int id) {
+ debug("SoundMan::play '%s' '%s' '%s' '%s' %d %d", process.c_str(), resource.c_str(), filename.c_str(), phaseVar.c_str(), startPlaying, id);
+ if (filename.empty())
return -1;
{
@@ -104,14 +104,14 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
}
}
Common::File *file = new Common::File();
- if (!file->open(resource)) {
+ if (!file->open(filename)) {
if (!phaseVar.empty())
_engine->setGlobal(phaseVar, 0);
- warning("no sound %s", resource.c_str());
+ warning("no sound %s", filename.c_str());
return -1;
}
- Common::String lname(resource);
+ Common::String lname(filename);
lname.toLowercase();
Audio::SeekableAudioStream *stream = NULL;
@@ -121,7 +121,7 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
stream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
}
if (!stream) {
- warning("could not play sound %s", resource.c_str());
+ warning("could not play sound %s", filename.c_str());
delete file;
if (!phaseVar.empty())
_engine->setGlobal(phaseVar, 0);
@@ -133,7 +133,7 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
if (id == -1)
id = _nextId++;
- _sounds.push_back(Sound(id, process, resource, phaseVar, handle));
+ _sounds.push_back(Sound(id, process, resource, filename, phaseVar, handle));
_mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, stream, id);
//if (sound_off)
// setPhaseVar(_sounds.back(), 1);
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index ea7997bfc01..e148fbdacef 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -38,15 +38,16 @@ namespace AGDS {
struct Sound {
int id;
Common::String process;
- Common::String name;
+ Common::String resource;
+ Common::String filename;
Common::String phaseVar;
Audio::SoundHandle handle;
int group;
int leftVolume;
int rightVolume;
bool paused;
- Sound(int id_, const Common::String &p, const Common::String & res, const Common::String & var, Audio::SoundHandle h, int g = 0):
- id(id_), process(p), name(res), phaseVar(var), handle(h), group(g), leftVolume(100), rightVolume(100), paused(false) {
+ Sound(int id_, const Common::String &p, const Common::String & res, const Common::String &file, const Common::String & var, Audio::SoundHandle h, int g = 0):
+ id(id_), process(p), resource(res), filename(file), phaseVar(var), handle(h), group(g), leftVolume(100), rightVolume(100), paused(false) {
}
};
@@ -60,7 +61,7 @@ namespace AGDS {
public:
SoundManager(AGDSEngine *engine, Audio::Mixer *mixer): _nextId(1), _engine(engine), _mixer(mixer) { }
void tick();
- int play(const Common::String &process, const Common::String &file, const Common::String &phaseVar, bool startPlaying = true, int id = -1);
+ int play(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying = true, int id = -1);
bool playing(int id) const;
void stopAll();
const Sound *find(int id) const;
Commit: 75192c15df744ad2f58eb650012411e3e40e1937
https://github.com/scummvm/scummvm/commit/75192c15df744ad2f58eb650012411e3e40e1937
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:46+01:00
Commit Message:
AGDS: revisited previous/next handling
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 8ff407fcc9c..5a9a015dad2 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -344,8 +344,10 @@ void AGDSEngine::loadScreen(const Common::String &name, bool savePatch) {
}
if (!patch->defaultMouseCursor.empty())
loadDefaultMouseCursor(patch->defaultMouseCursor);
- if (patch->hasPreviousScreen)
+ if (patch->hasPreviousScreen && !patch->prevScreenName.empty()) {
+ debug("setting previous screen name to %s (from patch)", patch->prevScreenName.c_str());
_previousScreenName = patch->prevScreenName;
+ }
}
reAddInventory();
_navigatedToPreviousScreen = false;
@@ -353,6 +355,9 @@ void AGDSEngine::loadScreen(const Common::String &name, bool savePatch) {
}
void AGDSEngine::resetCurrentScreen() {
+ debug("setting previous screen name to %s", _currentScreenName.c_str());
+ _previousScreenName = _currentScreenName;
+
if (_currentRegion) {
_currentRegion->hide(this);
_currentRegion = NULL;
@@ -1189,7 +1194,8 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
{
Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
- writeString(&stream, _currentScreenName);
+ writeString(&stream, _previousScreenName);
+ debug("saving screen name: %s", _previousScreenName.c_str());
char palette[0x300];
memset(palette, 0xaa, sizeof(palette));
stream.write(palette, sizeof(palette));
@@ -1303,5 +1309,18 @@ void AGDSEngine::returnCurrentInventoryObject() {
runObject(object);
}
+void AGDSEngine::setNextScreenName(const Common::String &nextScreenName) {
+ _navigatedToPreviousScreen = false;
+ _nextScreenName = nextScreenName;
+}
+
+void AGDSEngine::returnToPreviousScreen() {
+ debug("returnToPreviousScreen, previous screen: %s", _previousScreenName.c_str());
+ if (!_previousScreenName.empty()) {
+ _navigatedToPreviousScreen = true;
+ _nextScreenName = _previousScreenName;
+ _previousScreenName.clear();
+ }
+}
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 6b981e05321..bdd4bf25802 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -223,21 +223,8 @@ public:
void initSystemVariables();
SystemVariable *getSystemVariable(const Common::String &name);
- void setNextScreenName(const Common::String &nextScreenName, bool savePrev) {
- _navigatedToPreviousScreen = false;
- if (_currentScreen && savePrev) {
- _previousScreenName = _currentScreenName;
- }
- _nextScreenName = nextScreenName;
- }
-
- void returnToPreviousScreen() {
- if (!_previousScreenName.empty()) {
- _navigatedToPreviousScreen = true;
- _nextScreenName = _previousScreenName;
- _previousScreenName.clear();
- }
- }
+ void setNextScreenName(const Common::String &nextScreenName);
+ void returnToPreviousScreen();
void runDialog(const Common::String &dialogParentProcess, const Common::String &dialogProcess) {
_dialog.run(dialogParentProcess, dialogProcess);
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index dc801516383..5ea4a2a8fcd 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -98,7 +98,7 @@ enum Opcode {
kScreenCloneObject = 77,
kScreenRemoveObject = 78,
kSetNextScreen = 79,
- kSetNextScreenSaveInHistory = 80,
+ kSetNextScreen2 = 80,
kStub82 = 82,
kStub83 = 83,
kStub84 = 84,
@@ -342,7 +342,6 @@ enum Opcode {
OP(kResetMousePointer, resetMousePointer) \
OP(kInventoryAddObject, inventoryAddObject) \
OP(kInventoryRemoveObject, inventoryRemoveObject) \
- OP(kSetNextScreenSaveInHistory, setNextScreenSaveInHistory) \
OP_U(kObjectRegisterUseObjectHandler, onObjectUse) \
OP(kStub82, stub82) \
OP(kStub83, stub83) \
@@ -357,6 +356,7 @@ enum Opcode {
OP(kScreenLoadRegion, loadScreenRegion) \
OP(kScreenCloneObject, cloneObject) \
OP(kSetNextScreen, setNextScreen) \
+ OP(kSetNextScreen2, setNextScreen2) \
OP(kScreenRemoveObject, removeScreenObject) \
OP(kLoadAnimation, loadAnimation) \
OP(kLoadSample, loadSample) \
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index c443c19a619..4a5f919e593 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -183,12 +183,9 @@ void Process::run() {
_engine->runDialog(getName(), getExitArg1());
break;
case kExitCodeSetNextScreen:
+ case kExitCodeSetNextScreen2:
debug("process %s launches screen: %s", getName().c_str(), getExitArg1().c_str());
- _engine->setNextScreenName(getExitArg1(), false);
- done();
- break;
- case kExitCodeSetNextScreenSaveInHistory:
- _engine->setNextScreenName(getExitArg1(), true);
+ _engine->setNextScreenName(getExitArg1());
done();
break;
case kExitCodeMouseAreaChange:
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index 5a65265e720..3c55d124f6f 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -29,7 +29,7 @@ namespace AGDS {
kExitCodeDestroy = 2,
kExitCodeSuspend = 5,
kExitCodeSetNextScreen = 6,
- kExitCodeSetNextScreenSaveInHistory = 7,
+ kExitCodeSetNextScreen2 = 7,
kExitCodeLoadScreenObject = 8,
kExitCodeLoadScreenObjectAs = 9,
kExitCodeLoadInventoryObject = 10,
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3977754391e..f4d5ab3dc91 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1261,10 +1261,10 @@ void Process::setNextScreen() {
suspend(kExitCodeSetNextScreen, name);
}
-void Process::setNextScreenSaveInHistory() {
+void Process::setNextScreen2() {
Common::String name = popString();
- debug("setNextScreenSaveInHistory %s", name.c_str());
- suspend(kExitCodeSetNextScreenSaveInHistory, name);
+ debug("exitProcessSetNextScreen2 %s", name.c_str());
+ suspend(kExitCodeSetNextScreen2, name);
}
void Process::loadPreviousScreen() {
Commit: 33dda54d18ffa90c40f3d4fb79ce4d719511f38f
https://github.com/scummvm/scummvm/commit/33dda54d18ffa90c40f3d4fb79ce4d719511f38f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:47+01:00
Commit Message:
AGDS: save screen patch before saving
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 5a9a015dad2..28901282da0 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -295,26 +295,33 @@ PatchPtr AGDSEngine::createPatch(const Common::String &screenName) {
return patch;
}
+void AGDSEngine::saveScreenPatch() {
+ if (!_currentScreen || _currentScreenName.empty())
+ return;
+
+ PatchPtr &patch = _patches[_currentScreenName];
+ if (!patch)
+ patch = PatchPtr(new Patch());
+ _currentScreen->save(patch);
+ if (!_previousScreenName.empty()) {
+ patch->prevScreenName = _previousScreenName;
+ patch->hasPreviousScreen = 1;
+ }
+ patch->characterPresent = _currentCharacter != nullptr;
+ if (_currentCharacter) {
+ patch->characterPosition = _currentCharacter->position();
+ patch->characterDirection = _currentCharacter->direction();
+ }
+ patch->defaultMouseCursor = _defaultMouseCursorName;
+}
+
+
void AGDSEngine::loadScreen(const Common::String &name, bool savePatch) {
_loadingScreen = true;
_nextScreenName.clear();
debug("loadScreen %s [return to previous: %d, save patch: %d]", name.c_str(), _navigatedToPreviousScreen, savePatch);
- if (savePatch && _currentScreen && !_currentScreenName.empty()) {
- PatchPtr &patch = _patches[_currentScreenName];
- if (!patch)
- patch = PatchPtr(new Patch());
- _currentScreen->save(patch);
- if (!_previousScreenName.empty()) {
- patch->prevScreenName = _previousScreenName;
- patch->hasPreviousScreen = 1;
- }
- patch->characterPresent = _currentCharacter != nullptr;
- if (_currentCharacter) {
- patch->characterPosition = _currentCharacter->position();
- patch->characterDirection = _currentCharacter->direction();
- }
- patch->defaultMouseCursor = _defaultMouseCursorName;
- }
+ if (savePatch)
+ saveScreenPatch();
returnCurrentInventoryObject();
_inventory.enable(false);
_mouseMap.hideAll(this);
@@ -1165,6 +1172,8 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
if (!saveFile)
return Common::kWritingFailed;
+ saveScreenPatch();
+
Common::HashMap<Common::String, Common::Array<uint8>> entries;
{
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index bdd4bf25802..3f583208597 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -128,6 +128,7 @@ public:
void resetCurrentScreen();
void loadScreen(const Common::String & name, bool savePatch = true);
+ void saveScreenPatch();
RegionPtr loadRegion(const Common::String &name);
Common::String loadText(const Common::String &name);
Commit: 38a8d32eaca4df6a24370700927ed7c03056d467
https://github.com/scummvm/scummvm/commit/38a8d32eaca4df6a24370700927ed7c03056d467
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:47+01:00
Commit Message:
AGDS: fix crash when user interaction was enabled, but no mouse cursor
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 28901282da0..c085c2973ef 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -680,7 +680,7 @@ Common::Error AGDSEngine::run() {
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer->getRect())) {
picture->blit(*backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
}
- } else {
+ } else if (mouseCursor) {
mouseCursor->tick();
mouseCursor->paint(*backbuffer, _mouse);
}
Commit: 22e76f838ef95af61bf82acef33ad4f27bd93cde
https://github.com/scummvm/scummvm/commit/22e76f838ef95af61bf82acef33ad4f27bd93cde
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:47+01:00
Commit Message:
AGDS: add loadNextScreen
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c085c2973ef..c2124b9df0b 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -418,10 +418,7 @@ void AGDSEngine::newGame() {
}
void AGDSEngine::tick() {
- while (!_nextScreenName.empty()) {
- Common::String nextScreenName = _nextScreenName;
- loadScreen(nextScreenName);
- }
+ loadNextScreen();
if (_dialog.tick()) {
runProcesses();
return;
@@ -1165,6 +1162,13 @@ Common::Error AGDSEngine::loadGameState(int slot) {
return Common::kNoError;
}
+void AGDSEngine::loadNextScreen() {
+ while (!_nextScreenName.empty()) {
+ Common::String nextScreenName = _nextScreenName;
+ loadScreen(nextScreenName);
+ }
+}
+
Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
auto fileName = getSaveStateName(slot);
Common::OutSaveFile *saveFile = getSaveFileManager()->openForSaving(fileName, false);
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 3f583208597..1f63e3ac684 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -128,6 +128,7 @@ public:
void resetCurrentScreen();
void loadScreen(const Common::String & name, bool savePatch = true);
+ void loadNextScreen();
void saveScreenPatch();
RegionPtr loadRegion(const Common::String &name);
Commit: ca13c06fcc9bd64be2a30a2c9f6f9b7e09536ff8
https://github.com/scummvm/scummvm/commit/ca13c06fcc9bd64be2a30a2c9f6f9b7e09536ff8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:47+01:00
Commit Message:
AGDS: improve screen history support, add support for loading type flag
Changed paths:
A engines/agds/screenLoadingType.h
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/patch.cpp
engines/agds/patch.h
engines/agds/process.cpp
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c2124b9df0b..1917db470ff 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -54,8 +54,8 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_mjpgPlayer(), _filmStarted(0),
_currentScreen(), _loadingScreen(false),
_currentCharacter(),
- _navigatedToPreviousScreen(false),
_defaultMouseCursor(),
+ _nextScreenType(ScreenLoadingType::Normal),
_mouse(400, 300),
_userEnabled(true), _systemUserEnabled(true),
_currentRegion(),
@@ -165,7 +165,7 @@ bool AGDSEngine::load() {
return false;
initSystemVariables();
- _nextScreenName = "main";
+ setNextScreenName("main", ScreenLoadingType::Normal);
{
Common::File file;
@@ -303,10 +303,6 @@ void AGDSEngine::saveScreenPatch() {
if (!patch)
patch = PatchPtr(new Patch());
_currentScreen->save(patch);
- if (!_previousScreenName.empty()) {
- patch->prevScreenName = _previousScreenName;
- patch->hasPreviousScreen = 1;
- }
patch->characterPresent = _currentCharacter != nullptr;
if (_currentCharacter) {
patch->characterPosition = _currentCharacter->position();
@@ -316,16 +312,16 @@ void AGDSEngine::saveScreenPatch() {
}
-void AGDSEngine::loadScreen(const Common::String &name, bool savePatch) {
+void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadingType, bool savePatch) {
_loadingScreen = true;
- _nextScreenName.clear();
- debug("loadScreen %s [return to previous: %d, save patch: %d]", name.c_str(), _navigatedToPreviousScreen, savePatch);
+ debug("loadScreen %s [type: %d, save patch: %d, previous: %s]", name.c_str(), static_cast<int>(loadingType), savePatch, _currentScreenName.c_str());
if (savePatch)
saveScreenPatch();
returnCurrentInventoryObject();
_inventory.enable(false);
_mouseMap.hideAll(this);
+ auto previousScreenName = _currentScreenName;
resetCurrentScreen();
for(uint i = 0; i < _processes.size(); ++i) {
_processes[i].reset();
@@ -337,7 +333,7 @@ void AGDSEngine::loadScreen(const Common::String &name, bool savePatch) {
bool doPatch = patch;
_currentScreenName = name;
- _currentScreen = new Screen(this, screenObject);
+ _currentScreen = new Screen(this, screenObject, loadingType, previousScreenName);
if (doPatch)
screenObject->allowInitialise(false);
@@ -351,20 +347,12 @@ void AGDSEngine::loadScreen(const Common::String &name, bool savePatch) {
}
if (!patch->defaultMouseCursor.empty())
loadDefaultMouseCursor(patch->defaultMouseCursor);
- if (patch->hasPreviousScreen && !patch->prevScreenName.empty()) {
- debug("setting previous screen name to %s (from patch)", patch->prevScreenName.c_str());
- _previousScreenName = patch->prevScreenName;
- }
}
reAddInventory();
- _navigatedToPreviousScreen = false;
_loadingScreen = false;
}
void AGDSEngine::resetCurrentScreen() {
- debug("setting previous screen name to %s", _currentScreenName.c_str());
- _previousScreenName = _currentScreenName;
-
if (_currentRegion) {
_currentRegion->hide(this);
_currentRegion = NULL;
@@ -1138,7 +1126,7 @@ Common::Error AGDSEngine::loadGameState(int slot) {
runObject(initVar->getString());
loadPatches(saveFile, db);
- loadScreen(screenName, false);
+ loadScreen(screenName, ScreenLoadingType::Normal, false);
{
// Saved ambient sound
@@ -1165,7 +1153,10 @@ Common::Error AGDSEngine::loadGameState(int slot) {
void AGDSEngine::loadNextScreen() {
while (!_nextScreenName.empty()) {
Common::String nextScreenName = _nextScreenName;
- loadScreen(nextScreenName);
+ auto nextScreenType = _nextScreenType;
+ _nextScreenName.clear();
+ _nextScreenType = ScreenLoadingType::Normal;
+ loadScreen(nextScreenName, nextScreenType);
}
}
@@ -1176,7 +1167,10 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
if (!saveFile)
return Common::kWritingFailed;
- saveScreenPatch();
+ while(_currentScreen && _currentScreen->loadingType() == ScreenLoadingType::SaveOrLoad) {
+ returnToPreviousScreen();
+ loadNextScreen();
+ }
Common::HashMap<Common::String, Common::Array<uint8>> entries;
@@ -1207,8 +1201,8 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
{
Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
- writeString(&stream, _previousScreenName);
- debug("saving screen name: %s", _previousScreenName.c_str());
+ writeString(&stream, _currentScreenName);
+ debug("saving screen name: %s", _currentScreenName.c_str());
char palette[0x300];
memset(palette, 0xaa, sizeof(palette));
stream.write(palette, sizeof(palette));
@@ -1322,17 +1316,18 @@ void AGDSEngine::returnCurrentInventoryObject() {
runObject(object);
}
-void AGDSEngine::setNextScreenName(const Common::String &nextScreenName) {
- _navigatedToPreviousScreen = false;
+void AGDSEngine::setNextScreenName(const Common::String &nextScreenName, ScreenLoadingType type) {
+ debug("setNextScreenName %s:%d", nextScreenName.c_str(), static_cast<int>(type));
_nextScreenName = nextScreenName;
+ _nextScreenType = type;
}
void AGDSEngine::returnToPreviousScreen() {
- debug("returnToPreviousScreen, previous screen: %s", _previousScreenName.c_str());
- if (!_previousScreenName.empty()) {
- _navigatedToPreviousScreen = true;
- _nextScreenName = _previousScreenName;
- _previousScreenName.clear();
+ auto previousScreenName = _currentScreen? _currentScreen->getPreviousScreenName(): Common::String();
+ debug("returnToPreviousScreen from %s, previous screen: %s", _currentScreenName.c_str(), previousScreenName.c_str());
+ if (!previousScreenName.empty()) {
+ _nextScreenName = previousScreenName;
+ _nextScreenType = ScreenLoadingType::Previous;
}
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 1f63e3ac684..49bf1606da6 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -127,7 +127,7 @@ public:
void reactivate(const Common::String &name, bool runNow = false);
void resetCurrentScreen();
- void loadScreen(const Common::String & name, bool savePatch = true);
+ void loadScreen(const Common::String & name, ScreenLoadingType type, bool savePatch = true);
void loadNextScreen();
void saveScreenPatch();
@@ -225,7 +225,7 @@ public:
void initSystemVariables();
SystemVariable *getSystemVariable(const Common::String &name);
- void setNextScreenName(const Common::String &nextScreenName);
+ void setNextScreenName(const Common::String &nextScreenName, ScreenLoadingType type);
void returnToPreviousScreen();
void runDialog(const Common::String &dialogParentProcess, const Common::String &dialogProcess) {
@@ -319,9 +319,8 @@ private:
Character * _jokes;
Common::String _currentCharacterName, _currentCharacterFilename, _currentCharacterObject;
Common::String _nextScreenName;
- Common::String _previousScreenName;
+ ScreenLoadingType _nextScreenType;
Common::String _defaultMouseCursorName;
- bool _navigatedToPreviousScreen;
Animation * _defaultMouseCursor;
Common::Point _mouse;
MouseRegion * _currentRegion;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 5ea4a2a8fcd..02705cadb8b 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -98,7 +98,7 @@ enum Opcode {
kScreenCloneObject = 77,
kScreenRemoveObject = 78,
kSetNextScreen = 79,
- kSetNextScreen2 = 80,
+ kSetNextScreenSaveOrLoad = 80,
kStub82 = 82,
kStub83 = 83,
kStub84 = 84,
@@ -356,7 +356,7 @@ enum Opcode {
OP(kScreenLoadRegion, loadScreenRegion) \
OP(kScreenCloneObject, cloneObject) \
OP(kSetNextScreen, setNextScreen) \
- OP(kSetNextScreen2, setNextScreen2) \
+ OP(kSetNextScreenSaveOrLoad, setNextScreenSaveOrLoad) \
OP(kScreenRemoveObject, removeScreenObject) \
OP(kLoadAnimation, loadAnimation) \
OP(kLoadSample, loadSample) \
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index df928b55238..a26ee51cbeb 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -25,7 +25,7 @@ void Patch::load(Common::ReadStream *stream) {
if (extended == 0)
return;
- hasPreviousScreen = stream->readUint32LE();
+ loadingType = static_cast<ScreenLoadingType>(stream->readUint32LE());
characterPosition.x = stream->readUint32LE();
characterPosition.y = stream->readUint32LE();
characterDirection = stream->readUint32LE();
@@ -56,7 +56,7 @@ void Patch::save(Common::WriteStream *stream) {
if (extended == 0)
return;
- stream->writeUint32LE(hasPreviousScreen);
+ stream->writeUint32LE(static_cast<uint>(loadingType));
stream->writeUint32LE(characterPosition.x);
stream->writeUint32LE(characterPosition.y);
stream->writeUint32LE(characterDirection);
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index 4004515104d..65a2f53bf8d 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -27,6 +27,7 @@
#include "common/array.h"
#include "common/rect.h"
#include "common/str.h"
+#include "agds/screenLoadingType.h"
namespace Common { class ReadStream; class WriteStream; }
@@ -56,7 +57,7 @@ struct Patch {
Common::String screenRegionName;
Common::String prevScreenName;
- uint hasPreviousScreen = 0;
+ ScreenLoadingType loadingType = ScreenLoadingType::Normal;
Common::Point characterPosition;
uint characterDirection = 0;
bool characterPresent = false;
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 4a5f919e593..73ac91841c8 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -183,9 +183,9 @@ void Process::run() {
_engine->runDialog(getName(), getExitArg1());
break;
case kExitCodeSetNextScreen:
- case kExitCodeSetNextScreen2:
- debug("process %s launches screen: %s", getName().c_str(), getExitArg1().c_str());
- _engine->setNextScreenName(getExitArg1());
+ case kExitCodeSetNextScreenSaveOrLoad:
+ debug("process %s launches screen: %s, saveorload: ", getName().c_str(), getExitArg1().c_str(), code == kExitCodeSetNextScreenSaveOrLoad);
+ _engine->setNextScreenName(getExitArg1(), code == kExitCodeSetNextScreenSaveOrLoad? ScreenLoadingType::SaveOrLoad: ScreenLoadingType::Normal);
done();
break;
case kExitCodeMouseAreaChange:
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index 3c55d124f6f..ce16a83f7bb 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -29,7 +29,7 @@ namespace AGDS {
kExitCodeDestroy = 2,
kExitCodeSuspend = 5,
kExitCodeSetNextScreen = 6,
- kExitCodeSetNextScreen2 = 7,
+ kExitCodeSetNextScreenSaveOrLoad = 7,
kExitCodeLoadScreenObject = 8,
kExitCodeLoadScreenObjectAs = 9,
kExitCodeLoadInventoryObject = 10,
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f4d5ab3dc91..97ad69cbf8a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1261,10 +1261,10 @@ void Process::setNextScreen() {
suspend(kExitCodeSetNextScreen, name);
}
-void Process::setNextScreen2() {
+void Process::setNextScreenSaveOrLoad() {
Common::String name = popString();
- debug("exitProcessSetNextScreen2 %s", name.c_str());
- suspend(kExitCodeSetNextScreen2, name);
+ debug("exitProcessSetNextScreenSaveOrLoad %s", name.c_str());
+ suspend(kExitCodeSetNextScreenSaveOrLoad, name);
}
void Process::loadPreviousScreen() {
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index faebdd2ed46..c889ba864ac 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -39,7 +39,8 @@ int Screen::AnimationZCompare(const Animation *a, const Animation *b) {
return b->z() - a->z();
}
-Screen::Screen(AGDSEngine * engine, ObjectPtr object) : _engine(engine), _object(object), _name(object->getName()),
+Screen::Screen(AGDSEngine * engine, ObjectPtr object, ScreenLoadingType loadingType, const Common::String &prevScreen) :
+ _engine(engine), _object(object), _name(object->getName()), _loadingType(loadingType), _previousScreen(prevScreen),
_children(&ObjectZCompare), _animations(&AnimationZCompare), _applyingPatch(false),
_characterNear(g_system->getHeight()), _characterFar(g_system->getHeight()) {
add(object);
@@ -242,10 +243,15 @@ void Screen::load(const PatchPtr &patch) {
else
_engine->runObject(object.name, Common::String(), false);
}
+ _loadingType = patch->loadingType;
+ if (!patch->prevScreenName.empty())
+ _previousScreen = patch->prevScreenName;
_applyingPatch = false;
}
void Screen::save(const PatchPtr &patch) {
+ patch->prevScreenName = _previousScreen;
+ patch->loadingType = _loadingType;
patch->objects.clear();
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 76682cc4bfd..6682ed19736 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -28,6 +28,7 @@
#include "common/ptr.h"
#include "common/str.h"
#include "common/rect.h"
+#include "agds/screenLoadingType.h"
namespace Graphics {
struct Surface;
@@ -54,6 +55,8 @@ class Screen {
AGDSEngine * _engine;
ObjectPtr _object;
Common::String _name;
+ ScreenLoadingType _loadingType;
+ Common::String _previousScreen;
ChildrenType _children;
AnimationsType _animations;
RegionPtr _region;
@@ -69,7 +72,7 @@ public:
KeyHandler(Object *o, uint i): object(o), ip(i) { }
};
- Screen(AGDSEngine *engine, ObjectPtr object);
+ Screen(AGDSEngine *engine, ObjectPtr object, ScreenLoadingType loadingType, const Common::String &prevScreen);
~Screen();
void setCharacterNearFar(int near, int far) {
@@ -91,6 +94,14 @@ public:
return _name;
}
+ const Common::String &getPreviousScreenName() const {
+ return _previousScreen;
+ }
+
+ ScreenLoadingType loadingType() const {
+ return _loadingType;
+ }
+
RegionPtr region() const {
return _region;
}
diff --git a/engines/agds/screenLoadingType.h b/engines/agds/screenLoadingType.h
new file mode 100644
index 00000000000..1cb1498b6ed
--- /dev/null
+++ b/engines/agds/screenLoadingType.h
@@ -0,0 +1,36 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef AGDS_SCREEN_LOADING_TYPE_H
+#define AGDS_SCREEN_LOADING_TYPE_H
+
+namespace AGDS {
+
+enum struct ScreenLoadingType {
+ Normal = 0,
+ SaveOrLoad = 1,
+ Previous = 2
+};
+
+}
+
+#endif
Commit: 1e4cccf7cd000f46c52de792a79380d835bbcaa6
https://github.com/scummvm/scummvm/commit/1e4cccf7cd000f46c52de792a79380d835bbcaa6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:47+01:00
Commit Message:
AGDS: add shl/shr
Changed paths:
engines/agds/opcode.h
engines/agds/process.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 02705cadb8b..7ec774f264f 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -56,8 +56,8 @@ enum Opcode {
kOr = 34,
kXor = 35,
kNot = 36,
- kStub37 = 37,
- kStub38 = 38,
+ kShl = 37,
+ kShr = 38,
kBoolAnd = 39,
kBoolOr = 40,
kBoolNot = 41,
@@ -311,6 +311,8 @@ enum Opcode {
OP(kOr, bitOr) \
OP(kXor, bitXor) \
OP(kNot, bitNot) \
+ OP(kShl, shl) \
+ OP(kShr, shr) \
OP(kBoolNot, boolNot) \
OP(kNegate, negate) \
OP_U(kObjectInitialise, initialise) \
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 73ac91841c8..2ea54fd2bce 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -238,6 +238,8 @@ void Process::run() {
UNARY_OP(boolNot, !)
UNARY_OP(bitNot, ~)
UNARY_OP(negate, -)
+ BINARY_OP(shl, <<)
+ BINARY_OP(shr, >>)
BINARY_OP(boolOr, ||)
BINARY_OP(boolAnd, &&)
BINARY_OP(equals, ==)
Commit: 9917dda3fd8bd8c03a79e0e476e12f4aba38a585
https://github.com/scummvm/scummvm/commit/9917dda3fd8bd8c03a79e0e476e12f4aba38a585
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:47+01:00
Commit Message:
AGDS: implement object patching
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 1917db470ff..26fa58a5287 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -295,6 +295,18 @@ PatchPtr AGDSEngine::createPatch(const Common::String &screenName) {
return patch;
}
+ObjectPatchPtr AGDSEngine::getObjectPatch(const Common::String &objectName) const {
+ auto it = _objectPatches.find(objectName);
+ return it != _objectPatches.end()? it->_value: ObjectPatchPtr();
+}
+
+ObjectPatchPtr AGDSEngine::createObjectPatch(const Common::String &objectName) {
+ auto & patch = _objectPatches[objectName];
+ if (!patch)
+ patch = ObjectPatchPtr(new ObjectPatch());
+ return patch;
+}
+
void AGDSEngine::saveScreenPatch() {
if (!_currentScreen || _currentScreenName.empty())
return;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 49bf1606da6..a82cb6508eb 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -268,6 +268,8 @@ public:
void reAddInventory();
PatchPtr getPatch(const Common::String &screenName) const;
PatchPtr createPatch(const Common::String &screenName);
+ ObjectPatchPtr getObjectPatch(const Common::String &screenName) const;
+ ObjectPatchPtr createObjectPatch(const Common::String &screenName);
void shadowIntensity(int intensity) {
_shadowIntensity = intensity;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 7ec774f264f..99488e8b5f1 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -99,16 +99,16 @@ enum Opcode {
kScreenRemoveObject = 78,
kSetNextScreen = 79,
kSetNextScreenSaveOrLoad = 80,
- kStub82 = 82,
- kStub83 = 83,
- kStub84 = 84,
+ kObjectPatchSetText = 82,
+ kObjectPatchSetRegionName = 83,
+ kScreenPatchSetRegionName = 84,
kLoadCharacter = 85,
- kStub86 = 86,
- kStub87 = 87,
+ kUnloadCharacter = 86,
+ kAssociateCharacter = 87,
kAnimateCharacter = 88,
kHideCharacter = 89,
kShowCharacter = 90,
- kStub91 = 91,
+ kDisableCharacter = 91,
kEnableCharacter = 92,
kMoveCharacterUserMove = 93,
kLeaveCharacter = 94,
@@ -345,8 +345,8 @@ enum Opcode {
OP(kInventoryAddObject, inventoryAddObject) \
OP(kInventoryRemoveObject, inventoryRemoveObject) \
OP_U(kObjectRegisterUseObjectHandler, onObjectUse) \
- OP(kStub82, stub82) \
- OP(kStub83, stub83) \
+ OP(kObjectPatchSetText, objectPatchSetText) \
+ OP(kObjectPatchSetRegionName, objectPatchSetRegionName) \
OP(kAnimateCharacter, animateCharacter) \
OP(kLoadCharacter, loadCharacter) \
OP(kSetObjectZ, setObjectZ) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 97ad69cbf8a..a500d6f58c8 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -631,18 +631,6 @@ void Process::setPeriodic() {
_samplePeriodic = value;
}
-void Process::stub82() {
- Common::String arg2 = popString();
- Common::String arg1 = popString();
- debug("stub82: %s %s", arg1.c_str(), arg2.c_str());
-}
-
-void Process::stub83() {
- Common::String arg2 = popString();
- Common::String arg1 = popString();
- debug("stub83: %s %s", arg1.c_str(), arg2.c_str());
-}
-
void Process::stub102() {
Common::String name = popString();
debug("stub102: load picture? %s", name.c_str());
@@ -706,6 +694,34 @@ void Process::compareScreenName() {
push(name == currentScreenName? 1: 0);
}
+void Process::objectPatchSetText() {
+ Common::String resource = popString();
+ Common::String objectName = popString();
+ debug("objectPatchSetText: %s %s", objectName.c_str(), resource.c_str());
+ auto text = _engine->loadText(resource);
+
+ auto object = _engine->getCurrentScreenObject(objectName);
+ if (object) {
+ object->title(text);
+ }
+ auto patch = _engine->createObjectPatch(objectName);
+ patch->text = text;
+}
+
+void Process::objectPatchSetRegionName() {
+ Common::String regionName = popString();
+ Common::String objectName = popString();
+ debug("objectPatchSetRegionName: %s %s", objectName.c_str(), regionName.c_str());
+ auto object = _engine->getCurrentScreenObject(objectName);
+ if (object) {
+ RegionPtr region = _engine->loadRegion(regionName);
+ debug("region: %s", region->toString().c_str());
+ object->region(region);
+ }
+ auto patch = _engine->createObjectPatch(objectName);
+ patch->region = regionName;
+}
+
void Process::screenObjectPatchIncRef() {
Common::String objectName = popString();
Common::String screenName = popString();
Commit: 98e5241213081635e6918367be837082c1ee0353
https://github.com/scummvm/scummvm/commit/98e5241213081635e6918367be837082c1ee0353
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:47+01:00
Commit Message:
AGDS: add missing return
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index d25665ba3f7..81b132dd3dc 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -135,6 +135,7 @@ void Character::direction(int dir) {
debug("no animation?");
_phase = -1;
_frames = 0;
+ return;
}
_animation->rewind();
}
Commit: 1ae8612b37486f88f44ac3d515f2b05fb5700f0b
https://github.com/scummvm/scummvm/commit/1ae8612b37486f88f44ac3d515f2b05fb5700f0b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:47+01:00
Commit Message:
AGDS: moar logs
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 26fa58a5287..d217fb98861 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1165,6 +1165,7 @@ Common::Error AGDSEngine::loadGameState(int slot) {
void AGDSEngine::loadNextScreen() {
while (!_nextScreenName.empty()) {
Common::String nextScreenName = _nextScreenName;
+ debug("loadNextScreen %s", nextScreenName.c_str());
auto nextScreenType = _nextScreenType;
_nextScreenName.clear();
_nextScreenType = ScreenLoadingType::Normal;
@@ -1173,6 +1174,7 @@ void AGDSEngine::loadNextScreen() {
}
Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
+ debug("saveGameState %d %s autosave: %d", slot, desc.c_str(), isAutosave);
auto fileName = getSaveStateName(slot);
Common::OutSaveFile *saveFile = getSaveFileManager()->openForSaving(fileName, false);
Commit: a7f20788197b47ca53ad24c1fe625afa72379305
https://github.com/scummvm/scummvm/commit/a7f20788197b47ca53ad24c1fe625afa72379305
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:47+01:00
Commit Message:
AGDS: do not load patch for save/load type of the screens
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index d217fb98861..a8a4fc0a394 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -341,10 +341,10 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
_animations.clear();
auto patch = getPatch(name);
- auto screenObject = loadObject(name);
- bool doPatch = patch;
+ bool doPatch = patch && loadingType != ScreenLoadingType::SaveOrLoad;
_currentScreenName = name;
+ auto screenObject = loadObject(name);
_currentScreen = new Screen(this, screenObject, loadingType, previousScreenName);
if (doPatch)
screenObject->allowInitialise(false);
Commit: b1839522b629b4b245a49eb7de420fc9525d4281
https://github.com/scummvm/scummvm/commit/b1839522b629b4b245a49eb7de420fc9525d4281
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:47+01:00
Commit Message:
AGDS: pass final direction to stopCharacter()
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index a500d6f58c8..de5d822843e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1531,13 +1531,17 @@ void Process::getCharacterY() {
}
void Process::stopCharacter() {
- int arg = pop();
+ int direction = pop();
Common::String name = popString();
- debug("stopCharacter: stub %s %d", name.c_str(), arg);
+ debug("stopCharacter: %s, direction: %d", name.c_str(), direction);
Character *character = _engine->getCharacter(name);
- if (character)
+ if (character) {
+ if (direction != -1) {
+ character->direction(direction);
+ debug("no suspend here, stub");
+ }
character->stop();
- else
+ } else
warning("could not find character %s", name.c_str());
}
Commit: c47532ddedc4f600fe5d170040d3756fb84116b8
https://github.com/scummvm/scummvm/commit/c47532ddedc4f600fe5d170040d3756fb84116b8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:48+01:00
Commit Message:
AGDS: reactivate process started by animate/move/dialog
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
engines/agds/process_opcodes.cpp
engines/agds/textLayout.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 81b132dd3dc..e8740e41756 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -140,14 +140,16 @@ void Character::direction(int dir) {
_animation->rewind();
}
-void Character::moveTo(Common::Point dst, int dir) {
+void Character::moveTo(const Common::String & processName, Common::Point dst, int dir) {
debug("character move %d,%d %d", dst.x, dst.y, dir);
+ _processName = processName;
_pos = dst;
direction(dir);
}
-void Character::animate(Common::Point pos, int direction, int speed) {
+void Character::animate(const Common::String & processName, Common::Point pos, int direction, int speed) {
debug("animate character: %d,%d %d %d", pos.x, pos.y, direction, speed);
+ _processName = processName;
if (direction == -1)
return;
auto jokes = _engine->jokes();
@@ -162,10 +164,18 @@ void Character::animate(Common::Point pos, int direction, int speed) {
_animation->speed(speed);
_animation->rewind();
_phase = 0;
- _frames = (100 * _animation->frames() + speed - 1) / speed;
+ _frames = _animation->frames();
_animationPos = pos;
+ debug("character animation frames: %d, enabled: %d, visible: %d", _frames, _enabled, _visible);
}
+void Character::stop() {
+ debug("character %s: stop", _object->getName().c_str());
+ _phase = -1;
+ _frames = 0;
+}
+
+
void Character::paint(Graphics::Surface &backbuffer) {
if (!_enabled || !_visible || !_animation)
return;
@@ -176,15 +186,16 @@ void Character::paint(Graphics::Surface &backbuffer) {
auto scale = screen? screen->getZScale(_pos.y): 1;
_animation->scale(scale);
+ debug("character %d/%d", _phase, _frames);
if (_phase >= 0 && _phase < _frames) {
_animation->tick();
- if (_phase + 1 >= _frames) {
+ _phase = _animation->phase();
+ if (_phase >= _frames) {
_phase = -1;
_frames = 0;
- } else {
- ++_phase;
}
}
+ _engine->reactivate(_processName, true);
pos.y -= _animation->height();
pos.x -= _animation->width() / 2;
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 00008d103de..46516ac9f9f 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -34,7 +34,6 @@ namespace Graphics { struct Surface; }
namespace AGDS {
class AGDSEngine;
-class Process;
class Object;
typedef Common::SharedPtr<Object> ObjectPtr;
class Animation;
@@ -44,6 +43,7 @@ class Character {
ObjectPtr _object;
Animation * _animation;
Common::String _name;
+ Common::String _processName;
Common::Point _pos;
Common::Point _animationPos;
bool _enabled;
@@ -94,12 +94,9 @@ public:
_visible = visible;
}
- void animate(Common::Point pos, int direction, int speed);
+ void animate(const Common::String &processName, Common::Point pos, int direction, int speed);
- void stop() {
- _phase = -1;
- _frames = 0;
- }
+ void stop();
int getPhase() const {
return _phase;
@@ -113,7 +110,7 @@ public:
return _pos;
}
- void moveTo(Common::Point dst, int direction);
+ void moveTo(const Common::String &processName, Common::Point dst, int direction);
void direction(int dir);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index de5d822843e..403e4311af4 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1407,7 +1407,7 @@ void Process::moveCharacter(bool usermove) {
if (character) {
auto region = _engine->loadRegion(regionName);
if (region) {
- character->moveTo(region->center, direction);
+ character->moveTo(_object->getName(), region->center, direction);
}
} else
warning("character %s could not be found", id.c_str());
@@ -1430,7 +1430,7 @@ void Process::animateCharacter() {
Character *character = _engine->getCharacter(name);
if (character)
- character->animate(_animationPosition, direction, _animationSpeed);
+ character->animate(_object->getName(), _animationPosition, direction, _animationSpeed);
else
warning("character %s could not be found", name.c_str());
}
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 5b7bea7f287..2ebc7aa0820 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -102,7 +102,7 @@ void TextLayout::layout(AGDSEngine &engine, const Common::String &process, const
case 15:
break;
default:
- character->animate(Common::Point(), character->direction(), 100);
+ character->animate(_process, Common::Point(), character->direction(), 100);
}
}
} else
Commit: 4bf629106dc5980390f146333c22c6cc26178570
https://github.com/scummvm/scummvm/commit/4bf629106dc5980390f146333c22c6cc26178570
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:48+01:00
Commit Message:
AGDS: store text resource in patch, not text itself
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 403e4311af4..6959b9dfe8f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -705,7 +705,7 @@ void Process::objectPatchSetText() {
object->title(text);
}
auto patch = _engine->createObjectPatch(objectName);
- patch->text = text;
+ patch->text = resource;
}
void Process::objectPatchSetRegionName() {
Commit: 88d1daa8c0707ecdd51f98cde09da162f634a5f6
https://github.com/scummvm/scummvm/commit/88d1daa8c0707ecdd51f98cde09da162f634a5f6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:48+01:00
Commit Message:
AGDS: fixed animation rewinding
Changed paths:
engines/agds/animation.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index aabf5baa135..9c0ce010bf2 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -67,6 +67,9 @@ public:
int frames() const {
return _frames;
}
+ bool ended() const {
+ return _phase >= _frames;
+ }
const Common::Point & position() const {
return _position;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 6959b9dfe8f..96a6fedc36f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -978,7 +978,8 @@ void Process::restartAnimation() {
}
Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
if (animation) {
- if (_engine->getGlobal(phaseVar) == -1 && !animation->paused()) {
+ if ((_engine->getGlobal(phaseVar) == -1 && !animation->paused()) || animation->ended()) {
+ debug("restartAnimation: rewind");
animation->rewind();
}
animation->resume();
Commit: bb18f9e001dd4a00fca687635e4929485e38586d
https://github.com/scummvm/scummvm/commit/bb18f9e001dd4a00fca687635e4929485e38586d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:48+01:00
Commit Message:
AGDS: remove spam from char tick
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index e8740e41756..15dc1f9cd80 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -186,7 +186,7 @@ void Character::paint(Graphics::Surface &backbuffer) {
auto scale = screen? screen->getZScale(_pos.y): 1;
_animation->scale(scale);
- debug("character %d/%d", _phase, _frames);
+ // debug("character %d/%d", _phase, _frames);
if (_phase >= 0 && _phase < _frames) {
_animation->tick();
_phase = _animation->phase();
Commit: 87e785356690b8f42e6c1d672da677b56ae83fe3
https://github.com/scummvm/scummvm/commit/87e785356690b8f42e6c1d672da677b56ae83fe3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:48+01:00
Commit Message:
AGDS: screen.add skips null
Changed paths:
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index c889ba864ac..70a2452c705 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -86,6 +86,14 @@ bool Screen::add(ObjectPtr object) {
return true;
}
+void Screen::add(Animation * animation) {
+ if (animation)
+ _animations.insert(animation);
+ else
+ warning("Screen: skipping null animation");
+}
+
+
bool Screen::remove(Animation * animation) {
bool removed = false;
for(auto i = _animations.begin(); i != _animations.end(); ) {
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 6682ed19736..7f05f60d423 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -119,9 +119,7 @@ public:
}
bool add(ObjectPtr object);
- void add(Animation * animation) {
- _animations.insert(animation);
- }
+ void add(Animation * animation);
bool remove(Animation * animation);
void update(const ObjectPtr &object) {
Commit: dae8d57630a45e0324c652531ac5d38e3d552819
https://github.com/scummvm/scummvm/commit/dae8d57630a45e0324c652531ac5d38e3d552819
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:48+01:00
Commit Message:
AGDS: initialise Inventory::_visible in ctor
Changed paths:
engines/agds/inventory.cpp
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 1a060c13e7d..fe7de9f29cd 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -30,7 +30,7 @@
namespace AGDS {
-Inventory::Inventory(AGDSEngine* engine): _engine(engine), _entries(kMaxSize), _enabled(false) {}
+Inventory::Inventory(AGDSEngine* engine): _engine(engine), _entries(kMaxSize), _enabled(false), _visible(false) {}
Inventory::~Inventory() {}
int Inventory::free() const {
Commit: 71443b8d4e95acbbed2b06c6282633476fdad559
https://github.com/scummvm/scummvm/commit/71443b8d4e95acbbed2b06c6282633476fdad559
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:48+01:00
Commit Message:
AGDS: save process on stack, so loadScreen doesn't destroy current process
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index a8a4fc0a394..cd7cd8d4b48 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -378,7 +378,7 @@ void AGDSEngine::resetCurrentScreen() {
void AGDSEngine::runProcesses() {
for (uint i = 0; i < _processes.size(); ++i) {
- ProcessPtr &process = _processes[i];
+ ProcessPtr process = _processes[i];
if (!process)
continue;
@@ -387,7 +387,7 @@ void AGDSEngine::runProcesses() {
}
if (process->finished()) {
debug("deleting process %s", process->getName().c_str());
- process.reset();
+ _processes[i].reset();
//FIXME: when the last process exits, remove object from scene
} else {
//debug("suspended process %s", process->getName().c_str());
Commit: e2d8c7ba9ce5a5a956136281accf5f9ced4cd10d
https://github.com/scummvm/scummvm/commit/e2d8c7ba9ce5a5a956136281accf5f9ced4cd10d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:48+01:00
Commit Message:
AGDS: constify Object/Animation::paint
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/object.cpp
engines/agds/object.h
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 640de00a085..cc6c6ded70c 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -167,7 +167,7 @@ bool Animation::tick() {
return true;
}
-void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst) {
+void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst) const {
dst += _position;
if (_frame) {
Common::Rect srcRect = _frame->getRect();
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 9c0ce010bf2..e37cc604cac 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -150,7 +150,7 @@ public:
}
bool load(Common::SeekableReadStream *stream, const Common::String &fname);
- void paint(Graphics::Surface & backbuffer, Common::Point dst);
+ void paint(Graphics::Surface & backbuffer, Common::Point dst) const;
int width() const;
int height() const;
bool tick();
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 8e85edd8e21..5902a8dc551 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -244,7 +244,7 @@ bool Object::pointIn(Common::Point pos) {
return false;
}
-void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
+void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) const {
auto picture = getPicture();
if (picture) {
Common::Point dst = getPosition();
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 0187c93d61d..131b6f11692 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -220,7 +220,7 @@ public:
return _userUseHandler;
}
- void paint(AGDSEngine &engine, Graphics::Surface &backbuffer);
+ void paint(AGDSEngine &engine, Graphics::Surface &backbuffer) const;
void moveTo(Common::Point pos);
Commit: 45f48d4aec83fcd24e8c830845ad5ca8ca4087df
https://github.com/scummvm/scummvm/commit/45f48d4aec83fcd24e8c830845ad5ca8ca4087df
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:48+01:00
Commit Message:
AGDS: split tick/paint for Character (made paint immutable)
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
engines/agds/screen.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 15dc1f9cd80..737ca057e09 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -175,13 +175,10 @@ void Character::stop() {
_frames = 0;
}
-
-void Character::paint(Graphics::Surface &backbuffer) {
+void Character::tick() {
if (!_enabled || !_visible || !_animation)
return;
- Common::Point pos = _pos + _animationPos;
-
auto screen = _engine->getCurrentScreen();
auto scale = screen? screen->getZScale(_pos.y): 1;
_animation->scale(scale);
@@ -196,6 +193,14 @@ void Character::paint(Graphics::Surface &backbuffer) {
}
}
_engine->reactivate(_processName, true);
+}
+
+
+void Character::paint(Graphics::Surface &backbuffer) const {
+ if (!_enabled || !_visible || !_animation)
+ return;
+
+ Common::Point pos = _pos + _animationPos;
pos.y -= _animation->height();
pos.x -= _animation->width() / 2;
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 46516ac9f9f..73322062f11 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -118,7 +118,8 @@ public:
return _direction;
}
- void paint(Graphics::Surface & backbuffer);
+ void tick();
+ void paint(Graphics::Surface & backbuffer) const;
int getDirectionForMovement(Common::Point delta);
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 70a2452c705..980475cca6d 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -158,6 +158,9 @@ void Screen::paint(Graphics::Surface &backbuffer) {
}
Character * character = _engine->currentCharacter();
+ if (character)
+ character->tick();
+
ChildrenType::iterator child = _children.begin();
AnimationsType::iterator animation = _animations.begin();
while(child != _children.end() || animation != _animations.end() || character) {
Commit: 8c7975d3eecfe4360df15aa03971db3701e722ba
https://github.com/scummvm/scummvm/commit/8c7975d3eecfe4360df15aa03971db3701e722ba
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:48+01:00
Commit Message:
AGDS: fix enable/disable inventory flags
Changed paths:
engines/agds/agds.cpp
engines/agds/inventory.cpp
engines/agds/inventory.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index cd7cd8d4b48..b901b204713 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -330,7 +330,7 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
if (savePatch)
saveScreenPatch();
returnCurrentInventoryObject();
- _inventory.enable(false);
+ _inventory.visible(false);
_mouseMap.hideAll(this);
auto previousScreenName = _currentScreenName;
@@ -553,7 +553,7 @@ Common::Error AGDSEngine::run() {
region->show(this);
}
}
- _inventory.enable(_inventoryRegion ? !_mouseMap.disabled() && _inventoryRegion->pointIn(_mouse) : false);
+ _inventory.visible(_inventoryRegion ? !_mouseMap.disabled() && _inventoryRegion->pointIn(_mouse) : false);
}
break;
case Common::EVENT_LBUTTONDOWN:
@@ -911,7 +911,7 @@ void AGDSEngine::addSystemVar(const Common::String &name, SystemVariable *var) {
void AGDSEngine::tell(Process &process, const Common::String ®ionName, Common::String text, Common::String sound, bool npc) {
if (getSystemVariable("tell_close_inv")->getInteger())
- _inventory.enable(false);
+ _inventory.visible(false);
int font_id = getSystemVariable(npc? "npc_tell_font": "tell_font")->getInteger();
Common::Point pos;
@@ -994,20 +994,6 @@ SystemVariable *AGDSEngine::getSystemVariable(const Common::String &name) {
}
void AGDSEngine::tickInventory() {
- if (!_inventory.enabled() && _inventory.visible()) {
- debug("closing inventory...");
- Common::String inv_close = getSystemVariable("inv_close")->getString();
- if (!inv_close.empty())
- runObject(inv_close);
- _inventory.visible(false);
- } else if (_inventory.enabled() && !_inventory.visible()) {
- debug("opening inventory...");
- Common::String inv_open = getSystemVariable("inv_open")->getString();
- if (!inv_open.empty())
- runObject(inv_open);
- _inventory.visible(true);
- }
-
const Common::String &inv_region_name = getSystemVariable("inv_region")->getString();
if (!inv_region_name.empty()) {
if (!_inventoryRegion || _inventoryRegionName != inv_region_name) {
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index fe7de9f29cd..c34dec6b45f 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -24,6 +24,7 @@
#include "agds/object.h"
#include "agds/resourceManager.h"
#include "agds/agds.h"
+#include "agds/systemVariable.h"
#include "common/debug.h"
#include "common/textconsole.h"
#include "graphics/transparent_surface.h"
@@ -33,6 +34,25 @@ namespace AGDS {
Inventory::Inventory(AGDSEngine* engine): _engine(engine), _entries(kMaxSize), _enabled(false), _visible(false) {}
Inventory::~Inventory() {}
+void Inventory::visible(bool visible) {
+ if (_visible == visible)
+ return;
+
+ _visible = visible;
+
+ if (!_enabled || !visible) {
+ debug("closing inventory...");
+ Common::String inv_close = _engine->getSystemVariable("inv_close")->getString();
+ if (!inv_close.empty())
+ _engine->runObject(inv_close);
+ } else if (enabled() && visible) {
+ debug("opening inventory...");
+ Common::String inv_open = _engine->getSystemVariable("inv_open")->getString();
+ if (!inv_open.empty())
+ _engine->runObject(inv_open);
+ }
+}
+
int Inventory::free() const {
int free = 0;
for (uint i = 0; i < _entries.size(); ++i)
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index cf8fb3d309e..849f46e0072 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -33,6 +33,7 @@ namespace Common { class ReadStream; class WriteStream; }
namespace AGDS {
class Object;
typedef Common::SharedPtr<Object> ObjectPtr;
+class AGDSEngine;
class Inventory {
class AGDSEngine* _engine;
@@ -54,6 +55,8 @@ public:
return _enabled;
}
void enable(bool enabled) {
+ if (!enabled)
+ visible(false);
_enabled = enabled;
}
@@ -61,9 +64,7 @@ public:
return _visible;
}
- void visible(bool visible) {
- _visible = visible;
- }
+ void visible(bool visible);
int add(const ObjectPtr & object);
bool remove(const Common::String &name);
Commit: 736940aab91b357b5282b95ab5c0a1f73ea7e873
https://github.com/scummvm/scummvm/commit/736940aab91b357b5282b95ab5c0a1f73ea7e873
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:49+01:00
Commit Message:
AGDS: reverse z in Screen::find, so click will pick the top-level object
Changed paths:
engines/agds/screen.cpp
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 980475cca6d..412180a9fa3 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -217,10 +217,11 @@ void Screen::paint(Graphics::Surface &backbuffer) {
Common::Array<ObjectPtr> Screen::find(Common::Point pos) const {
Common::Array<ObjectPtr> objects;
+ objects.reserve(_children.size());
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
if (object->pointIn(pos) && object->alive()) {
- objects.push_back(object);
+ objects.insert_at(0, object);
}
}
return objects;
Commit: 89539b472f4bee4ab1f48605cf1b294eba342518
https://github.com/scummvm/scummvm/commit/89539b472f4bee4ab1f48605cf1b294eba342518
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:49+01:00
Commit Message:
AGDS: rearrange inventory/local handlers to fix their priority
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index b901b204713..cc5232887f3 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -580,6 +580,11 @@ Common::Error AGDSEngine::run() {
if (lclick) {
if (_currentInventoryObject) {
ip = object->getUseHandler(_currentInventoryObject->getName());
+ if (!ip) {
+ ip = _currentInventoryObject->useOnHandler();
+ if (ip)
+ object = _currentInventoryObject;
+ }
if (ip)
debug("found use handler for current inventory object %s", _currentInventoryObject->getName().c_str());
} else {
@@ -588,16 +593,16 @@ Common::Error AGDSEngine::run() {
debug("found click handler");
}
} else {
- ip = object->getExamineHandler();
+ if (_currentInventoryObject) {
+ ip = _currentInventoryObject->throwHandler();
+ if (ip)
+ object = _currentInventoryObject;
+ } else {
+ ip = object->getExamineHandler();
+ }
if (ip)
debug("found examine handler");
}
- if (!ip && _currentInventoryObject) {
- ip = lclick? _currentInventoryObject->useOnHandler(): _currentInventoryObject->throwHandler();
- if (ip)
- debug("found current inventory fallback action");
- object = _currentInventoryObject;
- }
if (ip) {
debug("found handler: %s %08x", object->getName().c_str(), ip + 7);
Commit: 530fa0bb48a5e5da44712f4233905d97a6334128
https://github.com/scummvm/scummvm/commit/530fa0bb48a5e5da44712f4233905d97a6334128
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:49+01:00
Commit Message:
AGDS: log allowInitialise
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index cc5232887f3..8a76153c00a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -204,7 +204,7 @@ Common::String AGDSEngine::loadText(const Common::String &entryName) {
}
ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::String &prototype, bool allowInitialise) {
- debug("loadObject %s %s", name.c_str(), prototype.c_str());
+ debug("loadObject %s %s, allow init: %d", name.c_str(), prototype.c_str(), allowInitialise);
Common::String clone = prototype.empty() ? name : prototype;
Common::SeekableReadStream *stream = _data.getEntry(clone);
if (!stream)
Commit: e6b8cd9be43090e83536d77a9458fda424e564a6
https://github.com/scummvm/scummvm/commit/e6b8cd9be43090e83536d77a9458fda424e564a6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:49+01:00
Commit Message:
AGDS: adjust x coordinate of character animation
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 737ca057e09..71196c58dd1 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -165,6 +165,7 @@ void Character::animate(const Common::String & processName, Common::Point pos, i
_animation->rewind();
_phase = 0;
_frames = _animation->frames();
+ pos.x += animationDescription->frames.empty()? 0: animationDescription->frames.front().w / 2;
_animationPos = pos;
debug("character animation frames: %d, enabled: %d, visible: %d", _frames, _enabled, _visible);
}
Commit: 2880b8ff8e2454bf0d66d3d290ff3e21f41cd080
https://github.com/scummvm/scummvm/commit/2880b8ff8e2454bf0d66d3d290ff3e21f41cd080
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:49+01:00
Commit Message:
AGDS: re-enable inventory after text ends
Changed paths:
engines/agds/textLayout.cpp
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 2ebc7aa0820..5b9a1f597bc 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -28,6 +28,7 @@ void TextLayout::reset(AGDSEngine &engine) {
engine.setGlobal(var, 0);
}
engine.reactivate(_process);
+ engine.inventory().enable(true);
}
}
Commit: 578c21bff5f8fe827d81252aaa71a67dca7d86ed
https://github.com/scummvm/scummvm/commit/578c21bff5f8fe827d81252aaa71a67dca7d86ed
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:49+01:00
Commit Message:
Revert "AGDS: adjust x coordinate of character animation"
This reverts commit 4158f798b1fbaf03aee2661cb71dbffd94251528.
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 71196c58dd1..737ca057e09 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -165,7 +165,6 @@ void Character::animate(const Common::String & processName, Common::Point pos, i
_animation->rewind();
_phase = 0;
_frames = _animation->frames();
- pos.x += animationDescription->frames.empty()? 0: animationDescription->frames.front().w / 2;
_animationPos = pos;
debug("character animation frames: %d, enabled: %d, visible: %d", _frames, _enabled, _visible);
}
Commit: 52c3a740bf5ebd2998133727ad23c246daf73efb
https://github.com/scummvm/scummvm/commit/52c3a740bf5ebd2998133727ad23c246daf73efb
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:49+01:00
Commit Message:
AGDS: store current animation description in character object
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 737ca057e09..5da1bffc52a 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -128,8 +128,8 @@ void Character::direction(int dir) {
if (dir < 0)
return;
- auto desc = animationDescription(dir);
- _animation = desc? _engine->loadAnimation(desc->filename): nullptr;
+ _description = animationDescription(dir);
+ _animation = _description? _engine->loadAnimation(_description->filename): nullptr;
_animationPos = Common::Point();
if (!_animation) {
debug("no animation?");
@@ -153,8 +153,8 @@ void Character::animate(const Common::String & processName, Common::Point pos, i
if (direction == -1)
return;
auto jokes = _engine->jokes();
- auto animationDescription = jokes->animationDescription(direction);
- _animation = animationDescription? _engine->loadAnimation(animationDescription->filename): nullptr;
+ _description = jokes->animationDescription(direction);
+ _animation = _description? _engine->loadAnimation(_description->filename): nullptr;
if (!_animation) {
warning("no jokes animation %d", direction);
_phase = -1;
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 73322062f11..4ec02046df4 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -63,6 +63,7 @@ class Character {
Common::Array<Frame> frames;
};
Common::HashMap<int, AnimationDescription> _animations;
+ const AnimationDescription * _description;
public:
Character(AGDSEngine * engine, const Common::String & name, const ObjectPtr & object):
Commit: af809cb53c22fbbadaea2a72095f7ad771aeb676
https://github.com/scummvm/scummvm/commit/af809cb53c22fbbadaea2a72095f7ad771aeb676
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:49+01:00
Commit Message:
AGDS: initialise scale member with 100
Changed paths:
engines/agds/animation.h
engines/agds/character.cpp
engines/agds/character.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index e37cc604cac..f39cc2f4b59 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -144,6 +144,9 @@ public:
void scale(float scale) {
_scale = scale;
}
+ float scale() const {
+ return _scale;
+ }
int phase() const {
return _phase;
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 5da1bffc52a..13a356b3423 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -196,11 +196,11 @@ void Character::tick() {
}
-void Character::paint(Graphics::Surface &backbuffer) const {
+void Character::paint(Graphics::Surface &backbuffer, Common::Point pos) const {
if (!_enabled || !_visible || !_animation)
return;
- Common::Point pos = _pos + _animationPos;
+ pos += _pos + _animationPos;
pos.y -= _animation->height();
pos.x -= _animation->width() / 2;
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 4ec02046df4..6b28ff03cd9 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -120,7 +120,7 @@ public:
}
void tick();
- void paint(Graphics::Surface & backbuffer) const;
+ void paint(Graphics::Surface & backbuffer, Common::Point pos) const;
int getDirectionForMovement(Common::Point delta);
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 5902a8dc551..9476961c01d 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -40,7 +40,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_pos(), _z(10),
_clickHandler(0), _examineHandler(0), _userUseHandler(0),
_throwHandler(0), _useOnHandler(0),
- _alpha(255), _alive(true),
+ _alpha(255), _scale(100), _alive(true),
_persistent(true), _allowInitialise(true) {
uint16 id = stream->readUint16LE();
debug("id: 0x%02x %u", id, id);
@@ -244,7 +244,7 @@ bool Object::pointIn(Common::Point pos) {
return false;
}
-void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) const {
+void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point pos) const {
auto picture = getPicture();
if (picture) {
Common::Point dst = getPosition();
@@ -261,13 +261,13 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) const {
}
if (!_text.empty()) {
- Common::Point pos = _region ? _region->center + _regionOffset : _pos;
+ pos += _region ? _region->center + _regionOffset : _pos;
int w = backbuffer.w - pos.x;
engine.getFont(engine.getSystemVariable("objtext_font")->getInteger())->drawString(&backbuffer, _text, pos.x, pos.y, w, 0);
}
if (engine.showHints() && !_title.empty()) {
- Common::Point pos = _region ? _region->center : _pos;
+ pos += _region ? _region->center : _pos;
int w = backbuffer.w - pos.x;
auto font = engine.getFont(engine.getSystemVariable("tell_font")->getInteger());
pos.x -= font->getStringWidth(_title) / 2;
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 131b6f11692..0c433120791 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -220,7 +220,7 @@ public:
return _userUseHandler;
}
- void paint(AGDSEngine &engine, Graphics::Surface &backbuffer) const;
+ void paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point pos) const;
void moveTo(Common::Point pos);
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 412180a9fa3..3f7ad7d00e5 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -50,6 +50,17 @@ Screen::~Screen() {
_children.clear();
}
+void Screen::scrollTo(Common::Point scroll) {
+ int maxW = g_system->getWidth();
+ int maxH = g_system->getHeight();
+ if (scroll.x < 0)
+ scroll.x = 0;
+ if (scroll.y < 0)
+ scroll.y = 0;
+ _scroll = scroll;
+}
+
+
float Screen::getZScale(int y) const
{
int dy = g_system->getHeight() - y;
@@ -192,21 +203,27 @@ void Screen::paint(Graphics::Surface &backbuffer) {
}
}
+ auto basePos = _scroll;
switch (render_type) {
case 0:
//debug("object z: %d", (*child)->z());
- if ((*child) != currentInventoryObject && (*child)->alive())
- (*child)->paint(*_engine, backbuffer);
+ if ((*child) != currentInventoryObject && (*child)->alive()) {
+ if ((*child)->scale() < 0)
+ basePos = Common::Point();
+ (*child)->paint(*_engine, backbuffer, basePos);
+ }
++child;
break;
case 1:
//debug("animation z: %d", (*animation)->z());
- (*animation)->paint(backbuffer, Common::Point());
+ (*animation)->paint(backbuffer, basePos);
+ if ((*animation)->scale() < 0)
+ basePos = Common::Point();
++animation;
break;
case 2:
//debug("character z: %d", character->z());
- character->paint(backbuffer);
+ character->paint(backbuffer, _scroll);
character = nullptr;
break;
default:
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 7f05f60d423..3f24514405d 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -54,6 +54,7 @@ class Screen {
AGDSEngine * _engine;
ObjectPtr _object;
+ Common::Point _scroll;
Common::String _name;
ScreenLoadingType _loadingType;
Common::String _previousScreen;
@@ -117,6 +118,10 @@ public:
const AnimationsType & animations() const {
return _animations;
}
+ void scrollTo(Common::Point scroll);
+ Common::Point scrollPosition() const {
+ return _scroll;
+ }
bool add(ObjectPtr object);
void add(Animation * animation);
Commit: d45d91d79cb0a0064229b8b6971e59420a63868f
https://github.com/scummvm/scummvm/commit/d45d91d79cb0a0064229b8b6971e59420a63868f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:49+01:00
Commit Message:
AGDS: support large screens
Changed paths:
engines/agds/agds.cpp
engines/agds/object.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 8a76153c00a..63545d0b2e5 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -608,8 +608,12 @@ Common::Error AGDSEngine::run() {
debug("found handler: %s %08x", object->getName().c_str(), ip + 7);
runProcess(object, ip);
break;
- } else
+ } else {
debug("no handler found");
+ auto scroll = _currentScreen->scrollPosition();
+ scroll.x += _mouse.x - g_system->getWidth() / 2;
+ _currentScreen->scrollTo(scroll);
+ }
}
}
break;
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 9476961c01d..3a106a6895b 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -247,7 +247,7 @@ bool Object::pointIn(Common::Point pos) {
void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point pos) const {
auto picture = getPicture();
if (picture) {
- Common::Point dst = getPosition();
+ Common::Point dst = pos + getPosition();
Common::Rect srcRect = picture->getRect();
uint32 color = (_alpha << 24) | 0xffffff; //fixme: _picture->format.ARGBToColor(_alpha, 255, 255, 255); is not working
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect())) {
@@ -256,8 +256,9 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Po
}
if (_animation) {
+ pos += _pos + _animationPos;
_animation->tick();
- _animation->paint(backbuffer, _pos + _animationPos);
+ _animation->paint(backbuffer, pos);
}
if (!_text.empty()) {
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 3f7ad7d00e5..93d3edbead6 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -51,12 +51,35 @@ Screen::~Screen() {
}
void Screen::scrollTo(Common::Point scroll) {
- int maxW = g_system->getWidth();
- int maxH = g_system->getHeight();
+ int windowW = g_system->getWidth();
+ int windowH = g_system->getHeight();
+
+ ObjectPtr background;
+ for(uint i = 0, n = _children.size(); i < n; ++i) {
+ auto & child = _children.data()[i];
+ if (child->getPicture()) {
+ background = child;
+ break;
+ }
+ }
+ if (!background) {
+ _scroll.x = _scroll.y = 0;
+ return;
+ }
+
+ auto rect = background->getRect();
+ int w = rect.width(), h = rect.height();
+ debug("picture size %dx%d", w, h);
+ if (scroll.x + windowW > w)
+ scroll.x = w - windowW;
+ if (scroll.y + windowH > h)
+ scroll.y = h - windowH;
if (scroll.x < 0)
scroll.x = 0;
if (scroll.y < 0)
scroll.y = 0;
+
+ debug("setting scroll to %d,%d", scroll.x, scroll.y);
_scroll = scroll;
}
@@ -203,7 +226,7 @@ void Screen::paint(Graphics::Surface &backbuffer) {
}
}
- auto basePos = _scroll;
+ auto basePos = Common::Point() - _scroll;
switch (render_type) {
case 0:
//debug("object z: %d", (*child)->z());
@@ -216,14 +239,14 @@ void Screen::paint(Graphics::Surface &backbuffer) {
break;
case 1:
//debug("animation z: %d", (*animation)->z());
- (*animation)->paint(backbuffer, basePos);
if ((*animation)->scale() < 0)
basePos = Common::Point();
+ (*animation)->paint(backbuffer, basePos);
++animation;
break;
case 2:
//debug("character z: %d", character->z());
- character->paint(backbuffer, _scroll);
+ character->paint(backbuffer, basePos);
character = nullptr;
break;
default:
@@ -233,6 +256,7 @@ void Screen::paint(Graphics::Surface &backbuffer) {
}
Common::Array<ObjectPtr> Screen::find(Common::Point pos) const {
+ pos += _scroll;
Common::Array<ObjectPtr> objects;
objects.reserve(_children.size());
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
Commit: 5e113b3237db802bbe38f8889ac135200e9d6733
https://github.com/scummvm/scummvm/commit/5e113b3237db802bbe38f8889ac135200e9d6733
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:49+01:00
Commit Message:
AGDS: implement Character::associate
Changed paths:
engines/agds/agds.cpp
engines/agds/character.cpp
engines/agds/character.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 63545d0b2e5..957a43439ed 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -178,7 +178,7 @@ bool AGDSEngine::load() {
{
Common::File * file = new Common::File();
file->open("jokes.chr");
- _jokes = new Character(this, "jokes", ObjectPtr());
+ _jokes = new Character(this, "jokes");
_jokes->load(file);
}
@@ -832,8 +832,9 @@ void AGDSEngine::loadCharacter(const Common::String &id, const Common::String &f
_currentCharacterFilename = filename;
_currentCharacterObject = object;
- _currentCharacter = new Character(this, id, loadObject(object));
+ _currentCharacter = new Character(this, id);
_currentCharacter->load(_resourceManager.getResource(loadText(filename)));
+ _currentCharacter->associate(object);
}
Graphics::TransparentSurface *AGDSEngine::loadPicture(const Common::String &name) {
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 13a356b3423..a361eb824e3 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -98,6 +98,12 @@ void Character::load(Common::SeekableReadStream *stream) {
delete stream;
}
+void Character::associate(const Common::String &name) {
+ _object = _engine->loadObject(name);
+ _engine->runObject(_object);
+}
+
+
void Character::loadState(Common::ReadStream* stream) {
int x = stream->readUint16LE();
int y = stream->readUint16LE();
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 6b28ff03cd9..fcec8dca335 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -66,10 +66,12 @@ class Character {
const AnimationDescription * _description;
public:
- Character(AGDSEngine * engine, const Common::String & name, const ObjectPtr & object):
- _engine(engine), _name(name), _object(object), _animation(nullptr), _enabled(true), _visible(true), _phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
+ Character(AGDSEngine * engine, const Common::String & name):
+ _engine(engine), _name(name), _object(), _animation(nullptr), _enabled(true), _visible(true), _phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
}
+ void associate(const Common::String &name);
+
const AnimationDescription * animationDescription(uint index) const {
auto it = _animations.find(index);
return it != _animations.end()? &it->_value: nullptr;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 99488e8b5f1..91b15e86521 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -349,6 +349,7 @@ enum Opcode {
OP(kObjectPatchSetRegionName, objectPatchSetRegionName) \
OP(kAnimateCharacter, animateCharacter) \
OP(kLoadCharacter, loadCharacter) \
+ OP(kAssociateCharacter, associateCharacter) \
OP(kSetObjectZ, setObjectZ) \
OP(kUpdateObjectZToDisplay, updateObjectZToDisplay) \
OP(kLoadTextFromObject, loadTextFromObject) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 96a6fedc36f..4be8a8b2e9f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1385,8 +1385,19 @@ void Process::addMouseArea() {
void Process::loadCharacter() {
Common::String object = popString();
Common::String filename = popString();
- Common::String id = popString();
- _engine->loadCharacter(id, filename, object);
+ Common::String name = popString();
+ _engine->loadCharacter(name, filename, object);
+}
+
+void Process::associateCharacter() {
+ Common::String object = popString();
+ Common::String name = popString();
+ debug("associateCharacter %s %s", name.c_str(), object.c_str());
+ Character *character = _engine->getCharacter(name);
+ if (character)
+ character->associate(name);
+ else
+ warning("character %s could not be found", name.c_str());
}
void Process::enableCharacter() {
Commit: 41ff8986e01c3aa3768e6720519854252570916f
https://github.com/scummvm/scummvm/commit/41ff8986e01c3aa3768e6720519854252570916f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:50+01:00
Commit Message:
AGDS: character direction is signed
Changed paths:
engines/agds/patch.cpp
engines/agds/patch.h
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index a26ee51cbeb..02dcf2f7f8f 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -28,9 +28,9 @@ void Patch::load(Common::ReadStream *stream) {
loadingType = static_cast<ScreenLoadingType>(stream->readUint32LE());
characterPosition.x = stream->readUint32LE();
characterPosition.y = stream->readUint32LE();
- characterDirection = stream->readUint32LE();
+ characterDirection = stream->readSint32LE();
characterPresent = stream->readUint32LE();
- debug("character %s at %u,%u with dir: %u", characterPresent? "[present]": "[absent]", characterPosition.x, characterPosition.y, characterDirection);
+ debug("character %s at %u,%u with dir: %d", characterPresent? "[present]": "[absent]", characterPosition.x, characterPosition.y, characterDirection);
uint object_count = stream->readUint32LE();
debug("objects in this patch: %u", object_count);
if (stream->read(palette, sizeof(palette)) != sizeof(palette)) {
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index 65a2f53bf8d..b983cda2b60 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -59,7 +59,7 @@ struct Patch {
ScreenLoadingType loadingType = ScreenLoadingType::Normal;
Common::Point characterPosition;
- uint characterDirection = 0;
+ int characterDirection = 0;
bool characterPresent = false;
byte palette[0x300] = {};
Commit: 62b23893c97cdddbeb8d6d5e00207998662ced7f
https://github.com/scummvm/scummvm/commit/62b23893c97cdddbeb8d6d5e00207998662ced7f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:50+01:00
Commit Message:
AGDS: implement dual animation support for character
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
engines/agds/textLayout.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index a361eb824e3..62a5451ab37 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -134,16 +134,8 @@ void Character::direction(int dir) {
if (dir < 0)
return;
- _description = animationDescription(dir);
- _animation = _description? _engine->loadAnimation(_description->filename): nullptr;
_animationPos = Common::Point();
- if (!_animation) {
- debug("no animation?");
- _phase = -1;
- _frames = 0;
- return;
- }
- _animation->rewind();
+ animate(dir, 100, false);
}
void Character::moveTo(const Common::String & processName, Common::Point dst, int dir) {
@@ -153,28 +145,41 @@ void Character::moveTo(const Common::String & processName, Common::Point dst, in
direction(dir);
}
-void Character::animate(const Common::String & processName, Common::Point pos, int direction, int speed) {
- debug("animate character: %d,%d %d %d", pos.x, pos.y, direction, speed);
- _processName = processName;
+void Character::animate(int direction, int speed, bool jokes) {
if (direction == -1)
return;
- auto jokes = _engine->jokes();
- _description = jokes->animationDescription(direction);
+
+ auto character = jokes? _engine->jokes(): this;
+ _description = character->animationDescription(direction);
_animation = _description? _engine->loadAnimation(_description->filename): nullptr;
if (!_animation) {
- warning("no jokes animation %d", direction);
+ warning("no %s animation %d", jokes? "jokes": "character", direction);
_phase = -1;
_frames = 0;
return;
}
_animation->speed(speed);
_animation->rewind();
+ if (!_jokes)
+ _animation->tick(); //load first frame
_phase = 0;
_frames = _animation->frames();
- _animationPos = pos;
+ _jokes = jokes;
+ if (jokes)
+ _jokesDirection = direction;
+ else
+ _direction = direction;
debug("character animation frames: %d, enabled: %d, visible: %d", _frames, _enabled, _visible);
}
+void Character::animate(const Common::String & processName, Common::Point pos, int direction, int speed) {
+ debug("animate character: %d,%d %d %d", pos.x, pos.y, direction, speed);
+ _processName = processName;
+ _animationPos = pos;
+
+ animate(direction, speed, true);
+}
+
void Character::stop() {
debug("character %s: stop", _object->getName().c_str());
_phase = -1;
@@ -191,11 +196,14 @@ void Character::tick() {
// debug("character %d/%d", _phase, _frames);
if (_phase >= 0 && _phase < _frames) {
- _animation->tick();
+ if (_jokes)
+ _animation->tick();
_phase = _animation->phase();
if (_phase >= _frames) {
+ //many dialog scripts rely on jokes direction returned from direction notify var
_phase = -1;
_frames = 0;
+ //animate(_direction, 100, false);
}
}
_engine->reactivate(_processName, true);
diff --git a/engines/agds/character.h b/engines/agds/character.h
index fcec8dca335..06131452ffc 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -42,6 +42,7 @@ class Character {
AGDSEngine * _engine;
ObjectPtr _object;
Animation * _animation;
+ bool _jokes;
Common::String _name;
Common::String _processName;
Common::Point _pos;
@@ -51,6 +52,7 @@ class Character {
int _phase;
int _frames;
int _direction;
+ int _jokesDirection;
int _movementDirections;
struct AnimationDescription {
@@ -67,7 +69,8 @@ class Character {
public:
Character(AGDSEngine * engine, const Common::String & name):
- _engine(engine), _name(name), _object(), _animation(nullptr), _enabled(true), _visible(true), _phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
+ _engine(engine), _name(name), _object(), _animation(nullptr), _jokes(false),
+ _enabled(true), _visible(true), _phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
}
void associate(const Common::String &name);
@@ -98,11 +101,12 @@ public:
}
void animate(const Common::String &processName, Common::Point pos, int direction, int speed);
+ void animate(int direction, int speed, bool jokes);
void stop();
int getPhase() const {
- return _phase;
+ return _jokes? _phase: -1;
}
void position(Common::Point pos) {
@@ -118,7 +122,7 @@ public:
void direction(int dir);
int direction() const {
- return _direction;
+ return _jokes? _jokesDirection: _direction;
}
void tick();
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 5b9a1f597bc..e58e88f5f8a 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -86,6 +86,7 @@ void TextLayout::layout(AGDSEngine &engine, const Common::String &process, const
if (!var.empty()) {
if (!engine.getGlobal(var))
engine.setGlobal(var, 1);
+ engine.reactivate(_process);
}
auto character = engine.currentCharacter();
if (character) {
@@ -106,6 +107,7 @@ void TextLayout::layout(AGDSEngine &engine, const Common::String &process, const
character->animate(_process, Common::Point(), character->direction(), 100);
}
}
+ engine.reactivate(_process);
} else
warning("no current character, skipping direction notification");
}
Commit: 5711ef40a7ee39342f9e9450357d909da5ce1c2b
https://github.com/scummvm/scummvm/commit/5711ef40a7ee39342f9e9450357d909da5ce1c2b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:50+01:00
Commit Message:
AGDS: stop all object processes when it's getting removed from screen, lock object in exit handler
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 3a106a6895b..60c95ce7b25 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -40,7 +40,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_pos(), _z(10),
_clickHandler(0), _examineHandler(0), _userUseHandler(0),
_throwHandler(0), _useOnHandler(0),
- _alpha(255), _scale(100), _alive(true),
+ _alpha(255), _scale(100), _locked(false), _alive(true),
_persistent(true), _allowInitialise(true) {
uint16 id = stream->readUint16LE();
debug("id: 0x%02x %u", id, id);
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 0c433120791..7e309c74cf8 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -81,6 +81,7 @@ private:
uint _useOnHandler;
int _alpha;
int _scale;
+ bool _locked;
bool _alive;
bool _persistent;
bool _allowInitialise;
@@ -275,6 +276,12 @@ public:
return _useOnHandler;
}
+ bool locked() const {
+ return _locked;
+ }
+ void lock() { _locked = true; }
+ void unlock() { _locked = false; }
+
bool alive() const
{ return _alive; }
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 2ea54fd2bce..26db9cae2bf 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -171,16 +171,19 @@ void Process::run() {
switch (code) {
case kExitCodeDestroy:
debug("process %s returned destroy exit code", getName().c_str());
- //_engine->getCurrentScreen()->remove(_object); //remove if the last process exits
done();
break;
case kExitCodeLoadScreenObjectAs:
case kExitCodeLoadScreenObject:
+ _object->lock();
_engine->runObject(getExitArg1(), getExitArg2());
+ _object->unlock();
activate();
continue;
case kExitCodeRunDialog:
+ _object->lock();
_engine->runDialog(getName(), getExitArg1());
+ _object->unlock();
break;
case kExitCodeSetNextScreen:
case kExitCodeSetNextScreenSaveOrLoad:
@@ -193,12 +196,16 @@ void Process::run() {
activate();
continue;
case kExitCodeLoadInventoryObject:
+ _object->lock();
_engine->inventory().add(_engine->runObject(getExitArg1()));
+ _object->unlock();
activate();
continue;
case kExitCodeCloseInventory:
+ _object->lock();
_engine->inventory().enable(false);
updateWithCurrentMousePosition();
+ _object->unlock();
activate();
return; //some codes are special, they needed to exit loop and keep process active
case kExitCodeSuspend:
@@ -213,17 +220,21 @@ void Process::run() {
}
break;
case kExitCodeLoadGame:
+ _object->lock();
if (_engine->loadGameState(getExitIntArg1()).getCode() == Common::kNoError) {
done();
} else {
debug("save loading failed, resuming execution...");
activate(); //continue
}
+ _object->unlock();
break;
case kExitCodeSaveGame:
+ _object->lock();
if (_engine->saveGameState(getExitIntArg1(), "").getCode() != Common::kNoError) {
warning("failed to save game");
}
+ _object->unlock();
activate();
break;
default:
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4be8a8b2e9f..a8cf69d3558 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -280,10 +280,12 @@ void Process::removeScreenObject() {
auto object = screen->find(name);
if (object) {
if (object->alive()) {
- if (name == _object->getName()) {
+ if (name == _object->getName() || object->locked()) {
debug("removeScreenObject: %s: removing object from its own body (sic)", name.c_str());
object->alive(false);
- } else if (!screen || !screen->remove(name))
+ } else if (screen && screen->remove(name)) {
+ _engine->stopProcess(name);
+ } else
warning("removeScreenObject: object %s not found", name.c_str());
} else
warning("removeScreenObject: object %s already removed", name.c_str());
Commit: ac944fb1c800705ccb27fac940dfe5d5edbd317f
https://github.com/scummvm/scummvm/commit/ac944fb1c800705ccb27fac940dfe5d5edbd317f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:50+01:00
Commit Message:
AGDS: reactivate animation process on each frame
Changed paths:
engines/agds/animation.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index cc6c6ded70c..1edbd2a6eb7 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -162,6 +162,7 @@ bool Animation::tick() {
if (!_process.empty()) {
if (!_phaseVar.empty()) {
_engine->setGlobal(_phaseVar, _phase - 1);
+ _engine->reactivate(_process, true);
}
}
return true;
Commit: f8ce56edecac85404193eee66cf0034655d5b55c
https://github.com/scummvm/scummvm/commit/f8ce56edecac85404193eee66cf0034655d5b55c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:50+01:00
Commit Message:
AGDS: add console 'stop' command
Changed paths:
engines/agds/console.cpp
engines/agds/console.h
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index 40cce836068..5c59e16af65 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -34,6 +34,7 @@ Console::Console(AGDSEngine *engine) : _engine(engine) {
registerCmd("info", WRAP_METHOD(Console, info));
registerCmd("load", WRAP_METHOD(Console, load));
registerCmd("run", WRAP_METHOD(Console, run));
+ registerCmd("stop", WRAP_METHOD(Console, stop));
registerCmd("set", WRAP_METHOD(Console, setGlobal));
}
@@ -68,6 +69,22 @@ bool Console::run(int argc, const char **argv) {
return false;
}
+bool Console::stop(int argc, const char **argv) {
+ if (argc < 2) {
+ debugPrintf("usage: %s object_id\n", argv[0]);
+ return true;
+ }
+ ObjectPtr object = _engine->getCurrentScreenObject(argv[1]);
+ if (!object) {
+ debugPrintf("no object %s\n", argv[1]);
+ return true;
+ }
+ _engine->getCurrentScreen()->remove(object);
+ _engine->stopProcess(argv[1]);
+ detach();
+ return false;
+}
+
bool Console::activate(int argc, const char **argv) {
if (argc < 2) {
debugPrintf("usage: %s object_id\n", argv[0]);
diff --git a/engines/agds/console.h b/engines/agds/console.h
index d71b13fffe5..7912a32aa88 100644
--- a/engines/agds/console.h
+++ b/engines/agds/console.h
@@ -38,6 +38,7 @@ public:
private:
bool load(int argc, const char **argv);
bool run(int argc, const char **argv);
+ bool stop(int argc, const char **argv);
bool activate(int argc, const char **argv);
bool info(int argc, const char **argv);
bool setGlobal(int argc, const char **argv);
Commit: c1e25ef7081495d463008dfb7726f681b205a3aa
https://github.com/scummvm/scummvm/commit/c1e25ef7081495d463008dfb7726f681b205a3aa
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:50+01:00
Commit Message:
AGDS: fix the latest dialog definition
Changed paths:
engines/agds/dialog.cpp
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index a2a102e95c1..0a1d595833f 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -21,7 +21,9 @@ void Dialog::parseDialogDefs(const Common::String &defs) {
char ch = defs[p];
if (ch == ' ') {
continue;
- } else if (ch == '\n' || ch == '\r') {
+ } else if (ch == '\n' || ch == '\r' || p + 1 == size) {
+ if (p + 1 == size)
+ value += ch;
//debug("dialog definition: '%s' = '%s'", name.c_str(), value.c_str());
if (!name.empty() && !value.empty()) {
_dialogDefs[name] = atoi(value.c_str());
Commit: 26ffdbd9d333a6ec276d8983e7aec14c7898b710
https://github.com/scummvm/scummvm/commit/26ffdbd9d333a6ec276d8983e7aec14c7898b710
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:50+01:00
Commit Message:
AGDS: handle @vybervariantyX and @varianta properly, keep current sample index
Changed paths:
engines/agds/dialog.cpp
engines/agds/dialog.h
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 0a1d595833f..4a0b2cfe3b4 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -160,8 +160,20 @@ bool Dialog::tick() {
DialogDefsType::const_iterator it = _dialogDefs.find(line);
if (it != _dialogDefs.end()) {
int value = it->_value;
- debug("dialog value %s = %d (0x%04x)", line.c_str(), value, value);
_currentDef = line;
+ if (!_currentDef.hasPrefix("vybervarianty") && !_currentDef.hasPrefix("varianta")) {
+ _currentSoundIndex = -1;
+
+ for(uint s = 0; s < _sounds.size(); ++s) {
+ auto & sound = _sounds[s];
+ if (_currentDef.hasPrefixIgnoreCase(sound.Name)) {
+ _currentSoundIndex = s;
+ break;
+ }
+ }
+ }
+ debug("dialog value %s = %d (0x%04x), sample index: %d", line.c_str(), value, value, _currentSoundIndex);
+
dialog_var->setInteger(value);
_engine->reactivate(_dialogProcessName);
} else
@@ -187,16 +199,11 @@ Common::String Dialog::getNextDialogSound() {
if (_currentDef.empty())
return Common::String();
- uint it;
- for(it = 0; it < _sounds.size(); ++it) {
- auto & sound = _sounds[it];
- if (_currentDef.hasPrefixIgnoreCase(sound.Name))
- break;
- }
- if (it == _sounds.size())
+ debug("getNextDialogSound %s %d", _currentDef.c_str(), _currentSoundIndex);
+ if (_currentSoundIndex < 0)
return Common::String();
- auto &sound = _sounds[it];
+ auto &sound = _sounds[_currentSoundIndex];
auto &sample = sound.Sample;
auto currentSample = sample;
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
index 53265d20c36..a471f2255f2 100644
--- a/engines/agds/dialog.h
+++ b/engines/agds/dialog.h
@@ -58,11 +58,12 @@ private:
SoundsType _sounds;
Common::String _currentDef;
+ int _currentSoundIndex;
void parseDialogDefs(const Common::String &defs);
public:
- Dialog(AGDSEngine *engine): _engine(engine), _dialogScriptPos(0) { }
+ Dialog(AGDSEngine *engine): _engine(engine), _dialogScriptPos(0), _currentSoundIndex(-1) { }
void run(const Common::String &dialogParent, const Common::String &dialogProcess);
int textDelay(const Common::String &str);
const Common::String &getNextDialogLine() const {
Commit: c6afd32df2e974a7b2b0618ed754393b5b1b4dc8
https://github.com/scummvm/scummvm/commit/c6afd32df2e974a7b2b0618ed754393b5b1b4dc8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:50+01:00
Commit Message:
AGDS: do not signal character var when npc say finishes
Changed paths:
engines/agds/textLayout.cpp
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index e58e88f5f8a..40907ecb26f 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -88,28 +88,30 @@ void TextLayout::layout(AGDSEngine &engine, const Common::String &process, const
engine.setGlobal(var, 1);
engine.reactivate(_process);
}
- auto character = engine.currentCharacter();
- if (character) {
- if (!_charDirectionNotifyVar.empty()) {
- if (!engine.getGlobal(_charDirectionNotifyVar))
- engine.setGlobal(_charDirectionNotifyVar, character->direction());
- } else {
- switch(character->direction()) {
- case 0:
- case 1:
- case 2:
- case 3:
- case 13:
- case 14:
- case 15:
- break;
- default:
- character->animate(_process, Common::Point(), character->direction(), 100);
+ if (!_npc) {
+ auto character = engine.currentCharacter();
+ if (character) {
+ if (!_charDirectionNotifyVar.empty()) {
+ if (!engine.getGlobal(_charDirectionNotifyVar))
+ engine.setGlobal(_charDirectionNotifyVar, character->direction());
+ } else {
+ switch(character->direction()) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 13:
+ case 14:
+ case 15:
+ break;
+ default:
+ character->animate(_process, Common::Point(), character->direction(), 100);
+ }
}
- }
- engine.reactivate(_process);
- } else
- warning("no current character, skipping direction notification");
+ engine.reactivate(_process);
+ } else
+ warning("no current character, skipping direction notification");
+ }
}
}
Commit: 4b0c0916f6ad4bc40272df6e2ebb2ec1af18e579
https://github.com/scummvm/scummvm/commit/4b0c0916f6ad4bc40272df6e2ebb2ec1af18e579
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:50+01:00
Commit Message:
AGDS: remove stub from scale op
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index a8cf69d3558..26af2b140ce 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -896,8 +896,8 @@ void Process::removeGapsFromInventory() {
void Process::setObjectScale() {
int value = pop();
+ debug("setObjectScale %d", value);
_object->scale(value);
- debug("setObjectScale stub %d", value);
}
void Process::disableMouseAreas() {
Commit: e9ea67c12036cf9cb3d71eb1e7609d16212f3d82
https://github.com/scummvm/scummvm/commit/e9ea67c12036cf9cb3d71eb1e7609d16212f3d82
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:50+01:00
Commit Message:
AGDS: make Screen::paint const
Changed paths:
engines/agds/agds.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 957a43439ed..e1b96191154 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -669,6 +669,7 @@ Common::Error AGDSEngine::run() {
skipFilm();
}
} else if (_currentScreen) {
+ _currentScreen->tick();
_currentScreen->paint(*backbuffer);
}
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 93d3edbead6..8016405e256 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -179,8 +179,7 @@ Animation *Screen::findAnimationByPhaseVar(const Common::String &phaseVar) {
return NULL;
}
-void Screen::paint(Graphics::Surface &backbuffer) {
- auto & currentInventoryObject = _engine->currentInventoryObject();
+void Screen::tick() {
for(uint i = 0; i < _animations.size(); ) {
Animation *animation = _animations.data()[i];
if (animation->tick())
@@ -194,9 +193,14 @@ void Screen::paint(Graphics::Surface &backbuffer) {
Character * character = _engine->currentCharacter();
if (character)
character->tick();
+}
+
+void Screen::paint(Graphics::Surface &backbuffer) const {
+ auto & currentInventoryObject = _engine->currentInventoryObject();
+ Character * character = _engine->currentCharacter();
- ChildrenType::iterator child = _children.begin();
- AnimationsType::iterator animation = _animations.begin();
+ auto child = _children.begin();
+ auto animation = _animations.begin();
while(child != _children.end() || animation != _animations.end() || character) {
bool child_valid = child != _children.end();
bool animation_valid = animation != _animations.end();
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 3f24514405d..99399d414da 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -135,7 +135,9 @@ public:
bool remove(const Common::String & name);
bool remove(const ObjectPtr & object);
- void paint(Graphics::Surface & backbuffer);
+
+ void tick();
+ void paint(Graphics::Surface & backbuffer) const;
Common::Array<ObjectPtr> find(Common::Point pos) const;
ObjectPtr find(const Common::String &name);
KeyHandler findKeyHandler(const Common::String &keyName);
Commit: c7474cbac78e254cb7ba453e31f04d09981baa18
https://github.com/scummvm/scummvm/commit/c7474cbac78e254cb7ba453e31f04d09981baa18
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:51+01:00
Commit Message:
AGDS: do not use phaseVar for sync sounds
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index e1b96191154..52c18cb2ff0 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -943,7 +943,7 @@ void AGDSEngine::tell(Process &process, const Common::String ®ionName, Common
_tellTextTimer = _dialog.textDelay(text);
_textLayout.layout(*this, process.getName(), text, pos, font_id, npc);
if (!sound.empty()) {
- playSoundSync(sound, process.phaseVar());
+ playSoundSync(sound);
} else {
_syncSoundId = -1;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index a82cb6508eb..fb7a17c77ae 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -238,8 +238,8 @@ public:
return _soundManager.play(process, resource, filename, phaseVar, playing);
}
- void playSoundSync(const Common::String &filename, const Common::String &phaseVar) {
- _syncSoundId = playSound(Common::String(), Common::String(), filename, phaseVar);
+ void playSoundSync(const Common::String &filename) {
+ _syncSoundId = playSound(Common::String(), Common::String(), filename, Common::String());
}
void setAmbientSoundId(int id) { _ambientSoundId = id; }
Commit: 224712583fc30b47b800ab65dcf079874419e78e
https://github.com/scummvm/scummvm/commit/224712583fc30b47b800ab65dcf079874419e78e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:51+01:00
Commit Message:
AGDS: change process status to passive from text layout, do not reactivate
Changed paths:
engines/agds/agds.cpp
engines/agds/process.h
engines/agds/textLayout.cpp
engines/agds/textLayout.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 52c18cb2ff0..209dec546c9 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -941,7 +941,7 @@ void AGDSEngine::tell(Process &process, const Common::String ®ionName, Common
sound = _dialog.getNextDialogSound();
_tellTextTimer = _dialog.textDelay(text);
- _textLayout.layout(*this, process.getName(), text, pos, font_id, npc);
+ _textLayout.layout(*this, process, text, pos, font_id, npc);
if (!sound.empty()) {
playSoundSync(sound);
} else {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index b42e675bdd7..147f6617aab 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -175,6 +175,9 @@ public:
void fail() {
_status = kStatusError;
}
+ void pause() {
+ _status = kStatusPassive;
+ }
bool finished() const {
return _status == kStatusDone || _status == kStatusError;
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 40907ecb26f..363a62dd532 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -3,6 +3,7 @@
#include "agds/agds.h"
#include "agds/character.h"
#include "agds/object.h"
+#include "agds/process.h"
#include "common/debug.h"
namespace AGDS {
@@ -32,13 +33,14 @@ void TextLayout::reset(AGDSEngine &engine) {
}
}
-void TextLayout::layout(AGDSEngine &engine, const Common::String &process, const Common::String &text, Common::Point pos, int fontId, bool npc) {
+void TextLayout::layout(AGDSEngine &engine, Process &process, const Common::String &text, Common::Point pos, int fontId, bool npc) {
if (text.empty()) {
_valid = false;
return;
}
- _process = process;
+ _process = process.getName();
+ process.pause();
_fontId = fontId;
_npc = npc;
Font *font = engine.getFont(fontId);
@@ -86,7 +88,6 @@ void TextLayout::layout(AGDSEngine &engine, const Common::String &process, const
if (!var.empty()) {
if (!engine.getGlobal(var))
engine.setGlobal(var, 1);
- engine.reactivate(_process);
}
if (!_npc) {
auto character = engine.currentCharacter();
@@ -108,7 +109,6 @@ void TextLayout::layout(AGDSEngine &engine, const Common::String &process, const
character->animate(_process, Common::Point(), character->direction(), 100);
}
}
- engine.reactivate(_process);
} else
warning("no current character, skipping direction notification");
}
diff --git a/engines/agds/textLayout.h b/engines/agds/textLayout.h
index d9b32e6abd5..fd64edc6e0e 100644
--- a/engines/agds/textLayout.h
+++ b/engines/agds/textLayout.h
@@ -35,6 +35,7 @@ namespace Graphics {
namespace AGDS {
class AGDSEngine;
+class Process;
class TextLayout {
int _fontId;
@@ -77,7 +78,7 @@ public:
}
void paint(AGDSEngine &engine, Graphics::Surface &backbuffer);
- void layout(AGDSEngine &engine, const Common::String &process, const Common::String &text, Common::Point pos, int fontId, bool npc);
+ void layout(AGDSEngine &engine, Process &process, const Common::String &text, Common::Point pos, int fontId, bool npc);
};
} // End of namespace AGDS
Commit: 4d0ff689e0b1532c26df50f1709e105de172ebdb
https://github.com/scummvm/scummvm/commit/4d0ff689e0b1532c26df50f1709e105de172ebdb
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:51+01:00
Commit Message:
AGDS: add animation name to animation object
Changed paths:
engines/agds/agds.cpp
engines/agds/animation.cpp
engines/agds/animation.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 209dec546c9..33f27e7e41c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -812,7 +812,7 @@ Animation *AGDSEngine::loadAnimation(const Common::String &name) {
Common::SeekableReadStream *stream = _resourceManager.getResource(name);
if (!stream)
error("could not load animation from %s", name.c_str());
- Animation *animation = new Animation(this);
+ Animation *animation = new Animation(this, name);
if (!animation->load(stream, name))
error("could not load animation from %s", name.c_str());
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 1edbd2a6eb7..8c0bd71ec88 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -30,8 +30,8 @@
namespace AGDS {
-Animation::Animation(AGDSEngine *engine) :
- _engine(engine), _flic(), _frame(),
+Animation::Animation(AGDSEngine *engine, const Common::String &name) :
+ _engine(engine), _name(name), _flic(), _frame(),
_frames(0), _loop(false), _cycles(1), _phaseVarControlled(false),
_phase(0), _paused(false), _speed(100), _z(0),
_delay(0), _random(0), _scale(1) {
@@ -98,7 +98,8 @@ bool Animation::load(Common::SeekableReadStream *stream, const Common::String &f
void Animation::decodeNextFrame() {
auto frame = _flic->decodeNextFrame();
if (!frame) {
- warning("frame couldn't be decoded");
+ debug("frame of %s couldn't be decoded, process: %s, phase var: %s, at end: %d", _name.c_str(), _process.c_str(), _phaseVar.c_str(), _flic->endOfVideo());
+ warning("frame of %s couldn't be decoded, process: %s, phase var: %s, at end: %d", _name.c_str(), _process.c_str(), _phaseVar.c_str(), _flic->endOfVideo());
return;
}
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index f39cc2f4b59..725541c251d 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -37,6 +37,7 @@ class Object;
class Animation {
AGDSEngine * _engine;
+ Common::String _name;
Video::FlicDecoder *_flic;
Graphics::TransparentSurface *_frame;
int _frames;
@@ -55,7 +56,7 @@ class Animation {
float _scale;
public:
- Animation(AGDSEngine *engine);
+ Animation(AGDSEngine *engine, const Common::String &name);
~Animation();
void freeFrame();
Commit: 9cbf76e9c08db9825d6b7c3669bd08cd98dd33ec
https://github.com/scummvm/scummvm/commit/9cbf76e9c08db9825d6b7c3669bd08cd98dd33ec
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:51+01:00
Commit Message:
AGDS: add getRandomNumber function for engine
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 33f27e7e41c..1822e07122e 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1342,4 +1342,8 @@ void AGDSEngine::returnToPreviousScreen() {
}
}
+int AGDSEngine::getRandomNumber(int max) {
+ return max > 0 ? _random.getRandomNumber(max - 1) : 0;
+}
+
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index fb7a17c77ae..30578f017f0 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -274,6 +274,7 @@ public:
void shadowIntensity(int intensity) {
_shadowIntensity = intensity;
}
+ int getRandomNumber(int max);
private:
void loadPatches(Common::SeekableReadStream *file, Database & db);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 26af2b140ce..8e40e45e62e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -312,7 +312,7 @@ void Process::resetMousePointer() {
void Process::getRandomNumber() {
int max = pop();
- int value = max > 0 ? _engine->_random.getRandomNumber(max - 1) : 0;
+ int value = _engine->getRandomNumber(max);
debug("random %d -> %d", max, value);
push(value);
}
Commit: 93e295b4fc0c3643a7c682f6523e416f4e1d179e
https://github.com/scummvm/scummvm/commit/93e295b4fc0c3643a7c682f6523e416f4e1d179e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:51+01:00
Commit Message:
AGDS: reorganised animation tick to be closer to engine's
Changed paths:
engines/agds/animation.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 8c0bd71ec88..c046a8bb3c7 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -141,31 +141,41 @@ bool Animation::tick() {
return true;
}
- bool eov = _flic->endOfVideo();
- if (eov) {
- if (!_loop) {
- if (!_phaseVar.empty())
- _engine->setGlobal(_phaseVar, -1);
- }
+ bool eov = _phase >= _frames;
+ if (_phaseVarControlled && eov) {
+ freeFrame();
+ _engine->setGlobal(_phaseVar, -1);
+ return true;
+ }
- if (_phaseVarControlled) {
- freeFrame();
- _engine->reactivate(_process, true);
+ if (!eov)
+ decodeNextFrame();
+
+ eov = _phase >= _frames;
+
+ if (!_process.empty()) {
+ if (!_phaseVar.empty())
+ _engine->setGlobal(_phaseVar, _phase - 1);
+ if (_phase || _phaseVarControlled) {
+ if (eov && _random) {
+ rewind();
+ _delay = _engine->getRandomNumber(_random);
+ return true;
+ }
return true;
}
- if (_loop)
- rewind();
- else
- return false;
}
- decodeNextFrame();
- if (!_process.empty()) {
- if (!_phaseVar.empty()) {
+ if (eov && (!_loop || --_cycles <= 0)) {
+ if (!_phaseVar.empty())
_engine->setGlobal(_phaseVar, _phase - 1);
+ else
_engine->reactivate(_process, true);
- }
+ return false;
}
+
+ if (eov)
+ rewind();
return true;
}
Commit: c05ed093aaa22d3d948c6899b532c513ce738115
https://github.com/scummvm/scummvm/commit/c05ed093aaa22d3d948c6899b532c513ce738115
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:51+01:00
Commit Message:
AGDS: activate dialog callbacks synchronously
Changed paths:
engines/agds/dialog.cpp
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 4a0b2cfe3b4..7971f6be2d0 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -175,7 +175,7 @@ bool Dialog::tick() {
debug("dialog value %s = %d (0x%04x), sample index: %d", line.c_str(), value, value, _currentSoundIndex);
dialog_var->setInteger(value);
- _engine->reactivate(_dialogProcessName);
+ _engine->reactivate(_dialogProcessName, true);
} else
warning("invalid dialog directive: %s", line.c_str());
}
Commit: c441007f644e2ecaba1b2c9c26b3a795845f48c9
https://github.com/scummvm/scummvm/commit/c441007f644e2ecaba1b2c9c26b3a795845f48c9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:51+01:00
Commit Message:
AGDS: remove animation cache
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 1822e07122e..c6832fb4a07 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -338,7 +338,6 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
for(uint i = 0; i < _processes.size(); ++i) {
_processes[i].reset();
}
- _animations.clear();
auto patch = getPatch(name);
bool doPatch = patch && loadingType != ScreenLoadingType::SaveOrLoad;
@@ -805,9 +804,6 @@ int AGDSEngine::getGlobal(const Common::String &name) const {
Animation *AGDSEngine::loadAnimation(const Common::String &name) {
debug("loadAnimation %s", name.c_str());
- AnimationsType::iterator i = _animations.find(name);
- if (i != _animations.end())
- return i->_value;
Common::SeekableReadStream *stream = _resourceManager.getResource(name);
if (!stream)
@@ -816,7 +812,6 @@ Animation *AGDSEngine::loadAnimation(const Common::String &name) {
if (!animation->load(stream, name))
error("could not load animation from %s", name.c_str());
- _animations[name] = animation;
return animation;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 30578f017f0..123bbe5b9a1 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -284,7 +284,6 @@ private:
typedef Common::Array<Common::String> SystemVariablesListType;
typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
- typedef Common::HashMap<Common::String, Animation *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> AnimationsType;
typedef Common::HashMap<int, Font *> FontsType;
typedef Common::HashMap<Common::String, PatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PatchesType;
typedef Common::HashMap<Common::String, ObjectPatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectPatchesType;
@@ -298,7 +297,6 @@ private:
PictureCacheLookup _pictureCacheLookup;
int _pictureCacheId;
FontsType _fonts;
- AnimationsType _animations;
ProcessListType _processes;
PatchesType _patches;
ObjectPatchesType _objectPatches;
Commit: 1cbad8d43ad02f547ec4e7881707b12a67abec6c
https://github.com/scummvm/scummvm/commit/1cbad8d43ad02f547ec4e7881707b12a67abec6c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:51+01:00
Commit Message:
AGDS: moved opcodes switch and processing to process.cpp
Changed paths:
engines/agds/process.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 26db9cae2bf..71073f80640 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -272,4 +272,152 @@ void Process::run() {
#undef BINARY_OP
+//fixme: add trace here
+#define AGDS_OP(NAME, METHOD) \
+ case NAME: \
+ METHOD(); \
+ break;
+
+#define AGDS_OP_C(NAME, METHOD) \
+ case NAME: { \
+ int8 arg = next(); \
+ METHOD(arg); \
+ } break;
+
+#define AGDS_OP_B(NAME, METHOD) \
+ case NAME: { \
+ uint8 arg = next(); \
+ METHOD(arg); \
+ } break;
+
+#define AGDS_OP_W(NAME, METHOD) \
+ case NAME: { \
+ int16 arg = next16(); \
+ METHOD(arg); \
+ } break;
+
+#define AGDS_OP_U(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg = next16(); \
+ METHOD(arg); \
+ } break;
+
+#define AGDS_OP_UU(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg1 = next16(); \
+ uint16 arg2 = next16(); \
+ METHOD(arg1, arg2); \
+ } break;
+
+#define AGDS_OP_UD(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg1 = next16(); \
+ uint32 arg2 = next16(); \
+ METHOD(static_cast<int32>(arg1 | (arg2 << 16))); \
+ } break;
+
+
+ProcessExitCode Process::resume() {
+ _exitCode = kExitCodeDestroy;
+ if (_timer) {
+ --_timer;
+ return kExitCodeSuspend;
+ }
+
+ const Object::CodeType &code = _object->getCode();
+ while (active() && _ip < code.size()) {
+ if (_timer) {
+ return kExitCodeSuspend;
+ }
+ _lastIp = _ip;
+ uint8 op = next();
+ //debug("CODE %04x: %u", _lastIp, (uint)op);
+ switch (op) {
+ AGDS_OPCODE_LIST(
+ AGDS_OP,
+ AGDS_OP_C, AGDS_OP_B,
+ AGDS_OP_W, AGDS_OP_U,
+ AGDS_OP_UD, AGDS_OP_UU
+ )
+ default:
+ error("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _ip - 1, (unsigned)op, (unsigned)op);
+ fail();
+ break;
+ }
+ }
+
+ if (active()) {
+ debug("code ended, exiting...");
+ }
+
+ return _exitCode;
+}
+
+#define AGDS_DIS(NAME, METHOD) \
+ case NAME: \
+ source += Common::String::format("%s\n", #NAME); \
+ break;
+
+#define AGDS_DIS_C(NAME, METHOD) \
+ case NAME: { \
+ int8 arg = code[ip++]; \
+ source += Common::String::format("%s %d\n", #NAME, (int)arg); \
+ } break;
+
+#define AGDS_DIS_B(NAME, METHOD) \
+ case NAME: { \
+ uint8 arg = code[ip++]; \
+ source += Common::String::format("%s %u\n", #NAME, (uint)arg); \
+ } break;
+
+#define AGDS_DIS_W(NAME, METHOD) \
+ case NAME: { \
+ int16 arg = code[ip++]; arg |= ((int16)code[ip++]) << 8; \
+ source += Common::String::format("%s %d\n", #NAME, (int)arg); \
+ } break;
+
+#define AGDS_DIS_U(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg = code[ip++]; arg |= ((uint16)code[ip++]) << 8; \
+ source += Common::String::format("%s %u\n", #NAME, (uint)arg); \
+ } break;
+
+#define AGDS_DIS_UU(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg1 = code[ip++]; arg1 |= ((uint16)code[ip++]) << 8; \
+ uint16 arg2 = code[ip++]; arg2 |= ((uint16)code[ip++]) << 8; \
+ source += Common::String::format("%s %u %u\n", #NAME, (uint)arg1, (uint)arg2); \
+ } break;
+
+#define AGDS_DIS_UD(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg1 = code[ip++]; arg1 |= ((uint16)code[ip++]) << 8; \
+ uint16 arg2 = code[ip++]; arg2 |= ((uint16)code[ip++]) << 8; \
+ source += Common::String::format("%s %u\n", #NAME, (uint)(arg1 | (arg2 << 16))); \
+ } break;
+
+Common::String Process::disassemble(ObjectPtr object) {
+ Common::String source = Common::String::format("Object %s disassembly:\n", object->getName().c_str());
+
+ const auto &code = object->getCode();
+ uint ip = 0;
+ while (ip < code.size()) {
+ uint8 op = code[ip++];
+ source += Common::String::format("%04x: %02x: ", ip - 1, op);
+ switch (op) {
+ AGDS_OPCODE_LIST(
+ AGDS_DIS,
+ AGDS_DIS_C, AGDS_DIS_B,
+ AGDS_DIS_W, AGDS_DIS_U,
+ AGDS_DIS_UD, AGDS_DIS_UU
+ )
+ default:
+ source += Common::String::format("unknown opcode 0x%02x (%u)\n", (unsigned)op, (unsigned)op);
+ break;
+ }
+ }
+ source += Common::String::format("Object %s disassembly end\n", object->getName().c_str());
+ return source;
+}
+
} // namespace AGDS
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 8e40e45e62e..d6e916bf21f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1656,152 +1656,4 @@ void Process::setCharacterNotifyVars() {
_engine->textLayout().setCharDirectionNotifyVar(arg2);
}
-//fixme: add trace here
-#define AGDS_OP(NAME, METHOD) \
- case NAME: \
- METHOD(); \
- break;
-
-#define AGDS_OP_C(NAME, METHOD) \
- case NAME: { \
- int8 arg = next(); \
- METHOD(arg); \
- } break;
-
-#define AGDS_OP_B(NAME, METHOD) \
- case NAME: { \
- uint8 arg = next(); \
- METHOD(arg); \
- } break;
-
-#define AGDS_OP_W(NAME, METHOD) \
- case NAME: { \
- int16 arg = next16(); \
- METHOD(arg); \
- } break;
-
-#define AGDS_OP_U(NAME, METHOD) \
- case NAME: { \
- uint16 arg = next16(); \
- METHOD(arg); \
- } break;
-
-#define AGDS_OP_UU(NAME, METHOD) \
- case NAME: { \
- uint16 arg1 = next16(); \
- uint16 arg2 = next16(); \
- METHOD(arg1, arg2); \
- } break;
-
-#define AGDS_OP_UD(NAME, METHOD) \
- case NAME: { \
- uint16 arg1 = next16(); \
- uint32 arg2 = next16(); \
- METHOD(static_cast<int32>(arg1 | (arg2 << 16))); \
- } break;
-
-
-ProcessExitCode Process::resume() {
- _exitCode = kExitCodeDestroy;
- if (_timer) {
- --_timer;
- return kExitCodeSuspend;
- }
-
- const Object::CodeType &code = _object->getCode();
- while (active() && _ip < code.size()) {
- if (_timer) {
- return kExitCodeSuspend;
- }
- _lastIp = _ip;
- uint8 op = next();
- //debug("CODE %04x: %u", _lastIp, (uint)op);
- switch (op) {
- AGDS_OPCODE_LIST(
- AGDS_OP,
- AGDS_OP_C, AGDS_OP_B,
- AGDS_OP_W, AGDS_OP_U,
- AGDS_OP_UD, AGDS_OP_UU
- )
- default:
- error("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _ip - 1, (unsigned)op, (unsigned)op);
- fail();
- break;
- }
- }
-
- if (active()) {
- debug("code ended, exiting...");
- }
-
- return _exitCode;
-}
-
-#define AGDS_DIS(NAME, METHOD) \
- case NAME: \
- source += Common::String::format("%s\n", #NAME); \
- break;
-
-#define AGDS_DIS_C(NAME, METHOD) \
- case NAME: { \
- int8 arg = code[ip++]; \
- source += Common::String::format("%s %d\n", #NAME, (int)arg); \
- } break;
-
-#define AGDS_DIS_B(NAME, METHOD) \
- case NAME: { \
- uint8 arg = code[ip++]; \
- source += Common::String::format("%s %u\n", #NAME, (uint)arg); \
- } break;
-
-#define AGDS_DIS_W(NAME, METHOD) \
- case NAME: { \
- int16 arg = code[ip++]; arg |= ((int16)code[ip++]) << 8; \
- source += Common::String::format("%s %d\n", #NAME, (int)arg); \
- } break;
-
-#define AGDS_DIS_U(NAME, METHOD) \
- case NAME: { \
- uint16 arg = code[ip++]; arg |= ((uint16)code[ip++]) << 8; \
- source += Common::String::format("%s %u\n", #NAME, (uint)arg); \
- } break;
-
-#define AGDS_DIS_UU(NAME, METHOD) \
- case NAME: { \
- uint16 arg1 = code[ip++]; arg1 |= ((uint16)code[ip++]) << 8; \
- uint16 arg2 = code[ip++]; arg2 |= ((uint16)code[ip++]) << 8; \
- source += Common::String::format("%s %u %u\n", #NAME, (uint)arg1, (uint)arg2); \
- } break;
-
-#define AGDS_DIS_UD(NAME, METHOD) \
- case NAME: { \
- uint16 arg1 = code[ip++]; arg1 |= ((uint16)code[ip++]) << 8; \
- uint16 arg2 = code[ip++]; arg2 |= ((uint16)code[ip++]) << 8; \
- source += Common::String::format("%s %u\n", #NAME, (uint)(arg1 | (arg2 << 16))); \
- } break;
-
-Common::String Process::disassemble(ObjectPtr object) {
- Common::String source = Common::String::format("Object %s disassembly:\n", object->getName().c_str());
-
- const auto &code = object->getCode();
- uint ip = 0;
- while (ip < code.size()) {
- uint8 op = code[ip++];
- source += Common::String::format("%04x: %02x: ", ip - 1, op);
- switch (op) {
- AGDS_OPCODE_LIST(
- AGDS_DIS,
- AGDS_DIS_C, AGDS_DIS_B,
- AGDS_DIS_W, AGDS_DIS_U,
- AGDS_DIS_UD, AGDS_DIS_UU
- )
- default:
- source += Common::String::format("unknown opcode 0x%02x (%u)\n", (unsigned)op, (unsigned)op);
- break;
- }
- }
- source += Common::String::format("Object %s disassembly end\n", object->getName().c_str());
- return source;
-}
-
} // namespace AGDS
Commit: edf0e7a9578fba4f13c5a8bd4293ab6af4c37b1a
https://github.com/scummvm/scummvm/commit/edf0e7a9578fba4f13c5a8bd4293ab6af4c37b1a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:51+01:00
Commit Message:
AGDS: implement process stopping from removeScreenObject
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process.cpp
engines/agds/process.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c6832fb4a07..81b0f21b3f4 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1293,12 +1293,16 @@ void AGDSEngine::reactivate(const Common::String &name, bool runNow) {
}
}
-void AGDSEngine::stopProcess(const Common::String & name) {
+void AGDSEngine::stopProcess(const Common::String & name, bool stopNow) {
for(uint i = 0; i < _processes.size(); ++i) {
ProcessPtr &process = _processes[i];
if (process && process->getName() == name) {
debug("stopping %s...", name.c_str());
- process->done();
+ if (stopNow) {
+ process->done();
+ } else {
+ process->stopOnSuspend();
+ }
}
}
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 123bbe5b9a1..d3932a2d47f 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -123,7 +123,7 @@ public:
ObjectPtr runObject(const Common::String & name, const Common::String &prototype = Common::String(), bool allowInitialise = true);
void runObject(const ObjectPtr &object);
void runProcess(const ObjectPtr &object, uint ip = 0);
- void stopProcess(const Common::String & name);
+ void stopProcess(const Common::String & name, bool stopNow = false);
void reactivate(const Common::String &name, bool runNow = false);
void resetCurrentScreen();
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 71073f80640..9ce027d1be9 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -28,15 +28,17 @@
namespace AGDS {
-Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) : _engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object), _ip(ip),
- _status(kStatusActive), _exitCode(kExitCodeDestroy),
- _tileWidth(16), _tileHeight(16), _tileResource(0), _tileIndex(0),
- _timer(0),
- _animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0),
- _phaseVarControlled(false), _animationSpeed(100),
- _samplePeriodic(false), _sampleAmbient(false),
- _filmSubtitlesResource(-1)
- {
+Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
+ _engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object),
+ _ip(ip), _lastIp(ip), _stopping(false),
+ _status(kStatusActive), _exitCode(kExitCodeDestroy),
+ _tileWidth(16), _tileHeight(16), _tileResource(0), _tileIndex(0),
+ _timer(0),
+ _animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0),
+ _phaseVarControlled(false), _animationSpeed(100),
+ _samplePeriodic(false), _sampleAmbient(false),
+ _filmSubtitlesResource(-1)
+ {
updateWithCurrentMousePosition();
}
@@ -72,6 +74,37 @@ void Process::error(const char *str, ...) {
_status = kStatusError;
}
+void Process::suspend(ProcessExitCode exitCode, const Common::String &arg1, const Common::String &arg2) {
+ debug("suspend %d", exitCode);
+ if (active())
+ _status = kStatusPassive;
+ if (_stopping && exitCode == kExitCodeSuspend) {
+ debug("stopping process of removed object");
+ done();
+ }
+ _exitCode = exitCode;
+ _exitIntArg1 = 0;
+ _exitIntArg2 = 0;
+ _exitArg1 = arg1;
+ _exitArg2 = arg2;
+}
+
+void Process::suspend(ProcessExitCode exitCode, int arg1, int arg2) {
+ debug("suspend %d", exitCode);
+ if (active())
+ _status = kStatusPassive;
+ if (_stopping && exitCode == kExitCodeSuspend) {
+ debug("stopping process of removed object");
+ done();
+ }
+ _exitCode = exitCode;
+ _exitIntArg1 = arg1;
+ _exitIntArg2 = arg2;
+ _exitArg1.clear();
+ _exitArg2.clear();
+}
+
+
uint8 Process::next() {
const Object::CodeType & code = _object->getCode();
if (_ip < code.size()) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 147f6617aab..df44176e42a 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -47,6 +47,7 @@ private:
ObjectPtr _object;
StackType _stack;
unsigned _ip, _lastIp;
+ bool _stopping;
Status _status;
ProcessExitCode _exitCode;
Common::String _exitArg1, _exitArg2;
@@ -116,27 +117,9 @@ private:
Common::String getCloneVarName(const Common::String & arg1, const Common::String & arg2);
- void suspend(ProcessExitCode exitCode, const Common::String &arg1, const Common::String &arg2 = Common::String()) {
- debug("suspend %d", exitCode);
- if (active())
- _status = kStatusPassive;
- _exitCode = exitCode;
- _exitIntArg1 = 0;
- _exitIntArg2 = 0;
- _exitArg1 = arg1;
- _exitArg2 = arg2;
- }
+ void suspend(ProcessExitCode exitCode, const Common::String &arg1, const Common::String &arg2 = Common::String());
- void suspend(ProcessExitCode exitCode, int arg1 = 0, int arg2 = 0) {
- debug("suspend %d", exitCode);
- if (active())
- _status = kStatusPassive;
- _exitCode = exitCode;
- _exitIntArg1 = arg1;
- _exitIntArg2 = arg2;
- _exitArg1.clear();
- _exitArg2.clear();
- }
+ void suspend(ProcessExitCode exitCode, int arg1 = 0, int arg2 = 0);
ProcessExitCode resume();
void setupAnimation(Animation *animation);
@@ -178,6 +161,9 @@ public:
void pause() {
_status = kStatusPassive;
}
+ void stopOnSuspend() {
+ _stopping = true;
+ }
bool finished() const {
return _status == kStatusDone || _status == kStatusError;
Commit: 19a1d0c2fa8a8312f4c332c20e5f8c4a9d11f529
https://github.com/scummvm/scummvm/commit/19a1d0c2fa8a8312f4c332c20e5f8c4a9d11f529
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:51+01:00
Commit Message:
AGDS: smooth rewinding (do not free frame), fix looped animations
Changed paths:
engines/agds/animation.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index c046a8bb3c7..c94f6abb4eb 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -117,7 +117,6 @@ void Animation::decodeNextFrame() {
}
void Animation::rewind() {
- freeFrame();
_phase = 0;
_flic->rewind();
}
@@ -151,12 +150,10 @@ bool Animation::tick() {
if (!eov)
decodeNextFrame();
- eov = _phase >= _frames;
-
if (!_process.empty()) {
if (!_phaseVar.empty())
_engine->setGlobal(_phaseVar, _phase - 1);
- if (_phase || _phaseVarControlled) {
+ if (/*_phase || */_phaseVarControlled) {
if (eov && _random) {
rewind();
_delay = _engine->getRandomNumber(_random);
@@ -166,7 +163,7 @@ bool Animation::tick() {
}
}
- if (eov && (!_loop || --_cycles <= 0)) {
+ if (eov && !_loop && --_cycles <= 0) {
if (!_phaseVar.empty())
_engine->setGlobal(_phaseVar, _phase - 1);
else
Commit: 2a3e3e167bd4aa2114211f88b7f2f5f9da542527
https://github.com/scummvm/scummvm/commit/2a3e3e167bd4aa2114211f88b7f2f5f9da542527
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:52+01:00
Commit Message:
AGDS: fix scrolling pos in Screen::find
Changed paths:
engines/agds/screen.cpp
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 8016405e256..1c284d1b8a8 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -260,12 +260,12 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
}
Common::Array<ObjectPtr> Screen::find(Common::Point pos) const {
- pos += _scroll;
Common::Array<ObjectPtr> objects;
objects.reserve(_children.size());
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
- if (object->pointIn(pos) && object->alive()) {
+ auto visiblePos = (object->scale() >= 0)? pos + _scroll: pos;
+ if (object->pointIn(visiblePos) && object->alive()) {
objects.insert_at(0, object);
}
}
Commit: 80a4947f7fe117ff28805f819779898251dd54b2
https://github.com/scummvm/scummvm/commit/80a4947f7fe117ff28805f819779898251dd54b2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:52+01:00
Commit Message:
AGDS: pass allowInitialise to loadObject (in loadScreen)
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 81b0f21b3f4..699ce363d26 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -343,10 +343,8 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
bool doPatch = patch && loadingType != ScreenLoadingType::SaveOrLoad;
_currentScreenName = name;
- auto screenObject = loadObject(name);
+ auto screenObject = loadObject(name, Common::String(), doPatch? false: true);
_currentScreen = new Screen(this, screenObject, loadingType, previousScreenName);
- if (doPatch)
- screenObject->allowInitialise(false);
runProcess(screenObject);
Commit: 837b10e8ce13528159298c6598732220fc2c7607
https://github.com/scummvm/scummvm/commit/837b10e8ce13528159298c6598732220fc2c7607
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:52+01:00
Commit Message:
AGDS: more logs in patch
Changed paths:
engines/agds/patch.cpp
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index 02dcf2f7f8f..5ea46ac1b96 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -22,6 +22,7 @@ void Patch::load(Common::ReadStream *stream) {
byte extended = stream->readByte();
screenRegionName = readString(stream);
prevScreenName = readString(stream);
+ debug("patch screen region: %s, prev: %s", screenRegionName.c_str(), prevScreenName.c_str());
if (extended == 0)
return;
@@ -43,6 +44,7 @@ void Patch::load(Common::ReadStream *stream) {
for(uint i = 0; i < object_count; ++i) {
int flag = stream->readSint16LE();
Common::String name = readString(stream);
+ debug("patch object %s %d", name.c_str(), flag);
objects.push_back(Object(name, flag));
}
}
Commit: 874732a98b6f578773c908b6601b056364d8f579
https://github.com/scummvm/scummvm/commit/874732a98b6f578773c908b6601b056364d8f579
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:52+01:00
Commit Message:
AGDS: fix screen patch check
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 699ce363d26..cfd3efa4ab9 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -341,9 +341,10 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
auto patch = getPatch(name);
bool doPatch = patch && loadingType != ScreenLoadingType::SaveOrLoad;
+ bool hasScreenPatch = patch && !patch->screenRegionName.empty();
_currentScreenName = name;
- auto screenObject = loadObject(name, Common::String(), doPatch? false: true);
+ auto screenObject = loadObject(name, Common::String(), !hasScreenPatch);
_currentScreen = new Screen(this, screenObject, loadingType, previousScreenName);
runProcess(screenObject);
Commit: 1f8b5fa89725f109e506c40d5e0cdd3e15b655b1
https://github.com/scummvm/scummvm/commit/1f8b5fa89725f109e506c40d5e0cdd3e15b655b1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:52+01:00
Commit Message:
AGDS: fix loading of screen patch preallocated by incref/decref
Changed paths:
engines/agds/agds.cpp
engines/agds/patch.cpp
engines/agds/patch.h
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index cfd3efa4ab9..931ea759de4 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -341,7 +341,7 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
auto patch = getPatch(name);
bool doPatch = patch && loadingType != ScreenLoadingType::SaveOrLoad;
- bool hasScreenPatch = patch && !patch->screenRegionName.empty();
+ bool hasScreenPatch = doPatch && patch->screenSaved;
_currentScreenName = name;
auto screenObject = loadObject(name, Common::String(), !hasScreenPatch);
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index 5ea46ac1b96..87acc800b65 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -19,12 +19,10 @@ void ObjectPatch::save(Common::WriteStream *stream) const {
}
void Patch::load(Common::ReadStream *stream) {
- byte extended = stream->readByte();
+ screenSaved = stream->readByte();
screenRegionName = readString(stream);
prevScreenName = readString(stream);
- debug("patch screen region: %s, prev: %s", screenRegionName.c_str(), prevScreenName.c_str());
- if (extended == 0)
- return;
+ debug("patch screen, valid: %d region: %s, prev: %s", screenSaved, screenRegionName.c_str(), prevScreenName.c_str());
loadingType = static_cast<ScreenLoadingType>(stream->readUint32LE());
characterPosition.x = stream->readUint32LE();
@@ -50,18 +48,14 @@ void Patch::load(Common::ReadStream *stream) {
}
void Patch::save(Common::WriteStream *stream) {
- int extended = 1;
- stream->writeByte(extended);
+ stream->writeByte(screenSaved);
writeString(stream, screenRegionName);
writeString(stream, prevScreenName);
- if (extended == 0)
- return;
-
stream->writeUint32LE(static_cast<uint>(loadingType));
stream->writeUint32LE(characterPosition.x);
stream->writeUint32LE(characterPosition.y);
- stream->writeUint32LE(characterDirection);
+ stream->writeSint32LE(characterDirection);
stream->writeUint32LE(characterPresent);
stream->writeUint32LE(objects.size());
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index b983cda2b60..23ed507a479 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -54,6 +54,7 @@ struct Patch {
Object(const Common::String &n, int f): name(n), flag(f) {}
};
+ bool screenSaved = false;
Common::String screenRegionName;
Common::String prevScreenName;
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 1c284d1b8a8..a60ea626da6 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -307,6 +307,7 @@ void Screen::load(const PatchPtr &patch) {
}
void Screen::save(const PatchPtr &patch) {
+ patch->screenSaved = 1;
patch->prevScreenName = _previousScreen;
patch->loadingType = _loadingType;
patch->objects.clear();
Commit: 4b15dfb321b0ff0597776d4460120185aa1512e8
https://github.com/scummvm/scummvm/commit/4b15dfb321b0ff0597776d4460120185aa1512e8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:52+01:00
Commit Message:
AGDS: remove animate call from setDirection
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 62a5451ab37..4a01e026c6e 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -134,8 +134,8 @@ void Character::direction(int dir) {
if (dir < 0)
return;
- _animationPos = Common::Point();
- animate(dir, 100, false);
+ //_animationPos = Common::Point();
+ //animate(dir, 100, false);
}
void Character::moveTo(const Common::String & processName, Common::Point dst, int dir) {
Commit: 7f92d1c04ce7419ef127a2aac6a441d94dffd281
https://github.com/scummvm/scummvm/commit/7f92d1c04ce7419ef127a2aac6a441d94dffd281
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:52+01:00
Commit Message:
AGDS: stop ambient sound before adding new one
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 931ea759de4..3ff53fbe447 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -943,6 +943,13 @@ void AGDSEngine::tell(Process &process, const Common::String ®ionName, Common
}
}
+void AGDSEngine::stopAmbientSound() {
+ if (_ambientSoundId >= 0) {
+ _mixer->stopID(_ambientSoundId);
+ _ambientSoundId = -1;
+ }
+}
+
void AGDSEngine::initSystemVariables() {
addSystemVar("inventory_scr", new StringSystemVariable());
@@ -1047,7 +1054,6 @@ void AGDSEngine::loadPatches(Common::SeekableReadStream *file, Database & db) {
debug("done loading patches");
}
-
Common::Error AGDSEngine::loadGameState(int slot) {
//saveAutosaveIfEnabled();
@@ -1061,6 +1067,8 @@ Common::Error AGDSEngine::loadGameState(int slot) {
if (!db.open(fileName, saveFile))
return Common::kReadingFailed;
+ stopAmbientSound();
+ _syncSoundId = -1;
_soundManager.stopAll();
{
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index d3932a2d47f..d80ece9f8be 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -241,7 +241,7 @@ public:
void playSoundSync(const Common::String &filename) {
_syncSoundId = playSound(Common::String(), Common::String(), filename, Common::String());
}
- void setAmbientSoundId(int id) { _ambientSoundId = id; }
+ void setAmbientSoundId(int id) { stopAmbientSound(); _ambientSoundId = id; }
void tell(Process &process, const Common::String ®ion, Common::String text, Common::String sound, bool npc);
@@ -277,6 +277,7 @@ public:
int getRandomNumber(int max);
private:
+ void stopAmbientSound();
void loadPatches(Common::SeekableReadStream *file, Database & db);
typedef Common::HashMap<int, Graphics::TransparentSurface *> PictureCacheType;
Commit: f9e203c45e31140027b912d495640da900c485d5
https://github.com/scummvm/scummvm/commit/f9e203c45e31140027b912d495640da900c485d5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:52+01:00
Commit Message:
AGDS: rename animationPaused to setPhaseVarControlledFlag
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 91b15e86521..dafea659528 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -136,7 +136,7 @@ enum Opcode {
kStub116 = 116,
kLoadAnimation = 117,
kLoadSample = 118,
- kSetAnimationPaused = 119,
+ kSetPhaseVarControlledFlag = 119,
kPlayerSay120 = 120,
kStub121 = 121,
kPlayerSay122 = 122,
@@ -363,7 +363,7 @@ enum Opcode {
OP(kScreenRemoveObject, removeScreenObject) \
OP(kLoadAnimation, loadAnimation) \
OP(kLoadSample, loadSample) \
- OP(kSetAnimationPaused, setAnimationPaused) \
+ OP(kSetPhaseVarControlledFlag, setPhaseVarControlledFlag) \
OP(kPlayerSay120, playerSay120) \
OP(kPlayerSay122, playerSay122) \
OP(kPlayerSay125, playerSay125) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d6e916bf21f..025e0796add 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -638,8 +638,8 @@ void Process::stub102() {
debug("stub102: load picture? %s", name.c_str());
}
-void Process::setAnimationPaused() {
- debug("setAnimationPaused");
+void Process::setPhaseVarControlledFlag() {
+ debug("setPhaseVarControlledFlag");
_phaseVarControlled = true;
}
Commit: bb9346e536cdea13e230df5b9453ef2d7872722a
https://github.com/scummvm/scummvm/commit/bb9346e536cdea13e230df5b9453ef2d7872722a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:52+01:00
Commit Message:
AGDS: do not start non-ambient samples by default
Changed paths:
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 025e0796add..2213e5b6e4d 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -165,7 +165,7 @@ void Process::loadAnimation() {
void Process::loadSample() {
Common::String name = popString();
debug("loadSample %s, phaseVar: %s, ambient: %d", name.c_str(), _phaseVar.c_str(), _sampleAmbient);
- int id = _engine->playSound(getName(), name, _engine->loadText(name), _phaseVar);
+ int id = _engine->playSound(getName(), name, _engine->loadText(name), _phaseVar, _sampleAmbient);
if (_sampleAmbient)
_engine->setAmbientSoundId(id);
}
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 6f6ab9f1912..7e375e6ef5e 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -134,7 +134,8 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
id = _nextId++;
_sounds.push_back(Sound(id, process, resource, filename, phaseVar, handle));
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, stream, id);
+ if (startPlaying)
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, stream, id);
//if (sound_off)
// setPhaseVar(_sounds.back(), 1);
return id;
Commit: 00ad4c047e930689077cf1a7901cfead97875682
https://github.com/scummvm/scummvm/commit/00ad4c047e930689077cf1a7901cfead97875682
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:52+01:00
Commit Message:
AGDS: log runNow flag in reactivate()
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3ff53fbe447..84ef1907a10 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1292,7 +1292,7 @@ void AGDSEngine::reactivate(const Common::String &name, bool runNow) {
for(uint i = 0; i < _processes.size(); ++i) {
ProcessPtr &process = _processes[i];
if (process && process->getName() == name) {
- debug("reactivate %s", name.c_str());
+ debug("reactivate %s now: %d", name.c_str(), runNow);
process->activate();
if (runNow)
process->run();
Commit: 890a5da625c6135cc89b242a917a0e4b5bcc157d
https://github.com/scummvm/scummvm/commit/890a5da625c6135cc89b242a917a0e4b5bcc157d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:53+01:00
Commit Message:
AGDS: do not return from dialog tick as we can miss dialog end signal, split directive processing into functions
Changed paths:
engines/agds/dialog.cpp
engines/agds/dialog.h
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 7971f6be2d0..9ba6e58ec67 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -121,68 +121,12 @@ bool Dialog::tick() {
debug("dialog line: %s", line.c_str());
if (line[0] == '@') {
- if (line.size() < 2 || line[1] == '@') //comment
- return true;
-
- line.erase(0, 1);
-
- if (line.hasPrefix("sound")) {
- debug("sound: %s", line.c_str());
- auto arg1 = line.find('(');
- if (arg1 == line.npos) {
- warning("invalid sound directive");
- return true;
- }
- ++arg1;
-
- auto comma1 = line.find(',', arg1);
- if (comma1 == line.npos) {
- warning("invalid sound directive, missing arg2");
- return true;
- }
- auto comma2 = line.find(',', comma1 + 1);
- if (comma2 == line.npos) {
- warning("invalid sound directive, missing arg3");
- return true;
- }
- auto end = line.find(')', comma2 + 1);
- if (end == line.npos) {
- warning("invalid sound directive");
- return true;
- }
- --end;
- Common::String name = line.substr(arg1, comma1 - arg1 - 1);
- Common::String sample = line.substr(comma1 + 1, comma2 - comma1 - 1);
- Common::String step = line.substr(comma2 + 1, end - comma2);
- debug("sound args = %s,%s,%s", name.c_str(), sample.c_str(), step.c_str());
- _sounds.push_back(Sound(name, sample, atoi(step.c_str())));
- } else {
- DialogDefsType::const_iterator it = _dialogDefs.find(line);
- if (it != _dialogDefs.end()) {
- int value = it->_value;
- _currentDef = line;
- if (!_currentDef.hasPrefix("vybervarianty") && !_currentDef.hasPrefix("varianta")) {
- _currentSoundIndex = -1;
-
- for(uint s = 0; s < _sounds.size(); ++s) {
- auto & sound = _sounds[s];
- if (_currentDef.hasPrefixIgnoreCase(sound.Name)) {
- _currentSoundIndex = s;
- break;
- }
- }
- }
- debug("dialog value %s = %d (0x%04x), sample index: %d", line.c_str(), value, value, _currentSoundIndex);
-
- dialog_var->setInteger(value);
- _engine->reactivate(_dialogProcessName, true);
- } else
- warning("invalid dialog directive: %s", line.c_str());
- }
+ processDirective(line);
} else if (line[0] == ' ') {
debug("text: %s", line.c_str() + 1);
dialog_var->setInteger(-3);
}
+
if (_dialogScriptPos >= n && !_dialogProcessName.empty()) {
_dialogProcessName.clear();
@@ -195,6 +139,72 @@ bool Dialog::tick() {
return true;
}
+void Dialog::processSoundDirective(const Common::String &line) {
+ debug("sound: %s", line.c_str());
+ auto arg1 = line.find('(');
+ if (arg1 == line.npos) {
+ warning("invalid sound directive");
+ return;
+ }
+ ++arg1;
+
+ auto comma1 = line.find(',', arg1);
+ if (comma1 == line.npos) {
+ warning("invalid sound directive, missing arg2");
+ return;
+ }
+ auto comma2 = line.find(',', comma1 + 1);
+ if (comma2 == line.npos) {
+ warning("invalid sound directive, missing arg3");
+ return;
+ }
+ auto end = line.find(')', comma2 + 1);
+ if (end == line.npos) {
+ warning("invalid sound directive");
+ return;
+ }
+ --end;
+ Common::String name = line.substr(arg1, comma1 - arg1 - 1);
+ Common::String sample = line.substr(comma1 + 1, comma2 - comma1 - 1);
+ Common::String step = line.substr(comma2 + 1, end - comma2);
+ debug("sound args = %s,%s,%s", name.c_str(), sample.c_str(), step.c_str());
+ _sounds.push_back(Sound(name, sample, atoi(step.c_str())));
+}
+
+void Dialog::processDirective(Common::String line) {
+ if (line.size() < 2 || line[1] == '@') {
+ debug("comment, bailing out");
+ return;
+ }
+
+ line.erase(0, 1);
+
+ if (line.hasPrefix("sound")) {
+ processSoundDirective(line);
+ } else {
+ DialogDefsType::const_iterator it = _dialogDefs.find(line);
+ if (it != _dialogDefs.end()) {
+ int value = it->_value;
+ _currentDef = line;
+ if (!_currentDef.hasPrefix("vybervarianty") && !_currentDef.hasPrefix("varianta")) {
+ _currentSoundIndex = -1;
+
+ for(uint s = 0; s < _sounds.size(); ++s) {
+ auto & sound = _sounds[s];
+ if (_currentDef.hasPrefixIgnoreCase(sound.Name)) {
+ _currentSoundIndex = s;
+ break;
+ }
+ }
+ }
+ debug("dialog value %s = %d (0x%04x), sample index: %d", line.c_str(), value, value, _currentSoundIndex);
+ _engine->getSystemVariable("dialog_var")->setInteger(value);
+ _engine->reactivate(_dialogProcessName, true);
+ } else
+ warning("invalid dialog directive: %s", line.c_str());
+ }
+}
+
Common::String Dialog::getNextDialogSound() {
if (_currentDef.empty())
return Common::String();
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
index a471f2255f2..f47120ee1bb 100644
--- a/engines/agds/dialog.h
+++ b/engines/agds/dialog.h
@@ -73,6 +73,9 @@ public:
void load(const Common::String &dialogScript, const Common::String & defs);
bool tick();
+private:
+ void processSoundDirective(const Common::String &line);
+ void processDirective(Common::String line);
};
Commit: 5a585b7feefe6de92b2233b90fea1319e3ebd6a8
https://github.com/scummvm/scummvm/commit/5a585b7feefe6de92b2233b90fea1319e3ebd6a8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:53+01:00
Commit Message:
AGDS: implement screen region patching
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index dafea659528..6d4dc2a0ac0 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -347,6 +347,7 @@ enum Opcode {
OP_U(kObjectRegisterUseObjectHandler, onObjectUse) \
OP(kObjectPatchSetText, objectPatchSetText) \
OP(kObjectPatchSetRegionName, objectPatchSetRegionName) \
+ OP(kScreenPatchSetRegionName, screenPatchSetRegionName) \
OP(kAnimateCharacter, animateCharacter) \
OP(kLoadCharacter, loadCharacter) \
OP(kAssociateCharacter, associateCharacter) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 2213e5b6e4d..18260c625ca 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -724,6 +724,25 @@ void Process::objectPatchSetRegionName() {
patch->region = regionName;
}
+void Process::screenPatchSetRegionName() {
+ Common::String regionName = popString();
+ Common::String screenName = popString();
+ debug("screenPatchSetRegionName: %s %s", screenName.c_str(), regionName.c_str());
+ auto screen = _engine->getCurrentScreen();
+ if (!screen) {
+ warning("no screen");
+ return;
+ }
+ if (screen->getName() == screenName) {
+ auto object = screen->getObject();
+ RegionPtr region = _engine->loadRegion(regionName);
+ debug("region: %s", region->toString().c_str());
+ object->region(region);
+ }
+ auto patch = _engine->createPatch(screenName);
+ patch->screenRegionName = regionName;
+}
+
void Process::screenObjectPatchIncRef() {
Common::String objectName = popString();
Common::String screenName = popString();
Commit: 74c2aa86999a0c3dc827d98b6fb35aafe65d5985
https://github.com/scummvm/scummvm/commit/74c2aa86999a0c3dc827d98b6fb35aafe65d5985
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:53+01:00
Commit Message:
AGDS: do not stop inventory onbjects removed from screen
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 18260c625ca..95a701554ec 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -284,7 +284,9 @@ void Process::removeScreenObject() {
debug("removeScreenObject: %s: removing object from its own body (sic)", name.c_str());
object->alive(false);
} else if (screen && screen->remove(name)) {
- _engine->stopProcess(name);
+ int index = _engine->inventory().find(name);
+ if (index < 0)
+ _engine->stopProcess(name);
} else
warning("removeScreenObject: object %s not found", name.c_str());
} else
Commit: 68c1d6ad10a22debdc3d47d256f15272394b90d7
https://github.com/scummvm/scummvm/commit/68c1d6ad10a22debdc3d47d256f15272394b90d7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:53+01:00
Commit Message:
AGDS: rename new game opcode
Changed paths:
engines/agds/opcode.h
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 6d4dc2a0ac0..4501f90d7b3 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -176,7 +176,7 @@ enum Opcode {
kLoadGame = 156,
kSaveGame = 157,
kQuit = 158,
- kExitProcessCreatePatch = 159,
+ kStartNewGame = 159,
kLoadSaveSlotNamePicture = 160,
kGetSaveGameName = 161,
kDisableInventory = 162,
@@ -416,7 +416,7 @@ enum Opcode {
OP(kStub174, stub174) \
OP(kStub192, stub192) \
OP(kQuit, quit) \
- OP(kExitProcessCreatePatch, exitProcessCreatePatch) \
+ OP(kStartNewGame, startNewGame) \
OP(kDisableInventory, disableInventory) \
OP(kEnableInventory, enableInventory) \
OP(kLoadPreviousScreen, loadPreviousScreen) \
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index ce16a83f7bb..b7fe0df4308 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -35,7 +35,7 @@ namespace AGDS {
kExitCodeLoadInventoryObject = 10,
kExitCodeMouseAreaChange = 11,
kExitCodeRunDialog = 12,
- kExitCodeCreatePatchLoadResources = 13,
+ kExitCodeNewGame = 13,
kExitCodeLoadGame = 14,
kExitCodeExitScreen = 15,
kExitCodeCloseInventory = 16,
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 95a701554ec..ebf44a5efda 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1114,8 +1114,8 @@ void Process::exitProcess() {
_exitCode = kExitCodeDestroy;
}
-void Process::exitProcessCreatePatch() {
- suspend(kExitCodeCreatePatchLoadResources);
+void Process::startNewGame() {
+ suspend(kExitCodeNewGame);
}
void Process::clearScreen() {
Commit: a597eb30f62482d95aad6d03f0707f274b1279c1
https://github.com/scummvm/scummvm/commit/a597eb30f62482d95aad6d03f0707f274b1279c1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:53+01:00
Commit Message:
AGDS: reworked process activation code, remove status dependency (original engine does not check it too)
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
engines/agds/textLayout.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 84ef1907a10..af53dfca61a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1300,16 +1300,12 @@ void AGDSEngine::reactivate(const Common::String &name, bool runNow) {
}
}
-void AGDSEngine::stopProcess(const Common::String & name, bool stopNow) {
+void AGDSEngine::stopProcess(const Common::String & name) {
for(uint i = 0; i < _processes.size(); ++i) {
ProcessPtr &process = _processes[i];
if (process && process->getName() == name) {
debug("stopping %s...", name.c_str());
- if (stopNow) {
- process->done();
- } else {
- process->stopOnSuspend();
- }
+ process->done();
}
}
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index d80ece9f8be..5657b6e3d87 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -123,7 +123,7 @@ public:
ObjectPtr runObject(const Common::String & name, const Common::String &prototype = Common::String(), bool allowInitialise = true);
void runObject(const ObjectPtr &object);
void runProcess(const ObjectPtr &object, uint ip = 0);
- void stopProcess(const Common::String & name, bool stopNow = false);
+ void stopProcess(const Common::String & name);
void reactivate(const Common::String &name, bool runNow = false);
void resetCurrentScreen();
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 9ce027d1be9..9e5eae58b1a 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -30,8 +30,8 @@ namespace AGDS {
Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
_engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object),
- _ip(ip), _lastIp(ip), _stopping(false),
- _status(kStatusActive), _exitCode(kExitCodeDestroy),
+ _ip(ip), _lastIp(ip),
+ _exited(false), _status(kStatusActive), _exitCode(kExitCodeDestroy),
_tileWidth(16), _tileHeight(16), _tileResource(0), _tileIndex(0),
_timer(0),
_animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0),
@@ -76,12 +76,7 @@ void Process::error(const char *str, ...) {
void Process::suspend(ProcessExitCode exitCode, const Common::String &arg1, const Common::String &arg2) {
debug("suspend %d", exitCode);
- if (active())
- _status = kStatusPassive;
- if (_stopping && exitCode == kExitCodeSuspend) {
- debug("stopping process of removed object");
- done();
- }
+ _exited = true;
_exitCode = exitCode;
_exitIntArg1 = 0;
_exitIntArg2 = 0;
@@ -91,12 +86,7 @@ void Process::suspend(ProcessExitCode exitCode, const Common::String &arg1, cons
void Process::suspend(ProcessExitCode exitCode, int arg1, int arg2) {
debug("suspend %d", exitCode);
- if (active())
- _status = kStatusPassive;
- if (_stopping && exitCode == kExitCodeSuspend) {
- debug("stopping process of removed object");
- done();
- }
+ _exited = true;
_exitCode = exitCode;
_exitIntArg1 = arg1;
_exitIntArg2 = arg2;
@@ -197,9 +187,23 @@ void Process::activate() {
}
}
+void Process::deactivate() {
+ switch(status()) {
+ case kStatusActive:
+ _status = Process::kStatusPassive;
+ break;
+ case kStatusDone:
+ case kStatusError:
+ break;
+ default:
+ break;
+ }
+}
void Process::run() {
- while(status() == kStatusActive) {
+ bool restart = true;
+ while(_status != kStatusDone && _status != kStatusError && restart) {
+ restart = false;
ProcessExitCode code = resume();
switch (code) {
case kExitCodeDestroy:
@@ -208,67 +212,73 @@ void Process::run() {
break;
case kExitCodeLoadScreenObjectAs:
case kExitCodeLoadScreenObject:
+ _status = kStatusPassive;
_object->lock();
_engine->runObject(getExitArg1(), getExitArg2());
_object->unlock();
activate();
- continue;
+ restart = true;
+ break;
case kExitCodeRunDialog:
+ _status = kStatusPassive;
_object->lock();
_engine->runDialog(getName(), getExitArg1());
_object->unlock();
+ deactivate();
break;
case kExitCodeSetNextScreen:
case kExitCodeSetNextScreenSaveOrLoad:
+ done();
debug("process %s launches screen: %s, saveorload: ", getName().c_str(), getExitArg1().c_str(), code == kExitCodeSetNextScreenSaveOrLoad);
_engine->setNextScreenName(getExitArg1(), code == kExitCodeSetNextScreenSaveOrLoad? ScreenLoadingType::SaveOrLoad: ScreenLoadingType::Normal);
- done();
break;
case kExitCodeMouseAreaChange:
+ _status = kStatusPassive;
+ _object->lock();
_engine->changeMouseArea(getExitIntArg1(), getExitIntArg2());
- activate();
- continue;
+ _object->unlock();
+ deactivate();
+ restart = true;
+ break;
case kExitCodeLoadInventoryObject:
+ _status = kStatusPassive;
_object->lock();
_engine->inventory().add(_engine->runObject(getExitArg1()));
_object->unlock();
- activate();
- continue;
+ deactivate();
+ restart = true;
+ break;
case kExitCodeCloseInventory:
_object->lock();
_engine->inventory().enable(false);
updateWithCurrentMousePosition();
_object->unlock();
- activate();
- return; //some codes are special, they needed to exit loop and keep process active
+ break;
case kExitCodeSuspend:
updateWithCurrentMousePosition();
- activate();
- return; //some codes are special, they needed to exit loop and keep process active
- case kExitCodeCreatePatchLoadResources:
- {
- debug("exitProcessCreatePatch");
- _engine->newGame();
- activate();
- }
+ break;
+ case kExitCodeNewGame:
+ suspend();
+ _object->lock();
+ debug("exitProcessNewGame");
+ _engine->newGame();
break;
case kExitCodeLoadGame:
+ _status = kStatusPassive;
_object->lock();
if (_engine->loadGameState(getExitIntArg1()).getCode() == Common::kNoError) {
done();
} else {
debug("save loading failed, resuming execution...");
- activate(); //continue
}
_object->unlock();
+ _status = kStatusActive;
+ restart = true;
break;
case kExitCodeSaveGame:
- _object->lock();
if (_engine->saveGameState(getExitIntArg1(), "").getCode() != Common::kNoError) {
warning("failed to save game");
}
- _object->unlock();
- activate();
break;
default:
error("unknown process exit code %d", code);
@@ -358,7 +368,7 @@ ProcessExitCode Process::resume() {
}
const Object::CodeType &code = _object->getCode();
- while (active() && _ip < code.size()) {
+ while (!_exited && _ip < code.size()) {
if (_timer) {
return kExitCodeSuspend;
}
@@ -378,10 +388,7 @@ ProcessExitCode Process::resume() {
break;
}
}
-
- if (active()) {
- debug("code ended, exiting...");
- }
+ _exited = false;
return _exitCode;
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index df44176e42a..c4c16f6e6ef 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -47,8 +47,8 @@ private:
ObjectPtr _object;
StackType _stack;
unsigned _ip, _lastIp;
- bool _stopping;
Status _status;
+ bool _exited;
ProcessExitCode _exitCode;
Common::String _exitArg1, _exitArg2;
int _exitIntArg1, _exitIntArg2;
@@ -152,18 +152,13 @@ public:
return _status == kStatusPassive;
}
void activate();
+ void deactivate();
void done() {
_status = kStatusDone;
}
void fail() {
_status = kStatusError;
}
- void pause() {
- _status = kStatusPassive;
- }
- void stopOnSuspend() {
- _stopping = true;
- }
bool finished() const {
return _status == kStatusDone || _status == kStatusError;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index ebf44a5efda..42f8e48ddd4 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1112,6 +1112,7 @@ void Process::exitProcess() {
debug("exitProcess");
done();
_exitCode = kExitCodeDestroy;
+ _exited = true;
}
void Process::startNewGame() {
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 363a62dd532..6d0dda00d2b 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -40,7 +40,7 @@ void TextLayout::layout(AGDSEngine &engine, Process &process, const Common::Stri
}
_process = process.getName();
- process.pause();
+ process.deactivate();
_fontId = fontId;
_npc = npc;
Font *font = engine.getFont(fontId);
Commit: 0bb211956047cef25ca0df2fdf843edb739c3398
https://github.com/scummvm/scummvm/commit/0bb211956047cef25ca0df2fdf843edb739c3398
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:53+01:00
Commit Message:
AGDS: allow lclick with current object attached
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index af53dfca61a..94a986a469a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -574,7 +574,7 @@ Common::Error AGDSEngine::run() {
for(auto & object : objects) {
debug("found object %s", object->getName().c_str());
- uint ip;
+ uint ip = 0;
if (lclick) {
if (_currentInventoryObject) {
ip = object->getUseHandler(_currentInventoryObject->getName());
@@ -585,7 +585,8 @@ Common::Error AGDSEngine::run() {
}
if (ip)
debug("found use handler for current inventory object %s", _currentInventoryObject->getName().c_str());
- } else {
+ }
+ if (!ip) {
ip = object->getClickHandler();
if (ip)
debug("found click handler");
Commit: eeb7469d4a5d9510925c77f7089044fab51eab54
https://github.com/scummvm/scummvm/commit/eeb7469d4a5d9510925c77f7089044fab51eab54
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:53+01:00
Commit Message:
AGDS: remove readd inventory code
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 94a986a469a..9efbe2baae7 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -273,16 +273,6 @@ ObjectPtr AGDSEngine::runObject(const Common::String &name, const Common::String
return object;
}
-void AGDSEngine::reAddInventory() {
- if (!_currentScreen)
- return;
-
- for(auto & object : _inventory.entries()) {
- if (object)
- runObject(object);
- }
-}
-
PatchPtr AGDSEngine::getPatch(const Common::String &screenName) const {
auto it = _patches.find(screenName);
return it != _patches.end()? it->_value: PatchPtr();
@@ -358,7 +348,6 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
if (!patch->defaultMouseCursor.empty())
loadDefaultMouseCursor(patch->defaultMouseCursor);
}
- reAddInventory();
_loadingScreen = false;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 5657b6e3d87..45a16a2b3db 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -265,7 +265,6 @@ public:
return _hintMode;
}
- void reAddInventory();
PatchPtr getPatch(const Common::String &screenName) const;
PatchPtr createPatch(const Common::String &screenName);
ObjectPatchPtr getObjectPatch(const Common::String &screenName) const;
Commit: a85edad9f6cbfed7c220cdb79d6bfaeb0b944fe6
https://github.com/scummvm/scummvm/commit/a85edad9f6cbfed7c220cdb79d6bfaeb0b944fe6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:53+01:00
Commit Message:
AGDS: add logs in engine resource ctor/dtor
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 9efbe2baae7..f7b5bfa1fa4 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -390,6 +390,7 @@ Console *AGDSEngine::getConsole() {
void AGDSEngine::newGame() {
SystemVariable *doneVar = getSystemVariable("done_resources");
Common::String done = doneVar->getString();
+ debug("running engine resource dtor: %s", done.c_str());
runObject(done);
_patches.clear();
@@ -401,6 +402,7 @@ void AGDSEngine::newGame() {
SystemVariable *initVar = getSystemVariable("init_resources");
Common::String init = initVar->getString();
+ debug("running engine resource ctor: %s", init.c_str());
runObject(init);
}
Commit: e340f04a82aa527ab3fdc8e3aa6ffd3f76367f72
https://github.com/scummvm/scummvm/commit/e340f04a82aa527ab3fdc8e3aa6ffd3f76367f72
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:53+01:00
Commit Message:
AGDS: fix crash if inventory object has no picture
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index f7b5bfa1fa4..57f5f1defdf 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -667,8 +667,8 @@ Common::Error AGDSEngine::run() {
mouseCursor = _defaultMouseCursor;
if (userEnabled()) {
- if (_currentInventoryObject) {
- auto picture = _currentInventoryObject->getPicture();
+ auto picture = _currentInventoryObject? _currentInventoryObject->getPicture(): nullptr;
+ if (picture) {
Common::Rect srcRect = picture->getRect();
Common::Point dst = _mouse;
dst.x -= srcRect.width() / 2;
Commit: 26bd1c420a1102a6c423e9042eae6b77d4fe1ca6
https://github.com/scummvm/scummvm/commit/26bd1c420a1102a6c423e9042eae6b77d4fe1ca6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:53+01:00
Commit Message:
AGDS: remove noisy log
Changed paths:
engines/agds/agds.cpp
engines/agds/object.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 57f5f1defdf..ac6dad5ed21 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -788,7 +788,7 @@ int AGDSEngine::getGlobal(const Common::String &name) const {
if (i != _globals.end())
return i->_value;
else {
- debug("global %s was not declared, returning 0", name.c_str());
+ //debug("global %s was not declared, returning 0", name.c_str());
return 0;
}
}
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 7e309c74cf8..0b97261c7f6 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -205,7 +205,6 @@ public:
}
void setUserUseHandler(uint ip) {
- debug("OBJECT %s USER USE %04x", _name.c_str(), ip);
_userUseHandler = ip;
}
Commit: 0bb38022f04fcfd48130ca8c0d911ea37c1c926a
https://github.com/scummvm/scummvm/commit/0bb38022f04fcfd48130ca8c0d911ea37c1c926a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:54+01:00
Commit Message:
AGDS: implement setGlobalWithTop
Changed paths:
engines/agds/object.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 0b97261c7f6..90e8c4dc9e6 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -67,6 +67,7 @@ private:
Graphics::TransparentSurface * _picture;
Graphics::TransparentSurface * _rotatedPicture;
RegionPtr _region;
+ RegionPtr _trapRegion;
Animation * _animation;
Animation * _mouseCursor;
Common::Point _pos, _animationPos, _offset;
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 4501f90d7b3..b17ae85a0d3 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -66,7 +66,7 @@ enum Opcode {
kStub44 = 44,
kPostIncrementGlobal = 45,
kPostDecrementGlobal = 46,
- kStub47 = 47,
+ kSetGlobalWithTop = 47,
kSetGlobal = 48,
kIncrementGlobalByTop = 49,
kDecrementGlobalByTop = 50,
@@ -304,6 +304,7 @@ enum Opcode {
OP(kMul, mul) \
OP(kDiv, div) \
OP(kMod, mod) \
+ OP(kSetGlobalWithTop, setGlobalWithTop) \
OP(kSetGlobal, setGlobal) \
OP(kBoolOr, boolOr) \
OP(kBoolAnd, boolAnd) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 42f8e48ddd4..c5960593b2a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -326,6 +326,13 @@ void Process::setGlobal() {
_engine->setGlobal(name, value);
}
+void Process::setGlobalWithTop() {
+ Common::String name = popString();
+ int value = top();
+ debug("setGlobalWithTop %s %d", name.c_str(), value);
+ _engine->setGlobal(name, value);
+}
+
void Process::setPhaseVar() {
Common::String name = popString();
debug("setPhaseVar %s", name.c_str());
Commit: 93cb0540f6444fcd88ee9f6684ad7f7b332798c9
https://github.com/scummvm/scummvm/commit/93cb0540f6444fcd88ee9f6684ad7f7b332798c9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:54+01:00
Commit Message:
AGDS: implement signal animation end
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index b17ae85a0d3..c0e3424eb8b 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -239,7 +239,7 @@ enum Opcode {
kLeaveCharacterEx = 219,
kStopCharacter = 220,
kRestartAnimation = 221,
- kStub222 = 222,
+ kSignalAnimationEnd = 222,
kSetShadowIntensity = 223,
kSetNPCTellNotifyVar = 224,
kPauseAnimation = 225,
@@ -448,6 +448,7 @@ enum Opcode {
OP(kStopCharacter, stopCharacter) \
OP(kLeaveCharacterEx, leaveCharacterEx) \
OP(kRestartAnimation, restartAnimation) \
+ OP(kSignalAnimationEnd, signalAnimationEnd) \
OP(kSetShadowIntensity, setShadowIntensity) \
OP(kSetNPCTellNotifyVar, setNPCTellNotifyVar) \
OP(kPauseAnimation, pauseAnimation) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c5960593b2a..3380cb864c3 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1021,6 +1021,21 @@ void Process::restartAnimation() {
}
}
+void Process::signalAnimationEnd() {
+ Common::String phaseVar = popString();
+ debug("restartAnimation %s", phaseVar.c_str());
+ if (phaseVar.empty()) {
+ warning("no phaseVar");
+ return;
+ }
+ Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
+ if (animation) {
+ _engine->setGlobal(phaseVar, -2);
+ } else {
+ warning("no animation with phase var %s", phaseVar.c_str());
+ }
+}
+
void Process::setShadowIntensity() {
int value = pop();
debug("setShadowIntensity: %d", value);
Commit: 60e4ee929f62502c41218f66bfce45f214dbd469
https://github.com/scummvm/scummvm/commit/60e4ee929f62502c41218f66bfce45f214dbd469
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:54+01:00
Commit Message:
AGDS: implement character trap handler stub
Changed paths:
engines/agds/object.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 90e8c4dc9e6..fe21f70f030 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -80,6 +80,7 @@ private:
uint _userUseHandler;
uint _throwHandler;
uint _useOnHandler;
+ uint _trapHandler;
int _alpha;
int _scale;
bool _locked;
@@ -217,6 +218,11 @@ public:
_useOnHandler = ip;
}
+ void setTrapHandler(uint ip, RegionPtr region) {
+ _trapHandler = ip;
+ _trapRegion = region;
+ }
+
uint getUserUseHandler() const {
return _userUseHandler;
}
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index c0e3424eb8b..0f2e30aa853 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -84,7 +84,7 @@ enum Opcode {
kObjectRegisterHandlerC1 = 62,
kObjectRegisterUseObjectHandler = 63,
kObjectRegisterHandlerBD = 64,
- kObjectRegisterHandlerB9 = 65,
+ kObjectRegisterCharacterTrap = 65,
kLoadMouseCursorFromObject = 66,
kLoadRegionFromObject = 68,
kLoadPictureFromObject = 69,
@@ -320,7 +320,7 @@ enum Opcode {
OP_U(kObjectRegisterLookHandler, onLook) \
OP_U(kObjectRegisterUseHandler, onUse) \
OP_U(kObjectRegisterHandlerC1, onObjectC1) \
- OP_U(kObjectRegisterHandlerB9, onObjectB9) \
+ OP_U(kObjectRegisterCharacterTrap, onCharacterTrap) \
OP_U(kObjectRegisterHandlerBD, onObjectBD) \
OP(kLoadMouseCursorFromObject, loadMouseCursorFromObject) \
OP(kLoadRegionFromObject, loadRegionFromObject) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3380cb864c3..c81c92691e3 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1388,23 +1388,24 @@ void Process::onUse(uint16 size) {
}
void Process::onObjectC1(uint16 size) {
- debug("unknown (0xc1) [handler], %u instructions", size);
+ debug("unknown (0xc1) [handler] stub, %u instructions", size);
_ip += size;
}
void Process::onLook(uint16 size) {
- debug("look? [handler], %u instructions", size);
+ debug("look [handler], %u instructions", size);
_object->setExamineHandler(_ip);
_ip += size;
}
-void Process::onObjectB9(uint16 size) {
- debug("onObject(+B9) [handler], %u instructions", size);
+void Process::onCharacterTrap(uint16 size) {
+ auto regionName = popString();
+ debug("setCharacterTrap %s [handler], %u instructions", regionName.c_str(), size);
_ip += size;
}
void Process::onObjectBD(uint16 size) {
- debug("onObject(+BD) [handler], %u instructions", size);
+ debug("onObject(+BD) [handler] stub, %u instructions", size);
_ip += size;
}
Commit: 61a3cb2770e796077e363c88d4a5adb5c34c8c17
https://github.com/scummvm/scummvm/commit/61a3cb2770e796077e363c88d4a5adb5c34c8c17
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:54+01:00
Commit Message:
AGDS: properly implemented engine restart
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 9e5eae58b1a..6e04c281128 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -258,10 +258,13 @@ void Process::run() {
updateWithCurrentMousePosition();
break;
case kExitCodeNewGame:
- suspend();
+ deactivate();
_object->lock();
debug("exitProcessNewGame");
_engine->newGame();
+ _object->unlock();
+ activate();
+ restart = true;
break;
case kExitCodeLoadGame:
_status = kStatusPassive;
Commit: fba946698a952d6c5b856badc5673657082ab175
https://github.com/scummvm/scummvm/commit/fba946698a952d6c5b856badc5673657082ab175
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:54+01:00
Commit Message:
AGDS: slightly fixed indent madness
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ac6dad5ed21..1c99611c2b8 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -48,27 +48,27 @@
namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Engine(system),
- _gameDescription(gameDesc), _pictureCacheId(1), _sharedStorageIndex(-2),
- _shadowIntensity(0),
- _processes(MaxProcesses),
- _mjpgPlayer(), _filmStarted(0),
- _currentScreen(), _loadingScreen(false),
- _currentCharacter(),
- _defaultMouseCursor(),
- _nextScreenType(ScreenLoadingType::Normal),
- _mouse(400, 300),
- _userEnabled(true), _systemUserEnabled(true),
- _currentRegion(),
- _random("agds"),
- _inventoryRegion(),
- _soundManager(this, system->getMixer()),
- _inventory(this),
- _dialog(this),
- _tellTextTimer(0),
- _syncSoundId(-1),
- _ambientSoundId(-1),
- _fastMode(true),
- _hintMode(false) {
+ _gameDescription(gameDesc), _pictureCacheId(1), _sharedStorageIndex(-2),
+ _shadowIntensity(0),
+ _processes(MaxProcesses),
+ _mjpgPlayer(), _filmStarted(0),
+ _currentScreen(), _loadingScreen(false),
+ _currentCharacter(),
+ _defaultMouseCursor(),
+ _nextScreenType(ScreenLoadingType::Normal),
+ _mouse(400, 300),
+ _userEnabled(true), _systemUserEnabled(true),
+ _currentRegion(),
+ _random("agds"),
+ _inventoryRegion(),
+ _soundManager(this, system->getMixer()),
+ _inventory(this),
+ _dialog(this),
+ _tellTextTimer(0),
+ _syncSoundId(-1),
+ _ambientSoundId(-1),
+ _fastMode(true),
+ _hintMode(false) {
}
AGDSEngine::~AGDSEngine() {
Commit: dc981e8f20beaf36c253fefe895b094cdb9e1752
https://github.com/scummvm/scummvm/commit/dc981e8f20beaf36c253fefe895b094cdb9e1752
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:54+01:00
Commit Message:
AGDS: implement trap handler
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 1c99611c2b8..4a790071cba 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -413,6 +413,7 @@ void AGDSEngine::tick() {
return;
}
tickInventory();
+ tickCharacter();
runProcesses();
}
@@ -1008,9 +1009,24 @@ void AGDSEngine::tickInventory() {
_inventoryRegionName.clear();
_inventoryRegion.reset();
}
+}
+
+void AGDSEngine::tickCharacter() {
+ if (!_currentScreen || !_currentCharacter)
+ return;
+ auto pos = _currentCharacter->position();
+ auto objects = _currentScreen->find(pos);
+ for(auto & object: objects) {
+ auto region = object->getTrapRegion();
+ if (region && region->pointIn(pos)) {
+ debug("starting trap process");
+ runProcess(object, object->getTrapHandler());
+ }
+ }
}
+
bool AGDSEngine::hasFeature(EngineFeature f) const {
switch (f) {
case kSupportsSubtitleOptions:
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 45a16a2b3db..74f93777808 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -233,6 +233,7 @@ public:
}
void tickInventory();
+ void tickCharacter();
int playSound(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool playing = true) {
return _soundManager.play(process, resource, filename, phaseVar, playing);
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 60c95ce7b25..8d4f2969ab6 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -238,6 +238,10 @@ bool Object::pointIn(Common::Point pos) {
// pos -= _pos;
pos -= _regionOffset;
+ if (_trapRegion && _trapRegion->pointIn(pos))
+ return true;
+
+
if (_region && _region->pointIn(pos))
return true;
diff --git a/engines/agds/object.h b/engines/agds/object.h
index fe21f70f030..79ff5d7cb84 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -218,14 +218,20 @@ public:
_useOnHandler = ip;
}
+ uint getUserUseHandler() const {
+ return _userUseHandler;
+ }
+
void setTrapHandler(uint ip, RegionPtr region) {
_trapHandler = ip;
_trapRegion = region;
}
- uint getUserUseHandler() const {
- return _userUseHandler;
- }
+ RegionPtr getTrapRegion() const
+ { return _trapRegion; }
+
+ uint getTrapHandler() const
+ { return _trapHandler; }
void paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point pos) const;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c81c92691e3..56c5add218c 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1401,6 +1401,7 @@ void Process::onLook(uint16 size) {
void Process::onCharacterTrap(uint16 size) {
auto regionName = popString();
debug("setCharacterTrap %s [handler], %u instructions", regionName.c_str(), size);
+ _object->setTrapHandler(_ip, _engine->loadRegion(regionName));
_ip += size;
}
Commit: 8c811fbdc06dfbfd3785389adb54eb9a96c1f2d9
https://github.com/scummvm/scummvm/commit/8c811fbdc06dfbfd3785389adb54eb9a96c1f2d9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:54+01:00
Commit Message:
AGDS: skip spaces in sound directive
Changed paths:
engines/agds/dialog.cpp
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 9ba6e58ec67..65f13d6b11c 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -153,7 +153,8 @@ void Dialog::processSoundDirective(const Common::String &line) {
warning("invalid sound directive, missing arg2");
return;
}
- auto comma2 = line.find(',', comma1 + 1);
+ ++comma1;
+ auto comma2 = line.find(',', comma1);
if (comma2 == line.npos) {
warning("invalid sound directive, missing arg3");
return;
@@ -165,7 +166,11 @@ void Dialog::processSoundDirective(const Common::String &line) {
}
--end;
Common::String name = line.substr(arg1, comma1 - arg1 - 1);
- Common::String sample = line.substr(comma1 + 1, comma2 - comma1 - 1);
+ while(line[comma1] == ' ')
+ ++comma1;
+ Common::String sample = line.substr(comma1, comma2 - comma1);
+ while(line[comma2] == ' ')
+ ++comma2;
Common::String step = line.substr(comma2 + 1, end - comma2);
debug("sound args = %s,%s,%s", name.c_str(), sample.c_str(), step.c_str());
_sounds.push_back(Sound(name, sample, atoi(step.c_str())));
Commit: b5736b72bc2986b47d09f757fdbef14d49846ffc
https://github.com/scummvm/scummvm/commit/b5736b72bc2986b47d09f757fdbef14d49846ffc
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:54+01:00
Commit Message:
start playing if phase var is empty
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 56c5add218c..6d7bf9c1cba 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -165,7 +165,7 @@ void Process::loadAnimation() {
void Process::loadSample() {
Common::String name = popString();
debug("loadSample %s, phaseVar: %s, ambient: %d", name.c_str(), _phaseVar.c_str(), _sampleAmbient);
- int id = _engine->playSound(getName(), name, _engine->loadText(name), _phaseVar, _sampleAmbient);
+ int id = _engine->playSound(getName(), name, _engine->loadText(name), _phaseVar, _sampleAmbient || _phaseVar.empty());
if (_sampleAmbient)
_engine->setAmbientSoundId(id);
}
Commit: f13b3a2edbd4c26267e2ddbbd5e5c3e286731ce5
https://github.com/scummvm/scummvm/commit/f13b3a2edbd4c26267e2ddbbd5e5c3e286731ce5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:54+01:00
Commit Message:
AGDS: do not expect space at the beginning of each dialog line (RE mistake)
Changed paths:
engines/agds/dialog.cpp
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 65f13d6b11c..cd241528f84 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -122,7 +122,7 @@ bool Dialog::tick() {
debug("dialog line: %s", line.c_str());
if (line[0] == '@') {
processDirective(line);
- } else if (line[0] == ' ') {
+ } else {
debug("text: %s", line.c_str() + 1);
dialog_var->setInteger(-3);
}
Commit: 985d165b139c0f3fee9c1756ac429f18402c7906
https://github.com/scummvm/scummvm/commit/985d165b139c0f3fee9c1756ac429f18402c7906
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:55+01:00
Commit Message:
AGDS: do not reset syncSoundId in tell()
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 4a790071cba..d8e6f94ea16 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -931,8 +931,6 @@ void AGDSEngine::tell(Process &process, const Common::String ®ionName, Common
_textLayout.layout(*this, process, text, pos, font_id, npc);
if (!sound.empty()) {
playSoundSync(sound);
- } else {
- _syncSoundId = -1;
}
}
Commit: 46a58b8e02357fad237573e8ae151ad4512c4621
https://github.com/scummvm/scummvm/commit/46a58b8e02357fad237573e8ae151ad4512c4621
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:55+01:00
Commit Message:
AGDS: implement gaps removing from inventory, call it on open and from specific remove gaps opcode
Changed paths:
engines/agds/inventory.cpp
engines/agds/inventory.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index c34dec6b45f..3558b58ef12 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -47,6 +47,7 @@ void Inventory::visible(bool visible) {
_engine->runObject(inv_close);
} else if (enabled() && visible) {
debug("opening inventory...");
+ removeGaps();
Common::String inv_open = _engine->getSystemVariable("inv_open")->getString();
if (!inv_open.empty())
_engine->runObject(inv_open);
@@ -88,6 +89,23 @@ bool Inventory::remove(const Common::String &name) {
return removed;
}
+void Inventory::removeGaps() {
+ auto n = _entries.size();
+ for (uint src = 0, dst = 0; src < n; ++src) {
+ if (_entries[src])
+ {
+ if (dst != src)
+ {
+ debug("moving inventory object %u -> %u", src, dst);
+ _entries[dst++] = _entries[src];
+ _entries[src].reset();
+ }
+ else
+ ++dst;
+ }
+ }
+}
+
int Inventory::find(const Common::String &name) const {
for (uint i = 0; i < _entries.size(); ++i)
if (_entries[i] && _entries[i]->getName() == name)
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index 849f46e0072..a7b2cee3c63 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -68,6 +68,7 @@ public:
int add(const ObjectPtr & object);
bool remove(const Common::String &name);
+ void removeGaps();
ObjectPtr get(int index) const;
int find(const Common::String &name) const;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 6d7bf9c1cba..166a495ad93 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -919,7 +919,8 @@ void Process::stub192() {
}
void Process::removeGapsFromInventory() {
- debug("removeGapsFromInventory: stub");
+ debug("removeGapsFromInventory");
+ _engine->inventory().removeGaps();
}
void Process::setObjectScale() {
Commit: 057e2e25ee3e7044427f4dda1be4acc42fb8df6c
https://github.com/scummvm/scummvm/commit/057e2e25ee3e7044427f4dda1be4acc42fb8df6c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:55+01:00
Commit Message:
AGDS: implement animation next frame opcode
Changed paths:
engines/agds/animation.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 725541c251d..2b3147ef560 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -164,7 +164,6 @@ public:
decodeNextFrame();
}
-private:
void decodeNextFrame();
};
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 0f2e30aa853..282d3e5191d 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -254,7 +254,7 @@ enum Opcode {
kGetSampleVolume = 234,
kStub235 = 235,
kUserEnabled = 236,
- kStub237 = 237,
+ kAnimationNextFrame = 237,
kInventoryHasObjectByName = 238,
kStub239 = 239,
kLoadDialog = 240,
@@ -448,6 +448,7 @@ enum Opcode {
OP(kStopCharacter, stopCharacter) \
OP(kLeaveCharacterEx, leaveCharacterEx) \
OP(kRestartAnimation, restartAnimation) \
+ OP(kAnimationNextFrame, animationNextFrame) \
OP(kSignalAnimationEnd, signalAnimationEnd) \
OP(kSetShadowIntensity, setShadowIntensity) \
OP(kSetNPCTellNotifyVar, setNPCTellNotifyVar) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 166a495ad93..4a2866f030a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1022,6 +1022,28 @@ void Process::restartAnimation() {
}
}
+void Process::animationNextFrame() {
+ Common::String phaseVar = popString();
+ debug("animationGetCurrentFrame %s", phaseVar.c_str());
+ if (phaseVar.empty()) {
+ warning("no phaseVar");
+ return;
+ }
+ Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
+ if (animation) {
+ auto value = _engine->getGlobal(phaseVar);
+ if (value >= -1) {
+ if (!animation->ended() || value == -1) {
+ animation->decodeNextFrame();
+ _engine->setGlobal(phaseVar, animation->ended()? -1: animation->phase());
+ } else {
+ _engine->setGlobal(phaseVar, -1);
+ }
+ }
+ } else
+ warning("no animation with phase var %s found", phaseVar.c_str());
+}
+
void Process::signalAnimationEnd() {
Common::String phaseVar = popString();
debug("restartAnimation %s", phaseVar.c_str());
Commit: b4528c07e296c4815af098fca9e82aa7f4c12eda
https://github.com/scummvm/scummvm/commit/b4528c07e296c4815af098fca9e82aa7f4c12eda
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:55+01:00
Commit Message:
AGDS: fix missing Surface::free
Changed paths:
engines/agds/animation.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index c94f6abb4eb..5f0973771fe 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -106,10 +106,11 @@ void Animation::decodeNextFrame() {
freeFrame();
_delay = _flic->getCurFrameDelay() * _speed / 4000; //40 == 1000 / 25, 25 fps
_frame = _engine->convertToTransparent(frame->convertTo(_engine->pixelFormat(), _flic->getPalette()));
+
if (_scale != 1) {
auto f = _frame->scale(_frame->w * _scale, _frame->h * _scale, true);
if (f) {
- delete _frame;
+ freeFrame();
_frame = f;
}
}
Commit: 8987f8a1d82542abe34605ccad2af48e207cb06b
https://github.com/scummvm/scummvm/commit/8987f8a1d82542abe34605ccad2af48e207cb06b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:55+01:00
Commit Message:
AGDS: ported to the latest upstream
Changed paths:
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 3c6507b8073..f123a213b02 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -25,6 +25,7 @@
#include "common/debug.h"
#include "common/file.h"
#include "common/memstream.h"
+#include "common/path.h"
#include "common/ptr.h"
#include "graphics/surface.h"
#include "image/bmp.h"
@@ -132,16 +133,20 @@ int ResourceManager::GrpFile::listMembers(Common::ArchiveMemberList &list) const
return size;
}
-const Common::ArchiveMemberPtr ResourceManager::GrpFile::getMember(const Common::String &name) const {
+bool ResourceManager::GrpFile::hasFile(const Common::Path &name) const {
+ return _members.find(name.toString()) != _members.end();
+}
+
+const Common::ArchiveMemberPtr ResourceManager::GrpFile::getMember(const Common::Path &name) const {
Common::ArchiveMemberPtr member;
- MembersType::const_iterator i = _members.find(name);
+ MembersType::const_iterator i = _members.find(name.toString());
if (i != _members.end())
member = i->_value;
return member;
}
-Common::SeekableReadStream *ResourceManager::GrpFile::createReadStreamForMember(const Common::String &name) const {
- Common::ArchiveMemberPtr member = getMember(name);
+Common::SeekableReadStream *ResourceManager::GrpFile::createReadStreamForMember(const Common::Path &name) const {
+ Common::ArchiveMemberPtr member = getMember(name.toString());
return member ? member->createReadStream() : NULL;
}
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 4ff8f001cd9..624331d050d 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -71,12 +71,10 @@ private:
return _file;
}
- virtual bool hasFile(const Common::String &name) const
- { return _members.find(name) != _members.end(); }
-
+ bool hasFile(const Common::Path &name) const override;
int listMembers(Common::ArchiveMemberList &list) const override;
- const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
- Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
+ const Common::ArchiveMemberPtr getMember(const Common::Path &name) const override;
+ Common::SeekableReadStream *createReadStreamForMember(const Common::Path &name) const override;
};
public:
Commit: dfc40d4af6c89d5c7f896f6b4d933069a530b68a
https://github.com/scummvm/scummvm/commit/dfc40d4af6c89d5c7f896f6b4d933069a530b68a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:55+01:00
Commit Message:
AGDS: remove old hack and fix alpha
Changed paths:
engines/agds/agds.cpp
engines/agds/object.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index d8e6f94ea16..d1a0d11fd14 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -674,7 +674,7 @@ Common::Error AGDSEngine::run() {
Common::Point dst = _mouse;
dst.x -= srcRect.width() / 2;
dst.y -= srcRect.height() / 2;
- uint32 color = (_currentInventoryObject->alpha() << 24) | 0xffffff; //fixme: _picture->format.ARGBToColor(_alpha, 255, 255, 255); is not working
+ uint32 color = picture->format.ARGBToColor(_currentInventoryObject->alpha(), 255, 255, 255);
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer->getRect())) {
picture->blit(*backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
}
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 8d4f2969ab6..d7b2d31aae8 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -253,7 +253,7 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Po
if (picture) {
Common::Point dst = pos + getPosition();
Common::Rect srcRect = picture->getRect();
- uint32 color = (_alpha << 24) | 0xffffff; //fixme: _picture->format.ARGBToColor(_alpha, 255, 255, 255); is not working
+ uint32 color = _picture->format.ARGBToColor(_alpha, 255, 255, 255);
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect())) {
picture->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
}
Commit: c05b136fed41efbd808a0d9708b98dd168e674c1
https://github.com/scummvm/scummvm/commit/c05b136fed41efbd808a0d9708b98dd168e674c1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:55+01:00
Commit Message:
AGDS: do not call screen tick when dialog is active
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index d1a0d11fd14..77508a6f924 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -412,6 +412,8 @@ void AGDSEngine::tick() {
runProcesses();
return;
}
+ if (_currentScreen)
+ _currentScreen->tick();
tickInventory();
tickCharacter();
runProcesses();
@@ -660,7 +662,6 @@ Common::Error AGDSEngine::run() {
skipFilm();
}
} else if (_currentScreen) {
- _currentScreen->tick();
_currentScreen->paint(*backbuffer);
}
Commit: f1321f500589b22fd6e71185ccd81bdbfb46018d
https://github.com/scummvm/scummvm/commit/f1321f500589b22fd6e71185ccd81bdbfb46018d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:55+01:00
Commit Message:
AGDS: add missing parameters
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4a2866f030a..d3ce04ec937 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -540,7 +540,7 @@ void Process::checkScreenPatch() {
if (!screenName.empty() && screenName != screen->getName()) {
if (objectName != _engine->getSystemVariable("inventory_scr")->getString()) {
- debug("checkScreenPatch for object %s %s");
+ debug("checkScreenPatch for object %s %s", screenName.c_str(), objectName.c_str());
auto patch = _engine->getPatch(screenName);
push(patch? patch->getFlag(objectName): 0);
} else {
Commit: aacf784f83b36bcf507210a0de18a839ba5f9c9f
https://github.com/scummvm/scummvm/commit/aacf784f83b36bcf507210a0de18a839ba5f9c9f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:55+01:00
Commit Message:
COMMON: fix invalid right/bottom margins used in getBlitRect
Right margin is calculated using x + width not x + right.
The same applies to the bottom, it's y + height, not y + bottom.
Changed paths:
common/rect.h
diff --git a/common/rect.h b/common/rect.h
index e6e8b5e9352..290d6320a9f 100644
--- a/common/rect.h
+++ b/common/rect.h
@@ -496,11 +496,11 @@ struct RectBase {
dst.y = clip.top;
}
- int right = dst.x + rect.right;
+ int right = dst.x + rect.width();
if (right > clip.right)
rect.right -= right - clip.right;
- int bottom = dst.y + rect.bottom;
+ int bottom = dst.y + rect.height();
if (bottom > clip.bottom)
rect.bottom -= bottom - clip.bottom;
return !rect.isEmpty();
Commit: 6ef34bdde39825bcb77a57c8f40427d8eeff8fc8
https://github.com/scummvm/scummvm/commit/6ef34bdde39825bcb77a57c8f40427d8eeff8fc8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:55+01:00
Commit Message:
AGDS: render objects on top of animations
Changed paths:
engines/agds/screen.cpp
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index a60ea626da6..87b1c3b7d74 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -208,13 +208,6 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
bool z_valid = false;
int z = 0;
int render_type = -1;
- if (child_valid) {
- if (!z_valid || (*child)->z() > z) {
- z = (*child)->z();
- z_valid = true;
- render_type = 0;
- }
- }
if (animation_valid) {
if (!z_valid || (*animation)->z() > z) {
z = (*animation)->z();
@@ -222,6 +215,13 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
render_type = 1;
}
}
+ if (child_valid) {
+ if (!z_valid || (*child)->z() > z) {
+ z = (*child)->z();
+ z_valid = true;
+ render_type = 0;
+ }
+ }
if (character) {
if (!z_valid || character->z() > z) {
z = character->z();
Commit: 11fd3043dab64cf56b873b86672ccd0dc69832ef
https://github.com/scummvm/scummvm/commit/11fd3043dab64cf56b873b86672ccd0dc69832ef
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:56+01:00
Commit Message:
AGDS: fix active sound checking logic (fix brick puzzle and many other sounds)
Changed paths:
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 7e375e6ef5e..b6fc82ca0e5 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -37,12 +37,14 @@ void SoundManager::tick() {
Sound &sound = *i;
auto &phaseVar = sound.phaseVar;
- bool active = _mixer->isSoundHandleActive(sound.handle);
+ bool active = playing(sound.id);
if (!sound.phaseVar.empty()) {
int value = _engine->getGlobal(sound.phaseVar);
if (value <= 1) {
- if (value == 1 && !active)
+ if (value == 1 && !active) {
+ debug("sample %s:%s resets phase var to 0", sound.resource.c_str(), sound.filename.c_str());
_engine->setGlobal(phaseVar, 0);
+ }
} else if (value & 2) {
debug("sample %s:%s restarts (via phase var)", sound.resource.c_str(), sound.filename.c_str());
_engine->setGlobal(phaseVar, 1);
@@ -106,7 +108,7 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
Common::File *file = new Common::File();
if (!file->open(filename)) {
if (!phaseVar.empty())
- _engine->setGlobal(phaseVar, 0);
+ _engine->setGlobal(phaseVar, 1);
warning("no sound %s", filename.c_str());
return -1;
}
@@ -124,7 +126,7 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
warning("could not play sound %s", filename.c_str());
delete file;
if (!phaseVar.empty())
- _engine->setGlobal(phaseVar, 0);
+ _engine->setGlobal(phaseVar, _engine->getGlobal(phaseVar)? 1: 0);
else
_engine->reactivate(process);
return -1;
@@ -133,9 +135,9 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
if (id == -1)
id = _nextId++;
- _sounds.push_back(Sound(id, process, resource, filename, phaseVar, handle));
+ _sounds.push_back(Sound(id, process, resource, filename, phaseVar));
if (startPlaying)
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, stream, id);
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_sounds.back().handle, stream, id);
//if (sound_off)
// setPhaseVar(_sounds.back(), 1);
return id;
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index e148fbdacef..510de456579 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -46,8 +46,8 @@ namespace AGDS {
int leftVolume;
int rightVolume;
bool paused;
- Sound(int id_, const Common::String &p, const Common::String & res, const Common::String &file, const Common::String & var, Audio::SoundHandle h, int g = 0):
- id(id_), process(p), resource(res), filename(file), phaseVar(var), handle(h), group(g), leftVolume(100), rightVolume(100), paused(false) {
+ Sound(int id_, const Common::String &p, const Common::String & res, const Common::String &file, const Common::String & var, int g = 0):
+ id(id_), process(p), resource(res), filename(file), phaseVar(var), handle(), group(g), leftVolume(100), rightVolume(100), paused(false) {
}
};
Commit: f6dc22f43b904e0ad807441c5e16c994f365b02a
https://github.com/scummvm/scummvm/commit/f6dc22f43b904e0ad807441c5e16c994f365b02a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:56+01:00
Commit Message:
AGDS: explicitly show character from loadScreen and loadSave
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 77508a6f924..dea4e6d8036 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1105,6 +1105,7 @@ Common::Error AGDSEngine::loadGameState(int slot) {
auto character = getCharacter(id);
if (character) {
character->loadState(agds_c.get());
+ character->visible(true);
} else
warning("no character");
}
@@ -1177,6 +1178,8 @@ void AGDSEngine::loadNextScreen() {
_nextScreenType = ScreenLoadingType::Normal;
loadScreen(nextScreenName, nextScreenType);
}
+ if (_currentCharacter)
+ _currentCharacter->visible(true);
}
Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
Commit: e221ad5ae4215b9270f99cb3a9a00a96e44667b6
https://github.com/scummvm/scummvm/commit/e221ad5ae4215b9270f99cb3a9a00a96e44667b6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:56+01:00
Commit Message:
AGDS: do not skip engine tick if dialog is active
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index dea4e6d8036..631f96ca044 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -408,12 +408,12 @@ void AGDSEngine::newGame() {
void AGDSEngine::tick() {
loadNextScreen();
- if (_dialog.tick()) {
- runProcesses();
- return;
- }
+ bool dialogActive = _dialog.tick();
if (_currentScreen)
_currentScreen->tick();
+ runProcesses();
+ if (dialogActive)
+ return;
tickInventory();
tickCharacter();
runProcesses();
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 74f93777808..768f31bcf7d 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -137,7 +137,7 @@ public:
int appendToSharedStorage(const Common::String &value);
const Common::String & getSharedStorage(int id) const;
- bool active() const { return !_mjpgPlayer && !(_soundManager.playing(_syncSoundId) || _tellTextTimer > 0); }
+ bool active() const { return !_mjpgPlayer; }
void playFilm(Process &process, const Common::String &video, const Common::String &audio, const Common::String &subtitles);
void skipFilm();
Commit: 220437221ab29b5c8a6b4562320e4167b60dd226
https://github.com/scummvm/scummvm/commit/220437221ab29b5c8a6b4562320e4167b60dd226
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:56+01:00
Commit Message:
AGDS: improve tick logic, run processes after animation was expired
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 631f96ca044..98282214769 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -411,11 +411,10 @@ void AGDSEngine::tick() {
bool dialogActive = _dialog.tick();
if (_currentScreen)
_currentScreen->tick();
- runProcesses();
- if (dialogActive)
- return;
- tickInventory();
- tickCharacter();
+ if (!dialogActive) {
+ tickInventory();
+ tickCharacter();
+ }
runProcesses();
}
Commit: 09a84303d64f4a46d5f8ec8a4f76e71774d82c30
https://github.com/scummvm/scummvm/commit/09a84303d64f4a46d5f8ec8a4f76e71774d82c30
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:56+01:00
Commit Message:
AGDS: minor mjpg cleanup
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 98282214769..a9b7e03487a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -746,8 +746,10 @@ void AGDSEngine::playFilm(Process &process, const Common::String &video, const C
void AGDSEngine::skipFilm() {
debug("skip");
- delete _mjpgPlayer;
- _mjpgPlayer = NULL;
+ if (_mjpgPlayer) {
+ delete _mjpgPlayer;
+ _mjpgPlayer = NULL;
+ }
if (_syncSoundId >= 0) {
debug("skip: stopping sound %d", _syncSoundId);
_mixer->stopID(_syncSoundId);
Commit: b8c8a1fc05bcc941be0031d65d4a2ae2cf845d69
https://github.com/scummvm/scummvm/commit/b8c8a1fc05bcc941be0031d65d4a2ae2cf845d69
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:56+01:00
Commit Message:
AGDS: log text layout reset
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index a9b7e03487a..bb2c5047f4f 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -687,6 +687,7 @@ Common::Error AGDSEngine::run() {
if (_textLayout.valid()) {
if (_syncSoundId >= 0) {
if (!_soundManager.playing(_syncSoundId)) {
+ debug("sync sound %d finished, resetting text layout...", _syncSoundId);
_textLayout.reset(*this);
_syncSoundId = -1;
_tellTextTimer = 0;
@@ -695,6 +696,7 @@ Common::Error AGDSEngine::run() {
--_tellTextTimer;
} else {
_tellTextTimer = 0;
+ debug("text timer expired, resetting text layout");
_textLayout.reset(*this);
}
}
Commit: 668283641d78b8de7e4bbbd2c62d59a226775570
https://github.com/scummvm/scummvm/commit/668283641d78b8de7e4bbbd2c62d59a226775570
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:56+01:00
Commit Message:
AGDS: activate character process only when animation finishes, not on any tick
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 4a01e026c6e..5441c61be72 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -204,9 +204,9 @@ void Character::tick() {
_phase = -1;
_frames = 0;
//animate(_direction, 100, false);
+ _engine->reactivate(_processName, true);
}
}
- _engine->reactivate(_processName, true);
}
Commit: 36a1c6bd37c66b22571fb5d7abd07610f07bf0bc
https://github.com/scummvm/scummvm/commit/36a1c6bd37c66b22571fb5d7abd07610f07bf0bc
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:56+01:00
Commit Message:
AGDS: log character description filename
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 5441c61be72..aa59e28b927 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -64,7 +64,7 @@ void Character::load(Common::SeekableReadStream *stream) {
AnimationDescription animation;
animation.filename = filename;
- debug("%u: animation %s, frames: %d, format: %d", _animations.size(), animation.filename.c_str(), frames, format);
+ debug("%s:%u: animation %s, frames: %d, format: %d", _name.c_str(), _animations.size(), animation.filename.c_str(), frames, format);
while (frames--) {
int x = stream->readSint16LE();
int y = stream->readSint16LE();
Commit: 43bfc37006ef36253340b7af016f1e24e248bc24
https://github.com/scummvm/scummvm/commit/43bfc37006ef36253340b7af016f1e24e248bc24
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:56+01:00
Commit Message:
AGDS: add "add" command to debug console
Changed paths:
engines/agds/console.cpp
engines/agds/console.h
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index 5c59e16af65..41d5a4a9ad8 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -36,6 +36,7 @@ Console::Console(AGDSEngine *engine) : _engine(engine) {
registerCmd("run", WRAP_METHOD(Console, run));
registerCmd("stop", WRAP_METHOD(Console, stop));
registerCmd("set", WRAP_METHOD(Console, setGlobal));
+ registerCmd("invadd", WRAP_METHOD(Console, inventoryAdd));
}
bool Console::load(int argc, const char **argv) {
@@ -126,11 +127,25 @@ bool Console::setGlobal(int argc, const char **argv) {
}
int value;
if (sscanf(argv[2], "%d", &value) != 1) {
- debugPrintf("invalid value");
+ debugPrintf("invalid value\n");
return true;
}
_engine->setGlobal(argv[1], value);
return true;
}
+bool Console::inventoryAdd(int argc, const char **argv) {
+ if (argc < 2) {
+ debugPrintf("usage: %s inv.object\n", argv[0]);
+ return true;
+ }
+ auto object = _engine->runObject(argv[1]);
+ if (!object) {
+ debugPrintf("failed to load %s\n", argv[1]);
+ }
+ _engine->inventory().add(object);
+ detach();
+ return true;
+}
+
}
diff --git a/engines/agds/console.h b/engines/agds/console.h
index 7912a32aa88..e19800575ba 100644
--- a/engines/agds/console.h
+++ b/engines/agds/console.h
@@ -42,6 +42,7 @@ private:
bool activate(int argc, const char **argv);
bool info(int argc, const char **argv);
bool setGlobal(int argc, const char **argv);
+ bool inventoryAdd(int argc, const char **argv);
AGDSEngine *_engine;
};
Commit: 1f73ffd98c0714abb6f035070d782533c47be048
https://github.com/scummvm/scummvm/commit/1f73ffd98c0714abb6f035070d782533c47be048
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:56+01:00
Commit Message:
AGDS: implement stopCharacter and fix freeze in chapter V
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index aa59e28b927..95178045b7e 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -149,15 +149,15 @@ void Character::animate(int direction, int speed, bool jokes) {
if (direction == -1)
return;
+ _stopped = false;
auto character = jokes? _engine->jokes(): this;
_description = character->animationDescription(direction);
- _animation = _description? _engine->loadAnimation(_description->filename): nullptr;
- if (!_animation) {
+ auto animation = _description? _engine->loadAnimation(_description->filename): nullptr;
+ if (!animation) {
warning("no %s animation %d", jokes? "jokes": "character", direction);
- _phase = -1;
- _frames = 0;
return;
}
+ _animation = animation;
_animation->speed(speed);
_animation->rewind();
if (!_jokes)
@@ -182,12 +182,11 @@ void Character::animate(const Common::String & processName, Common::Point pos, i
void Character::stop() {
debug("character %s: stop", _object->getName().c_str());
- _phase = -1;
- _frames = 0;
+ _stopped = true;
}
void Character::tick() {
- if (!_enabled || !_visible || !_animation)
+ if (!_enabled || !_visible || !_animation || _stopped)
return;
auto screen = _engine->getCurrentScreen();
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 06131452ffc..fcc4afebd78 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -49,6 +49,7 @@ class Character {
Common::Point _animationPos;
bool _enabled;
bool _visible;
+ bool _stopped;
int _phase;
int _frames;
int _direction;
@@ -70,7 +71,8 @@ class Character {
public:
Character(AGDSEngine * engine, const Common::String & name):
_engine(engine), _name(name), _object(), _animation(nullptr), _jokes(false),
- _enabled(true), _visible(true), _phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
+ _enabled(true), _visible(true), _stopped(false),
+ _phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
}
void associate(const Common::String &name);
Commit: 4e96bc3f703958c2ef1cc0e9a6c2e97643c00e4b
https://github.com/scummvm/scummvm/commit/4e96bc3f703958c2ef1cc0e9a6c2e97643c00e4b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:57+01:00
Commit Message:
AGDS: remove irrelevant comments, reactivate process before it
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 95178045b7e..542dfe493c7 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -199,12 +199,10 @@ void Character::tick() {
_animation->tick();
_phase = _animation->phase();
if (_phase >= _frames) {
- //many dialog scripts rely on jokes direction returned from direction notify var
_phase = -1;
_frames = 0;
- //animate(_direction, 100, false);
- _engine->reactivate(_processName, true);
}
+ _engine->reactivate(_processName, true);
}
}
Commit: b7ceb1da6babe87cc322b7555acff99047367860
https://github.com/scummvm/scummvm/commit/b7ceb1da6babe87cc322b7555acff99047367860
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:57+01:00
Commit Message:
AGDS: disable autosave (breaks any puzzle)
Changed paths:
engines/agds/agds.h
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 768f31bcf7d..4467b728fe0 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -116,8 +116,8 @@ public:
bool hasFeature(EngineFeature f) const;
Common::Error loadGameState(int slot) override;
Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
- bool canLoadGameStateCurrently() { return true; }
- bool canSaveGameStateCurrently() { return _userEnabled; }
+ bool canLoadGameStateCurrently() override { return true; }
+ bool canSaveGameStateCurrently() override { return false; }
ObjectPtr loadObject(const Common::String & name, const Common::String & prototype = Common::String(), bool allowInitialise = true);
ObjectPtr runObject(const Common::String & name, const Common::String &prototype = Common::String(), bool allowInitialise = true);
Commit: 95e9b40088e52898ed0e2c3271b7a35e443f9c41
https://github.com/scummvm/scummvm/commit/95e9b40088e52898ed0e2c3271b7a35e443f9c41
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:57+01:00
Commit Message:
AGDS: better logging from SoundManager::play(), start non-phase controlled samples
Changed paths:
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d3ce04ec937..35d908ae9af 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -165,7 +165,7 @@ void Process::loadAnimation() {
void Process::loadSample() {
Common::String name = popString();
debug("loadSample %s, phaseVar: %s, ambient: %d", name.c_str(), _phaseVar.c_str(), _sampleAmbient);
- int id = _engine->playSound(getName(), name, _engine->loadText(name), _phaseVar, _sampleAmbient || _phaseVar.empty());
+ int id = _engine->playSound(getName(), name, _engine->loadText(name), _phaseVar, _sampleAmbient || !_phaseVarControlled || _phaseVar.empty());
if (_sampleAmbient)
_engine->setAmbientSoundId(id);
}
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index b6fc82ca0e5..e6ccd40a2fe 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -94,7 +94,7 @@ void SoundManager::stopAll() {
}
int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int id) {
- debug("SoundMan::play '%s' '%s' '%s' '%s' %d %d", process.c_str(), resource.c_str(), filename.c_str(), phaseVar.c_str(), startPlaying, id);
+ debug("SoundMan::play(process: '%s', resource: '%s', filename: '%s', phaseVar: '%s', start: %d id: %d", process.c_str(), resource.c_str(), filename.c_str(), phaseVar.c_str(), startPlaying, id);
if (filename.empty())
return -1;
Commit: 069f22d15b7ad0e3520c17d27c45a6a20f353b68
https://github.com/scummvm/scummvm/commit/069f22d15b7ad0e3520c17d27c45a6a20f353b68
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:57+01:00
Commit Message:
AGDS: accomodate volume/pan for samples
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index bb2c5047f4f..dea1204f665 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -743,7 +743,7 @@ void AGDSEngine::playFilm(Process &process, const Common::String &video, const C
_mjpgPlayer = new MJPGPlayer(_resourceManager.getResource(video), subtitles);
_soundManager.stopAll();
_filmStarted = _system->getMillis();
- _syncSoundId = _soundManager.play(process.getName(), Common::String(), audio, Common::String());
+ _syncSoundId = _soundManager.play(process.getName(), Common::String(), audio, Common::String(), true, 100, 0);
}
void AGDSEngine::skipFilm() {
@@ -934,7 +934,8 @@ void AGDSEngine::tell(Process &process, const Common::String ®ionName, Common
_tellTextTimer = _dialog.textDelay(text);
_textLayout.layout(*this, process, text, pos, font_id, npc);
if (!sound.empty()) {
- playSoundSync(sound);
+ int id = _soundManager.play(Common::String(), Common::String(), sound, Common::String(), true, 100, 0);
+ playSoundSync(id);
}
}
@@ -1160,7 +1161,7 @@ Common::Error AGDSEngine::loadGameState(int slot) {
uint type = agds_a->readUint32LE();
debug("saved audio state: sample: '%s:%s', var: '%s' %u %u", resource.c_str(), filename.c_str(), phaseVar.c_str(), volume, type);
debug("phase var for sample -> %d", getGlobal(phaseVar));
- _ambientSoundId = playSound(Common::String(), resource, filename, phaseVar); //fixme: double check
+ _ambientSoundId = _soundManager.play(Common::String(), resource, filename, phaseVar, true, volume, 0); //fixme: double check
debug("ambient sound id = %d", _ambientSoundId);
}
{
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 4467b728fe0..74d8cdefcc6 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -235,14 +235,14 @@ public:
void tickInventory();
void tickCharacter();
- int playSound(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool playing = true) {
- return _soundManager.play(process, resource, filename, phaseVar, playing);
+ void playSoundSync(int syncSoundId) {
+ _syncSoundId = syncSoundId;
}
- void playSoundSync(const Common::String &filename) {
- _syncSoundId = playSound(Common::String(), Common::String(), filename, Common::String());
+ void setAmbientSoundId(int id) {
+ stopAmbientSound();
+ _ambientSoundId = id;
}
- void setAmbientSoundId(int id) { stopAmbientSound(); _ambientSoundId = id; }
void tell(Process &process, const Common::String ®ion, Common::String text, Common::String sound, bool npc);
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 282d3e5191d..5ea078dee98 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -189,7 +189,7 @@ enum Opcode {
kGetIntegerSystemVariable = 169,
kSetDelay = 170,
kGetRandomNumber = 171,
- kSetSampleType = 172,
+ kSetSampleVolume = 172,
kStub173 = 173,
kStub174 = 174,
kAppendToSharedStorage = 175,
@@ -412,7 +412,7 @@ enum Opcode {
OP(kGetSaveGameName, getSaveGameName) \
OP(kSetObjectRegionOffset, setObjectRegionOffset) \
OP(kSetDelay, setDelay) \
- OP(kSetSampleType, setSampleType) \
+ OP(kSetSampleVolume, setSampleVolume) \
OP(kStub173, stub173) \
OP(kStub174, stub174) \
OP(kStub192, stub192) \
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 6e04c281128..9a4e90215c6 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -36,7 +36,7 @@ Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
_timer(0),
_animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0),
_phaseVarControlled(false), _animationSpeed(100),
- _samplePeriodic(false), _sampleAmbient(false),
+ _samplePeriodic(false), _sampleAmbient(false), _sampleVolume(100),
_filmSubtitlesResource(-1)
{
updateWithCurrentMousePosition();
diff --git a/engines/agds/process.h b/engines/agds/process.h
index c4c16f6e6ef..d33462de283 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -67,6 +67,7 @@ private:
int _animationSpeed;
bool _samplePeriodic;
bool _sampleAmbient;
+ int32 _sampleVolume;
Common::Point _mousePosition;
int _filmSubtitlesResource;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 35d908ae9af..5776b295d48 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -164,8 +164,8 @@ void Process::loadAnimation() {
void Process::loadSample() {
Common::String name = popString();
- debug("loadSample %s, phaseVar: %s, ambient: %d", name.c_str(), _phaseVar.c_str(), _sampleAmbient);
- int id = _engine->playSound(getName(), name, _engine->loadText(name), _phaseVar, _sampleAmbient || !_phaseVarControlled || _phaseVar.empty());
+ debug("loadSample %s, phaseVar: %s, ambient: %d, volume: %d", name.c_str(), _phaseVar.c_str(), _sampleAmbient, _sampleVolume);
+ int id = _engine->soundManager().play(getName(), name, _engine->loadText(name), _phaseVar, _sampleAmbient || !_phaseVarControlled || _phaseVar.empty(), _sampleVolume, 0);
if (_sampleAmbient)
_engine->setAmbientSoundId(id);
}
@@ -175,8 +175,8 @@ void Process::getSampleVolume() {
debug("getSampleVolume: %s", name.c_str());
auto sound = _engine->soundManager().findSampleByPhaseVar(name);
if (sound) {
- debug("\treturning %d", sound->leftVolume);
- push(sound->leftVolume);
+ debug("\treturning %d", sound->leftVolume());
+ push(sound->leftVolume());
} else {
warning("could not find sample %s", name.c_str());
push(-1);
@@ -211,8 +211,8 @@ void Process::setSampleVolumeAndPan() {
r = volume;
}
debug("\tleft: %d, right: %d", l, r);
- sound->leftVolume = l;
- sound->rightVolume = r;
+ sound->volume = volume;
+ sound->pan = pan;
}
void Process::addSampleToSoundGroup() {
@@ -665,6 +665,7 @@ void Process::resetState() {
_animationSpeed = 100;
_samplePeriodic = false;
_sampleAmbient = false;
+ _sampleVolume = 100;
_tileWidth = 16;
_tileHeight = 16;
@@ -899,9 +900,9 @@ void Process::setObjectRegionOffset() {
warning("setObjectRegionOffset: object %s not found", objectName.c_str());
}
-void Process::setSampleType() {
- int value = pop();
- debug("setSampleType: %d stub", value);
+void Process::setSampleVolume() {
+ _sampleVolume = pop();
+ debug("setSampleVolume: %d", _sampleVolume);
}
void Process::stub173() {
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index e6ccd40a2fe..21d7bb36dfb 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -49,7 +49,7 @@ void SoundManager::tick() {
debug("sample %s:%s restarts (via phase var)", sound.resource.c_str(), sound.filename.c_str());
_engine->setGlobal(phaseVar, 1);
_mixer->stopID(sound.id);
- play(sound.process, sound.resource, sound.filename, sound.phaseVar, true, sound.id);
+ play(sound.process, sound.resource, sound.filename, sound.phaseVar, true, sound.volume, sound.pan, sound.id);
} else if (value & 4) {
debug("sample %s:%s stops (via phase var)", sound.resource.c_str(), sound.filename.c_str());
_mixer->stopID(sound.id);
@@ -93,8 +93,8 @@ void SoundManager::stopAll() {
_sounds.clear();
}
-int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int id) {
- debug("SoundMan::play(process: '%s', resource: '%s', filename: '%s', phaseVar: '%s', start: %d id: %d", process.c_str(), resource.c_str(), filename.c_str(), phaseVar.c_str(), startPlaying, id);
+int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int volume, int pan, int id) {
+ debug("SoundMan::play(process: '%s', resource: '%s', filename: '%s', phaseVar: '%s', start: %d, volume: %d, pan: %d, id: %d", process.c_str(), resource.c_str(), filename.c_str(), phaseVar.c_str(), startPlaying, volume, pan, id);
if (filename.empty())
return -1;
@@ -135,9 +135,9 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
if (id == -1)
id = _nextId++;
- _sounds.push_back(Sound(id, process, resource, filename, phaseVar));
+ _sounds.push_back(Sound(id, process, resource, filename, phaseVar, volume, pan));
if (startPlaying)
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_sounds.back().handle, stream, id);
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_sounds.back().handle, stream, id, volume * Audio::Mixer::kMaxChannelVolume / 100, pan * 127 / 100);
//if (sound_off)
// setPhaseVar(_sounds.back(), 1);
return id;
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index 510de456579..cffd2a2e71e 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -42,12 +42,20 @@ namespace AGDS {
Common::String filename;
Common::String phaseVar;
Audio::SoundHandle handle;
+ int volume;
+ int pan;
int group;
- int leftVolume;
- int rightVolume;
bool paused;
- Sound(int id_, const Common::String &p, const Common::String & res, const Common::String &file, const Common::String & var, int g = 0):
- id(id_), process(p), resource(res), filename(file), phaseVar(var), handle(), group(g), leftVolume(100), rightVolume(100), paused(false) {
+ Sound(int id_, const Common::String &process_, const Common::String & res, const Common::String &filename_, const Common::String & var, int volume_, int pan_, int group_ = 0):
+ id(id_), process(process_), resource(res), filename(filename_), phaseVar(var), handle(), volume(volume_), pan(pan_), group(group_), paused(false) {
+ }
+
+ int leftVolume() const {
+ return pan < 0? volume: volume * (100 - pan) / 100;
+ }
+
+ int rightVolume() const {
+ return pan < 0? volume * (100 + pan) / 100: volume;
}
};
@@ -61,7 +69,7 @@ namespace AGDS {
public:
SoundManager(AGDSEngine *engine, Audio::Mixer *mixer): _nextId(1), _engine(engine), _mixer(mixer) { }
void tick();
- int play(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying = true, int id = -1);
+ int play(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int volume, int pan, int id = -1);
bool playing(int id) const;
void stopAll();
const Sound *find(int id) const;
Commit: 91bb27cb7823ed5f097ea66b4b29301be50a8730
https://github.com/scummvm/scummvm/commit/91bb27cb7823ed5f097ea66b4b29301be50a8730
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:57+01:00
Commit Message:
AGDS: add enableSystemUser correction
original engine enable user if system user wasn't disabled.
Changed paths:
engines/agds/agds.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 74d8cdefcc6..aefb1eb62be 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -215,8 +215,13 @@ public:
_userEnabled = enabled;
}
void enableSystemUser(bool enabled) {
- _systemUserEnabled = enabled;
+ if (enabled) {
+ if (_systemUserEnabled)
+ _userEnabled = true;
+ } else
+ _systemUserEnabled = enabled;
}
+
bool userEnabled() const {
return _userEnabled && _systemUserEnabled;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 5776b295d48..5667b7423e0 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1546,12 +1546,14 @@ void Process::leaveCharacter() {
debug("leaveCharacter %s %s", arg1.c_str(), arg2.c_str());
RegionPtr region = _engine->loadRegion(arg2);
debug("region: %s", region->toString().c_str());
+ _engine->enableSystemUser(true); //called from update_music_screen_sound_curtain
}
void Process::leaveCharacterEx() {
int arg3 = pop();
Common::String arg2 = popString();
Common::String arg1 = popString();
debug("leaveCharacterEx %s %s %d", arg1.c_str(), arg2.c_str(), arg3);
+ _engine->enableSystemUser(true); //called from update_music_screen_sound_curtain
}
void Process::setCharacter() {
@@ -1712,6 +1714,7 @@ void Process::stub235() {
_engine->getSystemVariable("screen_curtain")->setInteger(fadeScreen);
_engine->getSystemVariable("sound_curtain")->setInteger(fadeSound);
_engine->getSystemVariable("music_curtain")->setInteger(fadeMusic);
+ _engine->enableSystemUser(true);
}
void Process::setCharacterNotifyVars() {
Commit: e3b3152f719047ea3979fc2c8da1a214f54e9bbc
https://github.com/scummvm/scummvm/commit/e3b3152f719047ea3979fc2c8da1a214f54e9bbc
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:57+01:00
Commit Message:
AGDS: cleanup exit codes handling a bit, fix a few deactivate/activate mismatches
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 9a4e90215c6..1a721240329 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -212,7 +212,7 @@ void Process::run() {
break;
case kExitCodeLoadScreenObjectAs:
case kExitCodeLoadScreenObject:
- _status = kStatusPassive;
+ deactivate();
_object->lock();
_engine->runObject(getExitArg1(), getExitArg2());
_object->unlock();
@@ -220,11 +220,10 @@ void Process::run() {
restart = true;
break;
case kExitCodeRunDialog:
- _status = kStatusPassive;
+ deactivate();
_object->lock();
_engine->runDialog(getName(), getExitArg1());
_object->unlock();
- deactivate();
break;
case kExitCodeSetNextScreen:
case kExitCodeSetNextScreenSaveOrLoad:
@@ -233,19 +232,19 @@ void Process::run() {
_engine->setNextScreenName(getExitArg1(), code == kExitCodeSetNextScreenSaveOrLoad? ScreenLoadingType::SaveOrLoad: ScreenLoadingType::Normal);
break;
case kExitCodeMouseAreaChange:
- _status = kStatusPassive;
+ deactivate();
_object->lock();
_engine->changeMouseArea(getExitIntArg1(), getExitIntArg2());
_object->unlock();
- deactivate();
+ activate();
restart = true;
break;
case kExitCodeLoadInventoryObject:
- _status = kStatusPassive;
+ deactivate();
_object->lock();
_engine->inventory().add(_engine->runObject(getExitArg1()));
_object->unlock();
- deactivate();
+ activate();
restart = true;
break;
case kExitCodeCloseInventory:
@@ -267,7 +266,7 @@ void Process::run() {
restart = true;
break;
case kExitCodeLoadGame:
- _status = kStatusPassive;
+ deactivate();
_object->lock();
if (_engine->loadGameState(getExitIntArg1()).getCode() == Common::kNoError) {
done();
@@ -275,7 +274,7 @@ void Process::run() {
debug("save loading failed, resuming execution...");
}
_object->unlock();
- _status = kStatusActive;
+ activate();
restart = true;
break;
case kExitCodeSaveGame:
Commit: ef407d757fc9eb8b3f592c3cf01a9a8d1e0a835b
https://github.com/scummvm/scummvm/commit/ef407d757fc9eb8b3f592c3cf01a9a8d1e0a835b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:57+01:00
Commit Message:
AGDS: fix tile object opcode used with no resource
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index d7b2d31aae8..24b8920067c 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -253,6 +253,9 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Po
if (picture) {
Common::Point dst = pos + getPosition();
Common::Rect srcRect = picture->getRect();
+ if (!_srcRect.isEmpty()) {
+ srcRect = _srcRect;
+ }
uint32 color = _picture->format.ARGBToColor(_alpha, 255, 255, 255);
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect())) {
picture->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 79ff5d7cb84..cfac34e2bd4 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -72,6 +72,7 @@ private:
Animation * _mouseCursor;
Common::Point _pos, _animationPos, _offset;
Common::Point _regionOffset;
+ Common::Rect _srcRect;
int _z;
Common::String _text;
Common::String _title;
@@ -299,6 +300,8 @@ public:
void alive(bool value);
+ void srcRect(Common::Rect srcRect) { _srcRect = srcRect; }
+
bool pointIn(Common::Point pos);
};
typedef Common::SharedPtr<Object> ObjectPtr;
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 1a721240329..9fe7d851a62 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -32,7 +32,7 @@ Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
_engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object),
_ip(ip), _lastIp(ip),
_exited(false), _status(kStatusActive), _exitCode(kExitCodeDestroy),
- _tileWidth(16), _tileHeight(16), _tileResource(0), _tileIndex(0),
+ _tileWidth(16), _tileHeight(16), _tileResource(-1), _tileIndex(0),
_timer(0),
_animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0),
_phaseVarControlled(false), _animationSpeed(100),
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 5667b7423e0..c7d538babbd 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -670,7 +670,7 @@ void Process::resetState() {
_tileWidth = 16;
_tileHeight = 16;
_tileIndex = 0;
- _tileResource = 0;
+ _tileResource = -1;
_filmSubtitlesResource = -1;
}
@@ -1114,8 +1114,10 @@ void Process::setObjectTile() {
return;
}
- if (_tileResource <= 0) {
- warning("invalid resource id, skipping");
+ if (_tileResource < 0) {
+ int x = _animationPosition.x;
+ int y = _animationPosition.y;
+ object->srcRect(Common::Rect(x, y, x + _tileWidth, y + _tileHeight));
return;
}
if (_tileHeight <= 0 || _tileWidth <= 0) {
Commit: 39d08f1afd3ab552f536b49bb58917411b8b45aa
https://github.com/scummvm/scummvm/commit/39d08f1afd3ab552f536b49bb58917411b8b45aa
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:57+01:00
Commit Message:
AGDS: move character to the click point, skip respawning handlers, fix trap handler in chapter 2 (Vick)
Changed paths:
engines/agds/agds.cpp
engines/agds/character.cpp
engines/agds/character.h
engines/agds/process.cpp
engines/agds/process.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index dea1204f665..6ed34638f42 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -249,6 +249,10 @@ void AGDSEngine::runProcess(const ObjectPtr &object, uint ip) {
debug("starting process %s:%04x", object->getName().c_str(), ip);
for(uint i = 0; i < _processes.size(); ++i) {
auto &process = _processes[i];
+ if (ip != 0 && process && process->entryPoint() == ip) {
+ debug("found existing process, skipping...");
+ return;
+ }
if (!process) {
process = ProcessPtr(new Process(this, object, ip));
process->run();
@@ -262,7 +266,6 @@ ObjectPtr AGDSEngine::getCurrentScreenObject(const Common::String &name) {
return _currentScreen? _currentScreen->find(name): ObjectPtr();
}
-
ObjectPtr AGDSEngine::runObject(const Common::String &name, const Common::String &prototype, bool allowInitialise) {
debug("runObject %s %s", name.c_str(), prototype.c_str());
ObjectPtr object = getCurrentScreenObject(name);
@@ -558,6 +561,12 @@ Common::Error AGDSEngine::run() {
break;
}
+ if (_currentCharacter && _currentCharacter->active()) {
+ // FIXME: some object requires character to be in "trap" region
+ // Remove this after movement implementation.
+ _currentCharacter->moveTo(Common::String(), _mouse, -1);
+ }
+
auto objects = _currentScreen->find(_mouse);
if (objects.empty() && !_currentInventoryObject) { //allow inventory to be selected
auto object = _inventory.find(_mouse);
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 542dfe493c7..8a643d715ef 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -186,7 +186,7 @@ void Character::stop() {
}
void Character::tick() {
- if (!_enabled || !_visible || !_animation || _stopped)
+ if (!active() || !_animation)
return;
auto screen = _engine->getCurrentScreen();
diff --git a/engines/agds/character.h b/engines/agds/character.h
index fcc4afebd78..44ed5f28454 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -101,6 +101,9 @@ public:
void visible(bool visible) {
_visible = visible;
}
+ bool active() const {
+ return _enabled && _visible && !_stopped;
+ }
void animate(const Common::String &processName, Common::Point pos, int direction, int speed);
void animate(int direction, int speed, bool jokes);
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 9fe7d851a62..c03eea2dcc3 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -30,7 +30,7 @@ namespace AGDS {
Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
_engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object),
- _ip(ip), _lastIp(ip),
+ _entryPoint(ip), _ip(ip), _lastIp(ip),
_exited(false), _status(kStatusActive), _exitCode(kExitCodeDestroy),
_tileWidth(16), _tileHeight(16), _tileResource(-1), _tileIndex(0),
_timer(0),
diff --git a/engines/agds/process.h b/engines/agds/process.h
index d33462de283..f39b05846ef 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -46,6 +46,7 @@ private:
Common::String _parentScreen;
ObjectPtr _object;
StackType _stack;
+ unsigned _entryPoint;
unsigned _ip, _lastIp;
Status _status;
bool _exited;
@@ -128,6 +129,10 @@ private:
public:
Process(AGDSEngine *engine, ObjectPtr object, unsigned ip = 0);
+ unsigned entryPoint() const {
+ return _entryPoint;
+ }
+
static Common::String disassemble(ObjectPtr object);
ObjectPtr getObject() const {
Commit: 51ccf7af58754cdedcae686bc1cdf2baa1c1c3d2
https://github.com/scummvm/scummvm/commit/51ccf7af58754cdedcae686bc1cdf2baa1c1c3d2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:57+01:00
Commit Message:
AGDS: port to new engine detection API
Changed paths:
engines/agds/detection.cpp
diff --git a/engines/agds/detection.cpp b/engines/agds/detection.cpp
index e2400fe16aa..fcb75bb8047 100644
--- a/engines/agds/detection.cpp
+++ b/engines/agds/detection.cpp
@@ -35,11 +35,11 @@ public:
_maxScanDepth = 3;
}
- const char *getEngineId() const override {
+ const char *getName() const override {
return "agds";
}
- const char *getName() const override {
+ const char *getEngineName() const override {
return "AGDS Engine";
}
Commit: 3abde97b89673b23bf97c1d1d5803373f3063475
https://github.com/scummvm/scummvm/commit/3abde97b89673b23bf97c1d1d5803373f3063475
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:57+01:00
Commit Message:
AGDS: port to the new API
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 6ed34638f42..9b4a1abc686 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -38,7 +38,7 @@
#include "common/error.h"
#include "common/events.h"
#include "common/file.h"
-#include "common/ini-file.h"
+#include "common/formats/ini-file.h"
#include "common/memstream.h"
#include "common/savefile.h"
#include "common/system.h"
Commit: edf5696423284e3c1f780dada8fe735fd5862a02
https://github.com/scummvm/scummvm/commit/edf5696423284e3c1f780dada8fe735fd5862a02
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:58+01:00
Commit Message:
AGDS: fix inventory at top left corner
Inventory in AGDS is actually just name/refcount/object pointer, and after loading object pointer set to -1.
Changed paths:
engines/agds/inventory.cpp
engines/agds/inventory.h
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 3558b58ef12..7ffe4e58227 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -57,20 +57,29 @@ void Inventory::visible(bool visible) {
int Inventory::free() const {
int free = 0;
for (uint i = 0; i < _entries.size(); ++i)
- if (!_entries[i])
+ if (!_entries[i].hasObject)
++free;
return free;
}
-ObjectPtr Inventory::get(int index) const {
- return index >= 0 && index < kMaxSize? _entries[index]: ObjectPtr();
+ObjectPtr Inventory::get(int index) {
+ if (index >= 0 && index < kMaxSize) {
+ auto & entry = _entries[index];
+ if (entry.hasObject && !entry.object)
+ entry.object = _engine->runObject(entry.name);
+ return entry.object;
+ }
+ return {};
}
int Inventory::add(const ObjectPtr & object) {
object->persistent(false);
for (uint i = 0; i < _entries.size(); ++i) {
- if (!_entries[i]) {
- _entries[i] = object;
+ auto & entry = _entries[i];
+ if (!entry.hasObject) {
+ entry.name = object->getName();
+ entry.object = object;
+ entry.hasObject = true;
return i;
}
}
@@ -80,9 +89,9 @@ int Inventory::add(const ObjectPtr & object) {
bool Inventory::remove(const Common::String &name) {
bool removed = false;
for (uint i = 0; i < _entries.size(); ++i) {
- auto & object = _entries[i];
- if (object && object->getName() == name) {
- object.reset();
+ auto & entry = _entries[i];
+ if (entry.hasObject && entry.name == name) {
+ entry.reset();
removed = true;
}
}
@@ -92,7 +101,8 @@ bool Inventory::remove(const Common::String &name) {
void Inventory::removeGaps() {
auto n = _entries.size();
for (uint src = 0, dst = 0; src < n; ++src) {
- if (_entries[src])
+ auto & entry = _entries[src];
+ if (entry.hasObject)
{
if (dst != src)
{
@@ -107,18 +117,21 @@ void Inventory::removeGaps() {
}
int Inventory::find(const Common::String &name) const {
- for (uint i = 0; i < _entries.size(); ++i)
- if (_entries[i] && _entries[i]->getName() == name)
+ for (uint i = 0; i < _entries.size(); ++i) {
+ auto & entry = _entries[i];
+ if (entry.hasObject && entry.name == name)
return i;
+ }
return -1;
}
ObjectPtr Inventory::find(const Common::Point pos) const {
for (uint i = 0; i < _entries.size(); ++i) {
- auto & object = _entries[i];
- if (!object)
+ auto & entry = _entries[i];
+ if (!entry.object)
continue;
+ auto & object = entry.object;
auto picture = object->getPicture();
if (picture) {
auto rect = picture->getRect();
@@ -138,29 +151,24 @@ void Inventory::clear() {
void Inventory::load(Common::ReadStream* stream) {
clear();
- int n = kMaxSize;
- while(n--) {
+ for(int i = 0; i < kMaxSize; ++i) {
Common::String name = readString(stream);
int refcount = stream->readUint32LE();
int objectPtr = stream->readUint32LE();
if (!name.empty() && refcount) {
- debug("inventory: %s %d %d", name.c_str(), refcount, objectPtr);
- add(_engine->runObject(name));
+ debug("load inventory object: %s %d %d", name.c_str(), refcount, objectPtr);
+ auto & entry = _entries[i];
+ entry.name = name;
+ entry.hasObject = true;
}
}
}
void Inventory::save(Common::WriteStream* stream) const {
for(auto & entry : _entries) {
- if (entry) {
- writeString(stream, entry->getName());
- stream->writeUint32LE(1);
- stream->writeSint32LE(-1);
- } else {
- writeString(stream, Common::String());
- stream->writeUint32LE(0);
- stream->writeSint32LE(0);
- }
+ writeString(stream, entry.name);
+ stream->writeUint32LE(entry.hasObject? 1: 0);
+ stream->writeSint32LE(entry.hasObject? -1: 0);
}
}
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index a7b2cee3c63..499f91cf115 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -37,7 +37,18 @@ class AGDSEngine;
class Inventory {
class AGDSEngine* _engine;
- typedef Common::Array<ObjectPtr> EntriesType;
+ struct Entry {
+ Common::String name;
+ bool hasObject;
+ ObjectPtr object;
+
+ void reset() {
+ name.clear();
+ hasObject = false;
+ object.reset();
+ }
+ };
+ typedef Common::Array<Entry> EntriesType;
EntriesType _entries;
bool _enabled;
bool _visible;
@@ -45,7 +56,7 @@ class Inventory {
public:
static const int kMaxSize = 35;
- Inventory(AGDSEngine* _engine);
+ Inventory(AGDSEngine* engine);
~Inventory();
void load(Common::ReadStream* stream);
@@ -70,7 +81,7 @@ public:
bool remove(const Common::String &name);
void removeGaps();
- ObjectPtr get(int index) const;
+ ObjectPtr get(int index);
int find(const Common::String &name) const;
ObjectPtr find(const Common::Point pos) const;
Commit: febed22dfb0770000433d499f3a88386d2a0e2df
https://github.com/scummvm/scummvm/commit/febed22dfb0770000433d499f3a88386d2a0e2df
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:58+01:00
Commit Message:
AGDS: fix log string
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c7d538babbd..d24e7c50009 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1047,7 +1047,7 @@ void Process::animationNextFrame() {
void Process::signalAnimationEnd() {
Common::String phaseVar = popString();
- debug("restartAnimation %s", phaseVar.c_str());
+ debug("signalAnimationEnd %s", phaseVar.c_str());
if (phaseVar.empty()) {
warning("no phaseVar");
return;
Commit: 5ee012f1105124459e8b23099f6784d4a19ca256
https://github.com/scummvm/scummvm/commit/5ee012f1105124459e8b23099f6784d4a19ca256
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:58+01:00
Commit Message:
AGDS: separately handled animation frame and its on-screen status
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 5f0973771fe..f6bfb111500 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -34,7 +34,7 @@ Animation::Animation(AGDSEngine *engine, const Common::String &name) :
_engine(engine), _name(name), _flic(), _frame(),
_frames(0), _loop(false), _cycles(1), _phaseVarControlled(false),
_phase(0), _paused(false), _speed(100), _z(0),
- _delay(0), _random(0), _scale(1) {
+ _delay(0), _random(0), _scale(1), _onScreen(true) {
}
Animation::~Animation() {
@@ -88,6 +88,7 @@ bool Animation::load(Common::SeekableReadStream *stream, const Common::String &f
if (flic->loadStream(stream)) {
_frames = flic->getFrameCount();
_flic = flic;
+ decodeNextFrame();
return true;
} else {
_frames = 0;
@@ -122,17 +123,22 @@ void Animation::rewind() {
_flic->rewind();
}
+void Animation::onScreen(bool onScreen) {
+ _onScreen = onScreen;
+}
+
bool Animation::tick() {
if (!_flic && _frame) { //static frame
return true;
}
- if (_paused || (_phaseVarControlled && !_frame)) {
+ if (_paused || !_frame || (_phaseVarControlled && !_onScreen)) {
return true;
}
if (_phaseVarControlled && _engine->getGlobal(_phaseVar) == -2) {
debug("phase var %s signalled deleting of animation", _phaseVar.c_str());
+ freeFrame();
return false;
}
@@ -143,13 +149,16 @@ bool Animation::tick() {
bool eov = _phase >= _frames;
if (_phaseVarControlled && eov) {
- freeFrame();
_engine->setGlobal(_phaseVar, -1);
+ onScreen(false);
return true;
}
if (!eov)
+ {
decodeNextFrame();
+ onScreen(true);
+ }
if (!_process.empty()) {
if (!_phaseVar.empty())
@@ -172,14 +181,14 @@ bool Animation::tick() {
return false;
}
- if (eov)
+ if (eov && frames() > 1)
rewind();
return true;
}
void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst) const {
dst += _position;
- if (_frame) {
+ if (_frame && _onScreen) {
Common::Rect srcRect = _frame->getRect();
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
_frame->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 2b3147ef560..380a6a7e000 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -54,13 +54,12 @@ class Animation {
int _delay;
int _random;
float _scale;
+ bool _onScreen;
public:
Animation(AGDSEngine *engine, const Common::String &name);
~Animation();
- void freeFrame();
-
bool hasFrame() const {
return _frame != nullptr;
}
@@ -114,6 +113,7 @@ public:
void phaseVarControlled(bool controlled) {
_phaseVarControlled = controlled;
+ _onScreen = !controlled;
}
bool paused() const {
@@ -153,18 +153,18 @@ public:
return _phase;
}
+ void onScreen(bool onScreen);
+
bool load(Common::SeekableReadStream *stream, const Common::String &fname);
void paint(Graphics::Surface & backbuffer, Common::Point dst) const;
int width() const;
int height() const;
bool tick();
- void decodeNextFrameIfNoFrame() {
- if (!_frame)
- decodeNextFrame();
- }
-
void decodeNextFrame();
+
+private:
+ void freeFrame();
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d24e7c50009..d306875fb3c 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1015,8 +1015,9 @@ void Process::restartAnimation() {
animation->rewind();
}
animation->resume();
- animation->decodeNextFrameIfNoFrame();
- _engine->setGlobal(phaseVar, animation->phase() - 1);
+ animation->onScreen(true);
+ auto phase = animation->phase();
+ _engine->setGlobal(phaseVar, phase > 0? phase - 1: 0);
} else {
warning("no animation with phase var %s found", phaseVar.c_str());
_engine->setGlobal(phaseVar, -1);
@@ -1075,7 +1076,7 @@ void Process::pauseAnimation() {
animation->pause();
if (arg > 0) {
//1, 2 stop (2 with rewind)
- animation->freeFrame();
+ animation->onScreen(false);
if (arg == 2) {
animation->rewind();
_engine->setGlobal(phaseVar, 0);
Commit: 3e7c1406b0349f21fbeb401fb177b2ee2e73e5b3
https://github.com/scummvm/scummvm/commit/3e7c1406b0349f21fbeb401fb177b2ee2e73e5b3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:58+01:00
Commit Message:
AGDS: clean character visibility up
Changed paths:
engines/agds/agds.cpp
engines/agds/character.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 9b4a1abc686..8d56c1efc8a 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -308,7 +308,7 @@ void AGDSEngine::saveScreenPatch() {
if (!patch)
patch = PatchPtr(new Patch());
_currentScreen->save(patch);
- patch->characterPresent = _currentCharacter != nullptr;
+ patch->characterPresent = _currentCharacter != nullptr && _currentCharacter->visible();
if (_currentCharacter) {
patch->characterPosition = _currentCharacter->position();
patch->characterDirection = _currentCharacter->direction();
@@ -340,11 +340,15 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
auto screenObject = loadObject(name, Common::String(), !hasScreenPatch);
_currentScreen = new Screen(this, screenObject, loadingType, previousScreenName);
+ if (_currentCharacter)
+ _currentCharacter->visible(false);
+
runProcess(screenObject);
if (doPatch) {
_currentScreen->load(patch);
if (_currentCharacter && patch->characterPresent) {
+ _currentCharacter->visible(true);
_currentCharacter->position(patch->characterPosition);
_currentCharacter->direction(patch->characterDirection);
}
@@ -1191,8 +1195,6 @@ void AGDSEngine::loadNextScreen() {
_nextScreenType = ScreenLoadingType::Normal;
loadScreen(nextScreenName, nextScreenType);
}
- if (_currentCharacter)
- _currentCharacter->visible(true);
}
Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 44ed5f28454..cb6cba47839 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -101,6 +101,11 @@ public:
void visible(bool visible) {
_visible = visible;
}
+
+ bool visible() const {
+ return _visible;
+ }
+
bool active() const {
return _enabled && _visible && !_stopped;
}
Commit: b900d1843b79fa28bc1281e6fefc7f8baae3056f
https://github.com/scummvm/scummvm/commit/b900d1843b79fa28bc1281e6fefc7f8baae3056f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:58+01:00
Commit Message:
AGDS: Fix font surface leak
Changed paths:
engines/agds/font.h
diff --git a/engines/agds/font.h b/engines/agds/font.h
index ceff1ade677..5991f3c8dd4 100644
--- a/engines/agds/font.h
+++ b/engines/agds/font.h
@@ -24,6 +24,7 @@
#define AGDS_FONT_H
#include "graphics/font.h"
+#include "common/ptr.h"
namespace Graphics {
struct TransparentSurface;
@@ -32,7 +33,7 @@ namespace Graphics {
namespace AGDS {
class Font : public Graphics::Font {
- Graphics::TransparentSurface * _surface;
+ Common::ScopedPtr<Graphics::TransparentSurface> _surface;
int _glyphW, _glyphH;
int _cellW, _cellH;
uint8 _width[0x100];
Commit: a700e5bd8b610f2892ba7a3145ecd7973b1cf1aa
https://github.com/scummvm/scummvm/commit/a700e5bd8b610f2892ba7a3145ecd7973b1cf1aa
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:58+01:00
Commit Message:
AGDS: implement fog stub
Changed paths:
engines/agds/agds.cpp
engines/agds/character.cpp
engines/agds/character.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 8d56c1efc8a..201ddba5798 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -341,7 +341,7 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
_currentScreen = new Screen(this, screenObject, loadingType, previousScreenName);
if (_currentCharacter)
- _currentCharacter->visible(false);
+ _currentCharacter->reset();
runProcess(screenObject);
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 8a643d715ef..d9873348f08 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -32,11 +32,21 @@
#include "common/system.h"
#include "common/textconsole.h"
#include "common/util.h"
+#include "graphics/surface.h"
#include <math.h>
namespace AGDS {
+Character::Character(AGDSEngine * engine, const Common::String & name):
+ _engine(engine), _name(name), _object(), _animation(nullptr), _jokes(false),
+ _enabled(true), _visible(true), _stopped(false),
+ _phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
+}
+
+Character::~Character() {
+}
+
void Character::load(Common::SeekableReadStream *stream) {
debug("loading character...");
stream->readUint32LE(); //unk
@@ -111,19 +121,16 @@ void Character::loadState(Common::ReadStream* stream) {
debug("character at %d, %d, dir: %d", x, y, dir);
position(Common::Point(x, y));
direction(dir);
- int n = 2;
- while(n--) {
- int v = stream->readUint16LE();
- debug("savegame character leftover: %d", v);
- }
+ _visible = stream->readUint16LE();
+ _enabled = stream->readUint16LE();
}
void Character::saveState(Common::WriteStream* stream) const {
stream->writeUint16LE(_pos.x);
stream->writeUint16LE(_pos.y);
stream->writeUint16LE(_direction);
- stream->writeUint16LE(1);
- stream->writeUint16LE(1);
+ stream->writeUint16LE(_visible);
+ stream->writeUint16LE(_enabled);
}
@@ -225,6 +232,17 @@ int Character::z() const {
return g_system->getHeight() - y;
}
+void Character::reset() {
+ _fog.reset();
+ _visible = false;
+}
+
+
+void Character::setFog(Graphics::Surface * surface, int minZ, int maxZ) {
+ _fog.reset(surface);
+ _fogMinZ = minZ;
+ _fogMaxZ = maxZ;
+}
int Character::getDirectionForMovement(Common::Point delta) {
auto angle = atan2(delta.y, delta.x);
diff --git a/engines/agds/character.h b/engines/agds/character.h
index cb6cba47839..a757401a4a0 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -39,9 +39,11 @@ typedef Common::SharedPtr<Object> ObjectPtr;
class Animation;
class Character {
+ using FogPtr = Common::ScopedPtr<Graphics::Surface>;
AGDSEngine * _engine;
ObjectPtr _object;
Animation * _animation;
+ FogPtr _fog;
bool _jokes;
Common::String _name;
Common::String _processName;
@@ -55,6 +57,7 @@ class Character {
int _direction;
int _jokesDirection;
int _movementDirections;
+ int _fogMinZ, _fogMaxZ;
struct AnimationDescription {
struct Frame {
@@ -69,11 +72,8 @@ class Character {
const AnimationDescription * _description;
public:
- Character(AGDSEngine * engine, const Common::String & name):
- _engine(engine), _name(name), _object(), _animation(nullptr), _jokes(false),
- _enabled(true), _visible(true), _stopped(false),
- _phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
- }
+ Character(AGDSEngine * engine, const Common::String & name);
+ ~Character();
void associate(const Common::String &name);
@@ -141,6 +141,9 @@ public:
int getDirectionForMovement(Common::Point delta);
int z() const;
+
+ void reset();
+ void setFog(Graphics::Surface * surface, int minZ, int maxZ);
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d306875fb3c..7cb15c5c52f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1638,7 +1638,10 @@ void Process::fogOnCharacter() {
int arg2 = pop();
int arg1 = pop();
Common::String name = popText();
- debug("fogOnCharacter %s %d %d", name.c_str(), arg1, arg2);
+ debug("fogOnCharacter %s z: [%d,%d]", name.c_str(), arg1, arg2);
+ Character *character = _engine->currentCharacter();
+ if (character)
+ character->setFog(_engine->loadPicture(name), arg1, arg2);
}
void Process::setRain() {
Commit: 263f2533570d77ed7a1d30d16ffba809709dea08
https://github.com/scummvm/scummvm/commit/263f2533570d77ed7a1d30d16ffba809709dea08
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:58+01:00
Commit Message:
AGDS: remove _stopped check in active, do not touch visible
Changed paths:
engines/agds/agds.cpp
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 201ddba5798..05a361a715e 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -336,13 +336,19 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
bool doPatch = patch && loadingType != ScreenLoadingType::SaveOrLoad;
bool hasScreenPatch = doPatch && patch->screenSaved;
+ if (_currentScreen) {
+ if (_currentCharacter) {
+ _currentCharacter->reset();
+ if (loadingType != ScreenLoadingType::Normal) {
+ _currentCharacter->visible(false);
+ }
+ }
+ }
+
_currentScreenName = name;
auto screenObject = loadObject(name, Common::String(), !hasScreenPatch);
_currentScreen = new Screen(this, screenObject, loadingType, previousScreenName);
- if (_currentCharacter)
- _currentCharacter->reset();
-
runProcess(screenObject);
if (doPatch) {
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index d9873348f08..60b0b6d5cdd 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -234,10 +234,8 @@ int Character::z() const {
void Character::reset() {
_fog.reset();
- _visible = false;
}
-
void Character::setFog(Graphics::Surface * surface, int minZ, int maxZ) {
_fog.reset(surface);
_fogMinZ = minZ;
diff --git a/engines/agds/character.h b/engines/agds/character.h
index a757401a4a0..a4555c59622 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -107,7 +107,7 @@ public:
}
bool active() const {
- return _enabled && _visible && !_stopped;
+ return _enabled && _visible;
}
void animate(const Common::String &processName, Common::Point pos, int direction, int speed);
Commit: ea83311759045399c866d7eb494406d40813bee3
https://github.com/scummvm/scummvm/commit/ea83311759045399c866d7eb494406d40813bee3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:58+01:00
Commit Message:
AGDS: implement blending with "fog"
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/character.cpp
engines/agds/character.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index f6bfb111500..b208b513417 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -186,13 +186,47 @@ bool Animation::tick() {
return true;
}
-void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst) const {
+void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst, Graphics::TransparentSurface *mask, int maskAlpha) const {
dst += _position;
- if (_frame && _onScreen) {
- Common::Rect srcRect = _frame->getRect();
- if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
- _frame->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
- }
+ if (!_frame || !_onScreen)
+ return;
+
+ Common::Rect srcRect = _frame->getRect();
+ if (!Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
+ return;
+
+ if (mask) {
+ int invMaskAlpha = 255 - maskAlpha;
+ auto subFrame = _frame->getSubArea(srcRect);
+ auto subMask = mask->getSubArea(srcRect);
+ byte * dstPixels = static_cast<byte *>(backbuffer.getBasePtr(dst.x, dst.y));
+ const byte * srcPixels = static_cast<byte *>(subFrame.getPixels());
+ const byte * maskPixels = static_cast<byte *>(subMask.getPixels());
+ for(int y = 0; y != srcRect.height(); ++y) {
+ byte *dstRow = dstPixels;
+ const byte *srcRow = srcPixels;
+ const byte *maskRow = maskPixels;
+ for(int x = 0; x != srcRect.width(); ++x) {
+ uint8 srcA = *srcRow++;
+ ++dstRow;
+ ++maskRow;
+ uint8 invSrcA = 255 - srcA;
+ if (srcA != 0) {
+ for(int n = 3; n--; ++dstRow) {
+ *dstRow = ((*dstRow * invSrcA + *srcRow++ * srcA) * invMaskAlpha + *maskRow++ * maskAlpha * srcA) / 65025;
+ }
+ } else {
+ srcRow += 3;
+ dstRow += 3;
+ maskRow += 3;
+ }
+ }
+ dstPixels += backbuffer.pitch;
+ srcPixels += subFrame.pitch;
+ maskPixels += subMask.pitch;
+ }
+ } else
+ _frame->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
}
int Animation::width() const {
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 380a6a7e000..7d5e3212b36 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -156,7 +156,7 @@ public:
void onScreen(bool onScreen);
bool load(Common::SeekableReadStream *stream, const Common::String &fname);
- void paint(Graphics::Surface & backbuffer, Common::Point dst) const;
+ void paint(Graphics::Surface & backbuffer, Common::Point dst, Graphics::TransparentSurface *mask = nullptr, int maskAlpha = 0) const;
int width() const;
int height() const;
bool tick();
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 60b0b6d5cdd..390b616cb9c 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -32,7 +32,7 @@
#include "common/system.h"
#include "common/textconsole.h"
#include "common/util.h"
-#include "graphics/surface.h"
+#include "graphics/transparent_surface.h"
#include <math.h>
@@ -222,7 +222,17 @@ void Character::paint(Graphics::Surface &backbuffer, Common::Point pos) const {
pos.y -= _animation->height();
pos.x -= _animation->width() / 2;
- _animation->paint(backbuffer, pos);
+
+ int fogAlpha = 0;
+ if (_fog) {
+ auto z = this->z();
+ if (z >= _fogMinZ && z < _fogMaxZ) {
+ fogAlpha = 255 * (z - _fogMinZ) / (_fogMaxZ - _fogMinZ);
+ } else if (z >= _fogMaxZ) {
+ fogAlpha = 255;
+ }
+ }
+ _animation->paint(backbuffer, pos, _fog.get(), fogAlpha);
}
int Character::z() const {
@@ -236,7 +246,7 @@ void Character::reset() {
_fog.reset();
}
-void Character::setFog(Graphics::Surface * surface, int minZ, int maxZ) {
+void Character::setFog(Graphics::TransparentSurface * surface, int minZ, int maxZ) {
_fog.reset(surface);
_fogMinZ = minZ;
_fogMaxZ = maxZ;
diff --git a/engines/agds/character.h b/engines/agds/character.h
index a4555c59622..81bc8db44a9 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -29,7 +29,7 @@
#include "common/rect.h"
namespace Common { class SeekableReadStream; class ReadStream; class WriteStream; }
-namespace Graphics { struct Surface; }
+namespace Graphics { struct Surface; struct TransparentSurface; }
namespace AGDS {
@@ -39,7 +39,7 @@ typedef Common::SharedPtr<Object> ObjectPtr;
class Animation;
class Character {
- using FogPtr = Common::ScopedPtr<Graphics::Surface>;
+ using FogPtr = Common::ScopedPtr<Graphics::TransparentSurface>;
AGDSEngine * _engine;
ObjectPtr _object;
Animation * _animation;
@@ -143,7 +143,7 @@ public:
int z() const;
void reset();
- void setFog(Graphics::Surface * surface, int minZ, int maxZ);
+ void setFog(Graphics::TransparentSurface * surface, int minZ, int maxZ);
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 7cb15c5c52f..2020a06c53f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1641,7 +1641,7 @@ void Process::fogOnCharacter() {
debug("fogOnCharacter %s z: [%d,%d]", name.c_str(), arg1, arg2);
Character *character = _engine->currentCharacter();
if (character)
- character->setFog(_engine->loadPicture(name), arg1, arg2);
+ character->setFog(_engine->convertToTransparent(_engine->loadPicture(name)), arg1, arg2);
}
void Process::setRain() {
Commit: 2c36f3f9b433c8ddc9e35e71630f552ebad03214
https://github.com/scummvm/scummvm/commit/2c36f3f9b433c8ddc9e35e71630f552ebad03214
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:58+01:00
Commit Message:
AGDS: cache scaled surface/rescale animation
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/character.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index b208b513417..118645629d7 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -31,7 +31,7 @@
namespace AGDS {
Animation::Animation(AGDSEngine *engine, const Common::String &name) :
- _engine(engine), _name(name), _flic(), _frame(),
+ _engine(engine), _name(name), _flic(), _frame(), _scaledFrame(),
_frames(0), _loop(false), _cycles(1), _phaseVarControlled(false),
_phase(0), _paused(false), _speed(100), _z(0),
_delay(0), _random(0), _scale(1), _onScreen(true) {
@@ -42,7 +42,16 @@ Animation::~Animation() {
delete _flic;
}
+void Animation::freeScaledFrame() {
+ if (_scaledFrame) {
+ _scaledFrame->free();
+ delete _scaledFrame;
+ _scaledFrame = nullptr;
+ }
+}
+
void Animation::freeFrame() {
+ freeScaledFrame();
if (_frame) {
_frame->free();
delete _frame;
@@ -80,6 +89,7 @@ bool Animation::load(Common::SeekableReadStream *stream, const Common::String &f
if (fname.hasSuffixIgnoreCase(".bmp")) {
_frame = _engine->loadPicture(fname);
+ rescaleCurrentFrame();
_frames = 1;
return true;
}
@@ -96,6 +106,22 @@ bool Animation::load(Common::SeekableReadStream *stream, const Common::String &f
}
}
+void Animation::scale(float scale) {
+ if (scale != _scale) {
+ debug("changing scale to %g", scale);
+ _scale = scale;
+ rescaleCurrentFrame();
+ }
+}
+
+void Animation::rescaleCurrentFrame() {
+ if (_scale == 1 || !_frame)
+ return;
+
+ freeScaledFrame();
+ _scaledFrame = _frame->scale(_frame->w * _scale, _frame->h * _scale, true);
+}
+
void Animation::decodeNextFrame() {
auto frame = _flic->decodeNextFrame();
if (!frame) {
@@ -107,14 +133,7 @@ void Animation::decodeNextFrame() {
freeFrame();
_delay = _flic->getCurFrameDelay() * _speed / 4000; //40 == 1000 / 25, 25 fps
_frame = _engine->convertToTransparent(frame->convertTo(_engine->pixelFormat(), _flic->getPalette()));
-
- if (_scale != 1) {
- auto f = _frame->scale(_frame->w * _scale, _frame->h * _scale, true);
- if (f) {
- freeFrame();
- _frame = f;
- }
- }
+ rescaleCurrentFrame();
++_phase;
}
@@ -188,16 +207,17 @@ bool Animation::tick() {
void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst, Graphics::TransparentSurface *mask, int maskAlpha) const {
dst += _position;
- if (!_frame || !_onScreen)
+ auto *frame = _scaledFrame? _scaledFrame: _frame;
+ if (!frame || !_onScreen)
return;
- Common::Rect srcRect = _frame->getRect();
+ Common::Rect srcRect = frame->getRect();
if (!Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
return;
if (mask) {
int invMaskAlpha = 255 - maskAlpha;
- auto subFrame = _frame->getSubArea(srcRect);
+ auto subFrame = frame->getSubArea(srcRect);
auto subMask = mask->getSubArea(srcRect);
byte * dstPixels = static_cast<byte *>(backbuffer.getBasePtr(dst.x, dst.y));
const byte * srcPixels = static_cast<byte *>(subFrame.getPixels());
@@ -226,7 +246,7 @@ void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst, Graphics
maskPixels += subMask.pitch;
}
} else
- _frame->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
+ frame->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
}
int Animation::width() const {
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 7d5e3212b36..1a3e49da8af 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -40,6 +40,7 @@ class Animation {
Common::String _name;
Video::FlicDecoder *_flic;
Graphics::TransparentSurface *_frame;
+ Graphics::TransparentSurface *_scaledFrame;
int _frames;
Common::Point _position;
Common::String _process;
@@ -142,9 +143,7 @@ public:
return _z;
}
- void scale(float scale) {
- _scale = scale;
- }
+ void scale(float scale);
float scale() const {
return _scale;
}
@@ -164,7 +163,9 @@ public:
void decodeNextFrame();
private:
+ void rescaleCurrentFrame();
void freeFrame();
+ void freeScaledFrame();
};
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 390b616cb9c..d50a954db73 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -141,8 +141,8 @@ void Character::direction(int dir) {
if (dir < 0)
return;
- //_animationPos = Common::Point();
- //animate(dir, 100, false);
+ _animationPos = Common::Point();
+ animate(dir, 100, false);
}
void Character::moveTo(const Common::String & processName, Common::Point dst, int dir) {
Commit: 75c98d3311b34ef6211e00c6fdb5268c3c80e79c
https://github.com/scummvm/scummvm/commit/75c98d3311b34ef6211e00c6fdb5268c3c80e79c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:58+01:00
Commit Message:
AGDS: scan for visible height, properly calculate character base
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/character.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 118645629d7..708b26078d7 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -34,7 +34,7 @@ Animation::Animation(AGDSEngine *engine, const Common::String &name) :
_engine(engine), _name(name), _flic(), _frame(), _scaledFrame(),
_frames(0), _loop(false), _cycles(1), _phaseVarControlled(false),
_phase(0), _paused(false), _speed(100), _z(0),
- _delay(0), _random(0), _scale(1), _onScreen(true) {
+ _delay(0), _random(0), _scale(1), _onScreen(true), _visibleHeight(0) {
}
Animation::~Animation() {
@@ -115,11 +115,26 @@ void Animation::scale(float scale) {
}
void Animation::rescaleCurrentFrame() {
- if (_scale == 1 || !_frame)
- return;
-
- freeScaledFrame();
- _scaledFrame = _frame->scale(_frame->w * _scale, _frame->h * _scale, true);
+ if (_scale != 1 && _frame) {
+ freeScaledFrame();
+ _scaledFrame = _frame->scale(_frame->w * _scale, _frame->h * _scale, true);
+ }
+ auto *frame = _scaledFrame? _scaledFrame: _frame;
+ if (frame) {
+ uint h = frame->h, w = frame->w;
+ for(uint i = 0; i != h; ++i) {
+ uint y = h - 1 - i;
+ auto * ptr = static_cast<uint32*>(frame->getBasePtr(0, y));
+ for(uint x = 0; x != w; ++x) {
+ uint8 a, r, g, b;
+ frame->format.colorToARGB(*ptr++, a, r, g, b);
+ if (a != 0) {
+ _visibleHeight = h - i;
+ return;
+ }
+ }
+ }
+ }
}
void Animation::decodeNextFrame() {
@@ -249,11 +264,14 @@ void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst, Graphics
frame->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
}
-int Animation::width() const {
+uint Animation::width() const {
return _flic ? _flic->getWidth() * _scale: 0;
}
-int Animation::height() const {
+uint Animation::height() const {
return _flic ? _flic->getHeight() * _scale: 0;
}
+uint Animation::visibleHeight() const {
+ return _visibleHeight;
+}
} // namespace AGDS
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 1a3e49da8af..5f7c637bbdd 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -56,6 +56,7 @@ class Animation {
int _random;
float _scale;
bool _onScreen;
+ uint _visibleHeight;
public:
Animation(AGDSEngine *engine, const Common::String &name);
@@ -156,8 +157,9 @@ public:
bool load(Common::SeekableReadStream *stream, const Common::String &fname);
void paint(Graphics::Surface & backbuffer, Common::Point dst, Graphics::TransparentSurface *mask = nullptr, int maskAlpha = 0) const;
- int width() const;
- int height() const;
+ uint width() const;
+ uint height() const;
+ uint visibleHeight() const;
bool tick();
void decodeNextFrame();
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index d50a954db73..1185619b893 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -220,7 +220,7 @@ void Character::paint(Graphics::Surface &backbuffer, Common::Point pos) const {
pos += _pos + _animationPos;
- pos.y -= _animation->height();
+ pos.y -= _animation->visibleHeight();
pos.x -= _animation->width() / 2;
int fogAlpha = 0;
Commit: 82601a2d78d898210c8218fb18506d282e625d35
https://github.com/scummvm/scummvm/commit/82601a2d78d898210c8218fb18506d282e625d35
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:59+01:00
Commit Message:
AGDS: move character only when any other handler failed
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 05a361a715e..1faca2b75db 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -571,12 +571,6 @@ Common::Error AGDSEngine::run() {
break;
}
- if (_currentCharacter && _currentCharacter->active()) {
- // FIXME: some object requires character to be in "trap" region
- // Remove this after movement implementation.
- _currentCharacter->moveTo(Common::String(), _mouse, -1);
- }
-
auto objects = _currentScreen->find(_mouse);
if (objects.empty() && !_currentInventoryObject) { //allow inventory to be selected
auto object = _inventory.find(_mouse);
@@ -621,6 +615,11 @@ Common::Error AGDSEngine::run() {
break;
} else {
debug("no handler found");
+ if (_currentCharacter && _currentCharacter->active()) {
+ // FIXME: some object requires character to be in "trap" region
+ // Remove this after movement implementation.
+ _currentCharacter->moveTo(Common::String(), _mouse, -1);
+ }
auto scroll = _currentScreen->scrollPosition();
scroll.x += _mouse.x - g_system->getWidth() / 2;
_currentScreen->scrollTo(scroll);
Commit: 728d817609d83431f93f5df7d73243b55fb2bc16
https://github.com/scummvm/scummvm/commit/728d817609d83431f93f5df7d73243b55fb2bc16
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:59+01:00
Commit Message:
AGDS: add background object logic
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 5ea078dee98..f5ad5974020 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -90,7 +90,7 @@ enum Opcode {
kLoadPictureFromObject = 69,
kLoadAnimationFromObject = 70,
kSetObjectZ = 71,
- kUpdateObjectZToDisplay = 72,
+ kSetScreenBackground = 72,
kLoadTextFromObject = 73,
kScreenSetZNearFar = 74,
kScreenLoadRegion = 75,
@@ -353,7 +353,7 @@ enum Opcode {
OP(kLoadCharacter, loadCharacter) \
OP(kAssociateCharacter, associateCharacter) \
OP(kSetObjectZ, setObjectZ) \
- OP(kUpdateObjectZToDisplay, updateObjectZToDisplay) \
+ OP(kSetScreenBackground, setScreenBackground) \
OP(kLoadTextFromObject, loadTextFromObject) \
OP(kCompareScreenName, compareScreenName) \
OP(kScreenSetZNearFar, screenSetZNearFar) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 2020a06c53f..920ab90bfff 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1380,8 +1380,8 @@ void Process::setObjectZ() {
_engine->getCurrentScreen()->update(_object);
}
-void Process::updateObjectZToDisplay() {
- debug("updateObjectZtoDisplayHeight");
+void Process::setScreenBackground() {
+ debug("setScreenBackground");
_object->z(g_system->getHeight());
_engine->getCurrentScreen()->update(_object);
}
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 87b1c3b7d74..90c11f59943 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -40,7 +40,8 @@ int Screen::AnimationZCompare(const Animation *a, const Animation *b) {
}
Screen::Screen(AGDSEngine * engine, ObjectPtr object, ScreenLoadingType loadingType, const Common::String &prevScreen) :
- _engine(engine), _object(object), _name(object->getName()), _loadingType(loadingType), _previousScreen(prevScreen),
+ _engine(engine), _object(object), _background(nullptr),
+ _name(object->getName()), _loadingType(loadingType), _previousScreen(prevScreen),
_children(&ObjectZCompare), _animations(&AnimationZCompare), _applyingPatch(false),
_characterNear(g_system->getHeight()), _characterFar(g_system->getHeight()) {
add(object);
@@ -54,20 +55,12 @@ void Screen::scrollTo(Common::Point scroll) {
int windowW = g_system->getWidth();
int windowH = g_system->getHeight();
- ObjectPtr background;
- for(uint i = 0, n = _children.size(); i < n; ++i) {
- auto & child = _children.data()[i];
- if (child->getPicture()) {
- background = child;
- break;
- }
- }
- if (!background) {
+ if (!_background) {
_scroll.x = _scroll.y = 0;
return;
}
- auto rect = background->getRect();
+ auto rect = _background->getRect();
int w = rect.width(), h = rect.height();
debug("picture size %dx%d", w, h);
if (scroll.x + windowW > w)
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 99399d414da..bbc7526db80 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -54,6 +54,7 @@ class Screen {
AGDSEngine * _engine;
ObjectPtr _object;
+ Object * _background;
Common::Point _scroll;
Common::String _name;
ScreenLoadingType _loadingType;
@@ -133,6 +134,10 @@ public:
add(object);
}
+ void setBackground(Object * object) {
+ _background = object;
+ }
+
bool remove(const Common::String & name);
bool remove(const ObjectPtr & object);
Commit: 118af99fbdfd3604ac107164470fee1104ce536d
https://github.com/scummvm/scummvm/commit/118af99fbdfd3604ac107164470fee1104ce536d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:59+01:00
Commit Message:
AGDS: use background object to calculate bottom margin for z/scale
Changed paths:
engines/agds/screen.cpp
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 90c11f59943..60e9fdc4c50 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -28,6 +28,7 @@
#include "agds/patch.h"
#include "agds/region.h"
#include "common/system.h"
+#include "graphics/transparent_surface.h"
namespace AGDS {
@@ -79,7 +80,14 @@ void Screen::scrollTo(Common::Point scroll) {
float Screen::getZScale(int y) const
{
- int dy = g_system->getHeight() - y;
+ int h = g_system->getHeight();
+ if (_background) {
+ auto rect = _background->getRect();
+ if (rect.bottom < h)
+ h = rect.bottom;
+ }
+
+ int dy = h - y;
if (dy > _characterNear) {
if (dy < _characterFar)
return 1.0f * (_characterFar - dy) / (_characterFar - _characterNear);
Commit: 827cb7d39b831d3d827bb2ec8a4474fcdfa673ca
https://github.com/scummvm/scummvm/commit/827cb7d39b831d3d827bb2ec8a4474fcdfa673ca
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:59+01:00
Commit Message:
AGDS: return const ref to region
Changed paths:
engines/agds/object.h
diff --git a/engines/agds/object.h b/engines/agds/object.h
index cfac34e2bd4..9e4f937e254 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -179,7 +179,7 @@ public:
void region(RegionPtr region);
- RegionPtr region() const {
+ const RegionPtr& region() const {
return _region;
}
Commit: 0720b1845f7f8c5bf346c6e744a4a9757c6a4080
https://github.com/scummvm/scummvm/commit/0720b1845f7f8c5bf346c6e744a4a9757c6a4080
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:59+01:00
Commit Message:
AGDS: implement set character direction opcode
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 920ab90bfff..6c3c876f620 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1580,7 +1580,12 @@ void Process::setCharacter() {
void Process::setCharacterDirection() {
int dir = pop();
Common::String name = popString();
- debug("setCharacterDirection stub %s %d", name.c_str(), dir);
+ debug("setCharacterDirection %s %d", name.c_str(), dir);
+ auto character = _engine->getCharacter(name);
+ if (character) {
+ character->direction(dir);
+ } else
+ warning("no character %s", name.c_str());
}
void Process::pointCharacter() {
Commit: 94a93008ebb57b95dbf1e498963c29d434b3e630
https://github.com/scummvm/scummvm/commit/94a93008ebb57b95dbf1e498963c29d434b3e630
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:59+01:00
Commit Message:
AGDS: return constant ref from region()
Changed paths:
engines/agds/screen.h
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index bbc7526db80..ed2e28c0d25 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -104,7 +104,7 @@ public:
return _loadingType;
}
- RegionPtr region() const {
+ const RegionPtr & region() const {
return _region;
}
Commit: f346ce594718e5381d376c6ae0de8c3cbd5b0b5f
https://github.com/scummvm/scummvm/commit/f346ce594718e5381d376c6ae0de8c3cbd5b0b5f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:59+01:00
Commit Message:
AGDS: reset character visibility on each loadScreen
Changed paths:
engines/agds/agds.cpp
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 1faca2b75db..cf8b246850c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -336,13 +336,8 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
bool doPatch = patch && loadingType != ScreenLoadingType::SaveOrLoad;
bool hasScreenPatch = doPatch && patch->screenSaved;
- if (_currentScreen) {
- if (_currentCharacter) {
- _currentCharacter->reset();
- if (loadingType != ScreenLoadingType::Normal) {
- _currentCharacter->visible(false);
- }
- }
+ if (_currentCharacter) {
+ _currentCharacter->reset();
}
_currentScreenName = name;
@@ -615,10 +610,13 @@ Common::Error AGDSEngine::run() {
break;
} else {
debug("no handler found");
- if (_currentCharacter && _currentCharacter->active()) {
- // FIXME: some object requires character to be in "trap" region
- // Remove this after movement implementation.
- _currentCharacter->moveTo(Common::String(), _mouse, -1);
+ if (_currentCharacter && _currentCharacter->active() && _currentScreen && _currentScreen->region()) {
+ auto & region = _currentScreen->region();
+ if (region->pointIn(_mouse)) {
+ // FIXME: some object requires character to be in "trap" region
+ // Remove this after movement implementation.
+ _currentCharacter->moveTo(Common::String(), _mouse, -1);
+ }
}
auto scroll = _currentScreen->scrollPosition();
scroll.x += _mouse.x - g_system->getWidth() / 2;
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 1185619b893..71c3f08c1ae 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -40,7 +40,7 @@ namespace AGDS {
Character::Character(AGDSEngine * engine, const Common::String & name):
_engine(engine), _name(name), _object(), _animation(nullptr), _jokes(false),
- _enabled(true), _visible(true), _stopped(false),
+ _enabled(true), _visible(false), _stopped(false),
_phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
}
@@ -113,6 +113,9 @@ void Character::associate(const Common::String &name) {
_engine->runObject(_object);
}
+void Character::visible(bool visible) {
+ _visible = visible;
+}
void Character::loadState(Common::ReadStream* stream) {
int x = stream->readUint16LE();
@@ -149,6 +152,7 @@ void Character::moveTo(const Common::String & processName, Common::Point dst, in
debug("character move %d,%d %d", dst.x, dst.y, dir);
_processName = processName;
_pos = dst;
+ _visible = true;
direction(dir);
}
@@ -156,6 +160,7 @@ void Character::animate(int direction, int speed, bool jokes) {
if (direction == -1)
return;
+ _visible = true;
_stopped = false;
auto character = jokes? _engine->jokes(): this;
_description = character->animationDescription(direction);
@@ -244,6 +249,7 @@ int Character::z() const {
void Character::reset() {
_fog.reset();
+ _visible = false;
}
void Character::setFog(Graphics::TransparentSurface * surface, int minZ, int maxZ) {
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 81bc8db44a9..4df516b0764 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -98,10 +98,7 @@ public:
_enabled = enabled;
}
- void visible(bool visible) {
- _visible = visible;
- }
-
+ void visible(bool visible);
bool visible() const {
return _visible;
}
Commit: f262642784c2c11d612e2b221d42761c51d4bb9f
https://github.com/scummvm/scummvm/commit/f262642784c2c11d612e2b221d42761c51d4bb9f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:59+01:00
Commit Message:
AGDS: add Inventory::add(String) to skip duplicate adds
Changed paths:
engines/agds/console.cpp
engines/agds/inventory.cpp
engines/agds/inventory.h
engines/agds/process.cpp
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index 41d5a4a9ad8..9434d9a1bd9 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -139,11 +139,9 @@ bool Console::inventoryAdd(int argc, const char **argv) {
debugPrintf("usage: %s inv.object\n", argv[0]);
return true;
}
- auto object = _engine->runObject(argv[1]);
- if (!object) {
- debugPrintf("failed to load %s\n", argv[1]);
- }
- _engine->inventory().add(object);
+ int idx = _engine->inventory().add(argv[1]);
+ debugPrintf("add = %d\n", idx);
+
detach();
return true;
}
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 7ffe4e58227..454c74302ad 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -72,7 +72,23 @@ ObjectPtr Inventory::get(int index) {
return {};
}
+int Inventory::add(const Common::String & name) {
+ int idx = find(name);
+ if (idx >= 0) {
+ warning("Double adding object %s, skipping...", name.c_str());
+ return idx;
+ }
+ return add(_engine->runObject(name));
+}
+
int Inventory::add(const ObjectPtr & object) {
+ for (uint i = 0; i < _entries.size(); ++i) {
+ auto & entry = _entries[i];
+ if (entry.hasObject && entry.object == object) {
+ warning("Double adding object pointer %s, skipping...", object->getName().c_str());
+ return i;
+ }
+ }
object->persistent(false);
for (uint i = 0; i < _entries.size(); ++i) {
auto & entry = _entries[i];
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index 499f91cf115..55cd97611fc 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -77,6 +77,7 @@ public:
void visible(bool visible);
+ int add(const Common::String &name);
int add(const ObjectPtr & object);
bool remove(const Common::String &name);
void removeGaps();
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index c03eea2dcc3..80a8ce76864 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -242,7 +242,7 @@ void Process::run() {
case kExitCodeLoadInventoryObject:
deactivate();
_object->lock();
- _engine->inventory().add(_engine->runObject(getExitArg1()));
+ _engine->inventory().add(getExitArg1());
_object->unlock();
activate();
restart = true;
Commit: ec89f79e35cc3435d945ceb1b05818cba4c8550d
https://github.com/scummvm/scummvm/commit/ec89f79e35cc3435d945ceb1b05818cba4c8550d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:58:59+01:00
Commit Message:
AGDS: fix object finding logic, so we don't have to return array of matches, just the top one
Changed paths:
engines/agds/agds.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index cf8b246850c..b57bee49984 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -566,62 +566,60 @@ Common::Error AGDSEngine::run() {
break;
}
- auto objects = _currentScreen->find(_mouse);
- if (objects.empty() && !_currentInventoryObject) { //allow inventory to be selected
- auto object = _inventory.find(_mouse);
- if (object)
- objects.push_back(object);
+ auto object = _currentScreen->find(_mouse);
+ if (!object && !_currentInventoryObject) { //allow inventory to be selected
+ object = _inventory.find(_mouse);
}
+ if (!object)
+ break;
- for(auto & object : objects) {
- debug("found object %s", object->getName().c_str());
- uint ip = 0;
- if (lclick) {
- if (_currentInventoryObject) {
- ip = object->getUseHandler(_currentInventoryObject->getName());
- if (!ip) {
- ip = _currentInventoryObject->useOnHandler();
- if (ip)
- object = _currentInventoryObject;
- }
- if (ip)
- debug("found use handler for current inventory object %s", _currentInventoryObject->getName().c_str());
- }
+ debug("found object %s", object->getName().c_str());
+ uint ip = 0;
+ if (lclick) {
+ if (_currentInventoryObject) {
+ ip = object->getUseHandler(_currentInventoryObject->getName());
if (!ip) {
- ip = object->getClickHandler();
- if (ip)
- debug("found click handler");
- }
- } else {
- if (_currentInventoryObject) {
- ip = _currentInventoryObject->throwHandler();
+ ip = _currentInventoryObject->useOnHandler();
if (ip)
object = _currentInventoryObject;
- } else {
- ip = object->getExamineHandler();
}
if (ip)
- debug("found examine handler");
+ debug("found use handler for current inventory object %s", _currentInventoryObject->getName().c_str());
}
-
- if (ip) {
- debug("found handler: %s %08x", object->getName().c_str(), ip + 7);
- runProcess(object, ip);
- break;
+ if (!ip) {
+ ip = object->getClickHandler();
+ if (ip)
+ debug("found click handler");
+ }
+ } else {
+ if (_currentInventoryObject) {
+ ip = _currentInventoryObject->throwHandler();
+ if (ip)
+ object = _currentInventoryObject;
} else {
- debug("no handler found");
- if (_currentCharacter && _currentCharacter->active() && _currentScreen && _currentScreen->region()) {
- auto & region = _currentScreen->region();
- if (region->pointIn(_mouse)) {
- // FIXME: some object requires character to be in "trap" region
- // Remove this after movement implementation.
- _currentCharacter->moveTo(Common::String(), _mouse, -1);
- }
+ ip = object->getExamineHandler();
+ }
+ if (ip)
+ debug("found examine handler");
+ }
+
+ if (ip) {
+ debug("found handler: %s %08x", object->getName().c_str(), ip + 7);
+ runProcess(object, ip);
+ break;
+ } else {
+ debug("no handler found");
+ if (_currentCharacter && _currentCharacter->active() && _currentScreen && _currentScreen->region()) {
+ auto & region = _currentScreen->region();
+ if (region->pointIn(_mouse)) {
+ // FIXME: some object requires character to be in "trap" region
+ // Remove this after movement implementation.
+ _currentCharacter->moveTo(Common::String(), _mouse, -1);
}
- auto scroll = _currentScreen->scrollPosition();
- scroll.x += _mouse.x - g_system->getWidth() / 2;
- _currentScreen->scrollTo(scroll);
}
+ auto scroll = _currentScreen->scrollPosition();
+ scroll.x += _mouse.x - g_system->getWidth() / 2;
+ _currentScreen->scrollTo(scroll);
}
}
break;
@@ -640,33 +638,23 @@ Common::Error AGDSEngine::run() {
Animation *mouseCursor = NULL;
if (userEnabled() && _currentScreen) {
- auto objects = _currentScreen->find(_mouse);
- if (objects.empty()) {
- auto object = _inventory.find(_mouse);
- if (object)
- objects.push_back(object);
+ auto object = _currentScreen->find(_mouse);
+ if (!object) {
+ object = _inventory.find(_mouse);
}
-
- Animation *cursor = nullptr;
- for(auto & object : objects) {
- cursor = object->getMouseCursor();
- if (cursor)
- break;
- }
+ Animation *cursor = object? object->getMouseCursor(): nullptr;
if (cursor)
mouseCursor = cursor;
- for(auto & object : objects) {
- if (!object->title().empty()) {
- auto & title = object->title();
- auto font = getFont(getSystemVariable("objtext_font")->getInteger());
- int w = font->getStringWidth(title);
- int x = getSystemVariable("objtext_x")->getInteger() - w / 2;
- int y = getSystemVariable("objtext_y")->getInteger();
- font->drawString(backbuffer, title, x, y, backbuffer->w - x, 0);
- }
+ if (object && !object->title().empty()) {
+ auto & title = object->title();
+ auto font = getFont(getSystemVariable("objtext_font")->getInteger());
+ int w = font->getStringWidth(title);
+ int x = getSystemVariable("objtext_x")->getInteger() - w / 2;
+ int y = getSystemVariable("objtext_y")->getInteger();
+ font->drawString(backbuffer, title, x, y, backbuffer->w - x, 0);
}
}
@@ -1035,8 +1023,8 @@ void AGDSEngine::tickCharacter() {
return;
auto pos = _currentCharacter->position();
- auto objects = _currentScreen->find(pos);
- for(auto & object: objects) {
+ auto object = _currentScreen->find(pos);
+ if (object) {
auto region = object->getTrapRegion();
if (region && region->pointIn(pos)) {
debug("starting trap process");
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 60e9fdc4c50..d10a0dfee89 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -260,17 +260,17 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
}
}
-Common::Array<ObjectPtr> Screen::find(Common::Point pos) const {
- Common::Array<ObjectPtr> objects;
- objects.reserve(_children.size());
+ObjectPtr Screen::find(Common::Point pos) const {
+ ObjectPtr topObject;
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
auto visiblePos = (object->scale() >= 0)? pos + _scroll: pos;
if (object->pointIn(visiblePos) && object->alive()) {
- objects.insert_at(0, object);
+ if (!topObject || topObject->z() > object->z())
+ topObject = object;
}
}
- return objects;
+ return topObject;
}
Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index ed2e28c0d25..81a029fa534 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -143,7 +143,7 @@ public:
void tick();
void paint(Graphics::Surface & backbuffer) const;
- Common::Array<ObjectPtr> find(Common::Point pos) const;
+ ObjectPtr find(Common::Point pos) const;
ObjectPtr find(const Common::String &name);
KeyHandler findKeyHandler(const Common::String &keyName);
Animation * findAnimationByPhaseVar(const Common::String &phaseVar);
Commit: 0d4e7976c778058b697020c0c4148a7909513ca9
https://github.com/scummvm/scummvm/commit/0d4e7976c778058b697020c0c4148a7909513ca9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:00+01:00
Commit Message:
AGDS: implement ignore region opcode
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 24b8920067c..519a55fc502 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -41,7 +41,8 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_clickHandler(0), _examineHandler(0), _userUseHandler(0),
_throwHandler(0), _useOnHandler(0),
_alpha(255), _scale(100), _locked(false), _alive(true),
- _persistent(true), _allowInitialise(true) {
+ _persistent(true), _allowInitialise(true),
+ _ignoreRegion(false) {
uint16 id = stream->readUint16LE();
debug("id: 0x%02x %u", id, id);
@@ -242,7 +243,7 @@ bool Object::pointIn(Common::Point pos) {
return true;
- if (_region && _region->pointIn(pos))
+ if (!_ignoreRegion && _region && _region->pointIn(pos))
return true;
return false;
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 9e4f937e254..2e575a4d541 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -88,6 +88,7 @@ private:
bool _alive;
bool _persistent;
bool _allowInitialise;
+ bool _ignoreRegion;
private:
void freeRotated();
@@ -110,6 +111,13 @@ public:
return _persistent;
}
+ void ignoreRegion(bool ignoreRegion) {
+ _ignoreRegion = ignoreRegion;
+ }
+ bool ignoreRegion() const {
+ return _ignoreRegion;
+ }
+
void readStringTable(unsigned resOffset, uint16 resCount);
const StringEntry & getString(uint16 index) const;
uint getStringTableSize() const
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index f5ad5974020..24cb5cf47ba 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -209,7 +209,7 @@ enum Opcode {
kInventoryFindObjectByName = 189,
kSetObjectScale = 190,
kStub191 = 191,
- kStub192 = 192,
+ kObjectIgnoreRegion = 192,
kRemoveGapsFromInventory = 193,
kSampleAmbient = 194,
kGetObjectPictureWidth = 195,
@@ -415,7 +415,7 @@ enum Opcode {
OP(kSetSampleVolume, setSampleVolume) \
OP(kStub173, stub173) \
OP(kStub174, stub174) \
- OP(kStub192, stub192) \
+ OP(kObjectIgnoreRegion, objectIgnoreRegion) \
OP(kQuit, quit) \
OP(kStartNewGame, startNewGame) \
OP(kDisableInventory, disableInventory) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 6c3c876f620..22576ca42dc 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -913,10 +913,15 @@ void Process::stub174() {
debug("stub174: set mouse relative mode");
}
-void Process::stub192() {
+void Process::objectIgnoreRegion() {
int value = pop();
- Common::String name = popString();
- debug("stub192: %s: set some object flag to %d", name.c_str(), value);
+ Common::String objectName = popString();
+ debug("objectIgnoreRegion: %s %d", objectName.c_str(), value);
+ auto object = _engine->getCurrentScreenObject(objectName);
+ if (object)
+ object->ignoreRegion(value > 0);
+ else
+ warning("objectIgnoreRegion: object %s not found", objectName.c_str());
}
void Process::removeGapsFromInventory() {
Commit: 96def13fb70fcffebe06c7211c74846a9fc24a41
https://github.com/scummvm/scummvm/commit/96def13fb70fcffebe06c7211c74846a9fc24a41
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:00+01:00
Commit Message:
AGDS: fix duplicate process finding logic
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index b57bee49984..e3a80b39ba0 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -246,10 +246,11 @@ void AGDSEngine::runObject(const ObjectPtr &object) {
}
void AGDSEngine::runProcess(const ObjectPtr &object, uint ip) {
+ const auto & objectName = object->getName();
debug("starting process %s:%04x", object->getName().c_str(), ip);
for(uint i = 0; i < _processes.size(); ++i) {
auto &process = _processes[i];
- if (ip != 0 && process && process->entryPoint() == ip) {
+ if (ip != 0 && process && process->getName() == objectName && process->entryPoint() == ip) {
debug("found existing process, skipping...");
return;
}
Commit: c953aa03817b239dbf2cd5d17757008809d33021
https://github.com/scummvm/scummvm/commit/c953aa03817b239dbf2cd5d17757008809d33021
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:00+01:00
Commit Message:
Revert "AGDS: fix object finding logic, so we don't have to return array of matches, just the top one"
This reverts commit 8c56f94e7d61c8fa404d85c64ff940c0d023780b.
Changed paths:
engines/agds/agds.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index e3a80b39ba0..a6993d8519e 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -567,60 +567,62 @@ Common::Error AGDSEngine::run() {
break;
}
- auto object = _currentScreen->find(_mouse);
- if (!object && !_currentInventoryObject) { //allow inventory to be selected
- object = _inventory.find(_mouse);
+ auto objects = _currentScreen->find(_mouse);
+ if (objects.empty() && !_currentInventoryObject) { //allow inventory to be selected
+ auto object = _inventory.find(_mouse);
+ if (object)
+ objects.push_back(object);
}
- if (!object)
- break;
- debug("found object %s", object->getName().c_str());
- uint ip = 0;
- if (lclick) {
- if (_currentInventoryObject) {
- ip = object->getUseHandler(_currentInventoryObject->getName());
+ for(auto & object : objects) {
+ debug("found object %s", object->getName().c_str());
+ uint ip = 0;
+ if (lclick) {
+ if (_currentInventoryObject) {
+ ip = object->getUseHandler(_currentInventoryObject->getName());
+ if (!ip) {
+ ip = _currentInventoryObject->useOnHandler();
+ if (ip)
+ object = _currentInventoryObject;
+ }
+ if (ip)
+ debug("found use handler for current inventory object %s", _currentInventoryObject->getName().c_str());
+ }
if (!ip) {
- ip = _currentInventoryObject->useOnHandler();
+ ip = object->getClickHandler();
+ if (ip)
+ debug("found click handler");
+ }
+ } else {
+ if (_currentInventoryObject) {
+ ip = _currentInventoryObject->throwHandler();
if (ip)
object = _currentInventoryObject;
+ } else {
+ ip = object->getExamineHandler();
}
if (ip)
- debug("found use handler for current inventory object %s", _currentInventoryObject->getName().c_str());
- }
- if (!ip) {
- ip = object->getClickHandler();
- if (ip)
- debug("found click handler");
- }
- } else {
- if (_currentInventoryObject) {
- ip = _currentInventoryObject->throwHandler();
- if (ip)
- object = _currentInventoryObject;
- } else {
- ip = object->getExamineHandler();
+ debug("found examine handler");
}
- if (ip)
- debug("found examine handler");
- }
- if (ip) {
- debug("found handler: %s %08x", object->getName().c_str(), ip + 7);
- runProcess(object, ip);
- break;
- } else {
- debug("no handler found");
- if (_currentCharacter && _currentCharacter->active() && _currentScreen && _currentScreen->region()) {
- auto & region = _currentScreen->region();
- if (region->pointIn(_mouse)) {
- // FIXME: some object requires character to be in "trap" region
- // Remove this after movement implementation.
- _currentCharacter->moveTo(Common::String(), _mouse, -1);
+ if (ip) {
+ debug("found handler: %s %08x", object->getName().c_str(), ip + 7);
+ runProcess(object, ip);
+ break;
+ } else {
+ debug("no handler found");
+ if (_currentCharacter && _currentCharacter->active() && _currentScreen && _currentScreen->region()) {
+ auto & region = _currentScreen->region();
+ if (region->pointIn(_mouse)) {
+ // FIXME: some object requires character to be in "trap" region
+ // Remove this after movement implementation.
+ _currentCharacter->moveTo(Common::String(), _mouse, -1);
+ }
}
+ auto scroll = _currentScreen->scrollPosition();
+ scroll.x += _mouse.x - g_system->getWidth() / 2;
+ _currentScreen->scrollTo(scroll);
}
- auto scroll = _currentScreen->scrollPosition();
- scroll.x += _mouse.x - g_system->getWidth() / 2;
- _currentScreen->scrollTo(scroll);
}
}
break;
@@ -639,23 +641,33 @@ Common::Error AGDSEngine::run() {
Animation *mouseCursor = NULL;
if (userEnabled() && _currentScreen) {
- auto object = _currentScreen->find(_mouse);
- if (!object) {
- object = _inventory.find(_mouse);
+ auto objects = _currentScreen->find(_mouse);
+ if (objects.empty()) {
+ auto object = _inventory.find(_mouse);
+ if (object)
+ objects.push_back(object);
}
- Animation *cursor = object? object->getMouseCursor(): nullptr;
+
+ Animation *cursor = nullptr;
+ for(auto & object : objects) {
+ cursor = object->getMouseCursor();
+ if (cursor)
+ break;
+ }
if (cursor)
mouseCursor = cursor;
- if (object && !object->title().empty()) {
- auto & title = object->title();
- auto font = getFont(getSystemVariable("objtext_font")->getInteger());
- int w = font->getStringWidth(title);
- int x = getSystemVariable("objtext_x")->getInteger() - w / 2;
- int y = getSystemVariable("objtext_y")->getInteger();
- font->drawString(backbuffer, title, x, y, backbuffer->w - x, 0);
+ for(auto & object : objects) {
+ if (!object->title().empty()) {
+ auto & title = object->title();
+ auto font = getFont(getSystemVariable("objtext_font")->getInteger());
+ int w = font->getStringWidth(title);
+ int x = getSystemVariable("objtext_x")->getInteger() - w / 2;
+ int y = getSystemVariable("objtext_y")->getInteger();
+ font->drawString(backbuffer, title, x, y, backbuffer->w - x, 0);
+ }
}
}
@@ -1024,8 +1036,8 @@ void AGDSEngine::tickCharacter() {
return;
auto pos = _currentCharacter->position();
- auto object = _currentScreen->find(pos);
- if (object) {
+ auto objects = _currentScreen->find(pos);
+ for(auto & object: objects) {
auto region = object->getTrapRegion();
if (region && region->pointIn(pos)) {
debug("starting trap process");
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index d10a0dfee89..60e9fdc4c50 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -260,17 +260,17 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
}
}
-ObjectPtr Screen::find(Common::Point pos) const {
- ObjectPtr topObject;
+Common::Array<ObjectPtr> Screen::find(Common::Point pos) const {
+ Common::Array<ObjectPtr> objects;
+ objects.reserve(_children.size());
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
auto visiblePos = (object->scale() >= 0)? pos + _scroll: pos;
if (object->pointIn(visiblePos) && object->alive()) {
- if (!topObject || topObject->z() > object->z())
- topObject = object;
+ objects.insert_at(0, object);
}
}
- return topObject;
+ return objects;
}
Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 81a029fa534..ed2e28c0d25 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -143,7 +143,7 @@ public:
void tick();
void paint(Graphics::Surface & backbuffer) const;
- ObjectPtr find(Common::Point pos) const;
+ Common::Array<ObjectPtr> find(Common::Point pos) const;
ObjectPtr find(const Common::String &name);
KeyHandler findKeyHandler(const Common::String &keyName);
Animation * findAnimationByPhaseVar(const Common::String &phaseVar);
Commit: 0225963bbb52ed6e46e3f754826a2f2348778bff
https://github.com/scummvm/scummvm/commit/0225963bbb52ed6e46e3f754826a2f2348778bff
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:00+01:00
Commit Message:
AGDS: fix background
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 22576ca42dc..8895156a5b1 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1389,6 +1389,7 @@ void Process::setScreenBackground() {
debug("setScreenBackground");
_object->z(g_system->getHeight());
_engine->getCurrentScreen()->update(_object);
+ _engine->getCurrentScreen()->setBackground(_object.get());
}
void Process::loadTextFromObject() {
Commit: 51db21ebf1c35563de204a0a678492ac7580ff91
https://github.com/scummvm/scummvm/commit/51db21ebf1c35563de204a0a678492ac7580ff91
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:00+01:00
Commit Message:
AGDS: read signed direction from save file
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 71c3f08c1ae..eeab899e1d7 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -120,7 +120,7 @@ void Character::visible(bool visible) {
void Character::loadState(Common::ReadStream* stream) {
int x = stream->readUint16LE();
int y = stream->readUint16LE();
- int dir = stream->readUint16LE();
+ int dir = stream->readSint16LE();
debug("character at %d, %d, dir: %d", x, y, dir);
position(Common::Point(x, y));
direction(dir);
Commit: fe84e73be15cfb4cc593d2c068011187602e0042
https://github.com/scummvm/scummvm/commit/fe84e73be15cfb4cc593d2c068011187602e0042
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:00+01:00
Commit Message:
AGDS: do not skip cutscenes in fast mode
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index a6993d8519e..03872727ace 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -750,11 +750,6 @@ Common::Error AGDSEngine::run() {
void AGDSEngine::playFilm(Process &process, const Common::String &video, const Common::String &audio, const Common::String &subtitles) {
delete _mjpgPlayer;
_mjpgPlayer = nullptr;
- if (_fastMode) {
- debug("fast mode, skipping film");
- process.activate();
- return;
- }
_filmProcess = process.getName();
_mjpgPlayer = new MJPGPlayer(_resourceManager.getResource(video), subtitles);
Commit: 72c8270cd152ca257499760aefd3700f972c96e2
https://github.com/scummvm/scummvm/commit/72c8270cd152ca257499760aefd3700f972c96e2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:00+01:00
Commit Message:
AGDS: remove background from z scale code
Changed paths:
engines/agds/screen.cpp
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 60e9fdc4c50..970f1fad97e 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -81,12 +81,6 @@ void Screen::scrollTo(Common::Point scroll) {
float Screen::getZScale(int y) const
{
int h = g_system->getHeight();
- if (_background) {
- auto rect = _background->getRect();
- if (rect.bottom < h)
- h = rect.bottom;
- }
-
int dy = h - y;
if (dy > _characterNear) {
if (dy < _characterFar)
Commit: f84eb9ef3df36d87543332751e384938f094feb3
https://github.com/scummvm/scummvm/commit/f84eb9ef3df36d87543332751e384938f094feb3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:00+01:00
Commit Message:
AGDS: fix horizontal character alignment
Changed paths:
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/character.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 708b26078d7..f51bcca6090 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -34,7 +34,8 @@ Animation::Animation(AGDSEngine *engine, const Common::String &name) :
_engine(engine), _name(name), _flic(), _frame(), _scaledFrame(),
_frames(0), _loop(false), _cycles(1), _phaseVarControlled(false),
_phase(0), _paused(false), _speed(100), _z(0),
- _delay(0), _random(0), _scale(1), _onScreen(true), _visibleHeight(0) {
+ _delay(0), _random(0), _scale(1), _onScreen(true),
+ _visibleHeight(0), _visibleCenter(0) {
}
Animation::~Animation() {
@@ -122,6 +123,8 @@ void Animation::rescaleCurrentFrame() {
auto *frame = _scaledFrame? _scaledFrame: _frame;
if (frame) {
uint h = frame->h, w = frame->w;
+ _visibleHeight = 0;
+ uint minX = w, maxX = 0;
for(uint i = 0; i != h; ++i) {
uint y = h - 1 - i;
auto * ptr = static_cast<uint32*>(frame->getBasePtr(0, y));
@@ -129,11 +132,16 @@ void Animation::rescaleCurrentFrame() {
uint8 a, r, g, b;
frame->format.colorToARGB(*ptr++, a, r, g, b);
if (a != 0) {
- _visibleHeight = h - i;
- return;
+ if (h - i > _visibleHeight)
+ _visibleHeight = h - i;
+ if (x > maxX)
+ maxX = x;
+ else if (x < minX)
+ minX = x;
}
}
}
+ _visibleCenter = minX < maxX? (maxX + minX) / 2: 0;
}
}
@@ -270,8 +278,5 @@ uint Animation::width() const {
uint Animation::height() const {
return _flic ? _flic->getHeight() * _scale: 0;
}
-uint Animation::visibleHeight() const {
- return _visibleHeight;
-}
} // namespace AGDS
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 5f7c637bbdd..a43e0bcae28 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -57,6 +57,7 @@ class Animation {
float _scale;
bool _onScreen;
uint _visibleHeight;
+ uint _visibleCenter;
public:
Animation(AGDSEngine *engine, const Common::String &name);
@@ -159,7 +160,12 @@ public:
void paint(Graphics::Surface & backbuffer, Common::Point dst, Graphics::TransparentSurface *mask = nullptr, int maskAlpha = 0) const;
uint width() const;
uint height() const;
- uint visibleHeight() const;
+ uint visibleHeight() const {
+ return _visibleHeight;
+ }
+ uint visibleCenter() const {
+ return _visibleCenter;
+ }
bool tick();
void decodeNextFrame();
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index eeab899e1d7..cd0d68aa2b7 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -226,7 +226,7 @@ void Character::paint(Graphics::Surface &backbuffer, Common::Point pos) const {
pos += _pos + _animationPos;
pos.y -= _animation->visibleHeight();
- pos.x -= _animation->width() / 2;
+ pos.x -= _animation->visibleCenter();
int fogAlpha = 0;
if (_fog) {
Commit: d92af6f07496f71fffcb1c064d1dfc1c365eb763
https://github.com/scummvm/scummvm/commit/d92af6f07496f71fffcb1c064d1dfc1c365eb763
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:00+01:00
Commit Message:
AGDS: ignore direction animation when jokes animation is active
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index cd0d68aa2b7..a69960f5a17 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -144,6 +144,10 @@ void Character::direction(int dir) {
if (dir < 0)
return;
+ if (_jokes && _phase < _frames) {
+ debug("direction(%d) set during active animation, ignored", dir);
+ return;
+ }
_animationPos = Common::Point();
animate(dir, 100, false);
}
Commit: fa10c451bc9824aa84caeeb966820a201b51497c
https://github.com/scummvm/scummvm/commit/fa10c451bc9824aa84caeeb966820a201b51497c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:00+01:00
Commit Message:
AGDS: animate/restore latest direction
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index a69960f5a17..da1b3c921b9 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -217,6 +217,7 @@ void Character::tick() {
if (_phase >= _frames) {
_phase = -1;
_frames = 0;
+ direction(_direction);
}
_engine->reactivate(_processName, true);
}
Commit: 1fe0a98461f648e2065bee902e5dd5fdd3776f4e
https://github.com/scummvm/scummvm/commit/1fe0a98461f648e2065bee902e5dd5fdd3776f4e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:01+01:00
Commit Message:
AGDS: rename stub233 to objectRemovePictureAndAnimation
Changed paths:
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 24cb5cf47ba..a35cd57eca2 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -250,7 +250,7 @@ enum Opcode {
kStub230 = 230,
kStub231 = 231,
kStub232 = 232,
- kStub233 = 233,
+ kObjectFreePictureAndAnimation = 233,
kGetSampleVolume = 234,
kStub235 = 235,
kUserEnabled = 236,
@@ -469,7 +469,7 @@ enum Opcode {
OP_U(kOnKey, onKey) \
OP(kGetSampleVolume, getSampleVolume) \
OP(kStub231, stub231) \
- OP(kStub233, stub233) \
+ OP(kObjectFreePictureAndAnimation, objectFreePictureAndAnimation) \
OP(kStub235, stub235) \
OP(kUserEnabled, userEnabled) \
OP(kSetCharacterNotifyVars, setCharacterNotifyVars) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 8895156a5b1..804242a2833 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1714,12 +1714,13 @@ void Process::stub231() {
debug("stub231 %d %d", arg1, arg2);
}
-void Process::stub233() {
+void Process::objectFreePictureAndAnimation() {
Common::String name = popString();
- debug("stub233 %s unload picture?", name.c_str());
+ debug("objectFreePictureAndAnimation %s", name.c_str());
ObjectPtr object = _engine->getCurrentScreenObject(name);
if (object) {
- object->setPicture(NULL);
+ object->setAnimation(nullptr);
+ object->setPicture(nullptr);
}
}
Commit: 6b406dcdd9270f4668c5e5dc7e0a7efbbcd6fd24
https://github.com/scummvm/scummvm/commit/6b406dcdd9270f4668c5e5dc7e0a7efbbcd6fd24
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:01+01:00
Commit Message:
AGDS: render inventory object mouse cursor first
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 03872727ace..42f22fd1bdc 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -685,8 +685,13 @@ Common::Error AGDSEngine::run() {
mouseCursor = _defaultMouseCursor;
if (userEnabled()) {
- auto picture = _currentInventoryObject? _currentInventoryObject->getPicture(): nullptr;
- if (picture) {
+ if (auto *cursor = _currentInventoryObject? _currentInventoryObject->getMouseCursor(): nullptr) {
+ cursor->tick();
+ auto pos = _mouse;
+ pos.x -= cursor->visibleCenter();
+ pos.y -= cursor->visibleHeight() / 2;
+ cursor->paint(*backbuffer, pos);
+ } else if (auto *picture = _currentInventoryObject? _currentInventoryObject->getPicture(): nullptr) {
Common::Rect srcRect = picture->getRect();
Common::Point dst = _mouse;
dst.x -= srcRect.width() / 2;
Commit: d6bcd5f78adc176910148aba400da6408eb8fbe0
https://github.com/scummvm/scummvm/commit/d6bcd5f78adc176910148aba400da6408eb8fbe0
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:01+01:00
Commit Message:
AGDS: back off mouse cursor change
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 42f22fd1bdc..937051d3e26 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -685,13 +685,18 @@ Common::Error AGDSEngine::run() {
mouseCursor = _defaultMouseCursor;
if (userEnabled()) {
+#if 0
+ //FIXME: fixes planet puzzle but breaks all other objects.
+ // maybe use this only when used in conjunction with attachInventoryObjectToMouse?
if (auto *cursor = _currentInventoryObject? _currentInventoryObject->getMouseCursor(): nullptr) {
cursor->tick();
auto pos = _mouse;
pos.x -= cursor->visibleCenter();
pos.y -= cursor->visibleHeight() / 2;
cursor->paint(*backbuffer, pos);
- } else if (auto *picture = _currentInventoryObject? _currentInventoryObject->getPicture(): nullptr) {
+ } else
+#endif
+ if (auto *picture = _currentInventoryObject? _currentInventoryObject->getPicture(): nullptr) {
Common::Rect srcRect = picture->getRect();
Common::Point dst = _mouse;
dst.x -= srcRect.width() / 2;
Commit: 2849af1646cefef8c39caa7218f45155ec80daa4
https://github.com/scummvm/scummvm/commit/2849af1646cefef8c39caa7218f45155ec80daa4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:01+01:00
Commit Message:
AGDS: proper implement screen object protection
Also inventory remove object opcode is now removing object from screen.
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 519a55fc502..8e03032b3cf 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -40,7 +40,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_pos(), _z(10),
_clickHandler(0), _examineHandler(0), _userUseHandler(0),
_throwHandler(0), _useOnHandler(0),
- _alpha(255), _scale(100), _locked(false), _alive(true),
+ _alpha(255), _scale(100), _locked(0), _alive(true),
_persistent(true), _allowInitialise(true),
_ignoreRegion(false) {
uint16 id = stream->readUint16LE();
@@ -67,6 +67,16 @@ Object::~Object() {
}
}
+void Object::lock() {
+ ++_locked;
+}
+
+void Object::unlock() {
+ if (_locked == 0)
+ error("%s: object lock counter underrun", _name.c_str());
+ --_locked;
+}
+
void Object::freeRotated() {
if (_rotatedPicture) {
_rotatedPicture->free();
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 2e575a4d541..3c56fec84df 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -84,7 +84,7 @@ private:
uint _trapHandler;
int _alpha;
int _scale;
- bool _locked;
+ uint _locked;
bool _alive;
bool _persistent;
bool _allowInitialise;
@@ -298,10 +298,10 @@ public:
}
bool locked() const {
- return _locked;
+ return _locked != 0;
}
- void lock() { _locked = true; }
- void unlock() { _locked = false; }
+ void lock();
+ void unlock();
bool alive() const
{ return _alive; }
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 804242a2833..a5241803f8a 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -277,22 +277,11 @@ void Process::removeScreenObject() {
return;
}
- auto object = screen->find(name);
- if (object) {
- if (object->alive()) {
- if (name == _object->getName() || object->locked()) {
- debug("removeScreenObject: %s: removing object from its own body (sic)", name.c_str());
- object->alive(false);
- } else if (screen && screen->remove(name)) {
- int index = _engine->inventory().find(name);
- if (index < 0)
- _engine->stopProcess(name);
- } else
- warning("removeScreenObject: object %s not found", name.c_str());
- } else
- warning("removeScreenObject: object %s already removed", name.c_str());
- } else
- warning("cannot find object %s", name.c_str());
+ _object->lock();
+ if (!screen->remove(name)) {
+ warning("removeScreenObject: object %s not found", name.c_str());
+ }
+ _object->unlock();
}
void Process::loadFont() {
@@ -791,8 +780,10 @@ void Process::screenObjectPatchDecRef() {
} else {
Screen *screen = _engine->getCurrentScreen();
if (screen) {
+ _object->lock();
if (!screen->remove(objectName))
warning("screenRemoveObjectSavePatch: object %s not found", objectName.c_str());
+ _object->unlock();
}
}
}
@@ -1304,7 +1295,10 @@ void Process::inventoryAddObject() {
void Process::inventoryRemoveObject() {
Common::String name = popString();
debug("inventoryRemoveObject %s", name.c_str());
+ _object->lock();
_engine->inventory().remove(name);
+ _engine->getCurrentScreen()->remove(name);
+ _object->unlock();
}
void Process::inventoryFindObjectByName() {
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 970f1fad97e..44bef1128ad 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -147,7 +147,10 @@ ObjectPtr Screen::find(const Common::String &name) {
bool Screen::remove(const ObjectPtr &object) {
for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
if (*i == object) {
- _children.erase(i);
+ if (object->locked())
+ object->alive(false);
+ else
+ _children.erase(i);
return true;
}
}
@@ -158,7 +161,10 @@ bool Screen::remove(const Common::String &name) {
for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
const ObjectPtr & object = *i;
if (object->getName() == name) {
- _children.erase(i);
+ if (object->locked())
+ object->alive(false);
+ else
+ _children.erase(i);
return true;
}
}
Commit: 908853a043dd1c05d69daa302cf2dde536a93e13
https://github.com/scummvm/scummvm/commit/908853a043dd1c05d69daa302cf2dde536a93e13
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:01+01:00
Commit Message:
AGDS: reimplelementing current object infrastructure
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 937051d3e26..1af44902181 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -323,7 +323,7 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
debug("loadScreen %s [type: %d, save patch: %d, previous: %s]", name.c_str(), static_cast<int>(loadingType), savePatch, _currentScreenName.c_str());
if (savePatch)
saveScreenPatch();
- returnCurrentInventoryObject();
+ resetCurrentInventoryObject();
_inventory.visible(false);
_mouseMap.hideAll(this);
@@ -561,68 +561,81 @@ Common::Error AGDSEngine::run() {
_mouse = event.mouse;
if (userEnabled()) {
bool lclick = event.type == Common::EVENT_LBUTTONDOWN;
- debug("%s %d, %d", lclick ? "lclick" : "rclick", _mouse.x, _mouse.y);
- if (!lclick && _currentInventoryObject && !_currentInventoryObject->useOnHandler()) {
- returnCurrentInventoryObject();
- break;
- }
+ debug("%s %d, %d inv: %s", lclick ? "lclick" : "rclick", _mouse.x, _mouse.y,
+ _currentInventoryObject? _currentInventoryObject->getName().c_str(): "none");
- auto objects = _currentScreen->find(_mouse);
- if (objects.empty() && !_currentInventoryObject) { //allow inventory to be selected
- auto object = _inventory.find(_mouse);
- if (object)
- objects.push_back(object);
+ ObjectPtr runObject;
+ uint ip = 0;
+ if (_currentInventoryObject) {
+ if (lclick) {
+ ip = _currentInventoryObject->useOnHandler();
+ if (ip) {
+ debug("found useOn handler in current inventory object");
+ runObject = _currentInventoryObject;
+ }
+ } else {
+ ip = _currentInventoryObject->throwHandler();
+ if (ip) {
+ debug("found handler in current inventory object");
+ runObject = _currentInventoryObject;
+ }
+ }
}
+ if (!runObject) {
+ auto objects = _currentScreen->find(_mouse);
+ if (objects.empty() && !_currentInventoryObject) { //allow inventory to be selected
+ auto object = _inventory.find(_mouse);
+ if (object)
+ objects.push_back(object);
+ }
- for(auto & object : objects) {
- debug("found object %s", object->getName().c_str());
- uint ip = 0;
- if (lclick) {
- if (_currentInventoryObject) {
- ip = object->getUseHandler(_currentInventoryObject->getName());
- if (!ip) {
- ip = _currentInventoryObject->useOnHandler();
+ for(auto & object : objects) {
+ debug("found object %s", object->getName().c_str());
+ if (lclick) {
+ if (_currentInventoryObject) {
+ ip = object->getUseHandler(_currentInventoryObject->getName());
+ if (ip) {
+ runObject = object;
+ }
if (ip)
- object = _currentInventoryObject;
+ debug("found use handler");
+ }
+ if (!ip) {
+ ip = object->getClickHandler();
+ if (ip) {
+ debug("found click handler");
+ runObject = object;
+ }
}
- if (ip)
- debug("found use handler for current inventory object %s", _currentInventoryObject->getName().c_str());
- }
- if (!ip) {
- ip = object->getClickHandler();
- if (ip)
- debug("found click handler");
- }
- } else {
- if (_currentInventoryObject) {
- ip = _currentInventoryObject->throwHandler();
- if (ip)
- object = _currentInventoryObject;
} else {
ip = object->getExamineHandler();
+ if (ip) {
+ debug("found examine handler");
+ runObject = object;
+ }
}
- if (ip)
- debug("found examine handler");
- }
+ }
+ }
+ if (runObject) {
if (ip) {
- debug("found handler: %s %08x", object->getName().c_str(), ip + 7);
- runProcess(object, ip);
+ debug("found handler: %s %04x", runObject->getName().c_str(), ip);
+ runProcess(runObject, ip);
break;
- } else {
- debug("no handler found");
- if (_currentCharacter && _currentCharacter->active() && _currentScreen && _currentScreen->region()) {
- auto & region = _currentScreen->region();
- if (region->pointIn(_mouse)) {
- // FIXME: some object requires character to be in "trap" region
- // Remove this after movement implementation.
- _currentCharacter->moveTo(Common::String(), _mouse, -1);
- }
+ }
+ } else {
+ debug("no handler found");
+ if (_currentCharacter && _currentCharacter->active() && _currentScreen && _currentScreen->region()) {
+ auto & region = _currentScreen->region();
+ if (region->pointIn(_mouse)) {
+ // FIXME: some object requires character to be in "trap" region
+ // Remove this after movement implementation.
+ _currentCharacter->moveTo(Common::String(), _mouse, -1);
}
- auto scroll = _currentScreen->scrollPosition();
- scroll.x += _mouse.x - g_system->getWidth() / 2;
- _currentScreen->scrollTo(scroll);
}
+ auto scroll = _currentScreen->scrollPosition();
+ scroll.x += _mouse.x - g_system->getWidth() / 2;
+ _currentScreen->scrollTo(scroll);
}
}
break;
@@ -1345,20 +1358,17 @@ void AGDSEngine::stopProcess(const Common::String & name) {
}
void AGDSEngine::currentInventoryObject(const ObjectPtr & object) {
+ resetCurrentInventoryObject();
_currentInventoryObject = object;
}
void AGDSEngine::resetCurrentInventoryObject() {
- _currentInventoryObject.reset();
-}
-
-void AGDSEngine::returnCurrentInventoryObject() {
auto object = _currentInventoryObject;
if (!object)
return;
+ debug("returnCurrentInventoryObject %s", object->getName().c_str());
_currentInventoryObject.reset();
-
_inventory.add(object);
runObject(object);
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index aefb1eb62be..f0b8c018b00 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -261,8 +261,6 @@ public:
void currentInventoryObject(const ObjectPtr & object);
void resetCurrentInventoryObject();
- void returnCurrentInventoryObject();
-
const ObjectPtr & currentInventoryObject() const {
return _currentInventoryObject;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index a5241803f8a..69e365f79d2 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -564,8 +564,21 @@ void Process::attachInventoryObjectToMouse(bool flag) {
}
void Process::returnCurrentInventoryObject() {
- debug("returnCurrentInventoryObject");
- _engine->returnCurrentInventoryObject();
+ auto object = _engine->currentInventoryObject();
+ if (!object) {
+ warning("no current inventory object");
+ return;
+ }
+
+ auto name = object->getName();
+ debug("returnCurrentInventoryObject %s", name.c_str());
+ auto screen = _engine->getCurrentScreen();
+ if (screen) {
+ _object->lock();
+ screen->remove(object);
+ _object->unlock();
+ }
+ suspend(kExitCodeLoadInventoryObject, name);
}
void Process::attachInventoryObjectToMouse0() {
@@ -1195,10 +1208,6 @@ void Process::tell(bool npc, const Common::String &sound) {
Common::String region = popString();
debug("%s '%s' '%s' '%s'", npc? "npcSay": "playerSay", region.c_str(), text.c_str(), sound.c_str());
_engine->tell(*this, region, text, sound, npc);
-
- //close inventory here if close flag was set
- Common::String inventoryClose = _engine->getSystemVariable("inv_close")->getString();
- suspend(!inventoryClose.empty()? kExitCodeCloseInventory: kExitCodeSuspend);
}
void Process::npcSay() {
Commit: 34653187dcdf5071215a9c1ed9578f8fa19b08a5
https://github.com/scummvm/scummvm/commit/34653187dcdf5071215a9c1ed9578f8fa19b08a5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:01+01:00
Commit Message:
AGDS: remove various inventory visibility hacks
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/inventory.cpp
engines/agds/inventory.h
engines/agds/process_opcodes.cpp
engines/agds/textLayout.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 1af44902181..3206f5f1697 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -553,7 +553,15 @@ Common::Error AGDSEngine::run() {
region->show(this);
}
}
- _inventory.visible(_inventoryRegion ? !_mouseMap.disabled() && _inventoryRegion->pointIn(_mouse) : false);
+ if (_inventoryRegion && _inventory.enabled()) {
+ if (_mouseMap.disabled()) {
+ _inventory.visible(false);
+ } else {
+ if (_userEnabled) {
+ _inventory.visible(_inventoryRegion->pointIn(_mouse));
+ }
+ }
+ }
}
break;
case Common::EVENT_LBUTTONDOWN:
@@ -576,7 +584,7 @@ Common::Error AGDSEngine::run() {
} else {
ip = _currentInventoryObject->throwHandler();
if (ip) {
- debug("found handler in current inventory object");
+ debug("found throw handler in current inventory object");
runObject = _currentInventoryObject;
}
}
@@ -947,8 +955,9 @@ void AGDSEngine::addSystemVar(const Common::String &name, SystemVariable *var) {
}
void AGDSEngine::tell(Process &process, const Common::String ®ionName, Common::String text, Common::String sound, bool npc) {
- if (getSystemVariable("tell_close_inv")->getInteger())
- _inventory.visible(false);
+ if (getSystemVariable("tell_close_inv")->getInteger()) {
+ _inventory.enable(false);
+ }
int font_id = getSystemVariable(npc? "npc_tell_font": "tell_font")->getInteger();
Common::Point pos;
@@ -1362,13 +1371,17 @@ void AGDSEngine::currentInventoryObject(const ObjectPtr & object) {
_currentInventoryObject = object;
}
-void AGDSEngine::resetCurrentInventoryObject() {
+ObjectPtr AGDSEngine::popCurrentInventoryObject() {
auto object = _currentInventoryObject;
+ _currentInventoryObject.reset();
+ return object;
+}
+
+void AGDSEngine::resetCurrentInventoryObject() {
+ auto object = popCurrentInventoryObject();
if (!object)
return;
-
debug("returnCurrentInventoryObject %s", object->getName().c_str());
- _currentInventoryObject.reset();
_inventory.add(object);
runObject(object);
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index f0b8c018b00..e49443ee2f1 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -261,6 +261,7 @@ public:
void currentInventoryObject(const ObjectPtr & object);
void resetCurrentInventoryObject();
+ ObjectPtr popCurrentInventoryObject();
const ObjectPtr & currentInventoryObject() const {
return _currentInventoryObject;
}
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 454c74302ad..a61d8f15dba 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -40,12 +40,12 @@ void Inventory::visible(bool visible) {
_visible = visible;
- if (!_enabled || !visible) {
+ if (!visible) {
debug("closing inventory...");
Common::String inv_close = _engine->getSystemVariable("inv_close")->getString();
if (!inv_close.empty())
_engine->runObject(inv_close);
- } else if (enabled() && visible) {
+ } else {
debug("opening inventory...");
removeGaps();
Common::String inv_open = _engine->getSystemVariable("inv_open")->getString();
@@ -142,6 +142,9 @@ int Inventory::find(const Common::String &name) const {
}
ObjectPtr Inventory::find(const Common::Point pos) const {
+ if (!_enabled)
+ return {};
+
for (uint i = 0; i < _entries.size(); ++i) {
auto & entry = _entries[i];
if (!entry.object)
@@ -156,7 +159,7 @@ ObjectPtr Inventory::find(const Common::Point pos) const {
return object;
}
}
- return ObjectPtr();
+ return {};
}
void Inventory::clear() {
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index 55cd97611fc..bd324385c7b 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -66,8 +66,6 @@ public:
return _enabled;
}
void enable(bool enabled) {
- if (!enabled)
- visible(false);
_enabled = enabled;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 69e365f79d2..b0d77faa839 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -564,7 +564,7 @@ void Process::attachInventoryObjectToMouse(bool flag) {
}
void Process::returnCurrentInventoryObject() {
- auto object = _engine->currentInventoryObject();
+ auto object = _engine->popCurrentInventoryObject();
if (!object) {
warning("no current inventory object");
return;
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 6d0dda00d2b..63796401c24 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -4,6 +4,7 @@
#include "agds/character.h"
#include "agds/object.h"
#include "agds/process.h"
+#include "agds/systemVariable.h"
#include "common/debug.h"
namespace AGDS {
@@ -29,7 +30,9 @@ void TextLayout::reset(AGDSEngine &engine) {
engine.setGlobal(var, 0);
}
engine.reactivate(_process);
- engine.inventory().enable(true);
+ if (engine.getSystemVariable("tell_close_inv")->getInteger()) {
+ engine.inventory().enable(true);
+ }
}
}
Commit: bec9c565b891921ea53bed583cb448ec2baa3f95
https://github.com/scummvm/scummvm/commit/bec9c565b891921ea53bed583cb448ec2baa3f95
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:01+01:00
Commit Message:
AGDS: some objects have return to inventory code into their use-on(object) handlers - call it
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 3206f5f1697..70b43cfb208 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -582,10 +582,16 @@ Common::Error AGDSEngine::run() {
runObject = _currentInventoryObject;
}
} else {
- ip = _currentInventoryObject->throwHandler();
+ ip = _currentInventoryObject->getUseHandler(_currentInventoryObject->getName());
if (ip) {
- debug("found throw handler in current inventory object");
+ debug("found self use handler");
runObject = _currentInventoryObject;
+ } else {
+ ip = _currentInventoryObject->throwHandler();
+ if (ip) {
+ debug("found throw handler in current inventory object");
+ runObject = _currentInventoryObject;
+ }
}
}
}
Commit: b4c7b8bb87233668fef7e30e996814d512b0f517
https://github.com/scummvm/scummvm/commit/b4c7b8bb87233668fef7e30e996814d512b0f517
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:01+01:00
Commit Message:
AGDS: remove gaps only if no selected object present
Changed paths:
engines/agds/inventory.cpp
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index a61d8f15dba..40c3a5bd31a 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -47,7 +47,8 @@ void Inventory::visible(bool visible) {
_engine->runObject(inv_close);
} else {
debug("opening inventory...");
- removeGaps();
+ if (!_engine->currentInventoryObject())
+ removeGaps();
Common::String inv_open = _engine->getSystemVariable("inv_open")->getString();
if (!inv_open.empty())
_engine->runObject(inv_open);
Commit: 261a064c81a857a386a30647bd6b3f35a7cc151a
https://github.com/scummvm/scummvm/commit/261a064c81a857a386a30647bd6b3f35a7cc151a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:01+01:00
Commit Message:
AGDS: fix log line for use handler
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b0d77faa839..6b40a64aeb1 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -602,7 +602,7 @@ void Process::fadeObject() {
void Process::onObjectUse(uint16 size) {
Common::String arg = popString();
- debug("register use object handler %s -> 0x%04x", arg.c_str(), _ip);
+ debug("use [handler] on %s -> 0x%04x", arg.c_str(), _ip);
_object->setUseHandler(arg, _ip);
_ip += size;
}
Commit: 30b47232564df59ff75b384c8d6e7aa7288723ae
https://github.com/scummvm/scummvm/commit/30b47232564df59ff75b384c8d6e7aa7288723ae
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:01+01:00
Commit Message:
AGDS: do not call simple handlers in a current object presense
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 70b43cfb208..5cfbd544a58 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -614,21 +614,22 @@ Common::Error AGDSEngine::run() {
if (ip)
debug("found use handler");
}
- if (!ip) {
+ if (!ip && !_currentInventoryObject) {
ip = object->getClickHandler();
if (ip) {
debug("found click handler");
runObject = object;
}
}
- } else {
+ } else if (!_currentInventoryObject) {
ip = object->getExamineHandler();
if (ip) {
debug("found examine handler");
runObject = object;
}
}
-
+ if (runObject)
+ break;
}
}
if (runObject) {
Commit: 857196f9b7127a407dbc07c63cd4bb7505b08dcb
https://github.com/scummvm/scummvm/commit/857196f9b7127a407dbc07c63cd4bb7505b08dcb
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:02+01:00
Commit Message:
AGDS: silently add object to inventory after removal
Convert add(name) to be lazy (so there's no objects pop up at 0,0)
Also return to inventory via locking object (so it does not get destroyed) and re-adding object pointer
Changed paths:
engines/agds/inventory.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 40c3a5bd31a..1384b661ff2 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -79,14 +79,23 @@ int Inventory::add(const Common::String & name) {
warning("Double adding object %s, skipping...", name.c_str());
return idx;
}
- return add(_engine->runObject(name));
+ for (uint i = 0; i < _entries.size(); ++i) {
+ auto & entry = _entries[i];
+ if (!entry.hasObject) {
+ entry.name = name;
+ entry.object.reset();
+ entry.hasObject = true;
+ return i;
+ }
+ }
+ return idx;
}
int Inventory::add(const ObjectPtr & object) {
for (uint i = 0; i < _entries.size(); ++i) {
auto & entry = _entries[i];
- if (entry.hasObject && entry.object == object) {
- warning("Double adding object pointer %s, skipping...", object->getName().c_str());
+ if (entry.hasObject && entry.name == object->getName()) {
+ warning("Double adding object [pointer] %s, skipping...", object->getName().c_str());
return i;
}
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 6b40a64aeb1..c8980fc1c74 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -575,10 +575,12 @@ void Process::returnCurrentInventoryObject() {
auto screen = _engine->getCurrentScreen();
if (screen) {
_object->lock();
+ object->lock();
screen->remove(object);
+ object->unlock();
_object->unlock();
}
- suspend(kExitCodeLoadInventoryObject, name);
+ _engine->inventory().add(object);
}
void Process::attachInventoryObjectToMouse0() {
Commit: ff9f6e63c890d3f54bb97c6d2133d514f4c2be4d
https://github.com/scummvm/scummvm/commit/ff9f6e63c890d3f54bb97c6d2133d514f4c2be4d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:02+01:00
Commit Message:
AGDS: move character only on left click
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 5cfbd544a58..779543839bb 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -640,17 +640,19 @@ Common::Error AGDSEngine::run() {
}
} else {
debug("no handler found");
- if (_currentCharacter && _currentCharacter->active() && _currentScreen && _currentScreen->region()) {
- auto & region = _currentScreen->region();
- if (region->pointIn(_mouse)) {
- // FIXME: some object requires character to be in "trap" region
- // Remove this after movement implementation.
- _currentCharacter->moveTo(Common::String(), _mouse, -1);
+ if (lclick) {
+ if (_currentCharacter && _currentCharacter->active() && _currentScreen && _currentScreen->region()) {
+ auto & region = _currentScreen->region();
+ if (region->pointIn(_mouse)) {
+ // FIXME: some object requires character to be in "trap" region
+ // Remove this after movement implementation.
+ _currentCharacter->moveTo(Common::String(), _mouse, -1);
+ }
}
+ auto scroll = _currentScreen->scrollPosition();
+ scroll.x += _mouse.x - g_system->getWidth() / 2;
+ _currentScreen->scrollTo(scroll);
}
- auto scroll = _currentScreen->scrollPosition();
- scroll.x += _mouse.x - g_system->getWidth() / 2;
- _currentScreen->scrollTo(scroll);
}
}
break;
Commit: 0c7f924c92c5b299faba1c8f372afd9160cbf498
https://github.com/scummvm/scummvm/commit/0c7f924c92c5b299faba1c8f372afd9160cbf498
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:02+01:00
Commit Message:
AGDS: add reactivation reason
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/animation.cpp
engines/agds/character.cpp
engines/agds/console.cpp
engines/agds/dialog.cpp
engines/agds/soundManager.cpp
engines/agds/textLayout.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 779543839bb..799501f3d48 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -811,7 +811,7 @@ void AGDSEngine::skipFilm() {
}
_tellTextTimer = 0;
_textLayout.reset(*this);
- reactivate(_filmProcess);
+ reactivate(_filmProcess, "skipFilm");
}
int AGDSEngine::appendToSharedStorage(const Common::String &value) {
@@ -1350,14 +1350,14 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
}
-void AGDSEngine::reactivate(const Common::String &name, bool runNow) {
+void AGDSEngine::reactivate(const Common::String &name, const char *where, bool runNow) {
if (name.empty())
return;
for(uint i = 0; i < _processes.size(); ++i) {
ProcessPtr &process = _processes[i];
if (process && process->getName() == name) {
- debug("reactivate %s now: %d", name.c_str(), runNow);
+ debug("reactivate %s now: %d, %s", name.c_str(), runNow, where);
process->activate();
if (runNow)
process->run();
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index e49443ee2f1..21ae77a75ac 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -124,7 +124,7 @@ public:
void runObject(const ObjectPtr &object);
void runProcess(const ObjectPtr &object, uint ip = 0);
void stopProcess(const Common::String & name);
- void reactivate(const Common::String &name, bool runNow = false);
+ void reactivate(const Common::String &name, const char *where, bool runNow = false);
void resetCurrentScreen();
void loadScreen(const Common::String & name, ScreenLoadingType type, bool savePatch = true);
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index f51bcca6090..9750cd2437d 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -219,7 +219,7 @@ bool Animation::tick() {
if (!_phaseVar.empty())
_engine->setGlobal(_phaseVar, _phase - 1);
else
- _engine->reactivate(_process, true);
+ _engine->reactivate(_process, "animation end", true);
return false;
}
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index da1b3c921b9..4a9827ecc99 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -219,7 +219,7 @@ void Character::tick() {
_frames = 0;
direction(_direction);
}
- _engine->reactivate(_processName, true);
+ _engine->reactivate(_processName, "character", true);
}
}
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index 9434d9a1bd9..f7a136044bc 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -91,7 +91,7 @@ bool Console::activate(int argc, const char **argv) {
debugPrintf("usage: %s object_id\n", argv[0]);
return true;
}
- _engine->reactivate(argv[1]);
+ _engine->reactivate(argv[1], "console");
detach();
return false;
}
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index cd241528f84..df8239e1d35 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -132,7 +132,7 @@ bool Dialog::tick() {
debug("end of dialog, running %s", _dialogParentProcessName.c_str());
dialog_var->setInteger(-2);
- _engine->reactivate(_dialogParentProcessName);
+ _engine->reactivate(_dialogParentProcessName, "end of dialog");
_dialogParentProcessName.clear();
return false;
}
@@ -204,7 +204,7 @@ void Dialog::processDirective(Common::String line) {
}
debug("dialog value %s = %d (0x%04x), sample index: %d", line.c_str(), value, value, _currentSoundIndex);
_engine->getSystemVariable("dialog_var")->setInteger(value);
- _engine->reactivate(_dialogProcessName, true);
+ _engine->reactivate(_dialogProcessName, "dialog", true);
} else
warning("invalid dialog directive: %s", line.c_str());
}
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 21d7bb36dfb..746d9ae4215 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -56,7 +56,7 @@ void SoundManager::tick() {
_engine->setGlobal(phaseVar, 0);
}
} else if (!active)
- _engine->reactivate(sound.process);
+ _engine->reactivate(sound.process, "sound inactive");
}
}
@@ -128,7 +128,7 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
if (!phaseVar.empty())
_engine->setGlobal(phaseVar, _engine->getGlobal(phaseVar)? 1: 0);
else
- _engine->reactivate(process);
+ _engine->reactivate(process, "no sound");
return -1;
}
Audio::SoundHandle handle;
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 63796401c24..c9979ada1c8 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -29,7 +29,7 @@ void TextLayout::reset(AGDSEngine &engine) {
if (!var.empty()) {
engine.setGlobal(var, 0);
}
- engine.reactivate(_process);
+ engine.reactivate(_process, "text layout reset");
if (engine.getSystemVariable("tell_close_inv")->getInteger()) {
engine.inventory().enable(true);
}
Commit: c3a3f6e11846c056bc884c74000710d100f39b93
https://github.com/scummvm/scummvm/commit/c3a3f6e11846c056bc884c74000710d100f39b93
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:02+01:00
Commit Message:
AGDS: remove reactivation from dialog (not present in the original engine)
Changed paths:
engines/agds/dialog.cpp
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index df8239e1d35..2ea75a57ed3 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -204,7 +204,6 @@ void Dialog::processDirective(Common::String line) {
}
debug("dialog value %s = %d (0x%04x), sample index: %d", line.c_str(), value, value, _currentSoundIndex);
_engine->getSystemVariable("dialog_var")->setInteger(value);
- _engine->reactivate(_dialogProcessName, "dialog", true);
} else
warning("invalid dialog directive: %s", line.c_str());
}
Commit: 21effbad63c4074bbb6fa1af38b189c1cadc05c7
https://github.com/scummvm/scummvm/commit/21effbad63c4074bbb6fa1af38b189c1cadc05c7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:02+01:00
Commit Message:
AGDS: restore suspension of main "tell" process lost in refactoring
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c8980fc1c74..193cdc39501 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1210,6 +1210,10 @@ void Process::tell(bool npc, const Common::String &sound) {
Common::String region = popString();
debug("%s '%s' '%s' '%s'", npc? "npcSay": "playerSay", region.c_str(), text.c_str(), sound.c_str());
_engine->tell(*this, region, text, sound, npc);
+
+ //close inventory here if close flag was set
+ Common::String inventoryClose = _engine->getSystemVariable("inv_close")->getString();
+ suspend(!inventoryClose.empty()? kExitCodeCloseInventory: kExitCodeSuspend);
}
void Process::npcSay() {
Commit: 3df3f973c7e11e669406abd1548775283d61db1a
https://github.com/scummvm/scummvm/commit/3df3f973c7e11e669406abd1548775283d61db1a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:02+01:00
Commit Message:
AGDS: do not patch current screen (original engine)
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 193cdc39501..e096efb2d56 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -771,8 +771,7 @@ void Process::screenObjectPatchIncRef() {
debug("increment refcount for object %s, result: %d", objectName.c_str(), refs);
}
} else {
- debug("screenObjectPatchIncRef: current screen, loading object");
- suspend(kExitCodeLoadScreenObject, objectName);
+ debug("screenObjectPatchIncRef: current screen, skipping patch");
}
}
Commit: 606171f6e4d09863d7f6a7841a230c992580801d
https://github.com/scummvm/scummvm/commit/606171f6e4d09863d7f6a7841a230c992580801d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:02+01:00
Commit Message:
AGDS: fix missing argument to setRainDensity
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index e096efb2d56..46ad6c1bc5b 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1669,8 +1669,9 @@ void Process::setRain() {
}
void Process::setRainDensity() {
+ int change = pop();
int density = pop();
- debug("setRainDensity stub: %d", density);
+ debug("setRainDensity stub: %d (change: %d)", density, change);
}
Commit: 9b2471bc540ba6ef8276b252b0af22f61691c686
https://github.com/scummvm/scummvm/commit/9b2471bc540ba6ef8276b252b0af22f61691c686
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:02+01:00
Commit Message:
AGDS: remove reactivation from character (breaks morgue scene)
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 4a9827ecc99..51e7b7115d4 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -219,7 +219,6 @@ void Character::tick() {
_frames = 0;
direction(_direction);
}
- _engine->reactivate(_processName, "character", true);
}
}
Commit: 2eed4ea3b7deaf64d55153ce987138cc8159a117
https://github.com/scummvm/scummvm/commit/2eed4ea3b7deaf64d55153ce987138cc8159a117
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:02+01:00
Commit Message:
AGDS: do not rewind if animation ended from restartAnimation
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 46ad6c1bc5b..f449711bc10 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1020,7 +1020,7 @@ void Process::restartAnimation() {
}
Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
if (animation) {
- if ((_engine->getGlobal(phaseVar) == -1 && !animation->paused()) || animation->ended()) {
+ if (_engine->getGlobal(phaseVar) == -1 && !animation->paused()) {
debug("restartAnimation: rewind");
animation->rewind();
}
Commit: 1a3341995540052e5f8484aa4e5dbe0cb50c0a4d
https://github.com/scummvm/scummvm/commit/1a3341995540052e5f8484aa4e5dbe0cb50c0a4d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:02+01:00
Commit Message:
AGDS: do not return inventory object by default
Letter puzzle uses arbitrary object to juggle letter pieces (H.)
This ends up with cloned object being added to inventory.
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 799501f3d48..ad430aced46 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1376,7 +1376,6 @@ void AGDSEngine::stopProcess(const Common::String & name) {
}
void AGDSEngine::currentInventoryObject(const ObjectPtr & object) {
- resetCurrentInventoryObject();
_currentInventoryObject = object;
}
Commit: 5f31414b08f176321ab668b916e090949bd0f3bd
https://github.com/scummvm/scummvm/commit/5f31414b08f176321ab668b916e090949bd0f3bd
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:03+01:00
Commit Message:
AGDS: clean old sounds without phase vars
This fixes massive skips in dialogs
Changed paths:
engines/agds/soundManager.cpp
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 746d9ae4215..e34c1293233 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -33,8 +33,8 @@
namespace AGDS {
void SoundManager::tick() {
- for (SoundList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) {
- Sound &sound = *i;
+ for (auto it = _sounds.begin(); it != _sounds.end(); ) {
+ Sound &sound = *it;
auto &phaseVar = sound.phaseVar;
bool active = playing(sound.id);
@@ -55,8 +55,12 @@ void SoundManager::tick() {
_mixer->stopID(sound.id);
_engine->setGlobal(phaseVar, 0);
}
- } else if (!active)
+ ++it;
+ } else if (!active) {
_engine->reactivate(sound.process, "sound inactive");
+ it = _sounds.erase(it);
+ } else
+ ++it;
}
}
Commit: bded747b1bde62e39f87b51c12b3d04743e87156
https://github.com/scummvm/scummvm/commit/bded747b1bde62e39f87b51c12b3d04743e87156
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:03+01:00
Commit Message:
AGDS: add fixme
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f449711bc10..93ddd1779db 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -554,6 +554,7 @@ void Process::loadMouseCursorFromObject() {
}
void Process::attachInventoryObjectToMouse(bool flag) {
+ //FIXME: check that flag == true means re-adding current object back to inventory.
Common::String name = popString();
debug("attachInventoryObjectToMouse %s %d", name.c_str(), flag);
auto object = _engine->getCurrentScreenObject(name);
Commit: 2455561e749781f08f5ce9562e89dacd88f1f27a
https://github.com/scummvm/scummvm/commit/2455561e749781f08f5ce9562e89dacd88f1f27a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:03+01:00
Commit Message:
AGDS: allow lclick to click on inventory arrows while holding object (for using objects on each other)
Changed paths:
engines/agds/agds.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ad430aced46..18e0c3399e3 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -614,7 +614,7 @@ Common::Error AGDSEngine::run() {
if (ip)
debug("found use handler");
}
- if (!ip && !_currentInventoryObject) {
+ if (!ip) {
ip = object->getClickHandler();
if (ip) {
debug("found click handler");
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 93ddd1779db..f19b894d427 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -554,9 +554,10 @@ void Process::loadMouseCursorFromObject() {
}
void Process::attachInventoryObjectToMouse(bool flag) {
- //FIXME: check that flag == true means re-adding current object back to inventory.
Common::String name = popString();
debug("attachInventoryObjectToMouse %s %d", name.c_str(), flag);
+ if (flag)
+ _engine->resetCurrentInventoryObject();
auto object = _engine->getCurrentScreenObject(name);
if (object)
_engine->currentInventoryObject(object);
Commit: ec91f7db7cbc3840585f3913b727468e3d649bf0
https://github.com/scummvm/scummvm/commit/ec91f7db7cbc3840585f3913b727468e3d649bf0
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:03+01:00
Commit Message:
Revert "AGDS: do not patch current screen (original engine)"
Original engine checks that returned int == 0, and then exits with loadScreenObject
This reverts commit bdeff74876513dbf02f621016f0e79069e2c9103.
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f19b894d427..5a3e97b7a48 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -773,7 +773,8 @@ void Process::screenObjectPatchIncRef() {
debug("increment refcount for object %s, result: %d", objectName.c_str(), refs);
}
} else {
- debug("screenObjectPatchIncRef: current screen, skipping patch");
+ debug("screenObjectPatchIncRef: current screen, loading object");
+ suspend(kExitCodeLoadScreenObject, objectName);
}
}
Commit: 83dfd6775e0de67e62490e4f044c40d9dc33bc64
https://github.com/scummvm/scummvm/commit/83dfd6775e0de67e62490e4f044c40d9dc33bc64
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:03+01:00
Commit Message:
AGDS: do not lose the last message in dialog
Changed paths:
engines/agds/dialog.cpp
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 2ea75a57ed3..d1209736560 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -92,8 +92,19 @@ bool Dialog::tick() {
}
uint n = _dialogScript.size();
- if (_dialogScriptPos >= n)
+ if (_dialogScriptPos >= n) {
+
+ if (!_dialogProcessName.empty()) {
+ _dialogProcessName.clear();
+
+ debug("end of dialog, running %s", _dialogParentProcessName.c_str());
+ dialog_var->setInteger(-2);
+ _dialogParentProcessName.clear();
+ _engine->reactivate(_dialogParentProcessName, "end of dialog");
+ }
+
return false;
+ }
Common::String &line = _dialogLine;
line.clear();
@@ -127,15 +138,6 @@ bool Dialog::tick() {
dialog_var->setInteger(-3);
}
- if (_dialogScriptPos >= n && !_dialogProcessName.empty()) {
- _dialogProcessName.clear();
-
- debug("end of dialog, running %s", _dialogParentProcessName.c_str());
- dialog_var->setInteger(-2);
- _engine->reactivate(_dialogParentProcessName, "end of dialog");
- _dialogParentProcessName.clear();
- return false;
- }
return true;
}
Commit: a3ef27574a9b1a61ce13a4be59ca425503980c11
https://github.com/scummvm/scummvm/commit/a3ef27574a9b1a61ce13a4be59ca425503980c11
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:03+01:00
Commit Message:
AGDS: non destructive dialog reactivation
Changed paths:
engines/agds/dialog.cpp
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index d1209736560..f5f3c815245 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -95,11 +95,8 @@ bool Dialog::tick() {
if (_dialogScriptPos >= n) {
if (!_dialogProcessName.empty()) {
- _dialogProcessName.clear();
-
debug("end of dialog, running %s", _dialogParentProcessName.c_str());
dialog_var->setInteger(-2);
- _dialogParentProcessName.clear();
_engine->reactivate(_dialogParentProcessName, "end of dialog");
}
Commit: 7940da121528c8ed34acea5409226c7a0d115002
https://github.com/scummvm/scummvm/commit/7940da121528c8ed34acea5409226c7a0d115002
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:03+01:00
Commit Message:
AGDS: output warning if process finished with values on stack
Changed paths:
engines/agds/process.cpp
engines/agds/process.h
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 80a8ce76864..bd7f74b656b 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -200,6 +200,16 @@ void Process::deactivate() {
}
}
+void Process::done() {
+ _status = kStatusDone;
+ if (!_stack.empty())
+ warning("process %s finished with non-empty stack", getName().c_str());
+}
+void Process::fail() {
+ _status = kStatusError;
+}
+
+
void Process::run() {
bool restart = true;
while(_status != kStatusDone && _status != kStatusError && restart) {
diff --git a/engines/agds/process.h b/engines/agds/process.h
index f39b05846ef..7566c4bcb78 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -159,12 +159,8 @@ public:
}
void activate();
void deactivate();
- void done() {
- _status = kStatusDone;
- }
- void fail() {
- _status = kStatusError;
- }
+ void done();
+ void fail();
bool finished() const {
return _status == kStatusDone || _status == kStatusError;
Commit: 358610258d7f48b4826769ff63008ef0d246513b
https://github.com/scummvm/scummvm/commit/358610258d7f48b4826769ff63008ef0d246513b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:03+01:00
Commit Message:
AGDS: display only top-level object description
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 18e0c3399e3..685a9be56ef 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -697,6 +697,7 @@ Common::Error AGDSEngine::run() {
int x = getSystemVariable("objtext_x")->getInteger() - w / 2;
int y = getSystemVariable("objtext_y")->getInteger();
font->drawString(backbuffer, title, x, y, backbuffer->w - x, 0);
+ break;
}
}
}
Commit: 1a578f19052ce8a64bd256ecc639beb26c1464df
https://github.com/scummvm/scummvm/commit/1a578f19052ce8a64bd256ecc639beb26c1464df
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:03+01:00
Commit Message:
AGDS: remove tickCharacter, call trap handler only from move
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/character.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 685a9be56ef..ffd975eaf3e 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -422,7 +422,8 @@ void AGDSEngine::tick() {
_currentScreen->tick();
if (!dialogActive) {
tickInventory();
- tickCharacter();
+ if (_currentCharacter)
+ _currentCharacter->tick();
}
runProcesses();
}
@@ -1068,22 +1069,6 @@ void AGDSEngine::tickInventory() {
}
}
-void AGDSEngine::tickCharacter() {
- if (!_currentScreen || !_currentCharacter)
- return;
-
- auto pos = _currentCharacter->position();
- auto objects = _currentScreen->find(pos);
- for(auto & object: objects) {
- auto region = object->getTrapRegion();
- if (region && region->pointIn(pos)) {
- debug("starting trap process");
- runProcess(object, object->getTrapHandler());
- }
- }
-}
-
-
bool AGDSEngine::hasFeature(EngineFeature f) const {
switch (f) {
case kSupportsSubtitleOptions:
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 21ae77a75ac..79fda1b227a 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -238,7 +238,6 @@ public:
}
void tickInventory();
- void tickCharacter();
void playSoundSync(int syncSoundId) {
_syncSoundId = syncSoundId;
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 51e7b7115d4..847eccf3886 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -24,6 +24,7 @@
#include "agds/agds.h"
#include "agds/animation.h"
#include "agds/object.h"
+#include "agds/region.h"
#include "agds/resourceManager.h"
#include "common/array.h"
#include "common/debug.h"
@@ -158,6 +159,18 @@ void Character::moveTo(const Common::String & processName, Common::Point dst, in
_pos = dst;
_visible = true;
direction(dir);
+
+ auto *screen = _engine->getCurrentScreen();
+ if (screen) {
+ auto objects = screen->find(dst);
+ for(auto & object: objects) {
+ auto region = object->getTrapRegion();
+ if (region && region->pointIn(dst)) {
+ debug("starting trap process");
+ _engine->runProcess(object, object->getTrapHandler());
+ }
+ }
+ }
}
void Character::animate(int direction, int speed, bool jokes) {
Commit: 7d290407511d2bc33f431f09fac20ae78f74ad2c
https://github.com/scummvm/scummvm/commit/7d290407511d2bc33f431f09fac20ae78f74ad2c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:03+01:00
Commit Message:
AGDS: remove all sounds and stop processes for removed objects
Changed paths:
engines/agds/agds.h
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 79fda1b227a..bb0cb13a6f5 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -124,6 +124,7 @@ public:
void runObject(const ObjectPtr &object);
void runProcess(const ObjectPtr &object, uint ip = 0);
void stopProcess(const Common::String & name);
+ void stopProcessForObject(const Common::String & name);
void reactivate(const Common::String &name, const char *where, bool runNow = false);
void resetCurrentScreen();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 5a3e97b7a48..75a9b4c7e51 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -277,9 +277,17 @@ void Process::removeScreenObject() {
return;
}
- _object->lock();
- if (!screen->remove(name)) {
+ auto object = screen->find(name);
+ if (!object) {
warning("removeScreenObject: object %s not found", name.c_str());
+ return;
+ }
+
+ _object->lock();
+ screen->remove(object);
+ if (!object->locked()) {
+ _engine->stopProcess(name);
+ _engine->soundManager().stopAllFrom(name);
}
_object->unlock();
}
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index e34c1293233..d57871a6f18 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -97,6 +97,21 @@ void SoundManager::stopAll() {
_sounds.clear();
}
+void SoundManager::stopAllFrom(const Common::String &process) {
+ for (auto i = _sounds.begin(); i != _sounds.end(); ) {
+ auto &sound = *i;
+ if (sound.process == process) {
+ _mixer->stopID(sound.id);
+ if (!sound.phaseVar.empty())
+ _engine->setGlobal(sound.phaseVar, 0);
+ i = _sounds.erase(i);
+ } else {
+ ++i;
+ }
+ }
+}
+
+
int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int volume, int pan, int id) {
debug("SoundMan::play(process: '%s', resource: '%s', filename: '%s', phaseVar: '%s', start: %d, volume: %d, pan: %d, id: %d", process.c_str(), resource.c_str(), filename.c_str(), phaseVar.c_str(), startPlaying, volume, pan, id);
if (filename.empty())
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index cffd2a2e71e..5a72c2f37e9 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -71,6 +71,7 @@ namespace AGDS {
void tick();
int play(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int volume, int pan, int id = -1);
bool playing(int id) const;
+ void stopAllFrom(const Common::String &process);
void stopAll();
const Sound *find(int id) const;
Sound *findSampleByPhaseVar(const Common::String &phaseVar);
Commit: 991db7ab77cf264f432b746cce201dcc594f672a
https://github.com/scummvm/scummvm/commit/991db7ab77cf264f432b746cce201dcc594f672a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:04+01:00
Commit Message:
AGDS: reset direction only if jokes was played
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 847eccf3886..6e02270acc6 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -228,9 +228,12 @@ void Character::tick() {
_animation->tick();
_phase = _animation->phase();
if (_phase >= _frames) {
+ bool wasJokes = _jokes;
+ _jokes = false;
_phase = -1;
_frames = 0;
- direction(_direction);
+ if (wasJokes)
+ direction(_direction);
}
}
}
Commit: e9b264f8a3eae7f60ee76e948582c4e331a4fc4e
https://github.com/scummvm/scummvm/commit/e9b264f8a3eae7f60ee76e948582c4e331a4fc4e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:04+01:00
Commit Message:
AGDS: remove hack with single frame tick for non-jokes animations (now animations are loading its first frame at load())
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 6e02270acc6..356c48bdc15 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -189,8 +189,6 @@ void Character::animate(int direction, int speed, bool jokes) {
_animation = animation;
_animation->speed(speed);
_animation->rewind();
- if (!_jokes)
- _animation->tick(); //load first frame
_phase = 0;
_frames = _animation->frames();
_jokes = jokes;
Commit: e1349a78439990c7eeb27aa8afabbb78a0b3de5b
https://github.com/scummvm/scummvm/commit/e1349a78439990c7eeb27aa8afabbb78a0b3de5b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:04+01:00
Commit Message:
AGDS: remove double-tick for Character, reactivate process from tick
Changed paths:
engines/agds/character.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 356c48bdc15..87e2f9befdb 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -213,27 +213,27 @@ void Character::stop() {
}
void Character::tick() {
- if (!active() || !_animation)
- return;
-
- auto screen = _engine->getCurrentScreen();
- auto scale = screen? screen->getZScale(_pos.y): 1;
- _animation->scale(scale);
-
- // debug("character %d/%d", _phase, _frames);
- if (_phase >= 0 && _phase < _frames) {
- if (_jokes)
- _animation->tick();
- _phase = _animation->phase();
- if (_phase >= _frames) {
- bool wasJokes = _jokes;
- _jokes = false;
- _phase = -1;
- _frames = 0;
- if (wasJokes)
- direction(_direction);
+ if (active() && _animation) {
+ auto screen = _engine->getCurrentScreen();
+ auto scale = screen? screen->getZScale(_pos.y): 1;
+ _animation->scale(scale);
+
+ if (_phase >= 0 && _phase < _frames) {
+ if (_jokes)
+ _animation->tick();
+ _phase = _animation->phase();
+ if (_phase >= _frames) {
+ bool wasJokes = _jokes;
+ _jokes = false;
+ _phase = -1;
+ _frames = 0;
+ if (wasJokes)
+ direction(_direction);
+ }
}
}
+ if (!_stopped && !_processName.empty())
+ _engine->reactivate(_processName, "Character::tick");
}
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 44bef1128ad..067322b6bfc 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -190,10 +190,6 @@ void Screen::tick() {
_animations.erase(_animations.begin() + i);
}
}
-
- Character * character = _engine->currentCharacter();
- if (character)
- character->tick();
}
void Screen::paint(Graphics::Surface &backbuffer) const {
Commit: 264d069dab72a6b2b140fcc93952c6ceb02cfea5
https://github.com/scummvm/scummvm/commit/264d069dab72a6b2b140fcc93952c6ceb02cfea5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:04+01:00
Commit Message:
AGDS: make stop/leave/move suspend process and change process name in character object
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 87e2f9befdb..a4dd7fcf51f 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -207,11 +207,17 @@ void Character::animate(const Common::String & processName, Common::Point pos, i
animate(direction, speed, true);
}
-void Character::stop() {
- debug("character %s: stop", _object->getName().c_str());
+void Character::stop(const Common::String &processName) {
+ debug("character %s: stop, process: %s", _object->getName().c_str(), processName.c_str());
+ _processName = processName;
_stopped = true;
}
+void Character::leave(const Common::String &processName) {
+ debug("character %s: leave, process: %s", _object->getName().c_str(), processName.c_str());
+ _processName = processName;
+}
+
void Character::tick() {
if (active() && _animation) {
auto screen = _engine->getCurrentScreen();
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 4df516b0764..f6dd2cb269e 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -110,7 +110,8 @@ public:
void animate(const Common::String &processName, Common::Point pos, int direction, int speed);
void animate(int direction, int speed, bool jokes);
- void stop();
+ void stop(const Common::String &processName);
+ void leave(const Common::String &processName);
int getPhase() const {
return _jokes? _phase: -1;
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 7566c4bcb78..de98be68fdf 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -126,6 +126,7 @@ private:
ProcessExitCode resume();
void setupAnimation(Animation *animation);
void attachInventoryObjectToMouse(bool flag);
+ void leaveCharacter(const Common::String &name, const Common::String ®ionName, int dir);
public:
Process(AGDSEngine *engine, ObjectPtr object, unsigned ip = 0);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 75a9b4c7e51..ed9e14d031e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1520,11 +1520,10 @@ void Process::moveCharacter(bool usermove) {
auto region = _engine->loadRegion(regionName);
if (region) {
character->moveTo(_object->getName(), region->center, direction);
+ suspend();
}
} else
warning("character %s could not be found", id.c_str());
- if (_status == kStatusPassive)
- suspend();
}
void Process::moveCharacterUserMove() {
@@ -1568,20 +1567,29 @@ void Process::hideCharacter() {
warning("character %s could not be found", name.c_str());
}
-void Process::leaveCharacter() {
- Common::String arg2 = popString();
- Common::String arg1 = popString();
- debug("leaveCharacter %s %s", arg1.c_str(), arg2.c_str());
- RegionPtr region = _engine->loadRegion(arg2);
- debug("region: %s", region->toString().c_str());
+void Process::leaveCharacter(const Common::String &name, const Common::String ®ionName, int dir) {
+ debug("leaveCharacter %s %s %d", name.c_str(), regionName.c_str(), dir);
+ Character *character = _engine->getCharacter(name);
+ if (character) {
+ RegionPtr region = _engine->loadRegion(regionName);
+ debug("region: %s", region->toString().c_str());
+ character->moveTo(getName(), region->center, dir);
+ } else
+ warning("character %s could not be found", name.c_str());
_engine->enableSystemUser(true); //called from update_music_screen_sound_curtain
}
+
+void Process::leaveCharacter() {
+ Common::String regionName = popString();
+ Common::String name = popString();
+ leaveCharacter(name, regionName, -1);
+}
+
void Process::leaveCharacterEx() {
- int arg3 = pop();
- Common::String arg2 = popString();
- Common::String arg1 = popString();
- debug("leaveCharacterEx %s %s %d", arg1.c_str(), arg2.c_str(), arg3);
- _engine->enableSystemUser(true); //called from update_music_screen_sound_curtain
+ int dir = pop();
+ Common::String regionName = popString();
+ Common::String name = popString();
+ leaveCharacter(name, regionName, dir);
}
void Process::setCharacter() {
@@ -1658,8 +1666,9 @@ void Process::stopCharacter() {
if (direction != -1) {
character->direction(direction);
debug("no suspend here, stub");
+ character->stop(getName());
+ suspend();
}
- character->stop();
} else
warning("could not find character %s", name.c_str());
}
Commit: 0a9f1ce86a7cb6aec8fd25fa20ce4ae09678c31b
https://github.com/scummvm/scummvm/commit/0a9f1ce86a7cb6aec8fd25fa20ce4ae09678c31b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:04+01:00
Commit Message:
AGDS: do not reactivate character process if there's text layout
Changed paths:
engines/agds/agds.cpp
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ffd975eaf3e..a2fbcf83946 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -423,7 +423,7 @@ void AGDSEngine::tick() {
if (!dialogActive) {
tickInventory();
if (_currentCharacter)
- _currentCharacter->tick();
+ _currentCharacter->tick(!_textLayout.valid());
}
runProcesses();
}
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index a4dd7fcf51f..468956f18c0 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -218,7 +218,7 @@ void Character::leave(const Common::String &processName) {
_processName = processName;
}
-void Character::tick() {
+void Character::tick(bool reactivate) {
if (active() && _animation) {
auto screen = _engine->getCurrentScreen();
auto scale = screen? screen->getZScale(_pos.y): 1;
@@ -238,7 +238,7 @@ void Character::tick() {
}
}
}
- if (!_stopped && !_processName.empty())
+ if (reactivate && !_processName.empty())
_engine->reactivate(_processName, "Character::tick");
}
diff --git a/engines/agds/character.h b/engines/agds/character.h
index f6dd2cb269e..a063aa84182 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -133,7 +133,7 @@ public:
return _jokes? _jokesDirection: _direction;
}
- void tick();
+ void tick(bool reactivate);
void paint(Graphics::Surface & backbuffer, Common::Point pos) const;
int getDirectionForMovement(Common::Point delta);
Commit: ee7f9ac1dc21055cab59012ad383229cf198fc2b
https://github.com/scummvm/scummvm/commit/ee7f9ac1dc21055cab59012ad383229cf198fc2b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:04+01:00
Commit Message:
AGDS: add Inventory::has (do not create object)
Changed paths:
engines/agds/inventory.cpp
engines/agds/inventory.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 1384b661ff2..591f62fbb46 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -63,6 +63,14 @@ int Inventory::free() const {
return free;
}
+bool Inventory::has(int index) const {
+ if (index >= 0 && index < kMaxSize) {
+ auto & entry = _entries[index];
+ return entry.hasObject;
+ }
+ return {};
+}
+
ObjectPtr Inventory::get(int index) {
if (index >= 0 && index < kMaxSize) {
auto & entry = _entries[index];
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index bd324385c7b..254887c5627 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -80,6 +80,7 @@ public:
bool remove(const Common::String &name);
void removeGaps();
+ bool has(int index) const;
ObjectPtr get(int index);
int find(const Common::String &name) const;
ObjectPtr find(const Common::Point pos) const;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index ed9e14d031e..fa54d3d7066 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1344,9 +1344,8 @@ void Process::inventoryHasObjectByName() {
void Process::inventoryHasObject() {
int index = pop();
- debug("inventoryHasObject %d", index);
- bool hasObject = _engine->inventory().get(index);
- debug("\t->%d", hasObject);
+ bool hasObject = _engine->inventory().has(index);
+ debug("inventoryHasObject %d -> %d", index, hasObject);
push(hasObject);
}
Commit: 0b7fbe5c0d6e9c4ce65f33d33cfa2077cf5e721b
https://github.com/scummvm/scummvm/commit/0b7fbe5c0d6e9c4ce65f33d33cfa2077cf5e721b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:04+01:00
Commit Message:
AGDS: add a warning about replacing current inventory object
Changed paths:
engines/agds/agds.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index a2fbcf83946..ea22e8a57f0 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1362,6 +1362,9 @@ void AGDSEngine::stopProcess(const Common::String & name) {
}
void AGDSEngine::currentInventoryObject(const ObjectPtr & object) {
+ if (_currentInventoryObject)
+ warning("setting current inventory object to %s, old: %s", object? object->getName().c_str(): "none",
+ _currentInventoryObject? _currentInventoryObject->getName().c_str(): "none");
_currentInventoryObject = object;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index fa54d3d7066..c7405a030f3 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -306,7 +306,8 @@ void Process::loadMouse() {
}
void Process::resetMousePointer() {
- _engine->currentInventoryObject(ObjectPtr());
+ debug("resetMousePointer");
+ _engine->popCurrentInventoryObject();
}
void Process::getRandomNumber() {
Commit: 2e9e9d9145d4bd09e3ff7e40ac7ec0202bcbab69
https://github.com/scummvm/scummvm/commit/2e9e9d9145d4bd09e3ff7e40ac7ec0202bcbab69
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:04+01:00
Commit Message:
AGDS: remove dialog parent process/runDialog shortcut
Dialog runs argument object, but signals on the parent.
Changed paths:
engines/agds/agds.h
engines/agds/dialog.cpp
engines/agds/dialog.h
engines/agds/process.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index bb0cb13a6f5..1e6b4c862dd 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -234,10 +234,6 @@ public:
void setNextScreenName(const Common::String &nextScreenName, ScreenLoadingType type);
void returnToPreviousScreen();
- void runDialog(const Common::String &dialogParentProcess, const Common::String &dialogProcess) {
- _dialog.run(dialogParentProcess, dialogProcess);
- }
-
void tickInventory();
void playSoundSync(int syncSoundId) {
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index f5f3c815245..0f5ee983961 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -6,13 +6,6 @@
namespace AGDS {
-void Dialog::run(const Common::String &dialogParentProcess, const Common::String & dialogProcess) {
- debug("runDialog: %s", dialogProcess.c_str());
- _dialogParentProcessName = dialogParentProcess;
- _dialogProcessName = dialogProcess;
- _engine->runObject(dialogProcess);
-}
-
void Dialog::parseDialogDefs(const Common::String &defs) {
_dialogDefs.clear();
Common::String name, value;
@@ -47,10 +40,11 @@ void Dialog::parseDialogDefs(const Common::String &defs) {
}
}
-void Dialog::load(const Common::String &dialogScript, const Common::String &defs) {
+void Dialog::load(const Common::String &processName, const Common::String &dialogScript, const Common::String &defs) {
_currentDef.clear();
_sounds.clear();
parseDialogDefs(defs);
+ _dialogProcessName = processName;
_dialogScript = dialogScript;
_dialogScriptPos = 0;
_engine->getSystemVariable("dialog_var")->setInteger(-1);
@@ -87,7 +81,6 @@ bool Dialog::tick() {
auto dialog_var = _engine->getSystemVariable("dialog_var");
int dialog_var_value = dialog_var->getInteger();
if (dialog_var_value != 0) {
- debug("dialog_var = %d, skipping tick", dialog_var_value);
return false;
}
@@ -95,9 +88,9 @@ bool Dialog::tick() {
if (_dialogScriptPos >= n) {
if (!_dialogProcessName.empty()) {
- debug("end of dialog, running %s", _dialogParentProcessName.c_str());
+ debug("end of dialog, running %s", _dialogProcessName.c_str());
dialog_var->setInteger(-2);
- _engine->reactivate(_dialogParentProcessName, "end of dialog");
+ _engine->reactivate(_dialogProcessName, "end of dialog");
}
return false;
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
index f47120ee1bb..9f3c2546f20 100644
--- a/engines/agds/dialog.h
+++ b/engines/agds/dialog.h
@@ -52,7 +52,6 @@ private:
DialogDefsType _dialogDefs;
Common::String _dialogScript;
uint32 _dialogScriptPos;
- Common::String _dialogParentProcessName;
Common::String _dialogProcessName;
Common::String _dialogLine;
@@ -64,14 +63,13 @@ private:
public:
Dialog(AGDSEngine *engine): _engine(engine), _dialogScriptPos(0), _currentSoundIndex(-1) { }
- void run(const Common::String &dialogParent, const Common::String &dialogProcess);
int textDelay(const Common::String &str);
const Common::String &getNextDialogLine() const {
return _dialogLine;
}
Common::String getNextDialogSound();
- void load(const Common::String &dialogScript, const Common::String & defs);
+ void load(const Common::String &processName, const Common::String &dialogScript, const Common::String & defs);
bool tick();
private:
void processSoundDirective(const Common::String &line);
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index bd7f74b656b..64417c1fce4 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -232,7 +232,7 @@ void Process::run() {
case kExitCodeRunDialog:
deactivate();
_object->lock();
- _engine->runDialog(getName(), getExitArg1());
+ _engine->runObject(getExitArg1());
_object->unlock();
break;
case kExitCodeSetNextScreen:
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c7405a030f3..4212a5b28e8 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1255,7 +1255,7 @@ void Process::loadDialog() {
arg2 = _engine->loadText(arg2);
arg3 = _engine->loadText(arg3);
- _engine->dialog().load(arg2, arg3);
+ _engine->dialog().load(getName(), arg2, arg3);
suspend(kExitCodeRunDialog, arg1);
}
Commit: fe38854f23d59f32be580d7cc9579f043b9065ab
https://github.com/scummvm/scummvm/commit/fe38854f23d59f32be580d7cc9579f043b9065ab
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:04+01:00
Commit Message:
AGDS: add x,y from description to animation
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 468956f18c0..43ae5c7491f 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -177,6 +177,7 @@ void Character::animate(int direction, int speed, bool jokes) {
if (direction == -1)
return;
+ _description = nullptr;
_visible = true;
_stopped = false;
auto character = jokes? _engine->jokes(): this;
@@ -252,6 +253,15 @@ void Character::paint(Graphics::Surface &backbuffer, Common::Point pos) const {
pos.y -= _animation->visibleHeight();
pos.x -= _animation->visibleCenter();
+ if (_description) {
+ auto &frames = _description->frames;
+ if (_phase < frames.size()) {
+ auto &frame = frames[_phase];
+ pos.x += frame.x * _animation->scale();
+ pos.y += frame.y * _animation->scale();
+ }
+ }
+
int fogAlpha = 0;
if (_fog) {
auto z = this->z();
Commit: d13e9a0fe02cb20a3a5363fbe88247395c52a779
https://github.com/scummvm/scummvm/commit/d13e9a0fe02cb20a3a5363fbe88247395c52a779
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:04+01:00
Commit Message:
AGDS: add missing cleanup after destroy
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ea22e8a57f0..c5861fdece8 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -263,6 +263,15 @@ void AGDSEngine::runProcess(const ObjectPtr &object, uint ip) {
error("process table exhausted");
}
+bool AGDSEngine::hasActiveProcesses(const Common::String &name) const {
+ for(auto & process : _processes) {
+ if (process && process->getName() == name && !process->finished())
+ return true;
+ }
+ return false;
+}
+
+
ObjectPtr AGDSEngine::getCurrentScreenObject(const Common::String &name) {
return _currentScreen? _currentScreen->find(name): ObjectPtr();
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 1e6b4c862dd..5063d4a1c99 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -126,6 +126,7 @@ public:
void stopProcess(const Common::String & name);
void stopProcessForObject(const Common::String & name);
void reactivate(const Common::String &name, const char *where, bool runNow = false);
+ bool hasActiveProcesses(const Common::String &name) const;
void resetCurrentScreen();
void loadScreen(const Common::String & name, ScreenLoadingType type, bool savePatch = true);
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 64417c1fce4..6360960bacc 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -219,6 +219,11 @@ void Process::run() {
case kExitCodeDestroy:
debug("process %s returned destroy exit code", getName().c_str());
done();
+ if (!getObject()->alive() && !_engine->hasActiveProcesses(getName())) {
+ auto * screen = _engine->getCurrentScreen();
+ if (screen)
+ screen->remove(getName());
+ }
break;
case kExitCodeLoadScreenObjectAs:
case kExitCodeLoadScreenObject:
Commit: 5162f7e06fbb1a751bd637e9bfdb9788f9ad132c
https://github.com/scummvm/scummvm/commit/5162f7e06fbb1a751bd637e9bfdb9788f9ad132c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:05+01:00
Commit Message:
AGDS: add missing suspend() in returnCurrentInventoryObject
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4212a5b28e8..d37308e43b3 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -592,6 +592,7 @@ void Process::returnCurrentInventoryObject() {
_object->unlock();
}
_engine->inventory().add(object);
+ suspend();
}
void Process::attachInventoryObjectToMouse0() {
Commit: be7d8f3e58fc886141aa9fc1c6ba47eb420cf130
https://github.com/scummvm/scummvm/commit/be7d8f3e58fc886141aa9fc1c6ba47eb420cf130
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:05+01:00
Commit Message:
AGDS: clear object patches if new game started
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index c5861fdece8..51936a34f95 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -412,6 +412,7 @@ void AGDSEngine::newGame() {
runObject(done);
_patches.clear();
+ _objectPatches.clear();
_inventory.clear();
_globals.clear();
Console *console = getConsole();
Commit: 78ed71102358627ae40dd5062be1106f6614ff88
https://github.com/scummvm/scummvm/commit/78ed71102358627ae40dd5062be1106f6614ff88
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:05+01:00
Commit Message:
AGDS: pass ambient flag to sound manager, restart ambient streams automatically
Changed paths:
engines/agds/agds.cpp
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 51936a34f95..9aeb697a36c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1210,7 +1210,8 @@ Common::Error AGDSEngine::loadGameState(int slot) {
uint type = agds_a->readUint32LE();
debug("saved audio state: sample: '%s:%s', var: '%s' %u %u", resource.c_str(), filename.c_str(), phaseVar.c_str(), volume, type);
debug("phase var for sample -> %d", getGlobal(phaseVar));
- _ambientSoundId = _soundManager.play(Common::String(), resource, filename, phaseVar, true, volume, 0); //fixme: double check
+ _ambientSoundId = _soundManager.play(Common::String(), resource, filename, phaseVar, true,
+ volume, /*pan=*/0, /*id=*/-1, /*ambient=*/true);
debug("ambient sound id = %d", _ambientSoundId);
}
{
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d37308e43b3..ef4cd62a014 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -165,7 +165,7 @@ void Process::loadAnimation() {
void Process::loadSample() {
Common::String name = popString();
debug("loadSample %s, phaseVar: %s, ambient: %d, volume: %d", name.c_str(), _phaseVar.c_str(), _sampleAmbient, _sampleVolume);
- int id = _engine->soundManager().play(getName(), name, _engine->loadText(name), _phaseVar, _sampleAmbient || !_phaseVarControlled || _phaseVar.empty(), _sampleVolume, 0);
+ int id = _engine->soundManager().play(getName(), name, _engine->loadText(name), _phaseVar, _sampleAmbient || !_phaseVarControlled || _phaseVar.empty(), _sampleVolume, 0, -1, _sampleAmbient);
if (_sampleAmbient)
_engine->setAmbientSoundId(id);
}
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index d57871a6f18..9e071ab2d30 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -112,8 +112,8 @@ void SoundManager::stopAllFrom(const Common::String &process) {
}
-int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int volume, int pan, int id) {
- debug("SoundMan::play(process: '%s', resource: '%s', filename: '%s', phaseVar: '%s', start: %d, volume: %d, pan: %d, id: %d", process.c_str(), resource.c_str(), filename.c_str(), phaseVar.c_str(), startPlaying, volume, pan, id);
+int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int volume, int pan, int id, bool ambient) {
+ debug("SoundMan::play(process: '%s', resource: '%s', filename: '%s', phaseVar: '%s', start: %d, volume: %d, pan: %d, id: %d, ambient: %d", process.c_str(), resource.c_str(), filename.c_str(), phaseVar.c_str(), startPlaying, volume, pan, id, ambient);
if (filename.empty())
return -1;
@@ -150,13 +150,18 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
_engine->reactivate(process, "no sound");
return -1;
}
- Audio::SoundHandle handle;
if (id == -1)
id = _nextId++;
_sounds.push_back(Sound(id, process, resource, filename, phaseVar, volume, pan));
+ auto handle = &_sounds.back().handle;
if (startPlaying)
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_sounds.back().handle, stream, id, volume * Audio::Mixer::kMaxChannelVolume / 100, pan * 127 / 100);
+ _mixer->playStream(
+ ambient? Audio::Mixer::kMusicSoundType: Audio::Mixer::kPlainSoundType,
+ &_sounds.back().handle, stream, id,
+ volume * Audio::Mixer::kMaxChannelVolume / 100, pan * 127 / 100);
+ if (ambient)
+ _mixer->loopChannel(*handle);
//if (sound_off)
// setPhaseVar(_sounds.back(), 1);
return id;
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index 5a72c2f37e9..8db5470da08 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -69,7 +69,7 @@ namespace AGDS {
public:
SoundManager(AGDSEngine *engine, Audio::Mixer *mixer): _nextId(1), _engine(engine), _mixer(mixer) { }
void tick();
- int play(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int volume, int pan, int id = -1);
+ int play(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int volume, int pan, int id = -1, bool ambient = false);
bool playing(int id) const;
void stopAllFrom(const Common::String &process);
void stopAll();
Commit: 25bd4b7cd5635b8eaf7ed4859c3c51e2bf0f6705
https://github.com/scummvm/scummvm/commit/25bd4b7cd5635b8eaf7ed4859c3c51e2bf0f6705
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:05+01:00
Commit Message:
AGDS: remove bogus log level
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index ef4cd62a014..8e35e9e8259 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1666,7 +1666,6 @@ void Process::stopCharacter() {
if (character) {
if (direction != -1) {
character->direction(direction);
- debug("no suspend here, stub");
character->stop(getName());
suspend();
}
Commit: cfc7e27dac3a8a710ab1707702f76bf01048c7fc
https://github.com/scummvm/scummvm/commit/cfc7e27dac3a8a710ab1707702f76bf01048c7fc
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:05+01:00
Commit Message:
AGDS: do not set sound process for ambient sounds
Changed paths:
engines/agds/soundManager.cpp
engines/agds/soundManager.h
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 9e071ab2d30..b0f8f14e186 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -112,7 +112,7 @@ void SoundManager::stopAllFrom(const Common::String &process) {
}
-int SoundManager::play(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int volume, int pan, int id, bool ambient) {
+int SoundManager::play(Common::String process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int volume, int pan, int id, bool ambient) {
debug("SoundMan::play(process: '%s', resource: '%s', filename: '%s', phaseVar: '%s', start: %d, volume: %d, pan: %d, id: %d, ambient: %d", process.c_str(), resource.c_str(), filename.c_str(), phaseVar.c_str(), startPlaying, volume, pan, id, ambient);
if (filename.empty())
return -1;
@@ -131,6 +131,8 @@ int SoundManager::play(const Common::String &process, const Common::String &reso
warning("no sound %s", filename.c_str());
return -1;
}
+ if (ambient)
+ process.clear();
Common::String lname(filename);
lname.toLowercase();
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index 8db5470da08..d3f3994d399 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -69,7 +69,7 @@ namespace AGDS {
public:
SoundManager(AGDSEngine *engine, Audio::Mixer *mixer): _nextId(1), _engine(engine), _mixer(mixer) { }
void tick();
- int play(const Common::String &process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int volume, int pan, int id = -1, bool ambient = false);
+ int play(Common::String process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int volume, int pan, int id = -1, bool ambient = false);
bool playing(int id) const;
void stopAllFrom(const Common::String &process);
void stopAll();
Commit: 88980cdaa07a5af8c3fbea5a925b89e07857ac82
https://github.com/scummvm/scummvm/commit/88980cdaa07a5af8c3fbea5a925b89e07857ac82
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:05+01:00
Commit Message:
AGDS: implement "curtain" timer
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 9aeb697a36c..e2fe219ea7d 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -67,6 +67,7 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_tellTextTimer(0),
_syncSoundId(-1),
_ambientSoundId(-1),
+ _curtainTimer(-1),
_fastMode(true),
_hintMode(false) {
}
@@ -425,7 +426,26 @@ void AGDSEngine::newGame() {
runObject(init);
}
+void AGDSEngine::curtain(const Common::String &process, int screen, int sound, int music) {
+ assert(!process.empty());
+ _curtainProcess = process;
+ _curtainTimer = 100;
+ enableSystemUser(false);
+ getSystemVariable("screen_curtain")->setInteger(screen);
+ getSystemVariable("sound_curtain")->setInteger(sound);
+ getSystemVariable("music_curtain")->setInteger(music);
+}
+
void AGDSEngine::tick() {
+ if (_curtainTimer >= 0 && !_curtainProcess.empty()) {
+ _curtainTimer -= 5;
+ if (_curtainTimer < 0) {
+ _curtainTimer = -1;
+ enableSystemUser(true);
+ reactivate(_curtainProcess, "curtainTimer");
+ _curtainProcess.clear();
+ }
+ }
loadNextScreen();
bool dialogActive = _dialog.tick();
if (_currentScreen)
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 5063d4a1c99..9ce84f5419e 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -217,11 +217,7 @@ public:
_userEnabled = enabled;
}
void enableSystemUser(bool enabled) {
- if (enabled) {
- if (_systemUserEnabled)
- _userEnabled = true;
- } else
- _systemUserEnabled = enabled;
+ _systemUserEnabled = enabled;
}
bool userEnabled() const {
@@ -277,6 +273,8 @@ public:
}
int getRandomNumber(int max);
+ void curtain(const Common::String &process, int screen, int sound, int music);
+
private:
void stopAmbientSound();
void loadPatches(Common::SeekableReadStream *file, Database & db);
@@ -346,6 +344,9 @@ private:
int _syncSoundId;
int _ambientSoundId;
+ Common::String _curtainProcess;
+ int _curtainTimer;
+
bool _fastMode;
bool _hintMode;
};
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index a35cd57eca2..88457b6964b 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -252,7 +252,7 @@ enum Opcode {
kStub232 = 232,
kObjectFreePictureAndAnimation = 233,
kGetSampleVolume = 234,
- kStub235 = 235,
+ kFadeScreen = 235,
kUserEnabled = 236,
kAnimationNextFrame = 237,
kInventoryHasObjectByName = 238,
@@ -470,7 +470,7 @@ enum Opcode {
OP(kGetSampleVolume, getSampleVolume) \
OP(kStub231, stub231) \
OP(kObjectFreePictureAndAnimation, objectFreePictureAndAnimation) \
- OP(kStub235, stub235) \
+ OP(kFadeScreen, fadeScreen) \
OP(kUserEnabled, userEnabled) \
OP(kSetCharacterNotifyVars, setCharacterNotifyVars) \
OP(kInventoryFindObjectByName, inventoryFindObjectByName) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 8e35e9e8259..cfe9835a534 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1753,15 +1753,15 @@ void Process::objectFreePictureAndAnimation() {
}
}
-void Process::stub235() {
+void Process::fadeScreen() {
int fadeMusic = pop();
int fadeSound = pop();
int fadeScreen = pop();
- debug("stub235 (fadeScreen) screen: %d, sound: %d music: %d", fadeScreen, fadeSound, fadeMusic);
- _engine->getSystemVariable("screen_curtain")->setInteger(fadeScreen);
- _engine->getSystemVariable("sound_curtain")->setInteger(fadeSound);
- _engine->getSystemVariable("music_curtain")->setInteger(fadeMusic);
- _engine->enableSystemUser(true);
+ debug("fadeScreen screen: %d, sound: %d music: %d", fadeScreen, fadeSound, fadeMusic);
+ _engine->curtain(getName(), fadeScreen, fadeSound, fadeMusic);
+ deactivate();
+ if (passive())
+ suspend();
}
void Process::setCharacterNotifyVars() {
Commit: 669bbd5e8a9a96ba65234d3b4796493b9a115122
https://github.com/scummvm/scummvm/commit/669bbd5e8a9a96ba65234d3b4796493b9a115122
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:05+01:00
Commit Message:
AGDS: deactivate/activate process before/after move
Changed paths:
engines/agds/character.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 43ae5c7491f..ec44c92bc91 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -226,8 +226,7 @@ void Character::tick(bool reactivate) {
_animation->scale(scale);
if (_phase >= 0 && _phase < _frames) {
- if (_jokes)
- _animation->tick();
+ _animation->tick();
_phase = _animation->phase();
if (_phase >= _frames) {
bool wasJokes = _jokes;
@@ -236,11 +235,11 @@ void Character::tick(bool reactivate) {
_frames = 0;
if (wasJokes)
direction(_direction);
+ if (reactivate && !_processName.empty())
+ _engine->reactivate(_processName, "Character::tick");
}
}
}
- if (reactivate && !_processName.empty())
- _engine->reactivate(_processName, "Character::tick");
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index cfe9835a534..cc79b558768 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1521,6 +1521,7 @@ void Process::moveCharacter(bool usermove) {
auto region = _engine->loadRegion(regionName);
if (region) {
character->moveTo(_object->getName(), region->center, direction);
+ deactivate();
suspend();
}
} else
Commit: 9227d2425fd6a45cb5a78671f45847d54f563ef1
https://github.com/scummvm/scummvm/commit/9227d2425fd6a45cb5a78671f45847d54f563ef1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:05+01:00
Commit Message:
AGDS: allow string to reactivate
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index e2fe219ea7d..48f76f0f873 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1367,14 +1367,14 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
}
-void AGDSEngine::reactivate(const Common::String &name, const char *where, bool runNow) {
+void AGDSEngine::reactivate(const Common::String &name, const Common::String &where, bool runNow) {
if (name.empty())
return;
for(uint i = 0; i < _processes.size(); ++i) {
ProcessPtr &process = _processes[i];
if (process && process->getName() == name) {
- debug("reactivate %s now: %d, %s", name.c_str(), runNow, where);
+ debug("reactivate %s now: %d, %s", name.c_str(), runNow, where.c_str());
process->activate();
if (runNow)
process->run();
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 9ce84f5419e..1716ddaddd9 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -125,7 +125,7 @@ public:
void runProcess(const ObjectPtr &object, uint ip = 0);
void stopProcess(const Common::String & name);
void stopProcessForObject(const Common::String & name);
- void reactivate(const Common::String &name, const char *where, bool runNow = false);
+ void reactivate(const Common::String &name, const Common::String &where, bool runNow = false);
bool hasActiveProcesses(const Common::String &name) const;
void resetCurrentScreen();
Commit: 2569cd3ec3bcf1705005afd5095460a96c3ff9da
https://github.com/scummvm/scummvm/commit/2569cd3ec3bcf1705005afd5095460a96c3ff9da
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:05+01:00
Commit Message:
AGDS: suspend process that plays sync sound without phase var
Changed paths:
engines/agds/process_opcodes.cpp
engines/agds/soundManager.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index cc79b558768..c60134ffdc1 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -165,9 +165,15 @@ void Process::loadAnimation() {
void Process::loadSample() {
Common::String name = popString();
debug("loadSample %s, phaseVar: %s, ambient: %d, volume: %d", name.c_str(), _phaseVar.c_str(), _sampleAmbient, _sampleVolume);
- int id = _engine->soundManager().play(getName(), name, _engine->loadText(name), _phaseVar, _sampleAmbient || !_phaseVarControlled || _phaseVar.empty(), _sampleVolume, 0, -1, _sampleAmbient);
+ bool playNow = _sampleAmbient || !_phaseVarControlled || _phaseVar.empty();
+ int id = _engine->soundManager().play(getName(), name, _engine->loadText(name), _phaseVar, playNow, _sampleVolume, 0, -1, _sampleAmbient);
if (_sampleAmbient)
_engine->setAmbientSoundId(id);
+ // original engine sets timer to 24 * bitrate / 44100 / 4
+ if (playNow && _phaseVar.empty()) {
+ deactivate();
+ suspend();
+ }
}
void Process::getSampleVolume() {
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index b0f8f14e186..2490ed375d2 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -57,7 +57,7 @@ void SoundManager::tick() {
}
++it;
} else if (!active) {
- _engine->reactivate(sound.process, "sound inactive");
+ _engine->reactivate(sound.process, "sound " + sound.resource + " inactive", true);
it = _sounds.erase(it);
} else
++it;
Commit: f3a68676ef96f4bb7bfcbe5610d66135f835a96e
https://github.com/scummvm/scummvm/commit/f3a68676ef96f4bb7bfcbe5610d66135f835a96e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:06+01:00
Commit Message:
AGDS: reenabled attached object animation
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 48f76f0f873..064686d5c44 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -747,17 +747,6 @@ Common::Error AGDSEngine::run() {
mouseCursor = _defaultMouseCursor;
if (userEnabled()) {
-#if 0
- //FIXME: fixes planet puzzle but breaks all other objects.
- // maybe use this only when used in conjunction with attachInventoryObjectToMouse?
- if (auto *cursor = _currentInventoryObject? _currentInventoryObject->getMouseCursor(): nullptr) {
- cursor->tick();
- auto pos = _mouse;
- pos.x -= cursor->visibleCenter();
- pos.y -= cursor->visibleHeight() / 2;
- cursor->paint(*backbuffer, pos);
- } else
-#endif
if (auto *picture = _currentInventoryObject? _currentInventoryObject->getPicture(): nullptr) {
Common::Rect srcRect = picture->getRect();
Common::Point dst = _mouse;
@@ -767,6 +756,12 @@ Common::Error AGDSEngine::run() {
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer->getRect())) {
picture->blit(*backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
}
+ } else if (auto *cursor = (_currentInventoryObject? _currentInventoryObject->getMouseCursor(): nullptr)) {
+ cursor->tick();
+ auto pos = _mouse;
+ pos.x -= cursor->visibleCenter();
+ pos.y -= cursor->visibleHeight() / 2;
+ cursor->paint(*backbuffer, pos);
} else if (mouseCursor) {
mouseCursor->tick();
mouseCursor->paint(*backbuffer, _mouse);
Commit: d62609c9cb714c8696e2753f3ad6f93a94b33baa
https://github.com/scummvm/scummvm/commit/d62609c9cb714c8696e2753f3ad6f93a94b33baa
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:06+01:00
Commit Message:
AGDS: implement bidirectional fading
Move fading code to Screen
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 064686d5c44..52d6fa2031f 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -68,6 +68,7 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_syncSoundId(-1),
_ambientSoundId(-1),
_curtainTimer(-1),
+ _curtainScreen(0),
_fastMode(true),
_hintMode(false) {
}
@@ -426,14 +427,17 @@ void AGDSEngine::newGame() {
runObject(init);
}
-void AGDSEngine::curtain(const Common::String &process, int screen, int sound, int music) {
+void AGDSEngine::curtain(const Common::String &process, int screen, int sound, int music, bool updateGlobals) {
assert(!process.empty());
+ if (updateGlobals) {
+ getSystemVariable("screen_curtain")->setInteger(screen >= 0? screen: -screen);
+ getSystemVariable("sound_curtain")->setInteger(sound >= 0? sound: -sound);
+ getSystemVariable("music_curtain")->setInteger(music >= 0? music: -music);
+ }
_curtainProcess = process;
_curtainTimer = 100;
+ _curtainScreen = screen;
enableSystemUser(false);
- getSystemVariable("screen_curtain")->setInteger(screen);
- getSystemVariable("sound_curtain")->setInteger(sound);
- getSystemVariable("music_curtain")->setInteger(music);
}
void AGDSEngine::tick() {
@@ -789,6 +793,13 @@ Common::Error AGDSEngine::run() {
_textLayout.paint(*this, *backbuffer);
}
+ if (_curtainTimer != -1 && _currentScreen) {
+ if (_curtainScreen > 0)
+ _currentScreen->fade(100 - _curtainTimer);
+ else if (_curtainScreen < 0)
+ _currentScreen->fade(_curtainTimer);
+ }
+
_system->unlockScreen();
_system->updateScreen();
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 1716ddaddd9..a1191043537 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -273,7 +273,7 @@ public:
}
int getRandomNumber(int max);
- void curtain(const Common::String &process, int screen, int sound, int music);
+ void curtain(const Common::String &process, int screen, int sound, int music, bool updateGlobals);
private:
void stopAmbientSound();
@@ -346,6 +346,7 @@ private:
Common::String _curtainProcess;
int _curtainTimer;
+ int _curtainScreen;
bool _fastMode;
bool _hintMode;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c60134ffdc1..b21220fb9d3 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1765,7 +1765,7 @@ void Process::fadeScreen() {
int fadeSound = pop();
int fadeScreen = pop();
debug("fadeScreen screen: %d, sound: %d music: %d", fadeScreen, fadeSound, fadeMusic);
- _engine->curtain(getName(), fadeScreen, fadeSound, fadeMusic);
+ _engine->curtain(getName(), fadeScreen, fadeSound, fadeMusic, true);
deactivate();
if (passive())
suspend();
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 067322b6bfc..8657847a6cf 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -44,7 +44,7 @@ Screen::Screen(AGDSEngine * engine, ObjectPtr object, ScreenLoadingType loadingT
_engine(engine), _object(object), _background(nullptr),
_name(object->getName()), _loadingType(loadingType), _previousScreen(prevScreen),
_children(&ObjectZCompare), _animations(&AnimationZCompare), _applyingPatch(false),
- _characterNear(g_system->getHeight()), _characterFar(g_system->getHeight()) {
+ _characterNear(g_system->getHeight()), _characterFar(g_system->getHeight()), _fade(0) {
add(object);
}
@@ -254,6 +254,22 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
error("invalid logic in z-sort");
}
}
+ if (_fade != 0) {
+ auto alpha = (100 - _fade) * 256 / 100;
+ auto & format = backbuffer.format;
+ for(int y = 0; y < backbuffer.h; ++y) {
+ uint32 * line = (uint32 *)backbuffer.getBasePtr(0, y);
+ int w = backbuffer.w;
+ while(w--) {
+ uint8 r, g, b;
+ format.colorToRGB(*line, r, g, b);
+ r = (r * alpha) >> 8;
+ g = (g * alpha) >> 8;
+ b = (b * alpha) >> 8;
+ *line++ = format.RGBToColor(r, g, b);
+ }
+ }
+ }
}
Common::Array<ObjectPtr> Screen::find(Common::Point pos) const {
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index ed2e28c0d25..e1c81cb7065 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -64,6 +64,7 @@ class Screen {
RegionPtr _region;
bool _applyingPatch;
int _characterNear, _characterFar;
+ int _fade;
public:
struct KeyHandler {
@@ -77,6 +78,14 @@ public:
Screen(AGDSEngine *engine, ObjectPtr object, ScreenLoadingType loadingType, const Common::String &prevScreen);
~Screen();
+ int fade() const {
+ return _fade;
+ }
+
+ void fade(int fade) {
+ _fade = fade;
+ }
+
void setCharacterNearFar(int near, int far) {
_characterNear = near;
_characterFar = far;
Commit: f69cf0995eb07da497974ae22f577cfa878a148f
https://github.com/scummvm/scummvm/commit/f69cf0995eb07da497974ae22f577cfa878a148f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:06+01:00
Commit Message:
AGDS: do not run processes started by other screens
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 52d6fa2031f..e090567420f 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -386,7 +386,7 @@ void AGDSEngine::resetCurrentScreen() {
void AGDSEngine::runProcesses() {
for (uint i = 0; i < _processes.size(); ++i) {
ProcessPtr process = _processes[i];
- if (!process)
+ if (!process || process->parentScreenName() != _currentScreenName)
continue;
if (process->active()) {
Commit: 12e1d652a7bb8d542969a7b53c7143dd81a4db14
https://github.com/scummvm/scummvm/commit/12e1d652a7bb8d542969a7b53c7143dd81a4db14
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:06+01:00
Commit Message:
AGDS: better phase boundaries check
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index ec44c92bc91..820f9c28126 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -254,7 +254,7 @@ void Character::paint(Graphics::Surface &backbuffer, Common::Point pos) const {
if (_description) {
auto &frames = _description->frames;
- if (_phase < frames.size()) {
+ if (_phase >= 0 && _phase < static_cast<int>(frames.size())) {
auto &frame = frames[_phase];
pos.x += frame.x * _animation->scale();
pos.y += frame.y * _animation->scale();
Commit: 026f2345c804277b4774b132d5ffe77f25023395
https://github.com/scummvm/scummvm/commit/026f2345c804277b4774b132d5ffe77f25023395
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:06+01:00
Commit Message:
AGDS: better handling of character stopped flag, handle direction == -1 case
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 820f9c28126..5f8ee616381 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -174,7 +174,10 @@ void Character::moveTo(const Common::String & processName, Common::Point dst, in
}
void Character::animate(int direction, int speed, bool jokes) {
- if (direction == -1)
+ if (_stopped)
+ _stopped = false;
+
+ if (direction == -1 || !_enabled)
return;
_description = nullptr;
@@ -211,6 +214,10 @@ void Character::animate(const Common::String & processName, Common::Point pos, i
void Character::stop(const Common::String &processName) {
debug("character %s: stop, process: %s", _object->getName().c_str(), processName.c_str());
_processName = processName;
+ stop();
+}
+
+void Character::stop() {
_stopped = true;
}
diff --git a/engines/agds/character.h b/engines/agds/character.h
index a063aa84182..390d005f724 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -104,13 +104,14 @@ public:
}
bool active() const {
- return _enabled && _visible;
+ return _enabled && _visible && !_stopped;
}
void animate(const Common::String &processName, Common::Point pos, int direction, int speed);
void animate(int direction, int speed, bool jokes);
void stop(const Common::String &processName);
+ void stop();
void leave(const Common::String &processName);
int getPhase() const {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index b21220fb9d3..346a4cb4da2 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1674,7 +1674,10 @@ void Process::stopCharacter() {
if (direction != -1) {
character->direction(direction);
character->stop(getName());
+ deactivate();
suspend();
+ } else {
+ character->stop();
}
} else
warning("could not find character %s", name.c_str());
Commit: a4973624e72e9534dab3e169319ae5c12c9a6e85
https://github.com/scummvm/scummvm/commit/a4973624e72e9534dab3e169319ae5c12c9a6e85
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:06+01:00
Commit Message:
AGDS: only suspend parent process if animation started
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 5f8ee616381..41addd904fe 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -138,27 +138,27 @@ void Character::saveState(Common::WriteStream* stream) const {
}
-void Character::direction(int dir) {
+bool Character::direction(int dir) {
debug("setDirection %d", dir);
_direction = dir;
if (dir < 0)
- return;
+ return false;
if (_jokes && _phase < _frames) {
debug("direction(%d) set during active animation, ignored", dir);
- return;
+ return false;
}
_animationPos = Common::Point();
- animate(dir, 100, false);
+ return animate(dir, 100, false);
}
-void Character::moveTo(const Common::String & processName, Common::Point dst, int dir) {
+bool Character::moveTo(const Common::String & processName, Common::Point dst, int dir) {
debug("character move %d,%d %d", dst.x, dst.y, dir);
_processName = processName;
_pos = dst;
_visible = true;
- direction(dir);
+ bool r = direction(dir);
auto *screen = _engine->getCurrentScreen();
if (screen) {
@@ -171,14 +171,15 @@ void Character::moveTo(const Common::String & processName, Common::Point dst, in
}
}
}
+ return r;
}
-void Character::animate(int direction, int speed, bool jokes) {
+bool Character::animate(int direction, int speed, bool jokes) {
if (_stopped)
_stopped = false;
if (direction == -1 || !_enabled)
- return;
+ return false;
_description = nullptr;
_visible = true;
@@ -188,7 +189,7 @@ void Character::animate(int direction, int speed, bool jokes) {
auto animation = _description? _engine->loadAnimation(_description->filename): nullptr;
if (!animation) {
warning("no %s animation %d", jokes? "jokes": "character", direction);
- return;
+ return false;
}
_animation = animation;
_animation->speed(speed);
@@ -201,14 +202,15 @@ void Character::animate(int direction, int speed, bool jokes) {
else
_direction = direction;
debug("character animation frames: %d, enabled: %d, visible: %d", _frames, _enabled, _visible);
+ return true;
}
-void Character::animate(const Common::String & processName, Common::Point pos, int direction, int speed) {
+bool Character::animate(const Common::String & processName, Common::Point pos, int direction, int speed) {
debug("animate character: %d,%d %d %d", pos.x, pos.y, direction, speed);
_processName = processName;
_animationPos = pos;
- animate(direction, speed, true);
+ return animate(direction, speed, true);
}
void Character::stop(const Common::String &processName) {
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 390d005f724..56363029a9b 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -107,8 +107,8 @@ public:
return _enabled && _visible && !_stopped;
}
- void animate(const Common::String &processName, Common::Point pos, int direction, int speed);
- void animate(int direction, int speed, bool jokes);
+ bool animate(const Common::String &processName, Common::Point pos, int direction, int speed);
+ bool animate(int direction, int speed, bool jokes);
void stop(const Common::String &processName);
void stop();
@@ -126,9 +126,9 @@ public:
return _pos;
}
- void moveTo(const Common::String &processName, Common::Point dst, int direction);
+ bool moveTo(const Common::String &processName, Common::Point dst, int direction);
- void direction(int dir);
+ bool direction(int dir);
int direction() const {
return _jokes? _jokesDirection: _direction;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 346a4cb4da2..3533134f6ab 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1526,9 +1526,10 @@ void Process::moveCharacter(bool usermove) {
if (character) {
auto region = _engine->loadRegion(regionName);
if (region) {
- character->moveTo(_object->getName(), region->center, direction);
- deactivate();
- suspend();
+ if (character->moveTo(_object->getName(), region->center, direction)) {
+ deactivate();
+ suspend();
+ }
}
} else
warning("character %s could not be found", id.c_str());
Commit: cf4a99e15592d9d62085aa8c974bd30d080744c6
https://github.com/scummvm/scummvm/commit/cf4a99e15592d9d62085aa8c974bd30d080744c6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:06+01:00
Commit Message:
AGDS: promote patch-related failures to warnings
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 3533134f6ab..da8e042429e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -781,7 +781,7 @@ void Process::screenObjectPatchIncRef() {
debug("screenObjectPatchIncRef: %s %s", screenName.c_str(), objectName.c_str());
if (!screenName.empty() && screenName != _engine->getCurrentScreenName()) {
if (_engine->getCurrentScreen()->applyingPatch()) {
- debug("attempt to change screen patch (%s) in patching process (%s)", objectName.c_str(), screenName.c_str());
+ warning("attempt to change screen patch (%s) in patching process (%s)", objectName.c_str(), screenName.c_str());
} else {
//fixme: add non-existent screen check?
auto patch = _engine->createPatch(screenName);
@@ -800,7 +800,7 @@ void Process::screenObjectPatchDecRef() {
if (!screenName.empty() && screenName != _engine->getCurrentScreenName()) {
debug("screenObjectPatchDecRef %s %s", screenName.c_str(), objectName.c_str());
if (_engine->getCurrentScreen()->applyingPatch()) {
- debug("attempt to change screen patch (%s) in patching process (%s)", objectName.c_str(), screenName.c_str());
+ warning("attempt to change screen patch (%s) in patching process (%s)", objectName.c_str(), screenName.c_str());
} else {
//fixme: add non-existent screen check?
auto patch = _engine->getPatch(screenName);
Commit: 41ca1b0e09cd4cd9f381d75d4241956fd9fd2127
https://github.com/scummvm/scummvm/commit/41ca1b0e09cd4cd9f381d75d4241956fd9fd2127
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:06+01:00
Commit Message:
AGDS: remove _loadingScreen flag
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index e090567420f..86bcc0a8fd4 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -52,7 +52,7 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_shadowIntensity(0),
_processes(MaxProcesses),
_mjpgPlayer(), _filmStarted(0),
- _currentScreen(), _loadingScreen(false),
+ _currentScreen(),
_currentCharacter(),
_defaultMouseCursor(),
_nextScreenType(ScreenLoadingType::Normal),
@@ -330,7 +330,6 @@ void AGDSEngine::saveScreenPatch() {
void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadingType, bool savePatch) {
- _loadingScreen = true;
debug("loadScreen %s [type: %d, save patch: %d, previous: %s]", name.c_str(), static_cast<int>(loadingType), savePatch, _currentScreenName.c_str());
if (savePatch)
saveScreenPatch();
@@ -368,7 +367,6 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
if (!patch->defaultMouseCursor.empty())
loadDefaultMouseCursor(patch->defaultMouseCursor);
}
- _loadingScreen = false;
}
void AGDSEngine::resetCurrentScreen() {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index a1191043537..a7436b87660 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -315,7 +315,6 @@ private:
Common::String _filmProcess;
Screen * _currentScreen;
Common::String _currentScreenName;
- bool _loadingScreen;
Character * _currentCharacter;
Character * _jokes;
Common::String _currentCharacterName, _currentCharacterFilename, _currentCharacterObject;
Commit: 4b8df38eab044c197ef3ae2857a3546efbfa1ecd
https://github.com/scummvm/scummvm/commit/4b8df38eab044c197ef3ae2857a3546efbfa1ecd
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:06+01:00
Commit Message:
AGDS: do not store screen object in patch, so it won't be double-loaded
Changed paths:
engines/agds/screen.cpp
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 8657847a6cf..ec5d6dc51cb 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -308,7 +308,9 @@ void Screen::load(const PatchPtr &patch) {
for(uint i = 0; i < patch->objects.size(); ++i) {
const Patch::Object &object = patch->objects[i];
debug("patch object %s %d", object.name.c_str(), object.flag);
- if (object.flag <= 0)
+ if (object.name == _name)
+ continue;
+ else if (object.flag <= 0)
remove(object.name);
else
_engine->runObject(object.name, Common::String(), false);
@@ -326,7 +328,7 @@ void Screen::save(const PatchPtr &patch) {
patch->objects.clear();
for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr object = *i;
- if (!object->persistent() || !object->alive())
+ if (!object->persistent() || !object->alive() || object->getName() == _name)
continue;
debug("saving patch object %s %d", object->getName().c_str(), object->alive());
patch->objects.push_back(Patch::Object(object->getName(), 1));
Commit: 91ac0ee844460e6e38cea7afb61e86d4a58bce24
https://github.com/scummvm/scummvm/commit/91ac0ee844460e6e38cea7afb61e86d4a58bce24
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:06+01:00
Commit Message:
AGDS: processes which require reactivation put in a queue
sound manager is not really reentrant, so if anything calls stopAll()
it crashes sound manager with double-free
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/animation.cpp
engines/agds/soundManager.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 86bcc0a8fd4..59d722e06ea 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1381,7 +1381,17 @@ void AGDSEngine::reactivate(const Common::String &name, const Common::String &wh
debug("reactivate %s now: %d, %s", name.c_str(), runNow, where.c_str());
process->activate();
if (runNow)
- process->run();
+ _pendingReactivatedProcesses.push_back(process);
+ }
+ }
+}
+
+void AGDSEngine::runPendingReactivatedProcesses() {
+ while(!_pendingReactivatedProcesses.empty()) {
+ ProcessListType processes;
+ _pendingReactivatedProcesses.swap(processes);
+ for(auto & process : processes) {
+ process->run();
}
}
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index a7436b87660..f028b805219 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -127,6 +127,7 @@ public:
void stopProcessForObject(const Common::String & name);
void reactivate(const Common::String &name, const Common::String &where, bool runNow = false);
bool hasActiveProcesses(const Common::String &name) const;
+ void runPendingReactivatedProcesses();
void resetCurrentScreen();
void loadScreen(const Common::String & name, ScreenLoadingType type, bool savePatch = true);
@@ -298,6 +299,7 @@ private:
int _pictureCacheId;
FontsType _fonts;
ProcessListType _processes;
+ ProcessListType _pendingReactivatedProcesses;
PatchesType _patches;
ObjectPatchesType _objectPatches;
int _sharedStorageIndex;
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 9750cd2437d..0b2a4972ffb 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -216,10 +216,13 @@ bool Animation::tick() {
}
if (eov && !_loop && --_cycles <= 0) {
- if (!_phaseVar.empty())
+ if (!_phaseVar.empty()) {
_engine->setGlobal(_phaseVar, _phase - 1);
- else
+ } else {
_engine->reactivate(_process, "animation end", true);
+ _engine->runPendingReactivatedProcesses();
+ }
+
return false;
}
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 2490ed375d2..9ec4fc7ed46 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -62,6 +62,7 @@ void SoundManager::tick() {
} else
++it;
}
+ _engine->runPendingReactivatedProcesses();
}
const Sound *SoundManager::find(int id) const {
Commit: b2ed2db31036ca0932cf338f7c4ec869f203be82
https://github.com/scummvm/scummvm/commit/b2ed2db31036ca0932cf338f7c4ec869f203be82
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:07+01:00
Commit Message:
AGDS: reset current screen before loading object
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 59d722e06ea..1dbd5916e27 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -352,6 +352,7 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
}
_currentScreenName = name;
+ _currentScreen = nullptr;
auto screenObject = loadObject(name, Common::String(), !hasScreenPatch);
_currentScreen = new Screen(this, screenObject, loadingType, previousScreenName);
Commit: 20b0c62dbec730e2caa6d512c47932e9f50bd179
https://github.com/scummvm/scummvm/commit/20b0c62dbec730e2caa6d512c47932e9f50bd179
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:07+01:00
Commit Message:
AGDS: match mouse area management/id allocation to original engine
Changed paths:
engines/agds/agds.cpp
engines/agds/mouseMap.cpp
engines/agds/mouseMap.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 1dbd5916e27..bb5f22e2e7d 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1217,7 +1217,6 @@ Common::Error AGDSEngine::loadGameState(int slot) {
_systemVars[name]->read(agds_d.get());
}
}
- _mouseMap.clear();
SystemVariable *initVar = getSystemVariable("init_resources");
runObject(initVar->getString());
diff --git a/engines/agds/mouseMap.cpp b/engines/agds/mouseMap.cpp
index c78c861a8f2..2d99664ea3f 100644
--- a/engines/agds/mouseMap.cpp
+++ b/engines/agds/mouseMap.cpp
@@ -2,45 +2,54 @@
#include "agds/agds.h"
#include "agds/region.h"
#include "agds/object.h"
+#include <utility>
namespace AGDS {
-int MouseMap::add(const MouseRegion & area) {
- int id = _nextId++;
- _mouseRegions.push_back(area);
- _mouseRegions.back().id = id;
+int MouseMap::findFree() const {
+ for(int i = 0, n = _mouseRegions.size(); i != n; ++i) {
+ auto & region = _mouseRegions[i];
+ if (!region)
+ return i;
+ }
+ error("no mouse region available");
+}
+
+
+int MouseMap::add(MouseRegion area) {
+ auto id = findFree();
+ auto & region = _mouseRegions[id];
+ region.reset(new MouseRegion(std::move(area)));
+ region->id = id;
return id;
}
MouseRegion *MouseMap::find(Common::Point pos) {
if (_disabled)
- return NULL;
- for (MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i) {
- MouseRegion &mouse = *i;
- if (mouse.enabled && mouse.region->pointIn(pos))
- return &mouse;
+ return nullptr;
+ for (auto & region : _mouseRegions) {
+ if (region && region->enabled && region->region->pointIn(pos))
+ return region.get();
}
- return NULL;
+ return nullptr;
}
MouseRegion *MouseMap::find(int id) {
- for (MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i) {
- MouseRegion &mouse = *i;
- if (mouse.id == id)
- return &mouse;
+ for (auto & region : _mouseRegions) {
+ if (region && region->id == id)
+ return region.get();
}
- return NULL;
+ return nullptr;
}
void MouseMap::remove(AGDSEngine *engine, int id) {
- for (MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end();) {
- MouseRegion &mouse = *i;
- if (mouse.id == id) {
- i->disable(engine);
- i = _mouseRegions.erase(i);
- } else
- ++i;
+ auto ®ion = _mouseRegions[id];
+ if (!region) {
+ warning("removing non-existent mouse region %d", id);
+ return;
}
+ region->disable(engine);
+ region.reset();
}
void MouseRegion::show(AGDSEngine *engine) {
@@ -62,8 +71,9 @@ void MouseRegion::hide(AGDSEngine *engine) {
}
void MouseMap::hideAll(AGDSEngine *engine) {
- for (MouseRegionsType::iterator i = _mouseRegions.begin(); i != _mouseRegions.end(); ++i)
- i->hide(engine);
+ for (auto & region : _mouseRegions)
+ if (region)
+ region->hide(engine);
}
} // End of namespace AGDS
diff --git a/engines/agds/mouseMap.h b/engines/agds/mouseMap.h
index 182aa9ec46a..9b4850f94bc 100644
--- a/engines/agds/mouseMap.h
+++ b/engines/agds/mouseMap.h
@@ -23,7 +23,7 @@
#ifndef AGDS_MOUSE_MAP_H
#define AGDS_MOUSE_MAP_H
-#include "common/list.h"
+#include "common/array.h"
#include "common/ptr.h"
#include "common/rect.h"
#include "common/str.h"
@@ -35,10 +35,10 @@ struct Region;
typedef Common::SharedPtr<Region> RegionPtr;
struct MouseRegion {
- int id;
- RegionPtr region;
- bool enabled;
- bool visible;
+ int id = -1;
+ RegionPtr region = nullptr;
+ bool enabled = true;
+ bool visible = false;
Common::String onEnter;
Common::String onLeave;
@@ -52,22 +52,24 @@ struct MouseRegion {
hide(engine);
}
+ MouseRegion()
+ { }
+
MouseRegion(RegionPtr reg, const Common::String &enter, const Common::String &leave):
- id(-1), region(reg), enabled(1), visible(false), onEnter(enter), onLeave(leave) {
+ region(reg), onEnter(enter), onLeave(leave) {
}
void hide(AGDSEngine * engine);
void show(AGDSEngine * engine);
};
+using MouseRegionPtr = Common::ScopedPtr<MouseRegion>;
class MouseMap {
- typedef Common::List<MouseRegion> MouseRegionsType;
- MouseRegionsType _mouseRegions;
- int _nextId;
- bool _disabled;
+ Common::Array<MouseRegionPtr> _mouseRegions;
+ bool _disabled;
public:
- MouseMap(): _nextId(0), _disabled(false) { }
+ MouseMap(): _mouseRegions(100), _disabled(false) { }
void disable(AGDSEngine * engine, bool disabled) {
_disabled = disabled;
@@ -79,14 +81,12 @@ public:
return _disabled;
}
- int add(const MouseRegion & area);
+ int findFree() const;
+ int add(MouseRegion area);
void remove(AGDSEngine *engine, int id);
void hideAll(AGDSEngine *engine);
- void clear() {
- _mouseRegions.clear();
- }
MouseRegion * find(Common::Point pos);
MouseRegion * find(int id);
};
Commit: 77b0a19d8f1cfd0196b9fb17ba6578c3600c90a7
https://github.com/scummvm/scummvm/commit/77b0a19d8f1cfd0196b9fb17ba6578c3600c90a7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:07+01:00
Commit Message:
AGDS: save before suspend
Changed paths:
engines/agds/process.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 6360960bacc..325f03ee866 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -293,9 +293,6 @@ void Process::run() {
restart = true;
break;
case kExitCodeSaveGame:
- if (_engine->saveGameState(getExitIntArg1(), "").getCode() != Common::kNoError) {
- warning("failed to save game");
- }
break;
default:
error("unknown process exit code %d", code);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index da8e042429e..86c90fc78ae 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -876,7 +876,10 @@ void Process::loadGame() {
void Process::saveGame() {
int saveSlot = pop();
debug("saveGame %d", saveSlot);
- suspend(kExitCodeSaveGame, saveSlot);
+ if (_engine->saveGameState(saveSlot, "").getCode() != Common::kNoError) {
+ warning("failed to save game");
+ }
+ suspend(kExitCodeSaveGame);
}
void Process::getSaveGameName() {
Commit: 8c3939c505d1740827c06c909b8263a5e24c44eb
https://github.com/scummvm/scummvm/commit/8c3939c505d1740827c06c909b8263a5e24c44eb
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:07+01:00
Commit Message:
AGDS: implement new APIs in ArchiveMember
Changed paths:
engines/agds/resourceManager.h
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 624331d050d..c0b4d7fd085 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -50,8 +50,14 @@ private:
ArchiveMember(GrpFile * parent, const Common::String &name, uint32 offset, uint32 size):
_parent(parent), _name(name), _offset(offset), _size(size) {
}
- virtual Common::SeekableReadStream *createReadStream() const;
- virtual Common::String getName() const {
+ Common::SeekableReadStream *createReadStream() const override;
+ Common::String getName() const override {
+ return getFileName();
+ }
+ Common::Path getPathInArchive() const override {
+ return _name;
+ }
+ Common::String getFileName() const override {
return _name;
}
};
Commit: 79e5409cd4acfbcd8c01512f2990f1b9bcff6ca2
https://github.com/scummvm/scummvm/commit/79e5409cd4acfbcd8c01512f2990f1b9bcff6ca2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:07+01:00
Commit Message:
AGDS: do not blit empty glyphs
Changed paths:
engines/agds/font.cpp
diff --git a/engines/agds/font.cpp b/engines/agds/font.cpp
index 01e7ea1053e..63c35c0a5d8 100644
--- a/engines/agds/font.cpp
+++ b/engines/agds/font.cpp
@@ -32,7 +32,8 @@ void Font::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 col
Common::Rect srcRect(getCharWidth(chr), _glyphH);
srcRect.moveTo(_cellW * (chr & 0x0f), _cellH * (chr >> 4));
- _surface->blit(*dst, x, y, Graphics::FLIP_NONE, &srcRect);
+ if (!srcRect.isEmpty())
+ _surface->blit(*dst, x, y, Graphics::FLIP_NONE, &srcRect);
}
} // namespace AGDS
Commit: fb859b6fef121c1f7dbe12512af9698ac280886e
https://github.com/scummvm/scummvm/commit/fb859b6fef121c1f7dbe12512af9698ac280886e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:07+01:00
Commit Message:
AGDS: rewrite mouse area handling to be closer to the original engine
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/mouseMap.cpp
engines/agds/mouseMap.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index bb5f22e2e7d..aab58666de1 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -58,7 +58,6 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
_nextScreenType(ScreenLoadingType::Normal),
_mouse(400, 300),
_userEnabled(true), _systemUserEnabled(true),
- _currentRegion(),
_random("agds"),
_inventoryRegion(),
_soundManager(this, system->getMixer()),
@@ -371,11 +370,6 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
}
void AGDSEngine::resetCurrentScreen() {
- if (_currentRegion) {
- _currentRegion->hide(this);
- _currentRegion = NULL;
- }
-
delete _currentScreen;
_currentScreen = NULL;
_currentScreenName.clear();
@@ -483,19 +477,12 @@ void AGDSEngine::changeMouseArea(int id, int enabled) {
break;
case 0:
debug("disabling mouse area %d", id);
- if (_currentRegion) {
- _currentRegion->hide(this);
- _currentRegion = NULL;
- }
- mouseArea->disable(this);
+ mouseArea->hide(this);
+ mouseArea->disable();
break;
case -1:
debug("removing mouse area %d", id);
- if (_currentRegion) {
- _currentRegion->hide(this);
- _currentRegion = NULL;
- }
- _mouseMap.remove(this, id);
+ _mouseMap.remove(id);
break;
default:
warning("invalid value for changeMouseArea: %d", enabled);
@@ -573,30 +560,7 @@ Common::Error AGDSEngine::run() {
case Common::EVENT_MOUSEMOVE:
_mouse = event.mouse;
- if (userEnabled()) {
- MouseRegion *region = _mouseMap.find(_mouse);
- if (region != _currentRegion) {
- if (_currentRegion) {
- MouseRegion *currentRegion = _currentRegion;
- _currentRegion = NULL;
- currentRegion->hide(this);
- }
-
- if (region) {
- _currentRegion = region;
- region->show(this);
- }
- }
- if (_inventoryRegion && _inventory.enabled()) {
- if (_mouseMap.disabled()) {
- _inventory.visible(false);
- } else {
- if (_userEnabled) {
- _inventory.visible(_inventoryRegion->pointIn(_mouse));
- }
- }
- }
- }
+ _mouseMap.hideInactive(this, _mouse);
break;
case Common::EVENT_LBUTTONDOWN:
case Common::EVENT_RBUTTONDOWN:
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index f028b805219..69f816481fc 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -325,7 +325,6 @@ private:
Common::String _defaultMouseCursorName;
Animation * _defaultMouseCursor;
Common::Point _mouse;
- MouseRegion * _currentRegion;
bool _userEnabled;
bool _systemUserEnabled;
MouseMap _mouseMap;
diff --git a/engines/agds/mouseMap.cpp b/engines/agds/mouseMap.cpp
index 2d99664ea3f..a9d9d1ccf36 100644
--- a/engines/agds/mouseMap.cpp
+++ b/engines/agds/mouseMap.cpp
@@ -24,14 +24,22 @@ int MouseMap::add(MouseRegion area) {
return id;
}
-MouseRegion *MouseMap::find(Common::Point pos) {
- if (_disabled)
- return nullptr;
+void MouseMap::hideInactive(AGDSEngine *engine, Common::Point pos) {
for (auto & region : _mouseRegions) {
- if (region && region->enabled && region->region->pointIn(pos))
- return region.get();
+ if (!region || !region->enabled)
+ continue;
+
+ if (_disabled) {
+ region->hide(engine);
+ } else if (engine->userEnabled()) {
+ if (!region->region->pointIn(pos)) {
+ region->hide(engine);
+ } else {
+ region->show(engine);
+ return;
+ }
+ }
}
- return nullptr;
}
MouseRegion *MouseMap::find(int id) {
@@ -42,13 +50,13 @@ MouseRegion *MouseMap::find(int id) {
return nullptr;
}
-void MouseMap::remove(AGDSEngine *engine, int id) {
+void MouseMap::remove(int id) {
auto ®ion = _mouseRegions[id];
if (!region) {
warning("removing non-existent mouse region %d", id);
return;
}
- region->disable(engine);
+ region->disable();
region.reset();
}
diff --git a/engines/agds/mouseMap.h b/engines/agds/mouseMap.h
index 9b4850f94bc..99764846332 100644
--- a/engines/agds/mouseMap.h
+++ b/engines/agds/mouseMap.h
@@ -47,9 +47,8 @@ struct MouseRegion {
enabled = true;
}
- void disable(AGDSEngine *engine) {
+ void disable() {
enabled = false;
- hide(engine);
}
MouseRegion()
@@ -83,11 +82,11 @@ public:
int findFree() const;
int add(MouseRegion area);
- void remove(AGDSEngine *engine, int id);
+ void remove(int id);
void hideAll(AGDSEngine *engine);
- MouseRegion * find(Common::Point pos);
+ void hideInactive(AGDSEngine *engine, Common::Point pos);
MouseRegion * find(int id);
};
Commit: b97c811d0b57bfb4f08a4889b1425f480a65724c
https://github.com/scummvm/scummvm/commit/b97c811d0b57bfb4f08a4889b1425f480a65724c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:07+01:00
Commit Message:
AGDS: add stub191 implementation
Changed paths:
engines/agds/mouseMap.h
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/mouseMap.h b/engines/agds/mouseMap.h
index 99764846332..b643be314cc 100644
--- a/engines/agds/mouseMap.h
+++ b/engines/agds/mouseMap.h
@@ -70,10 +70,8 @@ class MouseMap {
public:
MouseMap(): _mouseRegions(100), _disabled(false) { }
- void disable(AGDSEngine * engine, bool disabled) {
+ void disable(bool disabled) {
_disabled = disabled;
- if (disabled)
- hideAll(engine);
}
bool disabled() const {
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 88457b6964b..d1c0d407cc6 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -208,7 +208,7 @@ enum Opcode {
kSetObjectText = 188,
kInventoryFindObjectByName = 189,
kSetObjectScale = 190,
- kStub191 = 191,
+ kDisableMouseAreas = 191,
kObjectIgnoreRegion = 192,
kRemoveGapsFromInventory = 193,
kSampleAmbient = 194,
@@ -432,7 +432,7 @@ enum Opcode {
OP(kReturnCurrentInventoryObject, returnCurrentInventoryObject) \
OP(kSetObjectText, setObjectText) \
OP(kSetObjectScale, setObjectScale) \
- OP(kStub191, disableMouseAreas) \
+ OP(kDisableMouseAreas, disableMouseAreas) \
OP(kRemoveGapsFromInventory, removeGapsFromInventory) \
OP(kSampleAmbient, sampleAmbient) \
OP(kGetObjectPictureWidth, getObjectPictureWidth) \
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 86c90fc78ae..f713967f05d 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -965,7 +965,7 @@ void Process::setObjectScale() {
void Process::disableMouseAreas() {
int value = pop();
debug("disableMouseAreas %d", value);
- _engine->_mouseMap.disable(_engine, value > 0);
+ _engine->_mouseMap.disable(value > 0);
}
void Process::sampleAmbient() {
Commit: 447944f6dcd8c423f022a144581c17b05783bbc9
https://github.com/scummvm/scummvm/commit/447944f6dcd8c423f022a144581c17b05783bbc9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:07+01:00
Commit Message:
remove system user enable from leaveCharacter
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f713967f05d..a3b8dcbac91 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1588,7 +1588,6 @@ void Process::leaveCharacter(const Common::String &name, const Common::String &r
character->moveTo(getName(), region->center, dir);
} else
warning("character %s could not be found", name.c_str());
- _engine->enableSystemUser(true); //called from update_music_screen_sound_curtain
}
void Process::leaveCharacter() {
Commit: 8ea8ae9adf7b979e3474f519f1eed634b6f2e4cc
https://github.com/scummvm/scummvm/commit/8ea8ae9adf7b979e3474f519f1eed634b6f2e4cc
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:07+01:00
Commit Message:
AGDS: disable user before hiding mouse areas
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index aab58666de1..773fa3f9461 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -333,8 +333,13 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
if (savePatch)
saveScreenPatch();
resetCurrentInventoryObject();
- _inventory.visible(false);
- _mouseMap.hideAll(this);
+ {
+ bool userEnabled = _userEnabled;
+ _userEnabled = false;
+ _mouseMap.hideAll(this);
+ _inventory.visible(false);
+ _userEnabled = userEnabled;
+ }
auto previousScreenName = _currentScreenName;
resetCurrentScreen();
Commit: 1ac39ee45e867a3d10a4f268d117fdd1a16b4086
https://github.com/scummvm/scummvm/commit/1ac39ee45e867a3d10a4f268d117fdd1a16b4086
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:07+01:00
Commit Message:
AGDS: fix order of the mouse area deactivation
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 773fa3f9461..9f838550727 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -336,6 +336,7 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
{
bool userEnabled = _userEnabled;
_userEnabled = false;
+ debug("loadScreen: hiding all mouse areas");
_mouseMap.hideAll(this);
_inventory.visible(false);
_userEnabled = userEnabled;
@@ -382,6 +383,7 @@ void AGDSEngine::resetCurrentScreen() {
void AGDSEngine::runProcesses() {
+ fadeAndReactivate();
for (uint i = 0; i < _processes.size(); ++i) {
ProcessPtr process = _processes[i];
if (!process || process->parentScreenName() != _currentScreenName)
@@ -436,9 +438,10 @@ void AGDSEngine::curtain(const Common::String &process, int screen, int sound, i
_curtainTimer = 100;
_curtainScreen = screen;
enableSystemUser(false);
+ fadeAndReactivate();
}
-void AGDSEngine::tick() {
+void AGDSEngine::fadeAndReactivate() {
if (_curtainTimer >= 0 && !_curtainProcess.empty()) {
_curtainTimer -= 5;
if (_curtainTimer < 0) {
@@ -448,10 +451,16 @@ void AGDSEngine::tick() {
_curtainProcess.clear();
}
}
+}
+
+void AGDSEngine::tick() {
loadNextScreen();
+ if (!_currentScreen)
+ return;
+
+ _currentScreen->tick();
+ _mouseMap.hideInactive(this, _mouse);
bool dialogActive = _dialog.tick();
- if (_currentScreen)
- _currentScreen->tick();
if (!dialogActive) {
tickInventory();
if (_currentCharacter)
@@ -565,7 +574,6 @@ Common::Error AGDSEngine::run() {
case Common::EVENT_MOUSEMOVE:
_mouse = event.mouse;
- _mouseMap.hideInactive(this, _mouse);
break;
case Common::EVENT_LBUTTONDOWN:
case Common::EVENT_RBUTTONDOWN:
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 69f816481fc..9e7015262d0 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -110,6 +110,7 @@ private:
bool load();
void runProcesses();
void tick();
+ void fadeAndReactivate();
public:
Commit: d05700bd87c6a2ca48416500f070d4d04864b025
https://github.com/scummvm/scummvm/commit/d05700bd87c6a2ca48416500f070d4d04864b025
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:08+01:00
Commit Message:
AGDS: return from hideInactive only if mouse area was really activated
Changed paths:
engines/agds/mouseMap.cpp
diff --git a/engines/agds/mouseMap.cpp b/engines/agds/mouseMap.cpp
index a9d9d1ccf36..22a106d5b26 100644
--- a/engines/agds/mouseMap.cpp
+++ b/engines/agds/mouseMap.cpp
@@ -34,7 +34,7 @@ void MouseMap::hideInactive(AGDSEngine *engine, Common::Point pos) {
} else if (engine->userEnabled()) {
if (!region->region->pointIn(pos)) {
region->hide(engine);
- } else {
+ } else if (!region->visible) {
region->show(engine);
return;
}
Commit: 4dbdc55cd36fb7f0fa5861907621cfb6b64ff81b
https://github.com/scummvm/scummvm/commit/4dbdc55cd36fb7f0fa5861907621cfb6b64ff81b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:08+01:00
Commit Message:
AGDS: restore inventory region check
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 9f838550727..ce3ba9bf6ea 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1079,6 +1079,15 @@ void AGDSEngine::tickInventory() {
_inventoryRegionName.clear();
_inventoryRegion.reset();
}
+ if (userEnabled() && _inventoryRegion && _inventory.enabled()) {
+ if (_mouseMap.disabled()) {
+ _inventory.visible(false);
+ } else {
+ if (_userEnabled) {
+ _inventory.visible(_inventoryRegion->pointIn(_mouse));
+ }
+ }
+ }
}
bool AGDSEngine::hasFeature(EngineFeature f) const {
Commit: 9c57c1ec6f3eaf9ab2836f0cafe93b1fde7ef920
https://github.com/scummvm/scummvm/commit/9c57c1ec6f3eaf9ab2836f0cafe93b1fde7ef920
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:08+01:00
Commit Message:
AGDS: handle "keepGraphics" flag of attachInventoryObjectToMouse
Changed paths:
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 8e03032b3cf..110ab11904f 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -61,10 +61,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
Object::~Object() {
freeRotated();
- if (_picture) {
- _picture->free();
- delete _picture;
- }
+ freePicture();
}
void Object::lock() {
@@ -81,10 +78,17 @@ void Object::freeRotated() {
if (_rotatedPicture) {
_rotatedPicture->free();
delete _rotatedPicture;
+ _rotatedPicture = nullptr;
}
- _rotatedPicture = nullptr;
}
+void Object::freePicture() {
+ if (_picture) {
+ _picture->free();
+ delete _picture;
+ _picture = nullptr;
+ }
+}
void Object::readStringTable(unsigned resOffset, uint16 resCount) {
if (_stringTableLoaded)
@@ -133,10 +137,7 @@ const Object::StringEntry &Object::getString(uint16 index) const {
void Object::setPicture(Graphics::TransparentSurface *picture) {
_pos = Common::Point();
- if (_picture) {
- _picture->free();
- delete _picture;
- }
+ freePicture();
_picture = picture;
freeRotated();
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 3c56fec84df..8767eb82106 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -92,6 +92,7 @@ private:
private:
void freeRotated();
+ void freePicture();
public:
Object(const Common::String &name, Common::SeekableReadStream * stream);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index a3b8dcbac91..939af1b16e2 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -563,21 +563,26 @@ void Process::checkScreenPatch() {
void Process::loadMouseCursorFromObject() {
Common::String name = popText();
- debug("loadMouseCursorFromObject %s", !name.empty()? name.c_str(): "<remove>");
+ auto inventoryObject = _engine->currentInventoryObject();
+ bool changeInventoryObject = (inventoryObject && inventoryObject->getName() == getName());
+ debug("loadMouseCursorFromObject %s inventory: %d", !name.empty()? name.c_str(): "<remove>", changeInventoryObject);
Animation *cursor = !name.empty()? _engine->loadMouseCursor(name): nullptr;
_object->setMouseCursor(cursor); //overlay cursor
}
-void Process::attachInventoryObjectToMouse(bool flag) {
+void Process::attachInventoryObjectToMouse(bool keepGraphics) {
Common::String name = popString();
- debug("attachInventoryObjectToMouse %s %d", name.c_str(), flag);
- if (flag)
- _engine->resetCurrentInventoryObject();
+ debug("attachInventoryObjectToMouse %s, keepGraphics: %d", name.c_str(), keepGraphics);
auto object = _engine->getCurrentScreenObject(name);
- if (object)
- _engine->currentInventoryObject(object);
- else
+ if (!object) {
warning("cannot find object %s", name.c_str());
+ return;
+ }
+ if (!keepGraphics) {
+ object->setAnimation(nullptr);
+ object->setPicture(nullptr);
+ }
+ _engine->currentInventoryObject(object);
}
void Process::returnCurrentInventoryObject() {
Commit: 72017c64a68497dfe19887e67313954b581ffe00
https://github.com/scummvm/scummvm/commit/72017c64a68497dfe19887e67313954b581ffe00
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:08+01:00
Commit Message:
AGDS: add rotation support to animation, fix inventory object rotation
Changed paths:
engines/agds/agds.cpp
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ce3ba9bf6ea..8ed6406ca1e 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -737,6 +737,7 @@ Common::Error AGDSEngine::run() {
picture->blit(*backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
}
} else if (auto *cursor = (_currentInventoryObject? _currentInventoryObject->getMouseCursor(): nullptr)) {
+ cursor->rotate(_currentInventoryObject->rotation());
cursor->tick();
auto pos = _mouse;
pos.x -= cursor->visibleCenter();
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 0b2a4972ffb..1b973d34032 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -33,7 +33,7 @@ namespace AGDS {
Animation::Animation(AGDSEngine *engine, const Common::String &name) :
_engine(engine), _name(name), _flic(), _frame(), _scaledFrame(),
_frames(0), _loop(false), _cycles(1), _phaseVarControlled(false),
- _phase(0), _paused(false), _speed(100), _z(0),
+ _phase(0), _paused(false), _speed(100), _z(0), _rotation(0),
_delay(0), _random(0), _scale(1), _onScreen(true),
_visibleHeight(0), _visibleCenter(0) {
}
@@ -116,8 +116,14 @@ void Animation::scale(float scale) {
}
void Animation::rescaleCurrentFrame() {
- if (_scale != 1 && _frame) {
- freeScaledFrame();
+ if (!_frame)
+ return;
+
+ freeScaledFrame();
+ if (_rotation != 0) {
+ Graphics::TransformStruct transform(_scale * 100, _scale * 100, 90 * _rotation, _frame->w / 2, _frame->h / 2, Graphics::TSpriteBlendMode::BLEND_NORMAL, Graphics::kDefaultRgbaMod);
+ _scaledFrame = _frame->rotoscale(transform);
+ } else if (_scale != 1) {
_scaledFrame = _frame->scale(_frame->w * _scale, _frame->h * _scale, true);
}
auto *frame = _scaledFrame? _scaledFrame: _frame;
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index a43e0bcae28..75aa8c9f218 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -52,6 +52,7 @@ class Animation {
bool _paused;
int _speed;
int _z;
+ int _rotation;
int _delay;
int _random;
float _scale;
@@ -144,6 +145,13 @@ public:
int z() const {
return _z;
}
+ void rotate(int rotation) {
+ if (_rotation == rotation)
+ return;
+
+ _rotation = rotation;
+ rescaleCurrentFrame();
+ }
void scale(float scale);
float scale() const {
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 110ab11904f..8e580b3ad23 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -37,7 +37,7 @@ namespace AGDS {
Object::Object(const Common::String &name, Common::SeekableReadStream *stream) : _name(name), _stringTableLoaded(false),
_picture(), _rotatedPicture(), _region(),
_animation(), _mouseCursor(),
- _pos(), _z(10),
+ _pos(), _z(10), _rotation(0),
_clickHandler(0), _examineHandler(0), _userUseHandler(0),
_throwHandler(0), _useOnHandler(0),
_alpha(255), _scale(100), _locked(0), _alive(true),
@@ -140,6 +140,7 @@ void Object::setPicture(Graphics::TransparentSurface *picture) {
freePicture();
_picture = picture;
freeRotated();
+ _rotation = 0;
if (!picture) {
_offset = Common::Point();
@@ -168,23 +169,27 @@ void Object::setPicture(Graphics::TransparentSurface *picture) {
}
}
}
+ createRotated();
}
void Object::rotate(int rot) {
- if (rot == 0)
+ rot %= 4;
+ if (rot == _rotation)
return;
- if (!_picture) {
- warning("no picture for rotation");
- return;
- }
+ debug("%s: setting rotation to %d", _name.c_str(), rot);
+ _rotation = rot;
+ createRotated();
+}
- Graphics::TransformStruct transform(100, 100, 90 * rot, _picture->w / 2, _picture->h / 2);
- auto rotated = getPicture()->rotoscale(transform);
+void Object::createRotated() {
freeRotated();
- _rotatedPicture = rotated;
-}
+ if (_rotation == 0 || !_picture)
+ return;
+ Graphics::TransformStruct transform(100, 100, 90 * _rotation, _picture->w / 2, _picture->h / 2);
+ _rotatedPicture = getPicture()->rotoscale(transform);
+}
void Object::alive(bool value)
{
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 8767eb82106..a97e3c5f4e6 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -74,6 +74,7 @@ private:
Common::Point _regionOffset;
Common::Rect _srcRect;
int _z;
+ int _rotation;
Common::String _text;
Common::String _title;
uint _clickHandler;
@@ -93,6 +94,7 @@ private:
private:
void freeRotated();
void freePicture();
+ void createRotated();
public:
Object(const Common::String &name, Common::SeekableReadStream * stream);
@@ -158,6 +160,9 @@ public:
}
void rotate(int rot);
+ int rotation() const {
+ return _rotation;
+ }
void generateRegion();
void generateRegion(Common::Rect rect);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 939af1b16e2..a27625d43c4 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -984,7 +984,7 @@ void Process::setRotation() {
debug("setRotation: object: %s %d", objectName.c_str(), rotate);
ObjectPtr object = _engine->getCurrentScreenObject(objectName);
if (object)
- object->rotate(rotate);
+ object->rotate(object->rotation() + rotate);
else
warning("setRotation: object: %s not found in scene", objectName.c_str());
}
Commit: 9664a574c57d45f2ba492e4cf7d92b7687e17d8a
https://github.com/scummvm/scummvm/commit/9664a574c57d45f2ba492e4cf7d92b7687e17d8a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:08+01:00
Commit Message:
AGDS: remove log when object name is pushed to the pool of strings
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index a27625d43c4..fa2e19ea42e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -463,7 +463,6 @@ void Process::appendToSharedStorage() {
void Process::appendNameToSharedStorage() {
int index = _engine->appendToSharedStorage(_object->getName());
- debug("appendNameToSharedStorage %s -> %d", _object->getName().c_str(), index);
push(index);
}
Commit: e838c471e31e2f3ea4081e728c8788bc57a0f1b3
https://github.com/scummvm/scummvm/commit/e838c471e31e2f3ea4081e728c8788bc57a0f1b3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:08+01:00
Commit Message:
AGDS: mark inventory object as non-persistent and don't save them to patches
Changed paths:
engines/agds/inventory.cpp
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 591f62fbb46..40da5b244ec 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -74,8 +74,10 @@ bool Inventory::has(int index) const {
ObjectPtr Inventory::get(int index) {
if (index >= 0 && index < kMaxSize) {
auto & entry = _entries[index];
- if (entry.hasObject && !entry.object)
+ if (entry.hasObject && !entry.object) {
entry.object = _engine->runObject(entry.name);
+ entry.object->persistent(false);
+ }
return entry.object;
}
return {};
Commit: ee12099926085063b7efb6b9a20186d92b0eb241
https://github.com/scummvm/scummvm/commit/ee12099926085063b7efb6b9a20186d92b0eb241
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:08+01:00
Commit Message:
AGDS: remove invalid comment
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 8ed6406ca1e..ccc5c686619 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -395,7 +395,6 @@ void AGDSEngine::runProcesses() {
if (process->finished()) {
debug("deleting process %s", process->getName().c_str());
_processes[i].reset();
- //FIXME: when the last process exits, remove object from scene
} else {
//debug("suspended process %s", process->getName().c_str());
}
Commit: 3e8dd751f9f03d7570bc06eea25663f268f99da7
https://github.com/scummvm/scummvm/commit/3e8dd751f9f03d7570bc06eea25663f268f99da7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:08+01:00
Commit Message:
AGDS: when cutscene is playing, act as a user was disabled
Changed paths:
engines/agds/agds.h
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 9e7015262d0..26802f12e2f 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -223,7 +223,7 @@ public:
}
bool userEnabled() const {
- return _userEnabled && _systemUserEnabled;
+ return _userEnabled && _systemUserEnabled && !_mjpgPlayer;
}
void newGame();
Commit: 9e222ee6f93a4ca3e6233301bbc2b8d09a84a4bb
https://github.com/scummvm/scummvm/commit/9e222ee6f93a4ca3e6233301bbc2b8d09a84a4bb
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:08+01:00
Commit Message:
AGDS: add safe animation removal - the real array resizing will happen in Screen::tick
Changed paths:
engines/agds/screen.cpp
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index ec5d6dc51cb..5083838f1fa 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -126,11 +126,12 @@ void Screen::add(Animation * animation) {
bool Screen::remove(Animation * animation) {
bool removed = false;
for(auto i = _animations.begin(); i != _animations.end(); ) {
- if (*i == animation) {
- _animations.erase(i++);
- removed = true;
- } else
+ if (*i != animation)
++i;
+ else {
+ debug("removing animation %s:%s", animation->process().c_str(), animation->phaseVar().c_str());
+ *i = nullptr;
+ }
}
return removed;
}
@@ -174,7 +175,7 @@ bool Screen::remove(const Common::String &name) {
Animation *Screen::findAnimationByPhaseVar(const Common::String &phaseVar) {
for (auto i = _animations.begin(); i != _animations.end(); ++i) {
Animation *animation = *i;
- if (animation->phaseVar() == phaseVar)
+ if (animation && animation->phaseVar() == phaseVar)
return animation;
}
return NULL;
@@ -183,10 +184,11 @@ Animation *Screen::findAnimationByPhaseVar(const Common::String &phaseVar) {
void Screen::tick() {
for(uint i = 0; i < _animations.size(); ) {
Animation *animation = _animations.data()[i];
- if (animation->tick())
+ if (animation && animation->tick())
++i;
else {
- debug("removing animation %s:%s", animation->process().c_str(), animation->phaseVar().c_str());
+ if (animation)
+ debug("removing animation %s:%s", animation->process().c_str(), animation->phaseVar().c_str());
_animations.erase(_animations.begin() + i);
}
}
@@ -201,6 +203,10 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
while(child != _children.end() || animation != _animations.end() || character) {
bool child_valid = child != _children.end();
bool animation_valid = animation != _animations.end();
+ if (animation_valid && !*animation) {
+ ++animation;
+ continue;
+ }
bool z_valid = false;
int z = 0;
Commit: cc03f5ee088df92078de5394125f102d9ba824e2
https://github.com/scummvm/scummvm/commit/cc03f5ee088df92078de5394125f102d9ba824e2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:08+01:00
Commit Message:
AGDS: fix initialisation order
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 325f03ee866..254363e4c0a 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -31,7 +31,7 @@ namespace AGDS {
Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
_engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object),
_entryPoint(ip), _ip(ip), _lastIp(ip),
- _exited(false), _status(kStatusActive), _exitCode(kExitCodeDestroy),
+ _status(kStatusActive), _exited(false), _exitCode(kExitCodeDestroy),
_tileWidth(16), _tileHeight(16), _tileResource(-1), _tileIndex(0),
_timer(0),
_animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0),
Commit: e7efed7bae8065a6e55f6349895cbd997f7b4bb4
https://github.com/scummvm/scummvm/commit/e7efed7bae8065a6e55f6349895cbd997f7b4bb4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:09+01:00
Commit Message:
AGDS: remove process-level animation when process exits
Changed paths:
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 254363e4c0a..a33d718694f 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -37,7 +37,8 @@ Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
_animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0),
_phaseVarControlled(false), _animationSpeed(100),
_samplePeriodic(false), _sampleAmbient(false), _sampleVolume(100),
- _filmSubtitlesResource(-1)
+ _filmSubtitlesResource(-1),
+ _processAnimation(nullptr)
{
updateWithCurrentMousePosition();
}
@@ -219,6 +220,12 @@ void Process::run() {
case kExitCodeDestroy:
debug("process %s returned destroy exit code", getName().c_str());
done();
+ if (_processAnimation) {
+ auto * screen = _engine->getCurrentScreen();
+ if (screen)
+ screen->remove(_processAnimation);
+ _processAnimation = nullptr;
+ }
if (!getObject()->alive() && !_engine->hasActiveProcesses(getName())) {
auto * screen = _engine->getCurrentScreen();
if (screen)
diff --git a/engines/agds/process.h b/engines/agds/process.h
index de98be68fdf..35d81b967e1 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -71,6 +71,7 @@ private:
int32 _sampleVolume;
Common::Point _mousePosition;
int _filmSubtitlesResource;
+ Animation * _processAnimation;
private:
void debug(const char *str, ...);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index fa2e19ea42e..40fc64136c6 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -158,6 +158,7 @@ void Process::loadAnimation() {
Animation *animation = _engine->loadAnimation(name);
if (animation) {
setupAnimation(animation);
+ _processAnimation = animation;
_engine->getCurrentScreen()->add(animation);
}
}
Commit: 295310c1733a18886410906e56b50fbe0a5e9f7e
https://github.com/scummvm/scummvm/commit/295310c1733a18886410906e56b50fbe0a5e9f7e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:09+01:00
Commit Message:
AGDS: use SharedPtr for animations, do not leak them
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/character.h
engines/agds/object.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ccc5c686619..5e77b8a12b1 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -468,8 +468,8 @@ void AGDSEngine::tick() {
runProcesses();
}
-Animation *AGDSEngine::loadMouseCursor(const Common::String &name) {
- Animation *animation = loadAnimation(name);
+AnimationPtr AGDSEngine::loadMouseCursor(const Common::String &name) {
+ auto animation = loadAnimation(name);
animation->loop(true);
animation->phaseVar(Common::String());
return animation;
@@ -678,7 +678,7 @@ Common::Error AGDSEngine::run() {
Graphics::Surface *backbuffer = _system->lockScreen();
backbuffer->fillRect(backbuffer->getRect(), 0);
- Animation *mouseCursor = NULL;
+ AnimationPtr mouseCursor;
if (userEnabled() && _currentScreen) {
auto objects = _currentScreen->find(_mouse);
@@ -689,7 +689,7 @@ Common::Error AGDSEngine::run() {
}
- Animation *cursor = nullptr;
+ AnimationPtr cursor;
for(auto & object : objects) {
cursor = object->getMouseCursor();
if (cursor)
@@ -735,7 +735,7 @@ Common::Error AGDSEngine::run() {
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer->getRect())) {
picture->blit(*backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
}
- } else if (auto *cursor = (_currentInventoryObject? _currentInventoryObject->getMouseCursor(): nullptr)) {
+ } else if (auto cursor = (_currentInventoryObject? _currentInventoryObject->getMouseCursor(): AnimationPtr())) {
cursor->rotate(_currentInventoryObject->rotation());
cursor->tick();
auto pos = _mouse;
@@ -864,20 +864,21 @@ int AGDSEngine::getGlobal(const Common::String &name) const {
}
}
-Animation *AGDSEngine::loadAnimation(const Common::String &name) {
+AnimationPtr AGDSEngine::loadAnimation(const Common::String &name) {
debug("loadAnimation %s", name.c_str());
Common::SeekableReadStream *stream = _resourceManager.getResource(name);
if (!stream)
error("could not load animation from %s", name.c_str());
- Animation *animation = new Animation(this, name);
+
+ Common::SharedPtr<Animation> animation(new Animation(this, name));
if (!animation->load(stream, name))
error("could not load animation from %s", name.c_str());
return animation;
}
-Animation *AGDSEngine::findAnimationByPhaseVar(const Common::String &phaseVar) {
+AnimationPtr AGDSEngine::findAnimationByPhaseVar(const Common::String &phaseVar) {
return _currentScreen? _currentScreen->findAnimationByPhaseVar(phaseVar): nullptr;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 26802f12e2f..5187794e8e8 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -56,19 +56,21 @@ namespace Graphics { struct TransparentSurface; }
namespace AGDS {
class Animation;
+using AnimationPtr = Common::SharedPtr<Animation>;
class Character;
class Font;
class Object;
-typedef Common::SharedPtr<Object> ObjectPtr;
+using ObjectPtr = Common::SharedPtr<Object>;
struct ObjectPatch;
-typedef Common::SharedPtr<ObjectPatch> ObjectPatchPtr;
+using ObjectPatchPtr = Common::SharedPtr<ObjectPatch>;
struct Patch;
-typedef Common::SharedPtr<Patch> PatchPtr;
+using PatchPtr = Common::SharedPtr<Patch>;
class Process;
-typedef Common::SharedPtr<Process> ProcessPtr;
+using ProcessPtr = Common::SharedPtr<Process>;
struct Region;
-typedef Common::SharedPtr<Region> RegionPtr;
+using RegionPtr = Common::SharedPtr<Region>;
struct MouseRegion;
+
class MJPGPlayer;
class Screen;
class SystemVariable;
@@ -194,9 +196,9 @@ public:
void loadFont(int id, const Common::String &name, int gw, int gh);
Font *getFont(int id) const;
- Animation * loadAnimation(const Common::String &name);
- Animation * loadMouseCursor(const Common::String &name);
- Animation * findAnimationByPhaseVar(const Common::String &phaseVar);
+ AnimationPtr loadAnimation(const Common::String &name);
+ AnimationPtr loadMouseCursor(const Common::String &name);
+ AnimationPtr findAnimationByPhaseVar(const Common::String &phaseVar);
void loadCharacter(const Common::String &id, const Common::String &name, const Common::String &object);
Character * getCharacter(const Common::String &name) {
return _currentCharacterName == name? _currentCharacter: nullptr;
@@ -324,7 +326,7 @@ private:
Common::String _nextScreenName;
ScreenLoadingType _nextScreenType;
Common::String _defaultMouseCursorName;
- Animation * _defaultMouseCursor;
+ AnimationPtr _defaultMouseCursor;
Common::Point _mouse;
bool _userEnabled;
bool _systemUserEnabled;
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 56363029a9b..fd6ac64a71f 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -35,14 +35,15 @@ namespace AGDS {
class AGDSEngine;
class Object;
-typedef Common::SharedPtr<Object> ObjectPtr;
+using ObjectPtr = Common::SharedPtr<Object>;
class Animation;
+using AnimationPtr = Common::SharedPtr<Animation>;
class Character {
using FogPtr = Common::ScopedPtr<Graphics::TransparentSurface>;
AGDSEngine * _engine;
ObjectPtr _object;
- Animation * _animation;
+ AnimationPtr _animation;
FogPtr _fog;
bool _jokes;
Common::String _name;
diff --git a/engines/agds/object.h b/engines/agds/object.h
index a97e3c5f4e6..f5dcb6d2d0c 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -37,8 +37,9 @@ namespace AGDS {
class AGDSEngine;
struct Region;
-typedef Common::SharedPtr<Region> RegionPtr;
+using RegionPtr = Common::SharedPtr<Region>;
class Animation;
+using AnimationPtr = Common::SharedPtr<Animation>;
class Object {
public:
@@ -68,8 +69,8 @@ private:
Graphics::TransparentSurface * _rotatedPicture;
RegionPtr _region;
RegionPtr _trapRegion;
- Animation * _animation;
- Animation * _mouseCursor;
+ AnimationPtr _animation;
+ AnimationPtr _mouseCursor;
Common::Point _pos, _animationPos, _offset;
Common::Point _regionOffset;
Common::Rect _srcRect;
@@ -133,11 +134,11 @@ public:
return _code;
}
- void setAnimation(Animation *animation) {
+ void setAnimation(const AnimationPtr & animation) {
_animation = animation;
}
- Animation *getAnimation() const {
+ const AnimationPtr & getAnimation() const {
return _animation;
}
@@ -145,11 +146,12 @@ public:
_animationPos = animationPos;
}
- void setMouseCursor(Animation *mouseCursor) {
+ void setMouseCursor(const AnimationPtr & mouseCursor) {
_mouseCursor = mouseCursor;
freeRotated();
}
- Animation *getMouseCursor() const {
+
+ const AnimationPtr & getMouseCursor() const {
return _mouseCursor;
}
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index a33d718694f..6a4960938f2 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -37,8 +37,7 @@ Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
_animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0),
_phaseVarControlled(false), _animationSpeed(100),
_samplePeriodic(false), _sampleAmbient(false), _sampleVolume(100),
- _filmSubtitlesResource(-1),
- _processAnimation(nullptr)
+ _filmSubtitlesResource(-1)
{
updateWithCurrentMousePosition();
}
@@ -158,7 +157,7 @@ void Process::updateWithCurrentMousePosition() {
}
-void Process::setupAnimation(Animation *animation) {
+void Process::setupAnimation(const AnimationPtr & animation) {
animation->position(_animationPosition);
animation->z(_animationZ);
animation->process(getName());
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 35d81b967e1..18b4b711627 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -34,6 +34,8 @@ namespace AGDS {
class AGDSEngine;
class Screen;
+class Animation;
+using AnimationPtr = Common::SharedPtr<Animation>;
class Process {
public:
@@ -71,7 +73,7 @@ private:
int32 _sampleVolume;
Common::Point _mousePosition;
int _filmSubtitlesResource;
- Animation * _processAnimation;
+ AnimationPtr _processAnimation;
private:
void debug(const char *str, ...);
@@ -125,7 +127,7 @@ private:
void suspend(ProcessExitCode exitCode, int arg1 = 0, int arg2 = 0);
ProcessExitCode resume();
- void setupAnimation(Animation *animation);
+ void setupAnimation(const AnimationPtr & animation);
void attachInventoryObjectToMouse(bool flag);
void leaveCharacter(const Common::String &name, const Common::String ®ionName, int dir);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 40fc64136c6..c7fb530f549 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -155,7 +155,7 @@ void Process::loadPicture() {
void Process::loadAnimation() {
Common::String name = popText();
debug("loadAnimation %s (phase: %s) %s", name.c_str(), _phaseVar.c_str(), _phaseVarControlled? "(phase-var)": "");
- Animation *animation = _engine->loadAnimation(name);
+ auto animation = _engine->loadAnimation(name);
if (animation) {
setupAnimation(animation);
_processAnimation = animation;
@@ -566,7 +566,7 @@ void Process::loadMouseCursorFromObject() {
auto inventoryObject = _engine->currentInventoryObject();
bool changeInventoryObject = (inventoryObject && inventoryObject->getName() == getName());
debug("loadMouseCursorFromObject %s inventory: %d", !name.empty()? name.c_str(): "<remove>", changeInventoryObject);
- Animation *cursor = !name.empty()? _engine->loadMouseCursor(name): nullptr;
+ auto cursor = !name.empty()? _engine->loadMouseCursor(name): nullptr;
_object->setMouseCursor(cursor); //overlay cursor
}
@@ -1045,7 +1045,7 @@ void Process::restartAnimation() {
warning("no phaseVar");
return;
}
- Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
+ auto animation = _engine->findAnimationByPhaseVar(phaseVar);
if (animation) {
if (_engine->getGlobal(phaseVar) == -1 && !animation->paused()) {
debug("restartAnimation: rewind");
@@ -1068,7 +1068,7 @@ void Process::animationNextFrame() {
warning("no phaseVar");
return;
}
- Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
+ auto animation = _engine->findAnimationByPhaseVar(phaseVar);
if (animation) {
auto value = _engine->getGlobal(phaseVar);
if (value >= -1) {
@@ -1090,7 +1090,7 @@ void Process::signalAnimationEnd() {
warning("no phaseVar");
return;
}
- Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
+ auto animation = _engine->findAnimationByPhaseVar(phaseVar);
if (animation) {
_engine->setGlobal(phaseVar, -2);
} else {
@@ -1107,7 +1107,7 @@ void Process::setShadowIntensity() {
void Process::pauseAnimation() {
int arg = pop();
Common::String phaseVar = popString();
- Animation *animation = _engine->findAnimationByPhaseVar(phaseVar);
+ auto animation = _engine->findAnimationByPhaseVar(phaseVar);
debug("pauseAnimation: phaseVar %s, arg %d", phaseVar.c_str(), arg);
if (animation) {
animation->pause();
@@ -1730,7 +1730,7 @@ void Process::loadPictureFromObject() {
void Process::loadAnimationFromObject() {
Common::String name = popText();
debug("loadAnimationFromObject %s %s", name.c_str(), _phaseVarControlled? "(phase-var)": "");
- Animation *animation = _engine->loadAnimation(name);
+ auto animation = _engine->loadAnimation(name);
if (animation) {
_animationCycles = 0;
_animationLoop = true;
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 5083838f1fa..90b6d061fd5 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -36,7 +36,7 @@ int Screen::ObjectZCompare(const ObjectPtr &a, const ObjectPtr &b) {
return b->z() - a->z();
}
-int Screen::AnimationZCompare(const Animation *a, const Animation *b) {
+int Screen::AnimationZCompare(const AnimationPtr & a, const AnimationPtr & b) {
return b->z() - a->z();
}
@@ -97,7 +97,7 @@ bool Screen::add(ObjectPtr object) {
warning("refusing to add null to scene");
return false;
}
- for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ) {
+ for (auto i = _children.begin(); i != _children.end(); ) {
if (*i == object) {
if (object->alive()) {
debug("double adding object %s", object->getName().c_str());
@@ -115,7 +115,7 @@ bool Screen::add(ObjectPtr object) {
return true;
}
-void Screen::add(Animation * animation) {
+void Screen::add(AnimationPtr animation) {
if (animation)
_animations.insert(animation);
else
@@ -123,21 +123,21 @@ void Screen::add(Animation * animation) {
}
-bool Screen::remove(Animation * animation) {
+bool Screen::remove(const AnimationPtr & animation) {
bool removed = false;
for(auto i = _animations.begin(); i != _animations.end(); ) {
if (*i != animation)
++i;
else {
debug("removing animation %s:%s", animation->process().c_str(), animation->phaseVar().c_str());
- *i = nullptr;
+ i->reset();
}
}
return removed;
}
ObjectPtr Screen::find(const Common::String &name) {
- for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
+ for (auto i = _children.begin(); i != _children.end(); ++i) {
ObjectPtr &object = *i;
if (object->getName() == name)
return *i;
@@ -146,7 +146,7 @@ ObjectPtr Screen::find(const Common::String &name) {
}
bool Screen::remove(const ObjectPtr &object) {
- for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
+ for (auto i = _children.begin(); i != _children.end(); ++i) {
if (*i == object) {
if (object->locked())
object->alive(false);
@@ -159,7 +159,7 @@ bool Screen::remove(const ObjectPtr &object) {
}
bool Screen::remove(const Common::String &name) {
- for (ChildrenType::iterator i = _children.begin(); i != _children.end(); ++i) {
+ for (auto i = _children.begin(); i != _children.end(); ++i) {
const ObjectPtr & object = *i;
if (object->getName() == name) {
if (object->locked())
@@ -172,9 +172,9 @@ bool Screen::remove(const Common::String &name) {
return false;
}
-Animation *Screen::findAnimationByPhaseVar(const Common::String &phaseVar) {
+AnimationPtr Screen::findAnimationByPhaseVar(const Common::String &phaseVar) {
for (auto i = _animations.begin(); i != _animations.end(); ++i) {
- Animation *animation = *i;
+ const auto & animation = *i;
if (animation && animation->phaseVar() == phaseVar)
return animation;
}
@@ -183,7 +183,7 @@ Animation *Screen::findAnimationByPhaseVar(const Common::String &phaseVar) {
void Screen::tick() {
for(uint i = 0; i < _animations.size(); ) {
- Animation *animation = _animations.data()[i];
+ const auto & animation = _animations.data()[i];
if (animation && animation->tick())
++i;
else {
@@ -281,8 +281,8 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
Common::Array<ObjectPtr> Screen::find(Common::Point pos) const {
Common::Array<ObjectPtr> objects;
objects.reserve(_children.size());
- for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
- ObjectPtr object = *i;
+ for (auto i = _children.begin(); i != _children.end(); ++i) {
+ const auto & object = *i;
auto visiblePos = (object->scale() >= 0)? pos + _scroll: pos;
if (object->pointIn(visiblePos) && object->alive()) {
objects.insert_at(0, object);
@@ -293,8 +293,8 @@ Common::Array<ObjectPtr> Screen::find(Common::Point pos) const {
Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
KeyHandler keyHandler;
- for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
- ObjectPtr object = *i;
+ for (auto i = _children.begin(); i != _children.end(); ++i) {
+ const auto & object = *i;
if (!object->alive())
continue;
@@ -332,8 +332,8 @@ void Screen::save(const PatchPtr &patch) {
patch->prevScreenName = _previousScreen;
patch->loadingType = _loadingType;
patch->objects.clear();
- for (ChildrenType::const_iterator i = _children.begin(); i != _children.end(); ++i) {
- ObjectPtr object = *i;
+ for (auto i = _children.begin(); i != _children.end(); ++i) {
+ const auto & object = *i;
if (!object->persistent() || !object->alive() || object->getName() == _name)
continue;
debug("saving patch object %s %d", object->getName().c_str(), object->alive());
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index e1c81cb7065..c45bcf8bf28 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -37,20 +37,21 @@ namespace Graphics {
namespace AGDS {
class AGDSEngine;
-class Object;
class Animation;
-typedef Common::SharedPtr<Object> ObjectPtr;
+using AnimationPtr = Common::SharedPtr<Animation>;
+class Object;
+using ObjectPtr = Common::SharedPtr<Object>;
struct Region;
-typedef Common::SharedPtr<Region> RegionPtr;
+using RegionPtr = Common::SharedPtr<Region>;
struct Patch;
-typedef Common::SharedPtr<Patch> PatchPtr;
+using PatchPtr = Common::SharedPtr<Patch>;
class Screen {
static int ObjectZCompare(const ObjectPtr & a, const ObjectPtr & b);
- static int AnimationZCompare(const Animation *a, const Animation *b);
+ static int AnimationZCompare(const AnimationPtr & a, const AnimationPtr & b);
- typedef Common::SortedArray<Animation *, const Animation *> AnimationsType;
- typedef Common::SortedArray<ObjectPtr, const ObjectPtr &> ChildrenType;
+ using Animations = Common::SortedArray<AnimationPtr, const AnimationPtr &>;
+ using Children = Common::SortedArray<ObjectPtr, const ObjectPtr &>;
AGDSEngine * _engine;
ObjectPtr _object;
@@ -59,8 +60,8 @@ class Screen {
Common::String _name;
ScreenLoadingType _loadingType;
Common::String _previousScreen;
- ChildrenType _children;
- AnimationsType _animations;
+ Children _children;
+ Animations _animations;
RegionPtr _region;
bool _applyingPatch;
int _characterNear, _characterFar;
@@ -121,11 +122,11 @@ public:
_region = region;
}
- const ChildrenType & children() const {
+ const Children & children() const {
return _children;
}
- const AnimationsType & animations() const {
+ const Animations & animations() const {
return _animations;
}
void scrollTo(Common::Point scroll);
@@ -134,8 +135,8 @@ public:
}
bool add(ObjectPtr object);
- void add(Animation * animation);
- bool remove(Animation * animation);
+ void add(AnimationPtr animation);
+ bool remove(const AnimationPtr &animation);
void update(const ObjectPtr &object) {
bool found = remove(object);
@@ -155,7 +156,7 @@ public:
Common::Array<ObjectPtr> find(Common::Point pos) const;
ObjectPtr find(const Common::String &name);
KeyHandler findKeyHandler(const Common::String &keyName);
- Animation * findAnimationByPhaseVar(const Common::String &phaseVar);
+ AnimationPtr findAnimationByPhaseVar(const Common::String &phaseVar);
void load(const PatchPtr &patch);
void save(const PatchPtr &patch);
Commit: 6efc59e6e9a721de5341e3559521ee26caba4b95
https://github.com/scummvm/scummvm/commit/6efc59e6e9a721de5341e3559521ee26caba4b95
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:09+01:00
Commit Message:
AGDS: ArchiveMember fixup
Changed paths:
engines/agds/resourceManager.h
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index c0b4d7fd085..5dab5a85aa3 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -60,6 +60,9 @@ private:
Common::String getFileName() const override {
return _name;
}
+ Common::SeekableReadStream *createReadStreamForAltStream(Common::AltStreamType altStreamType) const override {
+ return nullptr;
+ }
};
typedef Common::SharedPtr<ArchiveMember> ArchiveMemberPtr;
Commit: 15c858eb284408b91169a24b280848009004141d
https://github.com/scummvm/scummvm/commit/15c858eb284408b91169a24b280848009004141d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:09+01:00
Commit Message:
AGDS: replace TransparentSurface with ManagedSurface
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/character.cpp
engines/agds/character.h
engines/agds/font.cpp
engines/agds/font.h
engines/agds/inventory.cpp
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 5e77b8a12b1..2734e7c0c78 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -43,7 +43,7 @@
#include "common/savefile.h"
#include "common/system.h"
#include "engines/util.h"
-#include "graphics/transparent_surface.h"
+#include "graphics/managed_surface.h"
namespace AGDS {
@@ -88,7 +88,7 @@ bool AGDSEngine::initGraphics(int w, int h) {
for (FormatsType::iterator fi = formats.begin(); fi != formats.end(); ++fi) {
const Graphics::PixelFormat &format = *fi;
- if (fi->bytesPerPixel == 4 && format == Graphics::TransparentSurface::getSupportedPixelFormat()) {
+ if (fi->bytesPerPixel == 4 && format == Graphics::BlendBlit::getSupportedPixelFormat()) {
debug("found mode %s", format.toString().c_str());
_pixelFormat = format;
::initGraphics(w, h, &_pixelFormat);
@@ -727,13 +727,13 @@ Common::Error AGDSEngine::run() {
if (userEnabled()) {
if (auto *picture = _currentInventoryObject? _currentInventoryObject->getPicture(): nullptr) {
- Common::Rect srcRect = picture->getRect();
+ Common::Rect srcRect = picture->getBounds();
Common::Point dst = _mouse;
dst.x -= srcRect.width() / 2;
dst.y -= srcRect.height() / 2;
uint32 color = picture->format.ARGBToColor(_currentInventoryObject->alpha(), 255, 255, 255);
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer->getRect())) {
- picture->blit(*backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
+ picture->blendBlitTo(*backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
}
} else if (auto cursor = (_currentInventoryObject? _currentInventoryObject->getMouseCursor(): AnimationPtr())) {
cursor->rotate(_currentInventoryObject->rotation());
@@ -896,7 +896,7 @@ void AGDSEngine::loadCharacter(const Common::String &id, const Common::String &f
_currentCharacter->associate(object);
}
-Graphics::TransparentSurface *AGDSEngine::loadPicture(const Common::String &name) {
+Graphics::ManagedSurface *AGDSEngine::loadPicture(const Common::String &name) {
return convertToTransparent(_resourceManager.loadPicture(name, _pixelFormat));
}
@@ -905,7 +905,7 @@ int AGDSEngine::loadFromCache(const Common::String &name) const {
return i != _pictureCacheLookup.end() ? i->_value : -1;
}
-int AGDSEngine::saveToCache(const Common::String &name, Graphics::TransparentSurface *surface) {
+int AGDSEngine::saveToCache(const Common::String &name, Graphics::ManagedSurface *surface) {
if (!surface)
return -1;
int id = _pictureCacheId++;
@@ -914,14 +914,14 @@ int AGDSEngine::saveToCache(const Common::String &name, Graphics::TransparentSur
return id;
}
-Graphics::TransparentSurface *AGDSEngine::loadFromCache(int id) const {
+Graphics::ManagedSurface *AGDSEngine::loadFromCache(int id) const {
PictureCacheType::const_iterator i = _pictureCache.find(id);
return (i != _pictureCache.end()) ? i->_value : NULL;
}
void AGDSEngine::loadFont(int id, const Common::String &name, int gw, int gh) {
debug("loadFont %d %s %d %d", id, name.c_str(), gw, gh);
- Graphics::TransparentSurface *surface = loadPicture(name);
+ Graphics::ManagedSurface *surface = loadPicture(name);
Font *&font = _fonts[id];
delete font;
font = new Font(surface, gw, gh);
@@ -940,10 +940,10 @@ Graphics::Surface *AGDSEngine::createSurface(int w, int h) {
return surface;
}
-Graphics::TransparentSurface *AGDSEngine::convertToTransparent(Graphics::Surface *surface) {
+Graphics::ManagedSurface *AGDSEngine::convertToTransparent(Graphics::Surface *surface) {
if (!surface)
return NULL;
- Graphics::TransparentSurface *t = new Graphics::TransparentSurface(*surface, true);
+ Graphics::ManagedSurface *t = new Graphics::ManagedSurface(surface);
assert(t->format.bytesPerPixel == 4);
uint32* pixels = static_cast<uint32 *>(t->getPixels());
uint8 shadowAlpha = 255 * _shadowIntensity / 100;
@@ -968,8 +968,6 @@ Graphics::TransparentSurface *AGDSEngine::convertToTransparent(Graphics::Surface
*pixels = t->format.ARGBToColor(a, r, g, b);
}
}
- surface->free();
- delete surface;
return t;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 5187794e8e8..46ec24b0f32 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -51,7 +51,7 @@
* - Black Mirror (Windows)
*/
-namespace Graphics { struct TransparentSurface; }
+namespace Graphics { struct ManagedSurface; }
namespace AGDS {
@@ -185,13 +185,13 @@ public:
return _pixelFormat;
}
- Graphics::TransparentSurface *loadPicture(const Common::String &name);
+ Graphics::ManagedSurface *loadPicture(const Common::String &name);
Graphics::Surface *createSurface(int w, int h);
- Graphics::TransparentSurface *convertToTransparent(Graphics::Surface *surface); //destroys surface!
+ Graphics::ManagedSurface *convertToTransparent(Graphics::Surface *surface); //destroys surface!
int loadFromCache(const Common::String & name) const;
- Graphics::TransparentSurface *loadFromCache(int id) const;
- int saveToCache(const Common::String &name, Graphics::TransparentSurface *surface);
+ Graphics::ManagedSurface *loadFromCache(int id) const;
+ int saveToCache(const Common::String &name, Graphics::ManagedSurface *surface);
void loadFont(int id, const Common::String &name, int gw, int gh);
Font *getFont(int id) const;
@@ -283,7 +283,7 @@ private:
void stopAmbientSound();
void loadPatches(Common::SeekableReadStream *file, Database & db);
- typedef Common::HashMap<int, Graphics::TransparentSurface *> PictureCacheType;
+ typedef Common::HashMap<int, Graphics::ManagedSurface *> PictureCacheType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PictureCacheLookup;
typedef Common::Array<Common::String> SystemVariablesListType;
typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 1b973d34032..125ea69e4be 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -25,7 +25,7 @@
#include "agds/object.h"
#include "common/debug.h"
#include "common/textconsole.h"
-#include "graphics/transparent_surface.h"
+#include "graphics/managed_surface.h"
#include "video/flic_decoder.h"
namespace AGDS {
@@ -122,9 +122,13 @@ void Animation::rescaleCurrentFrame() {
freeScaledFrame();
if (_rotation != 0) {
Graphics::TransformStruct transform(_scale * 100, _scale * 100, 90 * _rotation, _frame->w / 2, _frame->h / 2, Graphics::TSpriteBlendMode::BLEND_NORMAL, Graphics::kDefaultRgbaMod);
- _scaledFrame = _frame->rotoscale(transform);
+ if (_scaledFrame)
+ delete _scaledFrame;
+ _scaledFrame = new Graphics::ManagedSurface(_frame->surfacePtr()->rotoscale(transform));
} else if (_scale != 1) {
- _scaledFrame = _frame->scale(_frame->w * _scale, _frame->h * _scale, true);
+ if (_scaledFrame)
+ delete _scaledFrame;
+ _scaledFrame = new Graphics::ManagedSurface(_frame->surfacePtr()->scale(_frame->w * _scale, _frame->h * _scale, true));
}
auto *frame = _scaledFrame? _scaledFrame: _frame;
if (frame) {
@@ -237,13 +241,13 @@ bool Animation::tick() {
return true;
}
-void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst, Graphics::TransparentSurface *mask, int maskAlpha) const {
+void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst, Graphics::ManagedSurface *mask, int maskAlpha) const {
dst += _position;
auto *frame = _scaledFrame? _scaledFrame: _frame;
if (!frame || !_onScreen)
return;
- Common::Rect srcRect = frame->getRect();
+ Common::Rect srcRect = frame->getBounds();
if (!Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
return;
@@ -278,7 +282,7 @@ void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst, Graphics
maskPixels += subMask.pitch;
}
} else
- frame->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
+ frame->blendBlitTo(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect);
}
uint Animation::width() const {
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 75aa8c9f218..4ec818a50b3 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -27,7 +27,7 @@
#include "common/rect.h"
namespace Common { class SeekableReadStream; }
-namespace Graphics { struct Surface; struct TransparentSurface; }
+namespace Graphics { struct Surface; struct ManagedSurface; }
namespace Video { class FlicDecoder; }
namespace AGDS {
@@ -39,8 +39,8 @@ class Animation {
AGDSEngine * _engine;
Common::String _name;
Video::FlicDecoder *_flic;
- Graphics::TransparentSurface *_frame;
- Graphics::TransparentSurface *_scaledFrame;
+ Graphics::ManagedSurface *_frame;
+ Graphics::ManagedSurface *_scaledFrame;
int _frames;
Common::Point _position;
Common::String _process;
@@ -165,7 +165,7 @@ public:
void onScreen(bool onScreen);
bool load(Common::SeekableReadStream *stream, const Common::String &fname);
- void paint(Graphics::Surface & backbuffer, Common::Point dst, Graphics::TransparentSurface *mask = nullptr, int maskAlpha = 0) const;
+ void paint(Graphics::Surface & backbuffer, Common::Point dst, Graphics::ManagedSurface *mask = nullptr, int maskAlpha = 0) const;
uint width() const;
uint height() const;
uint visibleHeight() const {
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 41addd904fe..bb8982fe0e7 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -33,7 +33,7 @@
#include "common/system.h"
#include "common/textconsole.h"
#include "common/util.h"
-#include "graphics/transparent_surface.h"
+#include "graphics/managed_surface.h"
#include <math.h>
@@ -294,7 +294,7 @@ void Character::reset() {
_visible = false;
}
-void Character::setFog(Graphics::TransparentSurface * surface, int minZ, int maxZ) {
+void Character::setFog(Graphics::ManagedSurface * surface, int minZ, int maxZ) {
_fog.reset(surface);
_fogMinZ = minZ;
_fogMaxZ = maxZ;
diff --git a/engines/agds/character.h b/engines/agds/character.h
index fd6ac64a71f..75202996cd7 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -29,7 +29,7 @@
#include "common/rect.h"
namespace Common { class SeekableReadStream; class ReadStream; class WriteStream; }
-namespace Graphics { struct Surface; struct TransparentSurface; }
+namespace Graphics { struct Surface; struct ManagedSurface; }
namespace AGDS {
@@ -40,7 +40,7 @@ class Animation;
using AnimationPtr = Common::SharedPtr<Animation>;
class Character {
- using FogPtr = Common::ScopedPtr<Graphics::TransparentSurface>;
+ using FogPtr = Common::ScopedPtr<Graphics::ManagedSurface>;
AGDSEngine * _engine;
ObjectPtr _object;
AnimationPtr _animation;
@@ -143,7 +143,7 @@ public:
int z() const;
void reset();
- void setFog(Graphics::TransparentSurface * surface, int minZ, int maxZ);
+ void setFog(Graphics::ManagedSurface * surface, int minZ, int maxZ);
};
diff --git a/engines/agds/font.cpp b/engines/agds/font.cpp
index 63c35c0a5d8..01627edbf4a 100644
--- a/engines/agds/font.cpp
+++ b/engines/agds/font.cpp
@@ -1,9 +1,9 @@
#include "agds/font.h"
-#include "graphics/transparent_surface.h"
+#include "graphics/managed_surface.h"
namespace AGDS {
-Font::Font(Graphics::TransparentSurface *surface, int gw, int gh) : _surface(surface),
+Font::Font(Graphics::ManagedSurface *surface, int gw, int gh) : _surface(surface),
_glyphW(gw), _glyphH(gh),
_cellW(surface->w / 16), _cellH(surface->h / 16) {
@@ -33,7 +33,7 @@ void Font::drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 col
Common::Rect srcRect(getCharWidth(chr), _glyphH);
srcRect.moveTo(_cellW * (chr & 0x0f), _cellH * (chr >> 4));
if (!srcRect.isEmpty())
- _surface->blit(*dst, x, y, Graphics::FLIP_NONE, &srcRect);
+ _surface->blendBlitTo(*dst, x, y, Graphics::FLIP_NONE, &srcRect);
}
} // namespace AGDS
diff --git a/engines/agds/font.h b/engines/agds/font.h
index 5991f3c8dd4..be9bc35b1e3 100644
--- a/engines/agds/font.h
+++ b/engines/agds/font.h
@@ -27,19 +27,19 @@
#include "common/ptr.h"
namespace Graphics {
- struct TransparentSurface;
+ struct ManagedSurface;
}
namespace AGDS {
class Font : public Graphics::Font {
- Common::ScopedPtr<Graphics::TransparentSurface> _surface;
+ Common::ScopedPtr<Graphics::ManagedSurface> _surface;
int _glyphW, _glyphH;
int _cellW, _cellH;
uint8 _width[0x100];
public:
- Font(Graphics::TransparentSurface *surface, int gw, int gh);
+ Font(Graphics::ManagedSurface *surface, int gw, int gh);
virtual int getFontHeight() const {
return _glyphH;
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 40da5b244ec..e952ed0d086 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -27,7 +27,7 @@
#include "agds/systemVariable.h"
#include "common/debug.h"
#include "common/textconsole.h"
-#include "graphics/transparent_surface.h"
+#include "graphics/managed_surface.h"
namespace AGDS {
@@ -173,7 +173,7 @@ ObjectPtr Inventory::find(const Common::Point pos) const {
auto & object = entry.object;
auto picture = object->getPicture();
if (picture) {
- auto rect = picture->getRect();
+ auto rect = picture->getBounds();
rect.moveTo(object->getPosition());
if (rect.contains(pos))
return object;
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 8e580b3ad23..ce028d190a3 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -30,7 +30,7 @@
#include "common/memstream.h"
#include "common/rect.h"
#include "graphics/surface.h"
-#include "graphics/transparent_surface.h"
+#include "graphics/managed_surface.h"
namespace AGDS {
@@ -135,7 +135,7 @@ const Object::StringEntry &Object::getString(uint16 index) const {
return _stringTable[index];
}
-void Object::setPicture(Graphics::TransparentSurface *picture) {
+void Object::setPicture(Graphics::ManagedSurface *picture) {
_pos = Common::Point();
freePicture();
_picture = picture;
@@ -188,7 +188,7 @@ void Object::createRotated() {
return;
Graphics::TransformStruct transform(100, 100, 90 * _rotation, _picture->w / 2, _picture->h / 2);
- _rotatedPicture = getPicture()->rotoscale(transform);
+ _rotatedPicture = new Graphics::ManagedSurface(getPicture()->surfacePtr()->rotoscale(transform));
}
void Object::alive(bool value)
@@ -227,7 +227,7 @@ Common::Rect Object::getRect() const {
warning("getRect called on null picture");
return Common::Rect();
}
- Common::Rect rect = picture->getRect();
+ Common::Rect rect = picture->getBounds();
rect.moveTo(_pos.x, _pos.y);
return rect;
}
@@ -269,13 +269,13 @@ void Object::paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Po
auto picture = getPicture();
if (picture) {
Common::Point dst = pos + getPosition();
- Common::Rect srcRect = picture->getRect();
+ Common::Rect srcRect = picture->getBounds();
if (!_srcRect.isEmpty()) {
srcRect = _srcRect;
}
uint32 color = _picture->format.ARGBToColor(_alpha, 255, 255, 255);
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect())) {
- picture->blit(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
+ picture->blendBlitTo(backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
}
}
diff --git a/engines/agds/object.h b/engines/agds/object.h
index f5dcb6d2d0c..16e9ccf9bb4 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -31,7 +31,7 @@
#include "common/rect.h"
#include "common/stream.h"
-namespace Graphics { struct Surface; struct TransparentSurface; }
+namespace Graphics { struct Surface; struct ManagedSurface; }
namespace AGDS {
@@ -65,8 +65,8 @@ private:
bool _stringTableLoaded;
KeyHandlersType _keyHandlers;
UseHandlersType _useHandlers;
- Graphics::TransparentSurface * _picture;
- Graphics::TransparentSurface * _rotatedPicture;
+ Graphics::ManagedSurface * _picture;
+ Graphics::ManagedSurface * _rotatedPicture;
RegionPtr _region;
RegionPtr _trapRegion;
AnimationPtr _animation;
@@ -155,9 +155,9 @@ public:
return _mouseCursor;
}
- void setPicture(Graphics::TransparentSurface *);
+ void setPicture(Graphics::ManagedSurface *);
- Graphics::TransparentSurface *getPicture() const {
+ Graphics::ManagedSurface *getPicture() const {
return _rotatedPicture? _rotatedPicture: _picture;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c7fb530f549..8353937b07b 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -33,7 +33,7 @@
#include "common/debug.h"
#include "common/savefile.h"
#include "common/system.h"
-#include "graphics/transparent_surface.h"
+#include "graphics/managed_surface.h"
namespace AGDS {
@@ -913,7 +913,7 @@ void Process::loadSaveSlotNamePicture() {
uint32 color = _engine->pixelFormat().RGBToColor(255, 0, 255);
label->fillRect(label->getRect(), color);
font->drawString(label, save? saveSlotName: "", 0, 0, w, color);
- Graphics::TransparentSurface *transparentLabel = _engine->convertToTransparent(label);
+ Graphics::ManagedSurface *transparentLabel = _engine->convertToTransparent(label);
_object->setPicture(transparentLabel);
_object->generateRegion();
@@ -1162,7 +1162,7 @@ void Process::setObjectTile() {
warning("invalid tile size");
return;
}
- Graphics::TransparentSurface *surface = _engine->loadFromCache(_tileResource);
+ Graphics::ManagedSurface *surface = _engine->loadFromCache(_tileResource);
if (!surface) {
warning("picture %d was not loaded", _tileResource);
return;
@@ -1173,12 +1173,12 @@ void Process::setObjectTile() {
int x = _tileIndex % tw;
debug("tile coordinate %dx%d", x, y);
- Graphics::TransparentSurface *tile = new Graphics::TransparentSurface();
+ Graphics::ManagedSurface *tile = new Graphics::ManagedSurface();
tile->create(_tileWidth, _tileHeight, surface->format);
- tile->applyColorKey(0xff, 0, 0xff);
+ tile->surfacePtr()->applyColorKey(0xff, 0, 0xff);
Common::Rect srcRect(_tileWidth, _tileHeight);
srcRect.translate(x * _tileWidth, y * _tileHeight);
- surface->blit(*tile, 0, 0, Graphics::FLIP_NONE, &srcRect);
+ surface->blendBlitTo(*tile, 0, 0, Graphics::FLIP_NONE, &srcRect);
object->setPicture(tile);
}
@@ -1287,7 +1287,7 @@ void Process::getObjectPictureWidth() {
debug("getObjectPictureWidth %s", name.c_str());
ObjectPtr object = _engine->getCurrentScreenObject(name);
if (object) {
- const Graphics::Surface *picture = object->getPicture();
+ const auto *picture = object->getPicture();
int value = picture ? picture->w : 0;
debug("\t->%d", value);
push(value);
@@ -1302,7 +1302,7 @@ void Process::getObjectPictureHeight() {
debug("getObjectPictureHeight %s", name.c_str());
ObjectPtr object = _engine->getCurrentScreenObject(name);
if (object) {
- const Graphics::Surface *picture = object->getPicture();
+ const auto *picture = object->getPicture();
int value = picture ? picture->h : 0;
debug("\t->%d", value);
push(value);
@@ -1698,7 +1698,7 @@ void Process::fogOnCharacter() {
debug("fogOnCharacter %s z: [%d,%d]", name.c_str(), arg1, arg2);
Character *character = _engine->currentCharacter();
if (character)
- character->setFog(_engine->convertToTransparent(_engine->loadPicture(name)), arg1, arg2);
+ character->setFog(_engine->loadPicture(name), arg1, arg2);
}
void Process::setRain() {
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 90b6d061fd5..ddb49d1bf3e 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -28,7 +28,7 @@
#include "agds/patch.h"
#include "agds/region.h"
#include "common/system.h"
-#include "graphics/transparent_surface.h"
+#include "graphics/managed_surface.h"
namespace AGDS {
Commit: 39f297b4768003c4db1a63c2958b21b191d2c78f
https://github.com/scummvm/scummvm/commit/39f297b4768003c4db1a63c2958b21b191d2c78f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:09+01:00
Commit Message:
AGDS: do not log jumps
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 6a4960938f2..430d104b5b4 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -106,7 +106,6 @@ uint8 Process::next() {
}
void Process::jump(int16 delta) {
- debug("jump %+d", delta);
_ip += delta;
}
Commit: 869a0a5a2f8c404da80597776d5495afa754a856
https://github.com/scummvm/scummvm/commit/869a0a5a2f8c404da80597776d5495afa754a856
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:09+01:00
Commit Message:
AGDS: safer animation removal - keep AnimationDesc in screen/mark as removed
Changed paths:
engines/agds/animation.h
engines/agds/console.cpp
engines/agds/process_opcodes.cpp
engines/agds/screen.cpp
engines/agds/screen.h
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 4ec818a50b3..4cd323035f3 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -145,6 +145,7 @@ public:
int z() const {
return _z;
}
+
void rotate(int rotation) {
if (_rotation == rotation)
return;
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index f7a136044bc..631d6541f06 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -104,7 +104,8 @@ bool Console::info(int argc, const char **argv) {
auto pos = object->getPosition();
debugPrintf("object %s [alive: %d] at %d,%d\n", object->getName().c_str(), object->alive(), pos.x, pos.y);
}
- for(auto & animation : screen->animations()) {
+ for(auto & desc : screen->animations()) {
+ auto &animation = desc.animation;
auto pos = animation->position();
debugPrintf("animation %s (process: %s, %s) at %d,%d,%d, frame: %d\n",
animation->phaseVar().c_str(), animation->process().c_str(), animation->paused()? "paused": "running",
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 8353937b07b..20f4d7d1791 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -157,6 +157,10 @@ void Process::loadAnimation() {
debug("loadAnimation %s (phase: %s) %s", name.c_str(), _phaseVar.c_str(), _phaseVarControlled? "(phase-var)": "");
auto animation = _engine->loadAnimation(name);
if (animation) {
+ if (animation == _processAnimation) {
+ warning("double adding animation, skipped.");
+ return;
+ }
setupAnimation(animation);
_processAnimation = animation;
_engine->getCurrentScreen()->add(animation);
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index ddb49d1bf3e..c696314e916 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -36,8 +36,8 @@ int Screen::ObjectZCompare(const ObjectPtr &a, const ObjectPtr &b) {
return b->z() - a->z();
}
-int Screen::AnimationZCompare(const AnimationPtr & a, const AnimationPtr & b) {
- return b->z() - a->z();
+int Screen::AnimationZCompare(const ScreenAnimationDesc &a, const ScreenAnimationDesc &b) {
+ return b.animation->z() - a.animation->z();
}
Screen::Screen(AGDSEngine * engine, ObjectPtr object, ScreenLoadingType loadingType, const Common::String &prevScreen) :
@@ -117,20 +117,22 @@ bool Screen::add(ObjectPtr object) {
void Screen::add(AnimationPtr animation) {
if (animation)
- _animations.insert(animation);
+ _animations.insert({animation});
else
warning("Screen: skipping null animation");
}
bool Screen::remove(const AnimationPtr & animation) {
+ if (!animation)
+ return false;
+
bool removed = false;
- for(auto i = _animations.begin(); i != _animations.end(); ) {
- if (*i != animation)
- ++i;
- else {
+ for(auto i = _animations.begin(); i != _animations.end(); ++i) {
+ if (i->animation == animation) {
debug("removing animation %s:%s", animation->process().c_str(), animation->phaseVar().c_str());
- i->reset();
+ i->removed = true;
+ removed = true;
}
}
return removed;
@@ -174,8 +176,9 @@ bool Screen::remove(const Common::String &name) {
AnimationPtr Screen::findAnimationByPhaseVar(const Common::String &phaseVar) {
for (auto i = _animations.begin(); i != _animations.end(); ++i) {
- const auto & animation = *i;
- if (animation && animation->phaseVar() == phaseVar)
+ const auto & desc = *i;
+ const auto & animation = desc.animation;
+ if (!desc.removed && animation->phaseVar() == phaseVar)
return animation;
}
return NULL;
@@ -183,12 +186,12 @@ AnimationPtr Screen::findAnimationByPhaseVar(const Common::String &phaseVar) {
void Screen::tick() {
for(uint i = 0; i < _animations.size(); ) {
- const auto & animation = _animations.data()[i];
- if (animation && animation->tick())
+ const auto & desc = _animations.data()[i];
+ const auto & animation = desc.animation;
+ if (!desc.removed && animation->tick())
++i;
else {
- if (animation)
- debug("removing animation %s:%s", animation->process().c_str(), animation->phaseVar().c_str());
+ debug("removing animation %s:%s", animation->process().c_str(), animation->phaseVar().c_str());
_animations.erase(_animations.begin() + i);
}
}
@@ -199,12 +202,12 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
Character * character = _engine->currentCharacter();
auto child = _children.begin();
- auto animation = _animations.begin();
- while(child != _children.end() || animation != _animations.end() || character) {
+ auto desc = _animations.begin();
+ while(child != _children.end() || desc != _animations.end() || character) {
bool child_valid = child != _children.end();
- bool animation_valid = animation != _animations.end();
- if (animation_valid && !*animation) {
- ++animation;
+ bool animation_valid = desc != _animations.end();
+ if (animation_valid && desc->removed) {
+ ++desc;
continue;
}
@@ -212,8 +215,9 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
int z = 0;
int render_type = -1;
if (animation_valid) {
- if (!z_valid || (*animation)->z() > z) {
- z = (*animation)->z();
+ const auto & animation = desc->animation;
+ if (!z_valid || animation->z() > z) {
+ z = animation->z();
z_valid = true;
render_type = 1;
}
@@ -246,10 +250,10 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
break;
case 1:
//debug("animation z: %d", (*animation)->z());
- if ((*animation)->scale() < 0)
+ if ((*desc).animation->scale() < 0)
basePos = Common::Point();
- (*animation)->paint(backbuffer, basePos);
- ++animation;
+ (*desc).animation->paint(backbuffer, basePos);
+ ++desc;
break;
case 2:
//debug("character z: %d", character->z());
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index c45bcf8bf28..ab0e3538d50 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -46,11 +46,18 @@ using RegionPtr = Common::SharedPtr<Region>;
struct Patch;
using PatchPtr = Common::SharedPtr<Patch>;
+struct ScreenAnimationDesc {
+ AnimationPtr animation;
+ bool removed = false;
+ ScreenAnimationDesc(const AnimationPtr &a): animation(a) {
+ }
+};
+
class Screen {
- static int ObjectZCompare(const ObjectPtr & a, const ObjectPtr & b);
- static int AnimationZCompare(const AnimationPtr & a, const AnimationPtr & b);
+ static int ObjectZCompare(const ObjectPtr &a, const ObjectPtr &b);
+ static int AnimationZCompare(const ScreenAnimationDesc &a, const ScreenAnimationDesc &b);
- using Animations = Common::SortedArray<AnimationPtr, const AnimationPtr &>;
+ using Animations = Common::SortedArray<ScreenAnimationDesc, const ScreenAnimationDesc &>;
using Children = Common::SortedArray<ObjectPtr, const ObjectPtr &>;
AGDSEngine * _engine;
Commit: 6f6546acae57dedcd890cae01450dab773a2f079
https://github.com/scummvm/scummvm/commit/6f6546acae57dedcd890cae01450dab773a2f079
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:09+01:00
Commit Message:
AGDS: follow upstream canLoad/canSave methods signatures
Changed paths:
engines/agds/agds.h
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 46ec24b0f32..d210e0d0d48 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -119,8 +119,8 @@ public:
bool hasFeature(EngineFeature f) const;
Common::Error loadGameState(int slot) override;
Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
- bool canLoadGameStateCurrently() override { return true; }
- bool canSaveGameStateCurrently() override { return false; }
+ bool canLoadGameStateCurrently(Common::U32String *msg) override { return true; }
+ bool canSaveGameStateCurrently(Common::U32String *msg) override { return false; }
ObjectPtr loadObject(const Common::String & name, const Common::String & prototype = Common::String(), bool allowInitialise = true);
ObjectPtr runObject(const Common::String & name, const Common::String &prototype = Common::String(), bool allowInitialise = true);
Commit: d15bda69a2f1428a0d1b87f56d39c3da0d76602d
https://github.com/scummvm/scummvm/commit/d15bda69a2f1428a0d1b87f56d39c3da0d76602d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:09+01:00
Commit Message:
AGDS: rebase, adopt some string â path changes
Changed paths:
engines/agds/agds.cpp
engines/agds/database.cpp
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
engines/agds/soundManager.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 2734e7c0c78..ed7a285771c 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -158,7 +158,7 @@ bool AGDSEngine::load() {
Common::INIFile::SectionKeyList values = config.getKeys("core");
for (Common::INIFile::SectionKeyList::iterator i = values.begin(); i != values.end(); ++i) {
if (i->key == "path")
- if (!_resourceManager.addPath(i->value))
+ if (!_resourceManager.addPath(Common::Path{i->value}))
return false;
}
diff --git a/engines/agds/database.cpp b/engines/agds/database.cpp
index 801b430eafa..7ead889587b 100644
--- a/engines/agds/database.cpp
+++ b/engines/agds/database.cpp
@@ -29,7 +29,7 @@ namespace AGDS {
bool Database::open(const Common::String &filename) {
Common::File file;
- if (!file.open(filename))
+ if (!file.open(Common::Path{filename}))
return false;
return open(filename, &file);
@@ -117,7 +117,7 @@ Common::Array<Common::String> Database::getEntries() const {
Common::SeekableReadStream *Database::getEntry(const Common::String &name) const {
Common::File file;
- if (!file.open(_filename)) {
+ if (!file.open(Common::Path{_filename})) {
error("could not open database file %s", _filename.c_str()); //previously available, but now disappeared or no fd, error
return NULL;
}
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index f123a213b02..8130fda805a 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -47,15 +47,15 @@ void ResourceManager::decrypt(uint8 *data, unsigned size) {
}
}
-bool ResourceManager::GrpFile::load(const Common::String &grpFilename) {
+bool ResourceManager::GrpFile::load(const Common::Path &grpPath) {
static const char *kSignature = "AGDS group file\x1a";
static const uint32 kMagic = 0x1a03c9e6;
static const uint32 kVersion1 = 44;
static const uint32 kVersion2 = 2;
- debug("adding path %s", grpFilename.c_str());
- if (!_file.open(grpFilename)) {
- warning("failing opening grp file %s", grpFilename.c_str());
+ debug("adding path %s", grpPath.toString().c_str());
+ if (!_file.open(grpPath)) {
+ warning("failing opening grp file %s", grpPath.toString().c_str());
return false;
}
uint8 header[0x2c];
@@ -122,7 +122,7 @@ bool ResourceManager::GrpFile::load(const Common::String &grpFilename) {
_members.setVal(name, resource);
}
- debug("%s: %u files in index", grpFilename.c_str(), _members.size());
+ debug("%s: %u files in index", grpPath.toString().c_str(), _members.size());
return true;
}
@@ -146,18 +146,18 @@ const Common::ArchiveMemberPtr ResourceManager::GrpFile::getMember(const Common:
}
Common::SeekableReadStream *ResourceManager::GrpFile::createReadStreamForMember(const Common::Path &name) const {
- Common::ArchiveMemberPtr member = getMember(name.toString());
+ Common::ArchiveMemberPtr member = getMember(name);
return member ? member->createReadStream() : NULL;
}
-bool ResourceManager::addPath(const Common::String &grpFilename) {
+bool ResourceManager::addPath(const Common::Path &grpFilename) {
GrpFile *grpFile = new GrpFile();
if (!grpFile->load(grpFilename)) {
delete grpFile;
return false;
}
- SearchMan.add(grpFilename, grpFile, 0, true);
+ SearchMan.add(grpFilename.toString(), grpFile, 0, true);
return true;
}
@@ -169,7 +169,7 @@ Common::SeekableReadStream *ResourceManager::ArchiveMember::createReadStream() c
Common::SeekableReadStream *ResourceManager::getResource(const Common::String &name) const {
Common::File file;
- return (file.open(name)) ? file.readStream(file.size()) : NULL;
+ return (file.open(Common::Path{name})) ? file.readStream(file.size()) : NULL;
}
Graphics::Surface *ResourceManager::loadPicture(const Common::String &name, const Graphics::PixelFormat &format) {
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 5dab5a85aa3..e635ad00b70 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -55,7 +55,7 @@ private:
return getFileName();
}
Common::Path getPathInArchive() const override {
- return _name;
+ return Common::Path{_name};
}
Common::String getFileName() const override {
return _name;
@@ -74,7 +74,7 @@ private:
MembersType _members;
public:
- bool load(const Common::String &fname);
+ bool load(const Common::Path &path);
Common::SeekableReadStream &getArchiveStream() {
return _file;
@@ -92,7 +92,7 @@ public:
static void decrypt(uint8 * data, unsigned size);
- bool addPath(const Common::String &grpFilename);
+ bool addPath(const Common::Path &grpFilename);
Common::SeekableReadStream * getResource(const Common::String &name) const;
Graphics::Surface * loadPicture(const Common::String & name, const Graphics::PixelFormat &format);
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 9ec4fc7ed46..209724156e1 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -126,7 +126,7 @@ int SoundManager::play(Common::String process, const Common::String &resource, c
}
}
Common::File *file = new Common::File();
- if (!file->open(filename)) {
+ if (!file->open(Common::Path{filename})) {
if (!phaseVar.empty())
_engine->setGlobal(phaseVar, 1);
warning("no sound %s", filename.c_str());
Commit: 823e4cae9a25b2f8d149e7b1e44ead1b91f17813
https://github.com/scummvm/scummvm/commit/823e4cae9a25b2f8d149e7b1e44ead1b91f17813
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:09+01:00
Commit Message:
AGDS: call removeScreenObject from screenObjectPatchDecRef
Original engine uses the same underlying function which reinitialise the object, stops all processes and remove global animations
Changed paths:
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 18b4b711627..9b80a274e2d 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -130,6 +130,7 @@ private:
void setupAnimation(const AnimationPtr & animation);
void attachInventoryObjectToMouse(bool flag);
void leaveCharacter(const Common::String &name, const Common::String ®ionName, int dir);
+ void removeScreenObject(const Common::String &name);
public:
Process(AGDSEngine *engine, ObjectPtr object, unsigned ip = 0);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 20f4d7d1791..ebe23ebd1a4 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -281,6 +281,10 @@ void Process::cloneObject() {
void Process::removeScreenObject() {
Common::String name = popString();
+ removeScreenObject(name);
+}
+
+void Process::removeScreenObject(const Common::String &name) {
debug("removeScreenObject: %s", name.c_str());
auto screen = _engine->getCurrentScreen();
if (!screen) {
@@ -806,8 +810,8 @@ void Process::screenObjectPatchIncRef() {
void Process::screenObjectPatchDecRef() {
Common::String objectName = popString();
Common::String screenName = popString();
+ debug("screenObjectPatchDecRef %s %s", screenName.c_str(), objectName.c_str());
if (!screenName.empty() && screenName != _engine->getCurrentScreenName()) {
- debug("screenObjectPatchDecRef %s %s", screenName.c_str(), objectName.c_str());
if (_engine->getCurrentScreen()->applyingPatch()) {
warning("attempt to change screen patch (%s) in patching process (%s)", objectName.c_str(), screenName.c_str());
} else {
@@ -820,13 +824,8 @@ void Process::screenObjectPatchDecRef() {
debug("decrement refcount for object %s, no patch for screen %s", objectName.c_str(), screenName.c_str());
}
} else {
- Screen *screen = _engine->getCurrentScreen();
- if (screen) {
- _object->lock();
- if (!screen->remove(objectName))
- warning("screenRemoveObjectSavePatch: object %s not found", objectName.c_str());
- _object->unlock();
- }
+ debug("screenObjectPatchDecRef: current screen, removing object");
+ removeScreenObject(objectName);
}
}
Commit: 43c9ad7b074ab607e44bd307eb4360d6bbc6b7d0
https://github.com/scummvm/scummvm/commit/43c9ad7b074ab607e44bd307eb4360d6bbc6b7d0
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:10+01:00
Commit Message:
AGDS: remove process animation from stopProcess(name)
This fixes live cable animation left behind when light's off in mines.
Changed paths:
engines/agds/agds.cpp
engines/agds/process.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ed7a285771c..d483d948c97 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1382,11 +1382,14 @@ void AGDSEngine::runPendingReactivatedProcesses() {
}
void AGDSEngine::stopProcess(const Common::String & name) {
+ auto *screen = getCurrentScreen();
for(uint i = 0; i < _processes.size(); ++i) {
ProcessPtr &process = _processes[i];
if (process && process->getName() == name) {
debug("stopping %s...", name.c_str());
process->done();
+ // Original engine removes global animations only from object reinitialisation.
+ screen->remove(process->processAnimation());
}
}
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 9b80a274e2d..c270a9378d3 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -201,6 +201,10 @@ public:
const Common::String & phaseVar() const {
return _phaseVar;
}
+
+ const AnimationPtr &processAnimation() const {
+ return _processAnimation;
+ }
};
Commit: ffa788860dd95b7f2860402c6af226cfbbfde851
https://github.com/scummvm/scummvm/commit/ffa788860dd95b7f2860402c6af226cfbbfde851
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:10+01:00
Commit Message:
AGDS: add suspendIfPassive() and use it when needed
Changed paths:
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 430d104b5b4..d6daa341774 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -122,6 +122,11 @@ void Process::suspend() {
suspend(kExitCodeSuspend);
}
+void Process::suspendIfPassive() {
+ if (passive())
+ suspend();
+}
+
int32 Process::pop() {
if (_stack.empty()) {
error("stack underflow at %s:%04x", _object->getName().c_str(), _lastIp + 7);
diff --git a/engines/agds/process.h b/engines/agds/process.h
index c270a9378d3..fa548b2fe10 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -123,10 +123,11 @@ private:
Common::String getCloneVarName(const Common::String & arg1, const Common::String & arg2);
void suspend(ProcessExitCode exitCode, const Common::String &arg1, const Common::String &arg2 = Common::String());
-
void suspend(ProcessExitCode exitCode, int arg1 = 0, int arg2 = 0);
ProcessExitCode resume();
+ void suspendIfPassive();
+
void setupAnimation(const AnimationPtr & animation);
void attachInventoryObjectToMouse(bool flag);
void leaveCharacter(const Common::String &name, const Common::String ®ionName, int dir);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index ebe23ebd1a4..74a03ef730e 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -165,6 +165,7 @@ void Process::loadAnimation() {
_processAnimation = animation;
_engine->getCurrentScreen()->add(animation);
}
+ suspendIfPassive();
}
void Process::loadSample() {
@@ -177,8 +178,8 @@ void Process::loadSample() {
// original engine sets timer to 24 * bitrate / 44100 / 4
if (playNow && _phaseVar.empty()) {
deactivate();
- suspend();
}
+ suspendIfPassive();
}
void Process::getSampleVolume() {
@@ -895,6 +896,7 @@ void Process::getSaveGameName() {
int saveSlot = pop();
debug("getSaveGameName stub %d %d", saveSlot, flag);
push(1);
+ suspendIfPassive();
}
void Process::loadSaveSlotNamePicture() {
@@ -1321,8 +1323,8 @@ void Process::playFilm() {
Common::String subtitles = _engine->loadText(getString(_filmSubtitlesResource));
debug("playFilm %s %s %s", video.c_str(), audio.c_str(), subtitles.c_str());
- suspend();
_engine->playFilm(*this, video, audio, subtitles);
+ suspendIfPassive();
}
void Process::inventoryClear() {
@@ -1539,11 +1541,11 @@ void Process::moveCharacter(bool usermove) {
if (region) {
if (character->moveTo(_object->getName(), region->center, direction)) {
deactivate();
- suspend();
}
}
} else
warning("character %s could not be found", id.c_str());
+ suspendIfPassive();
}
void Process::moveCharacterUserMove() {
@@ -1596,6 +1598,7 @@ void Process::leaveCharacter(const Common::String &name, const Common::String &r
character->moveTo(getName(), region->center, dir);
} else
warning("character %s could not be found", name.c_str());
+ suspendIfPassive();
}
void Process::leaveCharacter() {
@@ -1638,13 +1641,14 @@ void Process::setCharacterDirection() {
character->direction(dir);
} else
warning("no character %s", name.c_str());
+ suspendIfPassive();
}
void Process::pointCharacter() {
Common::String arg2 = popString();
Common::String arg1 = popString();
debug("pointCharacter stub %s %s", arg1.c_str(), arg2.c_str());
- suspend();
+ suspendIfPassive();
}
void Process::getCharacterAnimationPhase() {
@@ -1686,12 +1690,12 @@ void Process::stopCharacter() {
character->direction(direction);
character->stop(getName());
deactivate();
- suspend();
} else {
character->stop();
}
} else
warning("could not find character %s", name.c_str());
+ suspendIfPassive();
}
void Process::fogOnCharacter() {
@@ -1781,8 +1785,7 @@ void Process::fadeScreen() {
debug("fadeScreen screen: %d, sound: %d music: %d", fadeScreen, fadeSound, fadeMusic);
_engine->curtain(getName(), fadeScreen, fadeSound, fadeMusic, true);
deactivate();
- if (passive())
- suspend();
+ suspendIfPassive();
}
void Process::setCharacterNotifyVars() {
Commit: f291793de042ff08007af7637082420c5baa5a17
https://github.com/scummvm/scummvm/commit/f291793de042ff08007af7637082420c5baa5a17
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:10+01:00
Commit Message:
AGDS: clean up process deactivation/waking up in character code, better pointTo stub
Changed paths:
engines/agds/agds.h
engines/agds/character.cpp
engines/agds/character.h
engines/agds/process.cpp
engines/agds/process_opcodes.cpp
engines/agds/textLayout.cpp
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index d210e0d0d48..35157cff4e7 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -278,6 +278,9 @@ public:
int getRandomNumber(int max);
void curtain(const Common::String &process, int screen, int sound, int music, bool updateGlobals);
+ bool activeCurtain() const {
+ return _curtainTimer >= 0;
+ }
private:
void stopAmbientSound();
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index bb8982fe0e7..be669cf17d4 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -153,9 +153,16 @@ bool Character::direction(int dir) {
return animate(dir, 100, false);
}
+void Character::notifyProcess(const Common::String & name) {
+ if (!_processName.empty())
+ _engine->reactivate(name, "Character::notifyProcess", false);
+
+ _processName = name;
+}
+
bool Character::moveTo(const Common::String & processName, Common::Point dst, int dir) {
debug("character move %d,%d %d", dst.x, dst.y, dir);
- _processName = processName;
+ notifyProcess(processName);
_pos = dst;
_visible = true;
bool r = direction(dir);
@@ -174,6 +181,11 @@ bool Character::moveTo(const Common::String & processName, Common::Point dst, in
return r;
}
+void Character::pointTo(const Common::String & processName, Common::Point dst) {
+ debug("character point to stub %d,%d, process: %s", dst.x, dst.y, processName.c_str());
+ notifyProcess(processName);
+}
+
bool Character::animate(int direction, int speed, bool jokes) {
if (_stopped)
_stopped = false;
@@ -205,17 +217,20 @@ bool Character::animate(int direction, int speed, bool jokes) {
return true;
}
-bool Character::animate(const Common::String & processName, Common::Point pos, int direction, int speed) {
+bool Character::animate(Common::Point pos, int direction, int speed) {
debug("animate character: %d,%d %d %d", pos.x, pos.y, direction, speed);
- _processName = processName;
+ auto ok = animate(direction, speed, true);
+ if (!ok)
+ return false;
+
_animationPos = pos;
- return animate(direction, speed, true);
+ return true;
}
void Character::stop(const Common::String &processName) {
debug("character %s: stop, process: %s", _object->getName().c_str(), processName.c_str());
- _processName = processName;
+ notifyProcess(processName);
stop();
}
@@ -225,11 +240,13 @@ void Character::stop() {
void Character::leave(const Common::String &processName) {
debug("character %s: leave, process: %s", _object->getName().c_str(), processName.c_str());
- _processName = processName;
+ notifyProcess(processName);
}
void Character::tick(bool reactivate) {
- if (active() && _animation) {
+ if (!active())
+ return;
+ if (_animation) {
auto screen = _engine->getCurrentScreen();
auto scale = screen? screen->getZScale(_pos.y): 1;
_animation->scale(scale);
@@ -244,11 +261,15 @@ void Character::tick(bool reactivate) {
_frames = 0;
if (wasJokes)
direction(_direction);
- if (reactivate && !_processName.empty())
- _engine->reactivate(_processName, "Character::tick");
}
+ return;
}
}
+
+ if (reactivate && !_processName.empty() && !_engine->activeCurtain()) {
+ _engine->reactivate(_processName, "Character::tick");
+ _processName.clear();
+ }
}
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 75202996cd7..e8e79a681d6 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -72,6 +72,8 @@ class Character {
Common::HashMap<int, AnimationDescription> _animations;
const AnimationDescription * _description;
+ void notifyProcess(const Common::String & name);
+
public:
Character(AGDSEngine * engine, const Common::String & name);
~Character();
@@ -108,7 +110,7 @@ public:
return _enabled && _visible && !_stopped;
}
- bool animate(const Common::String &processName, Common::Point pos, int direction, int speed);
+ bool animate(Common::Point pos, int direction, int speed);
bool animate(int direction, int speed, bool jokes);
void stop(const Common::String &processName);
@@ -128,6 +130,7 @@ public:
}
bool moveTo(const Common::String &processName, Common::Point dst, int direction);
+ void pointTo(const Common::String &processName, Common::Point dst);
bool direction(int dir);
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index d6daa341774..3c44db640af 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -184,7 +184,7 @@ void Process::activate() {
break;
case kStatusDone:
case kStatusError:
- debug("process %s finished", getName().c_str());
+ debug("finished");
break;
default:
break;
@@ -194,6 +194,7 @@ void Process::activate() {
void Process::deactivate() {
switch(status()) {
case kStatusActive:
+ debug("deactivated");
_status = Process::kStatusPassive;
break;
case kStatusDone:
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 74a03ef730e..59b00681547 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1562,9 +1562,9 @@ void Process::animateCharacter() {
debug("animateCharacter: %s %d %d", name.c_str(), direction, _animationSpeed);
Character *character = _engine->getCharacter(name);
- if (character)
- character->animate(_object->getName(), _animationPosition, direction, _animationSpeed);
- else
+ if (character) {
+ character->animate(_animationPosition, direction, _animationSpeed);
+ } else
warning("character %s could not be found", name.c_str());
}
@@ -1595,7 +1595,8 @@ void Process::leaveCharacter(const Common::String &name, const Common::String &r
if (character) {
RegionPtr region = _engine->loadRegion(regionName);
debug("region: %s", region->toString().c_str());
- character->moveTo(getName(), region->center, dir);
+ if (character->moveTo(getName(), region->center, dir))
+ deactivate();
} else
warning("character %s could not be found", name.c_str());
suspendIfPassive();
@@ -1645,9 +1646,18 @@ void Process::setCharacterDirection() {
}
void Process::pointCharacter() {
- Common::String arg2 = popString();
- Common::String arg1 = popString();
- debug("pointCharacter stub %s %s", arg1.c_str(), arg2.c_str());
+ Common::String regionName = popString();
+ Common::String id = popString();
+ debug("pointCharacter %s, region: %s", id.c_str(), regionName.c_str());
+ Character *character = _engine->getCharacter(id);
+ if (character) {
+ auto region = _engine->loadRegion(regionName);
+ if (region) {
+ character->pointTo(getName(), region->center);
+ deactivate();
+ }
+ } else
+ warning("character %s could not be found", id.c_str());
suspendIfPassive();
}
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index c9979ada1c8..063106a6fe9 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -109,7 +109,7 @@ void TextLayout::layout(AGDSEngine &engine, Process &process, const Common::Stri
case 15:
break;
default:
- character->animate(_process, Common::Point(), character->direction(), 100);
+ character->animate(Common::Point(), character->direction(), 100);
}
}
} else
Commit: c7a05a27da5a8f24537a7d69dfea53b034468000
https://github.com/scummvm/scummvm/commit/c7a05a27da5a8f24537a7d69dfea53b034468000
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:10+01:00
Commit Message:
AGDS: do not use click handler with inventory object attached
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index d483d948c97..2dafcf956ca 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -623,8 +623,7 @@ Common::Error AGDSEngine::run() {
}
if (ip)
debug("found use handler");
- }
- if (!ip) {
+ } else if (!ip) {
ip = object->getClickHandler();
if (ip) {
debug("found click handler");
Commit: 65a83cb694fe555a7b7753f1d6bc0b37af7ffa5c
https://github.com/scummvm/scummvm/commit/65a83cb694fe555a7b7753f1d6bc0b37af7ffa5c
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:10+01:00
Commit Message:
AGDS: print ip of each handler in log
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 59b00681547..8f8446d581f 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -642,7 +642,7 @@ void Process::onObjectUse(uint16 size) {
}
void Process::onObjectUserUse(uint16 size) {
- debug("register user use handler -> 0x%04x", _ip);
+ debug("user use [handler], %u instructions -> 0x%04x", size, _ip);
_object->setUserUseHandler(_ip);
_ip += size;
}
@@ -1448,37 +1448,37 @@ void Process::initialise(uint16 addr) {
void Process::onKey(uint16 size) {
Common::String key = popString();
- debug("onKey %s [handler], %u instructions", key.c_str(), size);
+ debug("onKey %s [handler], %u instructions, ip: 0x%04x", key.c_str(), size, _ip);
_object->setKeyHandler(key, _ip);
_ip += size;
}
void Process::onUse(uint16 size) {
- debug("lclick [handler], %u instructions", size);
+ debug("lclick [handler], %u instructions, ip: 0x%04x", size, _ip);
_object->setClickHandler(_ip);
_ip += size;
}
void Process::onObjectC1(uint16 size) {
- debug("unknown (0xc1) [handler] stub, %u instructions", size);
+ debug("unknown (0xc1) [handler] stub, %u instructions, ip: 0x%04x", size, _ip);
_ip += size;
}
void Process::onLook(uint16 size) {
- debug("look [handler], %u instructions", size);
+ debug("look [handler], %u instructions, ip: 0x%04x", size, _ip);
_object->setExamineHandler(_ip);
_ip += size;
}
void Process::onCharacterTrap(uint16 size) {
auto regionName = popString();
- debug("setCharacterTrap %s [handler], %u instructions", regionName.c_str(), size);
+ debug("setCharacterTrap %s [handler], %u instructions, ip: 0x%04x", regionName.c_str(), size, _ip);
_object->setTrapHandler(_ip, _engine->loadRegion(regionName));
_ip += size;
}
void Process::onObjectBD(uint16 size) {
- debug("onObject(+BD) [handler] stub, %u instructions", size);
+ debug("onObject(+BD) [handler] stub, %u instructions, ip: 0x%04x", size, _ip);
_ip += size;
}
Commit: 44aa1f71900a3901069443cfedb4ed4366d572a5
https://github.com/scummvm/scummvm/commit/44aa1f71900a3901069443cfedb4ed4366d572a5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:10+01:00
Commit Message:
AGDS: split visible/shown as visible character may be removed from the screen
Almost every puzzle/book screen has a visible character although it's removed from the screen.
To make it reappear you need to add it back via move/animate/direct/point etc.
Changed paths:
engines/agds/agds.cpp
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 2dafcf956ca..52aee5f41a4 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -332,6 +332,14 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
debug("loadScreen %s [type: %d, save patch: %d, previous: %s]", name.c_str(), static_cast<int>(loadingType), savePatch, _currentScreenName.c_str());
if (savePatch)
saveScreenPatch();
+
+ if (_currentCharacter && _currentCharacter->visible()) {
+ _currentCharacter->reset();
+ if (loadingType != ScreenLoadingType::Normal) {
+ _currentCharacter->visible(false);
+ }
+ }
+
resetCurrentInventoryObject();
{
bool userEnabled = _userEnabled;
@@ -352,10 +360,6 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
bool doPatch = patch && loadingType != ScreenLoadingType::SaveOrLoad;
bool hasScreenPatch = doPatch && patch->screenSaved;
- if (_currentCharacter) {
- _currentCharacter->reset();
- }
-
_currentScreenName = name;
_currentScreen = nullptr;
auto screenObject = loadObject(name, Common::String(), !hasScreenPatch);
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index be669cf17d4..195d39705e0 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -41,7 +41,7 @@ namespace AGDS {
Character::Character(AGDSEngine * engine, const Common::String & name):
_engine(engine), _name(name), _object(), _animation(nullptr), _jokes(false),
- _enabled(true), _visible(false), _stopped(false),
+ _enabled(true), _visible(false), _shown(false), _stopped(false),
_phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
}
@@ -115,6 +115,9 @@ void Character::associate(const Common::String &name) {
}
void Character::visible(bool visible) {
+ if (visible) {
+ _shown = true;
+ }
_visible = visible;
}
@@ -164,7 +167,7 @@ bool Character::moveTo(const Common::String & processName, Common::Point dst, in
debug("character move %d,%d %d", dst.x, dst.y, dir);
notifyProcess(processName);
_pos = dst;
- _visible = true;
+ _shown = true;
bool r = direction(dir);
auto *screen = _engine->getCurrentScreen();
@@ -184,6 +187,7 @@ bool Character::moveTo(const Common::String & processName, Common::Point dst, in
void Character::pointTo(const Common::String & processName, Common::Point dst) {
debug("character point to stub %d,%d, process: %s", dst.x, dst.y, processName.c_str());
notifyProcess(processName);
+ _shown = true;
}
bool Character::animate(int direction, int speed, bool jokes) {
@@ -194,7 +198,7 @@ bool Character::animate(int direction, int speed, bool jokes) {
return false;
_description = nullptr;
- _visible = true;
+ _shown = true;
_stopped = false;
auto character = jokes? _engine->jokes(): this;
_description = character->animationDescription(direction);
@@ -274,7 +278,7 @@ void Character::tick(bool reactivate) {
void Character::paint(Graphics::Surface &backbuffer, Common::Point pos) const {
- if (!_enabled || !_visible || !_animation)
+ if (!_enabled || !visible()|| !_animation)
return;
pos += _pos + _animationPos;
@@ -312,7 +316,7 @@ int Character::z() const {
void Character::reset() {
_fog.reset();
- _visible = false;
+ _shown = false;
}
void Character::setFog(Graphics::ManagedSurface * surface, int minZ, int maxZ) {
diff --git a/engines/agds/character.h b/engines/agds/character.h
index e8e79a681d6..484e6b63185 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -52,6 +52,7 @@ class Character {
Common::Point _animationPos;
bool _enabled;
bool _visible;
+ bool _shown;
bool _stopped;
int _phase;
int _frames;
@@ -103,7 +104,7 @@ public:
void visible(bool visible);
bool visible() const {
- return _visible;
+ return _visible && _shown;
}
bool active() const {
Commit: c335e81f1b608c190edce91c65994c1683c24642
https://github.com/scummvm/scummvm/commit/c335e81f1b608c190edce91c65994c1683c24642
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:10+01:00
Commit Message:
AGDS: reset character animation on screen change
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 195d39705e0..d2cdd8f40bc 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -317,6 +317,9 @@ int Character::z() const {
void Character::reset() {
_fog.reset();
_shown = false;
+ _animation.reset();
+ _phase = -1;
+ _frames = 0;
}
void Character::setFog(Graphics::ManagedSurface * surface, int minZ, int maxZ) {
Commit: 73f0fd8391a1a565014090e4b08fd907dac74dde
https://github.com/scummvm/scummvm/commit/73f0fd8391a1a565014090e4b08fd907dac74dde
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:10+01:00
Commit Message:
AGDS: store BD/C1 handlers in object
It looks like they both act of some sort of override.
Normally lclick is disabled when you have attached inventory object or you can lose current object.
BD/C1 handlers are found on little arrows in inventory and it allows clicking even with attached object.
Changed paths:
engines/agds/agds.cpp
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 52aee5f41a4..41eac039ce8 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -627,6 +627,13 @@ Common::Error AGDSEngine::run() {
}
if (ip)
debug("found use handler");
+ if (!ip) {
+ ip = object->getHandlerC1();
+ if (ip) {
+ debug("found C1 handler");
+ runObject = object;
+ }
+ }
} else if (!ip) {
ip = object->getClickHandler();
if (ip) {
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index ce028d190a3..9b80d52fb7b 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -40,6 +40,7 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_pos(), _z(10), _rotation(0),
_clickHandler(0), _examineHandler(0), _userUseHandler(0),
_throwHandler(0), _useOnHandler(0),
+ _handlerBD(0), _handlerC1(0),
_alpha(255), _scale(100), _locked(0), _alive(true),
_persistent(true), _allowInitialise(true),
_ignoreRegion(false) {
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 16e9ccf9bb4..a91e9b2bd37 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -84,6 +84,8 @@ private:
uint _throwHandler;
uint _useOnHandler;
uint _trapHandler;
+ uint _handlerBD;
+ uint _handlerC1;
int _alpha;
int _scale;
uint _locked;
@@ -239,6 +241,22 @@ public:
return _userUseHandler;
}
+ void setHandlerBD(uint ip) {
+ _handlerBD = ip;
+ }
+
+ uint getHandlerBD() const {
+ return _handlerBD;
+ }
+
+ void setHandlerC1(uint ip) {
+ _handlerC1 = ip;
+ }
+
+ uint getHandlerC1() const {
+ return _handlerC1;
+ }
+
void setTrapHandler(uint ip, RegionPtr region) {
_trapHandler = ip;
_trapRegion = region;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 8f8446d581f..709da2fa9ba 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1460,7 +1460,8 @@ void Process::onUse(uint16 size) {
}
void Process::onObjectC1(uint16 size) {
- debug("unknown (0xc1) [handler] stub, %u instructions, ip: 0x%04x", size, _ip);
+ debug("lclick [fallback for attached inventory object] [handler] stub, %u instructions, ip: 0x%04x", size, _ip);
+ _object->setHandlerC1(_ip);
_ip += size;
}
@@ -1479,6 +1480,7 @@ void Process::onCharacterTrap(uint16 size) {
void Process::onObjectBD(uint16 size) {
debug("onObject(+BD) [handler] stub, %u instructions, ip: 0x%04x", size, _ip);
+ _object->setHandlerBD(_ip);
_ip += size;
}
Commit: 320fe5ce86391b23591ead864bf4086a7749b9d6
https://github.com/scummvm/scummvm/commit/320fe5ce86391b23591ead864bf4086a7749b9d6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:10+01:00
Commit Message:
AGDS: remove _stopped flag from character
it seems it only affects movement which is not implemented yet.
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index d2cdd8f40bc..67691e38ac6 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -41,7 +41,7 @@ namespace AGDS {
Character::Character(AGDSEngine * engine, const Common::String & name):
_engine(engine), _name(name), _object(), _animation(nullptr), _jokes(false),
- _enabled(true), _visible(false), _shown(false), _stopped(false),
+ _enabled(true), _visible(false), _shown(false),
_phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
}
@@ -191,15 +191,11 @@ void Character::pointTo(const Common::String & processName, Common::Point dst) {
}
bool Character::animate(int direction, int speed, bool jokes) {
- if (_stopped)
- _stopped = false;
-
if (direction == -1 || !_enabled)
return false;
_description = nullptr;
_shown = true;
- _stopped = false;
auto character = jokes? _engine->jokes(): this;
_description = character->animationDescription(direction);
auto animation = _description? _engine->loadAnimation(_description->filename): nullptr;
@@ -239,7 +235,6 @@ void Character::stop(const Common::String &processName) {
}
void Character::stop() {
- _stopped = true;
}
void Character::leave(const Common::String &processName) {
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 484e6b63185..daeb97200f1 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -53,7 +53,6 @@ class Character {
bool _enabled;
bool _visible;
bool _shown;
- bool _stopped;
int _phase;
int _frames;
int _direction;
@@ -108,7 +107,7 @@ public:
}
bool active() const {
- return _enabled && _visible && !_stopped;
+ return _enabled && _visible;
}
bool animate(Common::Point pos, int direction, int speed);
Commit: be9ee673e16d74869a7345bb3e7c03bde276de08
https://github.com/scummvm/scummvm/commit/be9ee673e16d74869a7345bb3e7c03bde276de08
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:10+01:00
Commit Message:
AGDS: name opcodes 43 and 44
Changed paths:
engines/agds/opcode.h
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index d1c0d407cc6..8f9a81d8db2 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -62,8 +62,8 @@ enum Opcode {
kBoolOr = 40,
kBoolNot = 41,
kNegate = 42,
- kStub43 = 43,
- kStub44 = 44,
+ kPreIncrementGlobal = 43,
+ kPreDecrementGlobal = 44,
kPostIncrementGlobal = 45,
kPostDecrementGlobal = 46,
kSetGlobalWithTop = 47,
Commit: 8ba083dd9408c3fbf4d8406259a5621013bb6a08
https://github.com/scummvm/scummvm/commit/8ba083dd9408c3fbf4d8406259a5621013bb6a08
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:11+01:00
Commit Message:
AGDS: perform object removal when the last process exits, call removeProcessAnimation from remove object, not from process exit handler
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/console.cpp
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 41eac039ce8..bf90bd04cca 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1391,17 +1391,13 @@ void AGDSEngine::runPendingReactivatedProcesses() {
}
}
-void AGDSEngine::stopProcess(const Common::String & name) {
- auto *screen = getCurrentScreen();
+ProcessPtr AGDSEngine::findProcess(const Common::String & name) const {
for(uint i = 0; i < _processes.size(); ++i) {
- ProcessPtr &process = _processes[i];
- if (process && process->getName() == name) {
- debug("stopping %s...", name.c_str());
- process->done();
- // Original engine removes global animations only from object reinitialisation.
- screen->remove(process->processAnimation());
- }
+ const ProcessPtr &process = _processes[i];
+ if (process && !process->finished() && process->getName() == name)
+ return process;
}
+ return {};
}
void AGDSEngine::currentInventoryObject(const ObjectPtr & object) {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 35157cff4e7..5f664d26afb 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -126,8 +126,7 @@ public:
ObjectPtr runObject(const Common::String & name, const Common::String &prototype = Common::String(), bool allowInitialise = true);
void runObject(const ObjectPtr &object);
void runProcess(const ObjectPtr &object, uint ip = 0);
- void stopProcess(const Common::String & name);
- void stopProcessForObject(const Common::String & name);
+ ProcessPtr findProcess(const Common::String & name) const;
void reactivate(const Common::String &name, const Common::String &where, bool runNow = false);
bool hasActiveProcesses(const Common::String &name) const;
void runPendingReactivatedProcesses();
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index 631d6541f06..0d5482c2ce6 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -81,7 +81,12 @@ bool Console::stop(int argc, const char **argv) {
return true;
}
_engine->getCurrentScreen()->remove(object);
- _engine->stopProcess(argv[1]);
+ auto process = _engine->findProcess(argv[1]);
+ if (!process) {
+ debugPrintf("no process %s\n", argv[1]);
+ return true;
+ }
+ process->done();
detach();
return false;
}
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 3c44db640af..28d9941479e 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -177,6 +177,15 @@ void Process::setupAnimation(const AnimationPtr & animation) {
_engine->setGlobal(_phaseVar, 0);
}
+void Process::removeProcessAnimation() {
+ if (_processAnimation) {
+ auto * screen = _engine->getCurrentScreen();
+ if (screen)
+ screen->remove(_processAnimation);
+ _processAnimation = nullptr;
+ }
+}
+
void Process::activate() {
switch(status()) {
case kStatusPassive:
@@ -206,15 +215,18 @@ void Process::deactivate() {
}
void Process::done() {
- _status = kStatusDone;
- if (!_stack.empty())
- warning("process %s finished with non-empty stack", getName().c_str());
+ if (_status != kStatusDone) {
+ debug("done");
+ _status = kStatusDone;
+ if (!_stack.empty())
+ warning("process %s finished with non-empty stack", getName().c_str());
+ }
}
+
void Process::fail() {
_status = kStatusError;
}
-
void Process::run() {
bool restart = true;
while(_status != kStatusDone && _status != kStatusError && restart) {
@@ -224,16 +236,8 @@ void Process::run() {
case kExitCodeDestroy:
debug("process %s returned destroy exit code", getName().c_str());
done();
- if (_processAnimation) {
- auto * screen = _engine->getCurrentScreen();
- if (screen)
- screen->remove(_processAnimation);
- _processAnimation = nullptr;
- }
if (!getObject()->alive() && !_engine->hasActiveProcesses(getName())) {
- auto * screen = _engine->getCurrentScreen();
- if (screen)
- screen->remove(getName());
+ removeScreenObject(getName());
}
break;
case kExitCodeLoadScreenObjectAs:
diff --git a/engines/agds/process.h b/engines/agds/process.h
index fa548b2fe10..820ed71037f 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -206,6 +206,8 @@ public:
const AnimationPtr &processAnimation() const {
return _processAnimation;
}
+
+ void removeProcessAnimation();
};
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 709da2fa9ba..925023aea38 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -302,7 +302,14 @@ void Process::removeScreenObject(const Common::String &name) {
_object->lock();
screen->remove(object);
if (!object->locked()) {
- _engine->stopProcess(name);
+ ProcessPtr process;
+ do {
+ process = _engine->findProcess(name);
+ if (process) {
+ process->removeProcessAnimation();
+ process->done();
+ }
+ } while(process);
_engine->soundManager().stopAllFrom(name);
}
_object->unlock();
Commit: bb5f249b7444683c79262bef60b1fe2f81891f9b
https://github.com/scummvm/scummvm/commit/bb5f249b7444683c79262bef60b1fe2f81891f9b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:11+01:00
Commit Message:
AGDS: reimplement stopped flag
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 67691e38ac6..cde14962eea 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -41,7 +41,7 @@ namespace AGDS {
Character::Character(AGDSEngine * engine, const Common::String & name):
_engine(engine), _name(name), _object(), _animation(nullptr), _jokes(false),
- _enabled(true), _visible(false), _shown(false),
+ _enabled(true), _visible(false), _stopped(false), _shown(false),
_phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
}
@@ -219,6 +219,11 @@ bool Character::animate(int direction, int speed, bool jokes) {
bool Character::animate(Common::Point pos, int direction, int speed) {
debug("animate character: %d,%d %d %d", pos.x, pos.y, direction, speed);
+ if (_stopped) {
+ debug("character stopped, skipping");
+ _stopped = false;
+ return true;
+ }
auto ok = animate(direction, speed, true);
if (!ok)
return false;
@@ -235,6 +240,7 @@ void Character::stop(const Common::String &processName) {
}
void Character::stop() {
+ _stopped = true;
}
void Character::leave(const Common::String &processName) {
@@ -250,7 +256,7 @@ void Character::tick(bool reactivate) {
auto scale = screen? screen->getZScale(_pos.y): 1;
_animation->scale(scale);
- if (_phase >= 0 && _phase < _frames) {
+ if (!_stopped && _phase >= 0 && _phase < _frames) {
_animation->tick();
_phase = _animation->phase();
if (_phase >= _frames) {
diff --git a/engines/agds/character.h b/engines/agds/character.h
index daeb97200f1..446fdfabc49 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -52,6 +52,7 @@ class Character {
Common::Point _animationPos;
bool _enabled;
bool _visible;
+ bool _stopped;
bool _shown;
int _phase;
int _frames;
Commit: e04f2d42ac60f551b1f325704ae4039b01453b0f
https://github.com/scummvm/scummvm/commit/e04f2d42ac60f551b1f325704ae4039b01453b0f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:11+01:00
Commit Message:
AGDS: do not mutate character state if animation wasn't found
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index cde14962eea..36c315fbb5c 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -194,15 +194,19 @@ bool Character::animate(int direction, int speed, bool jokes) {
if (direction == -1 || !_enabled)
return false;
- _description = nullptr;
- _shown = true;
auto character = jokes? _engine->jokes(): this;
- _description = character->animationDescription(direction);
- auto animation = _description? _engine->loadAnimation(_description->filename): nullptr;
- if (!animation) {
+ auto description = character->animationDescription(direction);
+ if (!description) {
warning("no %s animation %d", jokes? "jokes": "character", direction);
return false;
}
+ auto animation = _engine->loadAnimation(description->filename);
+ if (!animation) {
+ warning("no %s animation file %s", jokes? "jokes": "character", description->filename.c_str());
+ return false;
+ }
+ _description = description;
+ _shown = true;
_animation = animation;
_animation->speed(speed);
_animation->rewind();
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 446fdfabc49..04d364f9b96 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -75,6 +75,8 @@ class Character {
void notifyProcess(const Common::String & name);
+ bool animate(int direction, int speed, bool jokes);
+
public:
Character(AGDSEngine * engine, const Common::String & name);
~Character();
@@ -112,7 +114,6 @@ public:
}
bool animate(Common::Point pos, int direction, int speed);
- bool animate(int direction, int speed, bool jokes);
void stop(const Common::String &processName);
void stop();
Commit: 2cd4683ccce27f72b323721f33554770832cdbec
https://github.com/scummvm/scummvm/commit/2cd4683ccce27f72b323721f33554770832cdbec
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:11+01:00
Commit Message:
AGDS: remove stop(process)
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 36c315fbb5c..c19b45a1032 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -157,6 +157,7 @@ bool Character::direction(int dir) {
}
void Character::notifyProcess(const Common::String & name) {
+ debug("%s:notifyProcess %s", _name.c_str(), name.c_str());
if (!_processName.empty())
_engine->reactivate(name, "Character::notifyProcess", false);
@@ -237,12 +238,6 @@ bool Character::animate(Common::Point pos, int direction, int speed) {
return true;
}
-void Character::stop(const Common::String &processName) {
- debug("character %s: stop, process: %s", _object->getName().c_str(), processName.c_str());
- notifyProcess(processName);
- stop();
-}
-
void Character::stop() {
_stopped = true;
}
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 04d364f9b96..515fd3ff209 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -73,8 +73,6 @@ class Character {
Common::HashMap<int, AnimationDescription> _animations;
const AnimationDescription * _description;
- void notifyProcess(const Common::String & name);
-
bool animate(int direction, int speed, bool jokes);
public:
@@ -115,7 +113,6 @@ public:
bool animate(Common::Point pos, int direction, int speed);
- void stop(const Common::String &processName);
void stop();
void leave(const Common::String &processName);
@@ -131,6 +128,7 @@ public:
return _pos;
}
+ void notifyProcess(const Common::String & processName);
bool moveTo(const Common::String &processName, Common::Point dst, int direction);
void pointTo(const Common::String &processName, Common::Point dst);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 925023aea38..bf6126744a1 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1707,7 +1707,7 @@ void Process::stopCharacter() {
if (character) {
if (direction != -1) {
character->direction(direction);
- character->stop(getName());
+ character->notifyProcess(getName());
deactivate();
} else {
character->stop();
Commit: a8187559562b547f5900c79825b11d4885efddd9
https://github.com/scummvm/scummvm/commit/a8187559562b547f5900c79825b11d4885efddd9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:11+01:00
Commit Message:
AGDS: renamed getPhase to phase(), add setter phase(phase)
Changed paths:
engines/agds/character.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 515fd3ff209..493b99fdcdb 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -116,9 +116,12 @@ public:
void stop();
void leave(const Common::String &processName);
- int getPhase() const {
+ int phase() const {
return _jokes? _phase: -1;
}
+ void phase(int phase) {
+ _phase = phase;
+ }
void position(Common::Point pos) {
_pos = pos;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index bf6126744a1..ed2b57b3388 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1676,7 +1676,7 @@ void Process::getCharacterAnimationPhase() {
Character *character = _engine->getCharacter(name);
if (!character)
warning("no character %s", name.c_str());
- int phase = character ? character->getPhase() : -1;
+ int phase = character ? character->phase() : -1;
debug("animation phase = %d", phase);
push(phase);
}
Commit: 9d5bc80bd309fdc695df9da5e40ef1741f825d34
https://github.com/scummvm/scummvm/commit/9d5bc80bd309fdc695df9da5e40ef1741f825d34
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:11+01:00
Commit Message:
AGDS: do not reset direction in setCharacter
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index ed2b57b3388..4b9d1e39276 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1631,6 +1631,8 @@ void Process::setCharacter() {
debug("setCharacter %s %s %d", id.c_str(), regionName.c_str(), dir);
auto character = _engine->getCharacter(id);
if (character) {
+ if (dir == -1)
+ dir = character->direction();
auto region = _engine->loadRegion(regionName);
if (region) {
debug("setting character position to %d,%d", region->center.x, region->center.y);
Commit: 4cf6f7f05ef44d43b4837ae5808160c98c36d6e6
https://github.com/scummvm/scummvm/commit/4cf6f7f05ef44d43b4837ae5808160c98c36d6e6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:11+01:00
Commit Message:
AGDS: move does not work on invisible character
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index c19b45a1032..29afb5799a9 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -165,6 +165,9 @@ void Character::notifyProcess(const Common::String & name) {
}
bool Character::moveTo(const Common::String & processName, Common::Point dst, int dir) {
+ if (!_visible)
+ return false;
+
debug("character move %d,%d %d", dst.x, dst.y, dir);
notifyProcess(processName);
_pos = dst;
Commit: ff99fc0a0995060ac3437f8e9f4150100d19c3bc
https://github.com/scummvm/scummvm/commit/ff99fc0a0995060ac3437f8e9f4150100d19c3bc
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:11+01:00
Commit Message:
AGDS: remove animation skip hack
Now character is properly synchronised and activates its process only in a few places.
This fixes herman scene in chapter 5
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 29afb5799a9..6d297997303 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -148,10 +148,6 @@ bool Character::direction(int dir) {
if (dir < 0)
return false;
- if (_jokes && _phase < _frames) {
- debug("direction(%d) set during active animation, ignored", dir);
- return false;
- }
_animationPos = Common::Point();
return animate(dir, 100, false);
}
Commit: c754e2709d2d5ed73d09e3b2ec97c1027f122e79
https://github.com/scummvm/scummvm/commit/c754e2709d2d5ed73d09e3b2ec97c1027f122e79
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:11+01:00
Commit Message:
AGDS: generalise stop flag check
Changed paths:
engines/agds/character.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 6d297997303..bf2012054d9 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -194,6 +194,12 @@ bool Character::animate(int direction, int speed, bool jokes) {
if (direction == -1 || !_enabled)
return false;
+ if (_stopped) {
+ debug("character stopped, skipping");
+ _stopped = false;
+ return false;
+ }
+
auto character = jokes? _engine->jokes(): this;
auto description = character->animationDescription(direction);
if (!description) {
@@ -223,11 +229,6 @@ bool Character::animate(int direction, int speed, bool jokes) {
bool Character::animate(Common::Point pos, int direction, int speed) {
debug("animate character: %d,%d %d %d", pos.x, pos.y, direction, speed);
- if (_stopped) {
- debug("character stopped, skipping");
- _stopped = false;
- return true;
- }
auto ok = animate(direction, speed, true);
if (!ok)
return false;
Commit: 1c6e8538b11ef55884b135f298695fe1e0fcac1a
https://github.com/scummvm/scummvm/commit/1c6e8538b11ef55884b135f298695fe1e0fcac1a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:11+01:00
Commit Message:
AGDS: create a patch for decref
Changed paths:
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 4b9d1e39276..7ec45322c6c 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -824,12 +824,9 @@ void Process::screenObjectPatchDecRef() {
warning("attempt to change screen patch (%s) in patching process (%s)", objectName.c_str(), screenName.c_str());
} else {
//fixme: add non-existent screen check?
- auto patch = _engine->getPatch(screenName);
- if (patch) {
- int refs = patch->decRef(objectName);
- debug("decrement refcount for object %s, result: %d", objectName.c_str(), refs);
- } else
- debug("decrement refcount for object %s, no patch for screen %s", objectName.c_str(), screenName.c_str());
+ auto patch = _engine->createPatch(screenName);
+ int refs = patch->decRef(objectName);
+ debug("decrement refcount for object %s, result: %d", objectName.c_str(), refs);
}
} else {
debug("screenObjectPatchDecRef: current screen, removing object");
Commit: 21ba09d2ef8d2e6e5a9a1fd343eca107b6201bc3
https://github.com/scummvm/scummvm/commit/21ba09d2ef8d2e6e5a9a1fd343eca107b6201bc3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:12+01:00
Commit Message:
AGDS: add patch screen [object flag] command
Changed paths:
engines/agds/console.cpp
engines/agds/console.h
engines/agds/patch.cpp
engines/agds/patch.h
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index 0d5482c2ce6..74933a80c90 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -24,6 +24,7 @@
#include "agds/agds.h"
#include "agds/animation.h"
#include "agds/object.h"
+#include "agds/patch.h"
#include "agds/process.h"
#include "agds/screen.h"
@@ -37,6 +38,7 @@ Console::Console(AGDSEngine *engine) : _engine(engine) {
registerCmd("stop", WRAP_METHOD(Console, stop));
registerCmd("set", WRAP_METHOD(Console, setGlobal));
registerCmd("invadd", WRAP_METHOD(Console, inventoryAdd));
+ registerCmd("patch", WRAP_METHOD(Console, patch));
}
bool Console::load(int argc, const char **argv) {
@@ -152,4 +154,36 @@ bool Console::inventoryAdd(int argc, const char **argv) {
return true;
}
+bool Console::patch(int argc, const char **argv) {
+ if (argc != 2 && argc != 4) {
+ debugPrintf("usage: %s screen [object flag]\n", argv[0]);
+ return true;
+ }
+ if (argc == 2) {
+ auto patch = _engine->getPatch(argv[1]);
+ if (!patch) {
+ debugPrintf("no patch for %s found.", argv[1]);
+ return true;
+ }
+ debugPrintf("screen saved: %d\n", patch->screenSaved);
+ debugPrintf("screen region: %s\n", patch->screenRegionName.c_str());
+ debugPrintf("previous screen: %s\n", patch->prevScreenName.c_str());
+ debugPrintf("screen loading type: %d\n", static_cast<int>(patch->loadingType));
+ debugPrintf("character pos: %d,%d, direction: %d, present: %d\n", patch->characterPosition.x, patch->characterPosition.y, patch->characterDirection, patch->characterPresent);
+ debugPrintf("mouse cursor: %s\n", patch->defaultMouseCursor.c_str());
+ for(auto & object: patch->objects) {
+ debugPrintf(" - object %s: present: %d\n", object.name.c_str(), object.flag);
+ }
+ } else if (argc == 4) {
+ auto patch = _engine->getPatch(argv[1]);
+ if (!patch)
+ debugPrintf("no patch found, creating...\n");
+ patch = _engine->createPatch(argv[1]);
+ patch->setFlag(argv[2], atoi(argv[3]));
+ }
+
+ detach();
+ return true;
+}
+
}
diff --git a/engines/agds/console.h b/engines/agds/console.h
index e19800575ba..1dacd1263fa 100644
--- a/engines/agds/console.h
+++ b/engines/agds/console.h
@@ -43,6 +43,7 @@ private:
bool info(int argc, const char **argv);
bool setGlobal(int argc, const char **argv);
bool inventoryAdd(int argc, const char **argv);
+ bool patch(int argc, const char **argv);
AGDSEngine *_engine;
};
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index 87acc800b65..d15fcc08511 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -70,6 +70,16 @@ void Patch::save(Common::WriteStream *stream) {
}
}
+void Patch::setFlag(const Common::String & name, int flag) {
+ for(auto & object : objects) {
+ if (object.name == name) {
+ object.flag = flag;
+ return;
+ }
+ }
+ objects.push_back({name, flag});
+}
+
int Patch::getFlag(const Common::String & name) const {
for(auto & object : objects) {
if (object.name == name)
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index 23ed507a479..f26a1a2845a 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -69,6 +69,7 @@ struct Patch {
void load(Common::ReadStream *stream);
void save(Common::WriteStream *stream);
+ void setFlag(const Common::String & name, int flag);
int getFlag(const Common::String & name) const;
int incRef(const Common::String & name);
int decRef(const Common::String & name);
Commit: 1e162cf681473554675049220ebe9f46e9ff1dce
https://github.com/scummvm/scummvm/commit/1e162cf681473554675049220ebe9f46e9ff1dce
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:12+01:00
Commit Message:
AGDS: do not output OP, use just NAME
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 28d9941479e..1dc80348b0b 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -316,7 +316,7 @@ void Process::run() {
}
#define UNARY_OP(NAME, OP) void Process:: NAME () { int arg = pop(); debug(#NAME " %d", arg); push( OP arg ); }
-#define BINARY_OP(NAME, OP) void Process:: NAME () { int arg2 = pop(); int arg1 = pop(); debug(#NAME " %d " #OP " %d", arg1, arg2); push(arg1 OP arg2); }
+#define BINARY_OP(NAME, OP) void Process:: NAME () { int arg2 = pop(); int arg1 = pop(); debug(" %d " #NAME " %d", arg1, arg2); push(arg1 OP arg2); }
UNARY_OP(boolNot, !)
UNARY_OP(bitNot, ~)
Commit: fd6fb513f1ce0cb8f2d3decdd597ab237f60b74d
https://github.com/scummvm/scummvm/commit/fd6fb513f1ce0cb8f2d3decdd597ab237f60b74d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:12+01:00
Commit Message:
AGDS: fix case phase var == -1, this means nextAnimationFrame will restart the animation
Changed paths:
engines/agds/animation.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 125ea69e4be..73123bea9e8 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -156,6 +156,11 @@ void Animation::rescaleCurrentFrame() {
}
void Animation::decodeNextFrame() {
+ if (ended()) {
+ _phase = 0;
+ _flic->rewind();
+ }
+
auto frame = _flic->decodeNextFrame();
if (!frame) {
debug("frame of %s couldn't be decoded, process: %s, phase var: %s, at end: %d", _name.c_str(), _process.c_str(), _phaseVar.c_str(), _flic->endOfVideo());
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 7ec45322c6c..c9275fddb91 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1072,7 +1072,7 @@ void Process::restartAnimation() {
void Process::animationNextFrame() {
Common::String phaseVar = popString();
- debug("animationGetCurrentFrame %s", phaseVar.c_str());
+ debug("animationNextFrame %s", phaseVar.c_str());
if (phaseVar.empty()) {
warning("no phaseVar");
return;
@@ -1083,7 +1083,7 @@ void Process::animationNextFrame() {
if (value >= -1) {
if (!animation->ended() || value == -1) {
animation->decodeNextFrame();
- _engine->setGlobal(phaseVar, animation->ended()? -1: animation->phase());
+ _engine->setGlobal(phaseVar, animation->phase() - 1);
} else {
_engine->setGlobal(phaseVar, -1);
}
Commit: 967b15fff8980ce3c39565d719c2dc2a57f3a6ea
https://github.com/scummvm/scummvm/commit/967b15fff8980ce3c39565d719c2dc2a57f3a6ea
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:12+01:00
Commit Message:
AGDS: fix reactivation of character process (point seems to reactivate it - stub)
Changed paths:
engines/agds/character.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index bf2012054d9..09f0ef41bf1 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -187,6 +187,10 @@ bool Character::moveTo(const Common::String & processName, Common::Point dst, in
void Character::pointTo(const Common::String & processName, Common::Point dst) {
debug("character point to stub %d,%d, process: %s", dst.x, dst.y, processName.c_str());
notifyProcess(processName);
+ if (!_processName.empty() && !_engine->activeCurtain()) {
+ _engine->reactivate(_processName, "Character::pointTo");
+ _processName.clear();
+ }
_shown = true;
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index c9275fddb91..86ffdecf0ff 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1661,8 +1661,9 @@ void Process::pointCharacter() {
if (character) {
auto region = _engine->loadRegion(regionName);
if (region) {
- character->pointTo(getName(), region->center);
deactivate();
+ // Point to is stub, and it reactivates process based on internal state.
+ character->pointTo(getName(), region->center);
}
} else
warning("character %s could not be found", id.c_str());
Commit: 770936f4c343eb20a147cc0edb4be4ddfced7e78
https://github.com/scummvm/scummvm/commit/770936f4c343eb20a147cc0edb4be4ddfced7e78
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:12+01:00
Commit Message:
AGDS: return character object to use with anything
Character object contains only one handler - dagger. This fixes the final screen.
Changed paths:
engines/agds/character.cpp
engines/agds/character.h
engines/agds/screen.cpp
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 09f0ef41bf1..1485f4753af 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -280,24 +280,40 @@ void Character::tick(bool reactivate) {
}
}
+bool Character::pointIn(Common::Point pos) const {
+ if (!_animation)
+ return false;
-void Character::paint(Graphics::Surface &backbuffer, Common::Point pos) const {
- if (!_enabled || !visible()|| !_animation)
- return;
-
- pos += _pos + _animationPos;
+ Common::Rect rect(_animation->width(), _animation->height());
+ rect.moveTo(animationPosition());
+ return rect.contains(pos);
+}
- pos.y -= _animation->visibleHeight();
- pos.x -= _animation->visibleCenter();
+Common::Point Character::animationPosition() const {
+ Common::Point pos = _pos + _animationPos;
- if (_description) {
- auto &frames = _description->frames;
- if (_phase >= 0 && _phase < static_cast<int>(frames.size())) {
- auto &frame = frames[_phase];
- pos.x += frame.x * _animation->scale();
- pos.y += frame.y * _animation->scale();
+ if (_animation) {
+ pos.y -= _animation->visibleHeight();
+ pos.x -= _animation->visibleCenter();
+
+ if (_description) {
+ auto &frames = _description->frames;
+ if (_phase >= 0 && _phase < static_cast<int>(frames.size())) {
+ auto &frame = frames[_phase];
+ pos.x += frame.x * _animation->scale();
+ pos.y += frame.y * _animation->scale();
+ }
}
}
+ return pos;
+}
+
+
+void Character::paint(Graphics::Surface &backbuffer, Common::Point pos) const {
+ if (!_enabled || !visible()|| !_animation)
+ return;
+
+ pos += animationPosition();
int fogAlpha = 0;
if (_fog) {
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 493b99fdcdb..035c80d44e0 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -74,6 +74,7 @@ class Character {
const AnimationDescription * _description;
bool animate(int direction, int speed, bool jokes);
+ Common::Point animationPosition() const;
public:
Character(AGDSEngine * engine, const Common::String & name);
@@ -130,6 +131,7 @@ public:
Common::Point position() const {
return _pos;
}
+ bool pointIn(Common::Point pos) const;
void notifyProcess(const Common::String & processName);
bool moveTo(const Common::String &processName, Common::Point dst, int direction);
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index c696314e916..18ad91242b2 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -292,6 +292,12 @@ Common::Array<ObjectPtr> Screen::find(Common::Point pos) const {
objects.insert_at(0, object);
}
}
+ Character * character = _engine->currentCharacter();
+ if (character) {
+ if (character->pointIn(pos - _scroll)) {
+ objects.insert_at(0, character->object());
+ }
+ }
return objects;
}
Commit: 50aea89071945ea2d34dc489b4b84393db60d5af
https://github.com/scummvm/scummvm/commit/50aea89071945ea2d34dc489b4b84393db60d5af
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:12+01:00
Commit Message:
AGDS: animation end sets phase var to -1
Changed paths:
engines/agds/animation.cpp
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 73123bea9e8..f3237c716d5 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -205,7 +205,7 @@ bool Animation::tick() {
}
bool eov = _phase >= _frames;
- if (_phaseVarControlled && eov) {
+ if (!_phaseVar.empty() && eov) {
_engine->setGlobal(_phaseVar, -1);
onScreen(false);
return true;
Commit: f0a3df08730ccc20854d4facdc323da64f10230f
https://github.com/scummvm/scummvm/commit/f0a3df08730ccc20854d4facdc323da64f10230f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:12+01:00
Commit Message:
AGDS: implement video scaling
Changed paths:
engines/agds/mjpgPlayer.cpp
diff --git a/engines/agds/mjpgPlayer.cpp b/engines/agds/mjpgPlayer.cpp
index 7656a6de570..063d5097389 100644
--- a/engines/agds/mjpgPlayer.cpp
+++ b/engines/agds/mjpgPlayer.cpp
@@ -96,13 +96,25 @@ const Graphics::Surface *MJPGPlayer::decodeFrame() {
void MJPGPlayer::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
auto *surface = decodeFrame();
if (surface) {
- Graphics::Surface *converted = surface->convertTo(engine.pixelFormat());
- Common::Point dst((backbuffer.w - converted->w) / 2, (backbuffer.h - converted->h) / 2);
- Common::Rect srcRect(converted->getRect());
+ Graphics::Surface *scaled;
+ {
+ Graphics::Surface *converted = surface->convertTo(engine.pixelFormat());
+ auto scaleW = 1.0f * backbuffer.w / converted->w;
+ auto scaleH = 1.0f * backbuffer.h / converted->h;
+ auto scale = MIN(scaleW, scaleH);
+
+ scaled = converted->scale(converted->w * scale, converted->h * scale);
+ converted->free();
+ delete converted;
+ }
+
+ Common::Point dst((backbuffer.w - scaled->w) / 2, (backbuffer.h - scaled->h) / 2);
+ Common::Rect srcRect(scaled->getRect());
+ debug("scaled %u %d", scaled->w, scaled->h);
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
- backbuffer.copyRectToSurface(*converted, dst.x, dst.y, srcRect);
- converted->free();
- delete converted;
+ backbuffer.copyRectToSurface(*scaled, dst.x, dst.y, srcRect);
+ scaled->free();
+ delete scaled;
}
if (_subtitles.empty())
Commit: a3d407c21dbf5c4ed47a8cb4059604e988928c6f
https://github.com/scummvm/scummvm/commit/a3d407c21dbf5c4ed47a8cb4059604e988928c6f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:12+01:00
Commit Message:
AGDS: update scummvm
Changed paths:
engines/agds/animation.h
engines/agds/detection.cpp
engines/agds/inventory.h
engines/agds/metaengine.cpp
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 4cd323035f3..d85b7721e72 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/rect.h"
+#include "common/str.h"
namespace Common { class SeekableReadStream; }
namespace Graphics { struct Surface; struct ManagedSurface; }
diff --git a/engines/agds/detection.cpp b/engines/agds/detection.cpp
index fcb75bb8047..c6b20cc9562 100644
--- a/engines/agds/detection.cpp
+++ b/engines/agds/detection.cpp
@@ -29,9 +29,9 @@ static const PlainGameDescriptor agdsGames[] = {
#include "agds/detection_tables.h"
-class AGDSMetaEngineDetection : public AdvancedMetaEngineDetection {
+class AGDSMetaEngineDetection : public AdvancedMetaEngineDetection<ADGameDescription> {
public:
- AGDSMetaEngineDetection() : AdvancedMetaEngineDetection(AGDS::gameDescriptions, sizeof(ADGameDescription), agdsGames) {
+ AGDSMetaEngineDetection() : AdvancedMetaEngineDetection(AGDS::gameDescriptions, agdsGames) {
_maxScanDepth = 3;
}
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index 254887c5627..52c8f1b1c93 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -27,6 +27,7 @@
#include "common/array.h"
#include "common/ptr.h"
#include "common/rect.h"
+#include "common/str.h"
namespace Common { class ReadStream; class WriteStream; }
diff --git a/engines/agds/metaengine.cpp b/engines/agds/metaengine.cpp
index 5a100ee9b53..823ccd39c98 100644
--- a/engines/agds/metaengine.cpp
+++ b/engines/agds/metaengine.cpp
@@ -23,10 +23,11 @@
#include "agds/object.h"
#include "common/savefile.h"
#include "common/system.h"
+#include "engines/advancedDetector.h"
namespace AGDS {
-class AGDSMetaEngine : public AdvancedMetaEngine {
+class AGDSMetaEngine : public AdvancedMetaEngine<ADGameDescription> {
public:
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
@@ -47,7 +48,7 @@ public:
return 24;
}
- SaveStateList listSaves(const char *target) const {
+ SaveStateList listSaves(const char *target) const override {
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
Common::StringArray filenames;
Common::String pattern(getSavegameFilePattern(target));
Commit: c453c89748045fcbd591a889d77655d1d44ae8f4
https://github.com/scummvm/scummvm/commit/c453c89748045fcbd591a889d77655d1d44ae8f4
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:12+01:00
Commit Message:
AGDS: new managed surface api
Changed paths:
engines/agds/agds.cpp
engines/agds/animation.cpp
engines/agds/object.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index bf90bd04cca..44a35230eb8 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -950,19 +950,25 @@ Graphics::Surface *AGDSEngine::createSurface(int w, int h) {
return surface;
}
-Graphics::ManagedSurface *AGDSEngine::convertToTransparent(Graphics::Surface *surface) {
- if (!surface)
+Graphics::ManagedSurface *AGDSEngine::convertToTransparent(Graphics::Surface *s) {
+ if (!s)
return NULL;
- Graphics::ManagedSurface *t = new Graphics::ManagedSurface(surface);
+ Graphics::ManagedSurface *t = new Graphics::ManagedSurface(s->w, s->h, _pixelFormat);
+ assert(s->format.bytesPerPixel == 4);
assert(t->format.bytesPerPixel == 4);
- uint32* pixels = static_cast<uint32 *>(t->getPixels());
+ uint8* dst = static_cast<uint8 *>(t->getPixels());
+ const uint8* src = static_cast<uint8 *>(s->getPixels());
uint8 shadowAlpha = 255 * _shadowIntensity / 100;
- uint delta = t->pitch - t->w * t->format.bytesPerPixel;
- for (uint16 i = 0; i < t->h; ++i, pixels = reinterpret_cast<uint32*>((reinterpret_cast<uint8*>(pixels) + delta))) {
- for (uint16 j = 0; j < t->w; ++j, ++pixels) {
- uint32 pix = *pixels;
+ auto &dstFormat = t->format;
+ auto &srcFormat = s->format;
+ auto dstBPP = dstFormat.bytesPerPixel;
+ auto srcBPP = srcFormat.bytesPerPixel;
+ uint dstDelta = t->pitch - t->w * dstBPP;
+ uint srcDelta = s->pitch - s->w * srcBPP;
+ for (uint16 i = 0; i < t->h; ++i, dst += dstDelta, src += srcDelta) {
+ for (uint16 j = 0; j < t->w; ++j, dst += dstBPP, src += srcBPP) {
uint8 r, g, b, a;
- t->format.colorToARGB(pix, a, r, g, b);
+ srcFormat.colorToARGB(*reinterpret_cast<const uint32 *>(src), a, r, g, b);
if (r == _colorKey.r && g == _colorKey.g && b == _colorKey.b) {
r = g = b = a = 0;
} else if (
@@ -972,10 +978,8 @@ Graphics::ManagedSurface *AGDSEngine::convertToTransparent(Graphics::Surface *su
) {
r = g = b = 0;
a = shadowAlpha;
- } else
- continue;
-
- *pixels = t->format.ARGBToColor(a, r, g, b);
+ }
+ *reinterpret_cast<uint32 *>(dst) = dstFormat.ARGBToColor(a, r, g, b);
}
}
return t;
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index f3237c716d5..d5cc0cd0b59 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -124,11 +124,11 @@ void Animation::rescaleCurrentFrame() {
Graphics::TransformStruct transform(_scale * 100, _scale * 100, 90 * _rotation, _frame->w / 2, _frame->h / 2, Graphics::TSpriteBlendMode::BLEND_NORMAL, Graphics::kDefaultRgbaMod);
if (_scaledFrame)
delete _scaledFrame;
- _scaledFrame = new Graphics::ManagedSurface(_frame->surfacePtr()->rotoscale(transform));
+ _scaledFrame = _frame->rotoscale(transform);
} else if (_scale != 1) {
if (_scaledFrame)
delete _scaledFrame;
- _scaledFrame = new Graphics::ManagedSurface(_frame->surfacePtr()->scale(_frame->w * _scale, _frame->h * _scale, true));
+ _scaledFrame = _frame->scale(_frame->w * _scale, _frame->h * _scale, true);
}
auto *frame = _scaledFrame? _scaledFrame: _frame;
if (frame) {
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 9b80d52fb7b..865ab48af35 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -189,7 +189,7 @@ void Object::createRotated() {
return;
Graphics::TransformStruct transform(100, 100, 90 * _rotation, _picture->w / 2, _picture->h / 2);
- _rotatedPicture = new Graphics::ManagedSurface(getPicture()->surfacePtr()->rotoscale(transform));
+ _rotatedPicture = getPicture()->rotoscale(transform);
}
void Object::alive(bool value)
Commit: 775629ae6247dae4d53099f38033b0877ac143f3
https://github.com/scummvm/scummvm/commit/775629ae6247dae4d53099f38033b0877ac143f3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:12+01:00
Commit Message:
AGDS: add missing override
Changed paths:
engines/agds/agds.h
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 5f664d26afb..87079f6e7a3 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -116,7 +116,7 @@ private:
public:
- bool hasFeature(EngineFeature f) const;
+ bool hasFeature(EngineFeature f) const override;
Common::Error loadGameState(int slot) override;
Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
bool canLoadGameStateCurrently(Common::U32String *msg) override { return true; }
Commit: ab049d542ed07cd851c2d7d4603812ee03f3f75a
https://github.com/scummvm/scummvm/commit/ab049d542ed07cd851c2d7d4603812ee03f3f75a
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:13+01:00
Commit Message:
AGDS: just initialise with desired pixel format
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 44a35230eb8..18d71eccdd8 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -83,20 +83,9 @@ AGDSEngine::~AGDSEngine() {
}
bool AGDSEngine::initGraphics(int w, int h) {
- typedef Common::List<Graphics::PixelFormat> FormatsType;
- FormatsType formats = _system->getSupportedFormats();
-
- for (FormatsType::iterator fi = formats.begin(); fi != formats.end(); ++fi) {
- const Graphics::PixelFormat &format = *fi;
- if (fi->bytesPerPixel == 4 && format == Graphics::BlendBlit::getSupportedPixelFormat()) {
- debug("found mode %s", format.toString().c_str());
- _pixelFormat = format;
- ::initGraphics(w, h, &_pixelFormat);
- return true;
- }
- }
- error("no supported video format found");
- return false;
+ _pixelFormat = Graphics::BlendBlit::getSupportedPixelFormat();
+ ::initGraphics(w, h, &_pixelFormat);
+ return true;
}
void AGDSEngine::Color::FromString(const Common::String &rgb) {
Commit: db60595722212ea59854c70d6188c65223957ecd
https://github.com/scummvm/scummvm/commit/db60595722212ea59854c70d6188c65223957ecd
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:13+01:00
Commit Message:
AGDS: replace stream pointers with refs
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/character.cpp
engines/agds/character.h
engines/agds/database.cpp
engines/agds/database.h
engines/agds/inventory.cpp
engines/agds/inventory.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/patch.cpp
engines/agds/patch.h
engines/agds/region.cpp
engines/agds/region.h
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
engines/agds/systemVariable.cpp
engines/agds/systemVariable.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 18d71eccdd8..746e1e94db2 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -163,13 +163,13 @@ bool AGDSEngine::load() {
Database patch;
patch.open("patch.adb");
- loadPatches(&file, patch);
+ loadPatches(file, patch);
}
{
- Common::File * file = new Common::File();
+ Common::ScopedPtr<Common::File> file(new Common::File());
file->open("jokes.chr");
_jokes = new Character(this, "jokes");
- _jokes->load(file);
+ _jokes->load(*file);
}
return true;
@@ -177,14 +177,13 @@ bool AGDSEngine::load() {
RegionPtr AGDSEngine::loadRegion(const Common::String &name) {
debug("loading region %s", name.c_str());
- Common::SeekableReadStream *stream = _data.getEntry(name);
- if (!stream)
+ Common::ScopedPtr<Common::SeekableReadStream>stream(_data.getEntry(name));
+ if (!stream) {
error("no database entry for %s\n", name.c_str());
+ return {};
+ }
- RegionPtr region(new Region(name, stream));
- delete stream;
-
- return region;
+ return RegionPtr(new Region(name, *stream));
}
Common::String AGDSEngine::loadText(const Common::String &entryName) {
@@ -196,16 +195,15 @@ Common::String AGDSEngine::loadText(const Common::String &entryName) {
ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::String &prototype, bool allowInitialise) {
debug("loadObject %s %s, allow init: %d", name.c_str(), prototype.c_str(), allowInitialise);
Common::String clone = prototype.empty() ? name : prototype;
- Common::SeekableReadStream *stream = _data.getEntry(clone);
+ Common::ScopedPtr<Common::SeekableReadStream>stream(_data.getEntry(clone));
if (!stream)
error("no database entry for %s\n", clone.c_str());
- ObjectPtr object(new Object(name, stream));
+ ObjectPtr object(new Object(name, *stream));
object->allowInitialise(allowInitialise);
if (!prototype.empty()) {
object->persistent(false);
}
- delete stream;
return object;
}
@@ -891,7 +889,8 @@ void AGDSEngine::loadCharacter(const Common::String &id, const Common::String &f
_currentCharacterObject = object;
_currentCharacter = new Character(this, id);
- _currentCharacter->load(_resourceManager.getResource(loadText(filename)));
+ Common::ScopedPtr<Common::SeekableReadStream> stream(_resourceManager.getResource(loadText(filename)));
+ _currentCharacter->load(*stream);
_currentCharacter->associate(object);
}
@@ -1103,7 +1102,7 @@ bool AGDSEngine::hasFeature(EngineFeature f) const {
}
}
-void AGDSEngine::loadPatches(Common::SeekableReadStream *file, Database & db) {
+void AGDSEngine::loadPatches(Common::SeekableReadStream &file, Database & db) {
debug("loading patches");
_patches.clear();
_objectPatches.clear();
@@ -1116,11 +1115,11 @@ void AGDSEngine::loadPatches(Common::SeekableReadStream *file, Database & db) {
Common::ScopedPtr<Common::SeekableReadStream> patchStream(db.getEntry(file, name));
if (patchStream->size() != ObjectPatch::Size) {
PatchPtr patch(new Patch());
- patch->load(patchStream.get());
+ patch->load(*patchStream);
_patches[name] = patch;
} else {
ObjectPatchPtr patch(new ObjectPatch());
- patch->load(patchStream.get());
+ patch->load(*patchStream);
_objectPatches[name] = patch;
}
}
@@ -1131,13 +1130,13 @@ Common::Error AGDSEngine::loadGameState(int slot) {
//saveAutosaveIfEnabled();
auto fileName = getSaveStateName(slot);
- Common::InSaveFile *saveFile = _saveFileMan->openForLoading(fileName);
+ Common::ScopedPtr<Common::InSaveFile> saveFile(_saveFileMan->openForLoading(fileName));
if (!saveFile)
return Common::kReadingFailed;
Database db;
- if (!db.open(fileName, saveFile))
+ if (!db.open(fileName, *saveFile))
return Common::kReadingFailed;
stopAmbientSound();
@@ -1146,8 +1145,8 @@ Common::Error AGDSEngine::loadGameState(int slot) {
{
// Compiled version (should be 2)
- Common::ScopedPtr<Common::SeekableReadStream> agds_ver(db.getEntry(saveFile, "__agds_ver"));
- int version = agds_ver->readUint32LE();
+ Common::ScopedPtr<Common::SeekableReadStream> agds_ver(db.getEntry(*saveFile, "__agds_ver"));
+ uint version = agds_ver->readUint32LE();
debug("version: %d", version);
if (version != 2) {
warning("wrong engine version (%d)", version);
@@ -1162,15 +1161,15 @@ Common::Error AGDSEngine::loadGameState(int slot) {
{
// Current character
- Common::ScopedPtr<Common::SeekableReadStream> agds_c(db.getEntry(saveFile, "__agds_c"));
- Common::String object = readString(agds_c.get());
- Common::String filename = readString(agds_c.get());
- Common::String id = readString(agds_c.get());
+ Common::ScopedPtr<Common::SeekableReadStream> agds_c(db.getEntry(*saveFile, "__agds_c"));
+ Common::String object = readString(*agds_c);
+ Common::String filename = readString(*agds_c);
+ Common::String id = readString(*agds_c);
debug("savegame character %s %s -> %s %s", object.c_str(), filename.c_str(), filename.c_str(), id.c_str());
loadCharacter(id, filename, object);
auto character = getCharacter(id);
if (character) {
- character->loadState(agds_c.get());
+ character->loadState(*agds_c);
character->visible(true);
} else
warning("no character");
@@ -1179,18 +1178,18 @@ Common::Error AGDSEngine::loadGameState(int slot) {
Common::String screenName;
{
// Palette and screen name
- Common::ScopedPtr<Common::SeekableReadStream> agds_s(db.getEntry(saveFile, "__agds_s"));
- screenName = readString(agds_s.get());
+ Common::ScopedPtr<Common::SeekableReadStream> agds_s(db.getEntry(*saveFile, "__agds_s"));
+ screenName = readString(*agds_s);
}
{
// Global vars
_globals.clear();
- Common::ScopedPtr<Common::SeekableReadStream> agds_v(db.getEntry(saveFile, "__agds_v"));
+ Common::ScopedPtr<Common::SeekableReadStream> agds_v(db.getEntry(*saveFile, "__agds_v"));
uint32 n = agds_v->readUint32LE();
debug("reading %u vars...", n);
while(n--) {
- Common::String name = readString(agds_v.get());
+ Common::String name = readString(*agds_v);
int value = agds_v->readSint32LE();
debug("setting var %s to %d", name.c_str(), value);
setGlobal(name, value);
@@ -1199,25 +1198,25 @@ Common::Error AGDSEngine::loadGameState(int slot) {
{
// System vars
- Common::ScopedPtr<Common::SeekableReadStream> agds_d(db.getEntry(saveFile, "__agds_d"));
+ Common::ScopedPtr<Common::SeekableReadStream> agds_d(db.getEntry(*saveFile, "__agds_d"));
for(uint i = 0, n = _systemVarList.size(); i < n; ++i) {
Common::String & name = _systemVarList[i];
- _systemVars[name]->read(agds_d.get());
+ _systemVars[name]->read(*agds_d);
}
}
SystemVariable *initVar = getSystemVariable("init_resources");
runObject(initVar->getString());
- loadPatches(saveFile, db);
+ loadPatches(*saveFile, db);
loadScreen(screenName, ScreenLoadingType::Normal, false);
{
// Saved ambient sound
- Common::ScopedPtr<Common::SeekableReadStream> agds_a(db.getEntry(saveFile, "__agds_a"));
- auto resource = readString(agds_a.get());
+ Common::ScopedPtr<Common::SeekableReadStream> agds_a(db.getEntry(*saveFile, "__agds_a"));
+ auto resource = readString(*agds_a);
auto filename = loadText(resource);
- auto phaseVar = readString(agds_a.get());
+ auto phaseVar = readString(*agds_a);
uint volume = agds_a->readUint32LE();
uint type = agds_a->readUint32LE();
debug("saved audio state: sample: '%s:%s', var: '%s' %u %u", resource.c_str(), filename.c_str(), phaseVar.c_str(), volume, type);
@@ -1227,11 +1226,10 @@ Common::Error AGDSEngine::loadGameState(int slot) {
debug("ambient sound id = %d", _ambientSoundId);
}
{
- Common::ScopedPtr<Common::SeekableReadStream> agds_i(db.getEntry(saveFile, "__agds_i"));
- _inventory.load(agds_i.get());
+ Common::ScopedPtr<Common::SeekableReadStream> agds_i(db.getEntry(*saveFile, "__agds_i"));
+ _inventory.load(*agds_i);
}
- delete saveFile;
return Common::kNoError;
}
@@ -1249,7 +1247,7 @@ void AGDSEngine::loadNextScreen() {
Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
debug("saveGameState %d %s autosave: %d", slot, desc.c_str(), isAutosave);
auto fileName = getSaveStateName(slot);
- Common::OutSaveFile *saveFile = getSaveFileManager()->openForSaving(fileName, false);
+ Common::ScopedPtr<Common::OutSaveFile> saveFile(getSaveFileManager()->openForSaving(fileName, false));
if (!saveFile)
return Common::kWritingFailed;
@@ -1269,12 +1267,12 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
{
Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
- writeString(&stream, _currentCharacterObject);
- writeString(&stream, _currentCharacterFilename);
- writeString(&stream, _currentCharacterName);
+ writeString(stream, _currentCharacterObject);
+ writeString(stream, _currentCharacterFilename);
+ writeString(stream, _currentCharacterName);
auto character = getCharacter(_currentCharacterName);
if (character) {
- character->saveState(&stream);
+ character->saveState(stream);
} else
warning("no character to save");
@@ -1288,7 +1286,7 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
{
Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
- writeString(&stream, _currentScreenName);
+ writeString(stream, _currentScreenName);
debug("saving screen name: %s", _currentScreenName.c_str());
char palette[0x300];
memset(palette, 0xaa, sizeof(palette));
@@ -1300,7 +1298,7 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
for(uint i = 0, n = _systemVarList.size(); i < n; ++i) {
Common::String & name = _systemVarList[i];
- _systemVars[name]->write(&stream);
+ _systemVars[name]->write(stream);
}
entries["__agds_d"].assign(stream.getData(), stream.getData() + stream.size());
}
@@ -1311,7 +1309,7 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
stream.writeUint32LE(n);
debug("saving %u vars...", n);
for(auto & global : _globals) {
- writeString(&stream, global._key);
+ writeString(stream, global._key);
stream.writeUint32LE(global._value);
}
entries["__agds_v"].assign(stream.getData(), stream.getData() + stream.size());
@@ -1319,7 +1317,7 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
{
Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
- _inventory.save(&stream);
+ _inventory.save(stream);
entries["__agds_i"].assign(stream.getData(), stream.getData() + stream.size());
}
@@ -1328,11 +1326,11 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
debug("ambient sound id: %d", _ambientSoundId);
auto sound = _soundManager.find(_ambientSoundId);
if (sound) {
- writeString(&stream, sound->resource);
- writeString(&stream, sound->phaseVar);
+ writeString(stream, sound->resource);
+ writeString(stream, sound->phaseVar);
} else {
- writeString(&stream, Common::String());
- writeString(&stream, Common::String());
+ writeString(stream, Common::String());
+ writeString(stream, Common::String());
}
stream.writeUint32LE(70); //volume
stream.writeUint32LE(30); //type
@@ -1342,19 +1340,18 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
for(auto & objectPatch : _objectPatches) {
Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
- objectPatch._value->save(&stream);
+ objectPatch._value->save(stream);
entries[objectPatch._key].assign(stream.getData(), stream.getData() + stream.size());
}
for(auto & patch : _patches) {
Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
- patch._value->save(&stream);
+ patch._value->save(stream);
entries[patch._key].assign(stream.getData(), stream.getData() + stream.size());
}
- Database::write(saveFile, entries);
+ Database::write(*saveFile, entries);
- delete saveFile;
return Common::kNoError;
}
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 87079f6e7a3..1cfc620a87a 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -283,7 +283,7 @@ public:
private:
void stopAmbientSound();
- void loadPatches(Common::SeekableReadStream *file, Database & db);
+ void loadPatches(Common::SeekableReadStream &file, Database & db);
typedef Common::HashMap<int, Graphics::ManagedSurface *> PictureCacheType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PictureCacheLookup;
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 1485f4753af..b6d84ba5736 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -28,7 +28,6 @@
#include "agds/resourceManager.h"
#include "common/array.h"
#include "common/debug.h"
-#include "common/error.h"
#include "common/stream.h"
#include "common/system.h"
#include "common/textconsole.h"
@@ -40,7 +39,8 @@
namespace AGDS {
Character::Character(AGDSEngine * engine, const Common::String & name):
- _engine(engine), _name(name), _object(), _animation(nullptr), _jokes(false),
+ _engine(engine), _object(), _animation(nullptr), _jokes(false),
+ _name(name),
_enabled(true), _visible(false), _stopped(false), _shown(false),
_phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
}
@@ -48,10 +48,10 @@ Character::Character(AGDSEngine * engine, const Common::String & name):
Character::~Character() {
}
-void Character::load(Common::SeekableReadStream *stream) {
+void Character::load(Common::SeekableReadStream &stream) {
debug("loading character...");
- stream->readUint32LE(); //unk
- uint16 magic = stream->readUint16LE();
+ stream.readUint32LE(); //unk
+ uint16 magic = stream.readUint16LE();
switch (magic) {
case 0xdead:
_movementDirections = 16;
@@ -64,40 +64,40 @@ void Character::load(Common::SeekableReadStream *stream) {
}
_animations.clear();
- while (stream->pos() < stream->size()) {
- uint size = stream->readUint32LE();
- uint index = stream->readUint16LE();
+ while (stream.pos() < stream.size()) {
+ uint size = stream.readUint32LE();
+ uint index = stream.readUint16LE();
debug("header size %u, index: %u", size, index);
- uint16 frames = stream->readUint16LE();
- uint16 format = stream->readUint16LE();
+ uint16 frames = stream.readUint16LE();
+ uint16 format = stream.readUint16LE();
Common::String filename = readString(stream);
AnimationDescription animation;
animation.filename = filename;
debug("%s:%u: animation %s, frames: %d, format: %d", _name.c_str(), _animations.size(), animation.filename.c_str(), frames, format);
while (frames--) {
- int x = stream->readSint16LE();
- int y = stream->readSint16LE();
- int w = stream->readUint32LE();
- int h = stream->readUint32LE();
+ int x = stream.readSint16LE();
+ int y = stream.readSint16LE();
+ uint w = stream.readUint32LE();
+ uint h = stream.readUint32LE();
AnimationDescription::Frame frame = {x, y, w, h};
animation.frames.push_back(frame);
debug("frame %d, %d, %dx%d", x, y, w, h);
- uint unk1 = stream->readUint32LE();
- uint unk2 = stream->readUint32LE();
- uint unk3 = stream->readUint32LE();
- uint unk4 = stream->readUint32LE(); //GRP file offset?
- uint unk5 = stream->readUint32LE();
- uint unk6 = stream->readByte();
- uint unk7 = stream->readUint32LE();
- uint unk8 = stream->readUint32LE();
- stream->readUint32LE(); //CDCDCDCD
- uint unk9 = stream->readUint32LE();
- uint unk10 = stream->readUint32LE();
- stream->readUint32LE(); //CDCDCDCD
- uint unk11 = stream->readByte();
- stream->readUint32LE(); //CDCDCDCD
+ uint unk1 = stream.readUint32LE();
+ uint unk2 = stream.readUint32LE();
+ uint unk3 = stream.readUint32LE();
+ uint unk4 = stream.readUint32LE(); //GRP file offset?
+ uint unk5 = stream.readUint32LE();
+ uint unk6 = stream.readByte();
+ uint unk7 = stream.readUint32LE();
+ uint unk8 = stream.readUint32LE();
+ stream.readUint32LE(); //CDCDCDCD
+ uint unk9 = stream.readUint32LE();
+ uint unk10 = stream.readUint32LE();
+ stream.readUint32LE(); //CDCDCDCD
+ uint unk11 = stream.readByte();
+ stream.readUint32LE(); //CDCDCDCD
debug("unknown: %u %u %u 0x%08x - %u %u %u %u - %u %u %u",
unk1, unk2, unk3, unk4,
unk5, unk6, unk7, unk8,
@@ -105,8 +105,6 @@ void Character::load(Common::SeekableReadStream *stream) {
}
_animations[index] = animation;
}
-
- delete stream;
}
void Character::associate(const Common::String &name) {
@@ -121,23 +119,23 @@ void Character::visible(bool visible) {
_visible = visible;
}
-void Character::loadState(Common::ReadStream* stream) {
- int x = stream->readUint16LE();
- int y = stream->readUint16LE();
- int dir = stream->readSint16LE();
+void Character::loadState(Common::ReadStream& stream) {
+ int x = stream.readUint16LE();
+ int y = stream.readUint16LE();
+ int dir = stream.readSint16LE();
debug("character at %d, %d, dir: %d", x, y, dir);
position(Common::Point(x, y));
direction(dir);
- _visible = stream->readUint16LE();
- _enabled = stream->readUint16LE();
+ _visible = stream.readUint16LE();
+ _enabled = stream.readUint16LE();
}
-void Character::saveState(Common::WriteStream* stream) const {
- stream->writeUint16LE(_pos.x);
- stream->writeUint16LE(_pos.y);
- stream->writeUint16LE(_direction);
- stream->writeUint16LE(_visible);
- stream->writeUint16LE(_enabled);
+void Character::saveState(Common::WriteStream& stream) const {
+ stream.writeUint16LE(_pos.x);
+ stream.writeUint16LE(_pos.y);
+ stream.writeUint16LE(_direction);
+ stream.writeUint16LE(_visible);
+ stream.writeUint16LE(_enabled);
}
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 035c80d44e0..edaf9c01987 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -64,13 +64,13 @@ class Character {
struct AnimationDescription {
struct Frame {
int x, y;
- int w, h;
+ uint w, h;
};
Common::String filename;
Common::Array<Frame> frames;
};
- Common::HashMap<int, AnimationDescription> _animations;
+ Common::HashMap<uint, AnimationDescription> _animations;
const AnimationDescription * _description;
bool animate(int direction, int speed, bool jokes);
@@ -95,9 +95,9 @@ public:
return _object;
}
- void load(Common::SeekableReadStream* stream);
- void loadState(Common::ReadStream* stream);
- void saveState(Common::WriteStream* stream) const;
+ void load(Common::SeekableReadStream& stream);
+ void loadState(Common::ReadStream& stream);
+ void saveState(Common::WriteStream& stream) const;
void enable(bool enabled = true) {
_enabled = enabled;
diff --git a/engines/agds/database.cpp b/engines/agds/database.cpp
index 7ead889587b..96068d8630a 100644
--- a/engines/agds/database.cpp
+++ b/engines/agds/database.cpp
@@ -32,7 +32,7 @@ bool Database::open(const Common::String &filename) {
if (!file.open(Common::Path{filename}))
return false;
- return open(filename, &file);
+ return open(filename, file);
}
namespace {
@@ -46,17 +46,17 @@ uint32 Database::getDataOffset(uint32 maxNameSize, uint32 totalEntries) {
return kHeaderSize + (maxNameSize + kHeaderFieldSize) * totalEntries;
}
-bool Database::open(const Common::String &filename, Common::SeekableReadStream *stream) {
+bool Database::open(const Common::String &filename, Common::SeekableReadStream &stream) {
_filename = filename;
- uint32 magic = stream->readUint32LE();
+ uint32 magic = stream.readUint32LE();
if (magic != kMagic) {
debug("invalid magic for database %s", _filename.c_str());
return false;
}
- _writeable = stream->readUint32LE();
- _totalEntries = stream->readUint32LE();
- _usedEntries = stream->readUint32LE();
- _maxNameSize = stream->readUint32LE();
+ _writeable = stream.readUint32LE();
+ _totalEntries = stream.readUint32LE();
+ _usedEntries = stream.readUint32LE();
+ _maxNameSize = stream.readUint32LE();
if (_maxNameSize == 0) {
debug("invalid max name record size");
return false;
@@ -65,11 +65,11 @@ bool Database::open(const Common::String &filename, Common::SeekableReadStream *
uint32 dataOffset = getDataOffset(_maxNameSize, _totalEntries);
Common::Array<char> nameBuffer(_maxNameSize + 1);
for (uint32 i = 0; i < _usedEntries; ++i) {
- uint32 offset = stream->readUint32LE();
- stream->read(nameBuffer.data(), nameBuffer.size());
+ uint32 offset = stream.readUint32LE();
+ stream.read(nameBuffer.data(), nameBuffer.size());
char *z = Common::find(nameBuffer.begin(), nameBuffer.end(), 0);
Common::String name(nameBuffer.data(), z - nameBuffer.begin());
- uint32 size = stream->readUint32LE();
+ uint32 size = stream.readUint32LE();
//debug("adb entry: %s, offset %08x, size: %u", name.c_str(), offset, size);
_entries.setVal(name, Entry(dataOffset + offset, size));
}
@@ -77,33 +77,33 @@ bool Database::open(const Common::String &filename, Common::SeekableReadStream *
return true;
}
-void Database::write(Common::WriteStream *stream, const Common::HashMap<Common::String, Common::Array<uint8>> & entries) {
+void Database::write(Common::WriteStream &stream, const Common::HashMap<Common::String, Common::Array<uint8>> &entries) {
auto n = entries.size();
- stream->writeUint32LE(kMagic);
- stream->writeUint32LE(1);
- stream->writeUint32LE(n);
- stream->writeUint32LE(n);
- stream->writeUint32LE(kDefaultNameSize);
+ stream.writeUint32LE(kMagic);
+ stream.writeUint32LE(1);
+ stream.writeUint32LE(n);
+ stream.writeUint32LE(n);
+ stream.writeUint32LE(kDefaultNameSize);
auto dataOffset = getDataOffset(kDefaultNameSize, n);
debug("database data offset: 0x%06x", dataOffset);
- auto offset = 0;
+ uint offset = 0;
- for(auto entry: entries) {
+ for(auto &entry: entries) {
auto &key = entry._key;
auto &value = entry._value;
- stream->writeUint32LE(offset);
+ stream.writeUint32LE(offset);
Common::Array<char> text(kDefaultNameSize + 1);
strncpy(text.data(), key.c_str(), kDefaultNameSize);
- stream->write(text.data(), text.size());
+ stream.write(text.data(), text.size());
debug("database entry %s: 0x%06x", key.c_str(), offset);
offset += value.size();
- stream->writeUint32LE(value.size());
+ stream.writeUint32LE(value.size());
}
for(auto entry: entries) {
auto & value = entry._value;
- stream->write(value.data(), value.size());
+ stream.write(value.data(), value.size());
}
}
@@ -122,16 +122,16 @@ Common::SeekableReadStream *Database::getEntry(const Common::String &name) const
return NULL;
}
- return getEntry(&file, name);
+ return getEntry(file, name);
}
-Common::SeekableReadStream *Database::getEntry(Common::SeekableReadStream *parent, const Common::String &name) const {
+Common::SeekableReadStream *Database::getEntry(Common::SeekableReadStream &parent, const Common::String &name) const {
EntriesType::const_iterator i = _entries.find(name);
if (i == _entries.end())
return NULL;
const Entry &entry = i->_value;
- parent->seek(entry.offset);
- return parent->readStream(entry.size);
+ parent.seek(entry.offset);
+ return parent.readStream(entry.size);
}
} // namespace AGDS
diff --git a/engines/agds/database.h b/engines/agds/database.h
index 18c35023373..b04222294a5 100644
--- a/engines/agds/database.h
+++ b/engines/agds/database.h
@@ -57,13 +57,13 @@ private:
public:
bool open(const Common::String &filename);
- bool open(const Common::String &filename, Common::SeekableReadStream *stream);
+ bool open(const Common::String &filename, Common::SeekableReadStream &stream);
Common::Array<Common::String> getEntries() const;
Common::SeekableReadStream * getEntry(const Common::String &name) const;
- Common::SeekableReadStream *getEntry(Common::SeekableReadStream *parent, const Common::String &name) const;
+ Common::SeekableReadStream *getEntry(Common::SeekableReadStream &parent, const Common::String &name) const;
- static void write(Common::WriteStream *stream, const Common::HashMap<Common::String, Common::Array<uint8>> & entries);
+ static void write(Common::WriteStream &stream, const Common::HashMap<Common::String, Common::Array<uint8>> & entries);
};
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index e952ed0d086..f3c97128bc1 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -188,12 +188,12 @@ void Inventory::clear() {
}
}
-void Inventory::load(Common::ReadStream* stream) {
+void Inventory::load(Common::ReadStream& stream) {
clear();
for(int i = 0; i < kMaxSize; ++i) {
Common::String name = readString(stream);
- int refcount = stream->readUint32LE();
- int objectPtr = stream->readUint32LE();
+ int refcount = stream.readUint32LE();
+ int objectPtr = stream.readUint32LE();
if (!name.empty() && refcount) {
debug("load inventory object: %s %d %d", name.c_str(), refcount, objectPtr);
auto & entry = _entries[i];
@@ -203,11 +203,11 @@ void Inventory::load(Common::ReadStream* stream) {
}
}
-void Inventory::save(Common::WriteStream* stream) const {
+void Inventory::save(Common::WriteStream& stream) const {
for(auto & entry : _entries) {
writeString(stream, entry.name);
- stream->writeUint32LE(entry.hasObject? 1: 0);
- stream->writeSint32LE(entry.hasObject? -1: 0);
+ stream.writeUint32LE(entry.hasObject? 1: 0);
+ stream.writeSint32LE(entry.hasObject? -1: 0);
}
}
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index 52c8f1b1c93..297bbd8b949 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -60,8 +60,8 @@ public:
Inventory(AGDSEngine* engine);
~Inventory();
- void load(Common::ReadStream* stream);
- void save(Common::WriteStream* stream) const;
+ void load(Common::ReadStream& stream);
+ void save(Common::WriteStream& stream) const;
bool enabled() const {
return _enabled;
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 865ab48af35..9a24d884622 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -34,7 +34,7 @@
namespace AGDS {
-Object::Object(const Common::String &name, Common::SeekableReadStream *stream) : _name(name), _stringTableLoaded(false),
+Object::Object(const Common::String &name, Common::SeekableReadStream &stream) : _name(name), _stringTableLoaded(false),
_picture(), _rotatedPicture(), _region(),
_animation(), _mouseCursor(),
_pos(), _z(10), _rotation(0),
@@ -44,20 +44,20 @@ Object::Object(const Common::String &name, Common::SeekableReadStream *stream) :
_alpha(255), _scale(100), _locked(0), _alive(true),
_persistent(true), _allowInitialise(true),
_ignoreRegion(false) {
- uint16 id = stream->readUint16LE();
+ uint16 id = stream.readUint16LE();
debug("id: 0x%02x %u", id, id);
- uint16 dataSize = stream->readUint16LE();
+ uint16 dataSize = stream.readUint16LE();
if (dataSize != 0)
error("implement me: object with data (%u/0x%04x)", dataSize, dataSize);
- uint16 codeSize = stream->readUint16LE();
- uint8 flags = stream->readByte();
+ uint16 codeSize = stream.readUint16LE();
+ uint8 flags = stream.readByte();
if (flags != 1)
error("implement me: no flags handling yet");
debug("object code size %u", codeSize);
_code.resize(codeSize);
- stream->read(_code.data(), _code.size());
+ stream.read(_code.data(), _code.size());
}
Object::~Object() {
diff --git a/engines/agds/object.h b/engines/agds/object.h
index a91e9b2bd37..59fa9d7ef83 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -100,7 +100,7 @@ private:
void createRotated();
public:
- Object(const Common::String &name, Common::SeekableReadStream * stream);
+ Object(const Common::String &name, Common::SeekableReadStream &stream);
~Object();
bool allowInitialise() const {
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index d15fcc08511..6e799ee0080 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -6,33 +6,33 @@
namespace AGDS {
-void ObjectPatch::load(Common::ReadStream *stream) {
+void ObjectPatch::load(Common::ReadStream &stream) {
text = readString(stream);
region = readString(stream);
- z = stream->readUint16LE();
+ z = stream.readUint16LE();
}
-void ObjectPatch::save(Common::WriteStream *stream) const {
+void ObjectPatch::save(Common::WriteStream &stream) const {
writeString(stream, text);
writeString(stream, region);
- stream->writeUint16LE(z);
+ stream.writeUint16LE(z);
}
-void Patch::load(Common::ReadStream *stream) {
- screenSaved = stream->readByte();
+void Patch::load(Common::ReadStream &stream) {
+ screenSaved = stream.readByte();
screenRegionName = readString(stream);
prevScreenName = readString(stream);
debug("patch screen, valid: %d region: %s, prev: %s", screenSaved, screenRegionName.c_str(), prevScreenName.c_str());
- loadingType = static_cast<ScreenLoadingType>(stream->readUint32LE());
- characterPosition.x = stream->readUint32LE();
- characterPosition.y = stream->readUint32LE();
- characterDirection = stream->readSint32LE();
- characterPresent = stream->readUint32LE();
+ loadingType = static_cast<ScreenLoadingType>(stream.readUint32LE());
+ characterPosition.x = stream.readSint32LE();
+ characterPosition.y = stream.readSint32LE();
+ characterDirection = stream.readSint32LE();
+ characterPresent = stream.readUint32LE();
debug("character %s at %u,%u with dir: %d", characterPresent? "[present]": "[absent]", characterPosition.x, characterPosition.y, characterDirection);
- uint object_count = stream->readUint32LE();
+ uint object_count = stream.readUint32LE();
debug("objects in this patch: %u", object_count);
- if (stream->read(palette, sizeof(palette)) != sizeof(palette)) {
+ if (stream.read(palette, sizeof(palette)) != sizeof(palette)) {
error("short read, can't read palette");
}
@@ -40,32 +40,32 @@ void Patch::load(Common::ReadStream *stream) {
debug("default pointer name: %s", defaultMouseCursor.c_str());
objects.clear();
for(uint i = 0; i < object_count; ++i) {
- int flag = stream->readSint16LE();
+ int flag = stream.readSint16LE();
Common::String name = readString(stream);
debug("patch object %s %d", name.c_str(), flag);
objects.push_back(Object(name, flag));
}
}
-void Patch::save(Common::WriteStream *stream) {
- stream->writeByte(screenSaved);
+void Patch::save(Common::WriteStream &stream) {
+ stream.writeByte(screenSaved);
writeString(stream, screenRegionName);
writeString(stream, prevScreenName);
- stream->writeUint32LE(static_cast<uint>(loadingType));
- stream->writeUint32LE(characterPosition.x);
- stream->writeUint32LE(characterPosition.y);
- stream->writeSint32LE(characterDirection);
- stream->writeUint32LE(characterPresent);
+ stream.writeUint32LE(static_cast<uint>(loadingType));
+ stream.writeUint32LE(characterPosition.x);
+ stream.writeUint32LE(characterPosition.y);
+ stream.writeSint32LE(characterDirection);
+ stream.writeUint32LE(characterPresent);
- stream->writeUint32LE(objects.size());
- if (stream->write(palette, sizeof(palette)) != sizeof(palette)) {
+ stream.writeUint32LE(objects.size());
+ if (stream.write(palette, sizeof(palette)) != sizeof(palette)) {
error("short write, can't write palette");
}
writeString(stream, defaultMouseCursor);
for(auto &object: objects) {
- stream->writeSint16LE(object.flag);
+ stream.writeSint16LE(object.flag);
writeString(stream, object.name);
}
}
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index f26a1a2845a..dd72267f7e0 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -42,14 +42,14 @@ struct ObjectPatch {
Common::String text;
Common::String region;
int z;
- void load(Common::ReadStream *stream);
- void save(Common::WriteStream *stream) const;
+ void load(Common::ReadStream &stream);
+ void save(Common::WriteStream &stream) const;
};
struct Patch {
struct Object {
Common::String name;
- int flag;
+ int16 flag;
Object(const Common::String &n, int f): name(n), flag(f) {}
};
@@ -67,8 +67,8 @@ struct Patch {
Common::String defaultMouseCursor;
Common::Array<Object> objects;
- void load(Common::ReadStream *stream);
- void save(Common::WriteStream *stream);
+ void load(Common::ReadStream &stream);
+ void save(Common::WriteStream &stream);
void setFlag(const Common::String & name, int flag);
int getFlag(const Common::String & name) const;
int incRef(const Common::String & name);
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index 60098b646a1..d347827f59a 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -29,23 +29,23 @@
namespace AGDS {
-Region::Region(const Common::String &resourceName, Common::SeekableReadStream *stream) {
- int size = stream->size();
+Region::Region(const Common::String &resourceName, Common::SeekableReadStream &stream) {
+ auto size = stream.size();
name = readString(stream);
- center.x = stream->readUint16LE();
- center.y = stream->readUint16LE();
- flags = stream->readUint16LE();
+ center.x = stream.readSint16LE();
+ center.y = stream.readSint16LE();
+ flags = stream.readUint16LE();
debug("region %s at (%d,%d) %04x", name.c_str(), center.x, center.y, flags);
- while (stream->pos() + 2 <= size) {
- uint16 ext = stream->readUint16LE();
+ while (stream.pos() + 2 <= size) {
+ uint16 ext = stream.readUint16LE();
if (ext)
debug("extended entries %u", ext);
PointsType points;
while (ext--) {
- int16 a = stream->readSint16LE();
- int16 b = stream->readSint16LE();
- int16 c = stream->readUint16LE();
+ int16 a = stream.readSint16LE();
+ int16 b = stream.readSint16LE();
+ int16 c = stream.readUint16LE();
if (c != -12851) //0xcdcd
debug("extended entry: %d %d %d", a, b, c);
else
diff --git a/engines/agds/region.h b/engines/agds/region.h
index 3b41c40e9c8..c896b36c0eb 100644
--- a/engines/agds/region.h
+++ b/engines/agds/region.h
@@ -38,7 +38,7 @@ struct Region {
uint16 flags;
Common::Array<PointsType> regions;
- Region(const Common::String &resourceName, Common::SeekableReadStream * stream);
+ Region(const Common::String &resourceName, Common::SeekableReadStream &stream);
Region(const Common::Rect rect);
bool pointIn(Common::Point point) const;
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 8130fda805a..1d659c5a395 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -230,19 +230,19 @@ Common::String ResourceManager::loadText(const Common::String &name) const {
return loadText(stream);
}
-Common::String readString(Common::ReadStream *stream, uint size) {
+Common::String readString(Common::ReadStream &stream, uint size) {
Common::Array<char> text(size);
- if (stream->read(text.data(), text.size()) != text.size())
+ if (stream.read(text.data(), text.size()) != text.size())
error("readString: short read");
return Common::String(text.data(), strlen(text.data()));
}
-void writeString(Common::WriteStream *stream, const Common::String &string, uint size) {
+void writeString(Common::WriteStream &stream, const Common::String &string, uint size) {
Common::Array<char> text(size);
memcpy(text.data(), string.c_str(), MIN(string.size(), size));
- if (stream->write(text.data(), text.size()) != text.size())
+ if (stream.write(text.data(), text.size()) != text.size())
error("writeString: short write");
}
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index e635ad00b70..c0b22031f28 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -101,8 +101,8 @@ public:
Common::String loadText(const Common::String & name) const;
};
-Common::String readString(Common::ReadStream *stream, uint size = 32);
-void writeString(Common::WriteStream *stream, const Common::String &string, uint size = 32);
+Common::String readString(Common::ReadStream &stream, uint size = 32);
+void writeString(Common::WriteStream &stream, const Common::String &string, uint size = 32);
} // End of namespace AGDS
diff --git a/engines/agds/systemVariable.cpp b/engines/agds/systemVariable.cpp
index 051dfcdaa16..6749268bb91 100644
--- a/engines/agds/systemVariable.cpp
+++ b/engines/agds/systemVariable.cpp
@@ -22,7 +22,6 @@
#include "agds/systemVariable.h"
#include "common/array.h"
-#include "common/debug.h"
#include "common/stream.h"
#include "common/textconsole.h"
@@ -44,12 +43,12 @@ void IntegerSystemVariable::setInteger(int value) {
_value = value;
}
-void IntegerSystemVariable::read(Common::ReadStream * stream) {
- _value = stream->readUint32LE();
+void IntegerSystemVariable::read(Common::ReadStream &stream) {
+ _value = stream.readSint32LE();
}
-void IntegerSystemVariable::write(Common::WriteStream * stream) const {
- stream->writeUint32LE(_value);
+void IntegerSystemVariable::write(Common::WriteStream &stream) const {
+ stream.writeSint32LE(_value);
}
const Common::String &StringSystemVariable::getString() const {
@@ -68,21 +67,21 @@ void StringSystemVariable::setInteger(int value) {
error("invalid type");
}
-void StringSystemVariable::read(Common::ReadStream * stream) {
- byte len = stream->readByte();
+void StringSystemVariable::read(Common::ReadStream &stream) {
+ byte len = stream.readByte();
if (len == 0)
error("invalid string var length");
Common::Array<char> str(len);
- stream->read(str.data(), str.size());
+ stream.read(str.data(), str.size());
_value = Common::String(str.data(), len - 1);
}
-void StringSystemVariable::write(Common::WriteStream * stream) const {
+void StringSystemVariable::write(Common::WriteStream &stream) const {
uint len = _value.size() + 1;
if (len > 255)
error("variable too long, %u", len);
- stream->writeByte(len);
- stream->write(_value.c_str(), len);
+ stream.writeByte(len);
+ stream.write(_value.c_str(), len);
}
} // namespace AGDS
diff --git a/engines/agds/systemVariable.h b/engines/agds/systemVariable.h
index 6d25ae67760..0dd9590cef5 100644
--- a/engines/agds/systemVariable.h
+++ b/engines/agds/systemVariable.h
@@ -42,8 +42,8 @@ public:
virtual void setString(const Common::String &value) = 0;
virtual void setInteger(int value) = 0;
virtual void reset() = 0;
- virtual void read(Common::ReadStream * stream) = 0;
- virtual void write(Common::WriteStream * stream) const = 0;
+ virtual void read(Common::ReadStream &stream) = 0;
+ virtual void write(Common::WriteStream &stream) const = 0;
};
class IntegerSystemVariable : public SystemVariable {
@@ -62,8 +62,8 @@ public:
virtual void reset() {
_value = _defaultValue;
}
- virtual void read(Common::ReadStream * stream);
- virtual void write(Common::WriteStream * stream) const;
+ virtual void read(Common::ReadStream &stream);
+ virtual void write(Common::WriteStream &stream) const;
};
class StringSystemVariable : public SystemVariable {
@@ -81,8 +81,8 @@ public:
virtual void reset() {
_value = _defaultValue;
}
- virtual void read(Common::ReadStream * stream);
- virtual void write(Common::WriteStream * stream) const;
+ virtual void read(Common::ReadStream &stream);
+ virtual void write(Common::WriteStream &stream) const;
};
} // End of namespace AGDS
Commit: 9d4add9a0cdcb2e9551d9ccb36cbed6fbc7dd8c9
https://github.com/scummvm/scummvm/commit/9d4add9a0cdcb2e9551d9ccb36cbed6fbc7dd8c9
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:13+01:00
Commit Message:
AGDS: use ScopedPtr everywhere
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/mjpgPlayer.cpp
engines/agds/mjpgPlayer.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/process_opcodes.cpp
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
engines/agds/soundManager.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 746e1e94db2..55311f604d4 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -73,13 +73,10 @@ AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Eng
}
AGDSEngine::~AGDSEngine() {
- delete _jokes;
- delete _currentCharacter;
- delete _currentScreen;
for (PictureCacheType::iterator i = _pictureCache.begin(); i != _pictureCache.end(); ++i) {
i->_value->free();
- delete i->_value;
}
+ _pictureCache.clear();
}
bool AGDSEngine::initGraphics(int w, int h) {
@@ -168,7 +165,7 @@ bool AGDSEngine::load() {
{
Common::ScopedPtr<Common::File> file(new Common::File());
file->open("jokes.chr");
- _jokes = new Character(this, "jokes");
+ _jokes.reset(new Character(this, "jokes"));
_jokes->load(*file);
}
@@ -189,7 +186,8 @@ RegionPtr AGDSEngine::loadRegion(const Common::String &name) {
Common::String AGDSEngine::loadText(const Common::String &entryName) {
if (entryName.empty())
return Common::String();
- return ResourceManager::loadText(_data.getEntry(entryName));
+ Common::ScopedPtr<Common::SeekableReadStream> stream(_data.getEntry(entryName));
+ return ResourceManager::loadText(*stream);
}
ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::String &prototype, bool allowInitialise) {
@@ -348,9 +346,9 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
bool hasScreenPatch = doPatch && patch->screenSaved;
_currentScreenName = name;
- _currentScreen = nullptr;
+ _currentScreen.reset();
auto screenObject = loadObject(name, Common::String(), !hasScreenPatch);
- _currentScreen = new Screen(this, screenObject, loadingType, previousScreenName);
+ _currentScreen.reset(new Screen(this, screenObject, loadingType, previousScreenName));
runProcess(screenObject);
@@ -367,8 +365,7 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
}
void AGDSEngine::resetCurrentScreen() {
- delete _currentScreen;
- _currentScreen = NULL;
+ _currentScreen.reset();
_currentScreenName.clear();
}
@@ -799,11 +796,10 @@ Common::Error AGDSEngine::run() {
}
void AGDSEngine::playFilm(Process &process, const Common::String &video, const Common::String &audio, const Common::String &subtitles) {
- delete _mjpgPlayer;
- _mjpgPlayer = nullptr;
+ _mjpgPlayer.reset();
_filmProcess = process.getName();
- _mjpgPlayer = new MJPGPlayer(_resourceManager.getResource(video), subtitles);
+ _mjpgPlayer.reset(new MJPGPlayer(_resourceManager.getResource(video), subtitles));
_soundManager.stopAll();
_filmStarted = _system->getMillis();
_syncSoundId = _soundManager.play(process.getName(), Common::String(), audio, Common::String(), true, 100, 0);
@@ -811,10 +807,7 @@ void AGDSEngine::playFilm(Process &process, const Common::String &video, const C
void AGDSEngine::skipFilm() {
debug("skip");
- if (_mjpgPlayer) {
- delete _mjpgPlayer;
- _mjpgPlayer = NULL;
- }
+ _mjpgPlayer.reset();
if (_syncSoundId >= 0) {
debug("skip: stopping sound %d", _syncSoundId);
_mixer->stopID(_syncSoundId);
@@ -882,13 +875,11 @@ AnimationPtr AGDSEngine::findAnimationByPhaseVar(const Common::String &phaseVar)
void AGDSEngine::loadCharacter(const Common::String &id, const Common::String &filename, const Common::String &object) {
debug("loadCharacter %s %s %s", id.c_str(), filename.c_str(), object.c_str());
- delete _currentCharacter;
-
_currentCharacterName = id;
_currentCharacterFilename = filename;
_currentCharacterObject = object;
- _currentCharacter = new Character(this, id);
+ _currentCharacter.reset(new Character(this, id));
Common::ScopedPtr<Common::SeekableReadStream> stream(_resourceManager.getResource(loadText(filename)));
_currentCharacter->load(*stream);
_currentCharacter->associate(object);
@@ -908,28 +899,26 @@ int AGDSEngine::saveToCache(const Common::String &name, Graphics::ManagedSurface
return -1;
int id = _pictureCacheId++;
_pictureCacheLookup[name] = id;
- _pictureCache[id] = surface;
+ _pictureCache[id].reset(surface);
return id;
}
Graphics::ManagedSurface *AGDSEngine::loadFromCache(int id) const {
PictureCacheType::const_iterator i = _pictureCache.find(id);
- return (i != _pictureCache.end()) ? i->_value : NULL;
+ return (i != _pictureCache.end()) ? i->_value.get() : NULL;
}
void AGDSEngine::loadFont(int id, const Common::String &name, int gw, int gh) {
debug("loadFont %d %s %d %d", id, name.c_str(), gw, gh);
Graphics::ManagedSurface *surface = loadPicture(name);
- Font *&font = _fonts[id];
- delete font;
- font = new Font(surface, gw, gh);
+ _fonts[id].reset(new Font(surface, gw, gh));
}
Font *AGDSEngine::getFont(int id) const {
FontsType::const_iterator i = _fonts.find(id);
if (i == _fonts.end())
error("no font with id %d", id);
- return i->_value;
+ return i->_value.get();
}
Graphics::Surface *AGDSEngine::createSurface(int w, int h) {
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 1cfc620a87a..ccf285224ed 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -171,7 +171,7 @@ public:
}
Screen * getCurrentScreen() {
- return _currentScreen;
+ return _currentScreen.get();
}
Console * getConsole();
@@ -200,13 +200,13 @@ public:
AnimationPtr findAnimationByPhaseVar(const Common::String &phaseVar);
void loadCharacter(const Common::String &id, const Common::String &name, const Common::String &object);
Character * getCharacter(const Common::String &name) {
- return _currentCharacterName == name? _currentCharacter: nullptr;
+ return _currentCharacterName == name? _currentCharacter.get(): nullptr;
}
Character * currentCharacter() const {
- return _currentCharacter;
+ return _currentCharacter.get();
}
Character * jokes() const {
- return _jokes;
+ return _jokes.get();
}
void loadDefaultMouseCursor(const Common::String &name) {
@@ -285,76 +285,76 @@ private:
void stopAmbientSound();
void loadPatches(Common::SeekableReadStream &file, Database & db);
- typedef Common::HashMap<int, Graphics::ManagedSurface *> PictureCacheType;
+ typedef Common::HashMap<int, Common::ScopedPtr<Graphics::ManagedSurface>> PictureCacheType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PictureCacheLookup;
typedef Common::Array<Common::String> SystemVariablesListType;
typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
- typedef Common::HashMap<int, Font *> FontsType;
+ typedef Common::HashMap<int, Common::ScopedPtr<Font>> FontsType;
typedef Common::HashMap<Common::String, PatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PatchesType;
typedef Common::HashMap<Common::String, ObjectPatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectPatchesType;
typedef Common::HashMap<Common::String, Common::Array<uint8>> PatchDatabase;
- const ADGameDescription * _gameDescription;
- ResourceManager _resourceManager;
- SoundManager _soundManager;
- Database _data;
- PictureCacheType _pictureCache;
- PictureCacheLookup _pictureCacheLookup;
- int _pictureCacheId;
- FontsType _fonts;
- ProcessListType _processes;
- ProcessListType _pendingReactivatedProcesses;
- PatchesType _patches;
- ObjectPatchesType _objectPatches;
- int _sharedStorageIndex;
- Common::String _sharedStorage[10];
- GlobalsType _globals;
- SystemVariablesListType _systemVarList;
- SystemVariablesType _systemVars;
- Graphics::PixelFormat _pixelFormat;
- Color _colorKey;
- Color _minShadowColor;
- Color _maxShadowColor;
- int _shadowIntensity;
- MJPGPlayer * _mjpgPlayer;
- uint32 _filmStarted;
- Common::String _filmProcess;
- Screen * _currentScreen;
- Common::String _currentScreenName;
- Character * _currentCharacter;
- Character * _jokes;
- Common::String _currentCharacterName, _currentCharacterFilename, _currentCharacterObject;
- Common::String _nextScreenName;
- ScreenLoadingType _nextScreenType;
- Common::String _defaultMouseCursorName;
- AnimationPtr _defaultMouseCursor;
- Common::Point _mouse;
- bool _userEnabled;
- bool _systemUserEnabled;
- MouseMap _mouseMap;
- Common::RandomSource _random;
-
- Inventory _inventory;
- Common::String _inventoryRegionName;
- RegionPtr _inventoryRegion;
- ObjectPtr _currentInventoryObject;
-
- Dialog _dialog;
+ const ADGameDescription * _gameDescription;
+ ResourceManager _resourceManager;
+ SoundManager _soundManager;
+ Database _data;
+ PictureCacheType _pictureCache;
+ PictureCacheLookup _pictureCacheLookup;
+ int _pictureCacheId;
+ FontsType _fonts;
+ ProcessListType _processes;
+ ProcessListType _pendingReactivatedProcesses;
+ PatchesType _patches;
+ ObjectPatchesType _objectPatches;
+ int _sharedStorageIndex;
+ Common::String _sharedStorage[10];
+ GlobalsType _globals;
+ SystemVariablesListType _systemVarList;
+ SystemVariablesType _systemVars;
+ Graphics::PixelFormat _pixelFormat;
+ Color _colorKey;
+ Color _minShadowColor;
+ Color _maxShadowColor;
+ int _shadowIntensity;
+ Common::ScopedPtr<MJPGPlayer> _mjpgPlayer;
+ uint32 _filmStarted;
+ Common::String _filmProcess;
+ Common::ScopedPtr<Screen> _currentScreen;
+ Common::String _currentScreenName;
+ Common::ScopedPtr<Character> _currentCharacter;
+ Common::ScopedPtr<Character> _jokes;
+ Common::String _currentCharacterName, _currentCharacterFilename, _currentCharacterObject;
+ Common::String _nextScreenName;
+ ScreenLoadingType _nextScreenType;
+ Common::String _defaultMouseCursorName;
+ AnimationPtr _defaultMouseCursor;
+ Common::Point _mouse;
+ bool _userEnabled;
+ bool _systemUserEnabled;
+ MouseMap _mouseMap;
+ Common::RandomSource _random;
+
+ Inventory _inventory;
+ Common::String _inventoryRegionName;
+ RegionPtr _inventoryRegion;
+ ObjectPtr _currentInventoryObject;
+
+ Dialog _dialog;
// Original engine use weird names for the vars, I keep them.
- int _tellTextTimer;
- TextLayout _textLayout;
+ int _tellTextTimer;
+ TextLayout _textLayout;
- int _syncSoundId;
- int _ambientSoundId;
+ int _syncSoundId;
+ int _ambientSoundId;
- Common::String _curtainProcess;
- int _curtainTimer;
- int _curtainScreen;
+ Common::String _curtainProcess;
+ int _curtainTimer;
+ int _curtainScreen;
- bool _fastMode;
- bool _hintMode;
+ bool _fastMode;
+ bool _hintMode;
};
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index d5cc0cd0b59..3a28892b2e6 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -40,14 +40,12 @@ Animation::Animation(AGDSEngine *engine, const Common::String &name) :
Animation::~Animation() {
freeFrame();
- delete _flic;
}
void Animation::freeScaledFrame() {
if (_scaledFrame) {
_scaledFrame->free();
- delete _scaledFrame;
- _scaledFrame = nullptr;
+ _scaledFrame.reset();
}
}
@@ -55,8 +53,7 @@ void Animation::freeFrame() {
freeScaledFrame();
if (_frame) {
_frame->free();
- delete _frame;
- _frame = nullptr;
+ _frame.reset();
}
}
@@ -85,11 +82,10 @@ bool Animation::load(Common::SeekableReadStream *stream, const Common::String &f
_delay = 0;
}
}
- delete _flic;
- _flic = nullptr;
+ _flic.reset();
if (fname.hasSuffixIgnoreCase(".bmp")) {
- _frame = _engine->loadPicture(fname);
+ _frame.reset(_engine->loadPicture(fname));
rescaleCurrentFrame();
_frames = 1;
return true;
@@ -98,7 +94,7 @@ bool Animation::load(Common::SeekableReadStream *stream, const Common::String &f
Video::FlicDecoder *flic = new Video::FlicDecoder;
if (flic->loadStream(stream)) {
_frames = flic->getFrameCount();
- _flic = flic;
+ _flic.reset(flic);
decodeNextFrame();
return true;
} else {
@@ -122,15 +118,11 @@ void Animation::rescaleCurrentFrame() {
freeScaledFrame();
if (_rotation != 0) {
Graphics::TransformStruct transform(_scale * 100, _scale * 100, 90 * _rotation, _frame->w / 2, _frame->h / 2, Graphics::TSpriteBlendMode::BLEND_NORMAL, Graphics::kDefaultRgbaMod);
- if (_scaledFrame)
- delete _scaledFrame;
- _scaledFrame = _frame->rotoscale(transform);
+ _scaledFrame.reset(_frame->rotoscale(transform));
} else if (_scale != 1) {
- if (_scaledFrame)
- delete _scaledFrame;
- _scaledFrame = _frame->scale(_frame->w * _scale, _frame->h * _scale, true);
+ _scaledFrame.reset(_frame->scale(_frame->w * _scale, _frame->h * _scale, true));
}
- auto *frame = _scaledFrame? _scaledFrame: _frame;
+ auto *frame = _scaledFrame? _scaledFrame.get(): _frame.get();
if (frame) {
uint h = frame->h, w = frame->w;
_visibleHeight = 0;
@@ -170,7 +162,7 @@ void Animation::decodeNextFrame() {
freeFrame();
_delay = _flic->getCurFrameDelay() * _speed / 4000; //40 == 1000 / 25, 25 fps
- _frame = _engine->convertToTransparent(frame->convertTo(_engine->pixelFormat(), _flic->getPalette()));
+ _frame.reset(_engine->convertToTransparent(frame->convertTo(_engine->pixelFormat(), _flic->getPalette())));
rescaleCurrentFrame();
++_phase;
}
@@ -248,7 +240,7 @@ bool Animation::tick() {
void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst, Graphics::ManagedSurface *mask, int maskAlpha) const {
dst += _position;
- auto *frame = _scaledFrame? _scaledFrame: _frame;
+ auto *frame = _scaledFrame? _scaledFrame.get(): _frame.get();
if (!frame || !_onScreen)
return;
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index d85b7721e72..854597e54d3 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/rect.h"
#include "common/str.h"
+#include "common/ptr.h"
namespace Common { class SeekableReadStream; }
namespace Graphics { struct Surface; struct ManagedSurface; }
@@ -37,11 +38,14 @@ class AGDSEngine;
class Object;
class Animation {
+ using FlicPtr = Common::ScopedPtr<Video::FlicDecoder>;
+ using ManagedSurfacePtr = Common::ScopedPtr<Graphics::ManagedSurface>;
+
AGDSEngine * _engine;
Common::String _name;
- Video::FlicDecoder *_flic;
- Graphics::ManagedSurface *_frame;
- Graphics::ManagedSurface *_scaledFrame;
+ FlicPtr _flic;
+ ManagedSurfacePtr _frame;
+ ManagedSurfacePtr _scaledFrame;
int _frames;
Common::Point _position;
Common::String _process;
diff --git a/engines/agds/mjpgPlayer.cpp b/engines/agds/mjpgPlayer.cpp
index 063d5097389..c44b2776431 100644
--- a/engines/agds/mjpgPlayer.cpp
+++ b/engines/agds/mjpgPlayer.cpp
@@ -66,9 +66,7 @@ MJPGPlayer::MJPGPlayer(Common::SeekableReadStream *stream, const Common::String
}
}
-MJPGPlayer::~MJPGPlayer() {
- delete _stream;
-}
+MJPGPlayer::~MJPGPlayer() {}
void MJPGPlayer::rewind() {
_framesPlayed = 0;
@@ -86,26 +84,24 @@ const Graphics::Surface *MJPGPlayer::decodeFrame() {
if (_stream->eos())
return NULL;
- Common::SeekableReadStream *stream = _stream->readStream(size);
+ Common::ScopedPtr<Common::SeekableReadStream> stream(_stream->readStream(size));
const Graphics::Surface *surface = _decoder.decodeFrame(*stream);
++_framesPlayed;
- delete stream;
return surface;
}
void MJPGPlayer::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
auto *surface = decodeFrame();
if (surface) {
- Graphics::Surface *scaled;
+ Common::ScopedPtr<Graphics::Surface> scaled;
{
- Graphics::Surface *converted = surface->convertTo(engine.pixelFormat());
+ Common::ScopedPtr<Graphics::Surface> converted(surface->convertTo(engine.pixelFormat()));
auto scaleW = 1.0f * backbuffer.w / converted->w;
auto scaleH = 1.0f * backbuffer.h / converted->h;
auto scale = MIN(scaleW, scaleH);
- scaled = converted->scale(converted->w * scale, converted->h * scale);
+ scaled.reset(converted->scale(converted->w * scale, converted->h * scale));
converted->free();
- delete converted;
}
Common::Point dst((backbuffer.w - scaled->w) / 2, (backbuffer.h - scaled->h) / 2);
@@ -114,7 +110,6 @@ void MJPGPlayer::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer.getRect()))
backbuffer.copyRectToSurface(*scaled, dst.x, dst.y, srcRect);
scaled->free();
- delete scaled;
}
if (_subtitles.empty())
diff --git a/engines/agds/mjpgPlayer.h b/engines/agds/mjpgPlayer.h
index 8131b20c199..07294c98f98 100644
--- a/engines/agds/mjpgPlayer.h
+++ b/engines/agds/mjpgPlayer.h
@@ -34,7 +34,8 @@ namespace AGDS {
class AGDSEngine;
class MJPGPlayer {
- Common::SeekableReadStream * _stream;
+ using StreamPtr = Common::ScopedPtr<Common::SeekableReadStream>;
+ StreamPtr _stream;
int32 _firstFramePos;
Image::JPEGDecoder _decoder;
uint _framesPlayed;
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 9a24d884622..2671d84b04a 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -78,16 +78,14 @@ void Object::unlock() {
void Object::freeRotated() {
if (_rotatedPicture) {
_rotatedPicture->free();
- delete _rotatedPicture;
- _rotatedPicture = nullptr;
+ _rotatedPicture.reset();
}
}
void Object::freePicture() {
if (_picture) {
_picture->free();
- delete _picture;
- _picture = nullptr;
+ _picture.reset();
}
}
@@ -139,7 +137,7 @@ const Object::StringEntry &Object::getString(uint16 index) const {
void Object::setPicture(Graphics::ManagedSurface *picture) {
_pos = Common::Point();
freePicture();
- _picture = picture;
+ _picture.reset(picture);
freeRotated();
_rotation = 0;
@@ -189,7 +187,7 @@ void Object::createRotated() {
return;
Graphics::TransformStruct transform(100, 100, 90 * _rotation, _picture->w / 2, _picture->h / 2);
- _rotatedPicture = getPicture()->rotoscale(transform);
+ _rotatedPicture.reset(getPicture()->rotoscale(transform));
}
void Object::alive(bool value)
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 59fa9d7ef83..587c9a5a0b2 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -58,6 +58,7 @@ private:
typedef Common::Array<StringEntry> StringTableType;
typedef Common::HashMap<Common::String, uint, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> KeyHandlersType;
typedef Common::HashMap<Common::String, uint> UseHandlersType;
+ using ManagedSurfacePtr = Common::ScopedPtr<Graphics::ManagedSurface>;
Common::String _name;
CodeType _code;
@@ -65,8 +66,8 @@ private:
bool _stringTableLoaded;
KeyHandlersType _keyHandlers;
UseHandlersType _useHandlers;
- Graphics::ManagedSurface * _picture;
- Graphics::ManagedSurface * _rotatedPicture;
+ ManagedSurfacePtr _picture;
+ ManagedSurfacePtr _rotatedPicture;
RegionPtr _region;
RegionPtr _trapRegion;
AnimationPtr _animation;
@@ -160,7 +161,7 @@ public:
void setPicture(Graphics::ManagedSurface *);
Graphics::ManagedSurface *getPicture() const {
- return _rotatedPicture? _rotatedPicture: _picture;
+ return _rotatedPicture? _rotatedPicture.get(): _picture.get();
}
void rotate(int rot);
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 86ffdecf0ff..7c5066f6cd6 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -909,7 +909,7 @@ void Process::loadSaveSlotNamePicture() {
Common::String saveSlotName = _engine->getSaveStateName(saveSlot);
Common::SaveFileManager * saveMan = _engine->getSaveFileManager();
- Common::InSaveFile * save = saveMan->openForLoading(saveSlotName);
+ Common::ScopedPtr<Common::InSaveFile> save(saveMan->openForLoading(saveSlotName));
debug("save state name: %s", saveSlotName.c_str());
int fontId = _engine->getSystemVariable("edit_font")->getInteger();
@@ -925,8 +925,6 @@ void Process::loadSaveSlotNamePicture() {
Graphics::ManagedSurface *transparentLabel = _engine->convertToTransparent(label);
_object->setPicture(transparentLabel);
_object->generateRegion();
-
- delete save;
}
void Process::setObjectRegionOffset() {
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 1d659c5a395..8666013416e 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -151,13 +151,12 @@ Common::SeekableReadStream *ResourceManager::GrpFile::createReadStreamForMember(
}
bool ResourceManager::addPath(const Common::Path &grpFilename) {
- GrpFile *grpFile = new GrpFile();
+ Common::ScopedPtr<GrpFile> grpFile(new GrpFile());
if (!grpFile->load(grpFilename)) {
- delete grpFile;
return false;
}
- SearchMan.add(grpFilename.toString(), grpFile, 0, true);
+ SearchMan.add(grpFilename.toString(), grpFile.release(), 0, true);
return true;
}
@@ -199,13 +198,10 @@ Graphics::Surface *ResourceManager::loadPicture(const Common::String &name, cons
return NULL;
}
-Common::String ResourceManager::loadText(Common::SeekableReadStream *stream) {
- if (!stream)
- error("stream is null");
- Common::Array<char> text(stream->size());
- if (stream->read(text.data(), text.size()) != text.size())
+Common::String ResourceManager::loadText(Common::SeekableReadStream &stream) {
+ Common::Array<char> text(stream.size());
+ if (stream.read(text.data(), text.size()) != text.size())
error("short read from text resource");
- delete stream;
if (text.empty())
return Common::String();
@@ -224,10 +220,10 @@ Common::String ResourceManager::loadText(Common::SeekableReadStream *stream) {
}
Common::String ResourceManager::loadText(const Common::String &name) const {
- Common::SeekableReadStream *stream = getResource(name);
+ Common::ScopedPtr<Common::SeekableReadStream> stream(getResource(name));
if (!stream)
error("no text resource %s", name.c_str());
- return loadText(stream);
+ return loadText(*stream);
}
Common::String readString(Common::ReadStream &stream, uint size) {
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index c0b22031f28..1f9e7189f92 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -97,7 +97,7 @@ public:
Common::SeekableReadStream * getResource(const Common::String &name) const;
Graphics::Surface * loadPicture(const Common::String & name, const Graphics::PixelFormat &format);
- static Common::String loadText(Common::SeekableReadStream *stream);
+ static Common::String loadText(Common::SeekableReadStream &stream);
Common::String loadText(const Common::String & name) const;
};
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 209724156e1..5cd6c5cc24e 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -125,7 +125,7 @@ int SoundManager::play(Common::String process, const Common::String &resource, c
return sample->id;
}
}
- Common::File *file = new Common::File();
+ Common::ScopedPtr<Common::File> file(new Common::File());
if (!file->open(Common::Path{filename})) {
if (!phaseVar.empty())
_engine->setGlobal(phaseVar, 1);
@@ -140,13 +140,12 @@ int SoundManager::play(Common::String process, const Common::String &resource, c
Audio::SeekableAudioStream *stream = NULL;
if (lname.hasSuffix(".ogg")) {
- stream = Audio::makeVorbisStream(file, DisposeAfterUse::YES);
+ stream = Audio::makeVorbisStream(file.release(), DisposeAfterUse::YES);
} else if (lname.hasSuffix(".wav")) {
- stream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
+ stream = Audio::makeWAVStream(file.release(), DisposeAfterUse::YES);
}
if (!stream) {
warning("could not play sound %s", filename.c_str());
- delete file;
if (!phaseVar.empty())
_engine->setGlobal(phaseVar, _engine->getGlobal(phaseVar)? 1: 0);
else
Commit: a9caa34479612a7bf30f48e2da0741c8fe1c5877
https://github.com/scummvm/scummvm/commit/a9caa34479612a7bf30f48e2da0741c8fe1c5877
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:13+01:00
Commit Message:
AGDS: replace typedefs with using
Changed paths:
engines/agds/agds.h
engines/agds/database.h
engines/agds/dialog.h
engines/agds/inventory.h
engines/agds/mouseMap.h
engines/agds/object.h
engines/agds/process.h
engines/agds/region.cpp
engines/agds/region.h
engines/agds/resourceManager.h
engines/agds/soundManager.h
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index ccf285224ed..122011c892f 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -78,7 +78,7 @@ class Console;
class AGDSEngine : public Engine {
friend class Process;
- typedef Common::Array<ProcessPtr> ProcessListType;
+ using ProcessListType = Common::Array<ProcessPtr>;
static constexpr uint MaxProcesses = 100;
public:
@@ -285,15 +285,15 @@ private:
void stopAmbientSound();
void loadPatches(Common::SeekableReadStream &file, Database & db);
- typedef Common::HashMap<int, Common::ScopedPtr<Graphics::ManagedSurface>> PictureCacheType;
- typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PictureCacheLookup;
- typedef Common::Array<Common::String> SystemVariablesListType;
- typedef Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SystemVariablesType;
- typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> GlobalsType;
- typedef Common::HashMap<int, Common::ScopedPtr<Font>> FontsType;
- typedef Common::HashMap<Common::String, PatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> PatchesType;
- typedef Common::HashMap<Common::String, ObjectPatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ObjectPatchesType;
- typedef Common::HashMap<Common::String, Common::Array<uint8>> PatchDatabase;
+ using PictureCacheType = Common::HashMap<int, Common::ScopedPtr<Graphics::ManagedSurface>>;
+ using PictureCacheLookup = Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
+ using SystemVariablesListType = Common::Array<Common::String>;
+ using SystemVariablesType = Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
+ using GlobalsType = Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
+ using FontsType = Common::HashMap<int, Common::ScopedPtr<Font>>;
+ using PatchesType = Common::HashMap<Common::String, PatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
+ using ObjectPatchesType = Common::HashMap<Common::String, ObjectPatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
+ using PatchDatabase = Common::HashMap<Common::String, Common::Array<uint8>>;
const ADGameDescription * _gameDescription;
ResourceManager _resourceManager;
diff --git a/engines/agds/database.h b/engines/agds/database.h
index b04222294a5..fe5caaba76b 100644
--- a/engines/agds/database.h
+++ b/engines/agds/database.h
@@ -42,7 +42,7 @@ private:
Entry(uint32 o, uint32 s): offset(o), size(s) { }
};
- typedef Common::HashMap<Common::String, Entry> EntriesType;
+ using EntriesType = Common::HashMap<Common::String, Entry>;
Common::String _filename;
bool _writeable;
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
index 9f3c2546f20..77bb1b33d9d 100644
--- a/engines/agds/dialog.h
+++ b/engines/agds/dialog.h
@@ -32,7 +32,7 @@ namespace AGDS {
class AGDSEngine;
class Dialog {
- typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> DialogDefsType;
+ using DialogDefsType = Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
private:
struct Sound {
@@ -46,7 +46,7 @@ private:
Sound(const Common::String &name, const Common::String &sample, int step): Name(name), Sample(sample), Step(step) {
}
};
- typedef Common::Array<Sound> SoundsType;
+ using SoundsType = Common::Array<Sound>;
AGDSEngine * _engine;
DialogDefsType _dialogDefs;
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index 297bbd8b949..41e9646406d 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -33,7 +33,7 @@ namespace Common { class ReadStream; class WriteStream; }
namespace AGDS {
class Object;
-typedef Common::SharedPtr<Object> ObjectPtr;
+using ObjectPtr = Common::SharedPtr<Object>;
class AGDSEngine;
class Inventory {
@@ -49,7 +49,7 @@ class Inventory {
object.reset();
}
};
- typedef Common::Array<Entry> EntriesType;
+ using EntriesType = Common::Array<Entry>;
EntriesType _entries;
bool _enabled;
bool _visible;
@@ -93,7 +93,7 @@ public:
return _entries;
}
- int maxSize() const {
+ uint maxSize() const {
return _entries.size();
}
diff --git a/engines/agds/mouseMap.h b/engines/agds/mouseMap.h
index b643be314cc..45fc1b1daf0 100644
--- a/engines/agds/mouseMap.h
+++ b/engines/agds/mouseMap.h
@@ -32,7 +32,7 @@ namespace AGDS {
class AGDSEngine;
struct Region;
-typedef Common::SharedPtr<Region> RegionPtr;
+using RegionPtr = Common::SharedPtr<Region>;
struct MouseRegion {
int id = -1;
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 587c9a5a0b2..e1db6d9d2d2 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -43,7 +43,7 @@ using AnimationPtr = Common::SharedPtr<Animation>;
class Object {
public:
- typedef Common::Array<uint8> CodeType;
+ using CodeType = Common::Array<uint8>;
struct StringEntry
{
@@ -55,10 +55,10 @@ public:
};
private:
- typedef Common::Array<StringEntry> StringTableType;
- typedef Common::HashMap<Common::String, uint, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> KeyHandlersType;
- typedef Common::HashMap<Common::String, uint> UseHandlersType;
- using ManagedSurfacePtr = Common::ScopedPtr<Graphics::ManagedSurface>;
+ using StringTableType = Common::Array<StringEntry> ;
+ using KeyHandlersType = Common::HashMap<Common::String, uint, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
+ using UseHandlersType = Common::HashMap<Common::String, uint>;
+ using ManagedSurfacePtr = Common::ScopedPtr<Graphics::ManagedSurface>;
Common::String _name;
CodeType _code;
@@ -339,7 +339,7 @@ public:
bool pointIn(Common::Point pos);
};
-typedef Common::SharedPtr<Object> ObjectPtr;
+using ObjectPtr = Common::SharedPtr<Object>;
} // End of namespace AGDS
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 820ed71037f..5f3155d03ce 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -42,7 +42,7 @@ public:
enum Status { kStatusActive, kStatusPassive, kStatusDone, kStatusError };
private:
- typedef Common::Stack<int32> StackType;
+ using StackType = Common::Stack<int32>;
AGDSEngine * _engine;
Common::String _parentScreen;
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index d347827f59a..2d6b3ea9071 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -119,9 +119,9 @@ Common::Point Region::topLeft() const {
//FIXME: copied from wintermute/base_region.cpp
-typedef struct {
+struct dPoint {
double x, y;
-} dPoint;
+} ;
bool Region::pointIn(Common::Point point) const {
for(uint r = 0; r < regions.size(); ++r) {
diff --git a/engines/agds/region.h b/engines/agds/region.h
index c896b36c0eb..1696cc59047 100644
--- a/engines/agds/region.h
+++ b/engines/agds/region.h
@@ -31,7 +31,7 @@
namespace AGDS {
struct Region {
- typedef Common::Array<Common::Point> PointsType;
+ using PointsType = Common::Array<Common::Point> ;
Common::String name;
Common::Point center;
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 1f9e7189f92..70a8333c0b7 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -64,13 +64,13 @@ private:
return nullptr;
}
};
- typedef Common::SharedPtr<ArchiveMember> ArchiveMemberPtr;
+ using ArchiveMemberPtr = Common::SharedPtr<ArchiveMember>;
class GrpFile : public Common::Archive
{
Common::File _file;
- typedef Common::HashMap<Common::String, ArchiveMemberPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> MembersType;
+ using MembersType = Common::HashMap<Common::String, ArchiveMemberPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
MembersType _members;
public:
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index d3f3994d399..ec150d6f384 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -60,7 +60,7 @@ namespace AGDS {
};
class SoundManager {
- typedef Common::List<Sound> SoundList;
+ using SoundList = Common::List<Sound>;
int _nextId;
AGDSEngine * _engine;
Audio::Mixer * _mixer;
Commit: efca2860d8a2dd886279694b55d5b111f9976adc
https://github.com/scummvm/scummvm/commit/efca2860d8a2dd886279694b55d5b111f9976adc
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-11-12T15:59:13+01:00
Commit Message:
VIDEO: Add missing override keywords
Changed paths:
video/flic_decoder.h
diff --git a/video/flic_decoder.h b/video/flic_decoder.h
index c0510d0e983..79b2f4c8d21 100644
--- a/video/flic_decoder.h
+++ b/video/flic_decoder.h
@@ -66,21 +66,21 @@ protected:
virtual void readHeader();
- bool endOfTrack() const;
- virtual bool isRewindable() const { return true; }
- virtual bool rewind();
+ bool endOfTrack() const override;
+ virtual bool isRewindable() const override{ return true; }
+ virtual bool rewind() override;
- uint16 getWidth() const;
- uint16 getHeight() const;
- Graphics::PixelFormat getPixelFormat() const;
+ uint16 getWidth() const override;
+ uint16 getHeight() const override;
+ Graphics::PixelFormat getPixelFormat() const override;
int getCurFrame() const override { return _curFrame; }
int getCurFrameDelay() const override { return _frameDelay; }
int getFrameCount() const override { return _frameCount; }
- uint32 getNextFrameStartTime() const { return _nextFrameStartTime; }
- virtual const Graphics::Surface *decodeNextFrame();
+ uint32 getNextFrameStartTime() const override { return _nextFrameStartTime; }
+ virtual const Graphics::Surface *decodeNextFrame() override;
virtual void handleFrame();
- const byte *getPalette() const { _dirtyPalette = false; return _palette.data(); }
- bool hasDirtyPalette() const { return _dirtyPalette; }
+ const byte *getPalette() const override{ _dirtyPalette = false; return _palette.data(); }
+ bool hasDirtyPalette() const override { return _dirtyPalette; }
const Common::List<Common::Rect> *getDirtyRects() const { return &_dirtyRects; }
void clearDirtyRects() { _dirtyRects.clear(); }
Commit: a626fa98bcbbdbe6e84ae5a012b04b1f26f5f194
https://github.com/scummvm/scummvm/commit/a626fa98bcbbdbe6e84ae5a012b04b1f26f5f194
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-11-12T15:59:13+01:00
Commit Message:
AGDS: Fix struct/class forward declaration mismatches
Changed paths:
engines/agds/agds.h
engines/agds/animation.h
engines/agds/character.h
engines/agds/font.h
engines/agds/object.h
engines/agds/textLayout.h
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 122011c892f..3ce5957c972 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -51,7 +51,7 @@
* - Black Mirror (Windows)
*/
-namespace Graphics { struct ManagedSurface; }
+namespace Graphics { class ManagedSurface; }
namespace AGDS {
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 854597e54d3..d13470ece6f 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -29,7 +29,7 @@
#include "common/ptr.h"
namespace Common { class SeekableReadStream; }
-namespace Graphics { struct Surface; struct ManagedSurface; }
+namespace Graphics { struct Surface; class ManagedSurface; }
namespace Video { class FlicDecoder; }
namespace AGDS {
diff --git a/engines/agds/character.h b/engines/agds/character.h
index edaf9c01987..e3e91ce582f 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -29,7 +29,7 @@
#include "common/rect.h"
namespace Common { class SeekableReadStream; class ReadStream; class WriteStream; }
-namespace Graphics { struct Surface; struct ManagedSurface; }
+namespace Graphics { struct Surface; class ManagedSurface; }
namespace AGDS {
diff --git a/engines/agds/font.h b/engines/agds/font.h
index be9bc35b1e3..500a3913451 100644
--- a/engines/agds/font.h
+++ b/engines/agds/font.h
@@ -27,7 +27,7 @@
#include "common/ptr.h"
namespace Graphics {
- struct ManagedSurface;
+ class ManagedSurface;
}
namespace AGDS {
diff --git a/engines/agds/object.h b/engines/agds/object.h
index e1db6d9d2d2..96028cfc012 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -31,7 +31,7 @@
#include "common/rect.h"
#include "common/stream.h"
-namespace Graphics { struct Surface; struct ManagedSurface; }
+namespace Graphics { struct Surface; class ManagedSurface; }
namespace AGDS {
diff --git a/engines/agds/textLayout.h b/engines/agds/textLayout.h
index fd64edc6e0e..a5ddbcad956 100644
--- a/engines/agds/textLayout.h
+++ b/engines/agds/textLayout.h
@@ -29,7 +29,7 @@
#include "common/rect.h"
namespace Graphics {
- class Surface;
+ struct Surface;
}
namespace AGDS {
Commit: 4c85210750c196f254d16ca36932ee3264dd8dbf
https://github.com/scummvm/scummvm/commit/4c85210750c196f254d16ca36932ee3264dd8dbf
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-11-12T15:59:13+01:00
Commit Message:
AGDS: Update license to GPLv3
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/character.cpp
engines/agds/character.h
engines/agds/console.cpp
engines/agds/console.h
engines/agds/database.cpp
engines/agds/database.h
engines/agds/detection.cpp
engines/agds/detection_tables.h
engines/agds/dialog.cpp
engines/agds/dialog.h
engines/agds/font.cpp
engines/agds/font.h
engines/agds/inventory.cpp
engines/agds/inventory.h
engines/agds/metaengine.cpp
engines/agds/mjpgPlayer.cpp
engines/agds/mjpgPlayer.h
engines/agds/mouseMap.cpp
engines/agds/mouseMap.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/opcode.h
engines/agds/patch.cpp
engines/agds/patch.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
engines/agds/region.cpp
engines/agds/region.h
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
engines/agds/screen.cpp
engines/agds/screen.h
engines/agds/screenLoadingType.h
engines/agds/soundManager.cpp
engines/agds/soundManager.h
engines/agds/systemVariable.cpp
engines/agds/systemVariable.h
engines/agds/textLayout.cpp
engines/agds/textLayout.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 55311f604d4..0938551e673 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 3ce5957c972..652166fdf18 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 3a28892b2e6..a4608118eaa 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index d13470ece6f..c9dd2ede417 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index b6d84ba5736..d4a25ec6a53 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/character.h b/engines/agds/character.h
index e3e91ce582f..8ad59046e31 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index 74933a80c90..b55e4a99aae 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/console.h b/engines/agds/console.h
index 1dacd1263fa..b09a8ea6acd 100644
--- a/engines/agds/console.h
+++ b/engines/agds/console.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/database.cpp b/engines/agds/database.cpp
index 96068d8630a..93f0f8448ba 100644
--- a/engines/agds/database.cpp
+++ b/engines/agds/database.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/database.h b/engines/agds/database.h
index fe5caaba76b..6636dff2e7f 100644
--- a/engines/agds/database.h
+++ b/engines/agds/database.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/detection.cpp b/engines/agds/detection.cpp
index c6b20cc9562..22273a7fa12 100644
--- a/engines/agds/detection.cpp
+++ b/engines/agds/detection.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/detection_tables.h b/engines/agds/detection_tables.h
index 0a37032852f..abe3fd79b43 100644
--- a/engines/agds/detection_tables.h
+++ b/engines/agds/detection_tables.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 0f5ee983961..c533972c20e 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -1,3 +1,24 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
#include "agds/dialog.h"
#include "agds/agds.h"
#include "agds/systemVariable.h"
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
index 77bb1b33d9d..074705a69aa 100644
--- a/engines/agds/dialog.h
+++ b/engines/agds/dialog.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/font.cpp b/engines/agds/font.cpp
index 01627edbf4a..bd25299642e 100644
--- a/engines/agds/font.cpp
+++ b/engines/agds/font.cpp
@@ -1,3 +1,24 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
#include "agds/font.h"
#include "graphics/managed_surface.h"
diff --git a/engines/agds/font.h b/engines/agds/font.h
index 500a3913451..05ff8eab924 100644
--- a/engines/agds/font.h
+++ b/engines/agds/font.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index f3c97128bc1..b6cd1f83e60 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index 41e9646406d..0fa29b8b9e7 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/metaengine.cpp b/engines/agds/metaengine.cpp
index 823ccd39c98..ade0e88f9cb 100644
--- a/engines/agds/metaengine.cpp
+++ b/engines/agds/metaengine.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,10 +15,10 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
#include "agds/agds.h"
#include "agds/object.h"
#include "common/savefile.h"
diff --git a/engines/agds/mjpgPlayer.cpp b/engines/agds/mjpgPlayer.cpp
index c44b2776431..bfaa060eb7c 100644
--- a/engines/agds/mjpgPlayer.cpp
+++ b/engines/agds/mjpgPlayer.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/mjpgPlayer.h b/engines/agds/mjpgPlayer.h
index 07294c98f98..9e196f91e0e 100644
--- a/engines/agds/mjpgPlayer.h
+++ b/engines/agds/mjpgPlayer.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/mouseMap.cpp b/engines/agds/mouseMap.cpp
index 22a106d5b26..15fde872725 100644
--- a/engines/agds/mouseMap.cpp
+++ b/engines/agds/mouseMap.cpp
@@ -1,3 +1,24 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
#include "agds/mouseMap.h"
#include "agds/agds.h"
#include "agds/region.h"
@@ -85,4 +106,3 @@ void MouseMap::hideAll(AGDSEngine *engine) {
}
} // End of namespace AGDS
-
diff --git a/engines/agds/mouseMap.h b/engines/agds/mouseMap.h
index 45fc1b1daf0..89f43b74105 100644
--- a/engines/agds/mouseMap.h
+++ b/engines/agds/mouseMap.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 2671d84b04a..2d091b7a1b4 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 96028cfc012..8e57c327083 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 8f9a81d8db2..ef893c8a748 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index 6e799ee0080..2cc42572a0d 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -1,3 +1,24 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
#include "agds/patch.h"
#include "agds/resourceManager.h"
#include "common/stream.h"
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index dd72267f7e0..cd63c68fed5 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 1dc80348b0b..7bc85b77f40 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 5f3155d03ce..2ae1593c1f0 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index b7fe0df4308..5f36490201b 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 7c5066f6cd6..d94900611c5 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index 2d6b3ea9071..9a27b7b4624 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/region.h b/engines/agds/region.h
index 1696cc59047..327deb60919 100644
--- a/engines/agds/region.h
+++ b/engines/agds/region.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 8666013416e..51ffba651b2 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 70a8333c0b7..ac8e91c1c08 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 18ad91242b2..fa1eeb90166 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index ab0e3538d50..28b7495743a 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/screenLoadingType.h b/engines/agds/screenLoadingType.h
index 1cb1498b6ed..5635a7eeb3a 100644
--- a/engines/agds/screenLoadingType.h
+++ b/engines/agds/screenLoadingType.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 5cd6c5cc24e..81a9e1d2b26 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index ec150d6f384..d502bf12bc6 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/systemVariable.cpp b/engines/agds/systemVariable.cpp
index 6749268bb91..1ac69d74131 100644
--- a/engines/agds/systemVariable.cpp
+++ b/engines/agds/systemVariable.cpp
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/systemVariable.h b/engines/agds/systemVariable.h
index 0dd9590cef5..86305183b36 100644
--- a/engines/agds/systemVariable.h
+++ b/engines/agds/systemVariable.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 063106a6fe9..b343e8c4849 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -1,3 +1,24 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
#include "agds/textLayout.h"
#include "agds/font.h"
#include "agds/agds.h"
diff --git a/engines/agds/textLayout.h b/engines/agds/textLayout.h
index a5ddbcad956..7822fb73a52 100644
--- a/engines/agds/textLayout.h
+++ b/engines/agds/textLayout.h
@@ -4,10 +4,10 @@
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,8 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
Commit: 56d8df154f664ac35fff6d29e89abb56b1dc592c
https://github.com/scummvm/scummvm/commit/56d8df154f664ac35fff6d29e89abb56b1dc592c
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-11-12T15:59:13+01:00
Commit Message:
AGDS: Disable engine by default
Changed paths:
engines/agds/configure.engine
diff --git a/engines/agds/configure.engine b/engines/agds/configure.engine
index f16d163e116..2c2d229bd56 100644
--- a/engines/agds/configure.engine
+++ b/engines/agds/configure.engine
@@ -1,3 +1,3 @@
# This file is included from the main "configure" script
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine agds "AGDS (Black Mirror and others)" yes
+add_engine agds "AGDS (Black Mirror and others)" no
Commit: 7e49e66454d098cee09af429a648b08ceab9c3b7
https://github.com/scummvm/scummvm/commit/7e49e66454d098cee09af429a648b08ceab9c3b7
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-11-12T15:59:13+01:00
Commit Message:
JANITORIAL: Fix code formatting
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/character.cpp
engines/agds/character.h
engines/agds/database.cpp
engines/agds/database.h
engines/agds/dialog.cpp
engines/agds/dialog.h
engines/agds/inventory.cpp
engines/agds/inventory.h
engines/agds/mjpgPlayer.cpp
engines/agds/mouseMap.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/patch.cpp
engines/agds/patch.h
engines/agds/process.h
engines/agds/region.cpp
engines/agds/resourceManager.h
engines/agds/screen.cpp
engines/agds/screen.h
engines/agds/soundManager.h
engines/agds/textLayout.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 0938551e673..940ffb4b902 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -273,7 +273,7 @@ ObjectPtr AGDSEngine::runObject(const Common::String &name, const Common::String
PatchPtr AGDSEngine::getPatch(const Common::String &screenName) const {
auto it = _patches.find(screenName);
- return it != _patches.end()? it->_value: PatchPtr();
+ return it != _patches.end() ? it->_value : PatchPtr();
}
PatchPtr AGDSEngine::createPatch(const Common::String &screenName) {
@@ -285,7 +285,7 @@ PatchPtr AGDSEngine::createPatch(const Common::String &screenName) {
ObjectPatchPtr AGDSEngine::getObjectPatch(const Common::String &objectName) const {
auto it = _objectPatches.find(objectName);
- return it != _objectPatches.end()? it->_value: ObjectPatchPtr();
+ return it != _objectPatches.end() ? it->_value : ObjectPatchPtr();
}
ObjectPatchPtr AGDSEngine::createObjectPatch(const Common::String &objectName) {
@@ -683,7 +683,7 @@ Common::Error AGDSEngine::run() {
AnimationPtr cursor;
- for(auto & object : objects) {
+ for (auto & object : objects) {
cursor = object->getMouseCursor();
if (cursor)
break;
@@ -692,9 +692,9 @@ Common::Error AGDSEngine::run() {
if (cursor)
mouseCursor = cursor;
- for(auto & object : objects) {
+ for (auto &object : objects) {
if (!object->title().empty()) {
- auto & title = object->title();
+ auto &title = object->title();
auto font = getFont(getSystemVariable("objtext_font")->getInteger());
int w = font->getStringWidth(title);
int x = getSystemVariable("objtext_x")->getInteger() - w / 2;
@@ -1090,7 +1090,7 @@ bool AGDSEngine::hasFeature(EngineFeature f) const {
}
}
-void AGDSEngine::loadPatches(Common::SeekableReadStream &file, Database & db) {
+void AGDSEngine::loadPatches(Common::SeekableReadStream &file, Database &db) {
debug("loading patches");
_patches.clear();
_objectPatches.clear();
@@ -1176,7 +1176,7 @@ Common::Error AGDSEngine::loadGameState(int slot) {
Common::ScopedPtr<Common::SeekableReadStream> agds_v(db.getEntry(*saveFile, "__agds_v"));
uint32 n = agds_v->readUint32LE();
debug("reading %u vars...", n);
- while(n--) {
+ while (n--) {
Common::String name = readString(*agds_v);
int value = agds_v->readSint32LE();
debug("setting var %s to %d", name.c_str(), value);
@@ -1187,7 +1187,7 @@ Common::Error AGDSEngine::loadGameState(int slot) {
{
// System vars
Common::ScopedPtr<Common::SeekableReadStream> agds_d(db.getEntry(*saveFile, "__agds_d"));
- for(uint i = 0, n = _systemVarList.size(); i < n; ++i) {
+ for (uint i = 0, n = _systemVarList.size(); i < n; ++i) {
Common::String & name = _systemVarList[i];
_systemVars[name]->read(*agds_d);
}
@@ -1240,7 +1240,7 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
if (!saveFile)
return Common::kWritingFailed;
- while(_currentScreen && _currentScreen->loadingType() == ScreenLoadingType::SaveOrLoad) {
+ while (_currentScreen && _currentScreen->loadingType() == ScreenLoadingType::SaveOrLoad) {
returnToPreviousScreen();
loadNextScreen();
}
@@ -1284,7 +1284,7 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
{
Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
- for(uint i = 0, n = _systemVarList.size(); i < n; ++i) {
+ for (uint i = 0, n = _systemVarList.size(); i < n; ++i) {
Common::String & name = _systemVarList[i];
_systemVars[name]->write(stream);
}
@@ -1296,7 +1296,7 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
auto n = _globals.size();
stream.writeUint32LE(n);
debug("saving %u vars...", n);
- for(auto & global : _globals) {
+ for (auto &global : _globals) {
writeString(stream, global._key);
stream.writeUint32LE(global._value);
}
@@ -1326,13 +1326,13 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
entries["__agds_a"].assign(stream.getData(), stream.getData() + stream.size());
}
- for(auto & objectPatch : _objectPatches) {
+ for (auto &objectPatch : _objectPatches) {
Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
objectPatch._value->save(stream);
entries[objectPatch._key].assign(stream.getData(), stream.getData() + stream.size());
}
- for(auto & patch : _patches) {
+ for (auto &patch : _patches) {
Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
patch._value->save(stream);
entries[patch._key].assign(stream.getData(), stream.getData() + stream.size());
@@ -1348,7 +1348,7 @@ void AGDSEngine::reactivate(const Common::String &name, const Common::String &wh
if (name.empty())
return;
- for(uint i = 0; i < _processes.size(); ++i) {
+ for (uint i = 0; i < _processes.size(); ++i) {
ProcessPtr &process = _processes[i];
if (process && process->getName() == name) {
debug("reactivate %s now: %d, %s", name.c_str(), runNow, where.c_str());
@@ -1360,7 +1360,7 @@ void AGDSEngine::reactivate(const Common::String &name, const Common::String &wh
}
void AGDSEngine::runPendingReactivatedProcesses() {
- while(!_pendingReactivatedProcesses.empty()) {
+ while (!_pendingReactivatedProcesses.empty()) {
ProcessListType processes;
_pendingReactivatedProcesses.swap(processes);
for(auto & process : processes) {
@@ -1370,7 +1370,7 @@ void AGDSEngine::runPendingReactivatedProcesses() {
}
ProcessPtr AGDSEngine::findProcess(const Common::String & name) const {
- for(uint i = 0; i < _processes.size(); ++i) {
+ for (uint i = 0; i < _processes.size(); ++i) {
const ProcessPtr &process = _processes[i];
if (process && !process->finished() && process->getName() == name)
return process;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 652166fdf18..7e856fa9599 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -121,17 +121,17 @@ public:
bool canLoadGameStateCurrently(Common::U32String *msg) override { return true; }
bool canSaveGameStateCurrently(Common::U32String *msg) override { return false; }
- ObjectPtr loadObject(const Common::String & name, const Common::String & prototype = Common::String(), bool allowInitialise = true);
- ObjectPtr runObject(const Common::String & name, const Common::String &prototype = Common::String(), bool allowInitialise = true);
+ ObjectPtr loadObject(const Common::String &name, const Common::String &prototype = Common::String(), bool allowInitialise = true);
+ ObjectPtr runObject(const Common::String &name, const Common::String &prototype = Common::String(), bool allowInitialise = true);
void runObject(const ObjectPtr &object);
void runProcess(const ObjectPtr &object, uint ip = 0);
- ProcessPtr findProcess(const Common::String & name) const;
+ ProcessPtr findProcess(const Common::String &name) const;
void reactivate(const Common::String &name, const Common::String &where, bool runNow = false);
bool hasActiveProcesses(const Common::String &name) const;
void runPendingReactivatedProcesses();
void resetCurrentScreen();
- void loadScreen(const Common::String & name, ScreenLoadingType type, bool savePatch = true);
+ void loadScreen(const Common::String &name, ScreenLoadingType type, bool savePatch = true);
void loadNextScreen();
void saveScreenPatch();
@@ -139,47 +139,47 @@ public:
Common::String loadText(const Common::String &name);
int appendToSharedStorage(const Common::String &value);
- const Common::String & getSharedStorage(int id) const;
+ const Common::String &getSharedStorage(int id) const;
bool active() const { return !_mjpgPlayer; }
void playFilm(Process &process, const Common::String &video, const Common::String &audio, const Common::String &subtitles);
void skipFilm();
- ResourceManager & resourceManager() {
+ ResourceManager &resourceManager() {
return _resourceManager;
}
- SoundManager & soundManager() {
+ SoundManager &soundManager() {
return _soundManager;
}
- Inventory & inventory() {
+ Inventory &inventory() {
return _inventory;
}
- Dialog & dialog() {
+ Dialog &dialog() {
return _dialog;
}
- const ProcessListType & processes() const {
+ const ProcessListType &processes() const {
return _processes;
}
- TextLayout & textLayout() {
+ TextLayout &textLayout() {
return _textLayout;
}
- Screen * getCurrentScreen() {
+ Screen *getCurrentScreen() {
return _currentScreen.get();
}
- Console * getConsole();
+ Console *getConsole();
- Common::String & getCurrentScreenName() {
+ Common::String &getCurrentScreenName() {
return _currentScreenName;
}
ObjectPtr getCurrentScreenObject(const Common::String &name);
- const Graphics::PixelFormat & pixelFormat() const {
+ const Graphics::PixelFormat &pixelFormat() const {
return _pixelFormat;
}
@@ -199,12 +199,12 @@ public:
AnimationPtr findAnimationByPhaseVar(const Common::String &phaseVar);
void loadCharacter(const Common::String &id, const Common::String &name, const Common::String &object);
Character * getCharacter(const Common::String &name) {
- return _currentCharacterName == name? _currentCharacter.get(): nullptr;
+ return _currentCharacterName == name ? _currentCharacter.get() : nullptr;
}
- Character * currentCharacter() const {
+ Character *currentCharacter() const {
return _currentCharacter.get();
}
- Character * jokes() const {
+ Character *jokes() const {
return _jokes.get();
}
@@ -254,10 +254,10 @@ public:
return _mouse;
}
- void currentInventoryObject(const ObjectPtr & object);
+ void currentInventoryObject(const ObjectPtr &object);
void resetCurrentInventoryObject();
ObjectPtr popCurrentInventoryObject();
- const ObjectPtr & currentInventoryObject() const {
+ const ObjectPtr ¤tInventoryObject() const {
return _currentInventoryObject;
}
@@ -282,7 +282,7 @@ public:
private:
void stopAmbientSound();
- void loadPatches(Common::SeekableReadStream &file, Database & db);
+ void loadPatches(Common::SeekableReadStream &file, Database &db);
using PictureCacheType = Common::HashMap<int, Common::ScopedPtr<Graphics::ManagedSurface>>;
using PictureCacheLookup = Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
@@ -294,7 +294,7 @@ private:
using ObjectPatchesType = Common::HashMap<Common::String, ObjectPatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
using PatchDatabase = Common::HashMap<Common::String, Common::Array<uint8>>;
- const ADGameDescription * _gameDescription;
+ const ADGameDescription *_gameDescription;
ResourceManager _resourceManager;
SoundManager _soundManager;
Database _data;
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index a4608118eaa..bc11a71bc24 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -202,8 +202,7 @@ bool Animation::tick() {
return true;
}
- if (!eov)
- {
+ if (!eov) {
decodeNextFrame();
onScreen(true);
}
@@ -282,7 +281,7 @@ void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst, Graphics
}
uint Animation::width() const {
- return _flic ? _flic->getWidth() * _scale: 0;
+ return _flic ? _flic->getWidth() * _scale : 0;
}
uint Animation::height() const {
return _flic ? _flic->getHeight() * _scale: 0;
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index c9dd2ede417..c30c0986641 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -40,7 +40,7 @@ class Animation {
using FlicPtr = Common::ScopedPtr<Video::FlicDecoder>;
using ManagedSurfacePtr = Common::ScopedPtr<Graphics::ManagedSurface>;
- AGDSEngine * _engine;
+ AGDSEngine *_engine;
Common::String _name;
FlicPtr _flic;
ManagedSurfacePtr _frame;
@@ -79,7 +79,7 @@ public:
return _phase >= _frames;
}
- const Common::Point & position() const {
+ const Common::Point &position() const {
return _position;
}
@@ -87,19 +87,19 @@ public:
_position = position;
}
- const Common::String & phaseVar() const {
+ const Common::String &phaseVar() const {
return _phaseVar;
}
- void phaseVar(const Common::String & phaseVar) {
+ void phaseVar(const Common::String &phaseVar) {
_phaseVar = phaseVar;
}
- const Common::String & process() const {
+ const Common::String &process() const {
return _process;
}
- void process(const Common::String & process) {
+ void process(const Common::String &process) {
_process = process;
}
@@ -170,7 +170,7 @@ public:
void onScreen(bool onScreen);
bool load(Common::SeekableReadStream *stream, const Common::String &fname);
- void paint(Graphics::Surface & backbuffer, Common::Point dst, Graphics::ManagedSurface *mask = nullptr, int maskAlpha = 0) const;
+ void paint(Graphics::Surface &backbuffer, Common::Point dst, Graphics::ManagedSurface *mask = nullptr, int maskAlpha = 0) const;
uint width() const;
uint height() const;
uint visibleHeight() const {
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index d4a25ec6a53..6665e4822dc 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -118,7 +118,7 @@ void Character::visible(bool visible) {
_visible = visible;
}
-void Character::loadState(Common::ReadStream& stream) {
+void Character::loadState(Common::ReadStream &stream) {
int x = stream.readUint16LE();
int y = stream.readUint16LE();
int dir = stream.readSint16LE();
@@ -129,7 +129,7 @@ void Character::loadState(Common::ReadStream& stream) {
_enabled = stream.readUint16LE();
}
-void Character::saveState(Common::WriteStream& stream) const {
+void Character::saveState(Common::WriteStream &stream) const {
stream.writeUint16LE(_pos.x);
stream.writeUint16LE(_pos.y);
stream.writeUint16LE(_direction);
@@ -149,7 +149,7 @@ bool Character::direction(int dir) {
return animate(dir, 100, false);
}
-void Character::notifyProcess(const Common::String & name) {
+void Character::notifyProcess(const Common::String &name) {
debug("%s:notifyProcess %s", _name.c_str(), name.c_str());
if (!_processName.empty())
_engine->reactivate(name, "Character::notifyProcess", false);
@@ -157,7 +157,7 @@ void Character::notifyProcess(const Common::String & name) {
_processName = name;
}
-bool Character::moveTo(const Common::String & processName, Common::Point dst, int dir) {
+bool Character::moveTo(const Common::String &processName, Common::Point dst, int dir) {
if (!_visible)
return false;
@@ -170,7 +170,7 @@ bool Character::moveTo(const Common::String & processName, Common::Point dst, in
auto *screen = _engine->getCurrentScreen();
if (screen) {
auto objects = screen->find(dst);
- for(auto & object: objects) {
+ for (auto &object : objects) {
auto region = object->getTrapRegion();
if (region && region->pointIn(dst)) {
debug("starting trap process");
@@ -181,7 +181,7 @@ bool Character::moveTo(const Common::String & processName, Common::Point dst, in
return r;
}
-void Character::pointTo(const Common::String & processName, Common::Point dst) {
+void Character::pointTo(const Common::String &processName, Common::Point dst) {
debug("character point to stub %d,%d, process: %s", dst.x, dst.y, processName.c_str());
notifyProcess(processName);
if (!_processName.empty() && !_engine->activeCurtain()) {
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 8ad59046e31..bbdc13d090f 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -40,7 +40,7 @@ using AnimationPtr = Common::SharedPtr<Animation>;
class Character {
using FogPtr = Common::ScopedPtr<Graphics::ManagedSurface>;
- AGDSEngine * _engine;
+ AGDSEngine *_engine;
ObjectPtr _object;
AnimationPtr _animation;
FogPtr _fog;
@@ -70,27 +70,27 @@ class Character {
Common::Array<Frame> frames;
};
Common::HashMap<uint, AnimationDescription> _animations;
- const AnimationDescription * _description;
+ const AnimationDescription *_description;
bool animate(int direction, int speed, bool jokes);
Common::Point animationPosition() const;
public:
- Character(AGDSEngine * engine, const Common::String & name);
+ Character(AGDSEngine *engine, const Common::String &name);
~Character();
void associate(const Common::String &name);
- const AnimationDescription * animationDescription(uint index) const {
+ const AnimationDescription *animationDescription(uint index) const {
auto it = _animations.find(index);
- return it != _animations.end()? &it->_value: nullptr;
+ return it != _animations.end() ? &it->_value : nullptr;
}
- const Common::String & name() const {
+ const Common::String &name() const {
return _name;
}
- const ObjectPtr & object() const {
+ const ObjectPtr &object() const {
return _object;
}
@@ -117,7 +117,7 @@ public:
void leave(const Common::String &processName);
int phase() const {
- return _jokes? _phase: -1;
+ return _jokes ? _phase : -1;
}
void phase(int phase) {
_phase = phase;
@@ -139,18 +139,18 @@ public:
bool direction(int dir);
int direction() const {
- return _jokes? _jokesDirection: _direction;
+ return _jokes ? _jokesDirection : _direction;
}
void tick(bool reactivate);
- void paint(Graphics::Surface & backbuffer, Common::Point pos) const;
+ void paint(Graphics::Surface &backbuffer, Common::Point pos) const;
int getDirectionForMovement(Common::Point delta);
int z() const;
void reset();
- void setFog(Graphics::ManagedSurface * surface, int minZ, int maxZ);
+ void setFog(Graphics::ManagedSurface *surface, int minZ, int maxZ);
};
diff --git a/engines/agds/database.cpp b/engines/agds/database.cpp
index 93f0f8448ba..a85133a4908 100644
--- a/engines/agds/database.cpp
+++ b/engines/agds/database.cpp
@@ -87,7 +87,7 @@ void Database::write(Common::WriteStream &stream, const Common::HashMap<Common::
debug("database data offset: 0x%06x", dataOffset);
uint offset = 0;
- for(auto &entry: entries) {
+ for (auto &entry : entries) {
auto &key = entry._key;
auto &value = entry._value;
@@ -100,7 +100,7 @@ void Database::write(Common::WriteStream &stream, const Common::HashMap<Common::
stream.writeUint32LE(value.size());
}
- for(auto entry: entries) {
+ for (auto &entry : entries) {
auto & value = entry._value;
stream.write(value.data(), value.size());
}
@@ -108,7 +108,7 @@ void Database::write(Common::WriteStream &stream, const Common::HashMap<Common::
Common::Array<Common::String> Database::getEntries() const {
Common::Array<Common::String> names;
- for(EntriesType::const_iterator i = _entries.begin(); i != _entries.end(); ++i) {
+ for (EntriesType::const_iterator i = _entries.begin(); i != _entries.end(); ++i) {
names.push_back(i->_key);
}
return names;
@@ -133,4 +133,5 @@ Common::SeekableReadStream *Database::getEntry(Common::SeekableReadStream &paren
parent.seek(entry.offset);
return parent.readStream(entry.size);
}
+
} // namespace AGDS
diff --git a/engines/agds/database.h b/engines/agds/database.h
index 6636dff2e7f..c7ee7b6caff 100644
--- a/engines/agds/database.h
+++ b/engines/agds/database.h
@@ -59,7 +59,7 @@ public:
bool open(const Common::String &filename, Common::SeekableReadStream &stream);
Common::Array<Common::String> getEntries() const;
- Common::SeekableReadStream * getEntry(const Common::String &name) const;
+ Common::SeekableReadStream *getEntry(const Common::String &name) const;
Common::SeekableReadStream *getEntry(Common::SeekableReadStream &parent, const Common::String &name) const;
static void write(Common::WriteStream &stream, const Common::HashMap<Common::String, Common::Array<uint8>> & entries);
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index c533972c20e..553986bab31 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -121,7 +121,7 @@ bool Dialog::tick() {
line.clear();
bool command = _dialogScript[_dialogScriptPos] == '@';
- while(_dialogScriptPos < n) {
+ while (_dialogScriptPos < n) {
if (!command && _dialogScript[_dialogScriptPos] == '@')
break;
@@ -131,7 +131,7 @@ bool Dialog::tick() {
if (!command)
line += '\n';
- while(_dialogScriptPos < n && (_dialogScript[_dialogScriptPos] == '\n' || _dialogScript[_dialogScriptPos] == '\r'))
+ while (_dialogScriptPos < n && (_dialogScript[_dialogScriptPos] == '\n' || _dialogScript[_dialogScriptPos] == '\r'))
++_dialogScriptPos;
if (command)
@@ -179,7 +179,7 @@ void Dialog::processSoundDirective(const Common::String &line) {
}
--end;
Common::String name = line.substr(arg1, comma1 - arg1 - 1);
- while(line[comma1] == ' ')
+ while (line[comma1] == ' ')
++comma1;
Common::String sample = line.substr(comma1, comma2 - comma1);
while(line[comma2] == ' ')
@@ -207,8 +207,8 @@ void Dialog::processDirective(Common::String line) {
if (!_currentDef.hasPrefix("vybervarianty") && !_currentDef.hasPrefix("varianta")) {
_currentSoundIndex = -1;
- for(uint s = 0; s < _sounds.size(); ++s) {
- auto & sound = _sounds[s];
+ for (uint s = 0; s < _sounds.size(); ++s) {
+ auto &sound = _sounds[s];
if (_currentDef.hasPrefixIgnoreCase(sound.Name)) {
_currentSoundIndex = s;
break;
@@ -235,7 +235,7 @@ Common::String Dialog::getNextDialogSound() {
auto currentSample = sample;
int carry = sound.Step;
- for(auto pos = sample.size() - 1; pos > 0 && sample[pos] >= '0' && sample[pos] <= '9'; --pos) {
+ for (auto pos = sample.size() - 1; pos > 0 && sample[pos] >= '0' && sample[pos] <= '9'; --pos) {
int d = sample[pos] - '0';
d += carry;
carry = d / 10;
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
index 074705a69aa..2a67a703e64 100644
--- a/engines/agds/dialog.h
+++ b/engines/agds/dialog.h
@@ -47,7 +47,7 @@ private:
};
using SoundsType = Common::Array<Sound>;
- AGDSEngine * _engine;
+ AGDSEngine *_engine;
DialogDefsType _dialogDefs;
Common::String _dialogScript;
uint32 _dialogScriptPos;
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index b6cd1f83e60..5c9106ff623 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -30,7 +30,7 @@
namespace AGDS {
-Inventory::Inventory(AGDSEngine* engine): _engine(engine), _entries(kMaxSize), _enabled(false), _visible(false) {}
+Inventory::Inventory(AGDSEngine *engine): _engine(engine), _entries(kMaxSize), _enabled(false), _visible(false) {}
Inventory::~Inventory() {}
void Inventory::visible(bool visible) {
@@ -64,7 +64,7 @@ int Inventory::free() const {
bool Inventory::has(int index) const {
if (index >= 0 && index < kMaxSize) {
- auto & entry = _entries[index];
+ auto &entry = _entries[index];
return entry.hasObject;
}
return {};
@@ -72,7 +72,7 @@ bool Inventory::has(int index) const {
ObjectPtr Inventory::get(int index) {
if (index >= 0 && index < kMaxSize) {
- auto & entry = _entries[index];
+ auto &entry = _entries[index];
if (entry.hasObject && !entry.object) {
entry.object = _engine->runObject(entry.name);
entry.object->persistent(false);
@@ -82,14 +82,14 @@ ObjectPtr Inventory::get(int index) {
return {};
}
-int Inventory::add(const Common::String & name) {
+int Inventory::add(const Common::String &name) {
int idx = find(name);
if (idx >= 0) {
warning("Double adding object %s, skipping...", name.c_str());
return idx;
}
for (uint i = 0; i < _entries.size(); ++i) {
- auto & entry = _entries[i];
+ auto &entry = _entries[i];
if (!entry.hasObject) {
entry.name = name;
entry.object.reset();
@@ -100,9 +100,9 @@ int Inventory::add(const Common::String & name) {
return idx;
}
-int Inventory::add(const ObjectPtr & object) {
+int Inventory::add(const ObjectPtr &object) {
for (uint i = 0; i < _entries.size(); ++i) {
- auto & entry = _entries[i];
+ auto &entry = _entries[i];
if (entry.hasObject && entry.name == object->getName()) {
warning("Double adding object [pointer] %s, skipping...", object->getName().c_str());
return i;
@@ -110,7 +110,7 @@ int Inventory::add(const ObjectPtr & object) {
}
object->persistent(false);
for (uint i = 0; i < _entries.size(); ++i) {
- auto & entry = _entries[i];
+ auto &entry = _entries[i];
if (!entry.hasObject) {
entry.name = object->getName();
entry.object = object;
@@ -124,7 +124,7 @@ int Inventory::add(const ObjectPtr & object) {
bool Inventory::remove(const Common::String &name) {
bool removed = false;
for (uint i = 0; i < _entries.size(); ++i) {
- auto & entry = _entries[i];
+ auto &entry = _entries[i];
if (entry.hasObject && entry.name == name) {
entry.reset();
removed = true;
@@ -136,16 +136,13 @@ bool Inventory::remove(const Common::String &name) {
void Inventory::removeGaps() {
auto n = _entries.size();
for (uint src = 0, dst = 0; src < n; ++src) {
- auto & entry = _entries[src];
- if (entry.hasObject)
- {
- if (dst != src)
- {
+ auto &entry = _entries[src];
+ if (entry.hasObject) {
+ if (dst != src) {
debug("moving inventory object %u -> %u", src, dst);
_entries[dst++] = _entries[src];
_entries[src].reset();
- }
- else
+ } else
++dst;
}
}
@@ -153,7 +150,7 @@ void Inventory::removeGaps() {
int Inventory::find(const Common::String &name) const {
for (uint i = 0; i < _entries.size(); ++i) {
- auto & entry = _entries[i];
+ auto &entry = _entries[i];
if (entry.hasObject && entry.name == name)
return i;
}
@@ -165,11 +162,11 @@ ObjectPtr Inventory::find(const Common::Point pos) const {
return {};
for (uint i = 0; i < _entries.size(); ++i) {
- auto & entry = _entries[i];
+ auto &entry = _entries[i];
if (!entry.object)
continue;
- auto & object = entry.object;
+ auto &object = entry.object;
auto picture = object->getPicture();
if (picture) {
auto rect = picture->getBounds();
@@ -189,7 +186,7 @@ void Inventory::clear() {
void Inventory::load(Common::ReadStream& stream) {
clear();
- for(int i = 0; i < kMaxSize; ++i) {
+ for (int i = 0; i < kMaxSize; ++i) {
Common::String name = readString(stream);
int refcount = stream.readUint32LE();
int objectPtr = stream.readUint32LE();
@@ -203,10 +200,10 @@ void Inventory::load(Common::ReadStream& stream) {
}
void Inventory::save(Common::WriteStream& stream) const {
- for(auto & entry : _entries) {
+ for (const auto &entry : _entries) {
writeString(stream, entry.name);
- stream.writeUint32LE(entry.hasObject? 1: 0);
- stream.writeSint32LE(entry.hasObject? -1: 0);
+ stream.writeUint32LE(entry.hasObject ? 1 : 0);
+ stream.writeSint32LE(entry.hasObject ? -1 : 0);
}
}
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index 0fa29b8b9e7..d893723b6f3 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -36,7 +36,7 @@ using ObjectPtr = Common::SharedPtr<Object>;
class AGDSEngine;
class Inventory {
- class AGDSEngine* _engine;
+ class AGDSEngine *_engine;
struct Entry {
Common::String name;
bool hasObject;
@@ -56,11 +56,11 @@ class Inventory {
public:
static const int kMaxSize = 35;
- Inventory(AGDSEngine* engine);
+ Inventory(AGDSEngine *engine);
~Inventory();
- void load(Common::ReadStream& stream);
- void save(Common::WriteStream& stream) const;
+ void load(Common::ReadStream &stream);
+ void save(Common::WriteStream &stream) const;
bool enabled() const {
return _enabled;
@@ -76,7 +76,7 @@ public:
void visible(bool visible);
int add(const Common::String &name);
- int add(const ObjectPtr & object);
+ int add(const ObjectPtr &object);
bool remove(const Common::String &name);
void removeGaps();
@@ -88,7 +88,7 @@ public:
int free() const;
void clear();
- const EntriesType & entries() const {
+ const EntriesType &entries() const {
return _entries;
}
diff --git a/engines/agds/mjpgPlayer.cpp b/engines/agds/mjpgPlayer.cpp
index bfaa060eb7c..0beef802ee9 100644
--- a/engines/agds/mjpgPlayer.cpp
+++ b/engines/agds/mjpgPlayer.cpp
@@ -31,7 +31,7 @@ namespace AGDS {
MJPGPlayer::MJPGPlayer(Common::SeekableReadStream *stream, const Common::String &subtitles) :
_stream(stream), _firstFramePos(_stream->pos()), _framesPlayed(0), _nextSubtitleIndex(0) {
uint pos = 0;
- while(pos < subtitles.size()) {
+ while (pos < subtitles.size()) {
auto next = subtitles.find('\n', pos);
if (next == subtitles.npos)
next = subtitles.size();
@@ -44,7 +44,7 @@ MJPGPlayer::MJPGPlayer(Common::SeekableReadStream *stream, const Common::String
pos = next + 1;
continue;
}
- while(offset < static_cast<int>(line.size()) && line[offset] == ' ')
+ while (offset < static_cast<int>(line.size()) && line[offset] == ' ')
++offset;
line = line.substr(offset);
@@ -52,7 +52,7 @@ MJPGPlayer::MJPGPlayer(Common::SeekableReadStream *stream, const Common::String
Text::Lines lines;
{
uint lineBegin = 0;
- while(lineBegin < line.size()) {
+ while (lineBegin < line.size()) {
uint lineEnd = line.find('|', lineBegin);
if (lineEnd == line.npos)
lineEnd = line.size();
@@ -114,7 +114,7 @@ void MJPGPlayer::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
if (_subtitles.empty())
return;
- while(_nextSubtitleIndex < _subtitles.size() && _framesPlayed > _subtitles[_nextSubtitleIndex].end)
+ while (_nextSubtitleIndex < _subtitles.size() && _framesPlayed > _subtitles[_nextSubtitleIndex].end)
++_nextSubtitleIndex;
if (_nextSubtitleIndex >= _subtitles.size() || _framesPlayed < _subtitles[_nextSubtitleIndex].begin)
@@ -125,11 +125,11 @@ void MJPGPlayer::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
int baseY = engine.getSystemVariable("subtitle_y")->getInteger();
int maxWidth = engine.getSystemVariable("subtitle_width")->getInteger();
- auto & lines = _subtitles[_nextSubtitleIndex].lines;
- for(auto & line : lines) {
+ auto &lines = _subtitles[_nextSubtitleIndex].lines;
+ for (auto &line : lines) {
Text::Lines sublines;
font->wordWrapText(line, maxWidth, sublines);
- for(auto & subline : sublines) {
+ for (auto &subline : sublines) {
int w = font->getStringWidth(subline);
int x = baseX - w / 2;
font->drawString(&backbuffer, subline, x, baseY, backbuffer.w - x, 0);
diff --git a/engines/agds/mouseMap.h b/engines/agds/mouseMap.h
index 89f43b74105..f5b775c6445 100644
--- a/engines/agds/mouseMap.h
+++ b/engines/agds/mouseMap.h
@@ -84,7 +84,7 @@ public:
void hideAll(AGDSEngine *engine);
void hideInactive(AGDSEngine *engine, Common::Point pos);
- MouseRegion * find(int id);
+ MouseRegion *find(int id);
};
} // End of namespace AGDS
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 2d091b7a1b4..7aac70cd44c 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -189,8 +189,7 @@ void Object::createRotated() {
_rotatedPicture.reset(getPicture()->rotoscale(transform));
}
-void Object::alive(bool value)
-{
+void Object::alive(bool value) {
_alive = value;
if (!_alive)
_region.reset();
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 8e57c327083..3c7cda5eab6 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -44,8 +44,7 @@ class Object {
public:
using CodeType = Common::Array<uint8>;
- struct StringEntry
- {
+ struct StringEntry {
Common::String string;
uint16 flags;
@@ -125,18 +124,18 @@ public:
}
void readStringTable(unsigned resOffset, uint16 resCount);
- const StringEntry & getString(uint16 index) const;
+ const StringEntry &getString(uint16 index) const;
uint getStringTableSize() const
{ return _stringTable.size(); }
- const Common::String & getName() const
+ const Common::String &getName() const
{ return _name; }
const CodeType & getCode() const {
return _code;
}
- void setAnimation(const AnimationPtr & animation) {
+ void setAnimation(const AnimationPtr &animation) {
_animation = animation;
}
@@ -148,19 +147,19 @@ public:
_animationPos = animationPos;
}
- void setMouseCursor(const AnimationPtr & mouseCursor) {
+ void setMouseCursor(const AnimationPtr &mouseCursor) {
_mouseCursor = mouseCursor;
freeRotated();
}
- const AnimationPtr & getMouseCursor() const {
+ const AnimationPtr &getMouseCursor() const {
return _mouseCursor;
}
void setPicture(Graphics::ManagedSurface *);
Graphics::ManagedSurface *getPicture() const {
- return _rotatedPicture? _rotatedPicture.get(): _picture.get();
+ return _rotatedPicture ? _rotatedPicture.get() : _picture.get();
}
void rotate(int rot);
@@ -197,7 +196,7 @@ public:
void region(RegionPtr region);
- const RegionPtr& region() const {
+ const RegionPtr ®ion() const {
return _region;
}
@@ -262,11 +261,9 @@ public:
_trapRegion = region;
}
- RegionPtr getTrapRegion() const
- { return _trapRegion; }
+ RegionPtr getTrapRegion() const { return _trapRegion; }
- uint getTrapHandler() const
- { return _trapHandler; }
+ uint getTrapHandler() const { return _trapHandler; }
void paint(AGDSEngine &engine, Graphics::Surface &backbuffer, Common::Point pos) const;
@@ -280,7 +277,7 @@ public:
return _z;
}
- const Common::String & getText() const {
+ const Common::String &getText() const {
return _text;
}
@@ -292,7 +289,7 @@ public:
_title = title;
}
- const Common::String& title() const {
+ const Common::String &title() const {
return _title;
}
@@ -329,8 +326,7 @@ public:
void lock();
void unlock();
- bool alive() const
- { return _alive; }
+ bool alive() const { return _alive; }
void alive(bool value);
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index 2cc42572a0d..e943847eeeb 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -60,7 +60,7 @@ void Patch::load(Common::ReadStream &stream) {
defaultMouseCursor = readString(stream);
debug("default pointer name: %s", defaultMouseCursor.c_str());
objects.clear();
- for(uint i = 0; i < object_count; ++i) {
+ for (uint i = 0; i < object_count; ++i) {
int flag = stream.readSint16LE();
Common::String name = readString(stream);
debug("patch object %s %d", name.c_str(), flag);
@@ -91,8 +91,8 @@ void Patch::save(Common::WriteStream &stream) {
}
}
-void Patch::setFlag(const Common::String & name, int flag) {
- for(auto & object : objects) {
+void Patch::setFlag(const Common::String &name, int flag) {
+ for (auto &object : objects) {
if (object.name == name) {
object.flag = flag;
return;
@@ -101,16 +101,16 @@ void Patch::setFlag(const Common::String & name, int flag) {
objects.push_back({name, flag});
}
-int Patch::getFlag(const Common::String & name) const {
- for(auto & object : objects) {
+int Patch::getFlag(const Common::String &name) const {
+ for (auto &object : objects) {
if (object.name == name)
return object.flag;
}
return 0;
}
-int Patch::incRef(const Common::String & name) {
- for(auto & object : objects) {
+int Patch::incRef(const Common::String &name) {
+ for (auto &object : objects) {
if (object.name == name) {
return ++object.flag;
}
@@ -119,8 +119,8 @@ int Patch::incRef(const Common::String & name) {
return 1;
}
-int Patch::decRef(const Common::String & name) {
- for(auto & object : objects) {
+int Patch::decRef(const Common::String &name) {
+ for (auto &object : objects) {
if (object.name == name) {
//this is original code lol
object.flag = 0;
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index cd63c68fed5..3f8cdb9e52c 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -68,10 +68,10 @@ struct Patch {
void load(Common::ReadStream &stream);
void save(Common::WriteStream &stream);
- void setFlag(const Common::String & name, int flag);
- int getFlag(const Common::String & name) const;
- int incRef(const Common::String & name);
- int decRef(const Common::String & name);
+ void setFlag(const Common::String &name, int flag);
+ int getFlag(const Common::String &name) const;
+ int incRef(const Common::String &name);
+ int decRef(const Common::String &name);
};
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 2ae1593c1f0..47cabcfbb52 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -43,7 +43,7 @@ public:
private:
using StackType = Common::Stack<int32>;
- AGDSEngine * _engine;
+ AGDSEngine *_engine;
Common::String _parentScreen;
ObjectPtr _object;
StackType _stack;
@@ -119,7 +119,7 @@ private:
void tell(bool npc, const Common::String &sound);
void tell(bool npc) { tell(npc, Common::String()); }
- Common::String getCloneVarName(const Common::String & arg1, const Common::String & arg2);
+ Common::String getCloneVarName(const Common::String &arg1, const Common::String &arg2);
void suspend(ProcessExitCode exitCode, const Common::String &arg1, const Common::String &arg2 = Common::String());
void suspend(ProcessExitCode exitCode, int arg1 = 0, int arg2 = 0);
@@ -127,7 +127,7 @@ private:
ProcessExitCode resume();
void suspendIfPassive();
- void setupAnimation(const AnimationPtr & animation);
+ void setupAnimation(const AnimationPtr &animation);
void attachInventoryObjectToMouse(bool flag);
void leaveCharacter(const Common::String &name, const Common::String ®ionName, int dir);
void removeScreenObject(const Common::String &name);
@@ -144,11 +144,11 @@ public:
return _object;
}
- const Common::String & getName() const {
+ const Common::String &getName() const {
return _object->getName();
}
- const Common::String & parentScreenName() const {
+ const Common::String &parentScreenName() const {
return _parentScreen;
}
@@ -177,7 +177,7 @@ public:
return _exitCode;
}
- const Common::String & getExitArg1() const {
+ const Common::String &getExitArg1() const {
return _exitArg1;
}
@@ -185,7 +185,7 @@ public:
return _exitIntArg1;
}
- const Common::String & getExitArg2() const {
+ const Common::String &getExitArg2() const {
return _exitArg2;
}
@@ -198,7 +198,7 @@ public:
}
void updateWithCurrentMousePosition();
- const Common::String & phaseVar() const {
+ const Common::String &phaseVar() const {
return _phaseVar;
}
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index 9a27b7b4624..55054085a16 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -102,7 +102,7 @@ Common::Point Region::topLeft() const {
return Common::Point();
Common::Point p = regions[0][0];
- for(uint i = 0; i < regions.size(); ++i) {
+ for (uint i = 0; i < regions.size(); ++i) {
const PointsType &points = regions[i];
for(uint j = 0; j < points.size(); ++j) {
@@ -123,7 +123,7 @@ struct dPoint {
} ;
bool Region::pointIn(Common::Point point) const {
- for(uint r = 0; r < regions.size(); ++r) {
+ for (uint r = 0; r < regions.size(); ++r) {
const PointsType &points = regions[r];
uint32 size = points.size();
if (size < 3) {
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index ac8e91c1c08..635e99a4734 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -38,9 +38,8 @@ class ResourceManager {
private:
class GrpFile;
- class ArchiveMember : public Common::ArchiveMember
- {
- GrpFile * _parent;
+ class ArchiveMember : public Common::ArchiveMember {
+ GrpFile *_parent;
Common::String _name;
uint32 _offset;
uint32 _size;
@@ -65,8 +64,7 @@ private:
};
using ArchiveMemberPtr = Common::SharedPtr<ArchiveMember>;
- class GrpFile : public Common::Archive
- {
+ class GrpFile : public Common::Archive {
Common::File _file;
using MembersType = Common::HashMap<Common::String, ArchiveMemberPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
@@ -93,11 +91,11 @@ public:
bool addPath(const Common::Path &grpFilename);
- Common::SeekableReadStream * getResource(const Common::String &name) const;
- Graphics::Surface * loadPicture(const Common::String & name, const Graphics::PixelFormat &format);
+ Common::SeekableReadStream *getResource(const Common::String &name) const;
+ Graphics::Surface *loadPicture(const Common::String &name, const Graphics::PixelFormat &format);
static Common::String loadText(Common::SeekableReadStream &stream);
- Common::String loadText(const Common::String & name) const;
+ Common::String loadText(const Common::String &name) const;
};
Common::String readString(Common::ReadStream &stream, uint size = 32);
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index fa1eeb90166..9ed3d976188 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -77,8 +77,7 @@ void Screen::scrollTo(Common::Point scroll) {
}
-float Screen::getZScale(int y) const
-{
+float Screen::getZScale(int y) const {
int h = g_system->getHeight();
int dy = h - y;
if (dy > _characterNear) {
@@ -184,7 +183,7 @@ AnimationPtr Screen::findAnimationByPhaseVar(const Common::String &phaseVar) {
}
void Screen::tick() {
- for(uint i = 0; i < _animations.size(); ) {
+ for (uint i = 0; i < _animations.size(); ) {
const auto & desc = _animations.data()[i];
const auto & animation = desc.animation;
if (!desc.removed && animation->tick())
@@ -202,7 +201,7 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
auto child = _children.begin();
auto desc = _animations.begin();
- while(child != _children.end() || desc != _animations.end() || character) {
+ while (child != _children.end() || desc != _animations.end() || character) {
bool child_valid = child != _children.end();
bool animation_valid = desc != _animations.end();
if (animation_valid && desc->removed) {
@@ -238,38 +237,38 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
auto basePos = Common::Point() - _scroll;
switch (render_type) {
- case 0:
- //debug("object z: %d", (*child)->z());
- if ((*child) != currentInventoryObject && (*child)->alive()) {
- if ((*child)->scale() < 0)
- basePos = Common::Point();
- (*child)->paint(*_engine, backbuffer, basePos);
- }
- ++child;
- break;
- case 1:
- //debug("animation z: %d", (*animation)->z());
- if ((*desc).animation->scale() < 0)
+ case 0:
+ //debug("object z: %d", (*child)->z());
+ if ((*child) != currentInventoryObject && (*child)->alive()) {
+ if ((*child)->scale() < 0)
basePos = Common::Point();
- (*desc).animation->paint(backbuffer, basePos);
- ++desc;
- break;
- case 2:
- //debug("character z: %d", character->z());
- character->paint(backbuffer, basePos);
- character = nullptr;
- break;
- default:
- error("invalid logic in z-sort");
+ (*child)->paint(*_engine, backbuffer, basePos);
+ }
+ ++child;
+ break;
+ case 1:
+ //debug("animation z: %d", (*animation)->z());
+ if ((*desc).animation->scale() < 0)
+ basePos = Common::Point();
+ (*desc).animation->paint(backbuffer, basePos);
+ ++desc;
+ break;
+ case 2:
+ //debug("character z: %d", character->z());
+ character->paint(backbuffer, basePos);
+ character = nullptr;
+ break;
+ default:
+ error("invalid logic in z-sort");
}
}
if (_fade != 0) {
auto alpha = (100 - _fade) * 256 / 100;
auto & format = backbuffer.format;
- for(int y = 0; y < backbuffer.h; ++y) {
+ for (int y = 0; y < backbuffer.h; ++y) {
uint32 * line = (uint32 *)backbuffer.getBasePtr(0, y);
int w = backbuffer.w;
- while(w--) {
+ while (w--) {
uint8 r, g, b;
format.colorToRGB(*line, r, g, b);
r = (r * alpha) >> 8;
@@ -286,7 +285,7 @@ Common::Array<ObjectPtr> Screen::find(Common::Point pos) const {
objects.reserve(_children.size());
for (auto i = _children.begin(); i != _children.end(); ++i) {
const auto & object = *i;
- auto visiblePos = (object->scale() >= 0)? pos + _scroll: pos;
+ auto visiblePos = (object->scale() >= 0) ? pos + _scroll : pos;
if (object->pointIn(visiblePos) && object->alive()) {
objects.insert_at(0, object);
}
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 28b7495743a..0dc8900e301 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -59,9 +59,9 @@ class Screen {
using Animations = Common::SortedArray<ScreenAnimationDesc, const ScreenAnimationDesc &>;
using Children = Common::SortedArray<ObjectPtr, const ObjectPtr &>;
- AGDSEngine * _engine;
+ AGDSEngine *_engine;
ObjectPtr _object;
- Object * _background;
+ Object *_background;
Common::Point _scroll;
Common::String _name;
ScreenLoadingType _loadingType;
@@ -120,7 +120,7 @@ public:
return _loadingType;
}
- const RegionPtr & region() const {
+ const RegionPtr ®ion() const {
return _region;
}
@@ -128,7 +128,7 @@ public:
_region = region;
}
- const Children & children() const {
+ const Children &children() const {
return _children;
}
@@ -150,15 +150,15 @@ public:
add(object);
}
- void setBackground(Object * object) {
+ void setBackground(Object *object) {
_background = object;
}
- bool remove(const Common::String & name);
- bool remove(const ObjectPtr & object);
+ bool remove(const Common::String &name);
+ bool remove(const ObjectPtr &object);
void tick();
- void paint(Graphics::Surface & backbuffer) const;
+ void paint(Graphics::Surface &backbuffer) const;
Common::Array<ObjectPtr> find(Common::Point pos) const;
ObjectPtr find(const Common::String &name);
KeyHandler findKeyHandler(const Common::String &keyName);
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index d502bf12bc6..62c110030d9 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -45,7 +45,7 @@ namespace AGDS {
int pan;
int group;
bool paused;
- Sound(int id_, const Common::String &process_, const Common::String & res, const Common::String &filename_, const Common::String & var, int volume_, int pan_, int group_ = 0):
+ Sound(int id_, const Common::String &process_, const Common::String &res, const Common::String &filename_, const Common::String &var, int volume_, int pan_, int group_ = 0):
id(id_), process(process_), resource(res), filename(filename_), phaseVar(var), handle(), volume(volume_), pan(pan_), group(group_), paused(false) {
}
@@ -61,8 +61,8 @@ namespace AGDS {
class SoundManager {
using SoundList = Common::List<Sound>;
int _nextId;
- AGDSEngine * _engine;
- Audio::Mixer * _mixer;
+ AGDSEngine *_engine;
+ Audio::Mixer *_mixer;
SoundList _sounds;
public:
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index b343e8c4849..362f869f027 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -34,7 +34,7 @@ void TextLayout::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
if (!_valid)
return;
Font *font = engine.getFont(_fontId);
- for(uint i = 0; i < _lines.size(); ++i) {
+ for (uint i = 0; i < _lines.size(); ++i) {
Line & line = _lines[i];
font->drawString(&backbuffer, line.text, line.pos.x, line.pos.y, line.size.x, 0);
}
@@ -74,8 +74,8 @@ void TextLayout::layout(AGDSEngine &engine, Process &process, const Common::Stri
Common::Point basePos;
size_t begin = 0;
- while(begin < text.size()) {
- while(begin < text.size() && (text[begin]== '\r' || text[begin]== ' '))
+ while (begin < text.size()) {
+ while (begin < text.size() && (text[begin] == '\r' || text[begin] == ' '))
++begin;
size_t end = text.find('\n', begin);
if (end == text.npos)
@@ -100,7 +100,7 @@ void TextLayout::layout(AGDSEngine &engine, Process &process, const Common::Stri
}
int dy = -basePos.y / 2;
- for(uint i = 0; i < _lines.size(); ++i) {
+ for (uint i = 0; i < _lines.size(); ++i) {
Line & line = _lines[i];
line.pos.x += pos.x - line.size.x / 2;
line.pos.y += pos.y + dy;
@@ -121,16 +121,16 @@ void TextLayout::layout(AGDSEngine &engine, Process &process, const Common::Stri
engine.setGlobal(_charDirectionNotifyVar, character->direction());
} else {
switch(character->direction()) {
- case 0:
- case 1:
- case 2:
- case 3:
- case 13:
- case 14:
- case 15:
- break;
- default:
- character->animate(Common::Point(), character->direction(), 100);
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 13:
+ case 14:
+ case 15:
+ break;
+ default:
+ character->animate(Common::Point(), character->direction(), 100);
}
}
} else
Commit: 70a94a7adb1a011904d736417d879a139c549aad
https://github.com/scummvm/scummvm/commit/70a94a7adb1a011904d736417d879a139c549aad
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:13+01:00
Commit Message:
AGDS: mark nibiru as unsupported
Changed paths:
engines/agds/detection_tables.h
diff --git a/engines/agds/detection_tables.h b/engines/agds/detection_tables.h
index abe3fd79b43..7933854e909 100644
--- a/engines/agds/detection_tables.h
+++ b/engines/agds/detection_tables.h
@@ -49,7 +49,7 @@ static const ADGameDescription gameDescriptions[] = {
AD_ENTRY1s("gfx1.grp", "c8e711bc01b16cd82849cbd996d02642", 381768360),
Common::RU_RUS,
Common::kPlatformWindows,
- ADGF_DROPPLATFORM,
+ ADGF_DROPPLATFORM | ADGF_UNSUPPORTED,
GUIO1(GUIO_NONE)
},
Commit: 86684398ce71a58cc60ccfa7a7dcab5db04c3a94
https://github.com/scummvm/scummvm/commit/86684398ce71a58cc60ccfa7a7dcab5db04c3a94
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:14+01:00
Commit Message:
AGDS: fix nibiru initialisation
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 940ffb4b902..19638f19328 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -163,9 +163,10 @@ bool AGDSEngine::load() {
}
{
Common::ScopedPtr<Common::File> file(new Common::File());
- file->open("jokes.chr");
- _jokes.reset(new Character(this, "jokes"));
- _jokes->load(*file);
+ if (file->open("jokes.chr")) {
+ _jokes.reset(new Character(this, "jokes"));
+ _jokes->load(*file);
+ }
}
return true;
Commit: 6c1195bdc396bcb7ba57aa45f618fe3488eec2f1
https://github.com/scummvm/scummvm/commit/6c1195bdc396bcb7ba57aa45f618fe3488eec2f1
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:14+01:00
Commit Message:
AGDS: map v2 to v1 opcodes, fix v2 object loading
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/detection_tables.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 19638f19328..50e32dc25b3 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -24,6 +24,7 @@
#include "agds/character.h"
#include "agds/console.h"
#include "agds/database.h"
+#include "agds/detection.h"
#include "agds/font.h"
#include "agds/mjpgPlayer.h"
#include "agds/object.h"
@@ -197,7 +198,7 @@ ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::Strin
if (!stream)
error("no database entry for %s\n", clone.c_str());
- ObjectPtr object(new Object(name, *stream));
+ ObjectPtr object(new Object(name, *stream, v2()));
object->allowInitialise(allowInitialise);
if (!prototype.empty()) {
object->persistent(false);
@@ -241,7 +242,7 @@ void AGDSEngine::runProcess(const ObjectPtr &object, uint ip) {
return;
}
if (!process) {
- process = ProcessPtr(new Process(this, object, ip));
+ process = ProcessPtr(new Process(this, object, ip, v2()));
process->run();
return;
}
@@ -1420,4 +1421,8 @@ int AGDSEngine::getRandomNumber(int max) {
return max > 0 ? _random.getRandomNumber(max - 1) : 0;
}
+bool AGDSEngine::v2() const {
+ return _gameDescription->flags & AGDS_V2;
+}
+
} // End of namespace AGDS
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 7e856fa9599..203725f3f6a 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -279,6 +279,7 @@ public:
bool activeCurtain() const {
return _curtainTimer >= 0;
}
+ bool v2() const;
private:
void stopAmbientSound();
diff --git a/engines/agds/detection_tables.h b/engines/agds/detection_tables.h
index 7933854e909..db2a1eef3e0 100644
--- a/engines/agds/detection_tables.h
+++ b/engines/agds/detection_tables.h
@@ -19,6 +19,8 @@
*
*/
+#include "engines/agds/detection.h"
+
namespace AGDS {
static const ADGameDescription gameDescriptions[] = {
@@ -49,7 +51,7 @@ static const ADGameDescription gameDescriptions[] = {
AD_ENTRY1s("gfx1.grp", "c8e711bc01b16cd82849cbd996d02642", 381768360),
Common::RU_RUS,
Common::kPlatformWindows,
- ADGF_DROPPLATFORM | ADGF_UNSUPPORTED,
+ ADGF_DROPPLATFORM | AGDS_V2 | ADGF_UNSUPPORTED,
GUIO1(GUIO_NONE)
},
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index 7aac70cd44c..b742959bf25 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -33,16 +33,17 @@
namespace AGDS {
-Object::Object(const Common::String &name, Common::SeekableReadStream &stream) : _name(name), _stringTableLoaded(false),
- _picture(), _rotatedPicture(), _region(),
- _animation(), _mouseCursor(),
- _pos(), _z(10), _rotation(0),
- _clickHandler(0), _examineHandler(0), _userUseHandler(0),
- _throwHandler(0), _useOnHandler(0),
- _handlerBD(0), _handlerC1(0),
- _alpha(255), _scale(100), _locked(0), _alive(true),
- _persistent(true), _allowInitialise(true),
- _ignoreRegion(false) {
+Object::Object(const Common::String &name, Common::SeekableReadStream &stream, bool v2) :
+ _name(name), _stringTableLoaded(false),
+ _picture(), _rotatedPicture(), _region(),
+ _animation(), _mouseCursor(),
+ _pos(), _z(10), _rotation(0),
+ _clickHandler(0), _examineHandler(0), _userUseHandler(0),
+ _throwHandler(0), _useOnHandler(0),
+ _handlerBD(0), _handlerC1(0),
+ _alpha(255), _scale(100), _locked(0), _alive(true),
+ _persistent(true), _allowInitialise(true),
+ _ignoreRegion(false), _v2(v2) {
uint16 id = stream.readUint16LE();
debug("id: 0x%02x %u", id, id);
@@ -92,11 +93,11 @@ void Object::readStringTable(unsigned resOffset, uint16 resCount) {
if (_stringTableLoaded)
return;
- resOffset += 5 /*instruction*/ + 0x11 /*another header*/;
+ resOffset += 5 /*instruction*/ + (_v2? 0x13: 0x11) /*another header*/;
if (resOffset >= _code.size())
- error("invalid resource table offset");
+ error("invalid resource table offset %u/%u", resOffset, _code.size());
- //debug("resource table at %08x", resOffset);
+ // debug("resource table at %04x", resOffset);
Common::MemoryReadStream stream(_code.data() + resOffset, _code.size() - resOffset);
_stringTable.resize(resCount);
for (uint16 i = 0; i < resCount; ++i) {
@@ -105,7 +106,7 @@ void Object::readStringTable(unsigned resOffset, uint16 resCount) {
unsigned nameOffset = resOffset + offset;
if (nameOffset > _code.size())
- error("invalid resource name offset");
+ error("invalid resource name offset %u/%u", nameOffset, _code.size());
const char *nameBegin = reinterpret_cast<const char *>(_code.data() + nameOffset);
const char *codeEnd = reinterpret_cast<const char *>(_code.data() + _code.size());
@@ -113,7 +114,7 @@ void Object::readStringTable(unsigned resOffset, uint16 resCount) {
Common::String name(nameBegin, nameEnd - nameBegin);
- //debug("resource table 1[%04u]: 0x%04x %s", i, flags, name.c_str());
+ // debug("resource table 1[%04u]: 0x%04x %s", i, flags, name.c_str());
_stringTable[i] = StringEntry(name, flags);
}
debug("loaded %u strings", resCount);
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 3c7cda5eab6..45988367c81 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -92,6 +92,7 @@ private:
bool _persistent;
bool _allowInitialise;
bool _ignoreRegion;
+ bool _v2;
private:
void freeRotated();
@@ -99,7 +100,7 @@ private:
void createRotated();
public:
- Object(const Common::String &name, Common::SeekableReadStream &stream);
+ Object(const Common::String &name, Common::SeekableReadStream &stream, bool v2);
~Object();
bool allowInitialise() const {
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index ef893c8a748..7ad9f674913 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -22,9 +22,11 @@
#ifndef AGDS_OPCODE_H
#define AGDS_OPCODE_H
+#include "common/scummsys.h"
+
namespace AGDS {
-enum Opcode {
+enum Opcode : uint8 {
kEnter = 5,
kJumpZImm16 = 8,
kJumpImm16 = 9,
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index 7bc85b77f40..b99df7e57d2 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -27,7 +27,7 @@
namespace AGDS {
-Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
+Process::Process(AGDSEngine *engine, const ObjectPtr &object, unsigned ip, bool v2) :
_engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object),
_entryPoint(ip), _ip(ip), _lastIp(ip),
_status(kStatusActive), _exited(false), _exitCode(kExitCodeDestroy),
@@ -36,7 +36,7 @@ Process::Process(AGDSEngine *engine, ObjectPtr object, unsigned ip) :
_animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0),
_phaseVarControlled(false), _animationSpeed(100),
_samplePeriodic(false), _sampleAmbient(false), _sampleVolume(100),
- _filmSubtitlesResource(-1)
+ _filmSubtitlesResource(-1), _v2(v2)
{
updateWithCurrentMousePosition();
}
@@ -401,8 +401,21 @@ ProcessExitCode Process::resume() {
return kExitCodeSuspend;
}
_lastIp = _ip;
- uint8 op = next();
- //debug("CODE %04x: %u", _lastIp, (uint)op);
+ uint16 op = next();
+ if (_v2) {
+ if (op & 1) {
+ op |= next() << 8;
+ op >>= 1;
+ }
+ switch(op) {
+ case 8000: op = kEnter; break;
+ case 8011: op = kPushImm8; break;
+ case 8013: op = kPushImm8_2; break;
+ default:
+ break;
+ }
+ }
+ // debug("CODE %04x: %u", _lastIp, (uint)op);
switch (op) {
AGDS_OPCODE_LIST(
AGDS_OP,
@@ -411,7 +424,7 @@ ProcessExitCode Process::resume() {
AGDS_OP_UD, AGDS_OP_UU
)
default:
- error("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _ip - 1, (unsigned)op, (unsigned)op);
+ error("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _lastIp, (unsigned)op, (unsigned)op);
fail();
break;
}
@@ -464,13 +477,20 @@ ProcessExitCode Process::resume() {
source += Common::String::format("%s %u\n", #NAME, (uint)(arg1 | (arg2 << 16))); \
} break;
-Common::String Process::disassemble(ObjectPtr object) {
+Common::String Process::disassemble(const ObjectPtr &object, bool v2) {
Common::String source = Common::String::format("Object %s disassembly:\n", object->getName().c_str());
const auto &code = object->getCode();
uint ip = 0;
while (ip < code.size()) {
- uint8 op = code[ip++];
+ uint16 op = code[ip++];
+ if (v2) {
+ if (op & 1) {
+ op |= code[ip++] << 8;
+ op >>= 1;
+ }
+ }
+
source += Common::String::format("%04x: %02x: ", ip - 1, op);
switch (op) {
AGDS_OPCODE_LIST(
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 47cabcfbb52..1b0e8e38a26 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -73,6 +73,7 @@ private:
Common::Point _mousePosition;
int _filmSubtitlesResource;
AnimationPtr _processAnimation;
+ bool _v2;
private:
void debug(const char *str, ...);
@@ -133,12 +134,12 @@ private:
void removeScreenObject(const Common::String &name);
public:
- Process(AGDSEngine *engine, ObjectPtr object, unsigned ip = 0);
+ Process(AGDSEngine *engine, const ObjectPtr &object, unsigned ip, bool v2);
unsigned entryPoint() const {
return _entryPoint;
}
- static Common::String disassemble(ObjectPtr object);
+ static Common::String disassemble(const ObjectPtr &object, bool v2);
ObjectPtr getObject() const {
return _object;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index d94900611c5..0d3ffe9b1f3 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -78,8 +78,8 @@ void Process::enter(uint16 magic, uint16 size) {
uint16 resCount = next16();
uint16 unk4 = next16();
debug("resource block %04x %04x %04x %04x,"
- " resources table with %u entries",
- unk1, unk2, unk3, unk4, resCount);
+ " resources table at %04x with %u entries",
+ unk1, unk2, unk3, unk4, resOffset, resCount);
_object->readStringTable(resOffset, resCount);
}
Commit: aa9b5e551bc61d414e96bbaab807d39f3a5bf4a8
https://github.com/scummvm/scummvm/commit/aa9b5e551bc61d414e96bbaab807d39f3a5bf4a8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:14+01:00
Commit Message:
JANITORIAL: use pre-commit to format agds files
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/animation.cpp
engines/agds/animation.h
engines/agds/character.cpp
engines/agds/character.h
engines/agds/console.cpp
engines/agds/console.h
engines/agds/database.cpp
engines/agds/database.h
engines/agds/detection.cpp
engines/agds/detection_tables.h
engines/agds/dialog.cpp
engines/agds/dialog.h
engines/agds/font.cpp
engines/agds/font.h
engines/agds/inventory.cpp
engines/agds/inventory.h
engines/agds/metaengine.cpp
engines/agds/mjpgPlayer.cpp
engines/agds/mjpgPlayer.h
engines/agds/mouseMap.cpp
engines/agds/mouseMap.h
engines/agds/object.cpp
engines/agds/object.h
engines/agds/opcode.h
engines/agds/patch.cpp
engines/agds/patch.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/processExitCode.h
engines/agds/process_opcodes.cpp
engines/agds/region.cpp
engines/agds/region.h
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
engines/agds/screen.cpp
engines/agds/screen.h
engines/agds/soundManager.cpp
engines/agds/soundManager.h
engines/agds/systemVariable.h
engines/agds/textLayout.cpp
engines/agds/textLayout.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 50e32dc25b3..ad3bbecaa97 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -48,28 +48,28 @@
namespace AGDS {
AGDSEngine::AGDSEngine(OSystem *system, const ADGameDescription *gameDesc) : Engine(system),
- _gameDescription(gameDesc), _pictureCacheId(1), _sharedStorageIndex(-2),
- _shadowIntensity(0),
- _processes(MaxProcesses),
- _mjpgPlayer(), _filmStarted(0),
- _currentScreen(),
- _currentCharacter(),
- _defaultMouseCursor(),
- _nextScreenType(ScreenLoadingType::Normal),
- _mouse(400, 300),
- _userEnabled(true), _systemUserEnabled(true),
- _random("agds"),
- _inventoryRegion(),
- _soundManager(this, system->getMixer()),
- _inventory(this),
- _dialog(this),
- _tellTextTimer(0),
- _syncSoundId(-1),
- _ambientSoundId(-1),
- _curtainTimer(-1),
- _curtainScreen(0),
- _fastMode(true),
- _hintMode(false) {
+ _gameDescription(gameDesc), _pictureCacheId(1), _sharedStorageIndex(-2),
+ _shadowIntensity(0),
+ _processes(MaxProcesses),
+ _mjpgPlayer(), _filmStarted(0),
+ _currentScreen(),
+ _currentCharacter(),
+ _defaultMouseCursor(),
+ _nextScreenType(ScreenLoadingType::Normal),
+ _mouse(400, 300),
+ _userEnabled(true), _systemUserEnabled(true),
+ _random("agds"),
+ _inventoryRegion(),
+ _soundManager(this, system->getMixer()),
+ _inventory(this),
+ _dialog(this),
+ _tellTextTimer(0),
+ _syncSoundId(-1),
+ _ambientSoundId(-1),
+ _curtainTimer(-1),
+ _curtainScreen(0),
+ _fastMode(true),
+ _hintMode(false) {
}
AGDSEngine::~AGDSEngine() {
@@ -107,7 +107,7 @@ bool AGDSEngine::load() {
if (!configFile.open("agds.cfg"))
return false;
- configFile.readLine(); //skip first line
+ configFile.readLine(); // skip first line
config.setDefaultSectionName("core");
if (!config.loadFromStream(configFile))
return false;
@@ -175,7 +175,7 @@ bool AGDSEngine::load() {
RegionPtr AGDSEngine::loadRegion(const Common::String &name) {
debug("loading region %s", name.c_str());
- Common::ScopedPtr<Common::SeekableReadStream>stream(_data.getEntry(name));
+ Common::ScopedPtr<Common::SeekableReadStream> stream(_data.getEntry(name));
if (!stream) {
error("no database entry for %s\n", name.c_str());
return {};
@@ -194,7 +194,7 @@ Common::String AGDSEngine::loadText(const Common::String &entryName) {
ObjectPtr AGDSEngine::loadObject(const Common::String &name, const Common::String &prototype, bool allowInitialise) {
debug("loadObject %s %s, allow init: %d", name.c_str(), prototype.c_str(), allowInitialise);
Common::String clone = prototype.empty() ? name : prototype;
- Common::ScopedPtr<Common::SeekableReadStream>stream(_data.getEntry(clone));
+ Common::ScopedPtr<Common::SeekableReadStream> stream(_data.getEntry(clone));
if (!stream)
error("no database entry for %s\n", clone.c_str());
@@ -213,7 +213,7 @@ void AGDSEngine::runObject(const ObjectPtr &object) {
auto it = _objectPatches.find(object->getName());
if (it != _objectPatches.end()) {
- auto& patch = *it->_value;
+ auto &patch = *it->_value;
if (!patch.region.empty()) {
RegionPtr region = loadRegion(patch.region);
debug("runObject: patch region: %s", region->toString().c_str());
@@ -233,9 +233,9 @@ void AGDSEngine::runObject(const ObjectPtr &object) {
}
void AGDSEngine::runProcess(const ObjectPtr &object, uint ip) {
- const auto & objectName = object->getName();
+ const auto &objectName = object->getName();
debug("starting process %s:%04x", object->getName().c_str(), ip);
- for(uint i = 0; i < _processes.size(); ++i) {
+ for (uint i = 0; i < _processes.size(); ++i) {
auto &process = _processes[i];
if (ip != 0 && process && process->getName() == objectName && process->entryPoint() == ip) {
debug("found existing process, skipping...");
@@ -251,16 +251,15 @@ void AGDSEngine::runProcess(const ObjectPtr &object, uint ip) {
}
bool AGDSEngine::hasActiveProcesses(const Common::String &name) const {
- for(auto & process : _processes) {
+ for (auto &process : _processes) {
if (process && process->getName() == name && !process->finished())
return true;
}
return false;
}
-
ObjectPtr AGDSEngine::getCurrentScreenObject(const Common::String &name) {
- return _currentScreen? _currentScreen->find(name): ObjectPtr();
+ return _currentScreen ? _currentScreen->find(name) : ObjectPtr();
}
ObjectPtr AGDSEngine::runObject(const Common::String &name, const Common::String &prototype, bool allowInitialise) {
@@ -279,7 +278,7 @@ PatchPtr AGDSEngine::getPatch(const Common::String &screenName) const {
}
PatchPtr AGDSEngine::createPatch(const Common::String &screenName) {
- auto & patch = _patches[screenName];
+ auto &patch = _patches[screenName];
if (!patch)
patch = PatchPtr(new Patch());
return patch;
@@ -291,7 +290,7 @@ ObjectPatchPtr AGDSEngine::getObjectPatch(const Common::String &objectName) cons
}
ObjectPatchPtr AGDSEngine::createObjectPatch(const Common::String &objectName) {
- auto & patch = _objectPatches[objectName];
+ auto &patch = _objectPatches[objectName];
if (!patch)
patch = ObjectPatchPtr(new ObjectPatch());
return patch;
@@ -313,7 +312,6 @@ void AGDSEngine::saveScreenPatch() {
patch->defaultMouseCursor = _defaultMouseCursorName;
}
-
void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadingType, bool savePatch) {
debug("loadScreen %s [type: %d, save patch: %d, previous: %s]", name.c_str(), static_cast<int>(loadingType), savePatch, _currentScreenName.c_str());
if (savePatch)
@@ -338,7 +336,7 @@ void AGDSEngine::loadScreen(const Common::String &name, ScreenLoadingType loadin
auto previousScreenName = _currentScreenName;
resetCurrentScreen();
- for(uint i = 0; i < _processes.size(); ++i) {
+ for (uint i = 0; i < _processes.size(); ++i) {
_processes[i].reset();
}
@@ -370,7 +368,6 @@ void AGDSEngine::resetCurrentScreen() {
_currentScreenName.clear();
}
-
void AGDSEngine::runProcesses() {
fadeAndReactivate();
for (uint i = 0; i < _processes.size(); ++i) {
@@ -385,7 +382,7 @@ void AGDSEngine::runProcesses() {
debug("deleting process %s", process->getName().c_str());
_processes[i].reset();
} else {
- //debug("suspended process %s", process->getName().c_str());
+ // debug("suspended process %s", process->getName().c_str());
}
}
}
@@ -394,7 +391,6 @@ Console *AGDSEngine::getConsole() {
return static_cast<Console *>(getDebugger());
}
-
void AGDSEngine::newGame() {
SystemVariable *doneVar = getSystemVariable("done_resources");
Common::String done = doneVar->getString();
@@ -418,9 +414,9 @@ void AGDSEngine::newGame() {
void AGDSEngine::curtain(const Common::String &process, int screen, int sound, int music, bool updateGlobals) {
assert(!process.empty());
if (updateGlobals) {
- getSystemVariable("screen_curtain")->setInteger(screen >= 0? screen: -screen);
- getSystemVariable("sound_curtain")->setInteger(sound >= 0? sound: -sound);
- getSystemVariable("music_curtain")->setInteger(music >= 0? music: -music);
+ getSystemVariable("screen_curtain")->setInteger(screen >= 0 ? screen : -screen);
+ getSystemVariable("sound_curtain")->setInteger(sound >= 0 ? sound : -sound);
+ getSystemVariable("music_curtain")->setInteger(music >= 0 ? music : -music);
}
_curtainProcess = process;
_curtainTimer = 100;
@@ -569,7 +565,7 @@ Common::Error AGDSEngine::run() {
if (userEnabled()) {
bool lclick = event.type == Common::EVENT_LBUTTONDOWN;
debug("%s %d, %d inv: %s", lclick ? "lclick" : "rclick", _mouse.x, _mouse.y,
- _currentInventoryObject? _currentInventoryObject->getName().c_str(): "none");
+ _currentInventoryObject ? _currentInventoryObject->getName().c_str() : "none");
ObjectPtr runObject;
uint ip = 0;
@@ -596,13 +592,13 @@ Common::Error AGDSEngine::run() {
}
if (!runObject) {
auto objects = _currentScreen->find(_mouse);
- if (objects.empty() && !_currentInventoryObject) { //allow inventory to be selected
+ if (objects.empty() && !_currentInventoryObject) { // allow inventory to be selected
auto object = _inventory.find(_mouse);
if (object)
objects.push_back(object);
}
- for(auto & object : objects) {
+ for (auto &object : objects) {
debug("found object %s", object->getName().c_str());
if (lclick) {
if (_currentInventoryObject) {
@@ -647,7 +643,7 @@ Common::Error AGDSEngine::run() {
debug("no handler found");
if (lclick) {
if (_currentCharacter && _currentCharacter->active() && _currentScreen && _currentScreen->region()) {
- auto & region = _currentScreen->region();
+ auto ®ion = _currentScreen->region();
if (region->pointIn(_mouse)) {
// FIXME: some object requires character to be in "trap" region
// Remove this after movement implementation.
@@ -683,9 +679,8 @@ Common::Error AGDSEngine::run() {
objects.push_back(object);
}
-
AnimationPtr cursor;
- for (auto & object : objects) {
+ for (auto &object : objects) {
cursor = object->getMouseCursor();
if (cursor)
break;
@@ -721,7 +716,7 @@ Common::Error AGDSEngine::run() {
mouseCursor = _defaultMouseCursor;
if (userEnabled()) {
- if (auto *picture = _currentInventoryObject? _currentInventoryObject->getPicture(): nullptr) {
+ if (auto *picture = _currentInventoryObject ? _currentInventoryObject->getPicture() : nullptr) {
Common::Rect srcRect = picture->getBounds();
Common::Point dst = _mouse;
dst.x -= srcRect.width() / 2;
@@ -730,7 +725,7 @@ Common::Error AGDSEngine::run() {
if (Common::Rect::getBlitRect(dst, srcRect, backbuffer->getRect())) {
picture->blendBlitTo(*backbuffer, dst.x, dst.y, Graphics::FLIP_NONE, &srcRect, color);
}
- } else if (auto cursor = (_currentInventoryObject? _currentInventoryObject->getMouseCursor(): AnimationPtr())) {
+ } else if (auto cursor = (_currentInventoryObject ? _currentInventoryObject->getMouseCursor() : AnimationPtr())) {
cursor->rotate(_currentInventoryObject->rotation());
cursor->tick();
auto pos = _mouse;
@@ -850,7 +845,7 @@ int AGDSEngine::getGlobal(const Common::String &name) const {
if (i != _globals.end())
return i->_value;
else {
- //debug("global %s was not declared, returning 0", name.c_str());
+ // debug("global %s was not declared, returning 0", name.c_str());
return 0;
}
}
@@ -870,7 +865,7 @@ AnimationPtr AGDSEngine::loadAnimation(const Common::String &name) {
}
AnimationPtr AGDSEngine::findAnimationByPhaseVar(const Common::String &phaseVar) {
- return _currentScreen? _currentScreen->findAnimationByPhaseVar(phaseVar): nullptr;
+ return _currentScreen ? _currentScreen->findAnimationByPhaseVar(phaseVar) : nullptr;
}
void AGDSEngine::loadCharacter(const Common::String &id, const Common::String &filename, const Common::String &object) {
@@ -934,8 +929,8 @@ Graphics::ManagedSurface *AGDSEngine::convertToTransparent(Graphics::Surface *s)
Graphics::ManagedSurface *t = new Graphics::ManagedSurface(s->w, s->h, _pixelFormat);
assert(s->format.bytesPerPixel == 4);
assert(t->format.bytesPerPixel == 4);
- uint8* dst = static_cast<uint8 *>(t->getPixels());
- const uint8* src = static_cast<uint8 *>(s->getPixels());
+ uint8 *dst = static_cast<uint8 *>(t->getPixels());
+ const uint8 *src = static_cast<uint8 *>(s->getPixels());
uint8 shadowAlpha = 255 * _shadowIntensity / 100;
auto &dstFormat = t->format;
auto &srcFormat = s->format;
@@ -952,8 +947,7 @@ Graphics::ManagedSurface *AGDSEngine::convertToTransparent(Graphics::Surface *s)
} else if (
r >= _minShadowColor.r && r <= _maxShadowColor.r &&
g >= _minShadowColor.g && g <= _maxShadowColor.g &&
- b >= _minShadowColor.b && b <= _maxShadowColor.b
- ) {
+ b >= _minShadowColor.b && b <= _maxShadowColor.b) {
r = g = b = 0;
a = shadowAlpha;
}
@@ -973,7 +967,7 @@ void AGDSEngine::tell(Process &process, const Common::String ®ionName, Common
_inventory.enable(false);
}
- int font_id = getSystemVariable(npc? "npc_tell_font": "tell_font")->getInteger();
+ int font_id = getSystemVariable(npc ? "npc_tell_font" : "tell_font")->getInteger();
Common::Point pos;
if (regionName.empty()) {
@@ -1004,7 +998,6 @@ void AGDSEngine::stopAmbientSound() {
}
}
-
void AGDSEngine::initSystemVariables() {
addSystemVar("inventory_scr", new StringSystemVariable());
addSystemVar("escape_scr", new StringSystemVariable("none"));
@@ -1098,7 +1091,7 @@ void AGDSEngine::loadPatches(Common::SeekableReadStream &file, Database &db) {
_objectPatches.clear();
Common::Array<Common::String> entries = db.getEntries();
for (uint i = 0; i < entries.size(); ++i) {
- const Common::String & name = entries[i];
+ const Common::String &name = entries[i];
if (name[0] == '_')
continue;
debug("loading patch for %s", name.c_str());
@@ -1117,7 +1110,7 @@ void AGDSEngine::loadPatches(Common::SeekableReadStream &file, Database &db) {
}
Common::Error AGDSEngine::loadGameState(int slot) {
- //saveAutosaveIfEnabled();
+ // saveAutosaveIfEnabled();
auto fileName = getSaveStateName(slot);
Common::ScopedPtr<Common::InSaveFile> saveFile(_saveFileMan->openForLoading(fileName));
@@ -1190,7 +1183,7 @@ Common::Error AGDSEngine::loadGameState(int slot) {
// System vars
Common::ScopedPtr<Common::SeekableReadStream> agds_d(db.getEntry(*saveFile, "__agds_d"));
for (uint i = 0, n = _systemVarList.size(); i < n; ++i) {
- Common::String & name = _systemVarList[i];
+ Common::String &name = _systemVarList[i];
_systemVars[name]->read(*agds_d);
}
}
@@ -1212,7 +1205,7 @@ Common::Error AGDSEngine::loadGameState(int slot) {
debug("saved audio state: sample: '%s:%s', var: '%s' %u %u", resource.c_str(), filename.c_str(), phaseVar.c_str(), volume, type);
debug("phase var for sample -> %d", getGlobal(phaseVar));
_ambientSoundId = _soundManager.play(Common::String(), resource, filename, phaseVar, true,
- volume, /*pan=*/0, /*id=*/-1, /*ambient=*/true);
+ volume, /*pan=*/0, /*id=*/-1, /*ambient=*/true);
debug("ambient sound id = %d", _ambientSoundId);
}
{
@@ -1287,7 +1280,7 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
{
Common::MemoryWriteStreamDynamic stream(DisposeAfterUse::YES);
for (uint i = 0, n = _systemVarList.size(); i < n; ++i) {
- Common::String & name = _systemVarList[i];
+ Common::String &name = _systemVarList[i];
_systemVars[name]->write(stream);
}
entries["__agds_d"].assign(stream.getData(), stream.getData() + stream.size());
@@ -1322,8 +1315,8 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
writeString(stream, Common::String());
writeString(stream, Common::String());
}
- stream.writeUint32LE(70); //volume
- stream.writeUint32LE(30); //type
+ stream.writeUint32LE(70); // volume
+ stream.writeUint32LE(30); // type
entries["__agds_a"].assign(stream.getData(), stream.getData() + stream.size());
}
@@ -1345,7 +1338,6 @@ Common::Error AGDSEngine::saveGameState(int slot, const Common::String &desc, bo
return Common::kNoError;
}
-
void AGDSEngine::reactivate(const Common::String &name, const Common::String &where, bool runNow) {
if (name.empty())
return;
@@ -1365,13 +1357,13 @@ void AGDSEngine::runPendingReactivatedProcesses() {
while (!_pendingReactivatedProcesses.empty()) {
ProcessListType processes;
_pendingReactivatedProcesses.swap(processes);
- for(auto & process : processes) {
+ for (auto &process : processes) {
process->run();
}
}
}
-ProcessPtr AGDSEngine::findProcess(const Common::String & name) const {
+ProcessPtr AGDSEngine::findProcess(const Common::String &name) const {
for (uint i = 0; i < _processes.size(); ++i) {
const ProcessPtr &process = _processes[i];
if (process && !process->finished() && process->getName() == name)
@@ -1380,10 +1372,10 @@ ProcessPtr AGDSEngine::findProcess(const Common::String & name) const {
return {};
}
-void AGDSEngine::currentInventoryObject(const ObjectPtr & object) {
+void AGDSEngine::currentInventoryObject(const ObjectPtr &object) {
if (_currentInventoryObject)
- warning("setting current inventory object to %s, old: %s", object? object->getName().c_str(): "none",
- _currentInventoryObject? _currentInventoryObject->getName().c_str(): "none");
+ warning("setting current inventory object to %s, old: %s", object ? object->getName().c_str() : "none",
+ _currentInventoryObject ? _currentInventoryObject->getName().c_str() : "none");
_currentInventoryObject = object;
}
@@ -1409,7 +1401,7 @@ void AGDSEngine::setNextScreenName(const Common::String &nextScreenName, ScreenL
}
void AGDSEngine::returnToPreviousScreen() {
- auto previousScreenName = _currentScreen? _currentScreen->getPreviousScreenName(): Common::String();
+ auto previousScreenName = _currentScreen ? _currentScreen->getPreviousScreenName() : Common::String();
debug("returnToPreviousScreen from %s, previous screen: %s", _currentScreenName.c_str(), previousScreenName.c_str());
if (!previousScreenName.empty()) {
_nextScreenName = previousScreenName;
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index 203725f3f6a..f223b2b5bde 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -22,14 +22,6 @@
#ifndef AGDS_AGDS_H
#define AGDS_AGDS_H
-#include "common/scummsys.h"
-#include "common/array.h"
-#include "common/hashmap.h"
-#include "common/ptr.h"
-#include "common/random.h"
-#include "common/rect.h"
-#include "engines/advancedDetector.h"
-#include "agds/soundManager.h"
#include "agds/database.h"
#include "agds/dialog.h"
#include "agds/inventory.h"
@@ -37,7 +29,15 @@
#include "agds/processExitCode.h"
#include "agds/resourceManager.h"
#include "agds/screen.h"
+#include "agds/soundManager.h"
#include "agds/textLayout.h"
+#include "common/array.h"
+#include "common/hashmap.h"
+#include "common/ptr.h"
+#include "common/random.h"
+#include "common/rect.h"
+#include "common/scummsys.h"
+#include "engines/advancedDetector.h"
#include "graphics/pixelformat.h"
#include "video/flic_decoder.h"
@@ -50,7 +50,9 @@
* - Black Mirror (Windows)
*/
-namespace Graphics { class ManagedSurface; }
+namespace Graphics {
+class ManagedSurface;
+}
namespace AGDS {
@@ -81,7 +83,6 @@ class AGDSEngine : public Engine {
static constexpr uint MaxProcesses = 100;
public:
-
struct Color {
uint8 r = 0;
uint8 g = 0;
@@ -114,7 +115,6 @@ private:
void fadeAndReactivate();
public:
-
bool hasFeature(EngineFeature f) const override;
Common::Error loadGameState(int slot) override;
Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
@@ -185,9 +185,9 @@ public:
Graphics::ManagedSurface *loadPicture(const Common::String &name);
Graphics::Surface *createSurface(int w, int h);
- Graphics::ManagedSurface *convertToTransparent(Graphics::Surface *surface); //destroys surface!
+ Graphics::ManagedSurface *convertToTransparent(Graphics::Surface *surface); // destroys surface!
- int loadFromCache(const Common::String & name) const;
+ int loadFromCache(const Common::String &name) const;
Graphics::ManagedSurface *loadFromCache(int id) const;
int saveToCache(const Common::String &name, Graphics::ManagedSurface *surface);
@@ -198,7 +198,7 @@ public:
AnimationPtr loadMouseCursor(const Common::String &name);
AnimationPtr findAnimationByPhaseVar(const Common::String &phaseVar);
void loadCharacter(const Common::String &id, const Common::String &name, const Common::String &object);
- Character * getCharacter(const Common::String &name) {
+ Character *getCharacter(const Common::String &name) {
return _currentCharacterName == name ? _currentCharacter.get() : nullptr;
}
Character *currentCharacter() const {
@@ -295,69 +295,68 @@ private:
using ObjectPatchesType = Common::HashMap<Common::String, ObjectPatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
using PatchDatabase = Common::HashMap<Common::String, Common::Array<uint8>>;
- const ADGameDescription *_gameDescription;
- ResourceManager _resourceManager;
- SoundManager _soundManager;
- Database _data;
- PictureCacheType _pictureCache;
- PictureCacheLookup _pictureCacheLookup;
- int _pictureCacheId;
- FontsType _fonts;
- ProcessListType _processes;
- ProcessListType _pendingReactivatedProcesses;
- PatchesType _patches;
- ObjectPatchesType _objectPatches;
- int _sharedStorageIndex;
- Common::String _sharedStorage[10];
- GlobalsType _globals;
- SystemVariablesListType _systemVarList;
- SystemVariablesType _systemVars;
- Graphics::PixelFormat _pixelFormat;
- Color _colorKey;
- Color _minShadowColor;
- Color _maxShadowColor;
- int _shadowIntensity;
- Common::ScopedPtr<MJPGPlayer> _mjpgPlayer;
- uint32 _filmStarted;
- Common::String _filmProcess;
- Common::ScopedPtr<Screen> _currentScreen;
- Common::String _currentScreenName;
- Common::ScopedPtr<Character> _currentCharacter;
- Common::ScopedPtr<Character> _jokes;
- Common::String _currentCharacterName, _currentCharacterFilename, _currentCharacterObject;
- Common::String _nextScreenName;
- ScreenLoadingType _nextScreenType;
- Common::String _defaultMouseCursorName;
- AnimationPtr _defaultMouseCursor;
- Common::Point _mouse;
- bool _userEnabled;
- bool _systemUserEnabled;
- MouseMap _mouseMap;
- Common::RandomSource _random;
-
- Inventory _inventory;
- Common::String _inventoryRegionName;
- RegionPtr _inventoryRegion;
- ObjectPtr _currentInventoryObject;
-
- Dialog _dialog;
+ const ADGameDescription *_gameDescription;
+ ResourceManager _resourceManager;
+ SoundManager _soundManager;
+ Database _data;
+ PictureCacheType _pictureCache;
+ PictureCacheLookup _pictureCacheLookup;
+ int _pictureCacheId;
+ FontsType _fonts;
+ ProcessListType _processes;
+ ProcessListType _pendingReactivatedProcesses;
+ PatchesType _patches;
+ ObjectPatchesType _objectPatches;
+ int _sharedStorageIndex;
+ Common::String _sharedStorage[10];
+ GlobalsType _globals;
+ SystemVariablesListType _systemVarList;
+ SystemVariablesType _systemVars;
+ Graphics::PixelFormat _pixelFormat;
+ Color _colorKey;
+ Color _minShadowColor;
+ Color _maxShadowColor;
+ int _shadowIntensity;
+ Common::ScopedPtr<MJPGPlayer> _mjpgPlayer;
+ uint32 _filmStarted;
+ Common::String _filmProcess;
+ Common::ScopedPtr<Screen> _currentScreen;
+ Common::String _currentScreenName;
+ Common::ScopedPtr<Character> _currentCharacter;
+ Common::ScopedPtr<Character> _jokes;
+ Common::String _currentCharacterName, _currentCharacterFilename, _currentCharacterObject;
+ Common::String _nextScreenName;
+ ScreenLoadingType _nextScreenType;
+ Common::String _defaultMouseCursorName;
+ AnimationPtr _defaultMouseCursor;
+ Common::Point _mouse;
+ bool _userEnabled;
+ bool _systemUserEnabled;
+ MouseMap _mouseMap;
+ Common::RandomSource _random;
+
+ Inventory _inventory;
+ Common::String _inventoryRegionName;
+ RegionPtr _inventoryRegion;
+ ObjectPtr _currentInventoryObject;
+
+ Dialog _dialog;
// Original engine use weird names for the vars, I keep them.
- int _tellTextTimer;
- TextLayout _textLayout;
+ int _tellTextTimer;
+ TextLayout _textLayout;
- int _syncSoundId;
- int _ambientSoundId;
+ int _syncSoundId;
+ int _ambientSoundId;
- Common::String _curtainProcess;
- int _curtainTimer;
- int _curtainScreen;
+ Common::String _curtainProcess;
+ int _curtainTimer;
+ int _curtainScreen;
- bool _fastMode;
- bool _hintMode;
+ bool _fastMode;
+ bool _hintMode;
};
-
} // End of namespace AGDS
#endif /* AGDS_AGDS_H */
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index bc11a71bc24..59bbe475606 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -29,12 +29,11 @@
namespace AGDS {
-Animation::Animation(AGDSEngine *engine, const Common::String &name) :
- _engine(engine), _name(name), _flic(), _frame(), _scaledFrame(),
- _frames(0), _loop(false), _cycles(1), _phaseVarControlled(false),
- _phase(0), _paused(false), _speed(100), _z(0), _rotation(0),
- _delay(0), _random(0), _scale(1), _onScreen(true),
- _visibleHeight(0), _visibleCenter(0) {
+Animation::Animation(AGDSEngine *engine, const Common::String &name) : _engine(engine), _name(name), _flic(), _frame(), _scaledFrame(),
+ _frames(0), _loop(false), _cycles(1), _phaseVarControlled(false),
+ _phase(0), _paused(false), _speed(100), _z(0), _rotation(0),
+ _delay(0), _random(0), _scale(1), _onScreen(true),
+ _visibleHeight(0), _visibleCenter(0) {
}
Animation::~Animation() {
@@ -56,7 +55,6 @@ void Animation::freeFrame() {
}
}
-
bool Animation::load(Common::SeekableReadStream *stream, const Common::String &fname) {
if (_phaseVarControlled) {
if (_phaseVar.empty()) {
@@ -121,15 +119,15 @@ void Animation::rescaleCurrentFrame() {
} else if (_scale != 1) {
_scaledFrame.reset(_frame->scale(_frame->w * _scale, _frame->h * _scale, true));
}
- auto *frame = _scaledFrame? _scaledFrame.get(): _frame.get();
+ auto *frame = _scaledFrame ? _scaledFrame.get() : _frame.get();
if (frame) {
uint h = frame->h, w = frame->w;
_visibleHeight = 0;
uint minX = w, maxX = 0;
- for(uint i = 0; i != h; ++i) {
+ for (uint i = 0; i != h; ++i) {
uint y = h - 1 - i;
- auto * ptr = static_cast<uint32*>(frame->getBasePtr(0, y));
- for(uint x = 0; x != w; ++x) {
+ auto *ptr = static_cast<uint32 *>(frame->getBasePtr(0, y));
+ for (uint x = 0; x != w; ++x) {
uint8 a, r, g, b;
frame->format.colorToARGB(*ptr++, a, r, g, b);
if (a != 0) {
@@ -142,7 +140,7 @@ void Animation::rescaleCurrentFrame() {
}
}
}
- _visibleCenter = minX < maxX? (maxX + minX) / 2: 0;
+ _visibleCenter = minX < maxX ? (maxX + minX) / 2 : 0;
}
}
@@ -160,7 +158,7 @@ void Animation::decodeNextFrame() {
}
freeFrame();
- _delay = _flic->getCurFrameDelay() * _speed / 4000; //40 == 1000 / 25, 25 fps
+ _delay = _flic->getCurFrameDelay() * _speed / 4000; // 40 == 1000 / 25, 25 fps
_frame.reset(_engine->convertToTransparent(frame->convertTo(_engine->pixelFormat(), _flic->getPalette())));
rescaleCurrentFrame();
++_phase;
@@ -176,7 +174,7 @@ void Animation::onScreen(bool onScreen) {
}
bool Animation::tick() {
- if (!_flic && _frame) { //static frame
+ if (!_flic && _frame) { // static frame
return true;
}
@@ -210,7 +208,7 @@ bool Animation::tick() {
if (!_process.empty()) {
if (!_phaseVar.empty())
_engine->setGlobal(_phaseVar, _phase - 1);
- if (/*_phase || */_phaseVarControlled) {
+ if (/*_phase || */ _phaseVarControlled) {
if (eov && _random) {
rewind();
_delay = _engine->getRandomNumber(_random);
@@ -238,7 +236,7 @@ bool Animation::tick() {
void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst, Graphics::ManagedSurface *mask, int maskAlpha) const {
dst += _position;
- auto *frame = _scaledFrame? _scaledFrame.get(): _frame.get();
+ auto *frame = _scaledFrame ? _scaledFrame.get() : _frame.get();
if (!frame || !_onScreen)
return;
@@ -250,20 +248,20 @@ void Animation::paint(Graphics::Surface &backbuffer, Common::Point dst, Graphics
int invMaskAlpha = 255 - maskAlpha;
auto subFrame = frame->getSubArea(srcRect);
auto subMask = mask->getSubArea(srcRect);
- byte * dstPixels = static_cast<byte *>(backbuffer.getBasePtr(dst.x, dst.y));
- const byte * srcPixels = static_cast<byte *>(subFrame.getPixels());
- const byte * maskPixels = static_cast<byte *>(subMask.getPixels());
- for(int y = 0; y != srcRect.height(); ++y) {
+ byte *dstPixels = static_cast<byte *>(backbuffer.getBasePtr(dst.x, dst.y));
+ const byte *srcPixels = static_cast<byte *>(subFrame.getPixels());
+ const byte *maskPixels = static_cast<byte *>(subMask.getPixels());
+ for (int y = 0; y != srcRect.height(); ++y) {
byte *dstRow = dstPixels;
const byte *srcRow = srcPixels;
const byte *maskRow = maskPixels;
- for(int x = 0; x != srcRect.width(); ++x) {
+ for (int x = 0; x != srcRect.width(); ++x) {
uint8 srcA = *srcRow++;
++dstRow;
++maskRow;
uint8 invSrcA = 255 - srcA;
if (srcA != 0) {
- for(int n = 3; n--; ++dstRow) {
+ for (int n = 3; n--; ++dstRow) {
*dstRow = ((*dstRow * invSrcA + *srcRow++ * srcA) * invMaskAlpha + *maskRow++ * maskAlpha * srcA) / 65025;
}
} else {
@@ -284,7 +282,7 @@ uint Animation::width() const {
return _flic ? _flic->getWidth() * _scale : 0;
}
uint Animation::height() const {
- return _flic ? _flic->getHeight() * _scale: 0;
+ return _flic ? _flic->getHeight() * _scale : 0;
}
} // namespace AGDS
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index c30c0986641..4c6332dcff7 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -22,14 +22,21 @@
#ifndef AGDS_ANIMATION_H
#define AGDS_ANIMATION_H
-#include "common/scummsys.h"
+#include "common/ptr.h"
#include "common/rect.h"
+#include "common/scummsys.h"
#include "common/str.h"
-#include "common/ptr.h"
-namespace Common { class SeekableReadStream; }
-namespace Graphics { struct Surface; class ManagedSurface; }
-namespace Video { class FlicDecoder; }
+namespace Common {
+class SeekableReadStream;
+}
+namespace Graphics {
+struct Surface;
+class ManagedSurface;
+} // namespace Graphics
+namespace Video {
+class FlicDecoder;
+}
namespace AGDS {
@@ -40,29 +47,29 @@ class Animation {
using FlicPtr = Common::ScopedPtr<Video::FlicDecoder>;
using ManagedSurfacePtr = Common::ScopedPtr<Graphics::ManagedSurface>;
- AGDSEngine *_engine;
- Common::String _name;
- FlicPtr _flic;
- ManagedSurfacePtr _frame;
- ManagedSurfacePtr _scaledFrame;
- int _frames;
- Common::Point _position;
- Common::String _process;
- Common::String _phaseVar;
- bool _loop;
- int _cycles;
- bool _phaseVarControlled;
- int _phase;
- bool _paused;
- int _speed;
- int _z;
- int _rotation;
- int _delay;
- int _random;
- float _scale;
- bool _onScreen;
- uint _visibleHeight;
- uint _visibleCenter;
+ AGDSEngine *_engine;
+ Common::String _name;
+ FlicPtr _flic;
+ ManagedSurfacePtr _frame;
+ ManagedSurfacePtr _scaledFrame;
+ int _frames;
+ Common::Point _position;
+ Common::String _process;
+ Common::String _phaseVar;
+ bool _loop;
+ int _cycles;
+ bool _phaseVarControlled;
+ int _phase;
+ bool _paused;
+ int _speed;
+ int _z;
+ int _rotation;
+ int _delay;
+ int _random;
+ float _scale;
+ bool _onScreen;
+ uint _visibleHeight;
+ uint _visibleCenter;
public:
Animation(AGDSEngine *engine, const Common::String &name);
@@ -115,7 +122,7 @@ public:
_delay = delay;
}
- void setRandom(int value) { //can't declare random() because of stupid macro
+ void setRandom(int value) { // can't declare random() because of stupid macro
_random = value;
}
@@ -189,7 +196,6 @@ private:
void freeScaledFrame();
};
-
} // End of namespace AGDS
#endif /* AGDS_ANIMATION_H */
diff --git a/engines/agds/character.cpp b/engines/agds/character.cpp
index 6665e4822dc..6e79a62973e 100644
--- a/engines/agds/character.cpp
+++ b/engines/agds/character.cpp
@@ -37,11 +37,10 @@
namespace AGDS {
-Character::Character(AGDSEngine * engine, const Common::String & name):
- _engine(engine), _object(), _animation(nullptr), _jokes(false),
- _name(name),
- _enabled(true), _visible(false), _stopped(false), _shown(false),
- _phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
+Character::Character(AGDSEngine *engine, const Common::String &name) : _engine(engine), _object(), _animation(nullptr), _jokes(false),
+ _name(name),
+ _enabled(true), _visible(false), _stopped(false), _shown(false),
+ _phase(-1), _frames(0), _direction(-1), _movementDirections(0) {
}
Character::~Character() {
@@ -49,7 +48,7 @@ Character::~Character() {
void Character::load(Common::SeekableReadStream &stream) {
debug("loading character...");
- stream.readUint32LE(); //unk
+ stream.readUint32LE(); // unk
uint16 magic = stream.readUint16LE();
switch (magic) {
case 0xdead:
@@ -86,21 +85,21 @@ void Character::load(Common::SeekableReadStream &stream) {
uint unk1 = stream.readUint32LE();
uint unk2 = stream.readUint32LE();
uint unk3 = stream.readUint32LE();
- uint unk4 = stream.readUint32LE(); //GRP file offset?
+ uint unk4 = stream.readUint32LE(); // GRP file offset?
uint unk5 = stream.readUint32LE();
uint unk6 = stream.readByte();
uint unk7 = stream.readUint32LE();
uint unk8 = stream.readUint32LE();
- stream.readUint32LE(); //CDCDCDCD
+ stream.readUint32LE(); // CDCDCDCD
uint unk9 = stream.readUint32LE();
uint unk10 = stream.readUint32LE();
- stream.readUint32LE(); //CDCDCDCD
+ stream.readUint32LE(); // CDCDCDCD
uint unk11 = stream.readByte();
- stream.readUint32LE(); //CDCDCDCD
+ stream.readUint32LE(); // CDCDCDCD
debug("unknown: %u %u %u 0x%08x - %u %u %u %u - %u %u %u",
- unk1, unk2, unk3, unk4,
- unk5, unk6, unk7, unk8,
- unk9, unk10, unk11);
+ unk1, unk2, unk3, unk4,
+ unk5, unk6, unk7, unk8,
+ unk9, unk10, unk11);
}
_animations[index] = animation;
}
@@ -137,7 +136,6 @@ void Character::saveState(Common::WriteStream &stream) const {
stream.writeUint16LE(_enabled);
}
-
bool Character::direction(int dir) {
debug("setDirection %d", dir);
_direction = dir;
@@ -201,15 +199,15 @@ bool Character::animate(int direction, int speed, bool jokes) {
return false;
}
- auto character = jokes? _engine->jokes(): this;
+ auto character = jokes ? _engine->jokes() : this;
auto description = character->animationDescription(direction);
if (!description) {
- warning("no %s animation %d", jokes? "jokes": "character", direction);
+ warning("no %s animation %d", jokes ? "jokes" : "character", direction);
return false;
}
auto animation = _engine->loadAnimation(description->filename);
if (!animation) {
- warning("no %s animation file %s", jokes? "jokes": "character", description->filename.c_str());
+ warning("no %s animation file %s", jokes ? "jokes" : "character", description->filename.c_str());
return false;
}
_description = description;
@@ -253,7 +251,7 @@ void Character::tick(bool reactivate) {
return;
if (_animation) {
auto screen = _engine->getCurrentScreen();
- auto scale = screen? screen->getZScale(_pos.y): 1;
+ auto scale = screen ? screen->getZScale(_pos.y) : 1;
_animation->scale(scale);
if (!_stopped && _phase >= 0 && _phase < _frames) {
@@ -305,9 +303,8 @@ Common::Point Character::animationPosition() const {
return pos;
}
-
void Character::paint(Graphics::Surface &backbuffer, Common::Point pos) const {
- if (!_enabled || !visible()|| !_animation)
+ if (!_enabled || !visible() || !_animation)
return;
pos += animationPosition();
@@ -326,8 +323,8 @@ void Character::paint(Graphics::Surface &backbuffer, Common::Point pos) const {
int Character::z() const {
int y = _pos.y + _animationPos.y;
- //fixme: add temp var : _movePos?
- //debug("char z = %d", y);
+ // fixme: add temp var : _movePos?
+ // debug("char z = %d", y);
return g_system->getHeight() - y;
}
@@ -339,7 +336,7 @@ void Character::reset() {
_frames = 0;
}
-void Character::setFog(Graphics::ManagedSurface * surface, int minZ, int maxZ) {
+void Character::setFog(Graphics::ManagedSurface *surface, int minZ, int maxZ) {
_fog.reset(surface);
_fogMinZ = minZ;
_fogMaxZ = maxZ;
diff --git a/engines/agds/character.h b/engines/agds/character.h
index bbdc13d090f..01b759eb9a6 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -22,13 +22,20 @@
#ifndef AGDS_CHARACTER_H
#define AGDS_CHARACTER_H
-#include "common/scummsys.h"
#include "common/hashmap.h"
#include "common/ptr.h"
#include "common/rect.h"
+#include "common/scummsys.h"
-namespace Common { class SeekableReadStream; class ReadStream; class WriteStream; }
-namespace Graphics { struct Surface; class ManagedSurface; }
+namespace Common {
+class SeekableReadStream;
+class ReadStream;
+class WriteStream;
+} // namespace Common
+namespace Graphics {
+struct Surface;
+class ManagedSurface;
+} // namespace Graphics
namespace AGDS {
@@ -40,15 +47,15 @@ using AnimationPtr = Common::SharedPtr<Animation>;
class Character {
using FogPtr = Common::ScopedPtr<Graphics::ManagedSurface>;
- AGDSEngine *_engine;
- ObjectPtr _object;
- AnimationPtr _animation;
- FogPtr _fog;
- bool _jokes;
- Common::String _name;
- Common::String _processName;
- Common::Point _pos;
- Common::Point _animationPos;
+ AGDSEngine *_engine;
+ ObjectPtr _object;
+ AnimationPtr _animation;
+ FogPtr _fog;
+ bool _jokes;
+ Common::String _name;
+ Common::String _processName;
+ Common::Point _pos;
+ Common::Point _animationPos;
bool _enabled;
bool _visible;
bool _stopped;
@@ -66,8 +73,8 @@ class Character {
uint w, h;
};
- Common::String filename;
- Common::Array<Frame> frames;
+ Common::String filename;
+ Common::Array<Frame> frames;
};
Common::HashMap<uint, AnimationDescription> _animations;
const AnimationDescription *_description;
@@ -94,9 +101,9 @@ public:
return _object;
}
- void load(Common::SeekableReadStream& stream);
- void loadState(Common::ReadStream& stream);
- void saveState(Common::WriteStream& stream) const;
+ void load(Common::SeekableReadStream &stream);
+ void loadState(Common::ReadStream &stream);
+ void saveState(Common::WriteStream &stream) const;
void enable(bool enabled = true) {
_enabled = enabled;
@@ -132,7 +139,7 @@ public:
}
bool pointIn(Common::Point pos) const;
- void notifyProcess(const Common::String & processName);
+ void notifyProcess(const Common::String &processName);
bool moveTo(const Common::String &processName, Common::Point dst, int direction);
void pointTo(const Common::String &processName, Common::Point dst);
@@ -153,7 +160,6 @@ public:
void setFog(Graphics::ManagedSurface *surface, int minZ, int maxZ);
};
-
} // End of namespace AGDS
#endif /* AGDS_CHARACTER_H */
diff --git a/engines/agds/console.cpp b/engines/agds/console.cpp
index b55e4a99aae..ee08ca45391 100644
--- a/engines/agds/console.cpp
+++ b/engines/agds/console.cpp
@@ -30,13 +30,13 @@
namespace AGDS {
Console::Console(AGDSEngine *engine) : _engine(engine) {
- registerCmd("activate", WRAP_METHOD(Console, activate));
- registerCmd("info", WRAP_METHOD(Console, info));
- registerCmd("load", WRAP_METHOD(Console, load));
- registerCmd("run", WRAP_METHOD(Console, run));
- registerCmd("stop", WRAP_METHOD(Console, stop));
- registerCmd("set", WRAP_METHOD(Console, setGlobal));
- registerCmd("invadd", WRAP_METHOD(Console, inventoryAdd));
+ registerCmd("activate", WRAP_METHOD(Console, activate));
+ registerCmd("info", WRAP_METHOD(Console, info));
+ registerCmd("load", WRAP_METHOD(Console, load));
+ registerCmd("run", WRAP_METHOD(Console, run));
+ registerCmd("stop", WRAP_METHOD(Console, stop));
+ registerCmd("set", WRAP_METHOD(Console, setGlobal));
+ registerCmd("invadd", WRAP_METHOD(Console, inventoryAdd));
registerCmd("patch", WRAP_METHOD(Console, patch));
}
@@ -106,21 +106,21 @@ bool Console::info(int argc, const char **argv) {
auto screen = _engine->getCurrentScreen();
if (screen) {
debugPrintf("screen %s:\n", screen->getName().c_str());
- for(auto & object : screen->children()) {
+ for (auto &object : screen->children()) {
auto pos = object->getPosition();
debugPrintf("object %s [alive: %d] at %d,%d\n", object->getName().c_str(), object->alive(), pos.x, pos.y);
}
- for(auto & desc : screen->animations()) {
+ for (auto &desc : screen->animations()) {
auto &animation = desc.animation;
auto pos = animation->position();
debugPrintf("animation %s (process: %s, %s) at %d,%d,%d, frame: %d\n",
- animation->phaseVar().c_str(), animation->process().c_str(), animation->paused()? "paused": "running",
- pos.x, pos.y, animation->z(), animation->phase());
+ animation->phaseVar().c_str(), animation->process().c_str(), animation->paused() ? "paused" : "running",
+ pos.x, pos.y, animation->z(), animation->phase());
}
}
debugPrintf("processes:\n");
- auto & processes = _engine->processes();
- for(auto & process : processes) {
+ auto &processes = _engine->processes();
+ for (auto &process : processes) {
if (process)
debugPrintf("%s\n", process->getName().c_str());
}
@@ -170,7 +170,7 @@ bool Console::patch(int argc, const char **argv) {
debugPrintf("screen loading type: %d\n", static_cast<int>(patch->loadingType));
debugPrintf("character pos: %d,%d, direction: %d, present: %d\n", patch->characterPosition.x, patch->characterPosition.y, patch->characterDirection, patch->characterPresent);
debugPrintf("mouse cursor: %s\n", patch->defaultMouseCursor.c_str());
- for(auto & object: patch->objects) {
+ for (auto &object : patch->objects) {
debugPrintf(" - object %s: present: %d\n", object.name.c_str(), object.flag);
}
} else if (argc == 4) {
@@ -185,4 +185,4 @@ bool Console::patch(int argc, const char **argv) {
return true;
}
-}
+} // namespace AGDS
diff --git a/engines/agds/console.h b/engines/agds/console.h
index b09a8ea6acd..0236d9e8ad5 100644
--- a/engines/agds/console.h
+++ b/engines/agds/console.h
@@ -31,8 +31,8 @@ class AGDSEngine;
class Console : public GUI::Debugger {
public:
Console(AGDSEngine *engine);
- using GUI::Debugger::registerVar;
using GUI::Debugger::clearVars;
+ using GUI::Debugger::registerVar;
private:
bool load(int argc, const char **argv);
@@ -47,6 +47,6 @@ private:
AGDSEngine *_engine;
};
-} // End of namespace TeenAgent
+} // namespace AGDS
#endif
diff --git a/engines/agds/database.cpp b/engines/agds/database.cpp
index a85133a4908..b97736b8c1d 100644
--- a/engines/agds/database.cpp
+++ b/engines/agds/database.cpp
@@ -35,11 +35,11 @@ bool Database::open(const Common::String &filename) {
}
namespace {
- static const uint32 kMagic = 666;
- static const uint32 kHeaderFieldSize = 0x09;
- static const uint32 kHeaderSize = 0x14;
- static const uint32 kDefaultNameSize = 0x1f;
-}
+static const uint32 kMagic = 666;
+static const uint32 kHeaderFieldSize = 0x09;
+static const uint32 kHeaderSize = 0x14;
+static const uint32 kDefaultNameSize = 0x1f;
+} // namespace
uint32 Database::getDataOffset(uint32 maxNameSize, uint32 totalEntries) {
return kHeaderSize + (maxNameSize + kHeaderFieldSize) * totalEntries;
@@ -69,7 +69,7 @@ bool Database::open(const Common::String &filename, Common::SeekableReadStream &
char *z = Common::find(nameBuffer.begin(), nameBuffer.end(), 0);
Common::String name(nameBuffer.data(), z - nameBuffer.begin());
uint32 size = stream.readUint32LE();
- //debug("adb entry: %s, offset %08x, size: %u", name.c_str(), offset, size);
+ // debug("adb entry: %s, offset %08x, size: %u", name.c_str(), offset, size);
_entries.setVal(name, Entry(dataOffset + offset, size));
}
@@ -101,7 +101,7 @@ void Database::write(Common::WriteStream &stream, const Common::HashMap<Common::
}
for (auto &entry : entries) {
- auto & value = entry._value;
+ auto &value = entry._value;
stream.write(value.data(), value.size());
}
}
@@ -117,7 +117,7 @@ Common::Array<Common::String> Database::getEntries() const {
Common::SeekableReadStream *Database::getEntry(const Common::String &name) const {
Common::File file;
if (!file.open(Common::Path{_filename})) {
- error("could not open database file %s", _filename.c_str()); //previously available, but now disappeared or no fd, error
+ error("could not open database file %s", _filename.c_str()); // previously available, but now disappeared or no fd, error
return NULL;
}
diff --git a/engines/agds/database.h b/engines/agds/database.h
index c7ee7b6caff..a940d34f934 100644
--- a/engines/agds/database.h
+++ b/engines/agds/database.h
@@ -22,34 +22,33 @@
#ifndef AGDS_DATABASE_H
#define AGDS_DATABASE_H
+#include "common/hash-str.h"
+#include "common/hashmap.h"
#include "common/scummsys.h"
#include "common/str.h"
#include "common/stream.h"
-#include "common/hashmap.h"
-#include "common/hash-str.h"
namespace AGDS {
class Database {
private:
- struct Entry
- {
- uint32 offset;
- uint32 size;
+ struct Entry {
+ uint32 offset;
+ uint32 size;
- Entry(): offset(), size() { }
- Entry(uint32 o, uint32 s): offset(o), size(s) { }
+ Entry() : offset(), size() {}
+ Entry(uint32 o, uint32 s) : offset(o), size(s) {}
};
using EntriesType = Common::HashMap<Common::String, Entry>;
- Common::String _filename;
- bool _writeable;
- uint32 _totalEntries;
- uint32 _usedEntries;
- uint32 _maxNameSize;
+ Common::String _filename;
+ bool _writeable;
+ uint32 _totalEntries;
+ uint32 _usedEntries;
+ uint32 _maxNameSize;
- EntriesType _entries;
+ EntriesType _entries;
private:
static uint32 getDataOffset(uint32 maxNameSize, uint32 totalEntries);
@@ -62,10 +61,9 @@ public:
Common::SeekableReadStream *getEntry(const Common::String &name) const;
Common::SeekableReadStream *getEntry(Common::SeekableReadStream &parent, const Common::String &name) const;
- static void write(Common::WriteStream &stream, const Common::HashMap<Common::String, Common::Array<uint8>> & entries);
+ static void write(Common::WriteStream &stream, const Common::HashMap<Common::String, Common::Array<uint8>> &entries);
};
-
} // End of namespace AGDS
#endif /* AGDS_DATABASE_H */
diff --git a/engines/agds/detection.cpp b/engines/agds/detection.cpp
index 22273a7fa12..db0dd98bf48 100644
--- a/engines/agds/detection.cpp
+++ b/engines/agds/detection.cpp
@@ -22,9 +22,9 @@
#include "engines/advancedDetector.h"
static const PlainGameDescriptor agdsGames[] = {
- {"nibiru", "NiBiRu: Age of Secrets"},
- {"black-mirror", "Black Mirror"},
- {0, 0}};
+ {"nibiru", "NiBiRu: Age of Secrets"},
+ {"black-mirror", "Black Mirror"},
+ {0, 0}};
#include "agds/detection_tables.h"
diff --git a/engines/agds/detection_tables.h b/engines/agds/detection_tables.h
index db2a1eef3e0..04e6f7e5faf 100644
--- a/engines/agds/detection_tables.h
+++ b/engines/agds/detection_tables.h
@@ -33,29 +33,23 @@ static const ADGameDescription gameDescriptions[] = {
Common::EN_USA,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
- GUIO1(GUIO_NONE)
- },
- {
- "black-mirror",
- 0,
- AD_ENTRY1s("gfx1.grp", "652f931f02c5a79fb9bcbe32abafbdf7", 907732355),
- Common::RU_RUS,
- Common::kPlatformWindows,
- ADGF_DROPPLATFORM,
- GUIO1(GUIO_NONE)
- },
+ GUIO1(GUIO_NONE)},
+ {"black-mirror",
+ 0,
+ AD_ENTRY1s("gfx1.grp", "652f931f02c5a79fb9bcbe32abafbdf7", 907732355),
+ Common::RU_RUS,
+ Common::kPlatformWindows,
+ ADGF_DROPPLATFORM,
+ GUIO1(GUIO_NONE)},
- {
- "nibiru",
- 0,
- AD_ENTRY1s("gfx1.grp", "c8e711bc01b16cd82849cbd996d02642", 381768360),
- Common::RU_RUS,
- Common::kPlatformWindows,
- ADGF_DROPPLATFORM | AGDS_V2 | ADGF_UNSUPPORTED,
- GUIO1(GUIO_NONE)
- },
+ {"nibiru",
+ 0,
+ AD_ENTRY1s("gfx1.grp", "c8e711bc01b16cd82849cbd996d02642", 381768360),
+ Common::RU_RUS,
+ Common::kPlatformWindows,
+ ADGF_DROPPLATFORM | AGDS_V2 | ADGF_UNSUPPORTED,
+ GUIO1(GUIO_NONE)},
- AD_TABLE_END_MARKER
-};
+ AD_TABLE_END_MARKER};
} // End of namespace AGDS
diff --git a/engines/agds/dialog.cpp b/engines/agds/dialog.cpp
index 553986bab31..7d5521c586e 100644
--- a/engines/agds/dialog.cpp
+++ b/engines/agds/dialog.cpp
@@ -21,8 +21,8 @@
#include "agds/dialog.h"
#include "agds/agds.h"
-#include "agds/systemVariable.h"
#include "agds/object.h"
+#include "agds/systemVariable.h"
#include "common/debug.h"
namespace AGDS {
@@ -38,7 +38,7 @@ void Dialog::parseDialogDefs(const Common::String &defs) {
} else if (ch == '\n' || ch == '\r' || p + 1 == size) {
if (p + 1 == size)
value += ch;
- //debug("dialog definition: '%s' = '%s'", name.c_str(), value.c_str());
+ // debug("dialog definition: '%s' = '%s'", name.c_str(), value.c_str());
if (!name.empty() && !value.empty()) {
_dialogDefs[name] = atoi(value.c_str());
}
@@ -83,18 +83,16 @@ int Dialog::textDelay(const Common::String &str) {
if (delay < 20)
delay = 20;
- //this looks like an error in original code
- //original first value in this table is 0x0FFFFFEB4 (-332)
- //0x0FFFFFEB4 * 20 and then 16-to-32 conversion gives 0xffffe610
- // 0xe610 / 20 = 2944
+ // this looks like an error in original code
+ // original first value in this table is 0x0FFFFFEB4 (-332)
+ // 0x0FFFFFEB4 * 20 and then 16-to-32 conversion gives 0xffffe610
+ // 0xe610 / 20 = 2944
static const int delays[] = {
2944, 631, 398, 251, 158,
- 100, 63, 40, 25, 16, 10
- };
+ 100, 63, 40, 25, 16, 10};
return delays[speed] * delay / 41 + 1;
}
-
bool Dialog::tick() {
if (_dialogProcessName.empty())
return false;
@@ -182,7 +180,7 @@ void Dialog::processSoundDirective(const Common::String &line) {
while (line[comma1] == ' ')
++comma1;
Common::String sample = line.substr(comma1, comma2 - comma1);
- while(line[comma2] == ' ')
+ while (line[comma2] == ' ')
++comma2;
Common::String step = line.substr(comma2 + 1, end - comma2);
debug("sound args = %s,%s,%s", name.c_str(), sample.c_str(), step.c_str());
@@ -250,4 +248,4 @@ Common::String Dialog::getNextDialogSound() {
return currentSample + ".ogg";
}
-}
+} // namespace AGDS
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
index 2a67a703e64..d570e2e516e 100644
--- a/engines/agds/dialog.h
+++ b/engines/agds/dialog.h
@@ -22,9 +22,9 @@
#ifndef AGDS_DIALOG_H
#define AGDS_DIALOG_H
-#include "common/scummsys.h"
#include "common/hash-str.h"
#include "common/hashmap.h"
+#include "common/scummsys.h"
#include "common/str.h"
namespace AGDS {
@@ -39,43 +39,43 @@ private:
Common::String Sample;
int Step;
- Sound(): Step(1) {
+ Sound() : Step(1) {
}
- Sound(const Common::String &name, const Common::String &sample, int step): Name(name), Sample(sample), Step(step) {
+ Sound(const Common::String &name, const Common::String &sample, int step) : Name(name), Sample(sample), Step(step) {
}
};
using SoundsType = Common::Array<Sound>;
- AGDSEngine *_engine;
- DialogDefsType _dialogDefs;
- Common::String _dialogScript;
- uint32 _dialogScriptPos;
- Common::String _dialogProcessName;
- Common::String _dialogLine;
+ AGDSEngine *_engine;
+ DialogDefsType _dialogDefs;
+ Common::String _dialogScript;
+ uint32 _dialogScriptPos;
+ Common::String _dialogProcessName;
+ Common::String _dialogLine;
- SoundsType _sounds;
- Common::String _currentDef;
- int _currentSoundIndex;
+ SoundsType _sounds;
+ Common::String _currentDef;
+ int _currentSoundIndex;
void parseDialogDefs(const Common::String &defs);
public:
- Dialog(AGDSEngine *engine): _engine(engine), _dialogScriptPos(0), _currentSoundIndex(-1) { }
+ Dialog(AGDSEngine *engine) : _engine(engine), _dialogScriptPos(0), _currentSoundIndex(-1) {}
int textDelay(const Common::String &str);
const Common::String &getNextDialogLine() const {
return _dialogLine;
}
Common::String getNextDialogSound();
- void load(const Common::String &processName, const Common::String &dialogScript, const Common::String & defs);
+ void load(const Common::String &processName, const Common::String &dialogScript, const Common::String &defs);
bool tick();
+
private:
void processSoundDirective(const Common::String &line);
void processDirective(Common::String line);
};
-
} // End of namespace AGDS
#endif /* AGDS_DIALOG_H */
diff --git a/engines/agds/font.cpp b/engines/agds/font.cpp
index bd25299642e..243b23a28a6 100644
--- a/engines/agds/font.cpp
+++ b/engines/agds/font.cpp
@@ -25,10 +25,10 @@
namespace AGDS {
Font::Font(Graphics::ManagedSurface *surface, int gw, int gh) : _surface(surface),
- _glyphW(gw), _glyphH(gh),
- _cellW(surface->w / 16), _cellH(surface->h / 16) {
+ _glyphW(gw), _glyphH(gh),
+ _cellW(surface->w / 16), _cellH(surface->h / 16) {
- //debug("surface cell %dx%d", _cellW, _cellH);
+ // debug("surface cell %dx%d", _cellW, _cellH);
for (int y = 0; y < 16; ++y) {
for (int x = 0; x < 16; ++x) {
const uint32 *pixels = static_cast<uint32 *>(_surface->getBasePtr(x * _cellW, y * _cellH));
@@ -36,10 +36,10 @@ Font::Font(Graphics::ManagedSurface *surface, int gw, int gh) : _surface(surface
int ch = (y << 4) | x;
for (w = 0; w <= _glyphW; ++w, ++pixels) {
uint8 r, g, b, a;
- //debug("%d color #%08x", ch, *pixels);
+ // debug("%d color #%08x", ch, *pixels);
surface->format.colorToARGB(*pixels, r, g, b, a);
- //debug("%d %d %d %d", r, g, b, a);
- if (r == 0) //fixme: mapped incorrectly
+ // debug("%d %d %d %d", r, g, b, a);
+ if (r == 0) // fixme: mapped incorrectly
break;
}
_width[ch] = w;
diff --git a/engines/agds/font.h b/engines/agds/font.h
index 05ff8eab924..63d44b6fab4 100644
--- a/engines/agds/font.h
+++ b/engines/agds/font.h
@@ -22,20 +22,20 @@
#ifndef AGDS_FONT_H
#define AGDS_FONT_H
-#include "graphics/font.h"
#include "common/ptr.h"
+#include "graphics/font.h"
namespace Graphics {
- class ManagedSurface;
+class ManagedSurface;
}
namespace AGDS {
class Font : public Graphics::Font {
Common::ScopedPtr<Graphics::ManagedSurface> _surface;
- int _glyphW, _glyphH;
- int _cellW, _cellH;
- uint8 _width[0x100];
+ int _glyphW, _glyphH;
+ int _cellW, _cellH;
+ uint8 _width[0x100];
public:
Font(Graphics::ManagedSurface *surface, int gw, int gh);
@@ -49,11 +49,10 @@ public:
}
virtual int getCharWidth(uint32 chr) const {
- return chr < 0x100? _width[chr]: 0;
+ return chr < 0x100 ? _width[chr] : 0;
}
virtual void drawChar(Graphics::Surface *dst, uint32 chr, int x, int y, uint32 color) const;
-
};
} // End of namespace AGDS
diff --git a/engines/agds/inventory.cpp b/engines/agds/inventory.cpp
index 5c9106ff623..45292fcd2ba 100644
--- a/engines/agds/inventory.cpp
+++ b/engines/agds/inventory.cpp
@@ -20,9 +20,9 @@
*/
#include "agds/inventory.h"
+#include "agds/agds.h"
#include "agds/object.h"
#include "agds/resourceManager.h"
-#include "agds/agds.h"
#include "agds/systemVariable.h"
#include "common/debug.h"
#include "common/textconsole.h"
@@ -30,7 +30,7 @@
namespace AGDS {
-Inventory::Inventory(AGDSEngine *engine): _engine(engine), _entries(kMaxSize), _enabled(false), _visible(false) {}
+Inventory::Inventory(AGDSEngine *engine) : _engine(engine), _entries(kMaxSize), _enabled(false), _visible(false) {}
Inventory::~Inventory() {}
void Inventory::visible(bool visible) {
@@ -184,7 +184,7 @@ void Inventory::clear() {
}
}
-void Inventory::load(Common::ReadStream& stream) {
+void Inventory::load(Common::ReadStream &stream) {
clear();
for (int i = 0; i < kMaxSize; ++i) {
Common::String name = readString(stream);
@@ -192,14 +192,14 @@ void Inventory::load(Common::ReadStream& stream) {
int objectPtr = stream.readUint32LE();
if (!name.empty() && refcount) {
debug("load inventory object: %s %d %d", name.c_str(), refcount, objectPtr);
- auto & entry = _entries[i];
+ auto &entry = _entries[i];
entry.name = name;
entry.hasObject = true;
}
}
}
-void Inventory::save(Common::WriteStream& stream) const {
+void Inventory::save(Common::WriteStream &stream) const {
for (const auto &entry : _entries) {
writeString(stream, entry.name);
stream.writeUint32LE(entry.hasObject ? 1 : 0);
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index d893723b6f3..5f282ece839 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -22,13 +22,16 @@
#ifndef AGDS_INVENTORY_H
#define AGDS_INVENTORY_H
-#include "common/scummsys.h"
#include "common/array.h"
#include "common/ptr.h"
#include "common/rect.h"
+#include "common/scummsys.h"
#include "common/str.h"
-namespace Common { class ReadStream; class WriteStream; }
+namespace Common {
+class ReadStream;
+class WriteStream;
+} // namespace Common
namespace AGDS {
class Object;
@@ -95,10 +98,8 @@ public:
uint maxSize() const {
return _entries.size();
}
-
};
-
} // End of namespace AGDS
#endif /* AGDS_INVENTORY_H */
diff --git a/engines/agds/metaengine.cpp b/engines/agds/metaengine.cpp
index ade0e88f9cb..3faa013e82e 100644
--- a/engines/agds/metaengine.cpp
+++ b/engines/agds/metaengine.cpp
@@ -83,10 +83,10 @@ Common::Error AGDSMetaEngine::createInstance(OSystem *syst, Engine **engine, con
return Common::Error(Common::kNoError);
}
-}
+} // namespace AGDS
#if PLUGIN_ENABLED_DYNAMIC(AGDS)
- REGISTER_PLUGIN_DYNAMIC(AGDS, PLUGIN_TYPE_ENGINE, AGDS::AGDSMetaEngine);
+REGISTER_PLUGIN_DYNAMIC(AGDS, PLUGIN_TYPE_ENGINE, AGDS::AGDSMetaEngine);
#else
- REGISTER_PLUGIN_STATIC(AGDS, PLUGIN_TYPE_ENGINE, AGDS::AGDSMetaEngine);
+REGISTER_PLUGIN_STATIC(AGDS, PLUGIN_TYPE_ENGINE, AGDS::AGDSMetaEngine);
#endif
diff --git a/engines/agds/mjpgPlayer.cpp b/engines/agds/mjpgPlayer.cpp
index 0beef802ee9..6714982b40b 100644
--- a/engines/agds/mjpgPlayer.cpp
+++ b/engines/agds/mjpgPlayer.cpp
@@ -28,8 +28,7 @@
namespace AGDS {
-MJPGPlayer::MJPGPlayer(Common::SeekableReadStream *stream, const Common::String &subtitles) :
- _stream(stream), _firstFramePos(_stream->pos()), _framesPlayed(0), _nextSubtitleIndex(0) {
+MJPGPlayer::MJPGPlayer(Common::SeekableReadStream *stream, const Common::String &subtitles) : _stream(stream), _firstFramePos(_stream->pos()), _framesPlayed(0), _nextSubtitleIndex(0) {
uint pos = 0;
while (pos < subtitles.size()) {
auto next = subtitles.find('\n', pos);
@@ -138,5 +137,4 @@ void MJPGPlayer::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
}
}
-
} // namespace AGDS
diff --git a/engines/agds/mjpgPlayer.h b/engines/agds/mjpgPlayer.h
index 9e196f91e0e..31d1ad574b4 100644
--- a/engines/agds/mjpgPlayer.h
+++ b/engines/agds/mjpgPlayer.h
@@ -22,10 +22,10 @@
#ifndef AGDS_MJPG_PLAYER_H
#define AGDS_MJPG_PLAYER_H
-#include "common/scummsys.h"
#include "common/array.h"
-#include "common/stream.h"
+#include "common/scummsys.h"
#include "common/str.h"
+#include "common/stream.h"
#include "graphics/surface.h"
#include "image/jpeg.h"
@@ -34,24 +34,24 @@ namespace AGDS {
class AGDSEngine;
class MJPGPlayer {
using StreamPtr = Common::ScopedPtr<Common::SeekableReadStream>;
- StreamPtr _stream;
- int32 _firstFramePos;
- Image::JPEGDecoder _decoder;
- uint _framesPlayed;
+ StreamPtr _stream;
+ int32 _firstFramePos;
+ Image::JPEGDecoder _decoder;
+ uint _framesPlayed;
struct Text {
using Lines = Common::Array<Common::String>;
- uint begin;
- uint end;
- Lines lines;
+ uint begin;
+ uint end;
+ Lines lines;
};
- Common::Array<Text> _subtitles;
- uint _nextSubtitleIndex;
+ Common::Array<Text> _subtitles;
+ uint _nextSubtitleIndex;
public:
- MJPGPlayer(Common::SeekableReadStream * stream, const Common::String &subtitles);
+ MJPGPlayer(Common::SeekableReadStream *stream, const Common::String &subtitles);
~MJPGPlayer();
bool eos() {
@@ -67,7 +67,6 @@ public:
}
};
-
} // End of namespace AGDS
#endif /* AGDS_MJPG_PLAYER_H */
diff --git a/engines/agds/mouseMap.cpp b/engines/agds/mouseMap.cpp
index 15fde872725..a9de5bca76f 100644
--- a/engines/agds/mouseMap.cpp
+++ b/engines/agds/mouseMap.cpp
@@ -21,32 +21,31 @@
#include "agds/mouseMap.h"
#include "agds/agds.h"
-#include "agds/region.h"
#include "agds/object.h"
+#include "agds/region.h"
#include <utility>
namespace AGDS {
int MouseMap::findFree() const {
- for(int i = 0, n = _mouseRegions.size(); i != n; ++i) {
- auto & region = _mouseRegions[i];
+ for (int i = 0, n = _mouseRegions.size(); i != n; ++i) {
+ auto ®ion = _mouseRegions[i];
if (!region)
return i;
}
error("no mouse region available");
}
-
int MouseMap::add(MouseRegion area) {
auto id = findFree();
- auto & region = _mouseRegions[id];
+ auto ®ion = _mouseRegions[id];
region.reset(new MouseRegion(std::move(area)));
region->id = id;
return id;
}
void MouseMap::hideInactive(AGDSEngine *engine, Common::Point pos) {
- for (auto & region : _mouseRegions) {
+ for (auto ®ion : _mouseRegions) {
if (!region || !region->enabled)
continue;
@@ -64,7 +63,7 @@ void MouseMap::hideInactive(AGDSEngine *engine, Common::Point pos) {
}
MouseRegion *MouseMap::find(int id) {
- for (auto & region : _mouseRegions) {
+ for (auto ®ion : _mouseRegions) {
if (region && region->id == id)
return region.get();
}
@@ -100,7 +99,7 @@ void MouseRegion::hide(AGDSEngine *engine) {
}
void MouseMap::hideAll(AGDSEngine *engine) {
- for (auto & region : _mouseRegions)
+ for (auto ®ion : _mouseRegions)
if (region)
region->hide(engine);
}
diff --git a/engines/agds/mouseMap.h b/engines/agds/mouseMap.h
index f5b775c6445..3a63d065c62 100644
--- a/engines/agds/mouseMap.h
+++ b/engines/agds/mouseMap.h
@@ -34,10 +34,10 @@ struct Region;
using RegionPtr = Common::SharedPtr<Region>;
struct MouseRegion {
- int id = -1;
- RegionPtr region = nullptr;
- bool enabled = true;
- bool visible = false;
+ int id = -1;
+ RegionPtr region = nullptr;
+ bool enabled = true;
+ bool visible = false;
Common::String onEnter;
Common::String onLeave;
@@ -50,24 +50,22 @@ struct MouseRegion {
enabled = false;
}
- MouseRegion()
- { }
+ MouseRegion() {}
- MouseRegion(RegionPtr reg, const Common::String &enter, const Common::String &leave):
- region(reg), onEnter(enter), onLeave(leave) {
+ MouseRegion(RegionPtr reg, const Common::String &enter, const Common::String &leave) : region(reg), onEnter(enter), onLeave(leave) {
}
- void hide(AGDSEngine * engine);
- void show(AGDSEngine * engine);
+ void hide(AGDSEngine *engine);
+ void show(AGDSEngine *engine);
};
using MouseRegionPtr = Common::ScopedPtr<MouseRegion>;
class MouseMap {
- Common::Array<MouseRegionPtr> _mouseRegions;
- bool _disabled;
+ Common::Array<MouseRegionPtr> _mouseRegions;
+ bool _disabled;
public:
- MouseMap(): _mouseRegions(100), _disabled(false) { }
+ MouseMap() : _mouseRegions(100), _disabled(false) {}
void disable(bool disabled) {
_disabled = disabled;
diff --git a/engines/agds/object.cpp b/engines/agds/object.cpp
index b742959bf25..b6accc550e6 100644
--- a/engines/agds/object.cpp
+++ b/engines/agds/object.cpp
@@ -28,22 +28,21 @@
#include "common/debug.h"
#include "common/memstream.h"
#include "common/rect.h"
-#include "graphics/surface.h"
#include "graphics/managed_surface.h"
+#include "graphics/surface.h"
namespace AGDS {
-Object::Object(const Common::String &name, Common::SeekableReadStream &stream, bool v2) :
- _name(name), _stringTableLoaded(false),
- _picture(), _rotatedPicture(), _region(),
- _animation(), _mouseCursor(),
- _pos(), _z(10), _rotation(0),
- _clickHandler(0), _examineHandler(0), _userUseHandler(0),
- _throwHandler(0), _useOnHandler(0),
- _handlerBD(0), _handlerC1(0),
- _alpha(255), _scale(100), _locked(0), _alive(true),
- _persistent(true), _allowInitialise(true),
- _ignoreRegion(false), _v2(v2) {
+Object::Object(const Common::String &name, Common::SeekableReadStream &stream, bool v2) : _name(name), _stringTableLoaded(false),
+ _picture(), _rotatedPicture(), _region(),
+ _animation(), _mouseCursor(),
+ _pos(), _z(10), _rotation(0),
+ _clickHandler(0), _examineHandler(0), _userUseHandler(0),
+ _throwHandler(0), _useOnHandler(0),
+ _handlerBD(0), _handlerC1(0),
+ _alpha(255), _scale(100), _locked(0), _alive(true),
+ _persistent(true), _allowInitialise(true),
+ _ignoreRegion(false), _v2(v2) {
uint16 id = stream.readUint16LE();
debug("id: 0x%02x %u", id, id);
@@ -93,7 +92,7 @@ void Object::readStringTable(unsigned resOffset, uint16 resCount) {
if (_stringTableLoaded)
return;
- resOffset += 5 /*instruction*/ + (_v2? 0x13: 0x11) /*another header*/;
+ resOffset += 5 /*instruction*/ + (_v2 ? 0x13 : 0x11) /*another header*/;
if (resOffset >= _code.size())
error("invalid resource table offset %u/%u", resOffset, _code.size());
@@ -196,7 +195,6 @@ void Object::alive(bool value) {
_region.reset();
}
-
void Object::region(RegionPtr region) {
_region = region;
}
@@ -256,7 +254,6 @@ bool Object::pointIn(Common::Point pos) {
if (_trapRegion && _trapRegion->pointIn(pos))
return true;
-
if (!_ignoreRegion && _region && _region->pointIn(pos))
return true;
diff --git a/engines/agds/object.h b/engines/agds/object.h
index 45988367c81..f68daf88b91 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -22,15 +22,18 @@
#ifndef AGDS_OBJECT_H
#define AGDS_OBJECT_H
-#include "common/scummsys.h"
#include "common/array.h"
#include "common/hash-str.h"
#include "common/hashmap.h"
#include "common/ptr.h"
#include "common/rect.h"
+#include "common/scummsys.h"
#include "common/stream.h"
-namespace Graphics { struct Surface; class ManagedSurface; }
+namespace Graphics {
+struct Surface;
+class ManagedSurface;
+} // namespace Graphics
namespace AGDS {
@@ -45,54 +48,54 @@ public:
using CodeType = Common::Array<uint8>;
struct StringEntry {
- Common::String string;
- uint16 flags;
+ Common::String string;
+ uint16 flags;
- StringEntry(): string(), flags() { }
- StringEntry(const Common::String &s, uint16 f): string(s), flags(f) { }
+ StringEntry() : string(), flags() {}
+ StringEntry(const Common::String &s, uint16 f) : string(s), flags(f) {}
};
private:
- using StringTableType = Common::Array<StringEntry> ;
- using KeyHandlersType = Common::HashMap<Common::String, uint, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
- using UseHandlersType = Common::HashMap<Common::String, uint>;
- using ManagedSurfacePtr = Common::ScopedPtr<Graphics::ManagedSurface>;
-
- Common::String _name;
- CodeType _code;
- StringTableType _stringTable;
- bool _stringTableLoaded;
- KeyHandlersType _keyHandlers;
- UseHandlersType _useHandlers;
- ManagedSurfacePtr _picture;
- ManagedSurfacePtr _rotatedPicture;
- RegionPtr _region;
- RegionPtr _trapRegion;
- AnimationPtr _animation;
- AnimationPtr _mouseCursor;
- Common::Point _pos, _animationPos, _offset;
- Common::Point _regionOffset;
- Common::Rect _srcRect;
- int _z;
- int _rotation;
- Common::String _text;
- Common::String _title;
- uint _clickHandler;
- uint _examineHandler;
- uint _userUseHandler;
- uint _throwHandler;
- uint _useOnHandler;
- uint _trapHandler;
- uint _handlerBD;
- uint _handlerC1;
- int _alpha;
- int _scale;
- uint _locked;
- bool _alive;
- bool _persistent;
- bool _allowInitialise;
- bool _ignoreRegion;
- bool _v2;
+ using StringTableType = Common::Array<StringEntry>;
+ using KeyHandlersType = Common::HashMap<Common::String, uint, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
+ using UseHandlersType = Common::HashMap<Common::String, uint>;
+ using ManagedSurfacePtr = Common::ScopedPtr<Graphics::ManagedSurface>;
+
+ Common::String _name;
+ CodeType _code;
+ StringTableType _stringTable;
+ bool _stringTableLoaded;
+ KeyHandlersType _keyHandlers;
+ UseHandlersType _useHandlers;
+ ManagedSurfacePtr _picture;
+ ManagedSurfacePtr _rotatedPicture;
+ RegionPtr _region;
+ RegionPtr _trapRegion;
+ AnimationPtr _animation;
+ AnimationPtr _mouseCursor;
+ Common::Point _pos, _animationPos, _offset;
+ Common::Point _regionOffset;
+ Common::Rect _srcRect;
+ int _z;
+ int _rotation;
+ Common::String _text;
+ Common::String _title;
+ uint _clickHandler;
+ uint _examineHandler;
+ uint _userUseHandler;
+ uint _throwHandler;
+ uint _useOnHandler;
+ uint _trapHandler;
+ uint _handlerBD;
+ uint _handlerC1;
+ int _alpha;
+ int _scale;
+ uint _locked;
+ bool _alive;
+ bool _persistent;
+ bool _allowInitialise;
+ bool _ignoreRegion;
+ bool _v2;
private:
void freeRotated();
@@ -126,13 +129,11 @@ public:
void readStringTable(unsigned resOffset, uint16 resCount);
const StringEntry &getString(uint16 index) const;
- uint getStringTableSize() const
- { return _stringTable.size(); }
+ uint getStringTableSize() const { return _stringTable.size(); }
- const Common::String &getName() const
- { return _name; }
+ const Common::String &getName() const { return _name; }
- const CodeType & getCode() const {
+ const CodeType &getCode() const {
return _code;
}
@@ -140,7 +141,7 @@ public:
_animation = animation;
}
- const AnimationPtr & getAnimation() const {
+ const AnimationPtr &getAnimation() const {
return _animation;
}
@@ -222,7 +223,7 @@ public:
}
uint getUseHandler(const Common::String &name) const {
- return _useHandlers.getValOrDefault(name, 0); //use handler can never be 0
+ return _useHandlers.getValOrDefault(name, 0); // use handler can never be 0
}
void setUserUseHandler(uint ip) {
@@ -310,7 +311,7 @@ public:
uint getKeyHandler(const Common::String &name) const {
KeyHandlersType::const_iterator i = _keyHandlers.find(name);
- return i != _keyHandlers.end()? i->_value: 0;
+ return i != _keyHandlers.end() ? i->_value : 0;
}
uint throwHandler() const {
@@ -337,7 +338,6 @@ public:
};
using ObjectPtr = Common::SharedPtr<Object>;
-
} // End of namespace AGDS
#endif /* AGDS_OBJECT_H */
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 7ad9f674913..bcec7c6b99b 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -27,461 +27,461 @@
namespace AGDS {
enum Opcode : uint8 {
- kEnter = 5,
- kJumpZImm16 = 8,
- kJumpImm16 = 9,
- kPop = 10,
- kDup = 11,
- kExitProcess = 12,
- kSuspendProcess = 13,
- kPushImm32 = 14,
- kPushImm16 = 15,
- kPushImm8 = 16,
- kPushImm16_2 = 17,
- kPushImm8_2 = 18,
- kStub19 = 19,
- kStub20 = 20,
- kGetGlobalImm8 = 21,
- kEquals = 22,
- kNotEquals = 23,
- kGreater = 24,
- kLess = 25,
- kGreaterOrEquals = 26,
- kLessOrEquals = 27,
- kAdd = 28,
- kSub = 29,
- kMul = 30,
- kDiv = 31,
- kMod = 32,
- kAnd = 33,
- kOr = 34,
- kXor = 35,
- kNot = 36,
- kShl = 37,
- kShr = 38,
- kBoolAnd = 39,
- kBoolOr = 40,
- kBoolNot = 41,
- kNegate = 42,
- kPreIncrementGlobal = 43,
- kPreDecrementGlobal = 44,
- kPostIncrementGlobal = 45,
- kPostDecrementGlobal = 46,
- kSetGlobalWithTop = 47,
- kSetGlobal = 48,
- kIncrementGlobalByTop = 49,
- kDecrementGlobalByTop = 50,
- kMultiplyGlobalByTop = 51,
- kDivideGlobalByTop = 52,
- kModGlobalByTop = 53,
- kShlGlobalByTop = 54,
- kShrGlobalByTop = 55,
- kAndGlobalByTop = 56,
- kOrGlobalByTop = 57,
- kXorGlobalByTop = 58,
- kObjectInitialise = 59,
- kObjectRegisterLookHandler = 60,
- kObjectRegisterUseHandler = 61,
- kObjectRegisterHandlerC1 = 62,
+ kEnter = 5,
+ kJumpZImm16 = 8,
+ kJumpImm16 = 9,
+ kPop = 10,
+ kDup = 11,
+ kExitProcess = 12,
+ kSuspendProcess = 13,
+ kPushImm32 = 14,
+ kPushImm16 = 15,
+ kPushImm8 = 16,
+ kPushImm16_2 = 17,
+ kPushImm8_2 = 18,
+ kStub19 = 19,
+ kStub20 = 20,
+ kGetGlobalImm8 = 21,
+ kEquals = 22,
+ kNotEquals = 23,
+ kGreater = 24,
+ kLess = 25,
+ kGreaterOrEquals = 26,
+ kLessOrEquals = 27,
+ kAdd = 28,
+ kSub = 29,
+ kMul = 30,
+ kDiv = 31,
+ kMod = 32,
+ kAnd = 33,
+ kOr = 34,
+ kXor = 35,
+ kNot = 36,
+ kShl = 37,
+ kShr = 38,
+ kBoolAnd = 39,
+ kBoolOr = 40,
+ kBoolNot = 41,
+ kNegate = 42,
+ kPreIncrementGlobal = 43,
+ kPreDecrementGlobal = 44,
+ kPostIncrementGlobal = 45,
+ kPostDecrementGlobal = 46,
+ kSetGlobalWithTop = 47,
+ kSetGlobal = 48,
+ kIncrementGlobalByTop = 49,
+ kDecrementGlobalByTop = 50,
+ kMultiplyGlobalByTop = 51,
+ kDivideGlobalByTop = 52,
+ kModGlobalByTop = 53,
+ kShlGlobalByTop = 54,
+ kShrGlobalByTop = 55,
+ kAndGlobalByTop = 56,
+ kOrGlobalByTop = 57,
+ kXorGlobalByTop = 58,
+ kObjectInitialise = 59,
+ kObjectRegisterLookHandler = 60,
+ kObjectRegisterUseHandler = 61,
+ kObjectRegisterHandlerC1 = 62,
kObjectRegisterUseObjectHandler = 63,
- kObjectRegisterHandlerBD = 64,
- kObjectRegisterCharacterTrap = 65,
- kLoadMouseCursorFromObject = 66,
- kLoadRegionFromObject = 68,
- kLoadPictureFromObject = 69,
- kLoadAnimationFromObject = 70,
- kSetObjectZ = 71,
- kSetScreenBackground = 72,
- kLoadTextFromObject = 73,
- kScreenSetZNearFar = 74,
- kScreenLoadRegion = 75,
- kScreenLoadObject = 76,
- kScreenCloneObject = 77,
- kScreenRemoveObject = 78,
- kSetNextScreen = 79,
- kSetNextScreenSaveOrLoad = 80,
- kObjectPatchSetText = 82,
- kObjectPatchSetRegionName = 83,
- kScreenPatchSetRegionName = 84,
- kLoadCharacter = 85,
- kUnloadCharacter = 86,
- kAssociateCharacter = 87,
- kAnimateCharacter = 88,
- kHideCharacter = 89,
- kShowCharacter = 90,
- kDisableCharacter = 91,
- kEnableCharacter = 92,
- kMoveCharacterUserMove = 93,
- kLeaveCharacter = 94,
- kSetCharacter = 95,
- kSetCharacterDirection = 96,
- kPointCharacter = 97,
- kDisableUser = 98,
- kEnableUser = 99,
- kRestartSample = 100,
- kStopSample = 101,
- kStub102 = 102,
- kStub103 = 103,
- kStub104 = 104,
- kClearScreen = 105,
- kInventoryClear = 106,
- kStub107 = 107,
- kLoadMouse = 108,
- kAttachInventoryObjectToMouse0 = 109,
- kResetMousePointer = 110,
- kInventoryAddObject = 111,
- kInventoryRemoveObject = 112,
- kStub113 = 113,
- kStub114 = 114,
- kStub115 = 115,
- kStub116 = 116,
- kLoadAnimation = 117,
- kLoadSample = 118,
- kSetPhaseVarControlledFlag = 119,
- kPlayerSay120 = 120,
- kStub121 = 121,
- kPlayerSay122 = 122,
- kNPCSayNoSound = 123,
- kNPCSay = 124,
- kPlayerSay125 = 125,
- kStub126 = 126,
- kSetTimer = 127,
- kProcessResetState = 128,
- kSetAnimationZ = 129,
- kSetCycles = 130,
- kSetRandom = 131,
- kSetPeriodic = 132,
- kSetPanAndVolume = 133,
- kSetAnimationPosition = 134,
- kSetPhaseVar = 135,
- kSetAnimationLoop = 136,
- kSetAnimationSpeed = 137,
- kScreenObjectPatchIncRef = 138,
- kScreenObjectPatchDecRef = 139,
- kScreenCheckScreenPatch = 140,
- kGetFreeInventorySpace = 141,
- kSetStringSystemVariable = 142,
- kSetSystemIntegerVariable = 143,
- kGetSavedMouseX = 144,
- kGetSavedMouseY = 145,
- kGetRegionCenterX = 146,
- kGetRegionCenterY = 147,
- kGetCharacterAnimationPhase = 148,
- kGetCharacterX = 149,
- kGetCharacterY = 150,
- kCompareScreenName = 151,
- kGetPictureBaseX = 152,
- kGetPictureBaseY = 153,
- kGetObjectSurfaceX = 154,
- kGetObjectSurfaceY = 155,
- kLoadGame = 156,
- kSaveGame = 157,
- kQuit = 158,
- kStartNewGame = 159,
- kLoadSaveSlotNamePicture = 160,
- kGetSaveGameName = 161,
- kDisableInventory = 162,
- kEnableInventory = 163,
- kLoadPreviousScreen = 164,
- kMoveScreenObject = 165,
- kSetObjectRegionOffset = 166,
- kReturnCurrentInventoryObject = 167,
- kStub168 = 168,
- kGetIntegerSystemVariable = 169,
- kSetDelay = 170,
- kGetRandomNumber = 171,
- kSetSampleVolume = 172,
- kStub173 = 173,
- kStub174 = 174,
- kAppendToSharedStorage = 175,
- kCloneName = 176,
- kAppendNameToSharedStorage = 177,
- kGetCloneVar = 178,
- kSetCloneVar = 179,
- kGetObjectId = 180,
- kStub181 = 181,
- kSetTileSize = 182,
- kGenerateRegion = 183,
- kSetObjectTile = 184,
- kGetMaxInventorySize = 185,
- kInventoryHasObject = 186,
- kAppendInventoryObjectNameToSharedSpace = 187,
- kSetObjectText = 188,
- kInventoryFindObjectByName = 189,
- kSetObjectScale = 190,
- kDisableMouseAreas = 191,
- kObjectIgnoreRegion = 192,
- kRemoveGapsFromInventory = 193,
- kSampleAmbient = 194,
- kGetObjectPictureWidth = 195,
- kGetObjectPictureHeight = 196,
- kSetRotation = 197,
- kLoadPicture = 198,
- kStub199 = 199,
- kSetTileIndex = 200,
- kSetThrowHandler = 201,
- kSetUseOnHandler = 202,
- kPlayFilm = 203,
- kStub204 = 204,
- kAddMouseArea = 205,
- kModifyMouseArea = 206,
- kSetRain = 207,
- kFogOnCharacter = 208,
- kObjectRegisterUserUseHandler = 209,
- kStub210 = 210,
- kStub211 = 211,
- kSetSampleVolumeAndPan = 212,
- kStub213 = 213,
- kAddSampleToSoundGroup = 214,
- kClearSoundGroup = 215,
- kStub216 = 216,
- kStub217 = 217,
- kSetRainDensity = 218,
- kLeaveCharacterEx = 219,
- kStopCharacter = 220,
- kRestartAnimation = 221,
- kSignalAnimationEnd = 222,
- kSetShadowIntensity = 223,
- kSetNPCTellNotifyVar = 224,
- kPauseAnimation = 225,
- kFadeObject = 226,
- kLoadFont = 227,
- kMoveCharacterNoUserMove = 228,
- kOnKey = 229,
- kStub230 = 230,
- kStub231 = 231,
- kStub232 = 232,
- kObjectFreePictureAndAnimation = 233,
- kGetSampleVolume = 234,
- kFadeScreen = 235,
- kUserEnabled = 236,
- kAnimationNextFrame = 237,
- kInventoryHasObjectByName = 238,
- kStub239 = 239,
- kLoadDialog = 240,
- kStub241 = 241,
- kHasGlobal = 242,
- kStub243 = 243,
- kSetCharacterNotifyVars = 244,
- kAttachInventoryObjectToMouse1 = 245,
- kStub246 = 246,
- kSetDialogForNextFilm = 247
+ kObjectRegisterHandlerBD = 64,
+ kObjectRegisterCharacterTrap = 65,
+ kLoadMouseCursorFromObject = 66,
+ kLoadRegionFromObject = 68,
+ kLoadPictureFromObject = 69,
+ kLoadAnimationFromObject = 70,
+ kSetObjectZ = 71,
+ kSetScreenBackground = 72,
+ kLoadTextFromObject = 73,
+ kScreenSetZNearFar = 74,
+ kScreenLoadRegion = 75,
+ kScreenLoadObject = 76,
+ kScreenCloneObject = 77,
+ kScreenRemoveObject = 78,
+ kSetNextScreen = 79,
+ kSetNextScreenSaveOrLoad = 80,
+ kObjectPatchSetText = 82,
+ kObjectPatchSetRegionName = 83,
+ kScreenPatchSetRegionName = 84,
+ kLoadCharacter = 85,
+ kUnloadCharacter = 86,
+ kAssociateCharacter = 87,
+ kAnimateCharacter = 88,
+ kHideCharacter = 89,
+ kShowCharacter = 90,
+ kDisableCharacter = 91,
+ kEnableCharacter = 92,
+ kMoveCharacterUserMove = 93,
+ kLeaveCharacter = 94,
+ kSetCharacter = 95,
+ kSetCharacterDirection = 96,
+ kPointCharacter = 97,
+ kDisableUser = 98,
+ kEnableUser = 99,
+ kRestartSample = 100,
+ kStopSample = 101,
+ kStub102 = 102,
+ kStub103 = 103,
+ kStub104 = 104,
+ kClearScreen = 105,
+ kInventoryClear = 106,
+ kStub107 = 107,
+ kLoadMouse = 108,
+ kAttachInventoryObjectToMouse0 = 109,
+ kResetMousePointer = 110,
+ kInventoryAddObject = 111,
+ kInventoryRemoveObject = 112,
+ kStub113 = 113,
+ kStub114 = 114,
+ kStub115 = 115,
+ kStub116 = 116,
+ kLoadAnimation = 117,
+ kLoadSample = 118,
+ kSetPhaseVarControlledFlag = 119,
+ kPlayerSay120 = 120,
+ kStub121 = 121,
+ kPlayerSay122 = 122,
+ kNPCSayNoSound = 123,
+ kNPCSay = 124,
+ kPlayerSay125 = 125,
+ kStub126 = 126,
+ kSetTimer = 127,
+ kProcessResetState = 128,
+ kSetAnimationZ = 129,
+ kSetCycles = 130,
+ kSetRandom = 131,
+ kSetPeriodic = 132,
+ kSetPanAndVolume = 133,
+ kSetAnimationPosition = 134,
+ kSetPhaseVar = 135,
+ kSetAnimationLoop = 136,
+ kSetAnimationSpeed = 137,
+ kScreenObjectPatchIncRef = 138,
+ kScreenObjectPatchDecRef = 139,
+ kScreenCheckScreenPatch = 140,
+ kGetFreeInventorySpace = 141,
+ kSetStringSystemVariable = 142,
+ kSetSystemIntegerVariable = 143,
+ kGetSavedMouseX = 144,
+ kGetSavedMouseY = 145,
+ kGetRegionCenterX = 146,
+ kGetRegionCenterY = 147,
+ kGetCharacterAnimationPhase = 148,
+ kGetCharacterX = 149,
+ kGetCharacterY = 150,
+ kCompareScreenName = 151,
+ kGetPictureBaseX = 152,
+ kGetPictureBaseY = 153,
+ kGetObjectSurfaceX = 154,
+ kGetObjectSurfaceY = 155,
+ kLoadGame = 156,
+ kSaveGame = 157,
+ kQuit = 158,
+ kStartNewGame = 159,
+ kLoadSaveSlotNamePicture = 160,
+ kGetSaveGameName = 161,
+ kDisableInventory = 162,
+ kEnableInventory = 163,
+ kLoadPreviousScreen = 164,
+ kMoveScreenObject = 165,
+ kSetObjectRegionOffset = 166,
+ kReturnCurrentInventoryObject = 167,
+ kStub168 = 168,
+ kGetIntegerSystemVariable = 169,
+ kSetDelay = 170,
+ kGetRandomNumber = 171,
+ kSetSampleVolume = 172,
+ kStub173 = 173,
+ kStub174 = 174,
+ kAppendToSharedStorage = 175,
+ kCloneName = 176,
+ kAppendNameToSharedStorage = 177,
+ kGetCloneVar = 178,
+ kSetCloneVar = 179,
+ kGetObjectId = 180,
+ kStub181 = 181,
+ kSetTileSize = 182,
+ kGenerateRegion = 183,
+ kSetObjectTile = 184,
+ kGetMaxInventorySize = 185,
+ kInventoryHasObject = 186,
+ kAppendInventoryObjectNameToSharedSpace = 187,
+ kSetObjectText = 188,
+ kInventoryFindObjectByName = 189,
+ kSetObjectScale = 190,
+ kDisableMouseAreas = 191,
+ kObjectIgnoreRegion = 192,
+ kRemoveGapsFromInventory = 193,
+ kSampleAmbient = 194,
+ kGetObjectPictureWidth = 195,
+ kGetObjectPictureHeight = 196,
+ kSetRotation = 197,
+ kLoadPicture = 198,
+ kStub199 = 199,
+ kSetTileIndex = 200,
+ kSetThrowHandler = 201,
+ kSetUseOnHandler = 202,
+ kPlayFilm = 203,
+ kStub204 = 204,
+ kAddMouseArea = 205,
+ kModifyMouseArea = 206,
+ kSetRain = 207,
+ kFogOnCharacter = 208,
+ kObjectRegisterUserUseHandler = 209,
+ kStub210 = 210,
+ kStub211 = 211,
+ kSetSampleVolumeAndPan = 212,
+ kStub213 = 213,
+ kAddSampleToSoundGroup = 214,
+ kClearSoundGroup = 215,
+ kStub216 = 216,
+ kStub217 = 217,
+ kSetRainDensity = 218,
+ kLeaveCharacterEx = 219,
+ kStopCharacter = 220,
+ kRestartAnimation = 221,
+ kSignalAnimationEnd = 222,
+ kSetShadowIntensity = 223,
+ kSetNPCTellNotifyVar = 224,
+ kPauseAnimation = 225,
+ kFadeObject = 226,
+ kLoadFont = 227,
+ kMoveCharacterNoUserMove = 228,
+ kOnKey = 229,
+ kStub230 = 230,
+ kStub231 = 231,
+ kStub232 = 232,
+ kObjectFreePictureAndAnimation = 233,
+ kGetSampleVolume = 234,
+ kFadeScreen = 235,
+ kUserEnabled = 236,
+ kAnimationNextFrame = 237,
+ kInventoryHasObjectByName = 238,
+ kStub239 = 239,
+ kLoadDialog = 240,
+ kStub241 = 241,
+ kHasGlobal = 242,
+ kStub243 = 243,
+ kSetCharacterNotifyVars = 244,
+ kAttachInventoryObjectToMouse1 = 245,
+ kStub246 = 246,
+ kSetDialogForNextFilm = 247
};
-#define AGDS_OPCODE_LIST(OP, OP_C, OP_B, OP_W, OP_U, OP_UD, OP_UU) \
- OP_UU(kEnter, enter) \
- OP_W(kJumpZImm16, jumpz) \
- OP_W(kJumpImm16, jump) \
- OP(kPop, popNoResult) \
- OP(kDup, dup) \
- OP(kExitProcess, exitProcess) \
- OP(kSuspendProcess, suspend) \
- OP_UD(kPushImm32, push) \
- OP_C(kPushImm8, push) \
- OP_W(kPushImm16, push) \
- OP_C(kPushImm8_2, push2) \
- OP_W(kPushImm16_2, push2) \
- OP_B(kGetGlobalImm8, getGlobal) \
- OP(kPostIncrementGlobal, postIncrementGlobal) \
- OP(kPostDecrementGlobal, postDecrementGlobal) \
- OP(kIncrementGlobalByTop, incrementGlobalByTop) \
- OP(kDecrementGlobalByTop, decrementGlobalByTop) \
- OP(kMultiplyGlobalByTop, multiplyGlobalByTop) \
- OP(kDivideGlobalByTop, divideGlobalByTop) \
- OP(kModGlobalByTop, modGlobalByTop) \
- OP(kShlGlobalByTop, shlGlobalByTop) \
- OP(kShrGlobalByTop, shrGlobalByTop) \
- OP(kAndGlobalByTop, andGlobalByTop) \
- OP(kOrGlobalByTop, orGlobalByTop) \
- OP(kXorGlobalByTop, xorGlobalByTop) \
- OP(kEquals, equals) \
- OP(kNotEquals, notEquals) \
- OP(kGreater, greater) \
- OP(kLess, less) \
- OP(kGreaterOrEquals, greaterOrEquals) \
- OP(kLessOrEquals, lessOrEquals) \
- OP(kAdd, add) \
- OP(kSub, sub) \
- OP(kMul, mul) \
- OP(kDiv, div) \
- OP(kMod, mod) \
- OP(kSetGlobalWithTop, setGlobalWithTop) \
- OP(kSetGlobal, setGlobal) \
- OP(kBoolOr, boolOr) \
- OP(kBoolAnd, boolAnd) \
- OP(kAnd, bitAnd) \
- OP(kOr, bitOr) \
- OP(kXor, bitXor) \
- OP(kNot, bitNot) \
- OP(kShl, shl) \
- OP(kShr, shr) \
- OP(kBoolNot, boolNot) \
- OP(kNegate, negate) \
- OP_U(kObjectInitialise, initialise) \
- OP_U(kObjectRegisterLookHandler, onLook) \
- OP_U(kObjectRegisterUseHandler, onUse) \
- OP_U(kObjectRegisterHandlerC1, onObjectC1) \
- OP_U(kObjectRegisterCharacterTrap, onCharacterTrap) \
- OP_U(kObjectRegisterHandlerBD, onObjectBD) \
- OP(kLoadMouseCursorFromObject, loadMouseCursorFromObject) \
- OP(kLoadRegionFromObject, loadRegionFromObject) \
- OP(kLoadPictureFromObject, loadPictureFromObject) \
- OP(kLoadAnimationFromObject, loadAnimationFromObject) \
- OP(kHideCharacter, hideCharacter) \
- OP(kShowCharacter, showCharacter) \
- OP(kEnableCharacter, enableCharacter) \
- OP(kMoveCharacterUserMove, moveCharacterUserMove) \
- OP(kLeaveCharacter, leaveCharacter) \
- OP(kSetCharacter, setCharacter) \
- OP(kSetCharacterDirection, setCharacterDirection) \
- OP(kPointCharacter, pointCharacter) \
- OP(kDisableUser, disableUser) \
- OP(kEnableUser, enableUser) \
- OP(kRestartSample, restartSample) \
- OP(kStopSample, stopSample) \
- OP(kStub102, stub102) \
- OP(kClearScreen, clearScreen) \
- OP(kInventoryClear, inventoryClear) \
- OP(kLoadMouse, loadMouse) \
- OP(kResetMousePointer, resetMousePointer) \
- OP(kInventoryAddObject, inventoryAddObject) \
- OP(kInventoryRemoveObject, inventoryRemoveObject) \
- OP_U(kObjectRegisterUseObjectHandler, onObjectUse) \
- OP(kObjectPatchSetText, objectPatchSetText) \
- OP(kObjectPatchSetRegionName, objectPatchSetRegionName) \
- OP(kScreenPatchSetRegionName, screenPatchSetRegionName) \
- OP(kAnimateCharacter, animateCharacter) \
- OP(kLoadCharacter, loadCharacter) \
- OP(kAssociateCharacter, associateCharacter) \
- OP(kSetObjectZ, setObjectZ) \
- OP(kSetScreenBackground, setScreenBackground) \
- OP(kLoadTextFromObject, loadTextFromObject) \
- OP(kCompareScreenName, compareScreenName) \
- OP(kScreenSetZNearFar, screenSetZNearFar) \
- OP(kScreenLoadObject, loadScreenObject) \
- OP(kScreenLoadRegion, loadScreenRegion) \
- OP(kScreenCloneObject, cloneObject) \
- OP(kSetNextScreen, setNextScreen) \
- OP(kSetNextScreenSaveOrLoad, setNextScreenSaveOrLoad) \
- OP(kScreenRemoveObject, removeScreenObject) \
- OP(kLoadAnimation, loadAnimation) \
- OP(kLoadSample, loadSample) \
- OP(kSetPhaseVarControlledFlag, setPhaseVarControlledFlag) \
- OP(kPlayerSay120, playerSay120) \
- OP(kPlayerSay122, playerSay122) \
- OP(kPlayerSay125, playerSay125) \
- OP(kNPCSay, npcSay) \
- OP(kNPCSayNoSound, npcSayNoSound) \
- OP(kSetTimer, setTimer) \
- OP(kProcessResetState, resetState) \
- OP(kSetAnimationZ, setAnimationZ) \
- OP(kSetCycles, setCycles) \
- OP(kSetRandom, setRandom) \
- OP(kSetPeriodic, setPeriodic) \
- OP(kSetPanAndVolume, setPanAndVolume) \
- OP(kSetAnimationPosition, setAnimationPosition) \
- OP(kSetPhaseVar, setPhaseVar) \
- OP(kSetAnimationLoop, setAnimationLoop) \
- OP(kSetAnimationSpeed, setAnimationSpeed) \
- OP(kScreenObjectPatchIncRef, screenObjectPatchIncRef) \
- OP(kScreenObjectPatchDecRef, screenObjectPatchDecRef) \
- OP(kGetSavedMouseX, getSavedMouseX) \
- OP(kGetSavedMouseY, getSavedMouseY) \
- OP(kScreenCheckScreenPatch, checkScreenPatch) \
- OP(kGetFreeInventorySpace, getInventoryFreeSpace) \
- OP(kSetStringSystemVariable, setStringSystemVariable) \
- OP(kSetSystemIntegerVariable, setIntegerSystemVariable) \
- OP(kGetRegionCenterX, getRegionCenterX) \
- OP(kGetRegionCenterY, getRegionCenterY) \
- OP(kGetCharacterAnimationPhase, getCharacterAnimationPhase) \
- OP(kGetCharacterX, getCharacterX) \
- OP(kGetCharacterY, getCharacterY) \
- OP(kGetIntegerSystemVariable, getIntegerSystemVariable) \
- OP(kGetRandomNumber, getRandomNumber) \
- OP(kAppendToSharedStorage, appendToSharedStorage) \
- OP(kAppendNameToSharedStorage, appendNameToSharedStorage) \
- OP(kCloneName, cloneName) \
- OP(kGetCloneVar, getCloneVar) \
- OP(kSetCloneVar, setCloneVar) \
- OP(kGetPictureBaseX, getPictureBaseX) \
- OP(kGetPictureBaseY, getPictureBaseY) \
- OP(kGetObjectSurfaceX, getObjectSurfaceX) \
- OP(kGetObjectSurfaceY, getObjectSurfaceY) \
- OP(kLoadGame, loadGame) \
- OP(kSaveGame, saveGame) \
- OP(kLoadSaveSlotNamePicture, loadSaveSlotNamePicture) \
- OP(kGetSaveGameName, getSaveGameName) \
- OP(kSetObjectRegionOffset, setObjectRegionOffset) \
- OP(kSetDelay, setDelay) \
- OP(kSetSampleVolume, setSampleVolume) \
- OP(kStub173, stub173) \
- OP(kStub174, stub174) \
- OP(kObjectIgnoreRegion, objectIgnoreRegion) \
- OP(kQuit, quit) \
- OP(kStartNewGame, startNewGame) \
- OP(kDisableInventory, disableInventory) \
- OP(kEnableInventory, enableInventory) \
- OP(kLoadPreviousScreen, loadPreviousScreen) \
- OP(kMoveScreenObject, moveScreenObject) \
- OP(kGetObjectId, getObjectId) \
- OP(kSetTileSize, setTileSize) \
- OP(kGenerateRegion, generateRegion) \
- OP(kGetMaxInventorySize, getMaxInventorySize) \
+#define AGDS_OPCODE_LIST(OP, OP_C, OP_B, OP_W, OP_U, OP_UD, OP_UU) \
+ OP_UU(kEnter, enter) \
+ OP_W(kJumpZImm16, jumpz) \
+ OP_W(kJumpImm16, jump) \
+ OP(kPop, popNoResult) \
+ OP(kDup, dup) \
+ OP(kExitProcess, exitProcess) \
+ OP(kSuspendProcess, suspend) \
+ OP_UD(kPushImm32, push) \
+ OP_C(kPushImm8, push) \
+ OP_W(kPushImm16, push) \
+ OP_C(kPushImm8_2, push2) \
+ OP_W(kPushImm16_2, push2) \
+ OP_B(kGetGlobalImm8, getGlobal) \
+ OP(kPostIncrementGlobal, postIncrementGlobal) \
+ OP(kPostDecrementGlobal, postDecrementGlobal) \
+ OP(kIncrementGlobalByTop, incrementGlobalByTop) \
+ OP(kDecrementGlobalByTop, decrementGlobalByTop) \
+ OP(kMultiplyGlobalByTop, multiplyGlobalByTop) \
+ OP(kDivideGlobalByTop, divideGlobalByTop) \
+ OP(kModGlobalByTop, modGlobalByTop) \
+ OP(kShlGlobalByTop, shlGlobalByTop) \
+ OP(kShrGlobalByTop, shrGlobalByTop) \
+ OP(kAndGlobalByTop, andGlobalByTop) \
+ OP(kOrGlobalByTop, orGlobalByTop) \
+ OP(kXorGlobalByTop, xorGlobalByTop) \
+ OP(kEquals, equals) \
+ OP(kNotEquals, notEquals) \
+ OP(kGreater, greater) \
+ OP(kLess, less) \
+ OP(kGreaterOrEquals, greaterOrEquals) \
+ OP(kLessOrEquals, lessOrEquals) \
+ OP(kAdd, add) \
+ OP(kSub, sub) \
+ OP(kMul, mul) \
+ OP(kDiv, div) \
+ OP(kMod, mod) \
+ OP(kSetGlobalWithTop, setGlobalWithTop) \
+ OP(kSetGlobal, setGlobal) \
+ OP(kBoolOr, boolOr) \
+ OP(kBoolAnd, boolAnd) \
+ OP(kAnd, bitAnd) \
+ OP(kOr, bitOr) \
+ OP(kXor, bitXor) \
+ OP(kNot, bitNot) \
+ OP(kShl, shl) \
+ OP(kShr, shr) \
+ OP(kBoolNot, boolNot) \
+ OP(kNegate, negate) \
+ OP_U(kObjectInitialise, initialise) \
+ OP_U(kObjectRegisterLookHandler, onLook) \
+ OP_U(kObjectRegisterUseHandler, onUse) \
+ OP_U(kObjectRegisterHandlerC1, onObjectC1) \
+ OP_U(kObjectRegisterCharacterTrap, onCharacterTrap) \
+ OP_U(kObjectRegisterHandlerBD, onObjectBD) \
+ OP(kLoadMouseCursorFromObject, loadMouseCursorFromObject) \
+ OP(kLoadRegionFromObject, loadRegionFromObject) \
+ OP(kLoadPictureFromObject, loadPictureFromObject) \
+ OP(kLoadAnimationFromObject, loadAnimationFromObject) \
+ OP(kHideCharacter, hideCharacter) \
+ OP(kShowCharacter, showCharacter) \
+ OP(kEnableCharacter, enableCharacter) \
+ OP(kMoveCharacterUserMove, moveCharacterUserMove) \
+ OP(kLeaveCharacter, leaveCharacter) \
+ OP(kSetCharacter, setCharacter) \
+ OP(kSetCharacterDirection, setCharacterDirection) \
+ OP(kPointCharacter, pointCharacter) \
+ OP(kDisableUser, disableUser) \
+ OP(kEnableUser, enableUser) \
+ OP(kRestartSample, restartSample) \
+ OP(kStopSample, stopSample) \
+ OP(kStub102, stub102) \
+ OP(kClearScreen, clearScreen) \
+ OP(kInventoryClear, inventoryClear) \
+ OP(kLoadMouse, loadMouse) \
+ OP(kResetMousePointer, resetMousePointer) \
+ OP(kInventoryAddObject, inventoryAddObject) \
+ OP(kInventoryRemoveObject, inventoryRemoveObject) \
+ OP_U(kObjectRegisterUseObjectHandler, onObjectUse) \
+ OP(kObjectPatchSetText, objectPatchSetText) \
+ OP(kObjectPatchSetRegionName, objectPatchSetRegionName) \
+ OP(kScreenPatchSetRegionName, screenPatchSetRegionName) \
+ OP(kAnimateCharacter, animateCharacter) \
+ OP(kLoadCharacter, loadCharacter) \
+ OP(kAssociateCharacter, associateCharacter) \
+ OP(kSetObjectZ, setObjectZ) \
+ OP(kSetScreenBackground, setScreenBackground) \
+ OP(kLoadTextFromObject, loadTextFromObject) \
+ OP(kCompareScreenName, compareScreenName) \
+ OP(kScreenSetZNearFar, screenSetZNearFar) \
+ OP(kScreenLoadObject, loadScreenObject) \
+ OP(kScreenLoadRegion, loadScreenRegion) \
+ OP(kScreenCloneObject, cloneObject) \
+ OP(kSetNextScreen, setNextScreen) \
+ OP(kSetNextScreenSaveOrLoad, setNextScreenSaveOrLoad) \
+ OP(kScreenRemoveObject, removeScreenObject) \
+ OP(kLoadAnimation, loadAnimation) \
+ OP(kLoadSample, loadSample) \
+ OP(kSetPhaseVarControlledFlag, setPhaseVarControlledFlag) \
+ OP(kPlayerSay120, playerSay120) \
+ OP(kPlayerSay122, playerSay122) \
+ OP(kPlayerSay125, playerSay125) \
+ OP(kNPCSay, npcSay) \
+ OP(kNPCSayNoSound, npcSayNoSound) \
+ OP(kSetTimer, setTimer) \
+ OP(kProcessResetState, resetState) \
+ OP(kSetAnimationZ, setAnimationZ) \
+ OP(kSetCycles, setCycles) \
+ OP(kSetRandom, setRandom) \
+ OP(kSetPeriodic, setPeriodic) \
+ OP(kSetPanAndVolume, setPanAndVolume) \
+ OP(kSetAnimationPosition, setAnimationPosition) \
+ OP(kSetPhaseVar, setPhaseVar) \
+ OP(kSetAnimationLoop, setAnimationLoop) \
+ OP(kSetAnimationSpeed, setAnimationSpeed) \
+ OP(kScreenObjectPatchIncRef, screenObjectPatchIncRef) \
+ OP(kScreenObjectPatchDecRef, screenObjectPatchDecRef) \
+ OP(kGetSavedMouseX, getSavedMouseX) \
+ OP(kGetSavedMouseY, getSavedMouseY) \
+ OP(kScreenCheckScreenPatch, checkScreenPatch) \
+ OP(kGetFreeInventorySpace, getInventoryFreeSpace) \
+ OP(kSetStringSystemVariable, setStringSystemVariable) \
+ OP(kSetSystemIntegerVariable, setIntegerSystemVariable) \
+ OP(kGetRegionCenterX, getRegionCenterX) \
+ OP(kGetRegionCenterY, getRegionCenterY) \
+ OP(kGetCharacterAnimationPhase, getCharacterAnimationPhase) \
+ OP(kGetCharacterX, getCharacterX) \
+ OP(kGetCharacterY, getCharacterY) \
+ OP(kGetIntegerSystemVariable, getIntegerSystemVariable) \
+ OP(kGetRandomNumber, getRandomNumber) \
+ OP(kAppendToSharedStorage, appendToSharedStorage) \
+ OP(kAppendNameToSharedStorage, appendNameToSharedStorage) \
+ OP(kCloneName, cloneName) \
+ OP(kGetCloneVar, getCloneVar) \
+ OP(kSetCloneVar, setCloneVar) \
+ OP(kGetPictureBaseX, getPictureBaseX) \
+ OP(kGetPictureBaseY, getPictureBaseY) \
+ OP(kGetObjectSurfaceX, getObjectSurfaceX) \
+ OP(kGetObjectSurfaceY, getObjectSurfaceY) \
+ OP(kLoadGame, loadGame) \
+ OP(kSaveGame, saveGame) \
+ OP(kLoadSaveSlotNamePicture, loadSaveSlotNamePicture) \
+ OP(kGetSaveGameName, getSaveGameName) \
+ OP(kSetObjectRegionOffset, setObjectRegionOffset) \
+ OP(kSetDelay, setDelay) \
+ OP(kSetSampleVolume, setSampleVolume) \
+ OP(kStub173, stub173) \
+ OP(kStub174, stub174) \
+ OP(kObjectIgnoreRegion, objectIgnoreRegion) \
+ OP(kQuit, quit) \
+ OP(kStartNewGame, startNewGame) \
+ OP(kDisableInventory, disableInventory) \
+ OP(kEnableInventory, enableInventory) \
+ OP(kLoadPreviousScreen, loadPreviousScreen) \
+ OP(kMoveScreenObject, moveScreenObject) \
+ OP(kGetObjectId, getObjectId) \
+ OP(kSetTileSize, setTileSize) \
+ OP(kGenerateRegion, generateRegion) \
+ OP(kGetMaxInventorySize, getMaxInventorySize) \
OP(kAppendInventoryObjectNameToSharedSpace, appendInventoryObjectNameToSharedSpace) \
- OP(kSetObjectTile, setObjectTile) \
- OP(kInventoryHasObject, inventoryHasObject) \
- OP(kReturnCurrentInventoryObject, returnCurrentInventoryObject) \
- OP(kSetObjectText, setObjectText) \
- OP(kSetObjectScale, setObjectScale) \
- OP(kDisableMouseAreas, disableMouseAreas) \
- OP(kRemoveGapsFromInventory, removeGapsFromInventory) \
- OP(kSampleAmbient, sampleAmbient) \
- OP(kGetObjectPictureWidth, getObjectPictureWidth) \
- OP(kGetObjectPictureHeight, getObjectPictureHeight) \
- OP(kLoadPicture, loadPicture) \
- OP(kSetRotation, setRotation) \
- OP(kStub199, stub199) \
- OP(kSetSampleVolumeAndPan, setSampleVolumeAndPan) \
- OP(kAddSampleToSoundGroup, addSampleToSoundGroup) \
- OP(kClearSoundGroup, clearSoundGroup) \
- OP(kStub216, stub216) \
- OP(kStub217, stub217) \
- OP(kStopCharacter, stopCharacter) \
- OP(kLeaveCharacterEx, leaveCharacterEx) \
- OP(kRestartAnimation, restartAnimation) \
- OP(kAnimationNextFrame, animationNextFrame) \
- OP(kSignalAnimationEnd, signalAnimationEnd) \
- OP(kSetShadowIntensity, setShadowIntensity) \
- OP(kSetNPCTellNotifyVar, setNPCTellNotifyVar) \
- OP(kPauseAnimation, pauseAnimation) \
- OP(kFadeObject, fadeObject) \
- OP(kLoadFont, loadFont) \
- OP_U(kSetThrowHandler, setThrowHandler) \
- OP_U(kSetUseOnHandler, setUseOnHandler) \
- OP(kPlayFilm, playFilm) \
- OP(kAddMouseArea, addMouseArea) \
- OP(kSetRain, setRain) \
- OP(kSetRainDensity, setRainDensity) \
- OP(kFogOnCharacter, fogOnCharacter) \
- OP(kSetTileIndex, setTileIndex) \
- OP(kModifyMouseArea, modifyMouseArea) \
- OP_U(kObjectRegisterUserUseHandler, onObjectUserUse) \
- OP(kMoveCharacterNoUserMove, moveCharacterNoUserMove) \
- OP_U(kOnKey, onKey) \
- OP(kGetSampleVolume, getSampleVolume) \
- OP(kStub231, stub231) \
- OP(kObjectFreePictureAndAnimation, objectFreePictureAndAnimation) \
- OP(kFadeScreen, fadeScreen) \
- OP(kUserEnabled, userEnabled) \
- OP(kSetCharacterNotifyVars, setCharacterNotifyVars) \
- OP(kInventoryFindObjectByName, inventoryFindObjectByName) \
- OP(kInventoryHasObjectByName, inventoryHasObjectByName) \
- OP(kLoadDialog, loadDialog) \
- OP(kHasGlobal, hasGlobal) \
- OP(kAttachInventoryObjectToMouse0, attachInventoryObjectToMouse0) \
- OP(kAttachInventoryObjectToMouse1, attachInventoryObjectToMouse1) \
+ OP(kSetObjectTile, setObjectTile) \
+ OP(kInventoryHasObject, inventoryHasObject) \
+ OP(kReturnCurrentInventoryObject, returnCurrentInventoryObject) \
+ OP(kSetObjectText, setObjectText) \
+ OP(kSetObjectScale, setObjectScale) \
+ OP(kDisableMouseAreas, disableMouseAreas) \
+ OP(kRemoveGapsFromInventory, removeGapsFromInventory) \
+ OP(kSampleAmbient, sampleAmbient) \
+ OP(kGetObjectPictureWidth, getObjectPictureWidth) \
+ OP(kGetObjectPictureHeight, getObjectPictureHeight) \
+ OP(kLoadPicture, loadPicture) \
+ OP(kSetRotation, setRotation) \
+ OP(kStub199, stub199) \
+ OP(kSetSampleVolumeAndPan, setSampleVolumeAndPan) \
+ OP(kAddSampleToSoundGroup, addSampleToSoundGroup) \
+ OP(kClearSoundGroup, clearSoundGroup) \
+ OP(kStub216, stub216) \
+ OP(kStub217, stub217) \
+ OP(kStopCharacter, stopCharacter) \
+ OP(kLeaveCharacterEx, leaveCharacterEx) \
+ OP(kRestartAnimation, restartAnimation) \
+ OP(kAnimationNextFrame, animationNextFrame) \
+ OP(kSignalAnimationEnd, signalAnimationEnd) \
+ OP(kSetShadowIntensity, setShadowIntensity) \
+ OP(kSetNPCTellNotifyVar, setNPCTellNotifyVar) \
+ OP(kPauseAnimation, pauseAnimation) \
+ OP(kFadeObject, fadeObject) \
+ OP(kLoadFont, loadFont) \
+ OP_U(kSetThrowHandler, setThrowHandler) \
+ OP_U(kSetUseOnHandler, setUseOnHandler) \
+ OP(kPlayFilm, playFilm) \
+ OP(kAddMouseArea, addMouseArea) \
+ OP(kSetRain, setRain) \
+ OP(kSetRainDensity, setRainDensity) \
+ OP(kFogOnCharacter, fogOnCharacter) \
+ OP(kSetTileIndex, setTileIndex) \
+ OP(kModifyMouseArea, modifyMouseArea) \
+ OP_U(kObjectRegisterUserUseHandler, onObjectUserUse) \
+ OP(kMoveCharacterNoUserMove, moveCharacterNoUserMove) \
+ OP_U(kOnKey, onKey) \
+ OP(kGetSampleVolume, getSampleVolume) \
+ OP(kStub231, stub231) \
+ OP(kObjectFreePictureAndAnimation, objectFreePictureAndAnimation) \
+ OP(kFadeScreen, fadeScreen) \
+ OP(kUserEnabled, userEnabled) \
+ OP(kSetCharacterNotifyVars, setCharacterNotifyVars) \
+ OP(kInventoryFindObjectByName, inventoryFindObjectByName) \
+ OP(kInventoryHasObjectByName, inventoryHasObjectByName) \
+ OP(kLoadDialog, loadDialog) \
+ OP(kHasGlobal, hasGlobal) \
+ OP(kAttachInventoryObjectToMouse0, attachInventoryObjectToMouse0) \
+ OP(kAttachInventoryObjectToMouse1, attachInventoryObjectToMouse1) \
OP(kSetDialogForNextFilm, setDialogForNextFilm)
-}
+} // namespace AGDS
#endif
diff --git a/engines/agds/patch.cpp b/engines/agds/patch.cpp
index e943847eeeb..f4ff0cfde58 100644
--- a/engines/agds/patch.cpp
+++ b/engines/agds/patch.cpp
@@ -21,9 +21,9 @@
#include "agds/patch.h"
#include "agds/resourceManager.h"
-#include "common/stream.h"
#include "common/debug.h"
#include "common/error.h"
+#include "common/stream.h"
namespace AGDS {
@@ -50,7 +50,7 @@ void Patch::load(Common::ReadStream &stream) {
characterPosition.y = stream.readSint32LE();
characterDirection = stream.readSint32LE();
characterPresent = stream.readUint32LE();
- debug("character %s at %u,%u with dir: %d", characterPresent? "[present]": "[absent]", characterPosition.x, characterPosition.y, characterDirection);
+ debug("character %s at %u,%u with dir: %d", characterPresent ? "[present]" : "[absent]", characterPosition.x, characterPosition.y, characterDirection);
uint object_count = stream.readUint32LE();
debug("objects in this patch: %u", object_count);
if (stream.read(palette, sizeof(palette)) != sizeof(palette)) {
@@ -85,7 +85,7 @@ void Patch::save(Common::WriteStream &stream) {
}
writeString(stream, defaultMouseCursor);
- for(auto &object: objects) {
+ for (auto &object : objects) {
stream.writeSint16LE(object.flag);
writeString(stream, object.name);
}
@@ -122,7 +122,7 @@ int Patch::incRef(const Common::String &name) {
int Patch::decRef(const Common::String &name) {
for (auto &object : objects) {
if (object.name == name) {
- //this is original code lol
+ // this is original code lol
object.flag = 0;
return 0;
}
@@ -131,4 +131,4 @@ int Patch::decRef(const Common::String &name) {
return 0;
}
-}
+} // namespace AGDS
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index 3f8cdb9e52c..fdaabe5da25 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -22,13 +22,16 @@
#ifndef AGDS_PATCH_H
#define AGDS_PATCH_H
-#include "common/scummsys.h"
+#include "agds/screenLoadingType.h"
#include "common/array.h"
#include "common/rect.h"
+#include "common/scummsys.h"
#include "common/str.h"
-#include "agds/screenLoadingType.h"
-namespace Common { class ReadStream; class WriteStream; }
+namespace Common {
+class ReadStream;
+class WriteStream;
+} // namespace Common
namespace AGDS {
@@ -47,10 +50,10 @@ struct ObjectPatch {
struct Patch {
struct Object {
- Common::String name;
- int16 flag;
+ Common::String name;
+ int16 flag;
- Object(const Common::String &n, int f): name(n), flag(f) {}
+ Object(const Common::String &n, int f) : name(n), flag(f) {}
};
bool screenSaved = false;
@@ -74,7 +77,6 @@ struct Patch {
int decRef(const Common::String &name);
};
-
} // End of namespace AGDS
#endif /* AGDS_PATCH_H */
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index b99df7e57d2..fbda099361a 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -27,17 +27,15 @@
namespace AGDS {
-Process::Process(AGDSEngine *engine, const ObjectPtr &object, unsigned ip, bool v2) :
- _engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object),
- _entryPoint(ip), _ip(ip), _lastIp(ip),
- _status(kStatusActive), _exited(false), _exitCode(kExitCodeDestroy),
- _tileWidth(16), _tileHeight(16), _tileResource(-1), _tileIndex(0),
- _timer(0),
- _animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0),
- _phaseVarControlled(false), _animationSpeed(100),
- _samplePeriodic(false), _sampleAmbient(false), _sampleVolume(100),
- _filmSubtitlesResource(-1), _v2(v2)
- {
+Process::Process(AGDSEngine *engine, const ObjectPtr &object, unsigned ip, bool v2) : _engine(engine), _parentScreen(engine->getCurrentScreenName()), _object(object),
+ _entryPoint(ip), _ip(ip), _lastIp(ip),
+ _status(kStatusActive), _exited(false), _exitCode(kExitCodeDestroy),
+ _tileWidth(16), _tileHeight(16), _tileResource(-1), _tileIndex(0),
+ _timer(0),
+ _animationCycles(1), _animationLoop(false), _animationZ(0), _animationDelay(-1), _animationRandom(0),
+ _phaseVarControlled(false), _animationSpeed(100),
+ _samplePeriodic(false), _sampleAmbient(false), _sampleVolume(100),
+ _filmSubtitlesResource(-1), _v2(v2) {
updateWithCurrentMousePosition();
}
@@ -56,7 +54,7 @@ void Process::debug(const char *str, ...) {
va_end(va);
}
-//fixme: remove copy-paste
+// fixme: remove copy-paste
void Process::error(const char *str, ...) {
va_list va;
va_start(va, str);
@@ -93,9 +91,8 @@ void Process::suspend(ProcessExitCode exitCode, int arg1, int arg2) {
_exitArg2.clear();
}
-
uint8 Process::next() {
- const Object::CodeType & code = _object->getCode();
+ const Object::CodeType &code = _object->getCode();
if (_ip < code.size()) {
return code[_ip++];
} else {
@@ -159,8 +156,7 @@ void Process::updateWithCurrentMousePosition() {
setMousePosition(_engine->mousePosition());
}
-
-void Process::setupAnimation(const AnimationPtr & animation) {
+void Process::setupAnimation(const AnimationPtr &animation) {
animation->position(_animationPosition);
animation->z(_animationZ);
animation->process(getName());
@@ -171,14 +167,14 @@ void Process::setupAnimation(const AnimationPtr & animation) {
animation->setRandom(_animationRandom);
animation->phaseVarControlled(_phaseVarControlled);
if (_phaseVar.empty())
- suspend();
+ suspend();
else if (_phaseVarControlled)
- _engine->setGlobal(_phaseVar, 0);
+ _engine->setGlobal(_phaseVar, 0);
}
void Process::removeProcessAnimation() {
if (_processAnimation) {
- auto * screen = _engine->getCurrentScreen();
+ auto *screen = _engine->getCurrentScreen();
if (screen)
screen->remove(_processAnimation);
_processAnimation = nullptr;
@@ -186,7 +182,7 @@ void Process::removeProcessAnimation() {
}
void Process::activate() {
- switch(status()) {
+ switch (status()) {
case kStatusPassive:
_status = Process::kStatusActive;
break;
@@ -200,7 +196,7 @@ void Process::activate() {
}
void Process::deactivate() {
- switch(status()) {
+ switch (status()) {
case kStatusActive:
debug("deactivated");
_status = Process::kStatusPassive;
@@ -228,7 +224,7 @@ void Process::fail() {
void Process::run() {
bool restart = true;
- while(_status != kStatusDone && _status != kStatusError && restart) {
+ while (_status != kStatusDone && _status != kStatusError && restart) {
restart = false;
ProcessExitCode code = resume();
switch (code) {
@@ -258,7 +254,7 @@ void Process::run() {
case kExitCodeSetNextScreenSaveOrLoad:
done();
debug("process %s launches screen: %s, saveorload: ", getName().c_str(), getExitArg1().c_str(), code == kExitCodeSetNextScreenSaveOrLoad);
- _engine->setNextScreenName(getExitArg1(), code == kExitCodeSetNextScreenSaveOrLoad? ScreenLoadingType::SaveOrLoad: ScreenLoadingType::Normal);
+ _engine->setNextScreenName(getExitArg1(), code == kExitCodeSetNextScreenSaveOrLoad ? ScreenLoadingType::SaveOrLoad : ScreenLoadingType::Normal);
break;
case kExitCodeMouseAreaChange:
deactivate();
@@ -314,80 +310,89 @@ void Process::run() {
}
}
-#define UNARY_OP(NAME, OP) void Process:: NAME () { int arg = pop(); debug(#NAME " %d", arg); push( OP arg ); }
-#define BINARY_OP(NAME, OP) void Process:: NAME () { int arg2 = pop(); int arg1 = pop(); debug(" %d " #NAME " %d", arg1, arg2); push(arg1 OP arg2); }
-
- UNARY_OP(boolNot, !)
- UNARY_OP(bitNot, ~)
- UNARY_OP(negate, -)
- BINARY_OP(shl, <<)
- BINARY_OP(shr, >>)
- BINARY_OP(boolOr, ||)
- BINARY_OP(boolAnd, &&)
- BINARY_OP(equals, ==)
- BINARY_OP(notEquals, !=)
- BINARY_OP(greater, >)
- BINARY_OP(greaterOrEquals, >=)
- BINARY_OP(less, <)
- BINARY_OP(lessOrEquals, <=)
- BINARY_OP(add, +)
- BINARY_OP(sub, -)
- BINARY_OP(mul, *)
- BINARY_OP(div, /)
- BINARY_OP(mod, %)
- BINARY_OP(bitAnd, &)
- BINARY_OP(bitOr, |)
- BINARY_OP(bitXor, ^)
+#define UNARY_OP(NAME, OP) \
+ void Process::NAME() { \
+ int arg = pop(); \
+ debug(#NAME " %d", arg); \
+ push(OP arg); \
+ }
+#define BINARY_OP(NAME, OP) \
+ void Process::NAME() { \
+ int arg2 = pop(); \
+ int arg1 = pop(); \
+ debug(" %d " #NAME " %d", arg1, arg2); \
+ push(arg1 OP arg2); \
+ }
+
+UNARY_OP(boolNot, !)
+UNARY_OP(bitNot, ~)
+UNARY_OP(negate, -)
+BINARY_OP(shl, <<)
+BINARY_OP(shr, >>)
+BINARY_OP(boolOr, ||)
+BINARY_OP(boolAnd, &&)
+BINARY_OP(equals, ==)
+BINARY_OP(notEquals, !=)
+BINARY_OP(greater, >)
+BINARY_OP(greaterOrEquals, >=)
+BINARY_OP(less, <)
+BINARY_OP(lessOrEquals, <=)
+BINARY_OP(add, +)
+BINARY_OP(sub, -)
+BINARY_OP(mul, *)
+BINARY_OP(div, /)
+BINARY_OP(mod, %)
+BINARY_OP(bitAnd, &)
+BINARY_OP(bitOr, |)
+BINARY_OP(bitXor, ^)
#undef UNARY_OP
#undef BINARY_OP
-
-//fixme: add trace here
+// fixme: add trace here
#define AGDS_OP(NAME, METHOD) \
- case NAME: \
- METHOD(); \
+ case NAME: \
+ METHOD(); \
break;
#define AGDS_OP_C(NAME, METHOD) \
- case NAME: { \
- int8 arg = next(); \
- METHOD(arg); \
+ case NAME: { \
+ int8 arg = next(); \
+ METHOD(arg); \
} break;
-#define AGDS_OP_B(NAME, METHOD) \
- case NAME: { \
- uint8 arg = next(); \
- METHOD(arg); \
+#define AGDS_OP_B(NAME, METHOD) \
+ case NAME: { \
+ uint8 arg = next(); \
+ METHOD(arg); \
} break;
-#define AGDS_OP_W(NAME, METHOD) \
- case NAME: { \
- int16 arg = next16(); \
- METHOD(arg); \
+#define AGDS_OP_W(NAME, METHOD) \
+ case NAME: { \
+ int16 arg = next16(); \
+ METHOD(arg); \
} break;
-#define AGDS_OP_U(NAME, METHOD) \
- case NAME: { \
- uint16 arg = next16(); \
- METHOD(arg); \
+#define AGDS_OP_U(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg = next16(); \
+ METHOD(arg); \
} break;
-#define AGDS_OP_UU(NAME, METHOD) \
- case NAME: { \
- uint16 arg1 = next16(); \
- uint16 arg2 = next16(); \
- METHOD(arg1, arg2); \
+#define AGDS_OP_UU(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg1 = next16(); \
+ uint16 arg2 = next16(); \
+ METHOD(arg1, arg2); \
} break;
-#define AGDS_OP_UD(NAME, METHOD) \
- case NAME: { \
- uint16 arg1 = next16(); \
- uint32 arg2 = next16(); \
+#define AGDS_OP_UD(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg1 = next16(); \
+ uint32 arg2 = next16(); \
METHOD(static_cast<int32>(arg1 | (arg2 << 16))); \
} break;
-
ProcessExitCode Process::resume() {
_exitCode = kExitCodeDestroy;
if (_timer) {
@@ -407,12 +412,18 @@ ProcessExitCode Process::resume() {
op |= next() << 8;
op >>= 1;
}
- switch(op) {
- case 8000: op = kEnter; break;
- case 8011: op = kPushImm8; break;
- case 8013: op = kPushImm8_2; break;
- default:
- break;
+ switch (op) {
+ case 8000:
+ op = kEnter;
+ break;
+ case 8011:
+ op = kPushImm8;
+ break;
+ case 8013:
+ op = kPushImm8_2;
+ break;
+ default:
+ break;
}
}
// debug("CODE %04x: %u", _lastIp, (uint)op);
@@ -421,8 +432,7 @@ ProcessExitCode Process::resume() {
AGDS_OP,
AGDS_OP_C, AGDS_OP_B,
AGDS_OP_W, AGDS_OP_U,
- AGDS_OP_UD, AGDS_OP_UU
- )
+ AGDS_OP_UD, AGDS_OP_UU)
default:
error("%s: %08x: unknown opcode 0x%02x (%u)", _object->getName().c_str(), _lastIp, (unsigned)op, (unsigned)op);
fail();
@@ -434,46 +444,52 @@ ProcessExitCode Process::resume() {
return _exitCode;
}
-#define AGDS_DIS(NAME, METHOD) \
- case NAME: \
+#define AGDS_DIS(NAME, METHOD) \
+ case NAME: \
source += Common::String::format("%s\n", #NAME); \
break;
-#define AGDS_DIS_C(NAME, METHOD) \
- case NAME: { \
- int8 arg = code[ip++]; \
+#define AGDS_DIS_C(NAME, METHOD) \
+ case NAME: { \
+ int8 arg = code[ip++]; \
source += Common::String::format("%s %d\n", #NAME, (int)arg); \
} break;
-#define AGDS_DIS_B(NAME, METHOD) \
- case NAME: { \
- uint8 arg = code[ip++]; \
+#define AGDS_DIS_B(NAME, METHOD) \
+ case NAME: { \
+ uint8 arg = code[ip++]; \
source += Common::String::format("%s %u\n", #NAME, (uint)arg); \
} break;
-#define AGDS_DIS_W(NAME, METHOD) \
- case NAME: { \
- int16 arg = code[ip++]; arg |= ((int16)code[ip++]) << 8; \
+#define AGDS_DIS_W(NAME, METHOD) \
+ case NAME: { \
+ int16 arg = code[ip++]; \
+ arg |= ((int16)code[ip++]) << 8; \
source += Common::String::format("%s %d\n", #NAME, (int)arg); \
} break;
-#define AGDS_DIS_U(NAME, METHOD) \
- case NAME: { \
- uint16 arg = code[ip++]; arg |= ((uint16)code[ip++]) << 8; \
+#define AGDS_DIS_U(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg = code[ip++]; \
+ arg |= ((uint16)code[ip++]) << 8; \
source += Common::String::format("%s %u\n", #NAME, (uint)arg); \
} break;
-#define AGDS_DIS_UU(NAME, METHOD) \
- case NAME: { \
- uint16 arg1 = code[ip++]; arg1 |= ((uint16)code[ip++]) << 8; \
- uint16 arg2 = code[ip++]; arg2 |= ((uint16)code[ip++]) << 8; \
+#define AGDS_DIS_UU(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg1 = code[ip++]; \
+ arg1 |= ((uint16)code[ip++]) << 8; \
+ uint16 arg2 = code[ip++]; \
+ arg2 |= ((uint16)code[ip++]) << 8; \
source += Common::String::format("%s %u %u\n", #NAME, (uint)arg1, (uint)arg2); \
} break;
-#define AGDS_DIS_UD(NAME, METHOD) \
- case NAME: { \
- uint16 arg1 = code[ip++]; arg1 |= ((uint16)code[ip++]) << 8; \
- uint16 arg2 = code[ip++]; arg2 |= ((uint16)code[ip++]) << 8; \
+#define AGDS_DIS_UD(NAME, METHOD) \
+ case NAME: { \
+ uint16 arg1 = code[ip++]; \
+ arg1 |= ((uint16)code[ip++]) << 8; \
+ uint16 arg2 = code[ip++]; \
+ arg2 |= ((uint16)code[ip++]) << 8; \
source += Common::String::format("%s %u\n", #NAME, (uint)(arg1 | (arg2 << 16))); \
} break;
@@ -497,8 +513,7 @@ Common::String Process::disassemble(const ObjectPtr &object, bool v2) {
AGDS_DIS,
AGDS_DIS_C, AGDS_DIS_B,
AGDS_DIS_W, AGDS_DIS_U,
- AGDS_DIS_UD, AGDS_DIS_UU
- )
+ AGDS_DIS_UD, AGDS_DIS_UU)
default:
source += Common::String::format("unknown opcode 0x%02x (%u)\n", (unsigned)op, (unsigned)op);
break;
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 1b0e8e38a26..78273572c5a 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -25,9 +25,9 @@
#include "agds/object.h"
#include "agds/opcode.h"
#include "agds/processExitCode.h"
+#include "common/debug.h"
#include "common/scummsys.h"
#include "common/stack.h"
-#include "common/debug.h"
namespace AGDS {
@@ -38,42 +38,45 @@ using AnimationPtr = Common::SharedPtr<Animation>;
class Process {
public:
- enum Status { kStatusActive, kStatusPassive, kStatusDone, kStatusError };
+ enum Status { kStatusActive,
+ kStatusPassive,
+ kStatusDone,
+ kStatusError };
private:
using StackType = Common::Stack<int32>;
- AGDSEngine *_engine;
- Common::String _parentScreen;
- ObjectPtr _object;
- StackType _stack;
- unsigned _entryPoint;
- unsigned _ip, _lastIp;
- Status _status;
- bool _exited;
- ProcessExitCode _exitCode;
- Common::String _exitArg1, _exitArg2;
- int _exitIntArg1, _exitIntArg2;
- int _tileWidth, _tileHeight;
- int _tileResource;
- int _tileIndex;
- Common::String _phaseVar;
- int _timer;
- int _animationCycles;
- bool _animationLoop;
- Common::Point _animationPosition;
- int _animationZ;
- int _animationDelay;
- int _animationRandom;
- bool _phaseVarControlled;
- int _animationSpeed;
- bool _samplePeriodic;
- bool _sampleAmbient;
- int32 _sampleVolume;
- Common::Point _mousePosition;
- int _filmSubtitlesResource;
- AnimationPtr _processAnimation;
- bool _v2;
+ AGDSEngine *_engine;
+ Common::String _parentScreen;
+ ObjectPtr _object;
+ StackType _stack;
+ unsigned _entryPoint;
+ unsigned _ip, _lastIp;
+ Status _status;
+ bool _exited;
+ ProcessExitCode _exitCode;
+ Common::String _exitArg1, _exitArg2;
+ int _exitIntArg1, _exitIntArg2;
+ int _tileWidth, _tileHeight;
+ int _tileResource;
+ int _tileIndex;
+ Common::String _phaseVar;
+ int _timer;
+ int _animationCycles;
+ bool _animationLoop;
+ Common::Point _animationPosition;
+ int _animationZ;
+ int _animationDelay;
+ int _animationRandom;
+ bool _phaseVarControlled;
+ int _animationSpeed;
+ bool _samplePeriodic;
+ bool _sampleAmbient;
+ int32 _sampleVolume;
+ Common::Point _mousePosition;
+ int _filmSubtitlesResource;
+ AnimationPtr _processAnimation;
+ bool _v2;
private:
void debug(const char *str, ...);
@@ -98,23 +101,23 @@ private:
Common::String popText();
#define AGDS_PROCESS_METHOD(opcode, method) \
- void method () ;
+ void method();
#define AGDS_PROCESS_METHOD_C(opcode, method) \
- void method (int8) ;
+ void method(int8);
#define AGDS_PROCESS_METHOD_B(opcode, method) \
- void method (uint8) ;
+ void method(uint8);
#define AGDS_PROCESS_METHOD_W(opcode, method) \
- void method (int16) ;
+ void method(int16);
#define AGDS_PROCESS_METHOD_U(opcode, method) \
- void method (uint16) ;
+ void method(uint16);
#define AGDS_PROCESS_METHOD_UD(opcode, method) \
- void method (int32) ;
+ void method(int32);
#define AGDS_PROCESS_METHOD_UU(opcode, method) \
- void method (uint16, uint16) ;
+ void method(uint16, uint16);
AGDS_OPCODE_LIST(AGDS_PROCESS_METHOD,
- AGDS_PROCESS_METHOD_C, AGDS_PROCESS_METHOD_B, AGDS_PROCESS_METHOD_W,
- AGDS_PROCESS_METHOD_U, AGDS_PROCESS_METHOD_UD, AGDS_PROCESS_METHOD_UU)
+ AGDS_PROCESS_METHOD_C, AGDS_PROCESS_METHOD_B, AGDS_PROCESS_METHOD_W,
+ AGDS_PROCESS_METHOD_U, AGDS_PROCESS_METHOD_UD, AGDS_PROCESS_METHOD_UU)
void moveCharacter(bool usermove);
void tell(bool npc, const Common::String &sound);
@@ -194,7 +197,7 @@ public:
return _exitIntArg2;
}
- void setMousePosition(Common::Point mousePosition) {
+ void setMousePosition(Common::Point mousePosition) {
_mousePosition = mousePosition;
}
void updateWithCurrentMousePosition();
@@ -210,7 +213,6 @@ public:
void removeProcessAnimation();
};
-
} // End of namespace AGDS
#endif /* AGDS_PROCESS_H */
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index 5f36490201b..9655ad9d0c0 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -24,22 +24,22 @@
namespace AGDS {
- enum ProcessExitCode {
- kExitCodeDestroy = 2,
- kExitCodeSuspend = 5,
- kExitCodeSetNextScreen = 6,
- kExitCodeSetNextScreenSaveOrLoad = 7,
- kExitCodeLoadScreenObject = 8,
- kExitCodeLoadScreenObjectAs = 9,
- kExitCodeLoadInventoryObject = 10,
- kExitCodeMouseAreaChange = 11,
- kExitCodeRunDialog = 12,
- kExitCodeNewGame = 13,
- kExitCodeLoadGame = 14,
- kExitCodeExitScreen = 15,
- kExitCodeCloseInventory = 16,
- kExitCodeSaveGame = 17,
- };
+enum ProcessExitCode {
+ kExitCodeDestroy = 2,
+ kExitCodeSuspend = 5,
+ kExitCodeSetNextScreen = 6,
+ kExitCodeSetNextScreenSaveOrLoad = 7,
+ kExitCodeLoadScreenObject = 8,
+ kExitCodeLoadScreenObjectAs = 9,
+ kExitCodeLoadInventoryObject = 10,
+ kExitCodeMouseAreaChange = 11,
+ kExitCodeRunDialog = 12,
+ kExitCodeNewGame = 13,
+ kExitCodeLoadGame = 14,
+ kExitCodeExitScreen = 15,
+ kExitCodeCloseInventory = 16,
+ kExitCodeSaveGame = 17,
+};
}
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 0d3ffe9b1f3..46c29034508 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -78,8 +78,8 @@ void Process::enter(uint16 magic, uint16 size) {
uint16 resCount = next16();
uint16 unk4 = next16();
debug("resource block %04x %04x %04x %04x,"
- " resources table at %04x with %u entries",
- unk1, unk2, unk3, unk4, resOffset, resCount);
+ " resources table at %04x with %u entries",
+ unk1, unk2, unk3, unk4, resOffset, resCount);
_object->readStringTable(resOffset, resCount);
}
@@ -130,7 +130,7 @@ void Process::getRegionCenterY() {
void Process::getObjectId() {
const Common::String &name = _object->getName();
- //no rfind :(((
+ // no rfind :(((
Common::String::const_iterator dotpos = 0;
for (Common::String::const_iterator i = name.begin(); i != name.end(); ++i)
if (*i == '.')
@@ -153,7 +153,7 @@ void Process::loadPicture() {
void Process::loadAnimation() {
Common::String name = popText();
- debug("loadAnimation %s (phase: %s) %s", name.c_str(), _phaseVar.c_str(), _phaseVarControlled? "(phase-var)": "");
+ debug("loadAnimation %s (phase: %s) %s", name.c_str(), _phaseVar.c_str(), _phaseVarControlled ? "(phase-var)" : "");
auto animation = _engine->loadAnimation(name);
if (animation) {
if (animation == _processAnimation) {
@@ -308,7 +308,7 @@ void Process::removeScreenObject(const Common::String &name) {
process->removeProcessAnimation();
process->done();
}
- } while(process);
+ } while (process);
_engine->soundManager().stopAllFrom(name);
}
_object->unlock();
@@ -473,7 +473,7 @@ void Process::xorGlobalByTop() {
void Process::appendToSharedStorage() {
Common::String value = popString();
int index = _engine->appendToSharedStorage(value);
- //debug("appendToSharedStorage %s -> %d", value.c_str(), index);
+ // debug("appendToSharedStorage %s -> %d", value.c_str(), index);
push(index);
}
@@ -496,9 +496,9 @@ Common::String Process::getCloneVarName(const Common::String &arg1, const Common
Common::String name;
if (isNumeric) {
- //no substr :(((
+ // no substr :(((
name = Common::String(arg1.c_str(), arg1.c_str() + prefixLength) +
- "." + arg2 + Common::String(arg1.c_str() + prefixLength);
+ "." + arg2 + Common::String(arg1.c_str() + prefixLength);
} else {
name = arg1 + "." + arg2;
}
@@ -549,7 +549,7 @@ void Process::checkScreenPatch() {
Common::String screenName = popString();
Common::String inventoryScr = _engine->getSystemVariable("inventory_scr")->getString();
debug("checkScreenPatch: screen: %s, object: %s, inventory: %s",
- screenName.empty() ? "none" : screenName.c_str(), objectName.c_str(), inventoryScr.empty() ? "none" : inventoryScr.c_str());
+ screenName.empty() ? "none" : screenName.c_str(), objectName.c_str(), inventoryScr.empty() ? "none" : inventoryScr.c_str());
Screen *screen = _engine->getCurrentScreen();
if (!screen) {
@@ -561,7 +561,7 @@ void Process::checkScreenPatch() {
if (objectName != _engine->getSystemVariable("inventory_scr")->getString()) {
debug("checkScreenPatch for object %s %s", screenName.c_str(), objectName.c_str());
auto patch = _engine->getPatch(screenName);
- push(patch? patch->getFlag(objectName): 0);
+ push(patch ? patch->getFlag(objectName) : 0);
} else {
push(_engine->inventory().find(objectName) >= 0);
}
@@ -580,9 +580,9 @@ void Process::loadMouseCursorFromObject() {
Common::String name = popText();
auto inventoryObject = _engine->currentInventoryObject();
bool changeInventoryObject = (inventoryObject && inventoryObject->getName() == getName());
- debug("loadMouseCursorFromObject %s inventory: %d", !name.empty()? name.c_str(): "<remove>", changeInventoryObject);
- auto cursor = !name.empty()? _engine->loadMouseCursor(name): nullptr;
- _object->setMouseCursor(cursor); //overlay cursor
+ debug("loadMouseCursorFromObject %s inventory: %d", !name.empty() ? name.c_str() : "<remove>", changeInventoryObject);
+ auto cursor = !name.empty() ? _engine->loadMouseCursor(name) : nullptr;
+ _object->setMouseCursor(cursor); // overlay cursor
}
void Process::attachInventoryObjectToMouse(bool keepGraphics) {
@@ -745,7 +745,7 @@ void Process::compareScreenName() {
auto name = popString();
auto currentScreenName = _engine->getCurrentScreenName();
debug("compareScreenName %s (currentScreen: %s)", name.c_str(), currentScreenName.c_str());
- push(name == currentScreenName? 1: 0);
+ push(name == currentScreenName ? 1 : 0);
}
void Process::objectPatchSetText() {
@@ -803,7 +803,7 @@ void Process::screenObjectPatchIncRef() {
if (_engine->getCurrentScreen()->applyingPatch()) {
warning("attempt to change screen patch (%s) in patching process (%s)", objectName.c_str(), screenName.c_str());
} else {
- //fixme: add non-existent screen check?
+ // fixme: add non-existent screen check?
auto patch = _engine->createPatch(screenName);
int refs = patch->incRef(objectName);
debug("increment refcount for object %s, result: %d", objectName.c_str(), refs);
@@ -822,7 +822,7 @@ void Process::screenObjectPatchDecRef() {
if (_engine->getCurrentScreen()->applyingPatch()) {
warning("attempt to change screen patch (%s) in patching process (%s)", objectName.c_str(), screenName.c_str());
} else {
- //fixme: add non-existent screen check?
+ // fixme: add non-existent screen check?
auto patch = _engine->createPatch(screenName);
int refs = patch->decRef(objectName);
debug("decrement refcount for object %s, result: %d", objectName.c_str(), refs);
@@ -837,7 +837,7 @@ void Process::getPictureBaseX() {
Common::String name = popString();
debug("getPictureBaseX: %s", name.c_str());
ObjectPtr object = _engine->getCurrentScreenObject(name);
- int x = object? object->getOffset().x: 0;
+ int x = object ? object->getOffset().x : 0;
debug("\t%d", x);
push(x);
}
@@ -846,7 +846,7 @@ void Process::getPictureBaseY() {
Common::String name = popString();
debug("getPictureBaseY: %s", name.c_str());
ObjectPtr object = _engine->getCurrentScreenObject(name);
- int y = object? object->getOffset().y: 0;
+ int y = object ? object->getOffset().y : 0;
debug("\t%d", y);
push(y);
}
@@ -855,7 +855,7 @@ void Process::getObjectSurfaceX() {
Common::String name = popString();
debug("getObjectSurfaceX: %s", name.c_str());
ObjectPtr object = _engine->getCurrentScreenObject(name);
- int x = object? object->getPosition().x: 0;
+ int x = object ? object->getPosition().x : 0;
debug("\t%d", x);
push(x);
}
@@ -864,7 +864,7 @@ void Process::getObjectSurfaceY() {
Common::String name = popString();
debug("getObjectSurfaceY: %s", name.c_str());
ObjectPtr object = _engine->getCurrentScreenObject(name);
- int y = object? object->getPosition().y: 0;
+ int y = object ? object->getPosition().y : 0;
debug("\t%d", y);
push(y);
}
@@ -907,20 +907,20 @@ void Process::loadSaveSlotNamePicture() {
debug("loadSaveSlotNamePicture: %d", saveSlot);
Common::String saveSlotName = _engine->getSaveStateName(saveSlot);
- Common::SaveFileManager * saveMan = _engine->getSaveFileManager();
+ Common::SaveFileManager *saveMan = _engine->getSaveFileManager();
Common::ScopedPtr<Common::InSaveFile> save(saveMan->openForLoading(saveSlotName));
debug("save state name: %s", saveSlotName.c_str());
int fontId = _engine->getSystemVariable("edit_font")->getInteger();
- Font * font = _engine->getFont(fontId);
+ Font *font = _engine->getFont(fontId);
int h = font->getFontHeight();
static const int w = 400;
- Graphics::Surface * label = _engine->createSurface(w, h);
+ Graphics::Surface *label = _engine->createSurface(w, h);
uint32 color = _engine->pixelFormat().RGBToColor(255, 0, 255);
label->fillRect(label->getRect(), color);
- font->drawString(label, save? saveSlotName: "", 0, 0, w, color);
+ font->drawString(label, save ? saveSlotName : "", 0, 0, w, color);
Graphics::ManagedSurface *transparentLabel = _engine->convertToTransparent(label);
_object->setPicture(transparentLabel);
_object->generateRegion();
@@ -1060,7 +1060,7 @@ void Process::restartAnimation() {
animation->resume();
animation->onScreen(true);
auto phase = animation->phase();
- _engine->setGlobal(phaseVar, phase > 0? phase - 1: 0);
+ _engine->setGlobal(phaseVar, phase > 0 ? phase - 1 : 0);
} else {
warning("no animation with phase var %s found", phaseVar.c_str());
_engine->setGlobal(phaseVar, -1);
@@ -1118,7 +1118,7 @@ void Process::pauseAnimation() {
if (animation) {
animation->pause();
if (arg > 0) {
- //1, 2 stop (2 with rewind)
+ // 1, 2 stop (2 with rewind)
animation->onScreen(false);
if (arg == 2) {
animation->rewind();
@@ -1240,12 +1240,12 @@ void Process::setDialogForNextFilm() {
void Process::tell(bool npc, const Common::String &sound) {
Common::String text = popText();
Common::String region = popString();
- debug("%s '%s' '%s' '%s'", npc? "npcSay": "playerSay", region.c_str(), text.c_str(), sound.c_str());
+ debug("%s '%s' '%s' '%s'", npc ? "npcSay" : "playerSay", region.c_str(), text.c_str(), sound.c_str());
_engine->tell(*this, region, text, sound, npc);
- //close inventory here if close flag was set
+ // close inventory here if close flag was set
Common::String inventoryClose = _engine->getSystemVariable("inv_close")->getString();
- suspend(!inventoryClose.empty()? kExitCodeCloseInventory: kExitCodeSuspend);
+ suspend(!inventoryClose.empty() ? kExitCodeCloseInventory : kExitCodeSuspend);
}
void Process::npcSay() {
@@ -1265,7 +1265,7 @@ void Process::playerSay120() {
}
void Process::playerSay125() {
- playerSay120(); //same case
+ playerSay120(); // same case
}
void Process::loadDialog() {
@@ -1486,7 +1486,7 @@ void Process::onObjectBD(uint16 size) {
}
void Process::enableUser() {
- //screen loading block user interaction until this instruction
+ // screen loading block user interaction until this instruction
debug("enableUser");
_engine->enableUser(true);
}
@@ -1683,7 +1683,7 @@ void Process::getCharacterX() {
Character *character = _engine->getCharacter(name);
if (!character)
warning("no character %s", name.c_str());
- int value = character? character->position().x: -1;
+ int value = character ? character->position().x : -1;
push(value);
}
void Process::getCharacterY() {
@@ -1692,7 +1692,7 @@ void Process::getCharacterY() {
Character *character = _engine->getCharacter(name);
if (!character)
warning("no character %s", name.c_str());
- int value = character? character->position().y: -1;
+ int value = character ? character->position().y : -1;
push(value);
}
@@ -1733,7 +1733,6 @@ void Process::setRainDensity() {
int change = pop();
int density = pop();
debug("setRainDensity stub: %d (change: %d)", density, change);
-
}
void Process::loadRegionFromObject() {
@@ -1752,7 +1751,7 @@ void Process::loadPictureFromObject() {
void Process::loadAnimationFromObject() {
Common::String name = popText();
- debug("loadAnimationFromObject %s %s", name.c_str(), _phaseVarControlled? "(phase-var)": "");
+ debug("loadAnimationFromObject %s %s", name.c_str(), _phaseVarControlled ? "(phase-var)" : "");
auto animation = _engine->loadAnimation(name);
if (animation) {
_animationCycles = 0;
@@ -1811,7 +1810,7 @@ void Process::setCharacterNotifyVars() {
debug("setCharacterNotifyVars, tell: %s, direction: %s", arg1.c_str(), arg2.c_str());
auto character = _engine->currentCharacter();
_engine->setGlobal(arg1, 0);
- _engine->setGlobal(arg2, character? character->direction(): 0);
+ _engine->setGlobal(arg2, character ? character->direction() : 0);
_engine->textLayout().setCharNotifyVar(arg1);
_engine->textLayout().setCharDirectionNotifyVar(arg2);
}
diff --git a/engines/agds/region.cpp b/engines/agds/region.cpp
index 55054085a16..c5599cd3cb7 100644
--- a/engines/agds/region.cpp
+++ b/engines/agds/region.cpp
@@ -45,7 +45,7 @@ Region::Region(const Common::String &resourceName, Common::SeekableReadStream &s
int16 a = stream.readSint16LE();
int16 b = stream.readSint16LE();
int16 c = stream.readUint16LE();
- if (c != -12851) //0xcdcd
+ if (c != -12851) // 0xcdcd
debug("extended entry: %d %d %d", a, b, c);
else
debug("extended entry: %d %d", a, b);
@@ -105,7 +105,7 @@ Common::Point Region::topLeft() const {
for (uint i = 0; i < regions.size(); ++i) {
const PointsType &points = regions[i];
- for(uint j = 0; j < points.size(); ++j) {
+ for (uint j = 0; j < points.size(); ++j) {
Common::Point point = points[j];
if (point.x < p.x)
p.x = point.x;
@@ -116,11 +116,11 @@ Common::Point Region::topLeft() const {
return p;
}
-//FIXME: copied from wintermute/base_region.cpp
+// FIXME: copied from wintermute/base_region.cpp
struct dPoint {
double x, y;
-} ;
+};
bool Region::pointIn(Common::Point point) const {
for (uint r = 0; r < regions.size(); ++r) {
diff --git a/engines/agds/region.h b/engines/agds/region.h
index 327deb60919..2d47ccd2156 100644
--- a/engines/agds/region.h
+++ b/engines/agds/region.h
@@ -22,19 +22,19 @@
#ifndef AGDS_REGION_H
#define AGDS_REGION_H
-#include "common/scummsys.h"
#include "common/array.h"
-#include "common/stream.h"
#include "common/rect.h"
+#include "common/scummsys.h"
+#include "common/stream.h"
namespace AGDS {
struct Region {
- using PointsType = Common::Array<Common::Point> ;
+ using PointsType = Common::Array<Common::Point>;
- Common::String name;
- Common::Point center;
- uint16 flags;
+ Common::String name;
+ Common::Point center;
+ uint16 flags;
Common::Array<PointsType> regions;
Region(const Common::String &resourceName, Common::SeekableReadStream &stream);
@@ -50,7 +50,6 @@ struct Region {
}
};
-
} // End of namespace AGDS
#endif /* AGDS_REGION_H */
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index 51ffba651b2..d7a6ab70e71 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -92,7 +92,7 @@ bool ResourceManager::GrpFile::load(const Common::Path &grpPath) {
if (!reader.skip(3 * 4))
return false;
- //debug("+%u files in index", dirCount);
+ // debug("+%u files in index", dirCount);
while (dirCount--) {
uint8 dirData[0x31];
uint8 *dirDataEnd = dirData + sizeof(dirData);
@@ -116,7 +116,7 @@ bool ResourceManager::GrpFile::load(const Common::Path &grpPath) {
uint32 offset = dirReader.readSint32();
uint32 size = dirReader.readSint32();
- //debug("\t\tfile %s %u %u", name.c_str(), offset, size);
+ // debug("\t\tfile %s %u %u", name.c_str(), offset, size);
ArchiveMemberPtr resource(new ArchiveMember(this, name, offset, size));
_members.setVal(name, resource);
}
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 635e99a4734..670b4e21e65 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -22,31 +22,32 @@
#ifndef AGDS_RESOURCE_MANAGER_H
#define AGDS_RESOURCE_MANAGER_H
-#include "common/scummsys.h"
#include "common/archive.h"
#include "common/file.h"
-#include "common/str.h"
-#include "common/ptr.h"
-#include "common/hashmap.h"
#include "common/hash-str.h"
+#include "common/hashmap.h"
+#include "common/ptr.h"
+#include "common/scummsys.h"
+#include "common/str.h"
-namespace Graphics { struct Surface; struct PixelFormat; }
+namespace Graphics {
+struct Surface;
+struct PixelFormat;
+} // namespace Graphics
namespace AGDS {
class ResourceManager {
private:
-
class GrpFile;
class ArchiveMember : public Common::ArchiveMember {
- GrpFile *_parent;
- Common::String _name;
- uint32 _offset;
- uint32 _size;
+ GrpFile *_parent;
+ Common::String _name;
+ uint32 _offset;
+ uint32 _size;
public:
- ArchiveMember(GrpFile * parent, const Common::String &name, uint32 offset, uint32 size):
- _parent(parent), _name(name), _offset(offset), _size(size) {
+ ArchiveMember(GrpFile *parent, const Common::String &name, uint32 offset, uint32 size) : _parent(parent), _name(name), _offset(offset), _size(size) {
}
Common::SeekableReadStream *createReadStream() const override;
Common::String getName() const override {
@@ -65,7 +66,7 @@ private:
using ArchiveMemberPtr = Common::SharedPtr<ArchiveMember>;
class GrpFile : public Common::Archive {
- Common::File _file;
+ Common::File _file;
using MembersType = Common::HashMap<Common::String, ArchiveMemberPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
MembersType _members;
@@ -87,7 +88,7 @@ public:
ResourceManager();
~ResourceManager();
- static void decrypt(uint8 * data, unsigned size);
+ static void decrypt(uint8 *data, unsigned size);
bool addPath(const Common::Path &grpFilename);
diff --git a/engines/agds/screen.cpp b/engines/agds/screen.cpp
index 9ed3d976188..9b7d3b967a2 100644
--- a/engines/agds/screen.cpp
+++ b/engines/agds/screen.cpp
@@ -39,11 +39,10 @@ int Screen::AnimationZCompare(const ScreenAnimationDesc &a, const ScreenAnimatio
return b.animation->z() - a.animation->z();
}
-Screen::Screen(AGDSEngine * engine, ObjectPtr object, ScreenLoadingType loadingType, const Common::String &prevScreen) :
- _engine(engine), _object(object), _background(nullptr),
- _name(object->getName()), _loadingType(loadingType), _previousScreen(prevScreen),
- _children(&ObjectZCompare), _animations(&AnimationZCompare), _applyingPatch(false),
- _characterNear(g_system->getHeight()), _characterFar(g_system->getHeight()), _fade(0) {
+Screen::Screen(AGDSEngine *engine, ObjectPtr object, ScreenLoadingType loadingType, const Common::String &prevScreen) : _engine(engine), _object(object), _background(nullptr),
+ _name(object->getName()), _loadingType(loadingType), _previousScreen(prevScreen),
+ _children(&ObjectZCompare), _animations(&AnimationZCompare), _applyingPatch(false),
+ _characterNear(g_system->getHeight()), _characterFar(g_system->getHeight()), _fade(0) {
add(object);
}
@@ -76,7 +75,6 @@ void Screen::scrollTo(Common::Point scroll) {
_scroll = scroll;
}
-
float Screen::getZScale(int y) const {
int h = g_system->getHeight();
int dy = h - y;
@@ -89,13 +87,12 @@ float Screen::getZScale(int y) const {
return 1.0f;
}
-
bool Screen::add(ObjectPtr object) {
if (object == NULL) {
warning("refusing to add null to scene");
return false;
}
- for (auto i = _children.begin(); i != _children.end(); ) {
+ for (auto i = _children.begin(); i != _children.end();) {
if (*i == object) {
if (object->alive()) {
debug("double adding object %s", object->getName().c_str());
@@ -120,13 +117,12 @@ void Screen::add(AnimationPtr animation) {
warning("Screen: skipping null animation");
}
-
-bool Screen::remove(const AnimationPtr & animation) {
+bool Screen::remove(const AnimationPtr &animation) {
if (!animation)
return false;
bool removed = false;
- for(auto i = _animations.begin(); i != _animations.end(); ++i) {
+ for (auto i = _animations.begin(); i != _animations.end(); ++i) {
if (i->animation == animation) {
debug("removing animation %s:%s", animation->process().c_str(), animation->phaseVar().c_str());
i->removed = true;
@@ -160,7 +156,7 @@ bool Screen::remove(const ObjectPtr &object) {
bool Screen::remove(const Common::String &name) {
for (auto i = _children.begin(); i != _children.end(); ++i) {
- const ObjectPtr & object = *i;
+ const ObjectPtr &object = *i;
if (object->getName() == name) {
if (object->locked())
object->alive(false);
@@ -174,8 +170,8 @@ bool Screen::remove(const Common::String &name) {
AnimationPtr Screen::findAnimationByPhaseVar(const Common::String &phaseVar) {
for (auto i = _animations.begin(); i != _animations.end(); ++i) {
- const auto & desc = *i;
- const auto & animation = desc.animation;
+ const auto &desc = *i;
+ const auto &animation = desc.animation;
if (!desc.removed && animation->phaseVar() == phaseVar)
return animation;
}
@@ -183,9 +179,9 @@ AnimationPtr Screen::findAnimationByPhaseVar(const Common::String &phaseVar) {
}
void Screen::tick() {
- for (uint i = 0; i < _animations.size(); ) {
- const auto & desc = _animations.data()[i];
- const auto & animation = desc.animation;
+ for (uint i = 0; i < _animations.size();) {
+ const auto &desc = _animations.data()[i];
+ const auto &animation = desc.animation;
if (!desc.removed && animation->tick())
++i;
else {
@@ -196,8 +192,8 @@ void Screen::tick() {
}
void Screen::paint(Graphics::Surface &backbuffer) const {
- auto & currentInventoryObject = _engine->currentInventoryObject();
- Character * character = _engine->currentCharacter();
+ auto ¤tInventoryObject = _engine->currentInventoryObject();
+ Character *character = _engine->currentCharacter();
auto child = _children.begin();
auto desc = _animations.begin();
@@ -213,7 +209,7 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
int z = 0;
int render_type = -1;
if (animation_valid) {
- const auto & animation = desc->animation;
+ const auto &animation = desc->animation;
if (!z_valid || animation->z() > z) {
z = animation->z();
z_valid = true;
@@ -238,7 +234,7 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
auto basePos = Common::Point() - _scroll;
switch (render_type) {
case 0:
- //debug("object z: %d", (*child)->z());
+ // debug("object z: %d", (*child)->z());
if ((*child) != currentInventoryObject && (*child)->alive()) {
if ((*child)->scale() < 0)
basePos = Common::Point();
@@ -247,14 +243,14 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
++child;
break;
case 1:
- //debug("animation z: %d", (*animation)->z());
+ // debug("animation z: %d", (*animation)->z());
if ((*desc).animation->scale() < 0)
basePos = Common::Point();
(*desc).animation->paint(backbuffer, basePos);
++desc;
break;
case 2:
- //debug("character z: %d", character->z());
+ // debug("character z: %d", character->z());
character->paint(backbuffer, basePos);
character = nullptr;
break;
@@ -264,9 +260,9 @@ void Screen::paint(Graphics::Surface &backbuffer) const {
}
if (_fade != 0) {
auto alpha = (100 - _fade) * 256 / 100;
- auto & format = backbuffer.format;
+ auto &format = backbuffer.format;
for (int y = 0; y < backbuffer.h; ++y) {
- uint32 * line = (uint32 *)backbuffer.getBasePtr(0, y);
+ uint32 *line = (uint32 *)backbuffer.getBasePtr(0, y);
int w = backbuffer.w;
while (w--) {
uint8 r, g, b;
@@ -284,13 +280,13 @@ Common::Array<ObjectPtr> Screen::find(Common::Point pos) const {
Common::Array<ObjectPtr> objects;
objects.reserve(_children.size());
for (auto i = _children.begin(); i != _children.end(); ++i) {
- const auto & object = *i;
+ const auto &object = *i;
auto visiblePos = (object->scale() >= 0) ? pos + _scroll : pos;
if (object->pointIn(visiblePos) && object->alive()) {
objects.insert_at(0, object);
}
}
- Character * character = _engine->currentCharacter();
+ Character *character = _engine->currentCharacter();
if (character) {
if (character->pointIn(pos - _scroll)) {
objects.insert_at(0, character->object());
@@ -302,7 +298,7 @@ Common::Array<ObjectPtr> Screen::find(Common::Point pos) const {
Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
KeyHandler keyHandler;
for (auto i = _children.begin(); i != _children.end(); ++i) {
- const auto & object = *i;
+ const auto &object = *i;
if (!object->alive())
continue;
@@ -319,7 +315,7 @@ Screen::KeyHandler Screen::findKeyHandler(const Common::String &keyName) {
void Screen::load(const PatchPtr &patch) {
debug("applying patch with %u objects", patch->objects.size());
_applyingPatch = true;
- for(uint i = 0; i < patch->objects.size(); ++i) {
+ for (uint i = 0; i < patch->objects.size(); ++i) {
const Patch::Object &object = patch->objects[i];
debug("patch object %s %d", object.name.c_str(), object.flag);
if (object.name == _name)
@@ -341,7 +337,7 @@ void Screen::save(const PatchPtr &patch) {
patch->loadingType = _loadingType;
patch->objects.clear();
for (auto i = _children.begin(); i != _children.end(); ++i) {
- const auto & object = *i;
+ const auto &object = *i;
if (!object->persistent() || !object->alive() || object->getName() == _name)
continue;
debug("saving patch object %s %d", object->getName().c_str(), object->alive());
@@ -349,5 +345,4 @@ void Screen::save(const PatchPtr &patch) {
}
}
-
} // namespace AGDS
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 0dc8900e301..6a6df39d27a 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -22,15 +22,15 @@
#ifndef AGDS_SCREEN_H
#define AGDS_SCREEN_H
-#include "common/scummsys.h"
+#include "agds/screenLoadingType.h"
#include "common/array.h"
#include "common/ptr.h"
-#include "common/str.h"
#include "common/rect.h"
-#include "agds/screenLoadingType.h"
+#include "common/scummsys.h"
+#include "common/str.h"
namespace Graphics {
- struct Surface;
+struct Surface;
}
namespace AGDS {
@@ -48,7 +48,7 @@ using PatchPtr = Common::SharedPtr<Patch>;
struct ScreenAnimationDesc {
AnimationPtr animation;
bool removed = false;
- ScreenAnimationDesc(const AnimationPtr &a): animation(a) {
+ ScreenAnimationDesc(const AnimationPtr &a) : animation(a) {
}
};
@@ -59,27 +59,27 @@ class Screen {
using Animations = Common::SortedArray<ScreenAnimationDesc, const ScreenAnimationDesc &>;
using Children = Common::SortedArray<ObjectPtr, const ObjectPtr &>;
- AGDSEngine *_engine;
- ObjectPtr _object;
- Object *_background;
- Common::Point _scroll;
- Common::String _name;
+ AGDSEngine *_engine;
+ ObjectPtr _object;
+ Object *_background;
+ Common::Point _scroll;
+ Common::String _name;
ScreenLoadingType _loadingType;
- Common::String _previousScreen;
- Children _children;
- Animations _animations;
- RegionPtr _region;
- bool _applyingPatch;
- int _characterNear, _characterFar;
- int _fade;
+ Common::String _previousScreen;
+ Children _children;
+ Animations _animations;
+ RegionPtr _region;
+ bool _applyingPatch;
+ int _characterNear, _characterFar;
+ int _fade;
public:
struct KeyHandler {
- ObjectPtr object;
- uint ip;
+ ObjectPtr object;
+ uint ip;
- KeyHandler(): object(), ip() { }
- KeyHandler(Object *o, uint i): object(o), ip(i) { }
+ KeyHandler() : object(), ip() {}
+ KeyHandler(Object *o, uint i) : object(o), ip(i) {}
};
Screen(AGDSEngine *engine, ObjectPtr object, ScreenLoadingType loadingType, const Common::String &prevScreen);
@@ -132,7 +132,7 @@ public:
return _children;
}
- const Animations & animations() const {
+ const Animations &animations() const {
return _animations;
}
void scrollTo(Common::Point scroll);
@@ -142,7 +142,7 @@ public:
bool add(ObjectPtr object);
void add(AnimationPtr animation);
- bool remove(const AnimationPtr &animation);
+ bool remove(const AnimationPtr &animation);
void update(const ObjectPtr &object) {
bool found = remove(object);
@@ -168,7 +168,6 @@ public:
void save(const PatchPtr &patch);
};
-
} // End of namespace AGDS
#endif /* AGDS_SCREEN_H */
diff --git a/engines/agds/soundManager.cpp b/engines/agds/soundManager.cpp
index 81a9e1d2b26..28e5ab59169 100644
--- a/engines/agds/soundManager.cpp
+++ b/engines/agds/soundManager.cpp
@@ -32,7 +32,7 @@
namespace AGDS {
void SoundManager::tick() {
- for (auto it = _sounds.begin(); it != _sounds.end(); ) {
+ for (auto it = _sounds.begin(); it != _sounds.end();) {
Sound &sound = *it;
auto &phaseVar = sound.phaseVar;
@@ -86,7 +86,6 @@ Sound *SoundManager::findSampleByPhaseVar(const Common::String &phaseVar) {
return nullptr;
}
-
void SoundManager::stopAll() {
_mixer->stopAll();
for (auto i = _sounds.begin(); i != _sounds.end(); ++i) {
@@ -98,7 +97,7 @@ void SoundManager::stopAll() {
}
void SoundManager::stopAllFrom(const Common::String &process) {
- for (auto i = _sounds.begin(); i != _sounds.end(); ) {
+ for (auto i = _sounds.begin(); i != _sounds.end();) {
auto &sound = *i;
if (sound.process == process) {
_mixer->stopID(sound.id);
@@ -111,7 +110,6 @@ void SoundManager::stopAllFrom(const Common::String &process) {
}
}
-
int SoundManager::play(Common::String process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int volume, int pan, int id, bool ambient) {
debug("SoundMan::play(process: '%s', resource: '%s', filename: '%s', phaseVar: '%s', start: %d, volume: %d, pan: %d, id: %d, ambient: %d", process.c_str(), resource.c_str(), filename.c_str(), phaseVar.c_str(), startPlaying, volume, pan, id, ambient);
if (filename.empty())
@@ -146,7 +144,7 @@ int SoundManager::play(Common::String process, const Common::String &resource, c
if (!stream) {
warning("could not play sound %s", filename.c_str());
if (!phaseVar.empty())
- _engine->setGlobal(phaseVar, _engine->getGlobal(phaseVar)? 1: 0);
+ _engine->setGlobal(phaseVar, _engine->getGlobal(phaseVar) ? 1 : 0);
else
_engine->reactivate(process, "no sound");
return -1;
@@ -158,12 +156,12 @@ int SoundManager::play(Common::String process, const Common::String &resource, c
auto handle = &_sounds.back().handle;
if (startPlaying)
_mixer->playStream(
- ambient? Audio::Mixer::kMusicSoundType: Audio::Mixer::kPlainSoundType,
+ ambient ? Audio::Mixer::kMusicSoundType : Audio::Mixer::kPlainSoundType,
&_sounds.back().handle, stream, id,
volume * Audio::Mixer::kMaxChannelVolume / 100, pan * 127 / 100);
if (ambient)
_mixer->loopChannel(*handle);
- //if (sound_off)
+ // if (sound_off)
// setPhaseVar(_sounds.back(), 1);
return id;
}
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index 62c110030d9..93a1e19559f 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -22,59 +22,62 @@
#ifndef AGDS_SOUND_MANAGER_H
#define AGDS_SOUND_MANAGER_H
+#include "audio/mixer.h"
+#include "common/hashmap.h"
+#include "common/list.h"
#include "common/scummsys.h"
#include "common/str.h"
-#include "common/list.h"
-#include "common/hashmap.h"
-#include "audio/mixer.h"
-namespace Common { class SeekableReadStream; }
-namespace Audio { class Mixer; }
+namespace Common {
+class SeekableReadStream;
+}
+namespace Audio {
+class Mixer;
+}
namespace AGDS {
- class AGDSEngine;
+class AGDSEngine;
- struct Sound {
- int id;
- Common::String process;
- Common::String resource;
- Common::String filename;
- Common::String phaseVar;
- Audio::SoundHandle handle;
- int volume;
- int pan;
- int group;
- bool paused;
- Sound(int id_, const Common::String &process_, const Common::String &res, const Common::String &filename_, const Common::String &var, int volume_, int pan_, int group_ = 0):
- id(id_), process(process_), resource(res), filename(filename_), phaseVar(var), handle(), volume(volume_), pan(pan_), group(group_), paused(false) {
- }
+struct Sound {
+ int id;
+ Common::String process;
+ Common::String resource;
+ Common::String filename;
+ Common::String phaseVar;
+ Audio::SoundHandle handle;
+ int volume;
+ int pan;
+ int group;
+ bool paused;
+ Sound(int id_, const Common::String &process_, const Common::String &res, const Common::String &filename_, const Common::String &var, int volume_, int pan_, int group_ = 0) : id(id_), process(process_), resource(res), filename(filename_), phaseVar(var), handle(), volume(volume_), pan(pan_), group(group_), paused(false) {
+ }
- int leftVolume() const {
- return pan < 0? volume: volume * (100 - pan) / 100;
- }
+ int leftVolume() const {
+ return pan < 0 ? volume : volume * (100 - pan) / 100;
+ }
- int rightVolume() const {
- return pan < 0? volume * (100 + pan) / 100: volume;
- }
- };
+ int rightVolume() const {
+ return pan < 0 ? volume * (100 + pan) / 100 : volume;
+ }
+};
- class SoundManager {
- using SoundList = Common::List<Sound>;
- int _nextId;
- AGDSEngine *_engine;
- Audio::Mixer *_mixer;
- SoundList _sounds;
+class SoundManager {
+ using SoundList = Common::List<Sound>;
+ int _nextId;
+ AGDSEngine *_engine;
+ Audio::Mixer *_mixer;
+ SoundList _sounds;
- public:
- SoundManager(AGDSEngine *engine, Audio::Mixer *mixer): _nextId(1), _engine(engine), _mixer(mixer) { }
- void tick();
- int play(Common::String process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int volume, int pan, int id = -1, bool ambient = false);
- bool playing(int id) const;
- void stopAllFrom(const Common::String &process);
- void stopAll();
- const Sound *find(int id) const;
- Sound *findSampleByPhaseVar(const Common::String &phaseVar);
- };
+public:
+ SoundManager(AGDSEngine *engine, Audio::Mixer *mixer) : _nextId(1), _engine(engine), _mixer(mixer) {}
+ void tick();
+ int play(Common::String process, const Common::String &resource, const Common::String &filename, const Common::String &phaseVar, bool startPlaying, int volume, int pan, int id = -1, bool ambient = false);
+ bool playing(int id) const;
+ void stopAllFrom(const Common::String &process);
+ void stopAll();
+ const Sound *find(int id) const;
+ Sound *findSampleByPhaseVar(const Common::String &phaseVar);
+};
} // End of namespace AGDS
diff --git a/engines/agds/systemVariable.h b/engines/agds/systemVariable.h
index 86305183b36..fc9e2d20bfb 100644
--- a/engines/agds/systemVariable.h
+++ b/engines/agds/systemVariable.h
@@ -26,9 +26,9 @@
#include "common/str.h"
namespace Common {
- class ReadStream;
- class WriteStream;
-}
+class ReadStream;
+class WriteStream;
+} // namespace Common
namespace AGDS {
@@ -50,8 +50,7 @@ class IntegerSystemVariable : public SystemVariable {
int _defaultValue;
public:
- IntegerSystemVariable(int defaultValue = 0):
- _value(defaultValue), _defaultValue(defaultValue) {
+ IntegerSystemVariable(int defaultValue = 0) : _value(defaultValue), _defaultValue(defaultValue) {
}
virtual const Common::String &getString() const;
@@ -66,12 +65,11 @@ public:
};
class StringSystemVariable : public SystemVariable {
- Common::String _value;
- Common::String _defaultValue;
+ Common::String _value;
+ Common::String _defaultValue;
public:
- StringSystemVariable(const Common::String &defaultValue = Common::String()):
- _value(defaultValue), _defaultValue(defaultValue) {
+ StringSystemVariable(const Common::String &defaultValue = Common::String()) : _value(defaultValue), _defaultValue(defaultValue) {
}
virtual const Common::String &getString() const;
virtual int getInteger() const;
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index 362f869f027..b66b96839d7 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -20,9 +20,9 @@
*/
#include "agds/textLayout.h"
-#include "agds/font.h"
#include "agds/agds.h"
#include "agds/character.h"
+#include "agds/font.h"
#include "agds/object.h"
#include "agds/process.h"
#include "agds/systemVariable.h"
@@ -35,7 +35,7 @@ void TextLayout::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
return;
Font *font = engine.getFont(_fontId);
for (uint i = 0; i < _lines.size(); ++i) {
- Line & line = _lines[i];
+ Line &line = _lines[i];
font->drawString(&backbuffer, line.text, line.pos.x, line.pos.y, line.size.x, 0);
}
}
@@ -46,7 +46,7 @@ void TextLayout::reset(AGDSEngine &engine) {
_lines.clear();
if (valid) {
- Common::String &var = _npc? _npcNotifyVar: _charNotifyVar;
+ Common::String &var = _npc ? _npcNotifyVar : _charNotifyVar;
if (!var.empty()) {
engine.setGlobal(var, 0);
}
@@ -89,7 +89,7 @@ void TextLayout::layout(AGDSEngine &engine, Process &process, const Common::Stri
size.y = font->getFontHeight();
_lines.push_back(Line());
- Line & l = _lines.back();
+ Line &l = _lines.back();
l.pos = basePos;
l.text = line;
l.size = size;
@@ -101,14 +101,14 @@ void TextLayout::layout(AGDSEngine &engine, Process &process, const Common::Stri
int dy = -basePos.y / 2;
for (uint i = 0; i < _lines.size(); ++i) {
- Line & line = _lines[i];
+ Line &line = _lines[i];
line.pos.x += pos.x - line.size.x / 2;
line.pos.y += pos.y + dy;
}
_valid = true;
- Common::String &var = _npc? _npcNotifyVar: _charNotifyVar;
+ Common::String &var = _npc ? _npcNotifyVar : _charNotifyVar;
if (!var.empty()) {
if (!engine.getGlobal(var))
engine.setGlobal(var, 1);
@@ -120,7 +120,7 @@ void TextLayout::layout(AGDSEngine &engine, Process &process, const Common::Stri
if (!engine.getGlobal(_charDirectionNotifyVar))
engine.setGlobal(_charDirectionNotifyVar, character->direction());
} else {
- switch(character->direction()) {
+ switch (character->direction()) {
case 0:
case 1:
case 2:
@@ -138,4 +138,4 @@ void TextLayout::layout(AGDSEngine &engine, Process &process, const Common::Stri
}
}
-}
+} // namespace AGDS
diff --git a/engines/agds/textLayout.h b/engines/agds/textLayout.h
index 7822fb73a52..c6fffe5e32e 100644
--- a/engines/agds/textLayout.h
+++ b/engines/agds/textLayout.h
@@ -22,13 +22,13 @@
#ifndef AGDS_TEXT_LAYOUT_H
#define AGDS_TEXT_LAYOUT_H
-#include "common/scummsys.h"
#include "common/array.h"
-#include "common/str.h"
#include "common/rect.h"
+#include "common/scummsys.h"
+#include "common/str.h"
namespace Graphics {
- struct Surface;
+struct Surface;
}
namespace AGDS {
@@ -37,10 +37,10 @@ class AGDSEngine;
class Process;
class TextLayout {
- int _fontId;
- Common::Point _pos;
- bool _npc;
- bool _valid;
+ int _fontId;
+ Common::Point _pos;
+ bool _npc;
+ bool _valid;
struct Line {
Common::Point pos;
@@ -50,13 +50,13 @@ class TextLayout {
Common::Array<Line> _lines;
- Common::String _process;
- Common::String _charNotifyVar;
- Common::String _charDirectionNotifyVar;
- Common::String _npcNotifyVar;
+ Common::String _process;
+ Common::String _charNotifyVar;
+ Common::String _charDirectionNotifyVar;
+ Common::String _npcNotifyVar;
public:
- TextLayout(): _fontId(-1), _npc(true), _valid(false) {}
+ TextLayout() : _fontId(-1), _npc(true), _valid(false) {}
bool valid() const {
return _valid;
Commit: 21067ffaa5c1b5f361a4e1e95701943b87847e1e
https://github.com/scummvm/scummvm/commit/21067ffaa5c1b5f361a4e1e95701943b87847e1e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:14+01:00
Commit Message:
AGDS: add more v2 opcores
Changed paths:
engines/agds/process.cpp
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index fbda099361a..c0db5a7f2ac 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -422,6 +422,15 @@ ProcessExitCode Process::resume() {
case 8013:
op = kPushImm8_2;
break;
+ case 8043:
+ op = kSetGlobal;
+ break;
+ case 8137:
+ op = kSetStringSystemVariable;
+ break;
+ case 8193:
+ op = kLoadMouse;
+ break;
default:
break;
}
Commit: cf0ba514d982b735158ad45dde23dfebb1f0fb53
https://github.com/scummvm/scummvm/commit/cf0ba514d982b735158ad45dde23dfebb1f0fb53
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:14+01:00
Commit Message:
AGDS: add IsBMP
Changed paths:
engines/agds/agds.cpp
engines/agds/animation.cpp
engines/agds/process.cpp
engines/agds/resourceManager.cpp
engines/agds/resourceManager.h
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index ad3bbecaa97..4bd855e4da9 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -853,12 +853,12 @@ int AGDSEngine::getGlobal(const Common::String &name) const {
AnimationPtr AGDSEngine::loadAnimation(const Common::String &name) {
debug("loadAnimation %s", name.c_str());
- Common::SeekableReadStream *stream = _resourceManager.getResource(name);
+ Common::ScopedPtr<Common::SeekableReadStream> stream(_resourceManager.getResource(name));
if (!stream)
error("could not load animation from %s", name.c_str());
Common::SharedPtr<Animation> animation(new Animation(this, name));
- if (!animation->load(stream, name))
+ if (!animation->load(stream.release(), name))
error("could not load animation from %s", name.c_str());
return animation;
diff --git a/engines/agds/animation.cpp b/engines/agds/animation.cpp
index 59bbe475606..b945c8d6f7a 100644
--- a/engines/agds/animation.cpp
+++ b/engines/agds/animation.cpp
@@ -22,6 +22,7 @@
#include "agds/animation.h"
#include "agds/agds.h"
#include "agds/object.h"
+#include "agds/resourceManager.h"
#include "common/debug.h"
#include "common/textconsole.h"
#include "graphics/managed_surface.h"
@@ -80,8 +81,9 @@ bool Animation::load(Common::SeekableReadStream *stream, const Common::String &f
}
}
_flic.reset();
+ auto is_bmp = ResourceManager::IsBMP(*stream);
- if (fname.hasSuffixIgnoreCase(".bmp")) {
+ if (fname.hasSuffixIgnoreCase(".bmp") || is_bmp) {
_frame.reset(_engine->loadPicture(fname));
rescaleCurrentFrame();
_frames = 1;
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index c0db5a7f2ac..d6e95afbd76 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -416,6 +416,9 @@ ProcessExitCode Process::resume() {
case 8000:
op = kEnter;
break;
+ case 8005:
+ op = kPop;
+ break;
case 8011:
op = kPushImm8;
break;
diff --git a/engines/agds/resourceManager.cpp b/engines/agds/resourceManager.cpp
index d7a6ab70e71..172d70ce6a0 100644
--- a/engines/agds/resourceManager.cpp
+++ b/engines/agds/resourceManager.cpp
@@ -170,15 +170,24 @@ Common::SeekableReadStream *ResourceManager::getResource(const Common::String &n
return (file.open(Common::Path{name})) ? file.readStream(file.size()) : NULL;
}
+bool ResourceManager::IsBMP(Common::SeekableReadStream &stream) {
+ auto b0 = stream.readByte();
+ auto b1 = stream.readByte();
+ stream.seek(-2, SEEK_CUR);
+ return b0 == 'B' && b1 == 'M';
+}
+
Graphics::Surface *ResourceManager::loadPicture(const Common::String &name, const Graphics::PixelFormat &format) {
Common::SeekableReadStream *stream = getResource(name);
if (!stream)
return NULL;
+ auto is_bmp = IsBMP(*stream);
+
Common::String lname = name;
lname.toLowercase();
- if (lname.hasSuffix(".bmp")) {
+ if (lname.hasSuffix(".bmp") || is_bmp) {
Image::BitmapDecoder bmp;
return bmp.loadStream(*stream) ? bmp.getSurface()->convertTo(format) : NULL;
} else if (lname.hasSuffix(".pcx")) {
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 670b4e21e65..262bfaf3648 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -89,6 +89,7 @@ public:
~ResourceManager();
static void decrypt(uint8 *data, unsigned size);
+ static bool IsBMP(Common::SeekableReadStream &stream);
bool addPath(const Common::Path &grpFilename);
Commit: 12edcfbf9fb802a6ef0b5a52046c8e1d57609ab2
https://github.com/scummvm/scummvm/commit/12edcfbf9fb802a6ef0b5a52046c8e1d57609ab2
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:14+01:00
Commit Message:
AGDS: align load order with original engine
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 4bd855e4da9..878652b11be 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -1158,6 +1158,35 @@ Common::Error AGDSEngine::loadGameState(int slot) {
warning("no character");
}
+ {
+ // Saved ambient sound
+ Common::ScopedPtr<Common::SeekableReadStream> agds_a(db.getEntry(*saveFile, "__agds_a"));
+ auto resource = readString(*agds_a);
+ auto filename = loadText(resource);
+ auto phaseVar = readString(*agds_a);
+ uint volume = agds_a->readUint32LE();
+ uint type = agds_a->readUint32LE();
+ debug("saved audio state: sample: '%s:%s', var: '%s' %u %u", resource.c_str(), filename.c_str(), phaseVar.c_str(), volume, type);
+ debug("phase var for sample -> %d", getGlobal(phaseVar));
+ _ambientSoundId = _soundManager.play(Common::String(), resource, filename, phaseVar, true,
+ volume, /*pan=*/0, /*id=*/-1, /*ambient=*/true);
+ debug("ambient sound id = %d", _ambientSoundId);
+ }
+
+ {
+ // System vars
+ Common::ScopedPtr<Common::SeekableReadStream> agds_d(db.getEntry(*saveFile, "__agds_d"));
+ for (uint i = 0, n = _systemVarList.size(); i < n; ++i) {
+ Common::String &name = _systemVarList[i];
+ _systemVars[name]->read(*agds_d);
+ }
+ }
+
+ {
+ Common::ScopedPtr<Common::SeekableReadStream> agds_i(db.getEntry(*saveFile, "__agds_i"));
+ _inventory.load(*agds_i);
+ }
+
Common::String screenName;
{
// Palette and screen name
@@ -1179,40 +1208,12 @@ Common::Error AGDSEngine::loadGameState(int slot) {
}
}
- {
- // System vars
- Common::ScopedPtr<Common::SeekableReadStream> agds_d(db.getEntry(*saveFile, "__agds_d"));
- for (uint i = 0, n = _systemVarList.size(); i < n; ++i) {
- Common::String &name = _systemVarList[i];
- _systemVars[name]->read(*agds_d);
- }
- }
-
SystemVariable *initVar = getSystemVariable("init_resources");
runObject(initVar->getString());
loadPatches(*saveFile, db);
loadScreen(screenName, ScreenLoadingType::Normal, false);
- {
- // Saved ambient sound
- Common::ScopedPtr<Common::SeekableReadStream> agds_a(db.getEntry(*saveFile, "__agds_a"));
- auto resource = readString(*agds_a);
- auto filename = loadText(resource);
- auto phaseVar = readString(*agds_a);
- uint volume = agds_a->readUint32LE();
- uint type = agds_a->readUint32LE();
- debug("saved audio state: sample: '%s:%s', var: '%s' %u %u", resource.c_str(), filename.c_str(), phaseVar.c_str(), volume, type);
- debug("phase var for sample -> %d", getGlobal(phaseVar));
- _ambientSoundId = _soundManager.play(Common::String(), resource, filename, phaseVar, true,
- volume, /*pan=*/0, /*id=*/-1, /*ambient=*/true);
- debug("ambient sound id = %d", _ambientSoundId);
- }
- {
- Common::ScopedPtr<Common::SeekableReadStream> agds_i(db.getEntry(*saveFile, "__agds_i"));
- _inventory.load(*agds_i);
- }
-
return Common::kNoError;
}
Commit: 4f52bc970d3e5ea1093d542e03912fec3b811e8d
https://github.com/scummvm/scummvm/commit/4f52bc970d3e5ea1093d542e03912fec3b811e8d
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:14+01:00
Commit Message:
AGDS: add missing detection.h file
Changed paths:
A engines/agds/detection.h
diff --git a/engines/agds/detection.h b/engines/agds/detection.h
new file mode 100644
index 00000000000..07fffc1f88a
--- /dev/null
+++ b/engines/agds/detection.h
@@ -0,0 +1,33 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef AGDS_DETECTION_H
+#define AGDS_DETECTION_H
+
+namespace AGDS {
+
+enum AGDSGameFlag {
+ AGDS_V2 = (1 << 0),
+};
+
+} // End of namespace AGDS
+
+#endif // AGDS_DETECTION_H
Commit: f5266f60f5cd557ddb54ba062074466f2d3052be
https://github.com/scummvm/scummvm/commit/f5266f60f5cd557ddb54ba062074466f2d3052be
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:14+01:00
Commit Message:
AGDS: more stubs and general mapping from v2 to v1
Changed paths:
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index bcec7c6b99b..8a9c0a302ec 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -26,7 +26,7 @@
namespace AGDS {
-enum Opcode : uint8 {
+enum Opcode : uint16 {
kEnter = 5,
kJumpZImm16 = 8,
kJumpImm16 = 9,
@@ -259,13 +259,15 @@ enum Opcode : uint8 {
kInventoryHasObjectByName = 238,
kStub239 = 239,
kLoadDialog = 240,
- kStub241 = 241,
+ kColorStub241 = 241,
kHasGlobal = 242,
kStub243 = 243,
kSetCharacterNotifyVars = 244,
kAttachInventoryObjectToMouse1 = 245,
kStub246 = 246,
- kSetDialogForNextFilm = 247
+ kSetDialogForNextFilm = 247,
+ kStub275 = 275,
+ kColorStub276 = 276,
};
#define AGDS_OPCODE_LIST(OP, OP_C, OP_B, OP_W, OP_U, OP_UD, OP_UU) \
@@ -477,10 +479,13 @@ enum Opcode : uint8 {
OP(kInventoryFindObjectByName, inventoryFindObjectByName) \
OP(kInventoryHasObjectByName, inventoryHasObjectByName) \
OP(kLoadDialog, loadDialog) \
+ OP(kColorStub241, colorStub241) \
OP(kHasGlobal, hasGlobal) \
OP(kAttachInventoryObjectToMouse0, attachInventoryObjectToMouse0) \
OP(kAttachInventoryObjectToMouse1, attachInventoryObjectToMouse1) \
- OP(kSetDialogForNextFilm, setDialogForNextFilm)
+ OP(kSetDialogForNextFilm, setDialogForNextFilm) \
+ OP(kStub275, stub275) \
+ OP(kColorStub276, colorStub276)
} // namespace AGDS
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index d6e95afbd76..ea99ae78b3d 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -412,31 +412,7 @@ ProcessExitCode Process::resume() {
op |= next() << 8;
op >>= 1;
}
- switch (op) {
- case 8000:
- op = kEnter;
- break;
- case 8005:
- op = kPop;
- break;
- case 8011:
- op = kPushImm8;
- break;
- case 8013:
- op = kPushImm8_2;
- break;
- case 8043:
- op = kSetGlobal;
- break;
- case 8137:
- op = kSetStringSystemVariable;
- break;
- case 8193:
- op = kLoadMouse;
- break;
- default:
- break;
- }
+ op -= 7995;
}
// debug("CODE %04x: %u", _lastIp, (uint)op);
switch (op) {
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 46c29034508..faef59f5ae4 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1268,6 +1268,25 @@ void Process::playerSay125() {
playerSay120(); // same case
}
+void Process::colorStub241() {
+ int b = pop();
+ int g = pop();
+ int r = pop();
+ debug("colorStub241 #%02x%02x%02x", r, g, b);
+}
+
+void Process::colorStub276() {
+ int b = pop();
+ int g = pop();
+ int r = pop();
+ debug("colorStub276 #%02x%02x%02x", r, g, b);
+}
+
+void Process::stub275() {
+ auto x = pop();
+ debug("stub275: %d", x);
+}
+
void Process::loadDialog() {
Common::String arg3 = popString();
Common::String arg2 = popString();
Commit: 944b06125e8aa992f5276191e01c1143c8b32e4b
https://github.com/scummvm/scummvm/commit/944b06125e8aa992f5276191e01c1143c8b32e4b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:14+01:00
Commit Message:
AGDS: add v2 loadTTF stub
Changed paths:
engines/agds/agds.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 878652b11be..36a8c085f1b 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -905,9 +905,13 @@ Graphics::ManagedSurface *AGDSEngine::loadFromCache(int id) const {
}
void AGDSEngine::loadFont(int id, const Common::String &name, int gw, int gh) {
- debug("loadFont %d %s %d %d", id, name.c_str(), gw, gh);
- Graphics::ManagedSurface *surface = loadPicture(name);
- _fonts[id].reset(new Font(surface, gw, gh));
+ if (v2()) {
+ debug("loadTTF %d %s, pixelSize: %d: stub", id, name.c_str(), gh);
+ } else {
+ debug("loadFont %d %s %d %d", id, name.c_str(), gw, gh);
+ Graphics::ManagedSurface *surface = loadPicture(name);
+ _fonts[id].reset(new Font(surface, gw, gh));
+ }
}
Font *AGDSEngine::getFont(int id) const {
Commit: 57e4588cc70fef1a642def607e938f148060967e
https://github.com/scummvm/scummvm/commit/57e4588cc70fef1a642def607e938f148060967e
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:15+01:00
Commit Message:
AGDS: enough stubs to run NiBiRu intro
Changed paths:
engines/agds/agds.cpp
engines/agds/opcode.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 36a8c085f1b..108f9ba0da2 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -853,11 +853,16 @@ int AGDSEngine::getGlobal(const Common::String &name) const {
AnimationPtr AGDSEngine::loadAnimation(const Common::String &name) {
debug("loadAnimation %s", name.c_str());
+ Common::SharedPtr<Animation> animation(new Animation(this, name));
+ if (v2()) {
+ debug("v2 stub");
+ return animation;
+ }
+
Common::ScopedPtr<Common::SeekableReadStream> stream(_resourceManager.getResource(name));
if (!stream)
error("could not load animation from %s", name.c_str());
- Common::SharedPtr<Animation> animation(new Animation(this, name));
if (!animation->load(stream.release(), name))
error("could not load animation from %s", name.c_str());
@@ -876,7 +881,13 @@ void AGDSEngine::loadCharacter(const Common::String &id, const Common::String &f
_currentCharacterObject = object;
_currentCharacter.reset(new Character(this, id));
- Common::ScopedPtr<Common::SeekableReadStream> stream(_resourceManager.getResource(loadText(filename)));
+ auto resName = loadText(filename);
+ if (v2()) {
+ debug("character resource name: %s, stub\n", resName.c_str());
+ _currentCharacter->associate(object);
+ return;
+ }
+ Common::ScopedPtr<Common::SeekableReadStream> stream(_resourceManager.getResource(resName));
_currentCharacter->load(*stream);
_currentCharacter->associate(object);
}
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 8a9c0a302ec..9046fd98fac 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -266,8 +266,11 @@ enum Opcode : uint16 {
kAttachInventoryObjectToMouse1 = 245,
kStub246 = 246,
kSetDialogForNextFilm = 247,
+ kSetCamera = 252,
+ kSetFog = 263,
kStub275 = 275,
kColorStub276 = 276,
+ kStub284 = 284,
};
#define AGDS_OPCODE_LIST(OP, OP_C, OP_B, OP_W, OP_U, OP_UD, OP_UU) \
@@ -485,7 +488,10 @@ enum Opcode : uint16 {
OP(kAttachInventoryObjectToMouse1, attachInventoryObjectToMouse1) \
OP(kSetDialogForNextFilm, setDialogForNextFilm) \
OP(kStub275, stub275) \
- OP(kColorStub276, colorStub276)
+ OP(kColorStub276, colorStub276) \
+ OP(kSetCamera, setCamera) \
+ OP(kSetFog, setFog) \
+ OP(kStub284, stub284)
} // namespace AGDS
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index faef59f5ae4..f3194788bdc 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1287,6 +1287,23 @@ void Process::stub275() {
debug("stub275: %d", x);
}
+void Process::setCamera() {
+ auto lens = pop();
+ auto unk = pop();
+ auto camera = pop();
+ debug("setCamera %d %d %d", camera, unk, lens);
+}
+
+void Process::setFog() {
+ auto unk2 = pop();
+ auto unk1 = pop();
+ debug("setFog %d %d: stub", unk1, unk2);
+}
+
+void Process::stub284() {
+ debug("stub284");
+}
+
void Process::loadDialog() {
Common::String arg3 = popString();
Common::String arg2 = popString();
Commit: 8b0b73414a9370cb991c9f2f05cc03666a1cca9f
https://github.com/scummvm/scummvm/commit/8b0b73414a9370cb991c9f2f05cc03666a1cca9f
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:15+01:00
Commit Message:
AGDS: mark nibiru as unstable (it's possible to get to the start of the intro)
Changed paths:
engines/agds/detection_tables.h
diff --git a/engines/agds/detection_tables.h b/engines/agds/detection_tables.h
index 04e6f7e5faf..96592d21c2c 100644
--- a/engines/agds/detection_tables.h
+++ b/engines/agds/detection_tables.h
@@ -47,7 +47,7 @@ static const ADGameDescription gameDescriptions[] = {
AD_ENTRY1s("gfx1.grp", "c8e711bc01b16cd82849cbd996d02642", 381768360),
Common::RU_RUS,
Common::kPlatformWindows,
- ADGF_DROPPLATFORM | AGDS_V2 | ADGF_UNSUPPORTED,
+ ADGF_DROPPLATFORM | AGDS_V2 | ADGF_UNSTABLE,
GUIO1(GUIO_NONE)},
AD_TABLE_END_MARKER};
Commit: 081c77cc60c187832befa100ed75a8a507e5d6e6
https://github.com/scummvm/scummvm/commit/081c77cc60c187832befa100ed75a8a507e5d6e6
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:15+01:00
Commit Message:
AGDS: add all v2 stubs for intro
Changed paths:
engines/agds/opcode.h
engines/agds/process.cpp
engines/agds/process.h
engines/agds/process_opcodes.cpp
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 9046fd98fac..0d603deb860 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -259,7 +259,7 @@ enum Opcode : uint16 {
kInventoryHasObjectByName = 238,
kStub239 = 239,
kLoadDialog = 240,
- kColorStub241 = 241,
+ kStub241 = 241,
kHasGlobal = 242,
kStub243 = 243,
kSetCharacterNotifyVars = 244,
@@ -267,10 +267,23 @@ enum Opcode : uint16 {
kStub246 = 246,
kSetDialogForNextFilm = 247,
kSetCamera = 252,
+ kStub251 = 251,
+ kCharacterStub253 = 253,
+ kStub257 = 257,
+ kStub258 = 258,
kSetFog = 263,
+ kStub264 = 264,
+ kStub265 = 265,
+ kStub266 = 266,
+ kStub267 = 267,
kStub275 = 275,
- kColorStub276 = 276,
+ kStub276 = 276,
+ kStub278 = 278,
+ kStub279 = 279,
+ kStub280 = 280,
kStub284 = 284,
+ kStub291 = 291,
+ kStub292 = 292,
};
#define AGDS_OPCODE_LIST(OP, OP_C, OP_B, OP_W, OP_U, OP_UD, OP_UU) \
@@ -482,16 +495,29 @@ enum Opcode : uint16 {
OP(kInventoryFindObjectByName, inventoryFindObjectByName) \
OP(kInventoryHasObjectByName, inventoryHasObjectByName) \
OP(kLoadDialog, loadDialog) \
- OP(kColorStub241, colorStub241) \
+ OP(kStub241, stub241) \
OP(kHasGlobal, hasGlobal) \
OP(kAttachInventoryObjectToMouse0, attachInventoryObjectToMouse0) \
OP(kAttachInventoryObjectToMouse1, attachInventoryObjectToMouse1) \
OP(kSetDialogForNextFilm, setDialogForNextFilm) \
+ OP(kCharacterStub253, characterStub253) \
+ OP(kStub251, stub251) \
+ OP(kStub257, stub257) \
+ OP(kStub258, stub258) \
+ OP(kStub264, stub264) \
+ OP(kStub265, stub265) \
+ OP(kStub266, stub266) \
+ OP(kStub267, stub267) \
OP(kStub275, stub275) \
- OP(kColorStub276, colorStub276) \
+ OP(kStub276, stub276) \
OP(kSetCamera, setCamera) \
OP(kSetFog, setFog) \
- OP(kStub284, stub284)
+ OP(kStub278, stub278) \
+ OP(kStub279, stub279) \
+ OP(kStub280, stub280) \
+ OP(kStub284, stub284) \
+ OP(kStub291, stub291) \
+ OP(kStub292, stub292)
} // namespace AGDS
diff --git a/engines/agds/process.cpp b/engines/agds/process.cpp
index ea99ae78b3d..07c0850b186 100644
--- a/engines/agds/process.cpp
+++ b/engines/agds/process.cpp
@@ -152,6 +152,13 @@ Common::String Process::popText() {
return _engine->loadText(popString());
}
+uint32 Process::popColor() {
+ int b = pop();
+ int g = pop();
+ int r = pop();
+ return _engine->pixelFormat().RGBToColor(r, g, b);
+}
+
void Process::updateWithCurrentMousePosition() {
setMousePosition(_engine->mousePosition());
}
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 78273572c5a..9886966cf6d 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -99,6 +99,7 @@ private:
return getString(pop());
}
Common::String popText();
+ uint32 popColor();
#define AGDS_PROCESS_METHOD(opcode, method) \
void method();
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index f3194788bdc..40ecc879104 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -1268,18 +1268,14 @@ void Process::playerSay125() {
playerSay120(); // same case
}
-void Process::colorStub241() {
- int b = pop();
- int g = pop();
- int r = pop();
- debug("colorStub241 #%02x%02x%02x", r, g, b);
+void Process::stub241() {
+ auto color = popColor();
+ debug("stub241 #%08x", color);
}
-void Process::colorStub276() {
- int b = pop();
- int g = pop();
- int r = pop();
- debug("colorStub276 #%02x%02x%02x", r, g, b);
+void Process::stub276() {
+ auto color = popColor();
+ debug("stub276 #%08x", color);
}
void Process::stub275() {
@@ -1300,10 +1296,82 @@ void Process::setFog() {
debug("setFog %d %d: stub", unk1, unk2);
}
+void Process::stub251() {
+ auto arg3 = popString();
+ auto arg2 = popString();
+ auto arg1 = popString();
+ debug("stub251 %s %s %s", arg1.c_str(), arg2.c_str(), arg3.c_str());
+}
+
+void Process::stub257() {
+ auto arg2 = pop();
+ auto arg1 = pop();
+ debug("stub257 %d %d", arg1, arg2);
+}
+
+void Process::stub258() {
+ auto arg = pop();
+ debug("stub258 %d - rotation?", arg);
+}
+
+void Process::stub264() {
+ auto color = popColor();
+ debug("stub264: %08x", color);
+}
+
+void Process::stub265() {
+ auto color = popColor();
+ debug("stub265: %08x", color);
+}
+
+void Process::stub266() {
+ auto color = popColor();
+ debug("stub265: %08x", color);
+}
+
+void Process::stub267() {
+ auto color = popColor();
+ debug("stub267: %08x", color);
+}
+
+void Process::stub278() {
+ auto arg = popString();
+ debug("stub278 %s", arg.c_str());
+}
+
+void Process::stub279() {
+ auto arg = popString();
+ debug("stub279 %s", arg.c_str());
+}
+
+void Process::stub280() {
+ auto arg2 = pop();
+ auto arg1 = popString();
+ debug("stub280 %s %d", arg1.c_str(), arg2);
+}
+
void Process::stub284() {
debug("stub284");
}
+void Process::characterStub253() {
+ auto arg3 = pop();
+ auto arg2 = popString();
+ auto arg1 = popString();
+ debug("characterStub253: %s %s %d", arg1.c_str(), arg2.c_str(), arg3);
+}
+
+void Process::stub291() {
+ auto arg = popString();
+ debug("stub291: %s @ignore @ignore", arg.c_str());
+}
+
+void Process::stub292() {
+ auto arg2 = popString();
+ auto arg1 = popString();
+ debug("stub292: %s %s", arg1.c_str(), arg2.c_str());
+}
+
void Process::loadDialog() {
Common::String arg3 = popString();
Common::String arg2 = popString();
Commit: 72612d55587daaaecc1f5736eaee2164b83948b5
https://github.com/scummvm/scummvm/commit/72612d55587daaaecc1f5736eaee2164b83948b5
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:15+01:00
Commit Message:
AGDS: remove tools
Changed paths:
R engines/agds/tools/decrypt.py
R engines/agds/tools/unpack-db
R engines/agds/tools/unpack-grp
diff --git a/engines/agds/tools/decrypt.py b/engines/agds/tools/decrypt.py
deleted file mode 100644
index a924315de99..00000000000
--- a/engines/agds/tools/decrypt.py
+++ /dev/null
@@ -1,8 +0,0 @@
-key = bytes(map(lambda c: ord(c), 'Vyvojovy tym AGDS varuje: Hackerovani skodi obchodu!'))
-key_n = len(key)
-
-def decrypt(src):
- r = bytearray()
- for i in range(len(src)):
- r.append(src[i] ^ key[i % key_n] ^ 0xff)
- return r
diff --git a/engines/agds/tools/unpack-db b/engines/agds/tools/unpack-db
deleted file mode 100755
index 6544f3993e5..00000000000
--- a/engines/agds/tools/unpack-db
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/usr/bin/env python3
-
-from argparse import ArgumentParser
-from struct import unpack
-import sys
-import os.path
-from decrypt import decrypt
-
-argparser = ArgumentParser('Unpack ADB file')
-argparser.add_argument('file')
-args = argparser.parse_args()
-
-with open(args.file, "rb") as f:
- data = bytearray(f.read())
-
-size = len(data)
-magic, h1, h2, h3, h4 = unpack('<IIIII', data[:0x14])
-if magic != 666:
- raise Exception('invalid db magic', magic)
-
-db_name, _ = os.path.splitext(os.path.basename(args.file))
-try:
- os.makedirs(db_name)
-except:
- pass
-
-print('header', h1, h2, h3, h4)
-
-data_offset = h2 * 0x28 + 0x14
-print('data offset: 0x%08x' %(data_offset))
-for i in range(h3):
- offset = 0x14 + i * 0x28
- entry = data[offset: offset + 0x28]
- name_end = entry.index(bytes([0]), 4)
- name = str(entry[4: name_end], 'utf-8')
- index, = unpack('<I', entry[0:4])
- size, = unpack('<I', entry[0x24:])
- print(repr(name), hex(index), hex(data_offset + index), size)
-
- entry_data = data[data_offset + index: data_offset + index + size]
- with open(os.path.join(db_name, name + '.dec'), 'wb') as fo:
- fo.write(decrypt(entry_data))
-
- with open(os.path.join(db_name, name), 'wb') as fo:
- fo.write(entry_data)
-
diff --git a/engines/agds/tools/unpack-grp b/engines/agds/tools/unpack-grp
deleted file mode 100755
index 598a0c664bf..00000000000
--- a/engines/agds/tools/unpack-grp
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python3
-
-from argparse import ArgumentParser
-from struct import unpack
-from decrypt import decrypt
-
-import sys
-import os.path
-
-argparser = ArgumentParser('unpack GRP file')
-argparser.add_argument('file')
-args = argparser.parse_args()
-
-
-f = open(args.file, "rb")
-
-header = bytes(f.read(0x2c))
-grp_dir = bytes(f.read(0x31))
-
-id = decrypt(header[0:0x10])
-if id != bytes('AGDS group file\x1a', 'ascii'):
- raise Exception('invalid header', id)
-
-version1, magic, version2 = unpack('<III', header[0x10:0x1c])
-if magic != 0x1a03c9e6 or version1 != 44 or version2 != 2:
- raise Exception("unsupported version")
-dir_count, _dc2, _unk14, _unk18 = unpack('<IIII', header[0x1c:])
-
-dir_data = bytearray(f.read(0x31 * dir_count))
-
-gfx_name, _ = os.path.splitext(os.path.basename(args.file))
-try:
- os.makedirs(gfx_name)
-except:
- pass
-
-for offset in range(0, dir_count * 0x31, 0x31):
- entry = dir_data[offset: offset + 0x31]
- name_len = entry.index(bytes([0]))
- if name_len == 0:
- break
- name = str(decrypt(entry[:name_len]), "utf-8")
- offset, size, _unk1, _unk2 = unpack('<IIII', entry[0x21:])
- f.seek(offset)
-
- print("writing file %s" %name)
- with open(os.path.join(gfx_name, name), "wb") as fo:
- fo.write(f.read(size))
Commit: d03c032e0475a9582e9e23b60b9315f14ad1ad83
https://github.com/scummvm/scummvm/commit/d03c032e0475a9582e9e23b60b9315f14ad1ad83
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:15+01:00
Commit Message:
AGDS: try removing namespace from metaengine
Changed paths:
engines/agds/metaengine.cpp
diff --git a/engines/agds/metaengine.cpp b/engines/agds/metaengine.cpp
index 3faa013e82e..1b796590770 100644
--- a/engines/agds/metaengine.cpp
+++ b/engines/agds/metaengine.cpp
@@ -25,8 +25,6 @@
#include "common/system.h"
#include "engines/advancedDetector.h"
-namespace AGDS {
-
class AGDSMetaEngine : public AdvancedMetaEngine<ADGameDescription> {
public:
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
@@ -83,10 +81,8 @@ Common::Error AGDSMetaEngine::createInstance(OSystem *syst, Engine **engine, con
return Common::Error(Common::kNoError);
}
-} // namespace AGDS
-
#if PLUGIN_ENABLED_DYNAMIC(AGDS)
-REGISTER_PLUGIN_DYNAMIC(AGDS, PLUGIN_TYPE_ENGINE, AGDS::AGDSMetaEngine);
+REGISTER_PLUGIN_DYNAMIC(AGDS, PLUGIN_TYPE_ENGINE, AGDSMetaEngine);
#else
-REGISTER_PLUGIN_STATIC(AGDS, PLUGIN_TYPE_ENGINE, AGDS::AGDSMetaEngine);
+REGISTER_PLUGIN_STATIC(AGDS, PLUGIN_TYPE_ENGINE, AGDSMetaEngine);
#endif
Commit: 10a8a876dcc11d4473f652525aaf4add3980a080
https://github.com/scummvm/scummvm/commit/10a8a876dcc11d4473f652525aaf4add3980a080
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:15+01:00
Commit Message:
AGDS: fix header guards
Changed paths:
engines/agds/agds.h
engines/agds/animation.h
engines/agds/character.h
engines/agds/console.h
engines/agds/database.h
engines/agds/detection.h
engines/agds/dialog.h
engines/agds/font.h
engines/agds/inventory.h
engines/agds/mjpgPlayer.h
engines/agds/mouseMap.h
engines/agds/object.h
engines/agds/opcode.h
engines/agds/patch.h
engines/agds/process.h
engines/agds/processExitCode.h
engines/agds/region.h
engines/agds/resourceManager.h
engines/agds/screen.h
engines/agds/screenLoadingType.h
engines/agds/soundManager.h
engines/agds/systemVariable.h
engines/agds/textLayout.h
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index f223b2b5bde..d19bee892a1 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_AGDS_H
-#define AGDS_AGDS_H
+#ifndef AGDS_H
+#define AGDS_H
#include "agds/database.h"
#include "agds/dialog.h"
diff --git a/engines/agds/animation.h b/engines/agds/animation.h
index 4c6332dcff7..1a9c5acfe21 100644
--- a/engines/agds/animation.h
+++ b/engines/agds/animation.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_ANIMATION_H
-#define AGDS_ANIMATION_H
+#ifndef ANIMATION_H
+#define ANIMATION_H
#include "common/ptr.h"
#include "common/rect.h"
diff --git a/engines/agds/character.h b/engines/agds/character.h
index 01b759eb9a6..825b5359753 100644
--- a/engines/agds/character.h
+++ b/engines/agds/character.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_CHARACTER_H
-#define AGDS_CHARACTER_H
+#ifndef CHARACTER_H
+#define CHARACTER_H
#include "common/hashmap.h"
#include "common/ptr.h"
diff --git a/engines/agds/console.h b/engines/agds/console.h
index 0236d9e8ad5..3108a34acba 100644
--- a/engines/agds/console.h
+++ b/engines/agds/console.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_CONSOLE_H
-#define AGDS_CONSOLE_H
+#ifndef CONSOLE_H
+#define CONSOLE_H
#include "gui/debugger.h"
diff --git a/engines/agds/database.h b/engines/agds/database.h
index a940d34f934..2d74fc6f4dd 100644
--- a/engines/agds/database.h
+++ b/engines/agds/database.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_DATABASE_H
-#define AGDS_DATABASE_H
+#ifndef DATABASE_H
+#define DATABASE_H
#include "common/hash-str.h"
#include "common/hashmap.h"
diff --git a/engines/agds/detection.h b/engines/agds/detection.h
index 07fffc1f88a..54e29cc5e4e 100644
--- a/engines/agds/detection.h
+++ b/engines/agds/detection.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_DETECTION_H
-#define AGDS_DETECTION_H
+#ifndef DETECTION_H
+#define DETECTION_H
namespace AGDS {
diff --git a/engines/agds/dialog.h b/engines/agds/dialog.h
index d570e2e516e..f1e34651e9b 100644
--- a/engines/agds/dialog.h
+++ b/engines/agds/dialog.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_DIALOG_H
-#define AGDS_DIALOG_H
+#ifndef DIALOG_H
+#define DIALOG_H
#include "common/hash-str.h"
#include "common/hashmap.h"
diff --git a/engines/agds/font.h b/engines/agds/font.h
index 63d44b6fab4..10eb5014003 100644
--- a/engines/agds/font.h
+++ b/engines/agds/font.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_FONT_H
-#define AGDS_FONT_H
+#ifndef FONT_H
+#define FONT_H
#include "common/ptr.h"
#include "graphics/font.h"
diff --git a/engines/agds/inventory.h b/engines/agds/inventory.h
index 5f282ece839..5f49d2fd346 100644
--- a/engines/agds/inventory.h
+++ b/engines/agds/inventory.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_INVENTORY_H
-#define AGDS_INVENTORY_H
+#ifndef INVENTORY_H
+#define INVENTORY_H
#include "common/array.h"
#include "common/ptr.h"
diff --git a/engines/agds/mjpgPlayer.h b/engines/agds/mjpgPlayer.h
index 31d1ad574b4..ac0c9102716 100644
--- a/engines/agds/mjpgPlayer.h
+++ b/engines/agds/mjpgPlayer.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_MJPG_PLAYER_H
-#define AGDS_MJPG_PLAYER_H
+#ifndef MJPG_PLAYER_H
+#define MJPG_PLAYER_H
#include "common/array.h"
#include "common/scummsys.h"
diff --git a/engines/agds/mouseMap.h b/engines/agds/mouseMap.h
index 3a63d065c62..d9df81596ba 100644
--- a/engines/agds/mouseMap.h
+++ b/engines/agds/mouseMap.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_MOUSE_MAP_H
-#define AGDS_MOUSE_MAP_H
+#ifndef MOUSE_MAP_H
+#define MOUSE_MAP_H
#include "common/array.h"
#include "common/ptr.h"
diff --git a/engines/agds/object.h b/engines/agds/object.h
index f68daf88b91..3d7feb3c079 100644
--- a/engines/agds/object.h
+++ b/engines/agds/object.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_OBJECT_H
-#define AGDS_OBJECT_H
+#ifndef OBJECT_H
+#define OBJECT_H
#include "common/array.h"
#include "common/hash-str.h"
diff --git a/engines/agds/opcode.h b/engines/agds/opcode.h
index 0d603deb860..df7c8f7f98e 100644
--- a/engines/agds/opcode.h
+++ b/engines/agds/opcode.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_OPCODE_H
-#define AGDS_OPCODE_H
+#ifndef OPCODE_H
+#define OPCODE_H
#include "common/scummsys.h"
diff --git a/engines/agds/patch.h b/engines/agds/patch.h
index fdaabe5da25..c4780c7e23e 100644
--- a/engines/agds/patch.h
+++ b/engines/agds/patch.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_PATCH_H
-#define AGDS_PATCH_H
+#ifndef PATCH_H
+#define PATCH_H
#include "agds/screenLoadingType.h"
#include "common/array.h"
diff --git a/engines/agds/process.h b/engines/agds/process.h
index 9886966cf6d..9d0a94c9744 100644
--- a/engines/agds/process.h
+++ b/engines/agds/process.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_PROCESS_H
-#define AGDS_PROCESS_H
+#ifndef PROCESS_H
+#define PROCESS_H
#include "agds/object.h"
#include "agds/opcode.h"
diff --git a/engines/agds/processExitCode.h b/engines/agds/processExitCode.h
index 9655ad9d0c0..4785c6f0848 100644
--- a/engines/agds/processExitCode.h
+++ b/engines/agds/processExitCode.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_PROCESS_EXIT_CODE_H
-#define AGDS_PROCESS_EXIT_CODE_H
+#ifndef PROCESS_EXIT_CODE_H
+#define PROCESS_EXIT_CODE_H
namespace AGDS {
diff --git a/engines/agds/region.h b/engines/agds/region.h
index 2d47ccd2156..1489f88f161 100644
--- a/engines/agds/region.h
+++ b/engines/agds/region.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_REGION_H
-#define AGDS_REGION_H
+#ifndef REGION_H
+#define REGION_H
#include "common/array.h"
#include "common/rect.h"
diff --git a/engines/agds/resourceManager.h b/engines/agds/resourceManager.h
index 262bfaf3648..8ff5864cce8 100644
--- a/engines/agds/resourceManager.h
+++ b/engines/agds/resourceManager.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_RESOURCE_MANAGER_H
-#define AGDS_RESOURCE_MANAGER_H
+#ifndef RESOURCE_MANAGER_H
+#define RESOURCE_MANAGER_H
#include "common/archive.h"
#include "common/file.h"
diff --git a/engines/agds/screen.h b/engines/agds/screen.h
index 6a6df39d27a..e81f7250764 100644
--- a/engines/agds/screen.h
+++ b/engines/agds/screen.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_SCREEN_H
-#define AGDS_SCREEN_H
+#ifndef SCREEN_H
+#define SCREEN_H
#include "agds/screenLoadingType.h"
#include "common/array.h"
diff --git a/engines/agds/screenLoadingType.h b/engines/agds/screenLoadingType.h
index 5635a7eeb3a..1170f5468aa 100644
--- a/engines/agds/screenLoadingType.h
+++ b/engines/agds/screenLoadingType.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_SCREEN_LOADING_TYPE_H
-#define AGDS_SCREEN_LOADING_TYPE_H
+#ifndef SCREEN_LOADING_TYPE_H
+#define SCREEN_LOADING_TYPE_H
namespace AGDS {
diff --git a/engines/agds/soundManager.h b/engines/agds/soundManager.h
index 93a1e19559f..62c4c9a46d0 100644
--- a/engines/agds/soundManager.h
+++ b/engines/agds/soundManager.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_SOUND_MANAGER_H
-#define AGDS_SOUND_MANAGER_H
+#ifndef SOUND_MANAGER_H
+#define SOUND_MANAGER_H
#include "audio/mixer.h"
#include "common/hashmap.h"
diff --git a/engines/agds/systemVariable.h b/engines/agds/systemVariable.h
index fc9e2d20bfb..5792c07f4c3 100644
--- a/engines/agds/systemVariable.h
+++ b/engines/agds/systemVariable.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_SYSTEM_VARIABLE_H
-#define AGDS_SYSTEM_VARIABLE_H
+#ifndef SYSTEM_VARIABLE_H
+#define SYSTEM_VARIABLE_H
#include "common/scummsys.h"
#include "common/str.h"
diff --git a/engines/agds/textLayout.h b/engines/agds/textLayout.h
index c6fffe5e32e..d9a26c51cb1 100644
--- a/engines/agds/textLayout.h
+++ b/engines/agds/textLayout.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef AGDS_TEXT_LAYOUT_H
-#define AGDS_TEXT_LAYOUT_H
+#ifndef TEXT_LAYOUT_H
+#define TEXT_LAYOUT_H
#include "common/array.h"
#include "common/rect.h"
Commit: e6355a9b20a1c3980aafe7d62ed3b13435a1dcc7
https://github.com/scummvm/scummvm/commit/e6355a9b20a1c3980aafe7d62ed3b13435a1dcc7
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:15+01:00
Commit Message:
AGDS: support TTF fonts
Changed paths:
engines/agds/agds.cpp
engines/agds/agds.h
engines/agds/process_opcodes.cpp
engines/agds/textLayout.cpp
diff --git a/engines/agds/agds.cpp b/engines/agds/agds.cpp
index 108f9ba0da2..6b078c5248f 100644
--- a/engines/agds/agds.cpp
+++ b/engines/agds/agds.cpp
@@ -44,6 +44,7 @@
#include "common/system.h"
#include "engines/util.h"
#include "graphics/managed_surface.h"
+#include "graphics/fonts/ttf.h"
namespace AGDS {
@@ -917,7 +918,8 @@ Graphics::ManagedSurface *AGDSEngine::loadFromCache(int id) const {
void AGDSEngine::loadFont(int id, const Common::String &name, int gw, int gh) {
if (v2()) {
- debug("loadTTF %d %s, pixelSize: %d: stub", id, name.c_str(), gh);
+ debug("loadTTF %d %s, pixelSize: %d", id, name.c_str(), gh);
+ _fonts[id].reset(Graphics::loadTTFFontFromArchive(name, gh));
} else {
debug("loadFont %d %s %d %d", id, name.c_str(), gw, gh);
Graphics::ManagedSurface *surface = loadPicture(name);
@@ -925,7 +927,7 @@ void AGDSEngine::loadFont(int id, const Common::String &name, int gw, int gh) {
}
}
-Font *AGDSEngine::getFont(int id) const {
+const Graphics::Font *AGDSEngine::getFont(int id) const {
FontsType::const_iterator i = _fonts.find(id);
if (i == _fonts.end())
error("no font with id %d", id);
diff --git a/engines/agds/agds.h b/engines/agds/agds.h
index d19bee892a1..6ee5a2c4e6c 100644
--- a/engines/agds/agds.h
+++ b/engines/agds/agds.h
@@ -51,6 +51,7 @@
*/
namespace Graphics {
+class Font;
class ManagedSurface;
}
@@ -192,7 +193,7 @@ public:
int saveToCache(const Common::String &name, Graphics::ManagedSurface *surface);
void loadFont(int id, const Common::String &name, int gw, int gh);
- Font *getFont(int id) const;
+ const Graphics::Font *getFont(int id) const;
AnimationPtr loadAnimation(const Common::String &name);
AnimationPtr loadMouseCursor(const Common::String &name);
@@ -290,7 +291,7 @@ private:
using SystemVariablesListType = Common::Array<Common::String>;
using SystemVariablesType = Common::HashMap<Common::String, SystemVariable *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
using GlobalsType = Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
- using FontsType = Common::HashMap<int, Common::ScopedPtr<Font>>;
+ using FontsType = Common::HashMap<int, Common::ScopedPtr<Graphics::Font>>;
using PatchesType = Common::HashMap<Common::String, PatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
using ObjectPatchesType = Common::HashMap<Common::String, ObjectPatchPtr, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>;
using PatchDatabase = Common::HashMap<Common::String, Common::Array<uint8>>;
diff --git a/engines/agds/process_opcodes.cpp b/engines/agds/process_opcodes.cpp
index 40ecc879104..7a6aa9a386d 100644
--- a/engines/agds/process_opcodes.cpp
+++ b/engines/agds/process_opcodes.cpp
@@ -913,7 +913,7 @@ void Process::loadSaveSlotNamePicture() {
debug("save state name: %s", saveSlotName.c_str());
int fontId = _engine->getSystemVariable("edit_font")->getInteger();
- Font *font = _engine->getFont(fontId);
+ auto *font = _engine->getFont(fontId);
int h = font->getFontHeight();
static const int w = 400;
diff --git a/engines/agds/textLayout.cpp b/engines/agds/textLayout.cpp
index b66b96839d7..25118d9834c 100644
--- a/engines/agds/textLayout.cpp
+++ b/engines/agds/textLayout.cpp
@@ -33,7 +33,7 @@ namespace AGDS {
void TextLayout::paint(AGDSEngine &engine, Graphics::Surface &backbuffer) {
if (!_valid)
return;
- Font *font = engine.getFont(_fontId);
+ auto *font = engine.getFont(_fontId);
for (uint i = 0; i < _lines.size(); ++i) {
Line &line = _lines[i];
font->drawString(&backbuffer, line.text, line.pos.x, line.pos.y, line.size.x, 0);
@@ -67,7 +67,7 @@ void TextLayout::layout(AGDSEngine &engine, Process &process, const Common::Stri
process.deactivate();
_fontId = fontId;
_npc = npc;
- Font *font = engine.getFont(fontId);
+ auto *font = engine.getFont(fontId);
_lines.clear();
int w = 0;
Commit: 4f70a87d645b11c7db75f3cbc8a38f10fe61dc02
https://github.com/scummvm/scummvm/commit/4f70a87d645b11c7db75f3cbc8a38f10fe61dc02
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:15+01:00
Commit Message:
AGDS: include plugins.h in metaengine.cpp
Changed paths:
engines/agds/metaengine.cpp
diff --git a/engines/agds/metaengine.cpp b/engines/agds/metaengine.cpp
index 1b796590770..b267a65381e 100644
--- a/engines/agds/metaengine.cpp
+++ b/engines/agds/metaengine.cpp
@@ -21,6 +21,7 @@
#include "agds/agds.h"
#include "agds/object.h"
+#include "base/plugins.h"
#include "common/savefile.h"
#include "common/system.h"
#include "engines/advancedDetector.h"
Commit: 0ede9e7d0f3bd2a92cabd7876b95882ddf7d3ca3
https://github.com/scummvm/scummvm/commit/0ede9e7d0f3bd2a92cabd7876b95882ddf7d3ca3
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:15+01:00
Commit Message:
AGDS: add credits.pl
Changed paths:
A engines/agds/credits.pl
diff --git a/engines/agds/credits.pl b/engines/agds/credits.pl
new file mode 100644
index 00000000000..03d61bfb18f
--- /dev/null
+++ b/engines/agds/credits.pl
@@ -0,0 +1,3 @@
+begin_section("AGDS");
+ add_person("Vladimir Menshakov", "whoozle", "");
+end_section();
Commit: a465cf6afde7e57642a6a0fea0fa42263ab0007b
https://github.com/scummvm/scummvm/commit/a465cf6afde7e57642a6a0fea0fa42263ab0007b
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:15+01:00
Commit Message:
AGDS: correct engine.configure - only two games are known
Changed paths:
engines/agds/configure.engine
diff --git a/engines/agds/configure.engine b/engines/agds/configure.engine
index 2c2d229bd56..660ef5775ac 100644
--- a/engines/agds/configure.engine
+++ b/engines/agds/configure.engine
@@ -1,3 +1,3 @@
# This file is included from the main "configure" script
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine agds "AGDS (Black Mirror and others)" no
+add_engine agds "AGDS (Black Mirror and NiBiRu)" no
Commit: 4c9d89b311076e21099d85b88fb0fe15565ab9d8
https://github.com/scummvm/scummvm/commit/4c9d89b311076e21099d85b88fb0fe15565ab9d8
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:16+01:00
Commit Message:
AGDS: reorder module.mk to match skeleton
Changed paths:
engines/agds/module.mk
diff --git a/engines/agds/module.mk b/engines/agds/module.mk
index 8254ed7d65a..1b46d85d404 100644
--- a/engines/agds/module.mk
+++ b/engines/agds/module.mk
@@ -1,9 +1,5 @@
MODULE := engines/agds
-# Detection objects
-DETECT_OBJS += \
- $(MODULE)/detection.o
-
MODULE_OBJS := \
agds.o \
animation.o \
@@ -34,3 +30,7 @@ endif
# Include common rules
include $(srcdir)/rules.mk
+
+# Detection objects
+DETECT_OBJS += \
+ $(MODULE)/detection.o
Commit: 6cba76e056a71ecc8f7e396f5459206c51377289
https://github.com/scummvm/scummvm/commit/6cba76e056a71ecc8f7e396f5459206c51377289
Author: Vladimir Menshakov (vladimir.menshakov at gmail.com)
Date: 2025-11-12T15:59:16+01:00
Commit Message:
AGDS: janitorial - remove AGDS prefix
Changed paths:
engines/agds/detection.h
diff --git a/engines/agds/detection.h b/engines/agds/detection.h
index 54e29cc5e4e..740bf9192e5 100644
--- a/engines/agds/detection.h
+++ b/engines/agds/detection.h
@@ -30,4 +30,4 @@ enum AGDSGameFlag {
} // End of namespace AGDS
-#endif // AGDS_DETECTION_H
+#endif // DETECTION_H
More information about the Scummvm-git-logs
mailing list