Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

3
devtools/tasmrecover/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*.pyc
dreamgen.*
_stubs*

View File

@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View File

@@ -0,0 +1,852 @@
;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
;----------------------------------------------Code to draw floor and panel----
Blockget proc near
mov ah,al
mov al,0
mov ds,backdrop
mov si,blocks
add si,ax
ret
endp
;--------------------------------------------------------Background display----
Drawfloor proc near
push es bx ;in case this was called during
call eraseoldobs ;some sprite update.
call drawflags
call calcmapad
call doblocks
call showallobs
call showallfree
call showallex
call paneltomap
call initrain
mov newobs,0
pop bx es
ret
endp
Calcmapad proc near
call getdimension
push cx dx
mov al,11
sub al,dl
sub al,cl
sub al,cl
cbw
mov bx,8
mul bx
add ax,mapoffsetx
mov mapadx,ax
pop dx cx
mov al,10
sub al,dh
sub al,ch
sub al,ch
cbw
mov bx,8
mul bx
add ax,mapoffsety
mov mapady,ax
ret
endp
Getdimension proc near ;Routine finds width, length
;and top corner of room
mov es,buffers
mov bx,mapflags
mov ch,0
dimloop1: call addalong
cmp al,0
jnz finishdim1
inc ch
jmp dimloop1 ;ch holds y of top corner
finishdim1: mov bx,mapflags
mov cl,0
dimloop2: push bx
call addlength
pop bx
cmp al,0
jnz finishdim2
inc cl
add bx,3
jmp dimloop2 ;cl holds x of top corner
finishdim2: mov bx,mapflags+(11*3*9)
mov dh,10
dimloop3: push bx
call addalong
pop bx
cmp al,0
jnz finishdim3
dec dh
sub bx,11*3
jmp dimloop3 ;dh holds y of bottom corner
finishdim3: mov bx,mapflags+(3*10)
mov dl,11
dimloop4: push bx
call addlength
pop bx
cmp al,0
jnz finishdim4
dec dl
sub bx,3
jmp dimloop4 ;dl holds x of bottom corner
finishdim4: mov al,cl ;cl holds x start
mov ah,0
shl ax,1
shl ax,1
shl ax,1
shl ax,1
mov mapxstart,ax
mov al,ch ;ch holds y start
mov ah,0
shl ax,1
shl ax,1
shl ax,1
shl ax,1
mov mapystart,ax
sub dl,cl
sub dh,ch
;dx holds x and y size of room
mov al,dl ;dl holds x size
mov ah,0
shl ax,1
shl ax,1
shl ax,1
shl ax,1
mov mapxsize,al
mov al,dh ;dh holds y size
mov ah,0
shl ax,1
shl ax,1
shl ax,1
shl ax,1
mov mapysize,al ;cx still holds top left corner
ret
endp
Addalong proc near
mov ah,11
addloop: cmp byte ptr [es:bx],0
jnz gotalong
add bx,3
dec ah
jnz addloop
mov al,0
ret
gotalong: mov al,1
ret
endp
Addlength proc near
mov ah,10
addloop2: cmp byte ptr [es:bx],0
jnz gotlength
add bx,3*11
dec ah
jnz addloop2
mov al,0
ret
gotlength: mov al,1
ret
endp
Drawflags proc near
mov es,buffers
mov di,mapflags
mov al,mapy
mov ah,0
mov cx,mapwidth
mul cx
mov bl,mapx
mov bh,0
add ax,bx
mov si,map
add si,ax
mov cx,10
$28: push cx
mov cx,11
$28a: mov ds,mapdata
lodsb
mov ds,backdrop
push si ax
mov ah,0
add ax,ax
mov si,flags
add si,ax
movsw
pop ax
stosb
pop si
loop $28a
add si,mapwidth-11
pop cx
loop $28
ret
endp
;-------------------------------------------------------Set object printing----
Eraseoldobs proc near
cmp newobs,0
jz donterase
mov es,buffers
mov bx,spritetable
mov cx,16
oberase: push cx bx
mov ax,[es:bx+20]
cmp ax,0ffffh
jz notthisob
mov di,bx
mov al,255
mov cx,tablesize
rep stosb
notthisob: pop bx cx
add bx,tablesize
loop oberase
donterase: ret
endp
Showallobs proc near
mov es,buffers
mov bx,setlist
mov listpos,bx
mov di,bx
mov cx,128*5
mov al,255
rep stosb
mov es,setframes
mov frsegment,es
mov ax,framedata
mov dataad,ax
mov ax,frames
mov framesad,ax
mov currentob,0
mov ds,setdat
mov si,0
mov cx,128
showobsloop: push cx si
push si
add si,58
mov es,setdat
call getmapad
pop si
cmp ch,0
jz blankframe
mov al,[es:si+18]
mov ah,0
mov currentframe,ax
cmp al,255
jz blankframe
push es si
call calcfrframe
call finalframe
pop si es
mov al,[es:si+18]
mov [es:si+17],al
cmp byte ptr [es:si+8],0
jnz animating
cmp byte ptr [es:si+5],5
jz animating
cmp byte ptr [es:si+5],6
jz animating
mov ax,currentframe
mov ah,0
add di,mapadx
add bx,mapady
call showframe
jmp drawnsetob
animating: call makebackob
drawnsetob: mov si,listpos
mov es,buffers
mov al,savex
mov ah,savey
mov [es:si],ax
mov cx,ax
mov ax,savesize
add al,cl
add ah,ch
mov [es:si+2],ax
mov al,currentob
mov [es:si+4],al
add si,5
mov listpos,si
blankframe: inc currentob
pop si cx
add si,64
dec cx
jz finishedsetobs
jmp showobsloop
finishedsetobs: ret
endp
Makebackob proc near
cmp newobs,0
jz nomake
mov al,[es:si+5] ; priority
mov ah,[es:si+8] ; type - steady, constant,random,door etc.
push si ax si
mov ax,objectx
mov bx,objecty
mov ah,bl
mov si,ax
mov cx,offset cs:backobject
mov dx,setframes
mov di,framedata
call makesprite
pop ax
mov [es:bx+20],ax
pop ax
cmp al,255
jnz usedpriority ; forgotten to specify priority
mov al,0
usedpriority: mov [es:bx+23],al
mov [es:bx+30],ah
mov byte ptr [es:bx+16],0
mov byte ptr [es:bx+18],0
mov byte ptr [es:bx+19],0
pop si
nomake: ret
endp
;------------------------------------------------------Free object printing----
Showallfree proc near
mov es,buffers
mov bx,freelist
mov listpos,bx
mov di,freelist
mov cx,80*5
mov al,255
rep stosb
mov es,freeframes
mov frsegment,es
mov ax,frframedata
mov dataad,ax
mov ax,frframes
mov framesad,ax
mov al,0
mov currentfree,al
mov ds,freedat
mov si,2
mov cx,0
loop127: push cx si
push si
mov es,freedat
call getmapad
pop si
cmp ch,0
jz over138
mov al,currentfree
mov ah,0
mov dx,ax
add ax,ax
add ax,dx
mov currentframe,ax
push es si
call calcfrframe
mov es,mapstore
mov ds,frsegment
call finalframe
pop si es
cmp cx,0
jz over138
mov ax,currentframe
mov ah,0
add di,mapadx
add bx,mapady
call showframe
mov si,listpos
mov es,buffers
mov al,savex
mov ah,savey
mov [es:si],ax
mov cx,ax
mov ax,savesize
add al,cl
add ah,ch
mov [es:si+2],ax
pop ax cx
push cx ax
mov [es:si+4],cl
add si,5
mov listpos,si
over138: inc currentfree
pop si cx
add si,16
inc cx
cmp cx,80
jz finfree
jmp loop127
finfree: ret
endp
Showallex proc near
mov es,buffers
mov bx,exlist
mov listpos,bx
mov di,exlist
mov cx,100*5
mov al,255
rep stosb
mov es,extras
mov frsegment,es
mov ax,exframedata
mov dataad,ax
mov ax,exframes
mov framesad,ax
mov currentex,0
mov si,exdata+2
mov cx,0
exloop: push cx si
mov es,extras
push si
mov ch,0
cmp byte ptr [es:si],255
jz notinroom
mov al,[es:si-2]
cmp al,reallocation
jnz notinroom
call getmapad
notinroom: pop si
cmp ch,0
jz blankex
mov al,currentex
mov ah,0
mov dx,ax
add ax,ax
add ax,dx
mov currentframe,ax
push es si
call calcfrframe
mov es,mapstore
mov ds,frsegment
call finalframe
pop si es
cmp cx,0
jz blankex
mov ax,currentframe
mov ah,0
add di,mapadx
add bx,mapady
call showframe
mov si,listpos
mov es,buffers
mov al,savex
mov ah,savey
mov [es:si],ax
mov cx,ax
mov ax,savesize
add al,cl
add ah,ch
mov [es:si+2],ax
pop ax cx
push cx ax
mov [es:si+4],cl
add si,5
mov listpos,si
blankex: inc currentex
pop si cx
add si,16
inc cx
cmp cx,100
jz finex
jmp exloop
finex: ret
endp
Calcfrframe proc near
mov dx,frsegment
mov ax,framesad
push ax
mov cx,dataad
mov ax,currentframe
mov ds,dx
mov bx,6
mul bx
add ax,cx
mov bx,ax
mov cx,[bx]
mov ax,[bx+2]
mov dx,[bx+4]
pop bx
push dx
add ax,bx ;ax=source add, cx=x,y
;need this later
mov savesource,ax
mov savesize,cx
pop ax
push ax
mov ah,0
mov offsetx,ax
pop ax
mov al,ah
mov ah,0
mov offsety,ax
ret
nullframe: pop ax
mov cx,0
mov savesize,cx
ret
endp
Finalframe proc near
mov ax,objecty
add ax,offsety
mov bx,objectx
add bx,offsetx
mov savex,bl
mov savey,al
mov di,objectx
mov bx,objecty
ret
endp
Adjustlen proc near
mov ah,al
add al,ch
cmp al,100
jc over242
mov al,224
sub al,ch
mov ch,al
over242: ret
endp
Getmapad proc near
call getxad
cmp ch,0
jz over146
mov objectx,ax
call getyad
cmp ch,0
jz over146
mov objecty,ax
mov ch,1
over146: ret
endp
Getxad proc near
mov cl,[es:si]
inc si
mov al,[es:si]
inc si
mov ah,[es:si]
inc si
cmp cl,0
jnz over148
sub al,mapx
jc over148
cmp al,11
jnc over148
mov cl,4
shl al,cl
or al,ah
mov ah,0
mov ch,1
ret
over148: mov ch,0
ret
endp
Getyad proc near
mov al,[es:si]
inc si
mov ah,[es:si]
inc si
sub al,mapy
jc over147
cmp al,10
jnc over147
mov cl,4
shl al,cl
or al,ah
mov ah,0
mov ch,1
ret
over147: mov ch,0
ret
endp

View File

@@ -0,0 +1,381 @@
;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
if debuglevel2
Debugkeys proc near
ret
endp
Debugstart proc near
call allpalette
mov reeltohold,-1
mov newlocation,23
mov dreamnumber,0
mov al,"W"
mov ah,"S"
mov cl,"H"
mov ch,"D"
call findexobject
mov byte ptr [es:bx+12],"S"-"A"
mov byte ptr [es:bx+13],"C"-"A"
mov byte ptr [es:bx+14],"R"-"A"
mov byte ptr [es:bx+15],"W"-"A"
mov al,"W"
mov ah,"E"
mov cl,"T"
mov ch,"A"
call findexobject
mov byte ptr [es:bx+12],"G"-"A"
mov byte ptr [es:bx+13],"U"-"A"
mov byte ptr [es:bx+14],"N"-"A"
mov byte ptr [es:bx+15],"A"-"A"
mov al,"W"
mov ah,"E"
mov cl,"T"
mov ch,"B"
call findexobject
mov byte ptr [es:bx+12],"S"-"A"
mov byte ptr [es:bx+13],"H"-"A"
mov byte ptr [es:bx+14],"L"-"A"
mov byte ptr [es:bx+15],"D"-"A"
mov card1money,12342
ret
endp
Debuggreen proc near
push ax dx
mov al,0
mov dx,3c8h
out dx,al
mov dx,3c9h
mov al,0
out dx,al
mov al,63
out dx,al
mov al,0
out dx,al
pop dx ax
ret
endp
Debugred proc near
push ax dx
mov al,0
mov dx,3c8h
out dx,al
mov dx,3c9h
mov al,63
out dx,al
mov al,0
out dx,al
mov al,0
out dx,al
pop dx ax
ret
endp
Debugblue proc near
push ax dx
mov al,0
mov dx,3c8h
out dx,al
mov dx,3c9h
mov al,0
out dx,al
mov al,0
out dx,al
mov al,63
out dx,al
pop dx ax
ret
endp
Debugblack proc near
push dx ax
mov al,0
mov dx,3c8h
out dx,al
mov dx,3c9h
mov al,0
out dx,al
mov al,0
out dx,al
mov al,0
out dx,al
pop ax dx
ret
endp
Debug proc near
push ds dx cx
mov ah,3ch
mov cx,0
mov dx,seg filenamed
mov ds,dx
mov dx,offset filenamed
int 21h
mov bx,ax
pop cx dx ds
push bx
mov ah,40h
int 21h
pop bx
mov ah,3eh
int 21h
ret
filenamed db "DREAMWEB.TXT",0
endp
Shout proc near
push ax bx cx dx si di es ds
call debugblue
mov cx,50
call hangon
call debugblack
mov cx,10
call hangon
pop ds es di si dx cx bx ax
ret
endp
Shoutred proc near
push ax bx cx dx si di es ds
call debugred
mov cx,4
call hangon
call debugblack
mov cx,40
call hangon
pop ds es di si dx cx bx ax
ret
endp
Shoutgreen proc near
push ax bx cx dx si di es ds
call debuggreen
mov cx,4
call hangon
call debugblack
mov cx,40
call hangon
pop ds es di si dx cx bx ax
ret
endp
;Checkmemingame proc near
; cmp charset1,0
; jz nodebug
; mov bx,60000
; mov ah,48h
; int 21h
; mov ax,bx
; mov cl,6
; shr ax,cl
; mov di,offset cs:debugtextig
; call showword
; mov ax,soundbufferwrite
; ;mov ax,exframepos
; mov di,offset cs:debugtextex
; call showword
; ;mov ax,extextpos
; ;mov di,offset cs:debugtextex2
; ;call showword
; push cs
; pop es
; mov si,offset cs:debugtextig
; mov al,0
; mov ah,0
; mov dl,100
; mov di,204
; mov bx,14
; call printdirect
; push cs
; pop es
; mov si,offset cs:debugtextex
; mov al,0
; mov ah,0
; mov dl,100
; mov di,204
; mov bx,22
; call printdirect
; push cs
; pop es
; mov si,offset cs:debugtextex2
; mov al,0
; mov ah,0
; mov dl,100
; mov di,204
; mov bx,30
; call printdirect
; mov di,204
; mov bx,14
; mov cl,40
; mov ch,24
; call multidump
;nodebug: ret
endp
debugtextig: db "00000K",0
debugtextex: db "00000b",0
debugtextex2: db "00000b",0
if recording
mov ax,recordpos
mov di,offset cs:debugtextr
call showword
mov al,0
call print
dw 4,4,100
debugtextr: db "00000",0
mov si,0
mov di,0
mov cl,40
mov ch,12
call multidump
endif
ret
endp
;Debugax proc near
;
; push ax
; call showpanel
; pop ax
; mov di,offset cs:debugaxtext
; call showword
;
; mov di,204
; mov bx,14
; mov al,0
; mov ah,0
; mov dl,100
; push cs
; pop es
; mov si,offset cs:debugaxtext
; call printdirect
; mov di,204
; mov bx,14
; mov cl,40
; mov ch,24
; call multidump
; ret
;
;debugaxtext db "00000 ",0
;
; endp
endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,160 @@
;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
;---------------------------------------------------------------Look-routine----
Autolook proc near
mov ax,mousex
cmp ax,oldx
jnz diffmouse
mov ax,mousey
cmp ax,oldy
jnz diffmouse
dec lookcounter
cmp lookcounter,0
jnz noautolook
cmp watchingtime,0
jnz noautolook
call dolook
noautolook: ret
diffmouse: mov lookcounter,1000
ret
endp
Look proc near
cmp watchingtime,0
jnz blank
cmp pointermode,2
jz blank
cmp commandtype,241
jz alreadylook
mov commandtype,241
mov al,25
call commandonly
alreadylook: cmp mousebutton,1
jnz nolook
mov ax,mousebutton
cmp ax,oldbutton
jz nolook
call dolook
nolook: ret
endp
Dolook proc near
call createpanel
call showicon
call undertextline
call worktoscreenm
mov commandtype,255
call dumptextline
mov bl,roomnum
and bl,31
mov bh,0
add bx,bx
mov es,roomdesc
add bx,intextdat
mov si,[es:bx]
add si,intext
call findnextcolon
mov di,66
cmp reallocation,50
jc notdream3
mov di,40
notdream3: mov bx,80
mov dl,241
call printslow
cmp al,1
jz afterlook
mov cx,400
call hangonp
afterlook: mov pointermode,0
mov commandtype,0
call redrawmainscrn
call worktoscreenm
ret
endp
Redrawmainscrn proc near
mov timecount,0
call createpanel
mov newobs,0
call drawfloor
call printsprites
call reelsonscreen
call showicon
call getunderzoom
call undertextline
call readmouse
mov commandtype,255
ret
endp
Getback1 proc near
cmp pickup,0
jz notgotobject
call blank
ret
notgotobject: cmp commandtype,202
jz alreadyget
mov commandtype,202
mov al,26
call commandonly
alreadyget: mov ax,mousebutton
cmp ax,oldbutton
jz nogetback
and ax,1
jnz dogetback
nogetback: ret
dogetback: mov getback,1
mov pickup,0
ret
endp

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,579 @@
;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
;----------------------------------------------------Choosing a new location----
Newplace proc near
cmp needtotravel,1
jz istravel
cmp autolocation,-1
jnz isautoloc
ret
isautoloc: mov al,autolocation
mov newlocation,al
mov autolocation,-1
ret
istravel: mov needtotravel,0
call selectlocation
ret
endp
Selectlocation proc near
mov inmaparea,0
call clearbeforeload
mov getback,0
mov pointerframe,22
call readcitypic
call showcity
call getridoftemp
call readdesticon
call loadtraveltext
call showpanel
call showman
call showarrows
call showexit
call locationpic
call undertextline
mov commandtype,255
call readmouse
mov pointerframe,0
call showpointer
call worktoscreen
mov al,9
mov ah,255
call playchannel0
mov newlocation,255
select:
cmp quitrequested, 0
jnz quittravel
call delpointer
call readmouse
call showpointer
call vsync
call dumppointer
call dumptextline
cmp getback,1
jz quittravel
mov bx,offset cs:destlist
call checkcoords
cmp newlocation,255
jz select
mov al,newlocation
cmp al,location
jz quittravel
call getridoftemp
call getridoftemp2
call getridoftemp3
mov es,traveltext
call deallocatemem
ret
quittravel: mov al,reallocation ; was just location
mov newlocation,al
mov getback,0
call getridoftemp
call getridoftemp2
call getridoftemp3
mov es,traveltext
call deallocatemem
ret
destlist: dw 238,258,4,44,nextdest
dw 104,124,4,44,lastdest
dw 280,308,4,44,lookatplace
dw 104,216,138,192,destselect
dw 273,320,157,198,getback1
dw 0,320,0,200,blank
dw 0ffffh
endp
Showcity proc near
call clearwork
mov ds,tempgraphics
mov di,57
mov bx,32
mov al,0
mov ah,0
call showframe
mov ds,tempgraphics
mov di,120+57
mov bx,32
mov al,1
mov ah,0
call showframe
ret
endp
Lookatplace proc near
cmp commandtype,224
jz alreadyinfo
mov commandtype,224
mov al,27
call commandonly
alreadyinfo: mov ax,mousebutton
and ax,1
jz noinfo
cmp ax,oldbutton
jz noinfo
mov bl,destpos
cmp bl,15
jnc noinfo
push bx
call delpointer
call deltextline
call getundercentre
mov ds,tempgraphics3
mov al,0
mov ah,0
mov di,60
mov bx,72
call showframe
mov al,4
mov ah,0
mov di,60
mov bx,72+55
call showframe
cmp foreignrelease, 0
jz $1
mov al,4
mov ah,0
mov di,60
mov bx,72+55+21
call showframe
$1:
pop bx
mov bh,0
add bx,bx
mov es,traveltext
mov si,[es:bx]
add si,textstart
call findnextcolon
mov di,63
mov bx,84
cmp foreignrelease, 0
jz $2
mov bx,84+4
$2:
mov dl,191
mov al,0
mov ah,0
call printdirect
call worktoscreenm
mov cx,500
call hangonp
afterinfo: mov pointermode,0
mov pointerframe,0
call putundercentre
call worktoscreenm
noinfo: ret
endp
Getundercentre proc near
mov di,58
mov bx,72
mov ds,mapstore
mov si,0
mov cl,254
mov ch,110
call multiget
ret
endp
Putundercentre proc near
mov di,58
mov bx,72
mov ds,mapstore
mov si,0
mov cl,254
mov ch,110
call multiput
ret
endp
Locationpic proc near
call getdestinfo
mov al,[es:si]
push es si
mov di,0
cmp al,6
jnc secondlot
mov ds,tempgraphics
add al,4
jmp gotgraphic
secondlot: sub al,6
mov ds,tempgraphics2
gotgraphic: add di,104
mov bx,138+14
mov ah,0
call showframe
pop si es
mov al,destpos
cmp al,reallocation
jnz notinthisone
mov al,3
mov di,104
mov bx,140+14
mov ds,tempgraphics
mov ah,0
call showframe
notinthisone: mov bl,destpos
mov bh,0
add bx,bx
mov es,traveltext
mov si,[es:bx]
add si,textstart
mov di,50
mov bx,20
mov dl,241
mov al,0
mov ah,0
call printdirect
ret
endp
Getdestinfo proc near
mov al,destpos
mov ah,0
push ax
mov dx,seg roomscango
mov es,dx
mov si,offset es:roomscango
add si,ax
mov cl,[es:si]
pop ax
push cx
mov dx,seg roompics
mov es,dx
mov si,offset es:roompics
add si,ax
pop ax
ret
endp
Showarrows proc near
mov di,116-12
mov bx,16
mov ds,tempgraphics
mov al,0
mov ah,0
call showframe
mov di,226+12
mov bx,16
mov ds,tempgraphics
mov al,1
mov ah,0
call showframe
mov di,280
mov bx,14
mov ds,tempgraphics
mov al,2
mov ah,0
call showframe
ret
endp
Nextdest proc near
duok: cmp commandtype,218
jz alreadydu
mov commandtype,218
mov al,28
call commandonly
alreadydu: mov ax,mousebutton
and ax,1
jz nodu
cmp ax,oldbutton
jz nodu
searchdestup: inc destpos
cmp destpos,15
jnz notlastdest
mov destpos,0
notlastdest: call getdestinfo
cmp al,0
jz searchdestup
mov newtextline,1
call deltextline
call delpointer
call showpanel
call showman
call showarrows
call locationpic
call undertextline
call readmouse
call showpointer
call worktoscreen
call delpointer
nodu: ret
endp
Lastdest proc near
ddok: cmp commandtype,219
jz alreadydd
mov commandtype,219
mov al,29
call commandonly
alreadydd: mov ax,mousebutton
and ax,1
jz nodd
cmp ax,oldbutton
jz nodd
searchdestdown: dec destpos
cmp destpos,-1
jnz notfirstdest
mov destpos,15
notfirstdest: call getdestinfo
cmp al,0
jz searchdestdown
mov newtextline,1
call deltextline
call delpointer
call showpanel
call showman
call showarrows
call locationpic
call undertextline
call readmouse
call showpointer
call worktoscreen
call delpointer
nodd: ret
endp
Destselect proc near
cmp commandtype,222
jz alreadytrav
mov commandtype,222
mov al,30
call commandonly
alreadytrav: mov ax,mousebutton
and ax,1
jz notrav
cmp ax,oldbutton
jz notrav
call getdestinfo
mov al,destpos
mov newlocation,al
notrav: ret
endp
Getlocation proc near
mov ah,0
mov bx,ax
mov dx,seg roomscango
mov es,dx
add bx,offset es:roomscango
mov al,[es:bx]
ret
endp
Setlocation proc near ;makes a location accessible
mov ah,0
mov bx,ax
mov dx,seg roomscango
mov es,dx
add bx,offset es:roomscango
mov byte ptr [es:bx],1
ret
endp
Resetlocation proc near ;makes a location inaccessible
push ax
cmp al,5
jnz notdelhotel
call purgealocation
mov al,21
call purgealocation
mov al,22
call purgealocation
mov al,27
call purgealocation
jmp clearedlocations
notdelhotel: cmp al,8
jnz notdeltvstud
call purgealocation
mov al,28
call purgealocation
jmp clearedlocations
notdeltvstud: cmp al,6
jnz notdelsarters
call purgealocation
mov al,20
call purgealocation
mov al,25
call purgealocation
jmp clearedlocations
notdelsarters: cmp al,13
jnz notdelboathouse
call purgealocation
mov al,29
call purgealocation
jmp clearedlocations
notdelboathouse:
clearedlocations: pop ax
mov ah,0
mov bx,ax
mov dx,seg roomscango
mov es,dx
add bx,offset es:roomscango
mov byte ptr [es:bx],0
ret
endp
Readdesticon proc near
mov dx,offset cs:travelgraphic1
call loadintotemp
mov dx,offset cs:travelgraphic2
call loadintotemp2
mov dx,offset cs:icongraphics8
call loadintotemp3
ret
endp
Readcitypic proc near
mov dx,offset cs:cityname
call loadintotemp
ret
endp

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,591 @@
;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
Printchar proc near
cmp al,255
jz ignoreit
push si bx di
cmp foreignrelease, 0
jz $1
sub bx,3
$1:
push ax
sub al,32 ;"A"
mov ah,0
add ax,charshift
call showframe
pop ax di bx si
cmp kerning,0
jnz nokern
call kernchars
nokern: push cx
mov ch,0
add di,cx
pop cx
;dec di
ignoreit: ret
endp
Kernchars proc near
;sub al,13
cmp al,"a"
jz iskern
cmp al,"u"
jz iskern
ret
iskern: cmp ah,"n"
jz kernit
cmp ah,"t"
jz kernit
cmp ah,"r"
jz kernit
cmp ah,"i"
jz kernit
cmp ah,"l"
jz kernit
ret
kernit: dec cl
ret
endp
;------------------------------------------------Proportional text printing----
;Memprint proc near
;
; call usecharset1
;
; push ax bx cx dx es ds si di
; call deltextline
; pop di si ds es dx cx bx ax
;
; pop si
; push cs
; pop es
; inc si
; mov ds,currentset
; mov di,textaddressx
; mov bx,textaddressy
; mov dl,textlen
; mov al,0
; mov ah,0
; call printdirect
; push si
; mov newtextline,1
; ret
; endp
;------------------------------------------------Proportional text printing----
;Print proc near
;
; pop si
; mov bx,[cs:si+2]
; mov di,[cs:si+0]
; mov dl,[cs:si+4]
; add si,6
; mov ds,currentset
;
;printloop2: push bx di dx
; push es cs
; pop es
; call getnumber
; pop es
; mov ch,0
;printloop1: mov ax,[cs:si]
; inc si
; cmp al,0
; jz finishprint
; push cx es
; call modifychar
; call printchar
; pop es cx
; loop printloop1
; pop dx di bx
; add bx,linespacing
; jmp printloop2
;finishprint: pop dx di bx
; push si
; ret
; endp
Printslow proc near
mov pointerframe,1
mov pointermode,3
mov ds,charset1
printloopslow6: push bx di dx
call getnumber
mov ch,0
printloopslow5: push cx si es
mov ax,[es:si]
push bx cx es si ds
if foreign
call modifychar
endif
call printboth
pop ds si es cx bx
mov ax,[es:si+1]
inc si
cmp al,0
jz finishslow
cmp al,":"
jz finishslow
cmp cl,1
jz afterslow
push di ds bx cx es si
if foreign
call modifychar
endif
mov charshift,91
call printboth
mov charshift,0
pop si es cx bx ds di
call waitframes
cmp ax,0
jz keepgoing
cmp ax,oldbutton
jnz finishslow2
keepgoing: call waitframes
noslow: cmp ax,0
jz afterslow
cmp ax,oldbutton
jnz finishslow2 ;used to finish early
afterslow: pop es si cx
inc si
loop printloopslow5
pop dx di bx
add bx,10
jmp printloopslow6
finishslow: pop es si cx dx di bx
mov al,0
ret
finishslow2: pop es si cx dx di bx
mov al,1
ret
endp
Waitframes proc near
push di bx es si ds
call readmouse
call showpointer
call vsync
call dumppointer
call delpointer
mov ax,mousebutton
pop ds si es bx di
ret
endp
Printboth proc near
push ax cx bx
push di
call printchar
pop ax
push di
mov di,ax
call multidump
pop di
pop bx cx ax
ret
endp
Printdirect proc near
mov lastxpos,di
mov ds,currentset
printloop6: push bx di dx
call getnumber
mov ch,0
printloop5: mov ax,[es:si]
inc si
cmp al,0
jz finishdirct
cmp al,":"
jz finishdirct
push cx es
if foreign
call modifychar
endif
call printchar
mov lastxpos,di
pop es cx
loop printloop5
pop dx di bx
add bx,linespacing
jmp printloop6
finishdirct: pop dx di bx
ret
endp
Monprint proc near
mov kerning,1
mov si,bx
mov dl,166
mov di,monadx
mov bx,monady
mov ds,tempcharset
printloop8: push bx di dx
call getnumber
mov ch,0
printloop7: mov al,[es:si]
inc si
cmp al,":"
jz finishmon2
cmp al,0
jz finishmon
cmp al,34
jz finishmon
cmp al,"="
jz finishmon
cmp al,"%"
jnz nottrigger
mov ah,[es:si]
inc si
inc si
jmp finishmon
nottrigger: push cx es
if foreign
call modifychar
endif
call printchar
mov curslocx,di
mov curslocy,bx
mov maintimer,1
call printcurs
call vsync
push si dx ds es bx di
call lockmon
pop di bx es ds dx si
call delcurs
pop es cx
loop printloop7
finishmon2: pop dx di bx
call scrollmonitor
mov curslocx,di
jmp printloop8
finishmon: pop dx di bx
cmp al,"%"
jnz nottrigger2
mov lasttrigger,ah
nottrigger2: mov curslocx,di
call scrollmonitor
mov bx,si
mov kerning,0
ret
endp
Getnumber proc near
mov cx,0
push si bx di ds es
mov di,si
wordloop: push cx dx
call getnextword
pop dx cx
cmp al,1
jz endoftext
mov al,cl
mov ah,0
push bx
mov bh,0
add ax,bx
pop bx
sub ax,10
mov dh,0
cmp ax,dx
jnc gotoverend
add cl,bl
add ch,bh
jmp wordloop
gotoverend: mov al,dl
and al,1
jz notcentre
push cx
mov al,dl
and al,11111110b
mov ah,0
mov ch,0
sub ax,cx
add ax,20
shr ax,1
pop cx
pop es ds di bx si
add di,ax
mov cl,ch
ret
notcentre: pop es ds di bx si
mov cl,ch
ret
endoftext: mov al,cl
mov ah,0
push bx
mov bh,0
add ax,bx
pop bx
sub ax,10
mov dh,0
cmp ax,dx
jnc gotoverend2
add cl,bl
add ch,bh
gotoverend2: mov al,dl
and al,1
jz notcent2
push cx
mov al,dl
and al,11111110b
add al,2
mov ah,0
mov ch,0
add ax,20
sub ax,cx
shr ax,1
pop cx
pop es ds di bx si
add di,ax
mov cl,ch
ret
notcent2: pop es ds di bx si
mov cl,ch
ret
endp
Getnextword proc near
mov bx,0
getloop: mov ax,[es:di]
inc di
inc bh
cmp al,":"
jz endall
cmp al,0
jz endall
cmp al,32
jz endword
if foreign
call modifychar
endif
cmp al,255
jz getloop
push ax
sub al,32 ;"A"
mov ah,0
add ax,charshift
add ax,ax
mov si,ax
add ax,ax
add si,ax
mov cl,[si+0]
pop ax
call kernchars
add bl,cl
;dec bl
jmp getloop
endword: add bl,6
mov al,0
ret
endall: add bl,6
mov al,1
ret
endp
if german
Modifychar proc near
cmp al,128
jc nomod
cmp al,129
jnz not129
mov al,"Z"+3
ret
not129: cmp al,132
jnz not132
mov al,"Z"+1
ret
not132: cmp al,142
jnz not142
mov al,"Z"+4
ret
not142: cmp al,154
jnz not154
mov al,"Z"+6
ret
not154: cmp al,225
jnz not225
mov al,"A"-1
ret
not225: cmp al,153
jnz not153
mov al,"Z"+5
ret
not153: cmp al,148
jnz not148
mov al,"Z"+2
ret
not148: ret
nomod: ret
endp
endif
if spanish
Modifychar proc near
cmp al,128
jc nomod
cmp al,160
jnz not160
mov al,"Z"+1
ret
not160: cmp al,130
jnz not130
mov al,"Z"+2
ret
not130: cmp al,161
jnz not161
mov al,"Z"+3
ret
not161: cmp al,162
jnz not162
mov al,"Z"+4
ret
not162: cmp al,163
jnz not163
mov al,"Z"+5
ret
not163: cmp al,164
jnz not164
mov al,"Z"+6
ret
not164: cmp al,165
jnz not165
mov al,","-1
ret
not165: cmp al,168
jnz not168
mov al,"A"-1
ret
not168: cmp al,173
jnz not173
mov al,"A"-4
ret
not173: cmp al,129
jnz not129
mov al,"A"-5
not129: ret
nomod: ret
endp
endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,565 @@
;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
Talk proc near
mov talkpos,0
mov inmaparea,0
mov al,command
mov character,al
call createpanel
call showpanel
call showman
call showexit
call undertextline
call convicons
call starttalk
mov commandtype,255
call readmouse
call showpointer
call worktoscreen
waittalk: call delpointer
call readmouse
call animpointer
call showpointer
call vsync
call dumppointer
call dumptextline
mov getback,0
mov bx,offset cs:talklist
call checkcoords
cmp quitrequested, 0
jnz finishtalk
cmp getback,0
jz waittalk
finishtalk: mov bx,persondata
push cs
pop es
cmp talkpos,4
jc notnexttalk
mov al,[es:bx+7]
or al,128
mov [es:bx+7],al
notnexttalk: call redrawmainscrn
call worktoscreenm
cmp speechloaded,1
jnz nospeech
call cancelch1
mov volumedirection,-1 ;fade (louder)
mov volumeto,0 ;up to 0 (max)
nospeech: ret
talklist: dw 273,320,157,198,getback1
dw 240,290,2,44,moretalk
dw 0,320,0,200,blank
dw 0ffffh
endp
Convicons proc near
mov al,character
and al,127
call getpersframe
mov di,234
mov bx,2
mov currentframe,ax
call findsource
mov ax,currentframe
sub ax,takeoff
mov ah,0
call showframe
ret
endp
Getpersframe proc near
mov ah,0
add ax,ax
mov bx,ax
mov es,people
add bx,personframes
mov ax,[es:bx]
ret
endp
Starttalk proc near
mov talkmode,0
mov al,character
and al,127
call getpersontext
mov charshift,91+91
mov di,66
mov bx,64
mov dl,241
mov al,0
mov ah,79
call printdirect
mov charshift,0
mov di,66
mov bx,80
mov dl,241
mov al,0
mov ah,0
call printdirect
if cd
mov speechloaded,0
mov al,character
and al,127
mov ah,0
mov cx,64
mul cx
mov cl,"C"
mov dl,"R"
mov dh,reallocation
call loadspeech
cmp speechloaded,1
jnz nospeech1
mov volumedirection,1 ;quieter
mov volumeto,6 ;quite quiet!
mov al,50+12
call playchannel1
endif
nospeech1: ret
endp
Getpersontext proc near
mov ah,0
mov cx,64*2
mul cx
mov si,ax
mov es,people
add si,persontxtdat
mov cx,persontext
mov ax,[es:si]
add ax,cx
mov si,ax
ret
endp
Moretalk proc near
;cmp ch1playing,255
;jnz cantredes
cmp talkmode,0
jz canmore
call redes
ret
canmore: cmp commandtype,215
jz alreadymore
mov commandtype,215
mov al,49
call commandonly
alreadymore: mov ax,mousebutton
cmp ax,oldbutton
jz nomore
and ax,1
jnz domoretalk
nomore: ret
domoretalk: mov talkmode,2
mov talkpos,4
cmp character,100
jc notsecondpart
mov talkpos,48
notsecondpart: call dosometalk
ret
endp
Dosometalk proc near
if cd
dospeech: mov al,talkpos
mov al,character
and al,127
mov ah,0
mov cx,64
mul cx
mov cx,ax
mov al,talkpos
mov ah,0
add ax,cx
add ax,ax
mov si,ax
mov es,people
add si,persontxtdat
mov cx,persontext
mov ax,[es:si]
add ax,cx
mov si,ax
cmp byte ptr [es:si],0
jz endheartalk
push es si
call createpanel
call showpanel
call showman
call showexit
call convicons
pop si es
mov di,164
mov bx,64
mov dl,144
mov al,0
mov ah,0
call printdirect
mov al,character
and al,127
mov ah,0
mov cx,64
mul cx
mov cl,talkpos
mov ch,0
add ax,cx
mov cl,"C"
mov dl,"R"
mov dh,reallocation
call loadspeech
cmp speechloaded,0
jz noplay1
mov al,62
call playchannel1
noplay1: mov pointermode,3
call worktoscreenm
mov cx,180
call hangonpq
jnc $1
ret
$1:
inc talkpos
mov al,talkpos
mov al,character
and al,127
mov ah,0
mov cx,64
mul cx
mov cx,ax
mov al,talkpos
mov ah,0
add ax,cx
add ax,ax
mov si,ax
mov es,people
add si,persontxtdat
mov cx,persontext
mov ax,[es:si]
add ax,cx
mov si,ax
cmp byte ptr [es:si],0
jz endheartalk
cmp byte ptr [es:si],":"
jz skiptalk2
cmp byte ptr [es:si],32
jz skiptalk2
push es si
call createpanel
call showpanel
call showman
call showexit
call convicons
pop si es
mov di,48
mov bx,128
mov dl,144
mov al,0
mov ah,0
call printdirect
mov al,character
and al,127
mov ah,0
mov cx,64
mul cx
mov cl,talkpos
mov ch,0
add ax,cx
mov cl,"C"
mov dl,"R"
mov dh,reallocation
call loadspeech
cmp speechloaded,0
jz noplay2
mov al,62
call playchannel1
noplay2: mov pointermode,3
call worktoscreenm
mov cx,180
call hangonpq
jnc skiptalk2
ret
skiptalk2: inc talkpos
jmp dospeech
endheartalk: mov pointermode,0
ret
else
watchtalk: mov al,talkpos
mov al,character
and al,127
mov ah,0
mov cx,64
mul cx
mov cx,ax
mov al,talkpos
mov ah,0
add ax,cx
add ax,ax
mov si,ax
mov es,people
add si,persontxtdat
mov cx,persontext
mov ax,[es:si]
add ax,cx
mov si,ax
cmp byte ptr [es:si],0
jz endwatchtalk
push es si
call createpanel
call showpanel
call showman
call showexit
call convicons
pop si es
mov di,164
mov bx,64
mov dl,144
mov al,0
mov ah,0
call printdirect
mov pointermode,3
call worktoscreenm
mov cx,180
call hangonpq
jnc $1
ret
$1:
inc talkpos
mov al,talkpos
mov al,character
and al,127
mov ah,0
mov cx,64
mul cx
mov cx,ax
mov al,talkpos
mov ah,0
add ax,cx
add ax,ax
mov si,ax
mov es,people
add si,persontxtdat
mov cx,persontext
mov ax,[es:si]
add ax,cx
mov si,ax
cmp byte ptr [es:si],0
jz endwatchtalk
cmp byte ptr [es:si],":"
jz skiptalk
cmp byte ptr [es:si],32
jz skiptalk
push es si
call createpanel
call showpanel
call showman
call showexit
call convicons
pop si es
mov di,48
mov bx,128
mov dl,144
mov al,0
mov ah,0
call printdirect
mov pointermode,3
call worktoscreenm
mov cx,180
call hangonpq
jnc skiptalk
ret
skiptalk: inc talkpos
jmp watchtalk
endwatchtalk: mov pointermode,0
ret
endif
endp
Hangonpq proc near
mov getback,0
mov bx,0
hangloopq: push cx bx
call delpointer
call readmouse
call animpointer
call showpointer
call vsync
call dumppointer
call dumptextline
mov bx,offset cs:quitlist
call checkcoords
pop bx cx
cmp getback,1
jz quitconv
cmp quitrequested, 0
jnz quitconv
cmp speechloaded,1
jnz notspeaking
cmp ch1playing,255
jnz notspeaking
inc bx
cmp bx,40 ;pause after speech ends
jz finishconv
notspeaking: cmp mousebutton,0
jz hangloopq
cmp oldbutton,0
jnz hangloopq
finishconv: call delpointer
mov pointermode,0
clc
ret
quitconv: call delpointer
mov pointermode,0
call cancelch1
stc
ret
quitlist: dw 273,320,157,198,getback1
dw 0,320,0,200,blank
dw 0ffffh
endp
Redes proc near
cmp ch1playing,255
jnz cantredes
cmp talkmode,2
jz canredes
cantredes: call blank
ret
canredes: cmp commandtype,217
jz alreadyreds
mov commandtype,217
mov al,50
call commandonly
alreadyreds: mov ax,mousebutton
and ax,1
jnz doredes
ret
doredes: call delpointer
call createpanel
call showpanel
call showman
call showexit
call convicons
call starttalk
call readmouse
call showpointer
call worktoscreen
call delpointer
ret
endp

View File

@@ -0,0 +1,572 @@
;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
Titles proc near
if demo
ret
else
call clearpalette
call biblequote
cmp quitrequested, 0
jnz titlesearly
call intro
titlesearly:
ret
endif
endp
Endgame proc near
mov dx,offset cs:endtextname
call loadtemptext
call monkspeaking
call gettingshot
call getridoftemptext
mov volumeto,7
mov volumedirection,1
mov cx,200
call hangon
ret
endp
if cd
Monkspeaking proc near
mov roomssample,35
call loadroomssample
mov dx,offset cs:monkface
call loadintotemp
call clearwork ;createpanel2
call showmonk
call worktoscreen
mov volume,7
mov volumedirection,-1
mov volumeto,5
mov al,12
mov ah,255
call playchannel0
call fadescreenups
mov cx,300
call hangon
mov al,40
loadspeech2: push ax
mov dl,"T"
mov dh,83
mov cl,"T"
mov ah,0
call loadspeech
mov al,50+12
call playchannel1
notloadspeech2:
call vsync
cmp ch1playing,255
jnz notloadspeech2
pop ax
inc al
cmp al,48
jnz loadspeech2
mov volumedirection,1
mov volumeto,7
call fadescreendowns
mov cx,300
call hangon
call getridoftemp
ret
endp
else
Monkspeaking proc near
mov roomssample,35
call loadroomssample
mov dx,offset cs:monkface
call loadintotemp
call clearwork ;createpanel2
call showmonk
call worktoscreen
mov volume,7
mov volumedirection,-1
mov volumeto,0
mov al,12
mov ah,255
call playchannel0
call fadescreenups
mov cx,300
call hangon
mov al,40
nextmonkspeak: push ax
mov ah,0
mov si,ax
add si,si
mov es,textfile1
mov ax,[es:si]
add ax,textstart
mov si,ax
nextbit: mov di,36
mov bx,140
mov dl,239
call printdirect
push ax si es
call worktoscreen
call clearwork
call showmonk
mov cx,240
call hangon
pop es si ax
cmp al,0
jnz nextbit
pop ax
inc al
cmp al,44
jnz nextmonkspeak
mov volumedirection,1
mov volumeto,7
call fadescreendowns
mov cx,300
call hangon
call getridoftemp
ret
endp
endif
Showmonk proc near
mov al,0
mov ah,128
mov di,160
mov bx,72
mov ds,tempgraphics
call showframe
ret
endp
Gettingshot proc near
mov newlocation,55
call clearpalette
call loadintroroom
call fadescreenups
mov volumeto,0
mov volumedirection,-1
call runendseq
call clearbeforeload
ret
endp
Credits proc near
call clearpalette
call realcredits
ret
endp
Biblequote proc near
call mode640x480
mov dx,offset cs:title0graphics
call showpcx
call fadescreenups
mov cx,80
call hangone
cmp lasthardkey,1
jz biblequotearly
mov cx,560
call hangone
cmp lasthardkey,1
jz biblequotearly
call fadescreendowns
mov cx,200 ;128
call hangone
cmp lasthardkey,1
jz biblequotearly
call cancelch0
biblequotearly:
mov lasthardkey,0
ret
endp
Hangone proc near
hangonloope: push cx
call vsync
pop cx
cmp lasthardkey,1
jz hangonearly
loop hangonloope
hangonearly:
ret
endp
Intro proc near
mov dx,offset cs:introtextname
call loadtemptext
call loadpalfromiff
call setmode
mov newlocation,50
call clearpalette
call loadintroroom
mov volume,7
mov volumedirection,-1
if cd
mov volumeto,4
else
mov volumeto,0
endif
mov al,12 ;4
mov ah,255
call playchannel0
call fadescreenups
call runintroseq
cmp lasthardkey,1
jz introearly
;waitsound: cmp ch1blockstoplay,0
; jnz waitsound
call clearbeforeload
mov newlocation,52
call loadintroroom
call runintroseq
cmp lasthardkey,1
jz introearly
call clearbeforeload
mov newlocation,53
call loadintroroom
call runintroseq
cmp lasthardkey,1
jz introearly
call clearbeforeload
call allpalette
mov newlocation,54
call loadintroroom
;mov al,12
;mov ah,255
;call playchannel0
call runintroseq
cmp lasthardkey,1
jz introearly
call getridoftemptext
call clearbeforeload
introearly:
mov lasthardkey, 0
ret
endp
Runintroseq proc near
mov getback,0
moreintroseq: call vsync
cmp lasthardkey,1
jz earlyendrun
call spriteupdate
call vsync
cmp lasthardkey,1
jz earlyendrun
call deleverything
call printsprites
call reelsonscreen
call afterintroroom
call usetimedtext
call vsync
cmp lasthardkey,1
jz earlyendrun
call dumpmap
call dumptimedtext
call vsync
cmp lasthardkey,1
jz earlyendrun
cmp getback,1
jnz moreintroseq
ret
earlyendrun:
call getridoftemptext
call clearbeforeload
ret
endp
Runendseq proc near
call atmospheres
mov getback,0
moreendseq: call vsync
call spriteupdate
call vsync
call deleverything
call printsprites
call reelsonscreen
call afterintroroom
call usetimedtext
call vsync
call dumpmap
call dumptimedtext
call vsync
cmp getback,1
jnz moreendseq
ret
endp
Loadintroroom proc near
mov introcount,0
mov location,255
call loadroom
mov mapoffsetx,72
mov mapoffsety,16
call clearsprites
mov throughdoor,0
mov currentkey,"0"
mov mainmode,0
call clearwork
mov newobs,1
call drawfloor
call reelsonscreen
call spriteupdate
call printsprites
call worktoscreen
ret
endp
Mode640x480 proc near
mov al,12h+128
mov ah,0
int 10h
;call clearpalette
ret
endp
Set16colpalette proc near
mov cx,16
mov bl,0
mov bh,0
mov al,0
mov ah,10h
set16palloop2: push ax bx cx
int 10h
pop cx bx ax
inc bl
inc bh
loop set16palloop2
mov bl,31h
mov al,1
mov ah,12h
int 10h
ret
endp
RealCredits proc near
mov roomssample,33
call loadroomssample
mov volume,0
call mode640x480
mov cx,35
call hangon
mov dx,offset cs:title1graphics
call showpcx
mov al,12
mov ah,0
call playchannel0
mov cx,2
call hangone
cmp lasthardkey,1
jz realcreditsearly
call allpalette
mov cx,80
call hangone
cmp lasthardkey,1
jz realcreditsearly
call fadescreendowns
mov cx,256
call hangone
cmp lasthardkey,1
jz realcreditsearly
mov dx,offset cs:title2graphics
call showpcx
mov al,12
mov ah,0
call playchannel0
mov cx,2
call hangone
cmp lasthardkey,1
jz realcreditsearly
call allpalette
mov cx,80
call hangone
cmp lasthardkey,1
jz realcreditsearly
call fadescreendowns
mov cx,256
call hangone
cmp lasthardkey,1
jz realcreditsearly
if demo
else
mov dx,offset cs:title3graphics
call showpcx
mov al,12
mov ah,0
call playchannel0
mov cx,2
call hangone
cmp lasthardkey,1
jz realcreditsearly
call allpalette
mov cx,80
call hangone
cmp lasthardkey,1
jz realcreditsearly
call fadescreendowns
mov cx,256
call hangone
cmp lasthardkey,1
jz realcreditsearly
mov dx,offset cs:title4graphics
call showpcx
mov al,12
mov ah,0
call playchannel0
mov cx,2
call hangone
cmp lasthardkey,1
jz realcreditsearly
call allpalette
mov cx,80
call hangone
cmp lasthardkey,1
jz realcreditsearly
call fadescreendowns
mov cx,256
call hangone
cmp lasthardkey,1
jz realcreditsearly
mov dx,offset cs:title5graphics
call showpcx
mov al,12
mov ah,0
call playchannel0
mov cx,2
call hangone
cmp lasthardkey,1
jz realcreditsearly
call allpalette
mov cx,80
call hangone
cmp lasthardkey,1
jz realcreditsearly
call fadescreendowns
mov cx,256
call hangone
cmp lasthardkey,1
jz realcreditsearly
endif
mov dx,offset cs:title6graphics
call showpcx
call fadescreenups
mov cx,60
call hangone
cmp lasthardkey,1
jz realcreditsearly
mov al,13
mov ah,0
call playchannel0
mov cx,350
call hangone
cmp lasthardkey,1
jz realcreditsearly
call fadescreendowns
mov cx,256
call hangone
realcreditsearly:
mov lasthardkey, 0
ret
endp

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,562 @@
;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
;---------------------------------------------------Equates and definitions----
Inputport equ 63h
Mapwidth equ 66 ;132/2
Maplength equ 60 ;6/2
Tablesize equ 32 ;size of each entry in spritetable
Itempicsize equ 44 ;size of inventory slots
Opsy equ 52
Opsx equ 60
Inventx equ 80
Inventy equ 58
Zoomx equ 8
Zoomy equ 132
Keypadx equ 36+112
Keypady equ 72
Diaryx equ 68+24
Diaryy equ 48+12
Symbolx equ 64
Symboly equ 56
Menux equ 80+40
Menuy equ 60
if foreign
Undertextsizex equ 228
Undertextsizey equ 13
Undertimedysize equ 30
else
Undertextsizex equ 180
Undertextsizey equ 10
Undertimedysize equ 24
endif
Numchanges equ 250
Textunder equ 0 ;offsets for items in buffer segment
Openinvlist equ textunder+(undertextsizex*undertextsizey)
Ryaninvlist equ openinvlist+32
Pointerback equ ryaninvlist+60
Mapflags equ pointerback+(32*32)
Startpal equ mapflags+(11*10*3)
Endpal equ startpal+768
Maingamepal equ endpal+768
Spritetable equ maingamepal+768
Setlist equ spritetable+(32*tablesize)
Freelist equ setlist+(128*5)
Exlist equ freelist+(80*5)
Peoplelist equ exlist+(100*5)
Zoomspace equ peoplelist+(12*5)
Printedlist equ zoomspace+(46*40)
Listofchanges equ printedlist+(5*80)
Undertimedtext equ listofchanges+(numchanges*4)
Rainlist equ undertimedtext+(256*undertimedysize)
Initialreelrouts equ rainlist+(6*64)
Initialvars equ initialreelrouts+lenofreelrouts
Lengthofbuffer equ initialvars+lengthofvars
Flags equ 0 ;offsets of items in backdrop segment
Blocks equ flags+192
Map equ 0
Lengthofmap equ map+(mapwidth*maplength)
Intextdat equ 0
Intext equ intextdat+(38*2)
Blocktextdat equ 0
Blocktext equ blocktextdat+(98*2)
Settextdat equ 0
Settext equ settextdat+(130*2)
Freetextdat equ 0
Freetext equ freetextdat+(82*2)
Numexobjects equ 114
Exframeslen equ 30000
Extextlen equ 18000
Exframedata equ 0
Exframes equ exframedata+2080
Exdata equ exframes+exframeslen
Extextdat equ exdata+(16*numexobjects)
Extext equ extextdat+((numexobjects+2)*2)
Lengthofextra equ extext+extextlen
Framedata equ 0
Frames equ framedata+2080
Frframedata equ 0
Frframes equ frframedata+2080
Personframes equ 0
Persontxtdat equ personframes+24
Persontext equ persontxtdat+(1026*2)
Pathdata equ 0
Reellist equ pathdata+(36*144)
Lenofmapstore equ 22*8*20*8
Maplen equ mapwidth*maplength
Freedatlen equ 16*80
Setdatlen equ 64*128
Textstart equ 66*2
;-----------------------------------------------------------------Variables----
startvars db 0
progresspoints db 0
watchon db 0
shadeson db 0
secondcount db 0
minutecount db 30
hourcount db 19
zoomon db 1
location db 0
expos db 0
exframepos dw 0
extextpos dw 0
card1money dw 0
listpos dw 0
ryanpage db 0
watchingtime dw 0
reeltowatch dw -1 ;reel plays from here in mode 0
endwatchreel dw 0 ;and stops here. Mode set to 1
speedcount db 0
watchspeed db 0
reeltohold dw -1 ;if mode is 1 hold on this reel
endofholdreel dw -1 ;if mode is 2 then play to end of
watchmode db -1 ;hold reel. Set mode back to -1
destafterhold db 0 ;set walking destination.
newsitem db 0
liftflag db 0
liftpath db 0
lockstatus db 1
doorpath db 0
counttoopen db 0
counttoclose db 0
rockstardead db 0
generaldead db 0
sartaindead db 0
aidedead db 0
beenmugged db 0
gunpassflag db 0
canmovealtar db 0
talkedtoattendant db 0
talkedtosparky db 0
talkedtoboss db 0
talkedtorecep db 0
cardpassflag db 0
madmanflag db 0
keeperflag db 0
lasttrigger db 0
mandead db 0
seed db 1,2,3
needtotravel db 0
throughdoor db 0
newobs db 0
ryanon db 255
combatcount db 0
lastweapon db -1
dreamnumber db 0
roomafterdream db 0
shakecounter db 48
lengthofvars equ $-startvars
speechcount db 0
charshift dw 0
kerning db 0
brightness db 0
roomloaded db 0
didzoom db 0
linespacing dw 10
textaddressx dw 13
textaddressy dw 182 ;address on screen for text
textlen db 0
lastxpos dw 0
icontop dw 0
iconleft dw 0
itemframe db 0
itemtotran db 0
roomad dw 0
oldsubject dw 0
withobject db 0
withtype db 0
lookcounter dw 0
command db 0
commandtype db 0
oldcommandtype db 0
objecttype db 0
getback db 0
invopen db 0
mainmode db 0
pickup db 0
lastinvpos db 0
examagain db 0
newtextline db 0
openedob db 0
openedtype db 0
oldmapadx dw 0
oldmapady dw 0
mapadx dw 0
mapady dw 0
mapoffsetx dw 104
mapoffsety dw 38
mapxstart dw 0
mapystart dw 0
mapxsize db 0
mapysize db 0
havedoneobs db 0
manisoffscreen db 0
rainspace db 0
facing db 0
leavedirection db 0
turntoface db 0
turndirection db 0
maintimer dw 0
introcount db 0
arrowad dw 0
currentkey db 0
oldkey db 0
useddirection db 0
currentkey2 db 0
timercount db 0
oldtimercount db 0
mapx db 0
mapy db 0
newscreen db 0
ryanx db 0
ryany db 0
lastflag db 0
lastflagex db 0
flagx db 0
flagy db 0
currentex db 0
currentfree db 0
currentframe dw 0
framesad dw 0
dataad dw 0
frsegment dw 0
objectx dw 0
objecty dw 0
offsetx dw 0
offsety dw 0
savesize dw 0
savesource dw 0
savex db 0
savey db 0
currentob db 0
priorityDep db 0 ; dep for deprecated, I leave a byte here to minimize changes to the generated code
destpos db 0
reallocation db 0 ;----------;some rooms have more than one
roomnum db 0 ;place in the Roomdata list, to
;account for different start points
nowinnewroom db 0 ;this variable holds the rooms
resetmanxy db 0 ;real value - ie:which file it's in
newlocation db -1 ;if set then room is loaded at end of watch mode, or straight away if not in watch mode
autolocation db -1
mustload db 0
answered db 0
saidno db 0
doorcheck1 db 0
doorcheck2 db 0
doorcheck3 db 0
doorcheck4 db 0
mousex dw 0
mousey dw 0
mousebutton dw 0
mousebutton1 dw 0
mousebutton2 dw 0
mousebutton3 dw 0
mousebutton4 dw 0
oldbutton dw 0
oldx dw 0
oldy dw 0
lastbutton dw 0
oldpointerx dw 0
oldpointery dw 0
delherex dw 0
delherey dw 0
pointerxs db 32
pointerys db 32
delxs db 0
delys db 0
pointerframe db 0
pointerpower db 0
auxpointerframe db 0
pointermode db 0
pointerspeed db 0
pointercount db 0
inmaparea db 0
reelpointer dw 0
slotdata db 0
thisslot db 0
slotflags db 0
takeoff dw 0
talkmode db 0
talkpos db 0
character db 0
persondata dw 0
talknum db 0
numberinroom db 0
currentcel db 0
oldselection db 0
stopwalking db 0
mouseon db 0
played dw 0
timer1 db 0
timer2 db 0
timer3 db 0
wholetimer dw 0
timer1to db 0
timer2to db 0
timer3to db 0
watchdump db 0
currentset dw 0
logonum db 0
oldlogonum db 0
newlogonum db 0
netseg dw 0
netpoint dw 0
keynum db 0
cursorstate db 0
pressed db 0
presspointer dw 0
graphicpress db 0
presscount db 0
keypadax dw 0
keypadcx dw 0
lightcount db 0
folderpage db 0
diarypage db 0
menucount db 0
symboltopx db 0
symboltopnum db 0
symboltopdir db 0
symbolbotx db 0
symbolbotnum db 0
symbolbotdir db 0
symboltolight db 0
symbol1 db 0
symbol2 db 0
symbol3 db 0
symbolnum db 0
dumpx dw 0
dumpy dw 0
walkandexam db 0
walkexamtype db 0
walkexamnum db 0
cursloc dw 0
curslocx dw 0
curslocy dw 0
curpos dw 0
monadx dw 0
monady dw 0
gotfrom dw 0
monsource dw 0
numtodo dw 0
timecount dw 0
counttotimed dw 0
timedseg dw 0
timedoffset dw 0
timedy db 0
timedx db 0
needtodumptimed db 0
;recordpos dw 0
;rechandle dw 0
handle dw 0
loadingorsave db 0 ;1 if load 2 if save
currentslot db 0
cursorpos db 0
colourpos db 0
fadedirection db 0
numtofade db 0
fadecount db 0
addtogreen db 0
addtored db 0
addtoblue db 0
lastsoundreel dw 0
soundbuffer dw 0
soundbufferad dw 0
soundbufferpage db 0
soundtimes db 0
needsoundbuff db 0
oldint9seg dw -1
oldint9add dw -1
oldint8seg dw -1
oldint8add dw -1
oldsoundintseg dw 0
oldsoundintadd dw 0
soundbaseadd dw 0
dsp_status dw 0
dsp_write dw 0
dmaaddress db 0
soundint db 5
sounddmachannel db 1
sampleplaying db 255
testresult db 0
currentirq db 0
speechloaded db 0
speechlength dw 0
volume db 0
volumeto db 0
volumedirection db 0
volumecount db 0
playblock db 0
wongame db 0
lasthardkey db 0
bufferin dw 0
bufferout dw 0
extras dw 0 ;for allocated memory
workspace dw 0 ;allocated mem for screen buffer
mapstore dw 0 ;allocated mem for copy of room
charset1 dw 0 ;allocated mem for normal charset
tempcharset dw 0 ;monitor char set
icons1 dw 0 ;allocated mem for on screen stuff
icons2 dw 0
buffers dw 0 ;allocated mem for buffers
mainsprites dw 0 ;allocated mem for Ryan sprites
backdrop dw 0
mapdata dw 0
sounddata dw 0
sounddata2 dw 0
recordspace dw 0
freedat dw 0
setdat dw 0
reel1 dw -1
reel2 dw -1
reel3 dw -1
roomdesc dw -1
freedesc dw -1
setdesc dw -1
blockdesc dw -1
setframes dw -1
freeframes dw -1
people dw -1
reels dw -1
commandtext dw -1
puzzletext dw -1
traveltext dw -1
tempgraphics dw -1
tempgraphics2 dw -1
tempgraphics3 dw -1
tempsprites dw -1
textfile1 dw -1
textfile2 dw -1
textfile3 dw -1
blinkframe db 23
blinkcount db 0
reasseschanges db 0 ; if it's a 1 then obname will assume that
pointerspath db 0 ;the command has changed.
manspath db 0 ;ie. from "walk to" to "Examine"
pointerfirstpath db 0
finaldest db 0
destination db 0
linestartx dw 0
linestarty dw 0
lineendx dw 0
lineendy dw 0
increment1 dw 0
increment2 dw 0
lineroutine db 0
linepointer db 0
linedirection db 0
linelength db 0
liftsoundcount db 0
emmhandle dw 0
emmpageframe dw 0
emmhardwarepage db 0
ch0emmpage dw 0
ch0offset dw 0
ch0blockstocopy dw 0
ch0playing db 0
ch0repeat db 0
ch0oldemmpage dw 0
ch0oldoffset dw 0
ch0oldblockstocopy dw 0
ch1playing db 255
ch1emmpage dw 0
ch1offset dw 0
ch1blockstocopy dw 0
ch1blocksplayed dw 0
soundbufferwrite dw 0
soundemmpage dw 0
speechemmpage dw 0
currentsample db -1
roomssample db 0
gameerror db 0
howmuchalloc dw 0

View File

@@ -0,0 +1,864 @@
;Copyright (c) 1990-2012 by Neil Dodwell
;Released with permission from Neil Dodwell under GPLv2
;See LICENSE file for full license text
Fadedos proc near
call vsync
mov es,buffers
mov di,startpal
mov al,0
mov dx,3c7h
out dx,al
mov dx,3c9h
mov cx,768/4
dos1: in al,dx
stosb
loop dos1
mov cx,64
fadedosloop: push cx
mov ds,buffers
mov si,startpal
mov cx,768
dos3: lodsb
cmp al,0
jz nodown
dec al
nodown: mov [si-1],al
loop dos3
call vsync
mov ds,buffers
mov si,startpal
mov al,0
mov dx,3c8h
out dx,al
inc dx
mov cx,768/4
dos2: lodsb
out dx,al
loop dos2
pop cx
loop fadedosloop
ret
endp
Dofade proc near
cmp fadedirection,0
jz finishfade
mov cl,numtofade
mov ch,0
mov al,colourpos
mov ah,0
mov ds,buffers
mov si,startpal
add si,ax
add si,ax
add si,ax
call showgroup
mov al,numtofade
add al,colourpos
mov colourpos,al
cmp al,0
jnz finishfade
call fadecalculation
finishfade: ret
endp
Clearendpal proc near
mov es,buffers
mov di,endpal
mov cx,768
mov al,0
rep stosb
ret
endp
Clearpalette proc near
mov fadedirection,0
call clearstartpal
call dumpcurrent
ret
endp
Fadescreenup proc near
call clearstartpal
call paltoendpal
mov fadedirection,1
mov fadecount,63
mov colourpos,0
mov numtofade,128
ret
endp
Fadetowhite proc near
mov es,buffers
mov di,endpal
mov cx,768
mov al,63
rep stosb
mov di,endpal
mov al,0
stosb
stosb
stosb
call paltostartpal
mov fadedirection,1
mov fadecount,63
mov colourpos,0
mov numtofade,128
ret
endp
Fadefromwhite proc near
mov es,buffers
mov di,startpal
mov cx,768
mov al,63
rep stosb
mov di,startpal
mov al,0
stosb
stosb
stosb
call paltoendpal
mov fadedirection,1
mov fadecount,63
mov colourpos,0
mov numtofade,128
ret
endp
Fadescreenups proc near
call clearstartpal
call paltoendpal
mov fadedirection,1
mov fadecount,63
mov colourpos,0
mov numtofade,64
ret
endp
Fadescreendownhalf proc near
call paltostartpal
call paltoendpal
mov cx,768
mov es,buffers
mov bx,endpal
halfend: mov al,[es:bx]
shr al,1
mov [es:bx],al
inc bx
loop halfend
mov ds,buffers
mov es,buffers
mov si,startpal+(56*3)
mov di,endpal+(56*3)
mov cx,3*5
rep movsb
mov si,startpal+(77*3)
mov di,endpal+(77*3)
mov cx,3*2
rep movsb
mov fadedirection,1
mov fadecount,31
mov colourpos,0
mov numtofade,32
ret
endp
Fadescreenuphalf proc near
call endpaltostart
call paltoendpal
mov fadedirection,1
mov fadecount,31
mov colourpos,0
mov numtofade,32
ret
endp
Fadescreendown proc near
call paltostartpal
call clearendpal
mov fadedirection,1
mov fadecount,63
mov colourpos,0
mov numtofade,128
ret
endp
Fadescreendowns proc near
call paltostartpal
call clearendpal
mov fadedirection,1
mov fadecount,63
mov colourpos,0
mov numtofade,64
ret
endp
Clearstartpal proc near
mov es,buffers
mov di,startpal
mov cx,256
wholeloop1: mov ax,0
stosw
mov al,0
stosb
loop wholeloop1
ret
endp
Showgun proc near
mov addtored,0 ;12
mov addtogreen,0
mov addtoblue,0
call paltostartpal
call paltoendpal
call greyscalesum
; mov es,buffers
; mov di,endpal+3
; mov cx,255
; mov ax,0
;reds: mov byte ptr [es:di],63
; inc di
; stosw
; loop reds
mov fadedirection,1
mov fadecount,63
mov colourpos,0
mov numtofade,128
mov cx,130
call hangon
call endpaltostart
call clearendpal
mov fadedirection,1
mov fadecount,63
mov colourpos,0
mov numtofade,128
mov cx,200
call hangon
mov roomssample,34
call loadroomssample
mov volume,0
mov dx,offset cs:gungraphic
call loadintotemp
call createpanel2
mov ds,tempgraphics
mov al,0
mov ah,0
mov di,100
mov bx,4
call showframe
mov ds,tempgraphics
mov al,1
mov ah,0
mov di,158
mov bx,106
call showframe
call worktoscreen
call getridoftemp
call fadescreenup
mov cx,160
call hangon
mov al,12
mov ah,0
call playchannel0
mov dx,offset cs:endtextname
call loadtemptext
call rollendcredits2
call getridoftemptext
ret
endp
Rollendcredits2 proc near
call rollem
ret
endp
Rollem proc near
mov cl,160
mov ch,160
mov di,25
mov bx,20
mov ds,mapstore
mov si,0
call multiget
mov es,textfile1
mov si,49*2
mov ax,[es:si]
mov si,ax
add si,textstart
mov cx,80
endcredits21: push cx
mov bx,10
mov cx,linespacing
endcredits22: push cx si di es bx
call vsync
mov cl,160
mov ch,160
mov di,25
mov bx,20
mov ds,mapstore
mov si,0
call multiput
call vsync
pop bx es di si
push si di es bx
mov cx,18
onelot2: push cx
mov di,25 ;75
mov dx,161
mov ax,0
call printdirect
add bx,linespacing
pop cx
loop onelot2
call vsync
mov cl,160
mov ch,160
mov di,25 ;75
mov bx,20
call multidump
pop bx es di si cx
cmp lasthardkey,1
jz endearly2
dec bx
loop endcredits22
pop cx
looknext2: mov al,[es:si]
inc si
cmp al,":"
jz gotnext2
cmp al,0
jz gotnext2
jmp looknext2
gotnext2: cmp lasthardkey,1
jz endearly
loop endcredits21
mov cx,120
call hangone
ret
endearly2: pop cx
endearly: ret
endp
Fadecalculation proc near
cmp fadecount,0
jz nomorefading
mov bl,fadecount
mov es,buffers
mov si,startpal
mov di,endpal
mov cx,768
fadecolloop: mov al,[es:si]
mov ah,[es:di]
cmp al,ah
jz gotthere
jc lesscolour
dec byte ptr [es:si]
jmp gotthere
lesscolour: cmp bl,ah
jz withit
jnc gotthere
withit: inc byte ptr [es:si]
gotthere: inc si
inc di
loop fadecolloop
dec fadecount
ret
nomorefading: mov fadedirection,0
ret
endp
Greyscalesum proc near ;converts palette to grey scale
;summed using formula:
mov es,buffers ; .20xred + .59xGreen + .11xBlue
mov si,maingamepal
mov di,endpal
mov cx,256 ;convert 256 colours
greysumloop1: push cx
mov bx,0
mov al,[es:si]
mov ah,0
mov cx,20
mul cx
add bx,ax
mov al,[es:si+1]
mov ah,0
mov cx,59
mul cx
add bx,ax
mov al,[es:si+2]
mov ah,0
mov cx,11
mul cx
add bx,ax ;bx holds equationx100
mov al,-1 ;divide result by 100
greysumloop2: inc al
sub bx,100
jnc greysumloop2 ;ah holds grey scale number
mov bl,al
mov al,bl
mov ah,addtored
cmp al,0
;jz noaddr
add al,ah
noaddr: stosb
mov ah,addtogreen
mov al,bl
cmp al,0
jz noaddg
add al,ah
noaddg: stosb ;store result in red, green and
mov ah,addtoblue
mov al,bl
cmp al,0
jz noaddb
add al,ah
noaddb: stosb ;blue portions of palette.
add si,3
pop cx
loop greysumloop1
ret
endp
Showgroup proc near
mov dx,3c8h
out dx,al
mov dx,3c9h
showgroup1: lodsb
out dx,al
lodsb
out dx,al
lodsb
out dx,al
loop showgroup1
ret
endp
Paltostartpal proc near
mov es,buffers
mov ds,buffers
mov si,maingamepal
mov di,startpal
mov cx,768/2
rep movsw
ret
endp
Endpaltostart proc near
mov es,buffers
mov ds,buffers
mov si,endpal
mov di,startpal
mov cx,768/2
rep movsw
ret
endp
Startpaltoend proc near
mov es,buffers
mov ds,buffers
mov di,endpal
mov si,startpal
mov cx,768/2
rep movsw
ret
endp
Paltoendpal proc near
mov es,buffers
mov ds,buffers
mov di,endpal
mov si,maingamepal
mov cx,768/2
rep movsw
ret
endp
Allpalette proc near
mov es,buffers
mov ds,buffers
mov di,startpal
mov si,maingamepal
mov cx,768/2
rep movsw
call dumpcurrent
ret
endp
Dumpcurrent proc near
mov si,startpal
mov ds,buffers
call vsync
mov al,0
mov cx,128
call showgroup
call vsync
mov al,128
mov cx,128
call showgroup
ret
endp
Fadedownmon proc near
call paltostartpal
call paltoendpal
mov es,buffers
mov di,endpal+(231*3)
mov cx,3*8
mov ax,0
rep stosb
mov di,endpal+(246*3)
stosb
stosw
mov fadedirection,1
mov fadecount,63
mov colourpos,0
mov numtofade,128
mov cx,64 ;100
call hangon ;curs
ret
endp
Fadeupmon proc near
call paltostartpal
call paltoendpal
mov es,buffers
mov di,startpal+(231*3)
mov cx,3*8
mov ax,0
rep stosb
mov di,startpal+(246*3)
stosb
stosw
mov fadedirection,1
mov fadecount,63
mov colourpos,0
mov numtofade,128
mov cx,128
call hangon ;curs
ret
endp
Fadeupmonfirst proc near
call paltostartpal
call paltoendpal
mov es,buffers
mov di,startpal+(231*3)
mov cx,3*8
mov ax,0
rep stosb
mov di,startpal+(246*3)
stosb
stosw
mov fadedirection,1
mov fadecount,63
mov colourpos,0
mov numtofade,128
mov cx,64
call hangon
mov al,26
call playchannel1
mov cx,64
call hangon
ret
endp
Fadeupyellows proc near
;call startpaltoend
call paltoendpal
mov es,buffers
mov di,endpal+(231*3)
mov cx,3*8
mov ax,0
rep stosb
mov di,endpal+(246*3)
stosb
stosw
mov fadedirection,1
mov fadecount,63
mov colourpos,0
mov numtofade,128
mov cx,128
call hangon
ret
endp
Initialmoncols proc near
call paltostartpal
mov es,buffers
mov di,startpal+(230*3)
mov cx,3*9
mov ax,0
rep stosb
mov di,startpal+(246*3)
stosb
stosw
mov ds,buffers
mov si,startpal+(230*3)
mov al,230
mov cx,18
call showgroup
ret
endp

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

View File

@@ -0,0 +1,680 @@
# 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/>.
#
import op, traceback, re, proc
from copy import copy
proc_module = proc
class CrossJump(Exception):
pass
def parse_bin(s):
b = s.group(1)
v = hex(int(b, 2))
#print "BINARY: %s -> %s" %(b, v)
return v
class cpp:
def __init__(self, context, namespace, skip_first = 0, blacklist = [], skip_output = [], skip_dispatch_call = False, skip_addr_constants = False, header_omit_blacklisted = False, function_name_remapping = { }):
self.namespace = namespace
fname = namespace.lower() + ".cpp"
header = namespace.lower() + ".h"
banner = """/* PLEASE DO NOT MODIFY THIS FILE. ALL CHANGES WILL BE LOST! LOOK FOR README FOR DETAILS */
/* 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/>.
*
*/
"""
self.fd = open(fname, "wt")
self.hd = open(header, "wt")
hid = "TASMRECOVER_%s_STUBS_H__" %namespace.upper()
self.hd.write("""#ifndef %s
#define %s
%s""" %(hid, hid, banner))
self.context = context
self.data_seg = context.binary_data
self.procs = context.proc_list
self.skip_first = skip_first
self.proc_queue = []
self.proc_done = []
self.blacklist = blacklist
self.failed = list(blacklist)
self.skip_output = skip_output
self.skip_dispatch_call = skip_dispatch_call
self.skip_addr_constants = skip_addr_constants
self.header_omit_blacklisted = header_omit_blacklisted
self.function_name_remapping = function_name_remapping
self.translated = []
self.proc_addr = []
self.used_data_offsets = set()
self.methods = []
self.fd.write("""%s
#include \"%s\"
namespace %s {
""" %(banner, header, namespace))
def expand_cb(self, match):
name = match.group(0).lower()
if len(name) == 2 and \
((name[0] in ['a', 'b', 'c', 'd'] and name[1] in ['h', 'x', 'l']) or name in ['si', 'di', 'es', 'ds', 'cs']):
return "%s" %name
if self.indirection == -1:
try:
offset,p,p = self.context.get_offset(name)
except:
pass
else:
print "OFFSET = %d" %offset
self.indirection = 0
self.used_data_offsets.add((name,offset))
return "offset_%s" % (name,)
g = self.context.get_global(name)
if isinstance(g, op.const):
value = self.expand_equ(g.value)
print "equ: %s -> %s" %(name, value)
elif isinstance(g, proc.proc):
if self.indirection != -1:
raise Exception("invalid proc label usage")
value = str(g.offset)
self.indirection = 0
else:
size = g.size
if size == 0:
raise Exception("invalid var '%s' size %u" %(name, size))
if self.indirection == 0:
value = "data.%s(k%s)" %("byte" if size == 1 else "word", name.capitalize())
elif self.indirection == -1:
value = "%s" %g.offset
self.indirection = 0
else:
raise Exception("invalid indirection %d" %self.indirection)
return value
def get_size(self, expr):
#print 'get_size("%s")' %expr
try:
v = self.context.parse_int(expr)
return 1 if v < 256 else 2
except:
pass
if re.match(r'byte\s+ptr\s', expr) is not None:
return 1
if re.match(r'word\s+ptr\s', expr) is not None:
return 2
if len(expr) == 2 and expr[0] in ['a', 'b', 'c', 'd'] and expr[1] in ['h', 'l']:
return 1
if expr in ['ax', 'bx', 'cx', 'dx', 'si', 'di', 'sp', 'bp', 'ds', 'cs', 'es', 'fs']:
return 2
m = re.match(r'[a-zA-Z_]\w*', expr)
if m is not None:
name = m.group(0)
try:
g = self.context.get_global(name)
return g.size
except:
pass
return 0
def expand_equ_cb(self, match):
name = match.group(0).lower()
g = self.context.get_global(name)
if isinstance(g, op.const):
return g.value
return str(g.offset)
def expand_equ(self, expr):
n = 1
while n > 0:
expr, n = re.subn(r'\b[a-zA-Z_][a-zA-Z0-9_]+\b', self.expand_equ_cb, expr)
expr = re.sub(r'\b([0-9][a-fA-F0-9]*)h', '0x\\1', expr)
return "(%s)" %expr
def expand(self, expr, def_size = 0):
#print "EXPAND \"%s\"" %expr
size = self.get_size(expr) if def_size == 0 else def_size
indirection = 0
seg = None
reg = True
m = re.match(r'seg\s+(.*?)$', expr)
if m is not None:
return "data"
match_id = True
m = re.match(r'offset\s+(.*?)$', expr)
if m is not None:
indirection -= 1
expr = m.group(1).strip()
m = re.match(r'byte\s+ptr\s+(.*?)$', expr)
if m is not None:
expr = m.group(1).strip()
m = re.match(r'word\s+ptr\s+(.*?)$', expr)
if m is not None:
expr = m.group(1).strip()
m = re.match(r'\[(.*)\]$', expr)
if m is not None:
indirection += 1
expr = m.group(1).strip()
m = re.match(r'(\w{2,2}):(.*)$', expr)
if m is not None:
seg_prefix = m.group(1)
expr = m.group(2).strip()
print "SEGMENT %s, remains: %s" %(seg_prefix, expr)
else:
seg_prefix = "ds"
m = re.match(r'(([abcd][xhl])|si|di|bp|sp)([\+-].*)?$', expr)
if m is not None:
reg = m.group(1)
plus = m.group(3)
if plus is not None:
plus = self.expand(plus)
else:
plus = ""
match_id = False
#print "COMMON_REG: ", reg, plus
expr = "%s%s" %(reg, plus)
expr = re.sub(r'\b([0-9][a-fA-F0-9]*)h', '0x\\1', expr)
expr = re.sub(r'\b([0-1]+)b', parse_bin, expr)
expr = re.sub(r'"(.)"', '\'\\1\'', expr)
if match_id:
#print "BEFORE: %d" %indirection
self.indirection = indirection
expr = re.sub(r'\b[a-zA-Z_][a-zA-Z0-9_]+\b', self.expand_cb, expr)
indirection = self.indirection
#print "AFTER: %d" %indirection
if indirection == 1:
if size == 1:
expr = "%s.byte(%s)" %(seg_prefix, expr)
elif size == 2:
expr = "%s.word(%s)" %(seg_prefix, expr)
else:
expr = "@invalid size 0"
elif indirection == 0:
pass
elif indirection == -1:
expr = "&%s" %expr
else:
raise Exception("invalid indirection %d" %indirection)
return expr
def mangle_label(self, name):
name = name.lower()
return re.sub(r'\$', '_tmp', name)
def resolve_label(self, name):
name = name.lower()
if not name in self.proc.labels:
try:
offset, proc, pos = self.context.get_offset(name)
except:
print "no label %s, trying procedure" %name
proc = self.context.get_global(name)
pos = 0
if not isinstance(proc, proc_module.proc):
raise CrossJump("cross-procedure jump to non label and non procedure %s" %(name))
self.proc.labels.add(name)
for i in xrange(0, len(self.unbounded)):
u = self.unbounded[i]
if u[1] == proc:
if pos < u[2]:
self.unbounded[i] = (name, proc, pos)
return self.mangle_label(name)
self.unbounded.append((name, proc, pos))
return self.mangle_label(name)
def jump_to_label(self, name):
jump_proc = False
if name in self.blacklist:
jump_proc = True
if self.context.has_global(name) :
g = self.context.get_global(name)
if isinstance(g, proc_module.proc):
jump_proc = True
if jump_proc:
if name in self.function_name_remapping:
return "{ %s(); return; }" %self.function_name_remapping[name]
else:
return "{ %s(); return; }" %name
else:
# TODO: name or self.resolve_label(name) or self.mangle_label(name)??
if name in self.proc.retlabels:
return "return /* (%s) */" % (name)
return "goto %s" %self.resolve_label(name)
def _label(self, name):
self.body += "%s:\n" %self.mangle_label(name)
def schedule(self, name):
name = name.lower()
if name in self.proc_queue or name in self.proc_done or name in self.failed:
return
print "+scheduling function %s..." %name
self.proc_queue.append(name)
def _call(self, name):
name = name.lower()
if name == 'ax':
self.body += "\t__dispatch_call(%s);\n" %self.expand('ax', 2)
return
if name in self.function_name_remapping:
self.body += "\t%s();\n" %self.function_name_remapping[name]
else:
self.body += "\t%s();\n" %name
self.schedule(name)
def _ret(self):
self.body += "\treturn;\n"
def parse2(self, dst, src):
dst_size, src_size = self.get_size(dst), self.get_size(src)
if dst_size == 0:
if src_size == 0:
raise Exception("both sizes are 0")
dst_size = src_size
if src_size == 0:
src_size = dst_size
dst = self.expand(dst, dst_size)
src = self.expand(src, src_size)
return dst, src
def _mov(self, dst, src):
self.body += "\t%s = %s;\n" %self.parse2(dst, src)
def _add(self, dst, src):
self.body += "\t_add(%s, %s);\n" %self.parse2(dst, src)
def _sub(self, dst, src):
self.body += "\t_sub(%s, %s);\n" %self.parse2(dst, src)
def _and(self, dst, src):
self.body += "\t_and(%s, %s);\n" %self.parse2(dst, src)
def _or(self, dst, src):
self.body += "\t_or(%s, %s);\n" %self.parse2(dst, src)
def _xor(self, dst, src):
self.body += "\t_xor(%s, %s);\n" %self.parse2(dst, src)
def _neg(self, dst):
dst = self.expand(dst)
self.body += "\t_neg(%s);\n" %(dst)
def _cbw(self):
self.body += "\tax.cbw();\n"
def _shr(self, dst, src):
self.body += "\t_shr(%s, %s);\n" %self.parse2(dst, src)
def _shl(self, dst, src):
self.body += "\t_shl(%s, %s);\n" %self.parse2(dst, src)
#def _sar(self, dst, src):
# self.body += "\t_sar(%s%s);\n" %self.parse2(dst, src)
#def _sal(self, dst, src):
# self.body += "\t_sal(%s, %s);\n" %self.parse2(dst, src)
#def _rcl(self, dst, src):
# self.body += "\t_rcl(%s, %s);\n" %self.parse2(dst, src)
#def _rcr(self, dst, src):
# self.body += "\t_rcr(%s, %s);\n" %self.parse2(dst, src)
def _mul(self, src):
src = self.expand(src)
self.body += "\t_mul(%s);\n" %(src)
def _div(self, src):
src = self.expand(src)
self.body += "\t_div(%s);\n" %(src)
def _inc(self, dst):
dst = self.expand(dst)
self.body += "\t_inc(%s);\n" %(dst)
def _dec(self, dst):
dst = self.expand(dst)
self.body += "\t_dec(%s);\n" %(dst)
def _cmp(self, a, b):
self.body += "\t_cmp(%s, %s);\n" %self.parse2(a, b)
def _test(self, a, b):
self.body += "\t_test(%s, %s);\n" %self.parse2(a, b)
def _js(self, label):
self.body += "\tif (flags.s())\n\t\t%s;\n" %(self.jump_to_label(label))
def _jns(self, label):
self.body += "\tif (!flags.s())\n\t\t%s;\n" %(self.jump_to_label(label))
def _jz(self, label):
self.body += "\tif (flags.z())\n\t\t%s;\n" %(self.jump_to_label(label))
def _jnz(self, label):
self.body += "\tif (!flags.z())\n\t\t%s;\n" %(self.jump_to_label(label))
def _jl(self, label):
self.body += "\tif (flags.l())\n\t\t%s;\n" %(self.jump_to_label(label))
def _jg(self, label):
self.body += "\tif (!flags.le())\n\t\t%s;\n" %(self.jump_to_label(label))
def _jle(self, label):
self.body += "\tif (flags.le())\n\t\t%s;\n" %(self.jump_to_label(label))
def _jge(self, label):
self.body += "\tif (!flags.l())\n\t\t%s;\n" %(self.jump_to_label(label))
def _jc(self, label):
self.body += "\tif (flags.c())\n\t\t%s;\n" %(self.jump_to_label(label))
def _jnc(self, label):
self.body += "\tif (!flags.c())\n\t\t%s;\n" %(self.jump_to_label(label))
def _xchg(self, dst, src):
self.body += "\t_xchg(%s, %s);\n" %self.parse2(dst, src)
def _jmp(self, label):
self.body += "\t%s;\n" %(self.jump_to_label(label))
def _loop(self, label):
self.body += "\tif (--cx)\n\t\t%s;\n" %self.jump_to_label(label)
def _push(self, regs):
p = str();
for r in regs:
r = self.expand(r)
p += "\tpush(%s);\n" %(r)
self.body += p
def _pop(self, regs):
p = str();
for r in regs:
self.temps_count -= 1
i = self.temps_count
r = self.expand(r)
p += "\t%s = pop();\n" %r
self.body += p
def _rep(self):
self.body += "\twhile(cx--)\n\t"
def _lodsb(self):
self.body += "\t_lodsb();\n"
def _lodsw(self):
self.body += "\t_lodsw();\n"
def _stosb(self, n, clear_cx):
self.body += "\t_stosb(%s%s);\n" %("" if n == 1 else n, ", true" if clear_cx else "")
def _stosw(self, n, clear_cx):
self.body += "\t_stosw(%s%s);\n" %("" if n == 1 else n, ", true" if clear_cx else "")
def _movsb(self, n, clear_cx):
self.body += "\t_movsb(%s%s);\n" %("" if n == 1 else n, ", true" if clear_cx else "")
def _movsw(self, n, clear_cx):
self.body += "\t_movsw(%s%s);\n" %("" if n == 1 else n, ", true" if clear_cx else "")
def _stc(self):
self.body += "\tflags._c = true;\n "
def _clc(self):
self.body += "\tflags._c = false;\n "
def __proc(self, name, def_skip = 0):
try:
skip = def_skip
self.temps_count = 0
self.temps_max = 0
if self.context.has_global(name):
self.proc = self.context.get_global(name)
else:
print "No procedure named %s, trying label" %name
off, src_proc, skip = self.context.get_offset(name)
self.proc = proc_module.proc(name)
self.proc.stmts = copy(src_proc.stmts)
self.proc.labels = copy(src_proc.labels)
self.proc.retlabels = copy(src_proc.retlabels)
#for p in xrange(skip, len(self.proc.stmts)):
# s = self.proc.stmts[p]
# if isinstance(s, op.basejmp):
# o, p, s = self.context.get_offset(s.label)
# if p == src_proc and s < skip:
# skip = s
self.proc_addr.append((name, self.proc.offset))
self.body = str()
if name in self.function_name_remapping:
self.body += "void %sContext::%s() {\n\tSTACK_CHECK;\n" %(self.namespace, self.function_name_remapping[name]);
else:
self.body += "void %sContext::%s() {\n\tSTACK_CHECK;\n" %(self.namespace, name);
self.proc.optimize()
self.unbounded = []
self.proc.visit(self, skip)
#adding remaining labels:
for i in xrange(0, len(self.unbounded)):
u = self.unbounded[i]
print "UNBOUNDED: ", u
proc = u[1]
for p in xrange(u[2], len(proc.stmts)):
s = proc.stmts[p]
if isinstance(s, op.basejmp):
self.resolve_label(s.label)
#adding statements
#BIG FIXME: this is quite ugly to handle code analysis from the code generation. rewrite me!
for label, proc, offset in self.unbounded:
self.body += "\treturn;\n" #we need to return before calling code from the other proc
self.body += "/*continuing to unbounded code: %s from %s:%d-%d*/\n" %(label, proc.name, offset, len(proc.stmts))
start = len(self.proc.stmts)
self.proc.add_label(label)
for s in proc.stmts[offset:]:
if isinstance(s, op.label):
self.proc.labels.add(s.name)
self.proc.stmts.append(s)
self.proc.add("ret")
print "skipping %d instructions, todo: %d" %(start, len(self.proc.stmts) - start)
print "re-optimizing..."
self.proc.optimize(keep_labels=[label])
self.proc.visit(self, start)
self.body += "}\n";
if name not in self.skip_output:
self.translated.insert(0, self.body)
self.proc = None
if self.temps_count > 0:
raise Exception("temps count == %d at the exit of proc" %self.temps_count);
return True
except (CrossJump, op.Unsupported) as e:
print "%s: ERROR: %s" %(name, e)
self.failed.append(name)
except:
raise
def get_type(self, width):
return "uint%d_t" %(width * 8)
def write_stubs(self, fname, procs):
fd = open(fname, "wt")
fd.write("namespace %s {\n" %self.namespace)
for p in procs:
if p in self.function_name_remapping:
fd.write("void %sContext::%s() {\n\t::error(\"%s\");\n}\n\n" %(self.namespace, self.function_name_remapping[p], self.function_name_remapping[p]))
else:
fd.write("void %sContext::%s() {\n\t::error(\"%s\");\n}\n\n" %(self.namespace, p, p))
fd.write("} // End of namespace %s\n" %self.namespace)
fd.close()
def generate(self, start):
#print self.prologue()
#print context
self.proc_queue.append(start)
while len(self.proc_queue):
name = self.proc_queue.pop()
if name in self.failed or name in self.proc_done:
continue
if len(self.proc_queue) == 0 and len(self.procs) > 0:
print "queue's empty, adding remaining procs:"
for p in self.procs:
self.schedule(p)
self.procs = []
print "continuing on %s" %name
self.proc_done.append(name)
self.__proc(name)
self.methods.append(name)
self.write_stubs("_stubs.cpp", self.failed)
self.methods += self.failed
done, failed = len(self.proc_done), len(self.failed)
self.fd.write("\n")
self.fd.write("\n".join(self.translated))
self.fd.write("\n")
print "%d ok, %d failed of %d, %.02g%% translated" %(done, failed, done + failed, 100.0 * done / (done + failed))
print "\n".join(self.failed)
data_bin = self.data_seg
data_impl = "\n\tstatic const uint8 src[] = {\n\t\t"
n = 0
comment = str()
for v in data_bin:
data_impl += "0x%02x, " %v
n += 1
comment += chr(v) if (v >= 0x20 and v < 0x7f and v != ord('\\')) else "."
if (n & 0xf) == 0:
data_impl += "\n\t\t//0x%04x: %s\n\t\t" %(n - 16, comment)
comment = str()
elif (n & 0x3) == 0:
comment += " "
data_impl += "};\n\tds.assign(src, src + sizeof(src));\n"
self.hd.write(
"""\n#include "dreamweb/runtime.h"
#include "dreamweb/structs.h"
#include "dreamweb/dreambase.h"
namespace %s {
"""
%(self.namespace))
if self.skip_addr_constants == False:
for name,addr in self.proc_addr:
self.hd.write("static const uint16 addr_%s = 0x%04x;\n" %(name, addr))
for name,addr in self.used_data_offsets:
self.hd.write("static const uint16 offset_%s = 0x%04x;\n" %(name, addr))
offsets = []
for k, v in self.context.get_globals().items():
if isinstance(v, op.var):
offsets.append((k.capitalize(), v.offset))
elif isinstance(v, op.const):
offsets.append((k.capitalize(), self.expand_equ(v.value))) #fixme: try to save all constants here
offsets = sorted(offsets, key=lambda t: t[1])
for o in offsets:
self.hd.write("static const uint16 k%s = %s;\n" %o)
self.hd.write("\n")
self.hd.write(
"""
class %sContext : public DreamBase, public Context {
public:
DreamGenContext(DreamWeb::DreamWebEngine *en) : DreamBase(en), Context(this) {}
void __start();
"""
%(self.namespace))
if self.skip_dispatch_call == False:
self.hd.write(
""" void __dispatch_call(uint16 addr);
""")
for p in set(self.methods):
if p in self.blacklist:
if self.header_omit_blacklisted == False:
self.hd.write("\t//void %s();\n" %p)
else:
if p in self.function_name_remapping:
self.hd.write("\tvoid %s();\n" %self.function_name_remapping[p])
else:
self.hd.write("\tvoid %s();\n" %p)
self.hd.write("};\n\n} // End of namespace DreamGen\n\n#endif\n")
self.hd.close()
self.fd.write("void %sContext::__start() { %s\t%s(); \n}\n" %(self.namespace, data_impl, start))
if self.skip_dispatch_call == False:
self.fd.write("\nvoid %sContext::__dispatch_call(uint16 addr) {\n\tswitch(addr) {\n" %self.namespace)
self.proc_addr.sort(cmp = lambda x, y: x[1] - y[1])
for name,addr in self.proc_addr:
self.fd.write("\t\tcase addr_%s: %s(); break;\n" %(name, name))
self.fd.write("\t\tdefault: ::error(\"invalid call to %04x dispatched\", (uint16)ax);")
self.fd.write("\n\t}\n}")
self.fd.write("\n} // End of namespace DreamGen\n")
self.fd.close()

View File

@@ -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 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/>.
#
def parse_args(text):
#print "parsing: [%s]" %text
escape = False
string = False
result = []
token = str()
value = 0;
for c in text:
#print "[%s]%s: %s: %s" %(token, c, escape, string)
if c == '\\':
escape = True
continue
if escape:
if not string:
raise SyntaxError("escape found in no string: %s" %text);
#print "escaping[%s]" %c
escape = False
token += c
continue
if string:
if c == '\'' or c == '"':
string = False
token += c
continue
if c == '\'' or c == '"':
string = True
token += c
continue
if c == ',':
result.append(token.strip())
token = str()
continue
if c == ';': #comment, bailing out
break
token += c
#token = token.strip()
if len(token):
result.append(token)
#print result
return result
def compile(width, data):
print data
return data

View File

@@ -0,0 +1,429 @@
# 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/>.
#
import re
import lex
class Unsupported(Exception):
pass
class var:
def __init__(self, size, offset):
self.size = size
self.offset = offset
class const:
def __init__(self, value):
self.value = value
class reg:
def __init__(self, name):
self.name = name
def size(self):
return 2 if self.name[1] == 'x' else 1
def __str__(self):
return "<register %s>" %self.name
class unref:
def __init__(self, exp):
self.exp = exp
def __str__(self):
return "<unref %s>" %self.exp
class ref:
def __init__(self, name):
self.name = name
def __str__(self):
return "<ref %s>" %self.name
class glob:
def __init__(self, name):
self.name = name
def __str__(self):
return "<global %s>" %self.name
class segment:
def __init__(self, name):
self.name = name
def __str__(self):
return "<segment %s>" %self.name
class baseop(object):
def parse_arg(self, arg):
return arg
def split(self, text):
a, b = lex.parse_args(text)
return self.parse_arg(a), self.parse_arg(b)
def __str__(self):
return str(self.__class__)
class basejmp(baseop):
pass
class _call(baseop):
def __init__(self, arg):
self.name = arg
def visit(self, visitor):
visitor._call(self.name)
def __str__(self):
return "call(%s)" %self.name
class _rep(baseop):
def __init__(self, arg):
pass
def visit(self, visitor):
visitor._rep()
class _mov(baseop):
def __init__(self, arg):
self.dst, self.src = self.split(arg)
def visit(self, visitor):
visitor._mov(self.dst, self.src)
def __str__(self):
return "mov(%s, %s)" %(self.dst, self.src)
class _mov2(baseop):
def __init__(self, dst, src):
self.dst, self.src = dst, src
def visit(self, visitor):
visitor._mov(self.dst, self.src)
class _shr(baseop):
def __init__(self, arg):
self.dst, self.src = self.split(arg)
def visit(self, visitor):
visitor._shr(self.dst, self.src)
class _shl(baseop):
def __init__(self, arg):
self.dst, self.src = self.split(arg)
def visit(self, visitor):
visitor._shl(self.dst, self.src)
class _ror(baseop):
def __init__(self, arg):
pass
class _rol(baseop):
def __init__(self, arg):
pass
class _sar(baseop):
def __init__(self, arg):
self.dst, self.src = self.split(arg)
def visit(self, visitor):
visitor._sar(self.dst, self.src)
class _sal(baseop):
def __init__(self, arg):
self.dst, self.src = self.split(arg)
def visit(self, visitor):
visitor._sal(self.dst, self.src)
class _rcl(baseop):
def __init__(self, arg):
self.dst, self.src = self.split(arg)
def visit(self, visitor):
visitor._rcl(self.dst, self.src)
class _rcr(baseop):
def __init__(self, arg):
self.dst, self.src = self.split(arg)
def visit(self, visitor):
visitor._rcr(self.dst, self.src)
class _neg(baseop):
def __init__(self, arg):
self.arg = arg
def visit(self, visitor):
visitor._neg(self.arg)
class _dec(baseop):
def __init__(self, arg):
self.dst = arg
def visit(self, visitor):
visitor._dec(self.dst)
class _inc(baseop):
def __init__(self, arg):
self.dst = arg
def visit(self, visitor):
visitor._inc(self.dst)
class _add(baseop):
def __init__(self, arg):
self.dst, self.src = self.split(arg)
def visit(self, visitor):
visitor._add(self.dst, self.src)
class _sub(baseop):
def __init__(self, arg):
self.dst, self.src = self.split(arg)
def visit(self, visitor):
visitor._sub(self.dst, self.src)
class _mul(baseop):
def __init__(self, arg):
self.arg = self.parse_arg(arg)
def visit(self, visitor):
visitor._mul(self.arg)
class _div(baseop):
def __init__(self, arg):
self.arg = self.parse_arg(arg)
def visit(self, visitor):
visitor._div(self.arg)
class _and(baseop):
def __init__(self, arg):
self.dst, self.src = self.split(arg)
def visit(self, visitor):
visitor._and(self.dst, self.src)
class _xor(baseop):
def __init__(self, arg):
self.dst, self.src = self.split(arg)
def visit(self, visitor):
visitor._xor(self.dst, self.src)
class _or(baseop):
def __init__(self, arg):
self.dst, self.src = self.split(arg)
def visit(self, visitor):
visitor._or(self.dst, self.src)
class _cmp(baseop):
def __init__(self, arg):
self.a, self.b = self.split(arg)
def visit(self, visitor):
visitor._cmp(self.a, self.b)
class _test(baseop):
def __init__(self, arg):
self.a, self.b = self.split(arg)
def visit(self, visitor):
visitor._test(self.a, self.b)
class _xchg(baseop):
def __init__(self, arg):
self.a, self.b = self.split(arg)
def visit(self, visitor):
visitor._xchg(self.a, self.b)
class _jnz(basejmp):
def __init__(self, label):
self.label = label
def visit(self, visitor):
visitor._jnz(self.label)
class _jz(basejmp):
def __init__(self, label):
self.label = label
def visit(self, visitor):
visitor._jz(self.label)
class _jc(basejmp):
def __init__(self, label):
self.label = label
def visit(self, visitor):
visitor._jc(self.label)
class _jnc(basejmp):
def __init__(self, label):
self.label = label
def visit(self, visitor):
visitor._jnc(self.label)
class _js(basejmp):
def __init__(self, label):
self.label = label
def visit(self, visitor):
visitor._js(self.label)
class _jns(basejmp):
def __init__(self, label):
self.label = label
def visit(self, visitor):
visitor._jns(self.label)
class _jl(basejmp):
def __init__(self, label):
self.label = label
def visit(self, visitor):
visitor._jl(self.label)
class _jg(basejmp):
def __init__(self, label):
self.label = label
def visit(self, visitor):
visitor._jg(self.label)
class _jle(basejmp):
def __init__(self, label):
self.label = label
def visit(self, visitor):
visitor._jle(self.label)
class _jge(basejmp):
def __init__(self, label):
self.label = label
def visit(self, visitor):
visitor._jge(self.label)
class _jmp(basejmp):
def __init__(self, label):
self.label = label
def visit(self, visitor):
visitor._jmp(self.label)
class _loop(basejmp):
def __init__(self, label):
self.label = label
def visit(self, visitor):
visitor._loop(self.label)
class _push(baseop):
def __init__(self, arg):
self.regs = []
for r in arg.split():
self.regs.append(self.parse_arg(r))
def visit(self, visitor):
visitor._push(self.regs)
class _pop(baseop):
def __init__(self, arg):
self.regs = []
for r in arg.split():
self.regs.append(self.parse_arg(r))
def visit(self, visitor):
visitor._pop(self.regs)
class _ret(baseop):
def __init__(self, arg):
pass
def visit(self, visitor):
visitor._ret()
class _lodsb(baseop):
def __init__(self, arg):
pass
def visit(self, visitor):
visitor._lodsb()
class _lodsw(baseop):
def __init__(self, arg):
pass
def visit(self, visitor):
visitor._lodsw()
class _stosw(baseop):
def __init__(self, arg):
self.repeat = 1
self.clear_cx = False
def visit(self, visitor):
visitor._stosw(self.repeat, self.clear_cx)
class _stosb(baseop):
def __init__(self, arg):
self.repeat = 1
self.clear_cx = False
def visit(self, visitor):
visitor._stosb(self.repeat, self.clear_cx)
class _movsw(baseop):
def __init__(self, arg):
self.repeat = 1
self.clear_cx = False
def visit(self, visitor):
visitor._movsw(self.repeat, self.clear_cx)
class _movsb(baseop):
def __init__(self, arg):
self.repeat = 1
self.clear_cx = False
def visit(self, visitor):
visitor._movsb(self.repeat, self.clear_cx)
class _in(baseop):
def __init__(self, arg):
self.arg = arg
def visit(self, visitor):
raise Unsupported("input from port: %s" %self.arg)
class _out(baseop):
def __init__(self, arg):
self.arg = arg
def visit(self, visitor):
raise Unsupported("out to port: %s" %self.arg)
class _cli(baseop):
def __init__(self, arg):
pass
def visit(self, visitor):
raise Unsupported("cli")
class _sti(baseop):
def __init__(self, arg):
pass
def visit(self, visitor):
raise Unsupported("sli")
class _int(baseop):
def __init__(self, arg):
self.arg = arg
def visit(self, visitor):
raise Unsupported("interrupt: %s" %self.arg)
class _iret(baseop):
def __init__(self, arg):
pass
def visit(self, visitor):
raise Unsupported("interrupt return")
class _cbw(baseop):
def __init__(self, arg):
pass
def visit(self, visitor):
visitor._cbw()
class _nop(baseop):
def __init__(self, arg):
pass
def visit(self, visitor):
pass
class _stc(baseop):
def __init__(self, arg):
pass
def visit(self, visitor):
visitor._stc()
class _clc(baseop):
def __init__(self, arg):
pass
def visit(self, visitor):
visitor._clc()
class label(baseop):
def __init__(self, name):
self.name = name
def visit(self, visitor):
visitor._label(self.name)

View File

@@ -0,0 +1,298 @@
# 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/>.
#
import os, re
from proc import proc
import lex
import op
class parser:
def __init__(self, skip_binary_data = []):
self.skip_binary_data = skip_binary_data
self.strip_path = 0
self.__globals = {}
self.__offsets = {}
self.__stack = []
self.proc = None
self.proc_list = []
self.binary_data = []
self.symbols = []
self.link_later = []
def visible(self):
for i in self.__stack:
if not i or i == 0:
return False
return True
def push_if(self, text):
value = self.eval(text)
#print "if %s -> %s" %(text, value)
self.__stack.append(value)
def push_else(self):
#print "else"
self.__stack[-1] = not self.__stack[-1]
def pop_if(self):
#print "endif"
return self.__stack.pop()
def set_global(self, name, value):
if len(name) == 0:
raise Exception("empty name is not allowed")
name = name.lower()
#print "adding global %s -> %s" %(name, value)
if self.__globals.has_key(name):
raise Exception("global %s was already defined", name)
self.__globals[name] = value
def get_global(self, name):
name = name.lower()
g = self.__globals[name]
g.used = True
return g
def get_globals(self):
return self.__globals
def has_global(self, name):
name = name.lower()
return self.__globals.has_key(name)
def set_offset(self, name, value):
if len(name) == 0:
raise Exception("empty name is not allowed")
name = name.lower()
#print "adding global %s -> %s" %(name, value)
if self.__offsets.has_key(name):
raise Exception("global %s was already defined", name)
self.__offsets[name] = value
def get_offset(self, name):
name = name.lower()
return self.__offsets[name]
def include(self, basedir, fname):
path = fname.split('\\')[self.strip_path:]
path = os.path.join(basedir, os.path.pathsep.join(path))
#print "including %s" %(path)
self.parse(path)
def eval(self, stmt):
try:
return self.parse_int(stmt)
except:
pass
value = self.__globals[stmt.lower()].value
return int(value)
def expr_callback(self, match):
name = match.group(1).lower()
g = self.get_global(name)
if isinstance(g, op.const):
return g.value
else:
return "0x%04x" %g.offset
def eval_expr(self, expr):
n = 1
while n > 0:
expr, n = re.subn(r'\b([a-zA-Z_]+[a-zA-Z0-9_]*)', self.expr_callback, expr)
return eval(expr)
def expand_globals(self, text):
return text
def fix_dollar(self, v):
print("$ = %d" %len(self.binary_data))
return re.sub(r'\$', "%d" %len(self.binary_data), v)
def parse_int(self, v):
if re.match(r'[01]+b$', v):
v = int(v[:-1], 2)
if re.match(r'[\+-]?[0-9a-f]+h$', v):
v = int(v[:-1], 16)
return int(v)
def compact_data(self, width, data):
#print "COMPACTING %d %s" %(width, data)
r = []
base = 0x100 if width == 1 else 0x10000
for v in data:
if v[0] == '"':
if v[-1] != '"':
raise Exception("invalid string %s" %v)
if width == 2:
raise Exception("string with data width more than 1") #we could allow it :)
for i in xrange(1, len(v) - 1):
r.append(ord(v[i]))
continue
m = re.match(r'(\w+)\s+dup\s+\((\s*\S+\s*)\)', v)
if m is not None:
#we should parse that
n = self.parse_int(m.group(1))
if m.group(2) != '?':
value = self.parse_int(m.group(2))
else:
value = 0
for i in xrange(0, n):
v = value
for b in xrange(0, width):
r.append(v & 0xff);
v >>= 8
continue
try:
v = self.parse_int(v)
if v < 0:
v += base
except:
#global name
print "global/expr: %s" %v
try:
g = self.get_global(v)
v = g.offset
except:
print "unknown address %s" %(v)
self.link_later.append((len(self.binary_data) + len(r), v))
v = 0
for b in xrange(0, width):
r.append(v & 0xff);
v >>= 8
#print r
return r
def parse(self, fname):
# print "opening file %s..." %(fname, basedir)
skipping_binary_data = False
fd = open(fname, 'rb')
for line in fd:
line = line.strip()
if len(line) == 0 or line[0] == ';' or line[0] == chr(0x1a):
continue
#print line
m = re.match('(\w+)\s*?:', line)
if m is not None:
line = line[len(m.group(0)):].strip()
if self.visible():
name = m.group(1)
if not (name.lower() in self.skip_binary_data):
if self.proc is not None:
self.proc.add_label(name)
print "offset %s -> %d" %(name, len(self.binary_data))
self.set_offset(name, (len(self.binary_data), self.proc, len(self.proc.stmts) if self.proc is not None else 0))
skipping_binary_data = False
else:
print "skipping binary data for %s" % (name,)
skipping_binary_data = True
#print line
cmd = line.split()
if len(cmd) == 0:
continue
cmd0 = str(cmd[0])
if cmd0 == 'if':
self.push_if(cmd[1])
continue
elif cmd0 == 'else':
self.push_else()
continue
elif cmd0 == 'endif':
self.pop_if()
continue
if not self.visible():
continue
if cmd0 == 'db' or cmd0 == 'dw' or cmd0 == 'dd':
arg = line[len(cmd0):].strip()
if not skipping_binary_data:
print "%d:1: %s" %(len(self.binary_data), arg) #fixme: COPYPASTE
binary_width = {'b': 1, 'w': 2, 'd': 4}[cmd0[1]]
self.binary_data += self.compact_data(binary_width, lex.parse_args(arg))
continue
elif cmd0 == 'include':
self.include(os.path.dirname(fname), cmd[1])
continue
elif cmd0 == 'endp':
self.proc = None
continue
elif cmd0 == 'assume':
print "skipping: %s" %line
continue
elif cmd0 == 'rep':
self.proc.add(cmd0)
self.proc.add(" ".join(cmd[1:]))
continue
if len(cmd) >= 3:
cmd1 = cmd[1]
if cmd1 == 'equ':
if not (cmd0.lower() in self.skip_binary_data):
v = cmd[2]
self.set_global(cmd0, op.const(self.fix_dollar(v)))
else:
print "skipping binary data for %s" % (cmd0.lower(),)
skipping_binary_data = True
elif cmd1 == 'db' or cmd1 == 'dw' or cmd1 == 'dd':
if not (cmd0.lower() in self.skip_binary_data):
binary_width = {'b': 1, 'w': 2, 'd': 4}[cmd1[1]]
offset = len(self.binary_data)
arg = line[len(cmd0):].strip()
arg = arg[len(cmd1):].strip()
print "%d: %s" %(offset, arg)
self.binary_data += self.compact_data(binary_width, lex.parse_args(arg))
self.set_global(cmd0.lower(), op.var(binary_width, offset))
skipping_binary_data = False
else:
print "skipping binary data for %s" % (cmd0.lower(),)
skipping_binary_data = True
continue
elif cmd1 == 'proc':
name = cmd0.lower()
self.proc = proc(name)
print "procedure %s, #%d" %(name, len(self.proc_list))
self.proc_list.append(name)
self.set_global(name, self.proc)
continue
if (self.proc):
self.proc.add(line)
else:
#print line
pass
fd.close()
return self
def link(self):
for addr, expr in self.link_later:
v = self.eval_expr(expr)
print "link: patching %04x -> %04x" %(addr, v)
while v != 0:
self.binary_data[addr] = v & 0xff
addr += 1
v >>= 8

View File

@@ -0,0 +1,191 @@
# 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/>.
#
import re
import op
class proc:
last_addr = 0xc000
def __init__(self, name):
self.name = name
self.calls = []
self.stmts = []
self.labels = set()
self.retlabels = set()
self.__label_re = re.compile(r'^(\S+):(.*)$')
self.offset = proc.last_addr
proc.last_addr += 4
def add_label(self, label):
self.stmts.append(op.label(label))
self.labels.add(label)
def remove_label(self, label):
try:
self.labels.remove(label)
except:
pass
for i in xrange(len(self.stmts)):
if isinstance(self.stmts[i], op.label) and self.stmts[i].name == label:
self.stmts[i] = op._nop(None)
return
def optimize_sequence(self, cls):
i = 0
stmts = self.stmts
while i < len(stmts):
if not isinstance(stmts[i], cls):
i += 1
continue
if i > 0 and isinstance(stmts[i - 1], op._rep): #skip rep prefixed instructions for now
i += 1
continue
j = i + 1
while j < len(stmts):
if not isinstance(stmts[j], cls):
break
j = j + 1
n = j - i
if n > 1:
print "Eliminate consequtive storage instructions at %u-%u" %(i, j)
for k in range(i+1,j):
stmts[k] = op._nop(None)
stmts[i].repeat = n
else:
i = j
i = 0
while i < len(stmts):
if not isinstance(stmts[i], op._rep):
i += 1
continue
if i + 1 >= len(stmts):
break
if isinstance(stmts[i + 1], cls):
stmts[i + 1].repeat = 'cx'
stmts[i + 1].clear_cx = True
stmts[i] = op._nop(None)
i += 1
return
def optimize(self, keep_labels=[]):
print "optimizing..."
#trivial simplifications
while len(self.stmts) and isinstance(self.stmts[-1], op.label):
print "stripping last label"
self.stmts.pop()
#mark labels that directly precede a ret
for i in range(len(self.stmts)):
if not isinstance(self.stmts[i], op.label):
continue
j = i
while j < len(self.stmts) and isinstance(self.stmts[j], (op.label, op._nop)):
j += 1
if j == len(self.stmts) or isinstance(self.stmts[j], op._ret):
print "Return label: %s" % (self.stmts[i].name,)
self.retlabels.add(self.stmts[i].name)
#merging push ax pop bx constructs
i = 0
while i + 1 < len(self.stmts):
a, b = self.stmts[i], self.stmts[i + 1]
if isinstance(a, op._push) and isinstance(b, op._pop):
ar, br = a.regs, b.regs
movs = []
while len(ar) and len(br):
src = ar.pop()
dst = br.pop(0)
movs.append(op._mov2(dst, src))
if len(br) == 0:
self.stmts.pop(i + 1)
print "merging %d push-pops into movs" %(len(movs))
for m in movs:
print "\t%s <- %s" %(m.dst, m.src)
self.stmts[i + 1:i + 1] = movs
if len(ar) == 0:
self.stmts.pop(i)
else:
i += 1
#eliminating unused labels
for s in list(self.stmts):
if not isinstance(s, op.label):
continue
print "checking label %s..." %s.name
used = s.name in keep_labels
if s.name not in self.retlabels:
for j in self.stmts:
if isinstance(j, op.basejmp) and j.label == s.name:
print "used"
used = True
break
if not used:
print self.labels
self.remove_label(s.name)
#removing duplicate rets and rets at end
for i in xrange(len(self.stmts)):
if isinstance(self.stmts[i], op._ret):
j = i+1
while j < len(self.stmts) and isinstance(self.stmts[j], op._nop):
j += 1
if j == len(self.stmts) or isinstance(self.stmts[j], op._ret):
self.stmts[i] = op._nop(None)
self.optimize_sequence(op._stosb);
self.optimize_sequence(op._stosw);
self.optimize_sequence(op._movsb);
self.optimize_sequence(op._movsw);
def add(self, stmt):
#print stmt
comment = stmt.rfind(';')
if comment >= 0:
stmt = stmt[:comment]
stmt = stmt.strip()
r = self.__label_re.search(stmt)
if r is not None:
#label
self.add_label(r.group(1).lower())
#print "remains: %s" %r.group(2)
stmt = r.group(2).strip()
if len(stmt) == 0:
return
s = stmt.split(None)
cmd = s[0]
cl = getattr(op, '_' + cmd)
arg = " ".join(s[1:]) if len(s) > 1 else str()
o = cl(arg)
self.stmts.append(o)
def __str__(self):
r = []
for i in self.stmts:
r.append(i.__str__())
return "\n".join(r)
def visit(self, visitor, skip = 0):
for i in xrange(skip, len(self.stmts)):
self.stmts[i].visit(visitor)