init commit
This commit is contained in:
+12
@@ -0,0 +1,12 @@
|
||||
# vs stuff
|
||||
*.ncb
|
||||
*.suo
|
||||
|
||||
# compile stuff
|
||||
*.ib_pdb_index
|
||||
.garbage
|
||||
src/XLibs/STLPort/build/
|
||||
dbg/
|
||||
|
||||
# build logs
|
||||
build*.log
|
||||
@@ -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>.
|
||||
@@ -0,0 +1,35 @@
|
||||
# QD Engine
|
||||
|
||||

|
||||
|
||||
(с) ООО "КД ВИЖЕН" (Калининград)
|
||||
|
||||
Весь код, за исключением сторонних библиотек, публикуется под лицензией GPLv3. Код сторонних библиотек (где указана иная лицензия) публикуется под лицензией этих библиотек.
|
||||
|
||||
Чат сообщества: https://t.me/kdlab_association_chat
|
||||
|
||||
## Структура:
|
||||
- src/XLibs - библиотека XLibs
|
||||
- src/QD - исходный код игры
|
||||
|
||||
## Работоспособность
|
||||
Движок запускается с ресурсами из игры "Похождения бравого солдата Швейка" (1С, 2007 г.), однако работает нестабильно.
|
||||
|
||||
## Что потребуется
|
||||
1. На текущий момент движок собирается для `Debug` конфигурации на Windows 10 + VS 2003 SP1.
|
||||
|
||||
## Пошаговая инструкция по сборке
|
||||
1. В `src/XLibs` с правами администратора запустить `build.bat`
|
||||
1. Результат сборки будет расположен в `C:\XLibs`
|
||||
1. Открыть в VS2003 `src\QD\Core\qdEngine.sln` выбрать проект `qdEngine` выбрать `Rebuild` это должно запустить последовательную сборку проектов `qdEngineCore` и `qdEngine`
|
||||
1. Результат сборки для `Debug` конфигурации в `src\QD\bin\dbg\qd_gameDBG.exe`
|
||||
|
||||
## Известные проблемы
|
||||
1. Если будут возникать ошибки "Не хватает lib", то соберите соответствующие lib из xlibs
|
||||
1. Если при сборке ругается на отсутствие `stlportd_static.5.0.lib `, то зайдите в `c:\XLibs\VC7.1\` и скопируйте `stlportd_static.5.1.lib` в `stlportd_static.5.0.lib`
|
||||
|
||||
## Ключевые изменения сделанные на текущий момент
|
||||
1. Добавлен `class MpegSound` кроме того сам он модифицирован так чтобы убрать зависимость от `__int64 getRDTSC()`
|
||||
2. Убрано использование `auto_ptr`
|
||||
3. Исправлена несовместимость с `XZipArchive`
|
||||
4. В `XLibs/Heap` добавлены отсутствующие, но необходимые заголовочные файлы, а также пара `.lib` файлов.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
Binary file not shown.
@@ -0,0 +1,224 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "app_error_handler.h"
|
||||
#include "qdscr_parser.h"
|
||||
#include "qdscr_convert.h"
|
||||
#include "xml_parser.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
|
||||
// Data types...
|
||||
enum qdscrDataType
|
||||
{
|
||||
QDSCR_DATA_VOID = 0,
|
||||
QDSCR_DATA_INT,
|
||||
QDSCR_DATA_DOUBLE,
|
||||
QDSCR_DATA_CHAR
|
||||
};
|
||||
|
||||
// qdscrDataBlock flags...
|
||||
#define QDSCR_ALLOC_DATA 0x01
|
||||
|
||||
struct qdscrDataBlock;
|
||||
typedef std::list<qdscrDataBlock*> qdscrDataBlockList;
|
||||
|
||||
class XStream;
|
||||
class XBuffer;
|
||||
|
||||
struct qdscrDataBlock
|
||||
{
|
||||
int ID;
|
||||
int flags;
|
||||
int dataSize;
|
||||
int dataType;
|
||||
|
||||
int dataSize0;
|
||||
char* name;
|
||||
|
||||
union {
|
||||
int* i_dataPtr;
|
||||
double* d_dataPtr;
|
||||
char* c_dataPtr;
|
||||
};
|
||||
|
||||
qdscrDataBlock* owner;
|
||||
qdscrDataBlockList nextLevel;
|
||||
|
||||
void saveInfo(XStream& fh);
|
||||
void saveData(XStream& fh);
|
||||
void loadInfo(XStream& fh);
|
||||
void loadData(XStream& fh);
|
||||
|
||||
void loadInfo(XBuffer& fh);
|
||||
void loadData(XBuffer& fh);
|
||||
|
||||
void initName(char* p);
|
||||
|
||||
void alloc(int tp,int sz);
|
||||
void allocData();
|
||||
void freeData();
|
||||
|
||||
void add(qdscrDataBlock* p);
|
||||
void dump(XStream& fh,int idx,int mode = 0);
|
||||
|
||||
qdscrDataBlock* find(int id);
|
||||
|
||||
qdscrDataBlock(int tp);
|
||||
qdscrDataBlock();
|
||||
~qdscrDataBlock();
|
||||
};
|
||||
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
|
||||
const char* qdscr_XML_string(const char* p);
|
||||
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
static void qdscr_write_tag(qdscrDataBlock* p,XStream& ff,int depth)
|
||||
{
|
||||
for(int i = 0; i < depth; i ++) ff < "\t";
|
||||
|
||||
if(p -> name)
|
||||
ff < "<" < p -> name;
|
||||
|
||||
if(!p -> nextLevel.empty()){
|
||||
if(p -> name){
|
||||
switch(p -> dataType){
|
||||
case QDSCR_DATA_INT:
|
||||
ff < " type=\"" <= *p -> i_dataPtr < "\"";
|
||||
break;
|
||||
case QDSCR_DATA_CHAR:
|
||||
if(p -> dataSize0 == -1)
|
||||
ff < " name=\"" < qdscr_XML_string(p -> c_dataPtr) < "\"";
|
||||
break;
|
||||
}
|
||||
ff < ">\r\n";
|
||||
}
|
||||
|
||||
qdscrDataBlockList::iterator it = p -> nextLevel.begin();
|
||||
FOR_EACH(p -> nextLevel,it)
|
||||
qdscr_write_tag(*it,ff,depth + 1);
|
||||
|
||||
if(p -> name){
|
||||
for(int i = 0; i < depth; i ++) ff < "\t";
|
||||
ff < "</" < p -> name < ">\r\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(p -> name){
|
||||
ff < ">";
|
||||
int j;
|
||||
switch(p -> dataType){
|
||||
case QDSCR_DATA_INT:
|
||||
if(p -> dataSize0 == -1)
|
||||
ff <= p -> dataSize < " ";
|
||||
for(j = 0; j < p -> dataSize; j ++){
|
||||
ff <= p -> i_dataPtr[j];
|
||||
if(j < p -> dataSize - 1) ff < " ";
|
||||
}
|
||||
break;
|
||||
case QDSCR_DATA_DOUBLE:
|
||||
if(p -> dataSize0 == -1)
|
||||
ff <= p -> dataSize < " ";
|
||||
for(j = 0; j < p -> dataSize; j ++){
|
||||
ff <= p -> d_dataPtr[j];
|
||||
if(j < p -> dataSize - 1) ff < " ";
|
||||
}
|
||||
break;
|
||||
case QDSCR_DATA_CHAR:
|
||||
if(p -> dataSize0 == -1)
|
||||
ff < qdscr_XML_string(p -> c_dataPtr);
|
||||
break;
|
||||
}
|
||||
ff < "</" < p -> name < ">\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool qdscr_convert_to_XML(const char* file_name,const char* new_file_name)
|
||||
{
|
||||
typedef qdscrDataBlock* (*parse_proc)(const char* fname);
|
||||
typedef void (*free_block_proc)(qdscrDataBlock* p);
|
||||
|
||||
#ifdef _DEBUG
|
||||
const char* dll_name = "parser_dbg.dll";
|
||||
#else
|
||||
const char* dll_name = "parser.dll";
|
||||
#endif
|
||||
|
||||
HMODULE hlib = LoadLibrary(dll_name);
|
||||
if(!hlib){
|
||||
app_errH.show_error(dll_name,appErrorHandler::ERR_FILE_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
parse_proc parse_p = (parse_proc)GetProcAddress(hlib,"qdscrParseScript");
|
||||
free_block_proc free_p = (free_block_proc)GetProcAddress(hlib,"qdscrFreeDataBlock");
|
||||
|
||||
if(!parse_p || !free_p){
|
||||
app_errH.show_error(dll_name,appErrorHandler::ERR_BAD_FILE_FORMAT);
|
||||
FreeLibrary(hlib);
|
||||
return false;
|
||||
}
|
||||
|
||||
qdscrDataBlock* p = (*parse_p)(file_name);
|
||||
if(!p){
|
||||
FreeLibrary(hlib);
|
||||
return false;
|
||||
}
|
||||
|
||||
XStream fh;
|
||||
|
||||
if(!new_file_name)
|
||||
fh.open(qdscr_get_XML_file_name(file_name),XS_OUT);
|
||||
else
|
||||
fh.open(new_file_name,XS_OUT);
|
||||
|
||||
fh < "<?xml version=\"1.0\" encoding=\"WINDOWS-1251\"?>\r\n<qd_script>\r\n";
|
||||
qdscr_write_tag(p,fh,0);
|
||||
fh < "</qd_script>\r\n";
|
||||
|
||||
fh.close();
|
||||
|
||||
(*free_p)(p);
|
||||
|
||||
FreeLibrary(hlib);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool qdscr_is_XML(const char* file_name)
|
||||
{
|
||||
char drive[_MAX_DRIVE];
|
||||
char dir[_MAX_DIR];
|
||||
char fname[_MAX_FNAME];
|
||||
char ext[_MAX_EXT];
|
||||
|
||||
_splitpath(file_name,drive,dir,fname,ext);
|
||||
|
||||
if(!stricmp(ext,".qml")) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* qdscr_get_XML_file_name(const char* file_name)
|
||||
{
|
||||
char drive[_MAX_DRIVE];
|
||||
char dir[_MAX_DIR];
|
||||
char fname[_MAX_FNAME];
|
||||
char ext[_MAX_EXT];
|
||||
|
||||
static std::string xml_file_name;
|
||||
|
||||
_splitpath(file_name,drive,dir,fname,ext);
|
||||
|
||||
xml_file_name = drive;
|
||||
xml_file_name += dir;
|
||||
xml_file_name += fname;
|
||||
xml_file_name += ".qml";
|
||||
|
||||
return xml_file_name.c_str();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef __QDSCR_CONVERT_H__
|
||||
#define __QDSCR_CONVERT_H__
|
||||
|
||||
//! Преобразование старого скрипта в новый XML формат.
|
||||
bool qdscr_convert_to_XML(const char* file_name,const char* new_file_name = NULL);
|
||||
//! Возвращает true, если скрипт в новом формате (проверяет только соответствие расширения имени файла).
|
||||
bool qdscr_is_XML(const char* file_name);
|
||||
//! Меняет расширение имени файла (на .qds).
|
||||
const char* qdscr_get_XML_file_name(const char* file_name);
|
||||
|
||||
#endif /* __QDSCR_CONVERT_H__ */
|
||||
@@ -0,0 +1,170 @@
|
||||
#ifndef __QDSCR_KEYWORDS_H__
|
||||
#define __QDSCR_KEYWORDS_H__
|
||||
|
||||
enum qdscrKeywordID
|
||||
{
|
||||
QDSCR_BLOCK_BEG = 1,
|
||||
QDSCR_BLOCK_END,
|
||||
|
||||
// Common
|
||||
QDSCR_ID,
|
||||
QDSCR_X,
|
||||
QDSCR_Y,
|
||||
QDSCR_SX,
|
||||
QDSCR_SY,
|
||||
QDSCR_POS2D,
|
||||
QDSCR_POS3D,
|
||||
QDSCR_SRC_POS,
|
||||
QDSCR_DEST_POS,
|
||||
QDSCR_FILE,
|
||||
QDSCR_START_TIME,
|
||||
QDSCR_PERIOD,
|
||||
QDSCR_LENGTH,
|
||||
QDSCR_SPEED,
|
||||
QDSCR_INTERPOLATION_TIME,
|
||||
QDSCR_SCALE,
|
||||
QDSCR_NAME,
|
||||
QDSCR_FLAG,
|
||||
QDSCR_RND,
|
||||
QDSCR_MASK_SIZE,
|
||||
QDSCR_MASK_ATTRIBUTES,
|
||||
QDSCR_MASK_HEIGHTS,
|
||||
QDSCR_BOUND,
|
||||
QDSCR_TYPE,
|
||||
QDSCR_SIZE,
|
||||
QDSCR_STATE,
|
||||
QDSCR_TEXT,
|
||||
QDSCR_SHORT_TEXT,
|
||||
|
||||
QDSCR_SCREEN_SIZE,
|
||||
|
||||
// Contours
|
||||
QDSCR_CONTOUR_RECTANGLE,
|
||||
QDSCR_CONTOUR_CIRCLE,
|
||||
QDSCR_CONTOUR_POLYGON,
|
||||
|
||||
// Named Object Reference
|
||||
QDSCR_NAMED_OBJECT,
|
||||
|
||||
// Grid zone
|
||||
QDSCR_GRID_ZONE,
|
||||
QDSCR_GRID_ZONE_CELLS,
|
||||
QDSCR_GRID_ZONE_HEIGHT,
|
||||
QDSCR_GRID_ZONE_CONTOUR,
|
||||
|
||||
// Trigger Element
|
||||
QDSCR_TRIGGER_ELEMENT,
|
||||
QDSCR_TRIGGER_ELEMENT_LINK,
|
||||
QDSCR_TRIGGER_ELEMENT_TITLE,
|
||||
QDSCR_TRIGGER_ELEMENT_CELL_NUMBER,
|
||||
QDSCR_TRIGGER_PARENT_LINK_OWNER_OFFSET,
|
||||
QDSCR_TRIGGER_PARENT_LINK_CHILD_OFFSET,
|
||||
QDSCR_TRIGGER_CHILD_LINK_OWNER_OFFSET,
|
||||
QDSCR_TRIGGER_CHILD_LINK_CHILD_OFFSET,
|
||||
|
||||
// Trigger Chain
|
||||
QDSCR_TRIGGER_CHAIN,
|
||||
QDSCR_TRIGGER_CHAIN_ROOT,
|
||||
QDSCR_TRIGGER_CHAIN_WORK_AREA,
|
||||
QDSCR_TRIGGER_CHAIN_LAYOUT,
|
||||
|
||||
QDSCR_TRIGGER_BOUND,
|
||||
|
||||
// Sound
|
||||
QDSCR_SOUND,
|
||||
|
||||
// Video
|
||||
QDSCR_VIDEO,
|
||||
QDSCR_VIDEO_POSITION,
|
||||
QDSCR_VIDEO_BACKGROUND,
|
||||
|
||||
// Animation
|
||||
QDSCR_ANIMATION_FRAME,
|
||||
QDSCR_ANIMATION_INFO,
|
||||
QDSCR_ANIMATION_FILE,
|
||||
QDSCR_ANIMATION,
|
||||
|
||||
// AnimationSet
|
||||
QDSCR_ANIMATION_SET,
|
||||
|
||||
// Coords Animation
|
||||
QDSCR_COORDS_ANIMATION_POINT,
|
||||
QDSCR_COORDS_ANIMATION,
|
||||
QDSCR_ANIMATION_PHASE,
|
||||
|
||||
// Game Object
|
||||
QDSCR_PARALLAX_OFFSET,
|
||||
|
||||
// Static Object
|
||||
QDSCR_STATIC_OBJECT,
|
||||
|
||||
// Animated Object
|
||||
QDSCR_ANIMATED_OBJECT,
|
||||
QDSCR_OBJECT_STATE,
|
||||
QDSCR_OBJECT_MOVEMENT_STATES,
|
||||
QDSCR_OBJECT_MOVEMENT_STATE,
|
||||
|
||||
QDSCR_OBJECT_DIRECTION,
|
||||
QDSCR_OBJECT_DEFAULT_POS,
|
||||
QDSCR_OBJECT_DEFAULT_DIRECTION,
|
||||
|
||||
QDSCR_OBJECT_STATE_STATIC,
|
||||
QDSCR_OBJECT_STATE_WALK,
|
||||
QDSCR_OBJECT_STATE_MASK,
|
||||
QDSCR_OBJECT_STATE_MASK_POS,
|
||||
QDSCR_OBJECT_STATE_MASK_SIZE,
|
||||
QDSCR_OBJECT_STATE_MASK_DATA,
|
||||
QDSCR_OBJECT_STATE_MASK_PARENT,
|
||||
QDSCR_OBJECT_STATE_MASK_CONTOUR,
|
||||
QDSCR_OBJECT_STATE_CENTER_OFFSET,
|
||||
QDSCR_OBJECT_STATE_DELAY,
|
||||
|
||||
// State conditions
|
||||
QDSCR_CONDITION,
|
||||
QDSCR_CONDITION_DATA_INT,
|
||||
QDSCR_CONDITION_DATA_FLOAT,
|
||||
QDSCR_CONDITION_DATA_STRING,
|
||||
QDSCR_CONDITIONS_MODE,
|
||||
|
||||
// Object Scale
|
||||
QDSCR_OBJ_SCALE_INFO,
|
||||
|
||||
// Mouse object
|
||||
QDSCR_MOUSE_OBJECT,
|
||||
|
||||
// Moving Object
|
||||
QDSCR_MOVEMENT_ANIMATION_NUMBER,
|
||||
QDSCR_MOVEMENT_ANIMATIONS,
|
||||
QDSCR_STATIC_ANIMATIONS,
|
||||
QDSCR_MOVING_OBJECT,
|
||||
|
||||
// Inventory
|
||||
QDSCR_INVENTORY_CELL_TYPE,
|
||||
QDSCR_INVENTORY_CELL_SET,
|
||||
QDSCR_INVENTORY_CELL_SET_SIZE,
|
||||
QDSCR_INVENTORY_CELL_SET_POS,
|
||||
QDSCR_INVENTORY,
|
||||
|
||||
// Camera & grid
|
||||
QDSCR_CAMERA,
|
||||
QDSCR_CAMERA_GRID_SIZE,
|
||||
QDSCR_CAMERA_GRID_HEIGHT,
|
||||
QDSCR_CAMERA_GRID_ATTRIBUTES,
|
||||
QDSCR_CAMERA_GRID_CENTER,
|
||||
QDSCR_CAMERA_CELL_SIZE,
|
||||
QDSCR_CAMERA_FOCUS,
|
||||
QDSCR_CAMERA_ANGLES,
|
||||
QDSCR_CAMERA_SCREEN_SIZE,
|
||||
QDSCR_CAMERA_SCREEN_OFFSET,
|
||||
QDSCR_CAMERA_SCREEN_CENTER,
|
||||
|
||||
// Scene
|
||||
QDSCR_SCENE,
|
||||
|
||||
// Location
|
||||
QDSCR_LOCATION,
|
||||
|
||||
QDSCR_MAX_KEYWORD_ID
|
||||
};
|
||||
|
||||
#endif /* __QDSCR_KEYWORDS_H__ */
|
||||
@@ -0,0 +1,376 @@
|
||||
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "qdscr_parser.h"
|
||||
#include "xml_parser.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
xml::parser& qdscr_XML_Parser()
|
||||
{
|
||||
static xml::parser p;
|
||||
|
||||
if(!p.num_tag_formats()){
|
||||
p.register_tag_format("qd_script",xml::tag(QDSCR_ROOT,xml::tag::TAG_DATA_VOID,1));
|
||||
|
||||
p.register_tag_format("ID",xml::tag(QDSCR_ID,xml::tag::TAG_DATA_INT,1));
|
||||
|
||||
p.register_tag_format("x",xml::tag(QDSCR_X,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("y",xml::tag(QDSCR_Y,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("sx",xml::tag(QDSCR_SX,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("sy",xml::tag(QDSCR_SY,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("pos_2d",xml::tag(QDSCR_POS2D,xml::tag::TAG_DATA_FLOAT, 2));
|
||||
p.register_tag_format("pos_3d",xml::tag(QDSCR_POS3D,xml::tag::TAG_DATA_FLOAT, 3));
|
||||
p.register_tag_format("src_pos",xml::tag(QDSCR_SRC_POS,xml::tag::TAG_DATA_FLOAT, 3));
|
||||
p.register_tag_format("dest_pos",xml::tag(QDSCR_DEST_POS,xml::tag::TAG_DATA_FLOAT, 3));
|
||||
|
||||
p.register_tag_format("file",xml::tag(QDSCR_FILE,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("start_time",xml::tag(QDSCR_START_TIME,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("period",xml::tag(QDSCR_PERIOD,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("length",xml::tag(QDSCR_LENGTH,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("speed",xml::tag(QDSCR_SPEED,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("animation_speed",xml::tag(QDSCR_ANIMATION_SPEED,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("interpolation_time",xml::tag(QDSCR_INTERPOLATION_TIME,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("scale",xml::tag(QDSCR_SCALE,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("name",xml::tag(QDSCR_NAME,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("flag",xml::tag(QDSCR_FLAG,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("flags",xml::tag(QDSCR_FLAG,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("rnd",xml::tag(QDSCR_RND,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("mask_size",xml::tag(QDSCR_MASK_SIZE,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("mask_attributes",xml::tag(QDSCR_MASK_ATTRIBUTES,xml::tag::TAG_DATA_INT, -1));
|
||||
p.register_tag_format("mask_heights",xml::tag(QDSCR_MASK_HEIGHTS,xml::tag::TAG_DATA_INT, -1));
|
||||
p.register_tag_format("bound",xml::tag(QDSCR_BOUND,xml::tag::TAG_DATA_FLOAT, 3));
|
||||
p.register_tag_format("type",xml::tag(QDSCR_TYPE,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("size",xml::tag(QDSCR_SIZE,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("state",xml::tag(QDSCR_STATE,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("text",xml::tag(QDSCR_TEXT,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("short_text",xml::tag(QDSCR_SHORT_TEXT,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("value",xml::tag(QDSCR_VALUE,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("time",xml::tag(QDSCR_TIME,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("cd",xml::tag(QDSCR_CD,xml::tag::TAG_DATA_UNSIGNED_INT, 1));
|
||||
p.register_tag_format("align",xml::tag(QDSCR_ALIGN,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("valign",xml::tag(QDSCR_VALIGN,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("orientation",xml::tag(QDSCR_ORIENTATION,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("color",xml::tag(QDSCR_COLOR,xml::tag::TAG_DATA_UNSIGNED_INT, 1));
|
||||
p.register_tag_format("comment",xml::tag(QDSCR_COMMENT,xml::tag::TAG_DATA_STRING, -1));
|
||||
|
||||
p.register_tag_format("font_info",xml::tag(QDSCR_FONT_INFO,xml::tag::TAG_DATA_VOID, -1));
|
||||
|
||||
p.register_tag_format("screen_size",xml::tag(QDSCR_SCREEN_SIZE,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("text_set",xml::tag(QDSCR_TEXT_SET,xml::tag::TAG_DATA_VOID, 1));
|
||||
|
||||
p.register_tag_format("text_color",xml::tag(QDSCR_TEXT_COLOR,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("text_hover_color",xml::tag(QDSCR_TEXT_HOVER_COLOR,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("text_align",xml::tag(QDSCR_TEXT_ALIGN,xml::tag::TAG_DATA_INT, 1));
|
||||
|
||||
p.register_tag_format("contour_rect",xml::tag(QDSCR_CONTOUR_RECTANGLE,xml::tag::TAG_DATA_SHORT, 2));
|
||||
p.register_tag_format("contour_circle",xml::tag(QDSCR_CONTOUR_CIRCLE,xml::tag::TAG_DATA_SHORT, 1));
|
||||
p.register_tag_format("contour_polygon",xml::tag(QDSCR_CONTOUR_POLYGON,xml::tag::TAG_DATA_SHORT, -1));
|
||||
|
||||
p.register_tag_format("named_object",xml::tag(QDSCR_NAMED_OBJECT,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("types",xml::tag(QDSCR_NAMED_OBJECT_TYPES,xml::tag::TAG_DATA_INT, -1));
|
||||
|
||||
p.register_tag_format("grid_zone",xml::tag(QDSCR_GRID_ZONE,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("grid_zone_cells",xml::tag(QDSCR_GRID_ZONE_CELLS,xml::tag::TAG_DATA_SHORT, -1));
|
||||
p.register_tag_format("grid_zone_height",xml::tag(QDSCR_GRID_ZONE_HEIGHT,xml::tag::TAG_DATA_UNSIGNED_INT, 1));
|
||||
p.register_tag_format("grid_zone_contour",xml::tag(QDSCR_GRID_ZONE_CONTOUR,xml::tag::TAG_DATA_SHORT, -1));
|
||||
p.register_tag_format("grid_zone_state",xml::tag(QDSCR_GRID_ZONE_STATE,xml::tag::TAG_DATA_VOID, -1));
|
||||
p.register_tag_format("shadow_color",xml::tag(QDSCR_GRID_ZONE_SHADOW_COLOR,xml::tag::TAG_DATA_UNSIGNED_INT, 1));
|
||||
p.register_tag_format("shadow_alpha",xml::tag(QDSCR_GRID_ZONE_SHADOW_ALPHA,xml::tag::TAG_DATA_INT, 1));
|
||||
|
||||
p.register_tag_format("trigger_element",xml::tag(QDSCR_TRIGGER_ELEMENT,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("trigger_element_link",xml::tag(QDSCR_TRIGGER_ELEMENT_LINK,xml::tag::TAG_DATA_INT, 3));
|
||||
p.register_tag_format("parent_links",xml::tag(QDSCR_TRIGGER_ELEMENT_PARENT_LINKS,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("child_links",xml::tag(QDSCR_TRIGGER_ELEMENT_CHILD_LINKS,xml::tag::TAG_DATA_VOID, 1));
|
||||
|
||||
p.register_tag_format("link",xml::tag(QDSCR_TRIGGER_ELEMENT_LINK,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("auto_restart",xml::tag(QDSCR_TRIGGER_ELEMENT_LINK_AUTO_RESTART,xml::tag::TAG_DATA_INT, 1));
|
||||
|
||||
#ifdef _QUEST_EDITOR
|
||||
p.register_tag_format("offsets",xml::tag(QDSCR_TRIGGER_ELEMENT_LINK_OFFSETS,xml::tag::TAG_DATA_INT, 4));
|
||||
p.register_tag_format("trigger_element_title",xml::tag(QDSCR_TRIGGER_ELEMENT_TITLE,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("trigger_element_cell_number",xml::tag(QDSCR_TRIGGER_ELEMENT_CELL_NUMBER,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("parent_link_owner_offset",xml::tag(QDSCR_TRIGGER_PARENT_LINK_OWNER_OFFSET,xml::tag::TAG_DATA_INT, 4));
|
||||
p.register_tag_format("parent_link_child_offset",xml::tag(QDSCR_TRIGGER_PARENT_LINK_CHILD_OFFSET,xml::tag::TAG_DATA_INT, 4));
|
||||
p.register_tag_format("child_link_owner_offset",xml::tag(QDSCR_TRIGGER_CHILD_LINK_OWNER_OFFSET,xml::tag::TAG_DATA_INT, 4));
|
||||
p.register_tag_format("child_link_child_offset",xml::tag(QDSCR_TRIGGER_CHILD_LINK_CHILD_OFFSET,xml::tag::TAG_DATA_INT, 4));
|
||||
#endif
|
||||
p.register_tag_format("start_element",xml::tag(QDSCR_TRIGGER_START_ELEMENT,xml::tag::TAG_DATA_INT, 1));
|
||||
|
||||
p.register_tag_format("trigger_chain",xml::tag(QDSCR_TRIGGER_CHAIN,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("trigger_chain_root",xml::tag(QDSCR_TRIGGER_CHAIN_ROOT,xml::tag::TAG_DATA_VOID, 1));
|
||||
|
||||
#ifdef _QUEST_EDITOR
|
||||
p.register_tag_format("trigger_chain_work_area",xml::tag(QDSCR_TRIGGER_CHAIN_WORK_AREA,xml::tag::TAG_DATA_INT, 4));
|
||||
p.register_tag_format("work_area",xml::tag(QDSCR_TRIGGER_CHAIN_WORK_AREA,xml::tag::TAG_DATA_INT, 4));
|
||||
p.register_tag_format("trigger_chain_layout",xml::tag(QDSCR_TRIGGER_CHAIN_LAYOUT,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("layout",xml::tag(QDSCR_TRIGGER_CHAIN_LAYOUT,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("trigger_bound",xml::tag(QDSCR_TRIGGER_BOUND,xml::tag::TAG_DATA_INT, 4));
|
||||
#endif
|
||||
p.register_tag_format("sound",xml::tag(QDSCR_SOUND,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("volume",xml::tag(QDSCR_SOUND_VOLUME,xml::tag::TAG_DATA_INT, 1));
|
||||
|
||||
p.register_tag_format("music_track",xml::tag(QDSCR_MUSIC_TRACK,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("cycled",xml::tag(QDSCR_MUSIC_TRACK_CYCLED,xml::tag::TAG_DATA_INT, 1));
|
||||
|
||||
p.register_tag_format("video",xml::tag(QDSCR_VIDEO,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("video_position",xml::tag(QDSCR_VIDEO_POSITION,xml::tag::TAG_DATA_SHORT, 2));
|
||||
p.register_tag_format("video_background",xml::tag(QDSCR_VIDEO_BACKGROUND,xml::tag::TAG_DATA_STRING, -1));
|
||||
|
||||
p.register_tag_format("minigame",xml::tag(QDSCR_MINIGAME,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("dll_name",xml::tag(QDSCR_MINIGAME_DLL_NAME,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("game_name",xml::tag(QDSCR_MINIGAME_GAME_NAME,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("config_file",xml::tag(QDSCR_MINIGAME_CONFIG_FILE,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("minigame_state",xml::tag(QDSCR_MINIGAME_STATE,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("score",xml::tag(QDSCR_MINIGAME_SCORE,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("minigame_config_prm",xml::tag(QDSCR_MINIGAME_CONFIG_PARAMETER,xml::tag::TAG_DATA_STRING, -1));
|
||||
|
||||
p.register_tag_format("animation_frame",xml::tag(QDSCR_ANIMATION_FRAME,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("animation_info",xml::tag(QDSCR_ANIMATION_INFO,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("animation_file",xml::tag(QDSCR_ANIMATION_FILE,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("animation",xml::tag(QDSCR_ANIMATION,xml::tag::TAG_DATA_STRING, -1));
|
||||
|
||||
p.register_tag_format("animation_set",xml::tag(QDSCR_ANIMATION_SET,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("start_angle",xml::tag(QDSCR_ANIMATION_SET_START_ANGLE,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("animation_turn",xml::tag(QDSCR_ANIMATION_SET_TURN,xml::tag::TAG_DATA_STRING, -1));
|
||||
|
||||
p.register_tag_format("walk_sound_frequency",xml::tag(QDSCR_OBJECT_STATE_WALK_SOUND_FREQUENCY,xml::tag::TAG_DATA_FLOAT, -1));
|
||||
|
||||
p.register_tag_format("center_offsets",xml::tag(QDSCR_STATE_CENTER_OFFSETS,xml::tag::TAG_DATA_INT, -1));
|
||||
p.register_tag_format("static_center_offsets",xml::tag(QDSCR_STATE_STATIC_CENTER_OFFSETS,xml::tag::TAG_DATA_INT, -1));
|
||||
p.register_tag_format("start_center_offsets",xml::tag(QDSCR_STATE_START_CENTER_OFFSETS,xml::tag::TAG_DATA_INT, -1));
|
||||
p.register_tag_format("stop_center_offsets",xml::tag(QDSCR_STATE_STOP_CENTER_OFFSETS,xml::tag::TAG_DATA_INT, -1));
|
||||
|
||||
p.register_tag_format("coords_animation_point",xml::tag(QDSCR_COORDS_ANIMATION_POINT,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("coords_animation",xml::tag(QDSCR_COORDS_ANIMATION,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("animation_phase",xml::tag(QDSCR_ANIMATION_PHASE,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
|
||||
p.register_tag_format("parallax_offset",xml::tag(QDSCR_PARALLAX_OFFSET,xml::tag::TAG_DATA_INT, 2));
|
||||
|
||||
p.register_tag_format("static_object",xml::tag(QDSCR_STATIC_OBJECT,xml::tag::TAG_DATA_STRING, -1));
|
||||
|
||||
p.register_tag_format("animated_object",xml::tag(QDSCR_ANIMATED_OBJECT,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("object_state",xml::tag(QDSCR_OBJECT_STATE,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("movement_states",xml::tag(QDSCR_OBJECT_MOVEMENT_STATES,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("object_movement_state",xml::tag(QDSCR_OBJECT_MOVEMENT_STATE,xml::tag::TAG_DATA_VOID, 1));
|
||||
|
||||
p.register_tag_format("object_direction",xml::tag(QDSCR_OBJECT_DIRECTION,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("default_pos",xml::tag(QDSCR_OBJECT_DEFAULT_POS,xml::tag::TAG_DATA_FLOAT, 3));
|
||||
p.register_tag_format("default_direction",xml::tag(QDSCR_OBJECT_DEFAULT_DIRECTION,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
|
||||
p.register_tag_format("object_state_static",xml::tag(QDSCR_OBJECT_STATE_STATIC,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("object_state_walk",xml::tag(QDSCR_OBJECT_STATE_WALK,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("object_state_mask",xml::tag(QDSCR_OBJECT_STATE_MASK,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("state_mask_pos",xml::tag(QDSCR_OBJECT_STATE_MASK_POS,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("state_mask_size",xml::tag(QDSCR_OBJECT_STATE_MASK_SIZE,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("state_mask_data",xml::tag(QDSCR_OBJECT_STATE_MASK_DATA,xml::tag::TAG_DATA_INT, -1));
|
||||
p.register_tag_format("state_mask_parent",xml::tag(QDSCR_OBJECT_STATE_MASK_PARENT,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("state_mask_contour",xml::tag(QDSCR_OBJECT_STATE_MASK_CONTOUR,xml::tag::TAG_DATA_SHORT, -1));
|
||||
p.register_tag_format("center_offset",xml::tag(QDSCR_OBJECT_STATE_CENTER_OFFSET,xml::tag::TAG_DATA_SHORT, 2));
|
||||
p.register_tag_format("state_activation_delay",xml::tag(QDSCR_OBJECT_STATE_DELAY,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("sound_delay",xml::tag(QDSCR_OBJECT_STATE_SOUND_DELAY,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("text_delay",xml::tag(QDSCR_OBJECT_STATE_TEXT_DELAY,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("cursor_id",xml::tag(QDSCR_OBJECT_STATE_CURSOR_ID,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("acceleration",xml::tag(QDSCR_OBJECT_STATE_ACCELERATION,xml::tag::TAG_DATA_FLOAT, 2));
|
||||
p.register_tag_format("rnd_move",xml::tag(QDSCR_OBJECT_STATE_RND_MOVE,xml::tag::TAG_DATA_FLOAT, 2));
|
||||
|
||||
p.register_tag_format("condition",xml::tag(QDSCR_CONDITION,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("condition_data_int",xml::tag(QDSCR_CONDITION_DATA_INT,xml::tag::TAG_DATA_INT, -1));
|
||||
p.register_tag_format("condition_data_float",xml::tag(QDSCR_CONDITION_DATA_FLOAT,xml::tag::TAG_DATA_FLOAT, -1));
|
||||
p.register_tag_format("condition_data_string",xml::tag(QDSCR_CONDITION_DATA_STRING,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("condition_inverse",xml::tag(QDSCR_CONDITION_INVERSE,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("conditions_mode",xml::tag(QDSCR_CONDITIONS_MODE,xml::tag::TAG_DATA_INT, 1));
|
||||
|
||||
p.register_tag_format("condition_group",xml::tag(QDSCR_CONDITION_GROUP,xml::tag::TAG_DATA_INT, -1));
|
||||
p.register_tag_format("condition_object",xml::tag(QDSCR_CONDITION_OBJECT,xml::tag::TAG_DATA_VOID, 1));
|
||||
|
||||
p.register_tag_format("counter",xml::tag(QDSCR_COUNTER,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("counter_element",xml::tag(QDSCR_COUNTER_ELEMENT,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("inc_value",xml::tag(QDSCR_COUNTER_INC_VALUE,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("limit",xml::tag(QDSCR_COUNTER_LIMIT,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("digits",xml::tag(QDSCR_COUNTER_DIGITS,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("counter_name",xml::tag(QDSCR_COUNTER_NAME,xml::tag::TAG_DATA_STRING, -1));
|
||||
|
||||
p.register_tag_format("object_scale",xml::tag(QDSCR_OBJ_SCALE_INFO,xml::tag::TAG_DATA_STRING, -1));
|
||||
|
||||
p.register_tag_format("mouse_object",xml::tag(QDSCR_MOUSE_OBJECT,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("default_cursors",xml::tag(QDSCR_MOUSE_DEFAULT_CURSORS,xml::tag::TAG_DATA_INT, 6));
|
||||
|
||||
p.register_tag_format("movement_animation_num",xml::tag(QDSCR_MOVEMENT_ANIMATION_NUMBER,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("movement_animations",xml::tag(QDSCR_MOVEMENT_ANIMATIONS,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("static_animations",xml::tag(QDSCR_STATIC_ANIMATIONS,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("moving_object",xml::tag(QDSCR_MOVING_OBJECT,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("collision_radius",xml::tag(QDSCR_COLLISION_RADIUS,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("collision_delay",xml::tag(QDSCR_COLLISION_DELAY,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("collision_path",xml::tag(QDSCR_COLLISION_PATH,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("follow_min_radius",xml::tag(QDSCR_FOLLOW_MIN_RADIUS,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("follow_max_radius",xml::tag(QDSCR_FOLLOW_MAX_RADIUS,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("attach_shift",xml::tag(QDSCR_ATTACH_SHIFT,xml::tag::TAG_DATA_SHORT, 2));
|
||||
p.register_tag_format("control",xml::tag(QDSCR_PERSONAGE_CONTROL,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("movement",xml::tag(QDSCR_PERSONAGE_MOVEMENT_TYPE,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("rotation_angle_per_quant",xml::tag(QDSCR_ROTATION_ANGLE_PER_QUANT,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
|
||||
p.register_tag_format("inventory_cell_type",xml::tag(QDSCR_INVENTORY_CELL_TYPE,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("inventory_cell_set",xml::tag(QDSCR_INVENTORY_CELL_SET,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("inventory_cell_set_size",xml::tag(QDSCR_INVENTORY_CELL_SET_SIZE,xml::tag::TAG_DATA_SHORT, 2));
|
||||
p.register_tag_format("inventory_cell_set_additional_cells",xml::tag(QDSCR_INVENTORY_CELL_SET_ADDITIONAL_CELLS,xml::tag::TAG_DATA_SHORT, 2));
|
||||
p.register_tag_format("inventory_cell_set_pos",xml::tag(QDSCR_INVENTORY_CELL_SET_POS,xml::tag::TAG_DATA_SHORT, 2));
|
||||
p.register_tag_format("inventory",xml::tag(QDSCR_INVENTORY,xml::tag::TAG_DATA_STRING, -1));
|
||||
|
||||
p.register_tag_format("camera",xml::tag(QDSCR_CAMERA,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("camera_grid_size",xml::tag(QDSCR_CAMERA_GRID_SIZE,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("camera_grid_height",xml::tag(QDSCR_CAMERA_GRID_HEIGHT,xml::tag::TAG_DATA_INT, -1));
|
||||
p.register_tag_format("camera_grid_attributes",xml::tag(QDSCR_CAMERA_GRID_ATTRIBUTES,xml::tag::TAG_DATA_INT, -1));
|
||||
p.register_tag_format("camera_grid_center",xml::tag(QDSCR_CAMERA_GRID_CENTER,xml::tag::TAG_DATA_FLOAT, 3));
|
||||
p.register_tag_format("camera_cell_size",xml::tag(QDSCR_CAMERA_CELL_SIZE,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("camera_focus",xml::tag(QDSCR_CAMERA_FOCUS,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("camera_angles",xml::tag(QDSCR_CAMERA_ANGLES,xml::tag::TAG_DATA_FLOAT, 3));
|
||||
p.register_tag_format("camera_screen_size",xml::tag(QDSCR_CAMERA_SCREEN_SIZE,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("camera_screen_offset",xml::tag(QDSCR_CAMERA_SCREEN_OFFSET,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("camera_screen_center",xml::tag(QDSCR_CAMERA_SCREEN_CENTER,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("camera_mode",xml::tag(QDSCR_CAMERA_MODE,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("scrolling_speed",xml::tag(QDSCR_CAMERA_SCROLLING_SPEED,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("scrolling_dist",xml::tag(QDSCR_CAMERA_SCROLLING_DIST,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("smooth_switch",xml::tag(QDSCR_CAMERA_SMOOTH_SWITCH,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("camera_scale_pow",xml::tag(QDSCR_CAMERA_SCALE_POW,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("camera_scale_z_offset",xml::tag(QDSCR_CAMERA_SCALE_Z_OFFSET,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
|
||||
p.register_tag_format("game_end",xml::tag(QDSCR_GAME_END,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("end_screen",xml::tag(QDSCR_GAME_END_SCREEN,xml::tag::TAG_DATA_STRING, -1));
|
||||
|
||||
p.register_tag_format("interface",xml::tag(QDSCR_INTERFACE,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("draw_scene",xml::tag(QDSCR_INTERFACE_SCENE_REDRAW,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("main_menu",xml::tag(QDSCR_INTERFACE_MAIN_MENU,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("ingame_screen0",xml::tag(QDSCR_INTERFACE_INGAME_SCREEN0,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("ingame_screen1",xml::tag(QDSCR_INTERFACE_INGAME_SCREEN1,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("save_prompt_screen",xml::tag(QDSCR_INTERFACE_SAVE_PROMPT_SCREEN,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("save_title_screen",xml::tag(QDSCR_INTERFACE_SAVE_NAME_SCREEN,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("highscore_name_screen",xml::tag(QDSCR_INTERFACE_HIGHSCORE_NAME_SCREEN,xml::tag::TAG_DATA_STRING, -1));
|
||||
|
||||
p.register_tag_format("need_save_screenshot",xml::tag(QDSCR_INTERFACE_NEED_SAVE_SCREENSHOT,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("need_show_save_name",xml::tag(QDSCR_INTERFACE_NEED_SHOW_SAVE_NAME,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("need_show_save_time",xml::tag(QDSCR_INTERFACE_NEED_SHOW_SAVE_TIME,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("save_font_type",xml::tag(QDSCR_INTERFACE_SAVE_FONT_TYPE,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("save_font_color",xml::tag(QDSCR_INTERFACE_SAVE_FONT_COLOR,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("is_autosave",xml::tag(QDSCR_INTERFACE_SAVE_IS_AUTOSAVE,xml::tag::TAG_DATA_INT, 1));
|
||||
|
||||
p.register_tag_format("interface_screen",xml::tag(QDSCR_INTERFACE_SCREEN,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("hide_time",xml::tag(QDSCR_INTERFACE_SCREEN_HIDE_TIME,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
p.register_tag_format("hide_offset",xml::tag(QDSCR_INTERFACE_SCREEN_HIDE_OFFSET,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("interface_element",xml::tag(QDSCR_INTERFACE_ELEMENT,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("interface_element_state",xml::tag(QDSCR_INTERFACE_ELEMENT_STATE,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("state_mode",xml::tag(QDSCR_INTERFACE_ELEMENT_STATE_MODE,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("pos",xml::tag(QDSCR_INTERFACE_ELEMENT_POS,xml::tag::TAG_DATA_INT, 3));
|
||||
|
||||
p.register_tag_format("option_id",xml::tag(QDSCR_INTERFACE_OPTION_ID,xml::tag::TAG_DATA_INT, 1));
|
||||
|
||||
p.register_tag_format("event",xml::tag(QDSCR_INTERFACE_EVENT,xml::tag::TAG_DATA_VOID, 1));
|
||||
p.register_tag_format("event_data",xml::tag(QDSCR_INTERFACE_EVENT_DATA,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("before_animation",xml::tag(QDSCR_INTERFACE_EVENT_BEFORE_ANIMATION,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("activation_type",xml::tag(QDSCR_INTERFACE_EVENT_ACTIVATION_TYPE,xml::tag::TAG_DATA_INT, 1));
|
||||
|
||||
p.register_tag_format("action",xml::tag(QDSCR_INTERFACE_ACTION,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("action_data",xml::tag(QDSCR_INTERFACE_ACTION_DATA,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("animation_flags",xml::tag(QDSCR_INTERFACE_ANIMATION_FLAGS,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("slider_rect",xml::tag(QDSCR_INTERFACE_SLIDER_RECTANGLE,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("slider_orientation",xml::tag(QDSCR_INTERFACE_SLIDER_ORIENTATION,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("background_offset",xml::tag(QDSCR_INTERFACE_BACKGROUND_OFFSET,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("thumbnail_size",xml::tag(QDSCR_INTERFACE_THUMBNAIL_SIZE,xml::tag::TAG_DATA_INT, 2));
|
||||
p.register_tag_format("text_shift",xml::tag(QDSCR_INTERFACE_TEXT_SHIFT,xml::tag::TAG_DATA_INT, 2));
|
||||
|
||||
p.register_tag_format("border_corner",xml::tag(QDSCR_TEXT_WINDOW_BORDER_CORNER,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("border_line",xml::tag(QDSCR_TEXT_WINDOW_BORDER_LINE_H,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("border_vline",xml::tag(QDSCR_TEXT_WINDOW_BORDER_LINE_V,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("border_back",xml::tag(QDSCR_TEXT_WINDOW_BORDER_BACK,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("window_slider",xml::tag(QDSCR_TEXT_WINDOW_SLIDER,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("window_type",xml::tag(QDSCR_TEXT_WINDOW_TYPE,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("string_length",xml::tag(QDSCR_TEXT_WINDOW_MAX_STRING_LENGTH,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("info_type",xml::tag(QDSCR_TEXT_WINDOW_INFO_TYPE,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("player_id",xml::tag(QDSCR_TEXT_WINDOW_PLAYER_ID,xml::tag::TAG_DATA_INT, 1));
|
||||
|
||||
p.register_tag_format("scene",xml::tag(QDSCR_SCENE,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("save_slot",xml::tag(QDSCR_SCENE_SAVE_SLOT,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("startup_scene",xml::tag(QDSCR_STARTUP_SCENE,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("restart_minigame",xml::tag(QDSCR_SCENE_RESTART_MINIGAME,xml::tag::TAG_DATA_INT, 1));
|
||||
|
||||
p.register_tag_format("location",xml::tag(QDSCR_LOCATION,xml::tag::TAG_DATA_STRING, -1));
|
||||
|
||||
p.register_tag_format("game_title",xml::tag(QDSCR_GAME_TITLE,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("text_db",xml::tag(QDSCR_TEXT_DB,xml::tag::TAG_DATA_STRING, -1));
|
||||
p.register_tag_format("cd_key",xml::tag(QDSCR_CD_KEY,xml::tag::TAG_DATA_STRING, -1));
|
||||
|
||||
// For qdScreenTextFormat
|
||||
p.register_tag_format("screen_text_format",xml::tag(QDSCR_SCREEN_TEXT_FORMAT,xml::tag::TAG_DATA_VOID, -1));
|
||||
p.register_tag_format("font_type",xml::tag(QDSCR_FONT_TYPE,xml::tag::TAG_DATA_INT, 1));
|
||||
|
||||
p.register_tag_format("default_font",xml::tag(QDSCR_DEFAULT_FONT,xml::tag::TAG_DATA_INT, 1));
|
||||
|
||||
p.register_tag_format("global_depend",xml::tag(QDSCR_GLOBAL_DEPEND,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("inverse_direction",xml::tag(QDSCR_INVERSE_DIRECTION,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("alpha",xml::tag(QDSCR_ALPHA,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("enable_background",xml::tag(QDSCR_ENABLE_BACKGROUND,xml::tag::TAG_DATA_INT, 1));
|
||||
p.register_tag_format("fade_time",xml::tag(QDSCR_FADE_TIME,xml::tag::TAG_DATA_FLOAT, 1));
|
||||
|
||||
p.register_tag_format("hof_size",xml::tag(QDSCR_HALL_OF_FAME_SIZE,xml::tag::TAG_DATA_INT, 1));
|
||||
|
||||
p.register_tag_format("screen_transform",xml::tag(QDSCR_SCREEN_TRANSFORM,xml::tag::TAG_DATA_FLOAT, 6));
|
||||
|
||||
p.register_tag_format("compression",xml::tag(QDSCR_RESOURCE_COMPRESSION,xml::tag::TAG_DATA_INT, 1));
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
const char* qdscr_XML_string(const char* p)
|
||||
{
|
||||
static std::string conv_str(1024,0);
|
||||
|
||||
conv_str = p;
|
||||
|
||||
int pos = std::string::npos;
|
||||
do {
|
||||
pos = conv_str.find("&",pos + 1);
|
||||
if(pos != std::string::npos)
|
||||
conv_str.replace(pos,1,"&");
|
||||
|
||||
} while(pos != std::string::npos);
|
||||
|
||||
pos = std::string::npos;
|
||||
do {
|
||||
pos = conv_str.find("<",pos + 1);
|
||||
if(pos != std::string::npos)
|
||||
conv_str.replace(pos,1,"<");
|
||||
|
||||
} while(pos != std::string::npos);
|
||||
|
||||
pos = std::string::npos;
|
||||
do {
|
||||
pos = conv_str.find(">",pos + 1);
|
||||
if(pos != std::string::npos)
|
||||
conv_str.replace(pos,1,">");
|
||||
|
||||
} while(pos != std::string::npos);
|
||||
|
||||
pos = std::string::npos;
|
||||
do {
|
||||
pos = conv_str.find("\"",pos + 1);
|
||||
if(pos != std::string::npos)
|
||||
conv_str.replace(pos,1,""");
|
||||
|
||||
} while(pos != std::string::npos);
|
||||
|
||||
pos = std::string::npos;
|
||||
do {
|
||||
pos = conv_str.find("'",pos + 1);
|
||||
if(pos != std::string::npos)
|
||||
conv_str.replace(pos,1,"'");
|
||||
|
||||
} while(pos != std::string::npos);
|
||||
|
||||
return conv_str.c_str();
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
|
||||
#ifndef __QDSCR_PARSER_H__
|
||||
#define __QDSCR_PARSER_H__
|
||||
|
||||
#include "xml_fwd.h"
|
||||
|
||||
//! Èäåíòèôèêàòîðû òýãîâ ñêðèïòà.
|
||||
enum qdscrTagID
|
||||
{
|
||||
QDSCR_ROOT = 1,
|
||||
|
||||
// Common
|
||||
QDSCR_ID,
|
||||
QDSCR_X,
|
||||
QDSCR_Y,
|
||||
QDSCR_SX,
|
||||
QDSCR_SY,
|
||||
QDSCR_POS2D,
|
||||
QDSCR_POS3D,
|
||||
QDSCR_SRC_POS,
|
||||
QDSCR_DEST_POS,
|
||||
QDSCR_FILE,
|
||||
QDSCR_START_TIME,
|
||||
QDSCR_PERIOD,
|
||||
QDSCR_LENGTH,
|
||||
QDSCR_SPEED,
|
||||
QDSCR_ANIMATION_SPEED,
|
||||
QDSCR_INTERPOLATION_TIME,
|
||||
QDSCR_SCALE,
|
||||
QDSCR_NAME,
|
||||
QDSCR_FLAG,
|
||||
QDSCR_RND,
|
||||
QDSCR_MASK_SIZE,
|
||||
QDSCR_MASK_ATTRIBUTES,
|
||||
QDSCR_MASK_HEIGHTS,
|
||||
QDSCR_BOUND,
|
||||
QDSCR_TYPE,
|
||||
QDSCR_SIZE,
|
||||
QDSCR_STATE,
|
||||
QDSCR_TEXT,
|
||||
QDSCR_SHORT_TEXT,
|
||||
QDSCR_VALUE,
|
||||
QDSCR_TIME,
|
||||
QDSCR_CD,
|
||||
QDSCR_ALIGN,
|
||||
QDSCR_VALIGN,
|
||||
QDSCR_ORIENTATION,
|
||||
QDSCR_COLOR,
|
||||
QDSCR_COMMENT,
|
||||
|
||||
QDSCR_SCREEN_SIZE,
|
||||
QDSCR_TEXT_SET,
|
||||
|
||||
// Text
|
||||
QDSCR_TEXT_COLOR,
|
||||
QDSCR_TEXT_HOVER_COLOR,
|
||||
QDSCR_TEXT_ALIGN,
|
||||
|
||||
// Fonts
|
||||
QDSCR_FONT_INFO,
|
||||
|
||||
// Contours
|
||||
QDSCR_CONTOUR_RECTANGLE,
|
||||
QDSCR_CONTOUR_CIRCLE,
|
||||
QDSCR_CONTOUR_POLYGON,
|
||||
|
||||
// Named Object Reference
|
||||
QDSCR_NAMED_OBJECT,
|
||||
QDSCR_NAMED_OBJECT_TYPES,
|
||||
|
||||
// Grid zone
|
||||
QDSCR_GRID_ZONE,
|
||||
QDSCR_GRID_ZONE_CELLS,
|
||||
QDSCR_GRID_ZONE_HEIGHT,
|
||||
QDSCR_GRID_ZONE_CONTOUR,
|
||||
QDSCR_GRID_ZONE_STATE,
|
||||
QDSCR_GRID_ZONE_SHADOW_COLOR,
|
||||
QDSCR_GRID_ZONE_SHADOW_ALPHA,
|
||||
|
||||
// Trigger Element
|
||||
QDSCR_TRIGGER_ELEMENT,
|
||||
QDSCR_TRIGGER_ELEMENT_LINK,
|
||||
QDSCR_TRIGGER_ELEMENT_PARENT_LINKS,
|
||||
QDSCR_TRIGGER_ELEMENT_CHILD_LINKS,
|
||||
QDSCR_TRIGGER_ELEMENT_LINK_AUTO_RESTART,
|
||||
QDSCR_TRIGGER_ELEMENT_LINK_OFFSETS,
|
||||
QDSCR_TRIGGER_ELEMENT_TITLE,
|
||||
QDSCR_TRIGGER_ELEMENT_CELL_NUMBER,
|
||||
QDSCR_TRIGGER_PARENT_LINK_OWNER_OFFSET,
|
||||
QDSCR_TRIGGER_PARENT_LINK_CHILD_OFFSET,
|
||||
QDSCR_TRIGGER_CHILD_LINK_OWNER_OFFSET,
|
||||
QDSCR_TRIGGER_CHILD_LINK_CHILD_OFFSET,
|
||||
QDSCR_TRIGGER_START_ELEMENT,
|
||||
|
||||
// Trigger Chain
|
||||
QDSCR_TRIGGER_CHAIN,
|
||||
QDSCR_TRIGGER_CHAIN_ROOT,
|
||||
QDSCR_TRIGGER_CHAIN_WORK_AREA,
|
||||
QDSCR_TRIGGER_CHAIN_LAYOUT,
|
||||
|
||||
QDSCR_TRIGGER_BOUND,
|
||||
|
||||
// Sound
|
||||
QDSCR_SOUND,
|
||||
QDSCR_SOUND_VOLUME,
|
||||
|
||||
// Music
|
||||
QDSCR_MUSIC_TRACK,
|
||||
QDSCR_MUSIC_TRACK_CYCLED,
|
||||
|
||||
// Video
|
||||
QDSCR_VIDEO,
|
||||
QDSCR_VIDEO_POSITION,
|
||||
QDSCR_VIDEO_BACKGROUND,
|
||||
|
||||
// Minigame
|
||||
QDSCR_MINIGAME,
|
||||
QDSCR_MINIGAME_DLL_NAME,
|
||||
QDSCR_MINIGAME_GAME_NAME,
|
||||
QDSCR_MINIGAME_CONFIG_FILE,
|
||||
QDSCR_MINIGAME_STATE,
|
||||
QDSCR_MINIGAME_SCORE,
|
||||
QDSCR_MINIGAME_CONFIG_PARAMETER,
|
||||
|
||||
// Animation
|
||||
QDSCR_ANIMATION_FRAME,
|
||||
QDSCR_ANIMATION_INFO,
|
||||
QDSCR_ANIMATION_FILE,
|
||||
QDSCR_ANIMATION,
|
||||
|
||||
// AnimationSet
|
||||
QDSCR_ANIMATION_SET,
|
||||
QDSCR_ANIMATION_SET_START_ANGLE,
|
||||
QDSCR_ANIMATION_SET_TURN,
|
||||
|
||||
// Coords Animation
|
||||
QDSCR_COORDS_ANIMATION_POINT,
|
||||
QDSCR_COORDS_ANIMATION,
|
||||
QDSCR_ANIMATION_PHASE,
|
||||
|
||||
// Game Object
|
||||
QDSCR_PARALLAX_OFFSET,
|
||||
|
||||
// Static Object
|
||||
QDSCR_STATIC_OBJECT,
|
||||
|
||||
// Animated Object
|
||||
QDSCR_ANIMATED_OBJECT,
|
||||
QDSCR_OBJECT_STATE,
|
||||
QDSCR_OBJECT_MOVEMENT_STATES,
|
||||
QDSCR_OBJECT_MOVEMENT_STATE,
|
||||
|
||||
QDSCR_OBJECT_DIRECTION,
|
||||
QDSCR_OBJECT_DEFAULT_POS,
|
||||
QDSCR_OBJECT_DEFAULT_DIRECTION,
|
||||
|
||||
QDSCR_OBJECT_STATE_STATIC,
|
||||
QDSCR_OBJECT_STATE_WALK,
|
||||
QDSCR_OBJECT_STATE_MASK,
|
||||
QDSCR_OBJECT_STATE_MASK_POS,
|
||||
QDSCR_OBJECT_STATE_MASK_SIZE,
|
||||
QDSCR_OBJECT_STATE_MASK_DATA,
|
||||
QDSCR_OBJECT_STATE_MASK_PARENT,
|
||||
QDSCR_OBJECT_STATE_MASK_CONTOUR,
|
||||
QDSCR_OBJECT_STATE_CENTER_OFFSET,
|
||||
QDSCR_OBJECT_STATE_DELAY,
|
||||
QDSCR_OBJECT_STATE_SOUND_DELAY,
|
||||
QDSCR_OBJECT_STATE_TEXT_DELAY,
|
||||
QDSCR_OBJECT_STATE_CURSOR_ID,
|
||||
QDSCR_OBJECT_STATE_ACCELERATION,
|
||||
QDSCR_OBJECT_STATE_RND_MOVE,
|
||||
|
||||
QDSCR_OBJECT_STATE_WALK_SOUND_FREQUENCY,
|
||||
|
||||
QDSCR_STATE_CENTER_OFFSETS,
|
||||
QDSCR_STATE_STATIC_CENTER_OFFSETS,
|
||||
QDSCR_STATE_START_CENTER_OFFSETS,
|
||||
QDSCR_STATE_STOP_CENTER_OFFSETS,
|
||||
|
||||
// State conditions
|
||||
QDSCR_CONDITION,
|
||||
QDSCR_CONDITION_DATA_INT,
|
||||
QDSCR_CONDITION_DATA_FLOAT,
|
||||
QDSCR_CONDITION_DATA_STRING,
|
||||
QDSCR_CONDITION_INVERSE,
|
||||
QDSCR_CONDITIONS_MODE,
|
||||
|
||||
QDSCR_CONDITION_GROUP,
|
||||
QDSCR_CONDITION_OBJECT,
|
||||
|
||||
// Counter
|
||||
QDSCR_COUNTER,
|
||||
QDSCR_COUNTER_ELEMENT,
|
||||
QDSCR_COUNTER_INC_VALUE,
|
||||
QDSCR_COUNTER_LIMIT,
|
||||
QDSCR_COUNTER_DIGITS,
|
||||
QDSCR_COUNTER_NAME,
|
||||
|
||||
// Object Scale
|
||||
QDSCR_OBJ_SCALE_INFO,
|
||||
|
||||
// Mouse object
|
||||
QDSCR_MOUSE_OBJECT,
|
||||
QDSCR_MOUSE_DEFAULT_CURSORS,
|
||||
|
||||
// Moving Object
|
||||
QDSCR_MOVEMENT_ANIMATION_NUMBER,
|
||||
QDSCR_MOVEMENT_ANIMATIONS,
|
||||
QDSCR_STATIC_ANIMATIONS,
|
||||
QDSCR_MOVING_OBJECT,
|
||||
QDSCR_COLLISION_RADIUS,
|
||||
QDSCR_COLLISION_DELAY,
|
||||
QDSCR_COLLISION_PATH,
|
||||
QDSCR_FOLLOW_MIN_RADIUS,
|
||||
QDSCR_FOLLOW_MAX_RADIUS,
|
||||
QDSCR_ATTACH_SHIFT,
|
||||
QDSCR_PERSONAGE_CONTROL,
|
||||
QDSCR_PERSONAGE_MOVEMENT_TYPE,
|
||||
QDSCR_ROTATION_ANGLE_PER_QUANT,
|
||||
|
||||
// Inventory
|
||||
QDSCR_INVENTORY_CELL_TYPE,
|
||||
QDSCR_INVENTORY_CELL_SET,
|
||||
QDSCR_INVENTORY_CELL_SET_SIZE,
|
||||
QDSCR_INVENTORY_CELL_SET_ADDITIONAL_CELLS,
|
||||
QDSCR_INVENTORY_CELL_SET_POS,
|
||||
QDSCR_INVENTORY,
|
||||
|
||||
// Camera & grid
|
||||
QDSCR_CAMERA,
|
||||
QDSCR_CAMERA_GRID_SIZE,
|
||||
QDSCR_CAMERA_GRID_HEIGHT,
|
||||
QDSCR_CAMERA_GRID_ATTRIBUTES,
|
||||
QDSCR_CAMERA_GRID_CENTER,
|
||||
QDSCR_CAMERA_CELL_SIZE,
|
||||
QDSCR_CAMERA_FOCUS,
|
||||
QDSCR_CAMERA_ANGLES,
|
||||
QDSCR_CAMERA_SCREEN_SIZE,
|
||||
QDSCR_CAMERA_SCREEN_OFFSET,
|
||||
QDSCR_CAMERA_SCREEN_CENTER,
|
||||
QDSCR_CAMERA_MODE,
|
||||
QDSCR_CAMERA_SCROLLING_SPEED,
|
||||
QDSCR_CAMERA_SCROLLING_DIST,
|
||||
QDSCR_CAMERA_SMOOTH_SWITCH,
|
||||
QDSCR_CAMERA_SCALE_POW,
|
||||
QDSCR_CAMERA_SCALE_Z_OFFSET,
|
||||
|
||||
// Game end
|
||||
QDSCR_GAME_END,
|
||||
QDSCR_GAME_END_SCREEN,
|
||||
|
||||
// Interface
|
||||
QDSCR_INTERFACE,
|
||||
|
||||
QDSCR_INTERFACE_SCENE_REDRAW,
|
||||
|
||||
QDSCR_INTERFACE_MAIN_MENU,
|
||||
QDSCR_INTERFACE_INGAME_SCREEN0,
|
||||
QDSCR_INTERFACE_INGAME_SCREEN1,
|
||||
QDSCR_INTERFACE_HIGHSCORE_NAME_SCREEN,
|
||||
QDSCR_INTERFACE_SAVE_PROMPT_SCREEN,
|
||||
QDSCR_INTERFACE_SAVE_NAME_SCREEN,
|
||||
|
||||
QDSCR_INTERFACE_NEED_SAVE_SCREENSHOT,
|
||||
QDSCR_INTERFACE_NEED_SHOW_SAVE_NAME,
|
||||
QDSCR_INTERFACE_NEED_SHOW_SAVE_TIME,
|
||||
QDSCR_INTERFACE_SAVE_FONT_TYPE,
|
||||
QDSCR_INTERFACE_SAVE_FONT_COLOR,
|
||||
QDSCR_INTERFACE_SAVE_IS_AUTOSAVE,
|
||||
|
||||
QDSCR_INTERFACE_SCREEN,
|
||||
QDSCR_INTERFACE_SCREEN_HIDE_TIME,
|
||||
QDSCR_INTERFACE_SCREEN_HIDE_OFFSET,
|
||||
QDSCR_INTERFACE_ELEMENT,
|
||||
|
||||
QDSCR_INTERFACE_ELEMENT_STATE,
|
||||
QDSCR_INTERFACE_ELEMENT_STATE_MODE,
|
||||
QDSCR_INTERFACE_ELEMENT_POS,
|
||||
|
||||
QDSCR_INTERFACE_OPTION_ID,
|
||||
|
||||
QDSCR_INTERFACE_EVENT,
|
||||
QDSCR_INTERFACE_EVENT_DATA,
|
||||
QDSCR_INTERFACE_EVENT_BEFORE_ANIMATION,
|
||||
QDSCR_INTERFACE_EVENT_ACTIVATION_TYPE,
|
||||
|
||||
QDSCR_INTERFACE_ACTION,
|
||||
QDSCR_INTERFACE_ACTION_DATA,
|
||||
|
||||
QDSCR_INTERFACE_ANIMATION_FLAGS,
|
||||
QDSCR_INTERFACE_SLIDER_RECTANGLE,
|
||||
QDSCR_INTERFACE_SLIDER_ORIENTATION,
|
||||
QDSCR_INTERFACE_BACKGROUND_OFFSET,
|
||||
|
||||
QDSCR_INTERFACE_THUMBNAIL_SIZE,
|
||||
QDSCR_INTERFACE_TEXT_SHIFT,
|
||||
|
||||
QDSCR_TEXT_WINDOW_BORDER_CORNER,
|
||||
QDSCR_TEXT_WINDOW_BORDER_LINE_H,
|
||||
QDSCR_TEXT_WINDOW_BORDER_LINE_V,
|
||||
QDSCR_TEXT_WINDOW_BORDER_BACK,
|
||||
QDSCR_TEXT_WINDOW_SLIDER,
|
||||
QDSCR_TEXT_WINDOW_TYPE,
|
||||
QDSCR_TEXT_WINDOW_MAX_STRING_LENGTH,
|
||||
QDSCR_TEXT_WINDOW_INFO_TYPE,
|
||||
QDSCR_TEXT_WINDOW_PLAYER_ID,
|
||||
|
||||
// Scene
|
||||
QDSCR_SCENE,
|
||||
QDSCR_SCENE_SAVE_SLOT,
|
||||
QDSCR_STARTUP_SCENE,
|
||||
QDSCR_SCENE_RESTART_MINIGAME,
|
||||
|
||||
// Location
|
||||
QDSCR_LOCATION,
|
||||
|
||||
QDSCR_GAME_TITLE,
|
||||
QDSCR_TEXT_DB,
|
||||
QDSCR_CD_KEY,
|
||||
|
||||
// For qdScreenTextFormat
|
||||
QDSCR_SCREEN_TEXT_FORMAT,
|
||||
QDSCR_FONT_TYPE,
|
||||
|
||||
QDSCR_DEFAULT_FONT,
|
||||
QDSCR_GLOBAL_DEPEND,
|
||||
QDSCR_INVERSE_DIRECTION,
|
||||
QDSCR_ALPHA,
|
||||
QDSCR_ENABLE_BACKGROUND,
|
||||
QDSCR_FADE_TIME,
|
||||
|
||||
QDSCR_HALL_OF_FAME_SIZE,
|
||||
|
||||
QDSCR_RESOURCE_COMPRESSION,
|
||||
|
||||
QDSCR_SCREEN_TRANSFORM,
|
||||
|
||||
QDSCR_MAX_KEYWORD_ID
|
||||
};
|
||||
|
||||
xml::parser& qdscr_XML_Parser();
|
||||
const char* qdscr_XML_string(const char* p);
|
||||
|
||||
#endif /* __QDSCR_PARSER_H__ */
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef __XML_FWD_H__
|
||||
#define __XML_FWD_H__
|
||||
|
||||
// forward declarations
|
||||
namespace xml {
|
||||
class tag;
|
||||
class tag_buffer;
|
||||
class parser;
|
||||
}; /* namespace xml */
|
||||
|
||||
#endif /* __XML_FWD_H__ */
|
||||
@@ -0,0 +1,404 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
//#include <fstream>
|
||||
|
||||
#ifndef _XML_ONLY_BINARY_SCRIPT_
|
||||
#include <expat.h>
|
||||
#endif
|
||||
|
||||
#include "xml_parser.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
|
||||
namespace xml {
|
||||
|
||||
#ifndef _XML_ONLY_BINARY_SCRIPT_
|
||||
static void start_element_handler(void* userData,const XML_Char* name,const XML_Char** atts);
|
||||
static void end_element_handler(void* userData,const XML_Char* name);
|
||||
static void character_data_handler(void* userData,const XML_Char* s,int len);
|
||||
static int unknown_encoding_handler(void* encodingHandlerData,const XML_Char *name,XML_Encoding* info);
|
||||
|
||||
static const char* UTF8_convert(const char* input_string,int input_string_length = -1);
|
||||
#endif
|
||||
|
||||
static bool write_tag(XStream& ff,const tag& tg,int depth = 0);
|
||||
|
||||
}; /* namespace xml */
|
||||
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
namespace xml {
|
||||
|
||||
#ifndef _XML_ONLY_BINARY_SCRIPT_
|
||||
static const char* UTF8_convert(const char* input_string,int input_string_length)
|
||||
{
|
||||
static std::wstring wstr(1024,0);
|
||||
static std::string str(1024,0);
|
||||
|
||||
unsigned int length = MultiByteToWideChar(CP_UTF8,0,input_string,input_string_length,NULL,0);
|
||||
if(wstr.length() < length)
|
||||
wstr.resize(length,0);
|
||||
|
||||
MultiByteToWideChar(CP_UTF8,0,input_string,input_string_length,&*wstr.begin(),length);
|
||||
|
||||
if(str.length() < length + 1)
|
||||
str.resize(length + 1,0);
|
||||
str[length] = 0;
|
||||
|
||||
WideCharToMultiByte(CP_ACP,0,wstr.c_str(),length,&*str.begin(),length,NULL,NULL);
|
||||
|
||||
return str.c_str();
|
||||
}
|
||||
|
||||
static int unknown_encoding_handler(void* encodingHandlerData,const XML_Char* name,XML_Encoding* info)
|
||||
{
|
||||
if(!strcmp(name,"WINDOWS-1251")){
|
||||
info -> data = NULL;
|
||||
info -> convert = NULL;
|
||||
info -> release = NULL;
|
||||
|
||||
for(int i = 0; i < 256; i ++){
|
||||
char c = i;
|
||||
unsigned short cc;
|
||||
|
||||
MultiByteToWideChar(1251,0,&c,1,&cc,1);
|
||||
|
||||
info -> map[i] = cc;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void start_element_handler(void* userData,const XML_Char* name,const XML_Char** atts)
|
||||
{
|
||||
parser* p = static_cast<parser*>(userData);
|
||||
p -> start_element_handler(name,atts);
|
||||
}
|
||||
|
||||
static void end_element_handler(void* userData,const XML_Char* name)
|
||||
{
|
||||
parser* p = static_cast<parser*>(userData);
|
||||
p -> end_element_handler(name);
|
||||
}
|
||||
|
||||
static void character_data_handler(void* userData,const XML_Char* s,int len)
|
||||
{
|
||||
parser* p = static_cast<parser*>(userData);
|
||||
p -> character_data_handler(s,len);
|
||||
}
|
||||
#endif
|
||||
|
||||
parser::parser() : data_pool_position_(0), data_buffer_(1024,0), cur_level_(0), skip_mode_(false), binary_script_(false)
|
||||
{
|
||||
root_tag_.set_data(&data_pool_);
|
||||
}
|
||||
|
||||
parser::~parser()
|
||||
{
|
||||
}
|
||||
|
||||
void parser::clear()
|
||||
{
|
||||
root_tag_.clear();
|
||||
while(!tag_stack_.empty()) tag_stack_.pop();
|
||||
|
||||
cur_level_ = 0;
|
||||
skip_mode_ = false;
|
||||
|
||||
data_pool_.clear();
|
||||
std::vector<char>(data_pool_).swap(data_pool_);
|
||||
}
|
||||
|
||||
#ifndef _XML_ONLY_BINARY_SCRIPT_
|
||||
void parser::start_element_handler(const char* tag_name,const char** tag_attributes)
|
||||
{
|
||||
if(!skip_mode_){
|
||||
const tag* fmt = get_tag_format(tag_name);
|
||||
if(fmt){
|
||||
tag tg(*fmt);
|
||||
tg.set_data(&data_pool_);
|
||||
|
||||
int sz = 0;
|
||||
while(tag_attributes[sz]) sz++;
|
||||
|
||||
if(sz >= 2){
|
||||
for(int i = 0; i < sz; i += 2){
|
||||
const tag* afmt = get_tag_format(tag_attributes[i]);
|
||||
if(afmt){
|
||||
tag att(*afmt);
|
||||
att.set_data(&data_pool_);
|
||||
|
||||
read_tag_data(att,tag_attributes[i + 1],strlen(tag_attributes[i + 1]));
|
||||
tg.add_subtag(att);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!tag_stack_.empty())
|
||||
tag_stack_.push(&tag_stack_.top() -> add_subtag(tg));
|
||||
}
|
||||
else {
|
||||
skip_mode_ = true;
|
||||
cur_level_ = 0;
|
||||
}
|
||||
|
||||
data_buffer_.clear();
|
||||
}
|
||||
else
|
||||
cur_level_ ++;
|
||||
}
|
||||
|
||||
void parser::end_element_handler(const char* tag_name)
|
||||
{
|
||||
if(!skip_mode_){
|
||||
if(!tag_stack_.empty())
|
||||
read_tag_data(*tag_stack_.top(),data_buffer_.c_str(),strlen(data_buffer_.c_str()));
|
||||
|
||||
tag_stack_.pop();
|
||||
}
|
||||
else {
|
||||
if(!cur_level_--) skip_mode_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void parser::character_data_handler(const char* data,int data_length)
|
||||
{
|
||||
data_buffer_.append(data,data_length);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool parser::parse_file(const char* fname)
|
||||
{
|
||||
if(is_script_binary(fname))
|
||||
return read_binary_script(fname);
|
||||
|
||||
#ifndef _XML_ONLY_BINARY_SCRIPT_
|
||||
binary_script_ = false;
|
||||
|
||||
XML_Parser p = XML_ParserCreate(NULL);
|
||||
|
||||
XML_SetUserData(p,this);
|
||||
XML_SetElementHandler(p,xml::start_element_handler,xml::end_element_handler);
|
||||
XML_SetCharacterDataHandler(p,xml::character_data_handler);
|
||||
|
||||
XML_SetUnknownEncodingHandler(p,unknown_encoding_handler,NULL);
|
||||
|
||||
if(!p) return false;
|
||||
|
||||
XStream ff(fname,XS_IN);
|
||||
|
||||
unsigned int fsize = ff.size();
|
||||
|
||||
void* buf = XML_GetBuffer(p,fsize);
|
||||
if(!buf) return false;
|
||||
|
||||
ff.read(static_cast<char*>(buf),fsize);
|
||||
ff.close();
|
||||
|
||||
if(data_pool_.size() < fsize/2)
|
||||
data_pool_.resize(fsize/2);
|
||||
|
||||
tag_stack_.push(&root_tag_);
|
||||
|
||||
if(XML_ParseBuffer(p,fsize,1) == XML_STATUS_OK){
|
||||
XML_ParserFree(p);
|
||||
return true;
|
||||
}
|
||||
|
||||
XML_Error err_code = XML_GetErrorCode(p);
|
||||
|
||||
XBuffer err_buf;
|
||||
err_buf < XML_ErrorString(err_code) < "\nLine: " <= XML_GetCurrentLineNumber(p);
|
||||
|
||||
MessageBox(NULL,err_buf.c_str(),"XML Parser error",MB_OK);
|
||||
XML_ParserFree(p);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef _XML_ONLY_BINARY_SCRIPT_
|
||||
bool parser::read_tag_data(tag& tg,const char* data_ptr,int data_length)
|
||||
{
|
||||
if(tg.data_size() && tg.data_format() != tag::TAG_DATA_VOID){
|
||||
if(tg.data_format() == tag::TAG_DATA_STRING){
|
||||
const char* str = UTF8_convert(data_ptr,data_length);
|
||||
tg.set_data_size(strlen(str) + 1);
|
||||
|
||||
tg.set_data_offset(data_pool_position_);
|
||||
unsigned int sz = tg.data_size() * tg.data_element_size();
|
||||
if(data_pool_.size() < data_pool_position_ + sz)
|
||||
data_pool_.resize(data_pool_position_ + sz);
|
||||
|
||||
char* p = &*(data_pool_.begin() + data_pool_position_);
|
||||
strcpy(p,str);
|
||||
|
||||
data_pool_position_ += sz;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
tag_buffer buf(data_ptr,data_length);
|
||||
if(tg.data_size() == -1){
|
||||
int sz;
|
||||
buf >= sz;
|
||||
tg.set_data_size(sz);
|
||||
}
|
||||
|
||||
tg.set_data_offset(data_pool_position_);
|
||||
|
||||
unsigned int sz = tg.data_size() * tg.data_element_size();
|
||||
if(data_pool_.size() < data_pool_position_ + sz)
|
||||
data_pool_.resize(data_pool_position_ + sz);
|
||||
|
||||
switch(tg.data_format()){
|
||||
case tag::TAG_DATA_SHORT: {
|
||||
short* p = reinterpret_cast<short*>(&*(data_pool_.begin() + data_pool_position_));
|
||||
for(int j = 0; j < tg.data_size(); j ++) buf >= p[j];
|
||||
}
|
||||
break;
|
||||
case tag::TAG_DATA_UNSIGNED_SHORT: {
|
||||
unsigned short* p = reinterpret_cast<unsigned short*>(&*(data_pool_.begin() + data_pool_position_));
|
||||
for(int j = 0; j < tg.data_size(); j ++) buf >= p[j];
|
||||
}
|
||||
break;
|
||||
case tag::TAG_DATA_INT: {
|
||||
int* p = reinterpret_cast<int*>(&*(data_pool_.begin() + data_pool_position_));
|
||||
for(int j = 0; j < tg.data_size(); j ++) buf >= p[j];
|
||||
}
|
||||
break;
|
||||
case tag::TAG_DATA_UNSIGNED_INT: {
|
||||
unsigned int* p = reinterpret_cast<unsigned int*>(&*(data_pool_.begin() + data_pool_position_));
|
||||
for(int j = 0; j < tg.data_size(); j ++) buf >= p[j];
|
||||
}
|
||||
break;
|
||||
case tag::TAG_DATA_FLOAT: {
|
||||
float* p = reinterpret_cast<float*>(&*(data_pool_.begin() + data_pool_position_));
|
||||
for(int j = 0; j < tg.data_size(); j ++) buf >= p[j];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
data_pool_position_ += sz;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
XStream& operator < (XStream& ff,const tag& tg)
|
||||
{
|
||||
int id = tg.ID();
|
||||
ff.write(reinterpret_cast<const char*>(&id),sizeof(int));
|
||||
|
||||
int data_format = tg.data_format();
|
||||
ff.write(reinterpret_cast<const char*>(&data_format),sizeof(int));
|
||||
|
||||
int data_size = tg.data_size();
|
||||
ff.write(reinterpret_cast<const char*>(&data_size),sizeof(int));
|
||||
|
||||
int data_offset = tg.data_offset();
|
||||
ff.write(reinterpret_cast<const char*>(&data_offset),sizeof(int));
|
||||
|
||||
int num_subtags = tg.num_subtags();
|
||||
ff.write(reinterpret_cast<const char*>(&num_subtags),sizeof(int));
|
||||
|
||||
for(tag::subtag_iterator it = tg.subtags_begin(); it != tg.subtags_end(); ++it)
|
||||
ff < *it;
|
||||
|
||||
return ff;
|
||||
}
|
||||
|
||||
XStream& operator > (XStream& ff,tag& tg)
|
||||
{
|
||||
int id = 0;
|
||||
ff.read(reinterpret_cast<char*>(&id),sizeof(int));
|
||||
|
||||
int data_format = 0;
|
||||
ff.read(reinterpret_cast<char*>(&data_format),sizeof(int));
|
||||
|
||||
int data_size = 0;
|
||||
ff.read(reinterpret_cast<char*>(&data_size),sizeof(int));
|
||||
|
||||
int data_offset = 0;
|
||||
ff.read(reinterpret_cast<char*>(&data_offset),sizeof(int));
|
||||
|
||||
tg = tag(tag(id,tag::tag_data_format(data_format),data_size,data_offset));
|
||||
|
||||
int num_subtags = 0;
|
||||
ff.read(reinterpret_cast<char*>(&num_subtags),sizeof(int));
|
||||
|
||||
for(int i = 0; i < num_subtags; i++){
|
||||
tag stg;
|
||||
ff > stg;
|
||||
|
||||
tg.add_subtag(stg);
|
||||
}
|
||||
|
||||
return ff;
|
||||
}
|
||||
|
||||
bool parser::read_binary_script(const char* fname)
|
||||
{
|
||||
XStream ff(fname, XS_IN);
|
||||
|
||||
binary_script_ = true;
|
||||
|
||||
int v = 0;
|
||||
ff.read(reinterpret_cast<char*>(&v),sizeof(int));
|
||||
|
||||
int size = 0;
|
||||
ff.read(reinterpret_cast<char*>(&size),sizeof(int));
|
||||
|
||||
if(data_pool_.size() < size)
|
||||
data_pool_.resize(size);
|
||||
|
||||
ff.read(&*data_pool_.begin(),size);
|
||||
|
||||
root_tag_.clear();
|
||||
ff > root_tag_;
|
||||
|
||||
root_tag_.set_data(&data_pool_);
|
||||
|
||||
ff.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parser::write_binary_script(const char* fname) const
|
||||
{
|
||||
XStream ff(fname, XS_OUT);
|
||||
|
||||
int v = 8383;
|
||||
ff.write(reinterpret_cast<const char*>(&v),sizeof(int));
|
||||
|
||||
ff.write(reinterpret_cast<const char*>(&data_pool_position_),sizeof(int));
|
||||
ff.write(&*data_pool_.begin(),data_pool_position_);
|
||||
|
||||
ff < root_tag_;
|
||||
|
||||
ff.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parser::is_script_binary(const char* fname) const
|
||||
{
|
||||
XStream ff(fname, XS_IN);
|
||||
|
||||
int v = 0;
|
||||
ff.read(reinterpret_cast<char*>(&v),sizeof(int));
|
||||
|
||||
ff.close();
|
||||
|
||||
if(v == 8383) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}; /* namespace xml */
|
||||
@@ -0,0 +1,81 @@
|
||||
#ifndef __XML_PARSER_H__
|
||||
#define __XML_PARSER_H__
|
||||
|
||||
#include "xml_tag_buffer.h"
|
||||
|
||||
namespace xml {
|
||||
|
||||
#ifdef _FINAL_VERSION_
|
||||
#define _XML_ONLY_BINARY_SCRIPT_
|
||||
#endif
|
||||
|
||||
class parser
|
||||
{
|
||||
public:
|
||||
typedef std::hash_map<std::string,tag> tag_format_t;
|
||||
typedef std::stack<tag*> tag_stack_t;
|
||||
|
||||
parser();
|
||||
virtual ~parser();
|
||||
|
||||
bool parse_file(const char* fname);
|
||||
|
||||
bool read_binary_script(const char* fname);
|
||||
bool write_binary_script(const char* fname) const;
|
||||
bool is_script_binary(const char* fname) const;
|
||||
bool is_script_binary() const { return binary_script_; }
|
||||
|
||||
const tag& root_tag() const { return root_tag_; }
|
||||
|
||||
void clear();
|
||||
|
||||
#ifndef _XML_ONLY_BINARY_SCRIPT_
|
||||
virtual void start_element_handler(const char* tag_name,const char** tag_attributes);
|
||||
virtual void end_element_handler(const char* tag_name);
|
||||
virtual void character_data_handler(const char* data,int data_length);
|
||||
#endif
|
||||
|
||||
void resize_data_pool(unsigned int pool_sz){ data_pool_.resize(pool_sz); }
|
||||
|
||||
bool register_tag_format(const char* tag_name,const tag& tg){
|
||||
tag_format_t::iterator it = tag_format_.find(tag_name);
|
||||
if(it != tag_format_.end())
|
||||
return false;
|
||||
|
||||
tag_format_.insert(tag_format_t::value_type(tag_name,tg));
|
||||
return true;
|
||||
}
|
||||
const tag* get_tag_format(const char* tag_name) const {
|
||||
tag_format_t::const_iterator it = tag_format_.find(tag_name);
|
||||
if(it != tag_format_.end())
|
||||
return &it -> second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int num_tag_formats() const { return tag_format_.size(); }
|
||||
|
||||
private:
|
||||
|
||||
tag root_tag_;
|
||||
|
||||
int data_pool_position_;
|
||||
std::vector<char> data_pool_;
|
||||
std::string data_buffer_;
|
||||
|
||||
bool binary_script_;
|
||||
|
||||
tag_stack_t tag_stack_;
|
||||
tag_format_t tag_format_;
|
||||
int cur_level_;
|
||||
bool skip_mode_;
|
||||
|
||||
#ifndef _XML_ONLY_BINARY_SCRIPT_
|
||||
bool read_tag_data(tag& tg,const char* data_ptr,int data_length);
|
||||
#endif
|
||||
};
|
||||
|
||||
}; /* namespace xml */
|
||||
|
||||
#endif /* __XML_PARSER_H__ */
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
#ifndef __XML_TAG_H__
|
||||
#define __XML_TAG_H__
|
||||
|
||||
//! Ïàðñåð XML íà áàçå expat.
|
||||
namespace xml {
|
||||
|
||||
//! XML òåã.
|
||||
class tag
|
||||
{
|
||||
public:
|
||||
typedef std::list<tag> subtags_t;
|
||||
typedef subtags_t::const_iterator subtag_iterator;
|
||||
|
||||
//! Ôîðìàò äàííûõ òåãà.
|
||||
enum tag_data_format {
|
||||
//! äàííûå îòñóòñòâóþò
|
||||
TAG_DATA_VOID,
|
||||
//! äàííûå òèïà short int
|
||||
TAG_DATA_SHORT,
|
||||
//! äàííûå òèïà unsigned short int
|
||||
TAG_DATA_UNSIGNED_SHORT,
|
||||
//! äàííûå òèïà int
|
||||
TAG_DATA_INT,
|
||||
//! äàííûå òèïà unsigned int
|
||||
TAG_DATA_UNSIGNED_INT,
|
||||
//! äàííûå òèïà float
|
||||
TAG_DATA_FLOAT,
|
||||
//! ñòðîêîâûå äàííûå
|
||||
TAG_DATA_STRING
|
||||
};
|
||||
|
||||
tag(int id = 0,tag_data_format data_fmt = TAG_DATA_VOID,int data_sz = 0,int data_offs = 0) : ID_(id), data_format_(data_fmt), data_size_(data_sz), data_offset_(data_offs), data_(NULL) { }
|
||||
tag(const tag& tg) : ID_(tg.ID_), data_format_(tg.data_format_), data_size_(tg.data_size_), data_offset_(tg.data_offset_), data_(tg.data_), subtags_(tg.subtags_) { }
|
||||
~tag(){ }
|
||||
|
||||
tag& operator = (const tag& tg){
|
||||
if(this == &tg) return *this;
|
||||
|
||||
ID_ = tg.ID_;
|
||||
data_format_ = tg.data_format_;
|
||||
data_size_ = tg.data_size_;
|
||||
data_offset_ = tg.data_offset_;
|
||||
|
||||
subtags_ = tg.subtags_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Âîçâðàùàåò èäåíòèôèêàòîð òåãà.
|
||||
int ID() const { return ID_; }
|
||||
|
||||
//! Âîçâðàùàåò ôîðìàò äàííûõ òåãà.
|
||||
tag_data_format data_format() const { return data_format_; }
|
||||
|
||||
//! Âîçâðàùàåò êîëè÷åñòâî ýëåìåòîâ äàííûõ òåãà.
|
||||
/**
|
||||
×òîáû ïîëó÷èòü ðàçìåð äàííûõ â áàéòàõ, íàäî ýòî ÷èñëî
|
||||
óìíîæèòü íà ðàçìåð ýëåìåíòà äàííûõ â áàéòàõ - data_elemet_size().
|
||||
*/
|
||||
int data_size() const { return data_size_; }
|
||||
//! Âîçâðàùàåò ðàçìåð ýëåìåíòà äàííûõ òåãà â áàéòàõ.
|
||||
int data_element_size() const {
|
||||
switch(data_format_){
|
||||
case TAG_DATA_VOID:
|
||||
return 0;
|
||||
case TAG_DATA_SHORT:
|
||||
return sizeof(short);
|
||||
case TAG_DATA_INT:
|
||||
return sizeof(int);
|
||||
case TAG_DATA_UNSIGNED_INT:
|
||||
return sizeof(unsigned int);
|
||||
case TAG_DATA_FLOAT:
|
||||
return sizeof(float);
|
||||
case TAG_DATA_STRING:
|
||||
return sizeof(char);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//! Óñòàíàâëèâàåò êîëè÷åñòâî ýëåìåíòîâ äàííûõ òåãà.
|
||||
void set_data_size(int sz){ data_size_ = sz; }
|
||||
|
||||
//! Âîçâðàùàåò ñìåùåíèå äî äàííûõ òåãà â äàííûõ ïàðñåðà.
|
||||
int data_offset() const { return data_offset_; }
|
||||
//! Óñòàíàâëèâàåò ñìåùåíèå äî äàííûõ òåãà â äàííûõ ïàðñåðà.
|
||||
void set_data_offset(int off){ data_offset_ = off; }
|
||||
|
||||
//! Âîçâðàùàåò óêàçàòåëü íà äàííûå òåãà.
|
||||
const char* data() const { return &*(data_ -> begin() + data_offset_); }
|
||||
|
||||
//! Óñòàíàâëèâàåò óêàçàòåëü íà îáùèå äàííûå.
|
||||
void set_data(const std::vector<char>* p){
|
||||
data_ = p;
|
||||
|
||||
for(subtags_t::iterator it = subtags_.begin(); it != subtags_.end(); ++it)
|
||||
it -> set_data(p);
|
||||
}
|
||||
|
||||
//! Î÷èñòêà âëîæåííûõ òåãîâ.
|
||||
void clear(){ subtags_.clear(); }
|
||||
//! Äîáàâëÿåò âëîæåííûé òåã.
|
||||
/**
|
||||
Âîçâðàùàåò ññûëêó íà ïîñëåäíèé âëîæåííûé òåã.
|
||||
*/
|
||||
tag& add_subtag(const tag& tg){ subtags_.push_back(tg); return subtags_.back(); }
|
||||
//! Âîçâðàùàåò true, åñëè ñïèñîê âëîæåííûõ òåãîâ íå ïóñòîé .
|
||||
bool has_subtags() const { return !subtags_.empty(); }
|
||||
//! Âîçâðàùàåò êîëè÷åñòâî âëîæåííûõ òýãîâ.
|
||||
int num_subtags() const { return subtags_.size(); }
|
||||
//! Âîçâðàùàåò èòåðàòîð íà÷àëà ñïèñêà âëîæåííûõ òåãîâ.
|
||||
subtag_iterator subtags_begin() const { return subtags_.begin(); }
|
||||
//! Âîçâðàùàåò èòåðàòîð êîíöà ñïèñêà âëîæåííûõ òåãîâ.
|
||||
subtag_iterator subtags_end() const { return subtags_.end(); }
|
||||
//! Ïîèñê âëîæåííîãî òåãà ïî åãî èäåíòèôèêàòîðó.
|
||||
const tag* search_subtag(int subtag_id) const {
|
||||
for(subtag_iterator it = subtags_begin(); it != subtags_end(); ++it)
|
||||
if(it -> ID() == subtag_id) return &*it;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//! Èäåíòèôèêàòîð (òèï) òåãà.
|
||||
int ID_;
|
||||
//! Ôîðìàò äàííûõ òåãà.
|
||||
tag_data_format data_format_;
|
||||
//! Êîëè÷åñòâî ýëåìåíòîâ äàííûõ òåãà.
|
||||
int data_size_;
|
||||
//! Ñìåùåíèå äî äàííûõ òåãà â îáùèõ äàííûõ.
|
||||
int data_offset_;
|
||||
//! Óêàçàòåëü íà äàííûå.
|
||||
const std::vector<char>* data_;
|
||||
|
||||
//! Ñïèñîê âëîæåííûõ òåãîâ.
|
||||
subtags_t subtags_;
|
||||
};
|
||||
|
||||
}; /* namespace xml */
|
||||
|
||||
#endif /* __XML_TAG_H__ */
|
||||
@@ -0,0 +1,105 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "xml_tag_buffer.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
namespace xml {
|
||||
|
||||
tag_buffer::tag_buffer(const tag& tg) : data_size_(tg.data_size() * tg.data_element_size()),
|
||||
data_offset_(0),
|
||||
#ifdef _DEBUG
|
||||
data_format_(tg.data_format()),
|
||||
#endif
|
||||
data_(tg.data())
|
||||
{
|
||||
}
|
||||
|
||||
tag_buffer::tag_buffer(const char* dp,int len) : data_size_(len),
|
||||
data_offset_(0),
|
||||
#ifdef _DEBUG
|
||||
data_format_(tag::TAG_DATA_VOID),
|
||||
#endif
|
||||
data_(dp)
|
||||
{
|
||||
}
|
||||
|
||||
tag_buffer::tag_buffer(const tag_buffer& tb) : data_size_(tb.data_size_),
|
||||
data_offset_(tb.data_offset_),
|
||||
#ifdef _DEBUG
|
||||
data_format_(tb.data_format_),
|
||||
#endif
|
||||
data_(tb.data_)
|
||||
{
|
||||
}
|
||||
|
||||
tag_buffer& tag_buffer::operator = (const tag_buffer& tb)
|
||||
{
|
||||
if(this == &tb) return *this;
|
||||
|
||||
data_size_ = tb.data_size_;
|
||||
data_offset_ = tb.data_offset_;
|
||||
|
||||
#ifdef _DEBUG
|
||||
data_format_ = tb.data_format_;
|
||||
#endif
|
||||
data_ = tb.data_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
tag_buffer::~tag_buffer()
|
||||
{
|
||||
}
|
||||
|
||||
tag_buffer& tag_buffer::operator >= (short& var)
|
||||
{
|
||||
char* p;
|
||||
var = (short)strtol(data_ + data_offset_,&p,0);
|
||||
data_offset_ += p - (data_ + data_offset_);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
tag_buffer& tag_buffer::operator >= (unsigned short& var)
|
||||
{
|
||||
char* p;
|
||||
var = (unsigned short)strtoul(data_ + data_offset_,&p,0);
|
||||
data_offset_ += p - (data_ + data_offset_);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
tag_buffer& tag_buffer::operator >= (int& var)
|
||||
{
|
||||
char* p;
|
||||
var = (int)strtol(data_ + data_offset_,&p,0);
|
||||
data_offset_ += p - (data_ + data_offset_);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
tag_buffer& tag_buffer::operator >= (unsigned int& var)
|
||||
{
|
||||
char* p;
|
||||
var = (unsigned int)strtoul(data_ + data_offset_,&p,0);
|
||||
data_offset_ += p - (data_ + data_offset_);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
tag_buffer& tag_buffer::operator >= (float& var)
|
||||
{
|
||||
char* p;
|
||||
var = (float)strtod(data_ + data_offset_,&p);
|
||||
data_offset_ += p - (data_ + data_offset_);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
}; /* namespace xml */
|
||||
@@ -0,0 +1,113 @@
|
||||
#ifndef __XML_TAG_BUFFER_H__
|
||||
#define __XML_TAG_BUFFER_H__
|
||||
|
||||
#include "xml_tag.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define XML_ASSERT(a) assert(a)
|
||||
#else
|
||||
#define XML_ASSERT(a)
|
||||
#endif
|
||||
|
||||
namespace xml {
|
||||
|
||||
class tag_buffer
|
||||
{
|
||||
public:
|
||||
tag_buffer(const tag& tg);
|
||||
tag_buffer(const char* dp,int len);
|
||||
tag_buffer(const tag_buffer& tb);
|
||||
~tag_buffer();
|
||||
|
||||
tag_buffer& operator = (const tag_buffer& tb);
|
||||
|
||||
tag_buffer& operator >= (short& var);
|
||||
tag_buffer& operator >= (unsigned short& var);
|
||||
tag_buffer& operator >= (int& var);
|
||||
tag_buffer& operator >= (unsigned int& var);
|
||||
tag_buffer& operator >= (float& var);
|
||||
|
||||
tag_buffer& operator > (short& var){
|
||||
XML_ASSERT(data_format_ == tag::TAG_DATA_VOID || data_format_ == tag::TAG_DATA_SHORT);
|
||||
var = *reinterpret_cast<const short*>(data_ + data_offset_);
|
||||
data_offset_ += sizeof(short);
|
||||
|
||||
return *this;
|
||||
}
|
||||
tag_buffer& operator > (unsigned short& var){
|
||||
XML_ASSERT(data_format_ == tag::TAG_DATA_VOID || data_format_ == tag::TAG_DATA_UNSIGNED_SHORT);
|
||||
var = *reinterpret_cast<const unsigned short*>(data_ + data_offset_);
|
||||
data_offset_ += sizeof(unsigned short);
|
||||
|
||||
return *this;
|
||||
}
|
||||
tag_buffer& operator > (int& var){
|
||||
XML_ASSERT(data_format_ == tag::TAG_DATA_VOID || data_format_ == tag::TAG_DATA_INT);
|
||||
var = *reinterpret_cast<const int*>(data_ + data_offset_);
|
||||
data_offset_ += sizeof(int);
|
||||
|
||||
return *this;
|
||||
}
|
||||
tag_buffer& operator > (unsigned int& var){
|
||||
XML_ASSERT(data_format_ == tag::TAG_DATA_VOID || data_format_ == tag::TAG_DATA_UNSIGNED_INT);
|
||||
var = *reinterpret_cast<const unsigned int*>(data_ + data_offset_);
|
||||
data_offset_ += sizeof(unsigned int);
|
||||
|
||||
return *this;
|
||||
}
|
||||
tag_buffer& operator > (float& var){
|
||||
XML_ASSERT(data_format_ == tag::TAG_DATA_VOID || data_format_ == tag::TAG_DATA_FLOAT);
|
||||
var = *reinterpret_cast<const float*>(data_ + data_offset_);
|
||||
data_offset_ += sizeof(float);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
short get_short(){
|
||||
XML_ASSERT(data_format_ == tag::TAG_DATA_VOID || data_format_ == tag::TAG_DATA_SHORT);
|
||||
short v;
|
||||
*this > v;
|
||||
return v;
|
||||
}
|
||||
unsigned short get_ushort(){
|
||||
XML_ASSERT(data_format_ == tag::TAG_DATA_VOID || data_format_ == tag::TAG_DATA_UNSIGNED_SHORT);
|
||||
unsigned short v;
|
||||
*this > v;
|
||||
return v;
|
||||
}
|
||||
int get_int(){
|
||||
XML_ASSERT(data_format_ == tag::TAG_DATA_VOID || data_format_ == tag::TAG_DATA_INT);
|
||||
int v;
|
||||
*this > v;
|
||||
return v;
|
||||
}
|
||||
unsigned int get_uint(){
|
||||
XML_ASSERT(data_format_ == tag::TAG_DATA_VOID || data_format_ == tag::TAG_DATA_UNSIGNED_INT);
|
||||
unsigned int v;
|
||||
*this > v;
|
||||
return v;
|
||||
}
|
||||
float get_float(){
|
||||
XML_ASSERT(data_format_ == tag::TAG_DATA_VOID || data_format_ == tag::TAG_DATA_FLOAT);
|
||||
float v;
|
||||
*this > v;
|
||||
return v;
|
||||
}
|
||||
|
||||
bool end_of_storage() const { return data_size_ > data_offset_; }
|
||||
void reset(){ data_offset_ = 0; }
|
||||
|
||||
private:
|
||||
int data_size_;
|
||||
int data_offset_;
|
||||
|
||||
#ifdef _DEBUG
|
||||
tag::tag_data_format data_format_;
|
||||
#endif
|
||||
|
||||
const char* data_;
|
||||
};
|
||||
|
||||
}; /* namespace xml */
|
||||
|
||||
#endif /* __XML_TAG_BUFFER_H__ */
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,170 @@
|
||||
256 150
|
||||
160
|
||||
33 1 1 4 20
|
||||
34 6 1 7 20
|
||||
35 14 1 11 20
|
||||
36 26 1 10 20
|
||||
37 37 1 14 20
|
||||
38 52 1 11 20
|
||||
39 64 1 4 20
|
||||
40 69 1 6 20
|
||||
41 76 1 6 20
|
||||
42 83 1 7 20
|
||||
43 91 1 10 20
|
||||
44 102 1 4 20
|
||||
45 107 1 7 20
|
||||
46 115 1 4 20
|
||||
47 120 1 6 20
|
||||
48 127 1 10 20
|
||||
49 138 1 7 20
|
||||
50 146 1 9 20
|
||||
51 156 1 10 20
|
||||
52 167 1 10 20
|
||||
53 178 1 10 20
|
||||
54 189 1 10 20
|
||||
55 200 1 10 20
|
||||
56 211 1 10 20
|
||||
57 222 1 10 20
|
||||
58 233 1 4 20
|
||||
59 238 1 4 20
|
||||
60 243 1 10 20
|
||||
61 1 22 10 20
|
||||
62 12 22 10 20
|
||||
63 23 22 10 20
|
||||
64 34 22 16 20
|
||||
65 51 22 12 20
|
||||
66 64 22 10 20
|
||||
67 75 22 12 20
|
||||
68 88 22 11 20
|
||||
69 100 22 10 20
|
||||
70 111 22 10 20
|
||||
71 122 22 13 20
|
||||
72 136 22 11 20
|
||||
73 148 22 4 20
|
||||
74 153 22 8 20
|
||||
75 162 22 11 20
|
||||
76 174 22 9 20
|
||||
77 184 22 12 20
|
||||
78 197 22 11 20
|
||||
79 209 22 13 20
|
||||
80 223 22 10 20
|
||||
81 234 22 13 20
|
||||
82 1 43 11 20
|
||||
83 13 43 11 20
|
||||
84 25 43 11 20
|
||||
85 37 43 11 20
|
||||
86 49 43 13 20
|
||||
87 63 43 16 20
|
||||
88 80 43 12 20
|
||||
89 93 43 11 20
|
||||
90 105 43 11 20
|
||||
91 117 43 6 20
|
||||
92 124 43 6 20
|
||||
93 131 43 5 20
|
||||
94 137 43 8 20
|
||||
95 146 43 12 20
|
||||
96 159 43 5 20
|
||||
97 165 43 9 20
|
||||
98 175 43 10 20
|
||||
99 186 43 9 20
|
||||
100 196 43 9 20
|
||||
101 206 43 10 20
|
||||
102 217 43 7 20
|
||||
103 225 43 9 20
|
||||
104 235 43 8 20
|
||||
105 244 43 4 20
|
||||
106 249 43 5 20
|
||||
107 1 64 9 20
|
||||
108 11 64 4 20
|
||||
109 16 64 13 20
|
||||
110 30 64 8 20
|
||||
111 39 64 10 20
|
||||
112 50 64 10 20
|
||||
113 61 64 9 20
|
||||
114 71 64 6 20
|
||||
115 78 64 9 20
|
||||
116 88 64 6 20
|
||||
117 95 64 8 20
|
||||
118 104 64 9 20
|
||||
119 114 64 13 20
|
||||
120 128 64 9 20
|
||||
121 138 64 9 20
|
||||
122 148 64 9 20
|
||||
123 158 64 7 20
|
||||
124 166 64 4 20
|
||||
125 171 64 7 20
|
||||
126 179 64 10 20
|
||||
168 190 64 10 20
|
||||
184 201 64 10 20
|
||||
192 212 64 12 20
|
||||
193 225 64 10 20
|
||||
194 236 64 10 20
|
||||
195 1 85 9 20
|
||||
196 11 85 13 20
|
||||
197 25 85 10 20
|
||||
198 36 85 17 20
|
||||
199 54 85 10 20
|
||||
200 65 85 11 20
|
||||
201 77 85 11 20
|
||||
202 89 85 10 20
|
||||
203 100 85 11 20
|
||||
204 112 85 12 20
|
||||
205 125 85 11 20
|
||||
206 137 85 13 20
|
||||
207 151 85 11 20
|
||||
208 163 85 10 20
|
||||
209 174 85 12 20
|
||||
210 187 85 11 20
|
||||
211 199 85 11 20
|
||||
212 211 85 13 20
|
||||
213 225 85 12 20
|
||||
214 238 85 11 20
|
||||
215 1 106 10 20
|
||||
216 12 106 15 20
|
||||
217 28 106 16 20
|
||||
218 45 106 14 20
|
||||
219 60 106 13 20
|
||||
220 74 106 10 20
|
||||
221 85 106 12 20
|
||||
222 98 106 15 20
|
||||
223 114 106 12 20
|
||||
224 127 106 9 20
|
||||
225 137 106 10 20
|
||||
226 148 106 9 20
|
||||
227 158 106 8 20
|
||||
228 167 106 11 20
|
||||
229 179 106 10 20
|
||||
230 190 106 12 20
|
||||
231 203 106 8 20
|
||||
232 212 106 8 20
|
||||
233 221 106 8 20
|
||||
234 230 106 7 20
|
||||
235 238 106 10 20
|
||||
236 1 127 10 20
|
||||
237 12 127 8 20
|
||||
238 21 127 10 20
|
||||
239 32 127 8 20
|
||||
240 41 127 10 20
|
||||
241 52 127 9 20
|
||||
242 62 127 9 20
|
||||
243 72 127 9 20
|
||||
244 82 127 14 20
|
||||
245 97 127 9 20
|
||||
246 107 127 9 20
|
||||
247 117 127 9 20
|
||||
248 127 127 12 20
|
||||
249 140 127 13 20
|
||||
250 154 127 11 20
|
||||
251 166 127 11 20
|
||||
252 178 127 8 20
|
||||
253 187 127 9 20
|
||||
254 197 127 11 20
|
||||
255 209 127 9 20
|
||||
|
||||
File format:
|
||||
bitmapSX bitmapSY
|
||||
numChars
|
||||
chrID0 X Y SX SY
|
||||
chrID1 X Y SX SY
|
||||
...
|
||||
chrIDN X Y SX SY
|
||||
Binary file not shown.
@@ -0,0 +1,204 @@
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Òàéìåðû äëÿ îòñ÷åòà äëèòåëüíîñòåé
|
||||
//
|
||||
// 1. Âðåìÿ èçìåðÿåòñÿ â ìèëèñåêóíäàõ.
|
||||
//
|
||||
// 2. Òàéìåðû:
|
||||
// îòìåðåíèå âðåìåíè
|
||||
// çàäåðæêà ñîáûòèÿ
|
||||
// çàäåðæêà true-óñëîâèÿ ñ "óñðåäíåíèåì"
|
||||
// âûïîëíåíèå â òå÷åíèè óêàçàííîãî âðåìåíè
|
||||
//
|
||||
// 3. Ñáðîñ òàéìåðîâ - stop().
|
||||
//
|
||||
// 4. Òèïû ñèíõðîíèçàöèè (÷åðåç SyncroTimer)
|
||||
// ïî clocki()
|
||||
// ïî frames - ñ óêàçàíèåì îðèåíòèðîâî÷íîãî FPS
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////
|
||||
#ifndef __DURATION_TIMER_H__
|
||||
#define __DURATION_TIMER_H__
|
||||
|
||||
#include "SynchroTimer.h"
|
||||
|
||||
extern SyncroTimer global_time;
|
||||
|
||||
class BaseTimer {
|
||||
protected:
|
||||
time_type start_time;
|
||||
public:
|
||||
BaseTimer() { start_time = 0; }
|
||||
void stop() { start_time = 0; }
|
||||
|
||||
time_type get_start_time() const { return start_time; }
|
||||
};
|
||||
|
||||
// Èçìåðåíèå âðåìåíè
|
||||
class MeasurementTimer : public BaseTimer {
|
||||
public:
|
||||
void start();
|
||||
time_type operator () () const; // Âðåìÿ ñ ìîìåíòà ñòàðòà
|
||||
};
|
||||
|
||||
// Òàéìåð - âûïîëíåíèå â òå÷åíèè óêàçàííîãî âðåìåíè
|
||||
class DurationTimer : public BaseTimer {
|
||||
public:
|
||||
void start(time_type duration);
|
||||
time_type operator () () const; // true: áûë start è íå ïðîøëî âðåìÿ duration, âîçâðàùàåò îñòàòîê âðåìåíè
|
||||
int operator ! () const { return (*this)() ? 0 : 1; }
|
||||
};
|
||||
|
||||
// Òàéìåð - çàäåðæêà ñîáûòèÿ
|
||||
class DelayTimer : public BaseTimer {
|
||||
public:
|
||||
void start(time_type delay);
|
||||
time_type operator () () const; // true: áûë start è ïðîøëî âðåìÿ delay, âîçâðàùàåò âðåìÿ îò êîíöà çàäåðæêè
|
||||
int operator ! () const { return (*this)() ? 0 : 1; }
|
||||
};
|
||||
|
||||
// Òàéìåð - çàäåðæêà true-óñëîâèÿ
|
||||
class DelayConditionTimer : public BaseTimer {
|
||||
public:
|
||||
int operator () (int condition, time_type delay); // true: condition == true âûïîëíèëîñü âðåìÿ delay íàçàä.
|
||||
};
|
||||
|
||||
// Òàéìåð - óñðåäíåíèå true-óñëîâèÿ
|
||||
class AverageConditionTimer : public BaseTimer {
|
||||
public:
|
||||
int operator () (int condition, time_type delay); // true: condition == true âûïîëíÿëîñü âðåìÿ delay.
|
||||
};
|
||||
|
||||
// Òàéìåð - ãèñòåðåçèñ true-óñëîâèÿ
|
||||
class HysteresisConditionTimer : public BaseTimer {
|
||||
int turned_on;
|
||||
public:
|
||||
HysteresisConditionTimer() { turned_on = 0; }
|
||||
// true: condition == true âûïîëíÿëîñü âðåìÿ on_delay, ñêèäûâàåòñÿ, åñëè condition == false âðåìÿ off_delay
|
||||
int operator () (int condition, time_type on_delay, time_type off_delay);
|
||||
int operator () (int condition, time_type delay) { return (*this)(condition, delay, delay); }
|
||||
int operator () () { return turned_on; }
|
||||
};
|
||||
|
||||
class InterpolationTimer : public MeasurementTimer {
|
||||
public:
|
||||
void start(time_type duration);
|
||||
float operator () () const; // [0..1]
|
||||
private:
|
||||
float durationInv_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Inline definitions
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Îòìåðåíèå âðåìåíè
|
||||
inline void MeasurementTimer::start()
|
||||
{
|
||||
start_time = global_time();
|
||||
}
|
||||
inline time_type MeasurementTimer::operator()() const
|
||||
{
|
||||
return start_time ? global_time() - start_time : 0;
|
||||
}
|
||||
|
||||
// Òàéìåð - çàäåðæêà ñîáûòèÿ
|
||||
inline void DelayTimer::start(time_type delay)
|
||||
{
|
||||
start_time = global_time() + delay;
|
||||
}
|
||||
inline time_type DelayTimer::operator () () const
|
||||
{
|
||||
return start_time && global_time() > start_time ? global_time() - start_time : 0;
|
||||
}
|
||||
|
||||
// Òàéìåð - çàäåðæêà true-óñëîâèÿ
|
||||
inline int DelayConditionTimer::operator () (int condition, time_type delay)
|
||||
{
|
||||
if(condition){
|
||||
if(start_time){
|
||||
if(global_time() - start_time >= delay)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
start_time = global_time();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Òàéìåð - óñðåäíåíèå true-óñëîâèÿ
|
||||
inline int AverageConditionTimer::operator () (int condition, time_type delay)
|
||||
{
|
||||
if(condition){
|
||||
if(start_time){
|
||||
if(global_time() - start_time >= delay)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
start_time = global_time();
|
||||
}
|
||||
else
|
||||
start_time = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Òàéìåð - âûïîëíåíèå â òå÷åíèè óêàçàííîãî âðåìåíè
|
||||
inline void DurationTimer::start(time_type duration)
|
||||
{
|
||||
start_time = global_time() + duration;
|
||||
}
|
||||
inline time_type DurationTimer::operator () () const
|
||||
{
|
||||
return start_time > global_time() ? start_time - global_time() : 0;
|
||||
}
|
||||
|
||||
// Òàéìåð - ãèñòåðåçèñ true-óñëîâèÿ
|
||||
inline int HysteresisConditionTimer::operator () (int condition, time_type on_delay, time_type off_delay)
|
||||
{
|
||||
if(turned_on && condition || !turned_on && !condition){
|
||||
start_time = 0;
|
||||
return turned_on;
|
||||
}
|
||||
|
||||
if(!turned_on && condition){
|
||||
if(start_time){
|
||||
if(global_time() - start_time >= on_delay){
|
||||
turned_on = 1;
|
||||
start_time = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
start_time = global_time();
|
||||
}
|
||||
|
||||
if(turned_on && !condition){
|
||||
if(start_time){
|
||||
if(global_time() - start_time >= off_delay){
|
||||
turned_on = 0;
|
||||
start_time = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
start_time = global_time();
|
||||
}
|
||||
|
||||
return turned_on;
|
||||
}
|
||||
|
||||
inline void InterpolationTimer::start(time_type duration)
|
||||
{
|
||||
durationInv_ = 1/(float)duration;
|
||||
MeasurementTimer::start();
|
||||
}
|
||||
|
||||
inline float InterpolationTimer::operator()() const
|
||||
{
|
||||
float t = MeasurementTimer::operator()()*durationInv_;
|
||||
if(t < 1.f)
|
||||
return t;
|
||||
else
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // __DURATION_TIMER_H__
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef __CDCHECK_H__
|
||||
#define __CDCHECK_H__
|
||||
|
||||
#ifndef _DEBUG
|
||||
#define _CDCHECK_
|
||||
#endif
|
||||
|
||||
extern "C" int WINAPI OpenCD(BYTE drive_letter);
|
||||
extern "C" int WINAPI FindCD();
|
||||
extern "C" int WINAPI SetSpeed(BYTE speed);
|
||||
extern "C" int WINAPI ReadCD();
|
||||
extern "C" int WINAPI ReadCD2();
|
||||
extern "C" int WINAPI ReadCheck(int mode);
|
||||
extern "C" int WINAPI RunCheck(char *key);
|
||||
extern "C" int WINAPI CloseCD();
|
||||
|
||||
#endif // __CDCHECK_H__
|
||||
@@ -0,0 +1,64 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "comline_parser.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
comlineParser::comlineParser()
|
||||
{
|
||||
}
|
||||
|
||||
comlineParser::~comlineParser()
|
||||
{
|
||||
}
|
||||
|
||||
bool comlineParser::register_option(const char* name,int id)
|
||||
{
|
||||
options_container_t::const_iterator it = std::find(options_.begin(),options_.end(),name);
|
||||
if(it != options_.end()) return false;
|
||||
|
||||
options_.push_back(comlineOption(name,id));
|
||||
return true;
|
||||
}
|
||||
|
||||
void comlineParser::parse_comline(int argc,char** argv)
|
||||
{
|
||||
arguments_.clear();
|
||||
arguments_.reserve(argc);
|
||||
|
||||
for(int i = 1; i < argc; i++){
|
||||
if(is_option(argv[i])){
|
||||
options_container_t::const_iterator it = std::find(options_.begin(),options_.end(),argv[i] + 1);
|
||||
int id = (it == options_.end()) ? -1 : it -> ID_;
|
||||
|
||||
if(i < argc - 1 && !is_option(argv[i + 1])){
|
||||
arguments_.push_back(comlineArgument(argv[i + 1],id));
|
||||
i++;
|
||||
}
|
||||
else
|
||||
arguments_.push_back(comlineArgument(NULL,id));
|
||||
}
|
||||
else
|
||||
arguments_.push_back(comlineArgument(argv[i],-1));
|
||||
}
|
||||
}
|
||||
|
||||
bool comlineParser::has_argument(int id) const
|
||||
{
|
||||
arguments_container_t::const_iterator it = std::find(arguments_.begin(),arguments_.end(),id);
|
||||
return (it != arguments_.end());
|
||||
}
|
||||
|
||||
const char* comlineParser::argument_string(int id) const
|
||||
{
|
||||
arguments_container_t::const_iterator it = std::find(arguments_.begin(),arguments_.end(),id);
|
||||
if(it != arguments_.end())
|
||||
return it -> data_;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef __COMLINE_PARSER_H__
|
||||
#define __COMLINE_PARSER_H__
|
||||
|
||||
class comlineParser
|
||||
{
|
||||
public:
|
||||
comlineParser();
|
||||
~comlineParser();
|
||||
|
||||
bool register_option(const char* name,int id);
|
||||
|
||||
void parse_comline(int argc,char** argv);
|
||||
|
||||
static bool is_option(const char* arg_str){ if(arg_str[0] == '-' || arg_str[0] == '/') return true; return false; }
|
||||
|
||||
bool has_argument(int id) const;
|
||||
const char* argument_string(int id) const;
|
||||
|
||||
private:
|
||||
|
||||
struct comlineArgument
|
||||
{
|
||||
const char* data_;
|
||||
int optionID_;
|
||||
|
||||
comlineArgument(const char* data,int id) : data_(data), optionID_(id) { }
|
||||
comlineArgument() : data_(NULL), optionID_(-1) { }
|
||||
|
||||
bool operator == (int opt_id) const { return (optionID_ == opt_id); }
|
||||
};
|
||||
|
||||
struct comlineOption
|
||||
{
|
||||
std::string name_;
|
||||
int ID_;
|
||||
|
||||
comlineOption(const char* name,int id) : name_(name), ID_(id) { }
|
||||
|
||||
bool operator == (const char* str) const { if(!str) return false; return !stricmp(name_.c_str(),str); }
|
||||
};
|
||||
|
||||
typedef std::vector<comlineArgument> arguments_container_t;
|
||||
arguments_container_t arguments_;
|
||||
|
||||
typedef std::list<comlineOption> options_container_t;
|
||||
options_container_t options_;
|
||||
};
|
||||
|
||||
#endif /* __COMLINE_PARSER_H__ */
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include <commctrl.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "qd_setup.h"
|
||||
#include "qd_dialog_control.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
bool qdlgOption::load_value() const
|
||||
{
|
||||
char* str = getIniKey(ini_file_.c_str(),ini_section_.c_str(),ini_key_.c_str());
|
||||
if(strlen(str)){
|
||||
set_value(atoi(str));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool qdlgOption::save_value() const
|
||||
{
|
||||
putIniKey(ini_file_.c_str(),ini_section_.c_str(),ini_key_.c_str(),value());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool qdlgOption::enable_control(bool status) const
|
||||
{
|
||||
if(HWND hwnd = GetDlgItem(control_parent(),control_ID())){
|
||||
EnableWindow(hwnd,status);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int qdlgOptionCheckbox::value() const
|
||||
{
|
||||
if(!has_control()) return 0;
|
||||
int check_state = SendDlgItemMessage(control_parent(),control_ID(),BM_GETCHECK,(WPARAM)0,(LPARAM)0);
|
||||
|
||||
if(check_state & BST_CHECKED) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void qdlgOptionCheckbox::set_value(int val) const
|
||||
{
|
||||
if(!has_control()) return;
|
||||
|
||||
int check_state = (val) ? BST_CHECKED : 0;
|
||||
SendDlgItemMessage(control_parent(),control_ID(),BM_SETCHECK,(WPARAM)check_state,(LPARAM)0);
|
||||
}
|
||||
|
||||
int qdlgOptionSlider::value() const
|
||||
{
|
||||
if(!has_control()) return 0;
|
||||
int val = SendDlgItemMessage(control_parent(),control_ID(),TBM_GETPOS,(WPARAM)0,(LPARAM)0);
|
||||
|
||||
if(invert_value_){
|
||||
int val_min = SendDlgItemMessage(control_parent(),control_ID(),TBM_GETRANGEMIN,(WPARAM)0,(LPARAM)0);
|
||||
int val_max = SendDlgItemMessage(control_parent(),control_ID(),TBM_GETRANGEMAX,(WPARAM)0,(LPARAM)0);
|
||||
|
||||
val = val_max - (val - val_min);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void qdlgOptionSlider::set_value(int val) const
|
||||
{
|
||||
if(!has_control()) return;
|
||||
|
||||
if(invert_value_){
|
||||
int val_min = SendDlgItemMessage(control_parent(),control_ID(),TBM_GETRANGEMIN,(WPARAM)0,(LPARAM)0);
|
||||
int val_max = SendDlgItemMessage(control_parent(),control_ID(),TBM_GETRANGEMAX,(WPARAM)0,(LPARAM)0);
|
||||
|
||||
val = val_max - (val - val_min);
|
||||
}
|
||||
|
||||
SendDlgItemMessage(control_parent(),control_ID(),TBM_SETPOS,(WPARAM)TRUE,(LPARAM)val);
|
||||
}
|
||||
|
||||
void qdlgOptionSlider::set_value_range(int min,int max,bool invert_value)
|
||||
{
|
||||
invert_value_ = invert_value;
|
||||
SendDlgItemMessage(control_parent(),control_ID(),TBM_SETRANGE,(WPARAM)TRUE,(LPARAM)MAKELONG(min,max));
|
||||
}
|
||||
|
||||
void qdlgOptionDroplist::init_control() const
|
||||
{
|
||||
int val = value();
|
||||
|
||||
SendDlgItemMessage(control_parent(),control_ID(),CB_RESETCONTENT,(WPARAM)0,(LPARAM)0);
|
||||
|
||||
for(int i = 0; i < items_.size(); i++){
|
||||
if(items_[i].is_enabled())
|
||||
SendDlgItemMessage(control_parent(),control_ID(),CB_ADDSTRING,(WPARAM)0,(LPARAM)items_[i].title());
|
||||
}
|
||||
|
||||
set_value(val);
|
||||
}
|
||||
|
||||
int qdlgOptionDroplist::value() const
|
||||
{
|
||||
if(!has_control()) return default_value();
|
||||
|
||||
int val = SendDlgItemMessage(control_parent(),control_ID(),CB_GETCURSEL,(WPARAM)0,(LPARAM)0);
|
||||
if(val == CB_ERR) return default_value();
|
||||
|
||||
return items_[val].value();
|
||||
}
|
||||
|
||||
void qdlgOptionDroplist::set_value(int val) const
|
||||
{
|
||||
if(!has_control()) return;
|
||||
|
||||
int idx = 0;
|
||||
for(item_container_t::const_iterator it = items_.begin(); it != items_.end(); ++it){
|
||||
if(it -> value() == val){
|
||||
SendDlgItemMessage(control_parent(),control_ID(),CB_SETCURSEL,(WPARAM)idx,(LPARAM)0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(it -> is_enabled())
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
void qdlgOptionDroplist::add_item(const char* title,int value)
|
||||
{
|
||||
items_.push_back(qdlgDroplistItem(title,value));
|
||||
}
|
||||
|
||||
bool qdlgOptionDroplist::enable_item(int value)
|
||||
{
|
||||
item_container_t::iterator it = std::find(items_.begin(),items_.end(),value);
|
||||
if(it != items_.end()){
|
||||
it -> enable();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool qdlgOptionDroplist::disable_item(int value)
|
||||
{
|
||||
item_container_t::iterator it = std::find(items_.begin(),items_.end(),value);
|
||||
if(it != items_.end()){
|
||||
it -> disable();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool qdlgOptionDroplist::is_value_enabled(int value) const
|
||||
{
|
||||
item_container_t::const_iterator it = std::find(items_.begin(),items_.end(),value);
|
||||
if(it != items_.end())
|
||||
return it -> is_enabled();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int qdlgOptionDroplist::default_value() const
|
||||
{
|
||||
for(int i = 0; i < items_.size(); i++){
|
||||
if(items_[i].is_enabled())
|
||||
return items_[i].value();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
#ifndef __QD_DIALOG_CONTROL_H__
|
||||
#define __QD_DIALOG_CONTROL_H__
|
||||
|
||||
class qdlgOption
|
||||
{
|
||||
public:
|
||||
qdlgOption() : control_ID_(-1), control_parent_(NULL) { }
|
||||
|
||||
void set_control(HWND ctl_parent,int ctl_id){ control_parent_ = ctl_parent; control_ID_ = ctl_id; }
|
||||
void set_ini_key(const char* ini_file,const char* ini_section,const char* ini_key){ ini_file_ = ini_file; ini_section_ = ini_section; ini_key_ = ini_key; }
|
||||
|
||||
bool enable_control(bool status = true) const;
|
||||
|
||||
int control_ID() const { return control_ID_; }
|
||||
HWND control_parent() const { return control_parent_; }
|
||||
bool has_control() const { if(control_ID_ == -1 || !control_parent_) return false; return true; }
|
||||
|
||||
virtual int value() const = 0;
|
||||
virtual void set_value(int val) const = 0;
|
||||
|
||||
bool load_value() const;
|
||||
bool save_value() const;
|
||||
|
||||
private:
|
||||
|
||||
int control_ID_;
|
||||
HWND control_parent_;
|
||||
|
||||
std::string ini_file_;
|
||||
std::string ini_section_;
|
||||
std::string ini_key_;
|
||||
};
|
||||
|
||||
class qdlgOptionSlider : public qdlgOption
|
||||
{
|
||||
public:
|
||||
int value() const;
|
||||
void set_value(int val) const;
|
||||
|
||||
void set_value_range(int min,int max,bool invert_value = false);
|
||||
|
||||
private:
|
||||
|
||||
bool invert_value_;
|
||||
};
|
||||
|
||||
class qdlgOptionCheckbox : public qdlgOption
|
||||
{
|
||||
public:
|
||||
int value() const;
|
||||
void set_value(int val) const;
|
||||
};
|
||||
|
||||
class qdlgOptionDroplist : public qdlgOption
|
||||
{
|
||||
public:
|
||||
qdlgOptionDroplist(){ }
|
||||
|
||||
void init_control() const;
|
||||
|
||||
int value() const;
|
||||
void set_value(int val) const;
|
||||
|
||||
void add_item(const char* title,int value);
|
||||
bool enable_item(int value);
|
||||
bool disable_item(int value);
|
||||
bool is_value_enabled(int value) const;
|
||||
|
||||
private:
|
||||
class qdlgDroplistItem
|
||||
{
|
||||
public:
|
||||
qdlgDroplistItem(const char* title,int value) : title_(title), value_(value), is_enabled_(true) { }
|
||||
|
||||
bool operator == (int val) const { return (value_ == val); }
|
||||
|
||||
const char* title() const { return title_.c_str(); }
|
||||
int value() const { return value_; }
|
||||
|
||||
bool is_enabled() const { return is_enabled_; }
|
||||
void enable(){ is_enabled_ = true; }
|
||||
void disable(){ is_enabled_ = false; }
|
||||
|
||||
private:
|
||||
|
||||
std::string title_;
|
||||
int value_;
|
||||
|
||||
bool is_enabled_;
|
||||
};
|
||||
|
||||
typedef std::vector<qdlgDroplistItem> item_container_t;
|
||||
item_container_t items_;
|
||||
|
||||
int default_value() const;
|
||||
};
|
||||
|
||||
#endif /* __QD_DIALOG_CONTROL_H__ */
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
#include "qd_dialogs.h"
|
||||
#include "qd_dialog_control.h"
|
||||
|
||||
#include "ddraw_gr_dispatcher.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
|
||||
namespace qdrt {
|
||||
extern DDraw_grDispatcher* dd_grD;
|
||||
};
|
||||
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
|
||||
namespace qdlg {
|
||||
|
||||
BOOL APIENTRY settings_dlgproc(HWND hdlg,UINT msg,WPARAM wParam,LPARAM lParam);
|
||||
void settings_dialog_init(HWND hdlg);
|
||||
void settings_dialog_finit();
|
||||
|
||||
qdlgOption* find_option(int ctl_id);
|
||||
|
||||
void update_color_option();
|
||||
|
||||
}; // namespace qdlg
|
||||
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
namespace qdlg {
|
||||
|
||||
typedef std::list<qdlgOption*> options_container_t;
|
||||
options_container_t options_;
|
||||
|
||||
void set_icon(void* hwnd)
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
HICON ic = (HICON)LoadImage(NULL,"qd_game.ico",IMAGE_ICON,0,0,LR_DEFAULTCOLOR | LR_LOADFROMFILE);
|
||||
|
||||
if(!ic)
|
||||
ic = (HICON)LoadImage(GetModuleHandle(0),MAKEINTRESOURCE(IDI_APP),IMAGE_ICON,0,0,LR_DEFAULTCOLOR);
|
||||
|
||||
if(ic){
|
||||
SendMessage((HWND)hwnd,WM_SETICON,(WPARAM)ICON_BIG,(LPARAM)ic);
|
||||
SendMessage((HWND)hwnd,WM_SETICON,(WPARAM)ICON_SMALL,(LPARAM)ic);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void settings_dialog()
|
||||
{
|
||||
InitCommonControls();
|
||||
DialogBox(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_SETTINGS),NULL,settings_dlgproc);
|
||||
}
|
||||
|
||||
BOOL APIENTRY settings_dlgproc(HWND hdlg,UINT msg,WPARAM wParam,LPARAM lParam)
|
||||
{
|
||||
int ctl_id;
|
||||
|
||||
switch(msg){
|
||||
case WM_INITDIALOG:
|
||||
settings_dialog_init(hdlg);
|
||||
return 1;
|
||||
case WM_COMMAND:
|
||||
ctl_id = LOWORD(wParam);
|
||||
switch(ctl_id){
|
||||
case IDOK:
|
||||
settings_dialog_finit();
|
||||
EndDialog(hdlg,1);
|
||||
return 1;
|
||||
case IDCANCEL:
|
||||
EndDialog(hdlg,0);
|
||||
return 1;
|
||||
case IDC_FULLSCREEN:
|
||||
update_color_option();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void settings_dialog_init(HWND hdlg)
|
||||
{
|
||||
set_icon(hdlg);
|
||||
|
||||
qdlgOption* p = new qdlgOptionDroplist;
|
||||
p -> set_control(hdlg,IDC_COLOR_DEPTH);
|
||||
p -> set_ini_key("qd_game.ini","graphics","color_depth");
|
||||
|
||||
qdlgOptionDroplist* dp = static_cast<qdlgOptionDroplist*>(p);
|
||||
dp -> add_item("High Color (16bit)",0);
|
||||
dp -> add_item("High Color (16bit)",1);
|
||||
dp -> add_item("True Color (24bit)",2);
|
||||
dp -> add_item("True Color (32bit)",3);
|
||||
dp -> init_control();
|
||||
|
||||
options_.push_back(p);
|
||||
|
||||
p = new qdlgOptionCheckbox;
|
||||
p -> set_control(hdlg,IDC_FULLSCREEN);
|
||||
p -> set_ini_key("qd_game.ini","graphics","fullscreen");
|
||||
options_.push_back(p);
|
||||
|
||||
p = new qdlgOptionCheckbox;
|
||||
p -> set_control(hdlg,IDC_SOUND);
|
||||
p -> set_ini_key("qd_game.ini","sound","enable_sound");
|
||||
options_.push_back(p);
|
||||
|
||||
p = new qdlgOptionCheckbox;
|
||||
p -> set_control(hdlg,IDC_MUSIC);
|
||||
p -> set_ini_key("qd_game.ini","sound","enable_music");
|
||||
options_.push_back(p);
|
||||
|
||||
qdlgOptionSlider* sp = new qdlgOptionSlider;
|
||||
sp -> set_control(hdlg,IDC_SOUND_VOLUME);
|
||||
sp -> set_value_range(0,255,true);
|
||||
sp -> set_ini_key("qd_game.ini","sound","sound_volume");
|
||||
options_.push_back(sp);
|
||||
|
||||
sp = new qdlgOptionSlider;
|
||||
sp -> set_control(hdlg,IDC_MUSIC_VOLUME);
|
||||
sp -> set_value_range(0,255,true);
|
||||
sp -> set_ini_key("qd_game.ini","sound","music_volume");
|
||||
options_.push_back(sp);
|
||||
|
||||
SendDlgItemMessage(hdlg,IDC_SOUND_VOLUME,TBM_SETTICFREQ,(WPARAM)32,(LPARAM)0);
|
||||
SendDlgItemMessage(hdlg,IDC_MUSIC_VOLUME,TBM_SETTICFREQ,(WPARAM)32,(LPARAM)0);
|
||||
|
||||
for(options_container_t::const_iterator it = options_.begin(); it != options_.end(); ++it)
|
||||
(*it) -> load_value();
|
||||
|
||||
update_color_option();
|
||||
}
|
||||
|
||||
void settings_dialog_finit()
|
||||
{
|
||||
for(options_container_t::const_iterator it = options_.begin(); it != options_.end(); ++it)
|
||||
(*it) -> save_value();
|
||||
}
|
||||
|
||||
void update_color_option()
|
||||
{
|
||||
qdlgOption* sp = find_option(IDC_FULLSCREEN);
|
||||
if(!sp) return;
|
||||
|
||||
qdlgOptionDroplist* dp = dynamic_cast<qdlgOptionDroplist*>(find_option(IDC_COLOR_DEPTH));
|
||||
if(!dp) return;
|
||||
|
||||
for(int i = 0; i < 4; i++){
|
||||
if(qdrt::dd_grD -> is_mode_supported(grPixelFormat(i)))
|
||||
dp -> enable_item(i);
|
||||
else
|
||||
dp -> disable_item(i);
|
||||
}
|
||||
|
||||
dp -> init_control();
|
||||
if(!sp -> value()){
|
||||
dp -> enable_control(false);
|
||||
|
||||
int sx,sy;
|
||||
grPixelFormat pixel_format;
|
||||
if(qdrt::dd_grD->get_current_mode(sx,sy,pixel_format))
|
||||
dp -> set_value(pixel_format);
|
||||
}
|
||||
else
|
||||
dp -> enable_control(true);
|
||||
}
|
||||
|
||||
qdlgOption* find_option(int ctl_id)
|
||||
{
|
||||
for(options_container_t::iterator it = options_.begin(); it != options_.end(); ++it){
|
||||
if((*it) -> control_ID() == ctl_id)
|
||||
return *it;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}; // namespace qdlg
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef __QD_DIALOGS_H__
|
||||
#define __QD_DIALOGS_H__
|
||||
|
||||
namespace qdlg {
|
||||
|
||||
void set_icon(void* hwnd);
|
||||
void settings_dialog();
|
||||
|
||||
}; // namespace qdlg
|
||||
|
||||
#endif /* __QD_DIALOGS_H__ */
|
||||
@@ -0,0 +1,484 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
#include "gdi_gr_dispatcher.h"
|
||||
#include "ddraw_gr_dispatcher.h"
|
||||
#include "app_core.h"
|
||||
#include "app_error_handler.h"
|
||||
#include "qd_game_dispatcher.h"
|
||||
#include "qd_game_scene.h"
|
||||
#include "qd_trigger_chain.h"
|
||||
#include "qd_dialogs.h"
|
||||
#include "qd_setup.h"
|
||||
#include "ds_snd_dispatcher.h"
|
||||
#include "WinVideo.h"
|
||||
#include "qd_trigger_profiler.h"
|
||||
#include "qd_file_manager.h"
|
||||
#include "plaympp_api.h"
|
||||
|
||||
#include "input_wndproc.h"
|
||||
#include "input_recorder.h"
|
||||
#include "mouse_input.h"
|
||||
#include "keyboard_input.h"
|
||||
|
||||
#include "qd_dialogs.h"
|
||||
#include "splash_screen.h"
|
||||
|
||||
#include "ResourceDispatcher.h"
|
||||
|
||||
#include "comline_parser.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
|
||||
namespace qdrt {
|
||||
|
||||
void init_graphics();
|
||||
bool init_graphics_dispatcher();
|
||||
bool is_graphics_reinit_needed();
|
||||
void restore_graphics();
|
||||
|
||||
void toggle_fullscreen(bool force_fullscreen = false);
|
||||
void maximize_window(){ toggle_fullscreen(true); }
|
||||
|
||||
void qd_show_load_progress(int percents_loaded,void* p);
|
||||
|
||||
void restore();
|
||||
|
||||
bool request_CD_handler(int cd_id);
|
||||
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
//! Êîìàíäíàÿ ñòðîêà
|
||||
enum {
|
||||
COMLINE_SCENE_NAME,
|
||||
COMLINE_ENABLE_LOG,
|
||||
COMLINE_SETTINGS,
|
||||
COMLINE_RECORDER_WRITE,
|
||||
COMLINE_RECORDER_PLAY,
|
||||
COMLINE_TRIGGERS_DEBUG,
|
||||
COMLINE_TRIGGERS_PROFILER
|
||||
};
|
||||
|
||||
GDI_grDispatcher* gdi_grD = NULL;
|
||||
DDraw_grDispatcher* dd_grD = NULL;
|
||||
|
||||
HWND hmainWnd;
|
||||
|
||||
qdGameDispatcher* qd_gameD = NULL;
|
||||
|
||||
}; // namespace qdrt
|
||||
|
||||
using namespace qdrt;
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdLine, int nCmdShow)
|
||||
{
|
||||
const char* const event_name = "QD Engine Game";
|
||||
if(HANDLE event = OpenEvent(EVENT_ALL_ACCESS,FALSE,event_name)){
|
||||
if(HWND hwnd = FindWindow(grDispatcher::wnd_class_name(),NULL)){
|
||||
ShowWindow(hwnd,SW_RESTORE);
|
||||
BringWindowToTop(hwnd);
|
||||
SetForegroundWindow(hwnd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
event = CreateEvent(0,TRUE,TRUE,event_name);
|
||||
|
||||
ErrH.SetRestore(restore);
|
||||
|
||||
comlineParser comline_parser;
|
||||
comline_parser.register_option("s",COMLINE_SCENE_NAME);
|
||||
comline_parser.register_option("log",COMLINE_ENABLE_LOG);
|
||||
comline_parser.register_option("settings",COMLINE_SETTINGS);
|
||||
|
||||
comline_parser.register_option(inputRecorder::write_comline(),COMLINE_RECORDER_WRITE);
|
||||
comline_parser.register_option(inputRecorder::play_comline(),COMLINE_RECORDER_PLAY);
|
||||
|
||||
#ifdef __QD_DEBUG_ENABLE__
|
||||
comline_parser.register_option(qdTriggerChain::debug_comline(),COMLINE_TRIGGERS_DEBUG);
|
||||
#endif
|
||||
|
||||
#ifdef __QD_TRIGGER_PROFILER__
|
||||
comline_parser.register_option(qdTriggerProfiler::activation_comline(),COMLINE_TRIGGERS_PROFILER);
|
||||
#endif
|
||||
|
||||
comline_parser.parse_comline(__argc,__argv);
|
||||
|
||||
std::string script_name;
|
||||
if(comline_parser.has_argument(-1))
|
||||
script_name = comline_parser.argument_string(-1);
|
||||
|
||||
if(script_name.empty()){
|
||||
if(char* p = XFindFirst("*.qml"))
|
||||
script_name = p;
|
||||
|
||||
if(script_name.empty()) return 0;
|
||||
}
|
||||
|
||||
app_io::set_current_directory(script_name.c_str());
|
||||
|
||||
grDispatcher::sys_init();
|
||||
|
||||
gdi_grD = new GDI_grDispatcher;
|
||||
dd_grD = new DDraw_grDispatcher;
|
||||
|
||||
if(comline_parser.has_argument(COMLINE_SETTINGS)){
|
||||
qdlg::settings_dialog();
|
||||
|
||||
delete gdi_grD;
|
||||
delete dd_grD;
|
||||
|
||||
grDispatcher::sys_finit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __QD_DEBUG_ENABLE__
|
||||
if(comline_parser.has_argument(COMLINE_TRIGGERS_DEBUG))
|
||||
qdGameConfig::get_config().toggle_triggers_debug(true);
|
||||
#endif
|
||||
|
||||
#ifdef __QD_TRIGGER_PROFILER__
|
||||
if(comline_parser.has_argument(COMLINE_TRIGGERS_PROFILER))
|
||||
qdTriggerProfiler::instance().enable();
|
||||
#endif
|
||||
|
||||
if(const char* rec_name = comline_parser.argument_string(COMLINE_RECORDER_WRITE))
|
||||
inputRecorder::instance().open(rec_name,inputRecorder::RECORDER_WRITE);
|
||||
else if(rec_name = comline_parser.argument_string(COMLINE_RECORDER_PLAY))
|
||||
inputRecorder::instance().open(rec_name,inputRecorder::RECORDER_PLAY);
|
||||
|
||||
gdi_grD -> set_maximize_handler(maximize_window);
|
||||
dd_grD -> set_maximize_handler(maximize_window);
|
||||
|
||||
gdi_grD -> HideMouse();
|
||||
dd_grD -> HideMouse();
|
||||
|
||||
qdGameConfig::get_config().load();
|
||||
setlocale(LC_CTYPE, qdGameConfig::get_config().locale());
|
||||
|
||||
#ifdef __QD_TRIGGER_PROFILER__
|
||||
if(qdGameConfig::get_config().is_profiler_enabled())
|
||||
qdTriggerProfiler::instance().enable();
|
||||
if (0 != strlen(qdGameConfig::get_config().profiler_file()))
|
||||
qdTriggerProfiler::instance().set_work_file(qdGameConfig::get_config().profiler_file());
|
||||
#endif
|
||||
|
||||
if(qdGameConfig::get_config().driver_ID()){
|
||||
if(!qdGameConfig::get_config().fullscreen()){
|
||||
int sx,sy;
|
||||
grPixelFormat pixel_format;
|
||||
dd_grD -> get_current_mode(sx,sy,pixel_format);
|
||||
|
||||
qdGameConfig::get_config().set_pixel_format(pixel_format);
|
||||
}
|
||||
else
|
||||
qdGameConfig::get_config().set_pixel_format(dd_grD -> adjust_mode((grPixelFormat)qdGameConfig::get_config().pixel_format()));
|
||||
}
|
||||
|
||||
SplashScreen sp;
|
||||
if(qdGameConfig::get_config().is_splash_enabled()){
|
||||
sp.create(IDB_SPLASH);
|
||||
sp.set_mask(IDB_SPLASH_MASK);
|
||||
sp.show();
|
||||
}
|
||||
|
||||
SetErrorMode(SEM_FAILCRITICALERRORS);
|
||||
|
||||
// qdFileManager::instance().check_drive('E');
|
||||
qdFileManager::instance().set_request_CD_handler(request_CD_handler);
|
||||
|
||||
for(int i = 1; i < __argc; i ++)
|
||||
appLog::default_log() << " \"" << __argv[i] << "\"";
|
||||
appLog::default_log() << "\r\n";
|
||||
|
||||
grDispatcher::set_default_font(qdGameDispatcher::create_font(0));
|
||||
|
||||
qd_gameD = new qdGameDispatcher;
|
||||
qd_gameD -> load_script(app_io::strip_path(script_name.c_str()));
|
||||
|
||||
qd_gameD -> set_scene_loading_progress_callback(qd_show_load_progress);
|
||||
|
||||
if(qdGameConfig::get_config().is_splash_enabled()){
|
||||
sp.wait(qdGameConfig::get_config().splash_time());
|
||||
sp.destroy();
|
||||
}
|
||||
|
||||
init_graphics();
|
||||
|
||||
ds_sndDispatcher* sndD = new ds_sndDispatcher;
|
||||
|
||||
qdGameConfig::get_config().update_sound_settings();
|
||||
qdGameConfig::get_config().update_music_settings();
|
||||
|
||||
winVideo::init();
|
||||
|
||||
qd_gameD -> load_resources();
|
||||
|
||||
if(const char* scene_name = comline_parser.argument_string(COMLINE_SCENE_NAME)){
|
||||
if(!qd_gameD -> select_scene(scene_name)) app_errH.show_error("Ñòàðòîâàÿ ñöåíà íå íàéäåíà",appErrorHandler::ERR_OTHER);
|
||||
}
|
||||
else {
|
||||
bool music_enabled = mpegPlayer::instance().is_enabled();
|
||||
mpegPlayer::instance().disable();
|
||||
|
||||
qd_gameD -> toggle_main_menu(true);
|
||||
if(!qd_gameD -> start_intro_videos()){
|
||||
if(music_enabled)
|
||||
mpegPlayer::instance().enable(true);
|
||||
}
|
||||
else {
|
||||
if(music_enabled)
|
||||
mpegPlayer::instance().enable(false);
|
||||
}
|
||||
}
|
||||
|
||||
qd_gameD -> update_time();
|
||||
qd_gameD -> quant();
|
||||
|
||||
ResourceDispatcher resD;
|
||||
resD.setTimer(qdGameConfig::get_config().logic_synchro_by_clock(),qdGameConfig::get_config().logic_period(),300);
|
||||
resD.attach(new MemberFunctionCallResourceUser<qdGameDispatcher>(*qd_gameD,qdGameDispatcher::quant,qdGameConfig::get_config().logic_period()));
|
||||
sndD -> set_frequency_coeff(qdGameConfig::get_config().game_speed());
|
||||
resD.set_speed(qdGameConfig::get_config().game_speed());
|
||||
resD.start();
|
||||
|
||||
MSG msg;
|
||||
bool exit_flag = false;
|
||||
bool was_inactive = false;
|
||||
|
||||
while(!exit_flag && !qd_gameD -> need_exit()){
|
||||
while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
|
||||
switch(msg.message){
|
||||
case WM_QUIT:
|
||||
if(!grDispatcher::instance() -> is_in_reinit_mode())
|
||||
exit_flag = true;
|
||||
break;
|
||||
case WM_SYSCOMMAND:
|
||||
if(msg.wParam == SC_MAXIMIZE)
|
||||
toggle_fullscreen(true);
|
||||
break;
|
||||
case WM_SYSKEYDOWN:
|
||||
if(msg.wParam == VK_RETURN && msg.lParam & (1 << 29))
|
||||
toggle_fullscreen();
|
||||
break;
|
||||
case WM_KEYDOWN:
|
||||
if(msg.wParam == 'F')
|
||||
qdGameConfig::get_config().toggle_fps();
|
||||
#ifdef __QD_DEBUG_ENABLE__
|
||||
else if(msg.wParam == VK_NEXT){
|
||||
float speed = qdGameConfig::get_config().game_speed() * 0.9f;
|
||||
if(speed < 0.1f) speed = 0.1f;
|
||||
qdGameConfig::get_config().set_game_speed(speed);
|
||||
sndD -> set_frequency_coeff(speed);
|
||||
resD.set_speed(qdGameConfig::get_config().game_speed());
|
||||
}
|
||||
else if(msg.wParam == VK_PRIOR){
|
||||
float speed = qdGameConfig::get_config().game_speed() * 1.1f;
|
||||
if(speed > 10.0f) speed = 10.0f;
|
||||
qdGameConfig::get_config().set_game_speed(speed);
|
||||
sndD -> set_frequency_coeff(speed);
|
||||
resD.set_speed(qdGameConfig::get_config().game_speed());
|
||||
}
|
||||
else if(msg.wParam == VK_HOME){
|
||||
qdGameConfig::get_config().set_game_speed(1.0f);
|
||||
sndD -> set_frequency_coeff(1.0f);
|
||||
resD.set_speed(qdGameConfig::get_config().game_speed());
|
||||
}
|
||||
else if(msg.wParam == 'G')
|
||||
qdGameConfig::get_config().toggle_show_grid();
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
input::keyboard_wndproc(msg,keyboardDispatcher::instance());
|
||||
input::mouse_wndproc(msg,mouseDispatcher::instance());
|
||||
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
if(grDispatcher::is_active()){
|
||||
if (was_inactive)
|
||||
{
|
||||
was_inactive = false;
|
||||
// Ïðè àêòèâàöèè æäåì, ÷òîáû çâóêîâîâàÿ ñèñòåìà óñïåëà íàñòðîèòüñÿ
|
||||
// íà íàøå ïðèëîæåíèå (ïðåäïîëîæåíèå)
|
||||
Sleep(500);
|
||||
}
|
||||
resD.quant();
|
||||
qd_gameD -> redraw();
|
||||
|
||||
}
|
||||
else {
|
||||
was_inactive = true;
|
||||
Sleep(100);
|
||||
resD.skip_time();
|
||||
}
|
||||
}
|
||||
|
||||
delete qd_gameD;
|
||||
|
||||
grDispatcher::instance() -> Finit();
|
||||
|
||||
ShowWindow(hmainWnd,SW_HIDE);
|
||||
CloseWindow(hmainWnd);
|
||||
DestroyWindow(hmainWnd);
|
||||
|
||||
delete sndD;
|
||||
delete gdi_grD;
|
||||
delete dd_grD;
|
||||
|
||||
winVideo::done();
|
||||
|
||||
grDispatcher::sys_finit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace qdrt {
|
||||
|
||||
void init_graphics()
|
||||
{
|
||||
grDispatcher::set_restore_handler(restore_graphics);
|
||||
grDispatcher::instance() -> Finit();
|
||||
|
||||
if(!qdGameConfig::get_config().driver_ID())
|
||||
grDispatcher::set_instance(gdi_grD);
|
||||
else
|
||||
grDispatcher::set_instance(dd_grD);
|
||||
|
||||
|
||||
if(!init_graphics_dispatcher())
|
||||
app_errH.show_error("Îøèáêà èíèöèàëèçàöèè ãðàôèêè",appErrorHandler::ERR_OTHER);
|
||||
|
||||
grDispatcher::instance() -> resize_window();
|
||||
|
||||
hmainWnd = (HWND)grDispatcher::instance() -> Get_hWnd();
|
||||
qdGameConfig::get_config().set_pixel_format(grDispatcher::instance() -> pixel_format());
|
||||
|
||||
qdGameConfig::get_config().save();
|
||||
|
||||
qdlg::set_icon(hmainWnd);
|
||||
appSetHandle(hmainWnd);
|
||||
|
||||
SendMessage(hmainWnd,WM_SETTEXT,(WPARAM)0,(LPARAM)qd_gameD -> game_title());
|
||||
|
||||
grDispatcher::instance() -> SetClip();
|
||||
grDispatcher::instance() -> SetClipMode(1);
|
||||
grDispatcher::instance() -> Fill(0);
|
||||
|
||||
if(grDispatcher::instance() -> is_in_fullscreen_mode())
|
||||
ShowWindow(hmainWnd,SW_SHOWMAXIMIZED);
|
||||
else
|
||||
ShowWindow(hmainWnd,SW_SHOWNORMAL);
|
||||
|
||||
UpdateWindow(hmainWnd);
|
||||
|
||||
grDispatcher::instance() -> Flush();
|
||||
}
|
||||
|
||||
bool init_graphics_dispatcher()
|
||||
{
|
||||
if(grDispatcher::instance() -> init(qdGameConfig::get_config().screen_sx(),qdGameConfig::get_config().screen_sy(),(grPixelFormat)qdGameConfig::get_config().pixel_format(),hmainWnd,qdGameConfig::get_config().fullscreen()))
|
||||
return true;
|
||||
|
||||
for(int i = 0; i <= GR_ARGB8888; i++){
|
||||
if(grDispatcher::instance() -> init(qdGameConfig::get_config().screen_sx(),qdGameConfig::get_config().screen_sy(),(grPixelFormat)i,hmainWnd,qdGameConfig::get_config().fullscreen()))
|
||||
return true;
|
||||
}
|
||||
|
||||
qdGameConfig::get_config().toggle_fullscreen();
|
||||
|
||||
for(int i = 0; i <= GR_ARGB8888; i++){
|
||||
if(grDispatcher::instance() -> init(qdGameConfig::get_config().screen_sx(),qdGameConfig::get_config().screen_sy(),(grPixelFormat)i,hmainWnd,qdGameConfig::get_config().fullscreen()))
|
||||
return true;
|
||||
}
|
||||
|
||||
grDispatcher::set_instance(dd_grD);
|
||||
if(grDispatcher::instance() -> init(qdGameConfig::get_config().screen_sx(),qdGameConfig::get_config().screen_sy(),(grPixelFormat)qdGameConfig::get_config().pixel_format(),hmainWnd,qdGameConfig::get_config().fullscreen()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void qd_show_load_progress(int percents_loaded,void* p)
|
||||
{
|
||||
const int rect_sx = 200;
|
||||
const int rect_sy = 10;
|
||||
|
||||
int sx = rect_sx * percents_loaded / 100;
|
||||
if(sx < 0) sx = 0;
|
||||
if(sx > rect_sx) sx = rect_sx;
|
||||
|
||||
int x = 10;
|
||||
int y = grDispatcher::instance() -> Get_SizeY() - rect_sy - 10;
|
||||
|
||||
grDispatcher::instance() -> Rectangle(x,y,rect_sx,rect_sy,0xFFFFFF,0,GR_OUTLINED);
|
||||
grDispatcher::instance() -> Rectangle(x,y,sx,rect_sy,0xFFFFFF,0xFFFFFF,GR_FILLED);
|
||||
grDispatcher::instance() -> Flush(x,y,rect_sx,rect_sy);
|
||||
}
|
||||
|
||||
bool is_graphics_reinit_needed()
|
||||
{
|
||||
if(qdGameConfig::get_config().pixel_format() != (int)grDispatcher::instance() -> pixel_format() || qdGameConfig::get_config().fullscreen() != grDispatcher::instance() -> is_in_fullscreen_mode())
|
||||
return true;
|
||||
|
||||
if(qdGameConfig::get_config().driver_ID() && grDispatcher::instance() == gdi_grD)
|
||||
return true;
|
||||
|
||||
if(!qdGameConfig::get_config().driver_ID() && grDispatcher::instance() == dd_grD)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void restore_graphics()
|
||||
{
|
||||
if(sndDispatcher* dp = sndDispatcher::get_dispatcher())
|
||||
dp -> set_volume(dp -> volume());
|
||||
|
||||
if(qdGameDispatcher* dp = qdGameDispatcher::get_dispatcher())
|
||||
dp -> set_flag(qdGameDispatcher::FULLSCREEN_REDRAW_FLAG);
|
||||
}
|
||||
|
||||
void restore()
|
||||
{
|
||||
int dummy = 0;
|
||||
}
|
||||
|
||||
void toggle_fullscreen(bool force_fullscreen)
|
||||
{
|
||||
if(force_fullscreen && qdGameConfig::get_config().fullscreen()) return;
|
||||
|
||||
qdGameConfig::get_config().toggle_fullscreen();
|
||||
qdGameConfig::get_config().set_driver_ID(1);
|
||||
|
||||
grDispatcher::instance() -> toggle_reinit();
|
||||
grDispatcher::instance() -> Finit();
|
||||
grDispatcher::instance() -> destroy_window();
|
||||
|
||||
hmainWnd = NULL;
|
||||
|
||||
init_graphics();
|
||||
|
||||
qdGameDispatcher::get_dispatcher() -> toggle_full_redraw();
|
||||
// qdGameDispatcher::get_dispatcher() -> convert_graphics();
|
||||
}
|
||||
|
||||
bool request_CD_handler(int cd_id)
|
||||
{
|
||||
if(qdGameDispatcher* p = qdGameDispatcher::get_dispatcher())
|
||||
p -> request_CD(cd_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // namespace main
|
||||
@@ -0,0 +1,286 @@
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "gr_dispatcher.h"
|
||||
#include "UI_TextParser.h"
|
||||
|
||||
UI_TextParser::UI_TextParser(const grFont* font) : font_(font)
|
||||
{
|
||||
outNodes_.reserve(8);
|
||||
init();
|
||||
}
|
||||
|
||||
UI_TextParser::UI_TextParser(const UI_TextParser& src)
|
||||
{
|
||||
(*this) = src;
|
||||
}
|
||||
|
||||
void UI_TextParser::operator= (const UI_TextParser& src)
|
||||
{
|
||||
font_ = src.font_;
|
||||
|
||||
outNodes_.reserve(8);
|
||||
init();
|
||||
}
|
||||
|
||||
void UI_TextParser::init()
|
||||
{
|
||||
tagWidth_ = 0;
|
||||
lineWidth_ = 0;
|
||||
|
||||
lineBegin_ = 0;
|
||||
pstr_ = 0;
|
||||
|
||||
fitIn_ = -1;
|
||||
lastSpace_ = 0;
|
||||
lastTagWidth_ = 0;
|
||||
|
||||
outNodes_.clear();
|
||||
outNodes_.push_back(OutNode());
|
||||
prevLineIndex_ = outNodes_.size() - 1;
|
||||
|
||||
size_.set(0, fontHeight());
|
||||
|
||||
lineCount_ = 1;
|
||||
}
|
||||
|
||||
void UI_TextParser::setFont(const grFont* font)
|
||||
{
|
||||
font_ = font;
|
||||
init();
|
||||
}
|
||||
|
||||
OutNodes::const_iterator UI_TextParser::getLineBegin(int lineNum) const
|
||||
{
|
||||
dassert(lineNum >= 0);
|
||||
|
||||
if(!lineNum)
|
||||
return outNodes_.begin();
|
||||
|
||||
if(lineNum >= lineCount_)
|
||||
return outNodes_.end();
|
||||
|
||||
OutNodes::const_iterator it;
|
||||
FOR_EACH(outNodes_, it)
|
||||
if(it->type == OutNode::NEW_LINE)
|
||||
if(lineNum-- == 0)
|
||||
return it;
|
||||
|
||||
xassert(lineNum == 0);
|
||||
return outNodes_.end();
|
||||
}
|
||||
|
||||
bool UI_TextParser::testWidth(int width)
|
||||
{
|
||||
if(fitIn_ < 0)
|
||||
return true;
|
||||
|
||||
if(lineWidth_ + tagWidth_ + width > fitIn_){
|
||||
if(lastSpace_ != lineBegin_){
|
||||
outNodes_.push_back(OutNode(lineBegin_, lastSpace_, lastTagWidth_));
|
||||
|
||||
lineWidth_ += lastTagWidth_;
|
||||
endLine();
|
||||
|
||||
lineBegin_ = lastSpace_ + 1;
|
||||
lastSpace_ = lineBegin_;
|
||||
tagWidth_ -= lastTagWidth_;
|
||||
lastTagWidth_ = 0;
|
||||
}
|
||||
else if(lineWidth_ > 0){
|
||||
dassert(lastTagWidth_ == 0);
|
||||
endLine();
|
||||
testWidth(width);
|
||||
}
|
||||
else if(tagWidth_ > 0){
|
||||
putText();
|
||||
endLine();
|
||||
skipNode();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void UI_TextParser::parseString(const char* text, int color, int fitIn)
|
||||
{
|
||||
if(!font_)
|
||||
setFont(grDispatcher::get_default_font());
|
||||
|
||||
xassert(font_);
|
||||
init();
|
||||
|
||||
fitIn_ = fitIn > 2 * fontHeight() ? fitIn : -1;
|
||||
|
||||
pstr_ = text;
|
||||
|
||||
lineBegin_ = text;
|
||||
lastSpace_ = lineBegin_;
|
||||
|
||||
while(unsigned char cc = *pstr_){
|
||||
if(cc == '\n'){
|
||||
putText();
|
||||
++pstr_;
|
||||
|
||||
endLine();
|
||||
skipNode();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if(cc < 32){
|
||||
++pstr_;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(cc == ' '){
|
||||
lastTagWidth_ = tagWidth_;
|
||||
lastSpace_ = pstr_;
|
||||
}
|
||||
|
||||
//if(useWildChars)
|
||||
if(cc == '&'){
|
||||
if(pstr_[1] != '&'){
|
||||
putText();
|
||||
++pstr_;
|
||||
getColor(color);
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
addChar('&');
|
||||
putText();
|
||||
++pstr_;
|
||||
skipNode();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if(cc == '<'){
|
||||
if(pstr_[1] != '<'){
|
||||
putText();
|
||||
++pstr_;
|
||||
lineWidth_ += getToken();
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
addChar('<');
|
||||
putText();
|
||||
++pstr_;
|
||||
skipNode();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
addChar((BYTE)cc);
|
||||
}
|
||||
|
||||
putText();
|
||||
size_.x = max(size_.x, lineWidth_);
|
||||
outNodes_[prevLineIndex_].width = lineWidth_;
|
||||
|
||||
size_.y = fontHeight() * lineCount_;
|
||||
}
|
||||
|
||||
int UI_TextParser::getToken()
|
||||
{
|
||||
const char* ptr = pstr_;
|
||||
const char* begin_tag = ptr;
|
||||
const char* begin_style = 0;
|
||||
|
||||
char cc;
|
||||
while((cc = *pstr_) && cc != '=' && cc != '>')
|
||||
++pstr_;
|
||||
unsigned int tag_len = pstr_ - begin_tag;
|
||||
|
||||
if(cc != '>'){
|
||||
while((cc = *pstr_) && cc != ';' && cc != '>')
|
||||
++pstr_;
|
||||
if(cc == ';'){
|
||||
begin_style = pstr_;
|
||||
while((cc = *pstr_) && cc != '>')
|
||||
++pstr_;
|
||||
}
|
||||
}
|
||||
|
||||
if(!cc){
|
||||
skipNode();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* switch(tag_len){
|
||||
case 3:
|
||||
if(!strncmp(begin_tag, "img=", 4)){
|
||||
string img_name(begin_tag + 4, begin_style ? begin_style : pstr_);
|
||||
if(const UI_Sprite* sprite = UI_SpriteReference(img_name.c_str()))
|
||||
if(!sprite->isEmpty()){
|
||||
OutNode node;
|
||||
node.type = OutNode::SPRITE;
|
||||
node.sprite = sprite;
|
||||
node.style = getStyle(begin_style, pstr_);
|
||||
if((node.style & 0x03) != 2)
|
||||
node.width = sprite->size().xi();
|
||||
else{
|
||||
Vect2f size = sprite->size();
|
||||
node.width = round(size.x / size.y * fontHeight());
|
||||
}
|
||||
++pstr_;
|
||||
testWidth(node.width);
|
||||
putNode(node);
|
||||
return node.width;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}*/
|
||||
|
||||
++pstr_;
|
||||
skipNode();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UI_TextParser::getStyle(const char* styleptr, const char* end)
|
||||
{
|
||||
if(!styleptr || *end != '>')
|
||||
return 0;
|
||||
|
||||
char cc;
|
||||
while((cc = *(++styleptr)) && cc != '=' && cc != '>');
|
||||
|
||||
if(cc != '=')
|
||||
return 0;
|
||||
|
||||
int style = 0;
|
||||
while((cc = *(++styleptr)) >= '0' && cc <= '9')
|
||||
style = style * 10 + (int)(cc - '0');
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
void UI_TextParser::getColor(int defColor)
|
||||
{
|
||||
int color = defColor;
|
||||
|
||||
if(*pstr_ != '>'){
|
||||
DWORD s = 0;
|
||||
int i = 0;
|
||||
for(; i < 6; ++i, ++pstr_)
|
||||
if(char k = *pstr_){
|
||||
int a = fromHex(k);
|
||||
if(a < 0)
|
||||
break;
|
||||
s |= a << (i * 4);
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
if(i > 5){
|
||||
color &= 0xFF000000;
|
||||
color |= s;
|
||||
}
|
||||
else {
|
||||
skipNode();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
++pstr_;
|
||||
|
||||
putNode(OutNode(color));
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
#ifndef __UI_TEXT_PARSER_H__
|
||||
#define __UI_TEXT_PARSER_H__
|
||||
|
||||
#include "gr_font.h"
|
||||
|
||||
struct OutNode{
|
||||
enum{
|
||||
NEW_LINE,
|
||||
TEXT,
|
||||
COLOR
|
||||
} type;
|
||||
int width;
|
||||
union{
|
||||
struct {
|
||||
const char* begin;
|
||||
const char* end;
|
||||
};
|
||||
struct {
|
||||
int style;
|
||||
};
|
||||
int color;
|
||||
};
|
||||
OutNode() : type(NEW_LINE), width(0), begin(0), end(0) {}
|
||||
OutNode(const char* b, const char* e, int wd) : type(TEXT), width(wd), begin(b), end(e) {}
|
||||
OutNode(int clr) : type(COLOR), width(0), color(clr) {}
|
||||
};
|
||||
|
||||
typedef std::vector<OutNode> OutNodes;
|
||||
|
||||
class UI_TextParser
|
||||
{
|
||||
public:
|
||||
UI_TextParser(const grFont* font = 0);
|
||||
UI_TextParser(const UI_TextParser& src);
|
||||
|
||||
void operator= (const UI_TextParser& src);
|
||||
|
||||
void setFont(const grFont* font);
|
||||
|
||||
void parseString(const char* text, int color = 0, int fitIn = -1);
|
||||
|
||||
const OutNodes& outNodes() const { return outNodes_; }
|
||||
|
||||
int fontHeight() const { return font_ ? font_->size_y() : 1; }
|
||||
const Vect2i& size() const { return size_; }
|
||||
|
||||
int lineCount() const { return lineCount_; }
|
||||
OutNodes::const_iterator getLineBegin(int lineNum) const;
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
__forceinline int fromHex(char a)
|
||||
{
|
||||
if(a>='0' && a<='9')
|
||||
return a-'0';
|
||||
if(a>='A' && a<='F')
|
||||
return a-'A'+10;
|
||||
if(a>='a' && a<='f')
|
||||
return a-'a'+10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
__forceinline void addChar(BYTE cc)
|
||||
{
|
||||
int width = font_->char_width(cc);
|
||||
if(testWidth(width) || cc != ' ')
|
||||
tagWidth_ += width;
|
||||
++pstr_;
|
||||
}
|
||||
|
||||
__forceinline void skipNode()
|
||||
{
|
||||
lineBegin_ = pstr_;
|
||||
lastSpace_ = lineBegin_;
|
||||
lastTagWidth_ = 0;
|
||||
tagWidth_ = 0;
|
||||
}
|
||||
|
||||
__forceinline void putNode(OutNode& node)
|
||||
{
|
||||
outNodes_.push_back(node);
|
||||
skipNode();
|
||||
}
|
||||
|
||||
void putText()
|
||||
{
|
||||
if(pstr_ == lineBegin_)
|
||||
return;
|
||||
lineWidth_ += tagWidth_;
|
||||
putNode(OutNode(lineBegin_, pstr_, tagWidth_));
|
||||
}
|
||||
|
||||
void endLine()
|
||||
{
|
||||
size_.x = max(size_.x, lineWidth_);
|
||||
|
||||
outNodes_[prevLineIndex_].width = lineWidth_;
|
||||
lineWidth_ = 0;
|
||||
|
||||
outNodes_.push_back(OutNode());
|
||||
prevLineIndex_ = outNodes_.size() - 1;
|
||||
|
||||
++lineCount_;
|
||||
}
|
||||
|
||||
void getColor(int defColor);
|
||||
int getStyle(const char* styleptr, const char* end);
|
||||
int getToken();
|
||||
bool testWidth(int width);
|
||||
|
||||
OutNodes outNodes_;
|
||||
|
||||
int prevLineIndex_;
|
||||
const char* lastSpace_;
|
||||
int lastTagWidth_;
|
||||
|
||||
const char* lineBegin_;
|
||||
const char* pstr_;
|
||||
int tagWidth_;
|
||||
int lineWidth_;
|
||||
|
||||
int fitIn_;
|
||||
|
||||
Vect2i size_;
|
||||
int lineCount_;
|
||||
|
||||
const grFont* font_;
|
||||
|
||||
};
|
||||
|
||||
#endif //__UI_TEXT_PARSER_H__
|
||||
@@ -0,0 +1,318 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "ddraw_gr_dispatcher.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
|
||||
HRESULT CALLBACK ddEnumDisplayModesCallback(LPDDSURFACEDESC lpDDSurfaceDesc,LPVOID lpContext);
|
||||
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
DDraw_grDispatcher::DDraw_grDispatcher() : ddobj_(0),
|
||||
prim_surface_(0),
|
||||
back_surface_(0),
|
||||
fullscreen_(false)
|
||||
{
|
||||
DDSURFACEDESC ddSurf;
|
||||
ZeroMemory(&ddSurf,sizeof(DDSURFACEDESC));
|
||||
ddSurf.dwSize = sizeof(ddSurf);
|
||||
ddSurf.dwFlags = 0;
|
||||
|
||||
if(FAILED(DirectDrawCreate(NULL,&ddobj_,NULL))) return;
|
||||
|
||||
video_modes_.reserve(50);
|
||||
enum_display_modes();
|
||||
}
|
||||
|
||||
DDraw_grDispatcher::~DDraw_grDispatcher()
|
||||
{
|
||||
if(ddobj_){
|
||||
ddobj_ -> Release();
|
||||
ddobj_ = NULL;
|
||||
}
|
||||
|
||||
video_modes_.clear();
|
||||
}
|
||||
|
||||
bool DDraw_grDispatcher::Flush(int x,int y,int sx,int sy)
|
||||
{
|
||||
if(flags & GR_INITED && hWnd){
|
||||
int x1 = x + sx;
|
||||
int y1 = y + sy;
|
||||
|
||||
if(x < 0) x = 0;
|
||||
if(y < 0) y = 0;
|
||||
if(x1 > SizeX) x1 = SizeX;
|
||||
if(y1 > SizeY) y1 = SizeY;
|
||||
|
||||
RECT src_rect = { x,y,x1,y1 };
|
||||
RECT dest_rect = src_rect;
|
||||
|
||||
if(!fullscreen_){
|
||||
POINT pt = { 0,0 };
|
||||
ClientToScreen((HWND)Get_hWnd(),&pt);
|
||||
OffsetRect(&dest_rect,pt.x,pt.y);
|
||||
}
|
||||
|
||||
// if(prim_surface_ -> IsLost() != DD_OK) prim_surface_ -> Restore();
|
||||
back_surface_ -> Unlock(&back_surface_obj_);
|
||||
|
||||
while(TRUE){
|
||||
HRESULT hr = prim_surface_ -> Blt(&dest_rect,back_surface_,&src_rect,DDBLT_WAIT,NULL);
|
||||
if(hr == DD_OK)
|
||||
break;
|
||||
if(hr == DDERR_SURFACELOST){
|
||||
hr = prim_surface_ -> Restore();
|
||||
if(hr != DD_OK)
|
||||
break;
|
||||
}
|
||||
if(hr != DDERR_WASSTILLDRAWING)
|
||||
break;
|
||||
}
|
||||
|
||||
back_surface_ -> Lock(NULL,&back_surface_obj_,DDLOCK_SURFACEMEMORYPTR,NULL);
|
||||
screenBuf = static_cast<char*>(back_surface_obj_.lpSurface);
|
||||
for(int i = 0; i < SizeY; i ++)
|
||||
yTable[i] = i * back_surface_obj_.lPitch;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DDraw_grDispatcher::StretchFlush(int x_dest,int y_dest,int sx_dest,int sy_dest,int x_src,int y_src,int sx_src,int sy_src)
|
||||
{
|
||||
if(flags & GR_INITED && hWnd){
|
||||
RECT src = { x_src,y_src,x_src + sx_src,y_src + sy_src };
|
||||
RECT dst = { x_dest,y_dest,x_dest + sx_dest,y_dest + sy_dest };
|
||||
|
||||
if(!fullscreen_){
|
||||
POINT pt = { 0,0 };
|
||||
ClientToScreen((HWND)Get_hWnd(),&pt);
|
||||
OffsetRect(&dst,pt.x,pt.y);
|
||||
}
|
||||
|
||||
if(prim_surface_ -> IsLost() != DD_OK) prim_surface_ -> Restore();
|
||||
back_surface_ -> Unlock(&back_surface_obj_);
|
||||
|
||||
while(back_surface_ -> GetBltStatus(DDGBS_ISBLTDONE) == DDERR_WASSTILLDRAWING);
|
||||
prim_surface_ -> Blt(&dst,back_surface_,&src,DDBLT_WAIT,NULL);
|
||||
|
||||
back_surface_ -> Lock(NULL,&back_surface_obj_,DDLOCK_SURFACEMEMORYPTR,NULL);
|
||||
screenBuf = reinterpret_cast<char*>(back_surface_obj_.lpSurface);
|
||||
for(int i = 0; i < SizeY; i ++)
|
||||
yTable[i] = i * back_surface_obj_.lPitch;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DDraw_grDispatcher::init(int sx,int sy,grPixelFormat pixel_format,void* hwnd,bool fullscreen)
|
||||
{
|
||||
if(!ddobj_) return false;
|
||||
|
||||
fullscreen_ = fullscreen;
|
||||
grDispatcher::init(sx,sy,pixel_format,hwnd,fullscreen);
|
||||
|
||||
if(fullscreen_){
|
||||
if(ddobj_ -> SetCooperativeLevel((HWND)Get_hWnd(),DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN) != DD_OK)
|
||||
return false;
|
||||
if(ddobj_ -> SetDisplayMode(sx,sy,bytes_per_pixel() * 8) != DD_OK)
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(ddobj_ -> SetCooperativeLevel((HWND)Get_hWnd(),DDSCL_NORMAL) != DD_OK)
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!hwnd && sx && sy){
|
||||
resize_window(sx,sy);
|
||||
SizeX = sx;
|
||||
SizeY = sy;
|
||||
}
|
||||
|
||||
DDSURFACEDESC ddSurf;
|
||||
ZeroMemory(&ddSurf,sizeof(DDSURFACEDESC));
|
||||
ddSurf.dwSize = sizeof(ddSurf);
|
||||
ddSurf.dwFlags = DDSD_CAPS;
|
||||
ddSurf.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||||
if(ddobj_ -> CreateSurface(&ddSurf,&prim_surface_,NULL) != DD_OK) return false;
|
||||
|
||||
if(!fullscreen_){
|
||||
LPDIRECTDRAWCLIPPER cp = NULL;
|
||||
if(ddobj_ -> CreateClipper(0,&cp,NULL) != DD_OK) return false;
|
||||
cp -> SetHWnd(0,(HWND)Get_hWnd());
|
||||
prim_surface_ -> SetClipper(cp);
|
||||
cp -> Release();
|
||||
}
|
||||
|
||||
ZeroMemory(&ddSurf,sizeof(DDSURFACEDESC));
|
||||
ddSurf.dwSize = sizeof(ddSurf);
|
||||
ddobj_ -> GetDisplayMode(&ddSurf);
|
||||
|
||||
ddSurf.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
|
||||
ddSurf.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_SYSTEMMEMORY;
|
||||
ddSurf.dwWidth = SizeX;
|
||||
ddSurf.dwHeight = SizeY;
|
||||
|
||||
ddSurf.dwFlags |= DDSD_PIXELFORMAT;
|
||||
|
||||
if(ddobj_ -> CreateSurface(&ddSurf,&back_surface_,NULL) != DD_OK) return false;
|
||||
|
||||
switch(ddSurf.ddpfPixelFormat.dwRGBBitCount){
|
||||
case 16:
|
||||
if(ddSurf.ddpfPixelFormat.dwGBitMask == grDispatcher::mask_565_g)
|
||||
pixel_format_ = GR_RGB565;
|
||||
else
|
||||
pixel_format_ = GR_ARGB1555;
|
||||
break;
|
||||
case 24:
|
||||
pixel_format_ = GR_RGB888;
|
||||
break;
|
||||
case 32:
|
||||
pixel_format_ = GR_ARGB8888;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
ZeroMemory(&back_surface_obj_,sizeof(DDSURFACEDESC));
|
||||
back_surface_obj_.dwSize = sizeof(DDSURFACEDESC);
|
||||
back_surface_obj_.dwFlags = DDSD_PITCH;
|
||||
if(back_surface_ -> Lock(NULL,&back_surface_obj_,DDLOCK_SURFACEMEMORYPTR,NULL) != DD_OK) return false;
|
||||
screenBuf = reinterpret_cast<char*>(back_surface_obj_.lpSurface);
|
||||
|
||||
delete yTable;
|
||||
yTable = new int[SizeY + 1];
|
||||
for(int i = 0; i < SizeY; i ++)
|
||||
yTable[i] = i * back_surface_obj_.lPitch;
|
||||
|
||||
SetClip();
|
||||
|
||||
flags |= GR_INITED;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DDraw_grDispatcher::Finit()
|
||||
{
|
||||
grDispatcher::Finit();
|
||||
|
||||
if(back_surface_){
|
||||
while(back_surface_ -> GetBltStatus(DDGBS_ISBLTDONE) == DDERR_WASSTILLDRAWING);
|
||||
back_surface_ -> Unlock(&back_surface_obj_);
|
||||
ddobj_ -> SetCooperativeLevel((HWND)Get_hWnd(),DDSCL_NORMAL);
|
||||
if(fullscreen_ && ddobj_) ddobj_ -> RestoreDisplayMode();
|
||||
}
|
||||
if(prim_surface_){
|
||||
prim_surface_ -> Release();
|
||||
prim_surface_ = NULL;
|
||||
}
|
||||
if(back_surface_){
|
||||
back_surface_ -> Release();
|
||||
back_surface_ = NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DDraw_grDispatcher::enum_display_modes()
|
||||
{
|
||||
if(!ddobj_) return false;
|
||||
|
||||
video_modes_.clear();
|
||||
|
||||
if(FAILED(ddobj_ -> EnumDisplayModes(DDEDM_STANDARDVGAMODES,NULL,(LPVOID)(&video_modes_),ddEnumDisplayModesCallback)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
HRESULT CALLBACK ddEnumDisplayModesCallback(LPDDSURFACEDESC lpDDSurfaceDesc,LPVOID lpContext)
|
||||
{
|
||||
grPixelFormat pixel_format;
|
||||
switch(lpDDSurfaceDesc -> ddpfPixelFormat.dwRGBBitCount){
|
||||
case 16:
|
||||
if(lpDDSurfaceDesc -> ddpfPixelFormat.dwGBitMask == grDispatcher::mask_565_g)
|
||||
pixel_format = GR_RGB565;
|
||||
else
|
||||
pixel_format = GR_ARGB1555;
|
||||
break;
|
||||
case 24:
|
||||
pixel_format = GR_RGB888;
|
||||
break;
|
||||
case 32:
|
||||
pixel_format = GR_ARGB8888;
|
||||
break;
|
||||
default:
|
||||
return DDENUMRET_OK;
|
||||
}
|
||||
|
||||
DDraw_VideoMode vid_mode(lpDDSurfaceDesc -> dwWidth,lpDDSurfaceDesc -> dwHeight,pixel_format);
|
||||
DDraw_VideoModeVector* modes = reinterpret_cast<DDraw_VideoModeVector*>(lpContext);
|
||||
modes -> push_back(vid_mode);
|
||||
|
||||
return DDENUMRET_OK;
|
||||
}
|
||||
|
||||
bool DDraw_grDispatcher::is_mode_supported(int sx,int sy,grPixelFormat pixel_format) const
|
||||
{
|
||||
for(int i = 0; i < video_modes_.size(); i ++){
|
||||
if(video_modes_[i].screen_sx() == sx && video_modes_[i].screen_sy() == sy && video_modes_[i].pixel_format() == pixel_format)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DDraw_grDispatcher::is_mode_supported(grPixelFormat pixel_format) const
|
||||
{
|
||||
for(int i = 0; i < video_modes_.size(); i ++){
|
||||
if(video_modes_[i].pixel_format() == pixel_format)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool DDraw_grDispatcher::get_current_mode(int& sx,int& sy,grPixelFormat& pixel_format) const
|
||||
{
|
||||
DDSURFACEDESC ddsd;
|
||||
ZeroMemory(&ddsd,sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
HRESULT hRet = ddobj_ -> GetDisplayMode(&ddsd);
|
||||
if(hRet != DD_OK)
|
||||
return false;
|
||||
|
||||
sx = ddsd.dwWidth;
|
||||
sy = abs(float(ddsd.dwHeight));
|
||||
|
||||
switch(ddsd.ddpfPixelFormat.dwRGBBitCount){
|
||||
case 16:
|
||||
if(ddsd.ddpfPixelFormat.dwGBitMask == grDispatcher::mask_565_g)
|
||||
pixel_format = GR_RGB565;
|
||||
else
|
||||
pixel_format = GR_ARGB1555;
|
||||
break;
|
||||
case 24:
|
||||
pixel_format = GR_RGB888;
|
||||
break;
|
||||
case 32:
|
||||
pixel_format = GR_ARGB8888;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
#ifndef __DDRAW_GR_DISPATCHER_H__
|
||||
#define __DDRAW_GR_DISPATCHER_H__
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "gr_dispatcher.h"
|
||||
|
||||
class DDraw_VideoMode
|
||||
{
|
||||
public:
|
||||
DDraw_VideoMode(int sx,int sy,grPixelFormat pf) : screen_sx_(sx),
|
||||
screen_sy_(sy), pixel_format_(pf) { }
|
||||
~DDraw_VideoMode(){ }
|
||||
|
||||
int screen_sx() const { return screen_sx_; }
|
||||
int screen_sy() const { return screen_sy_; }
|
||||
grPixelFormat pixel_format() const { return pixel_format_; }
|
||||
|
||||
int bits_per_pixel() const {
|
||||
switch(pixel_format_){
|
||||
case GR_RGB565:
|
||||
case GR_ARGB1555:
|
||||
return 16;
|
||||
case GR_RGB888:
|
||||
return 24;
|
||||
case GR_ARGB8888:
|
||||
return 32;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
int screen_sx_;
|
||||
int screen_sy_;
|
||||
grPixelFormat pixel_format_;
|
||||
};
|
||||
|
||||
typedef std::vector<DDraw_VideoMode> DDraw_VideoModeVector;
|
||||
|
||||
class DDraw_grDispatcher : public grDispatcher
|
||||
{
|
||||
public:
|
||||
DDraw_grDispatcher();
|
||||
~DDraw_grDispatcher();
|
||||
|
||||
bool Flush(int x,int y,int sx,int sy);
|
||||
bool StretchFlush(int x_dest,int y_dest,int sx_dest,int sy_dest,int x_src,int y_src,int sx_src,int sy_src);
|
||||
|
||||
bool Finit();
|
||||
|
||||
bool init(int sx,int sy,grPixelFormat pixel_format,void* hwnd,bool fullscreen = false);
|
||||
|
||||
bool is_in_fullscreen_mode() const { return fullscreen_; }
|
||||
|
||||
bool is_mode_supported(int sx,int sy,grPixelFormat pixel_format) const;
|
||||
bool is_mode_supported(grPixelFormat pixel_format) const;
|
||||
|
||||
bool get_current_mode(int& sx,int& sy,grPixelFormat& pixel_format) const;
|
||||
|
||||
bool enum_display_modes();
|
||||
|
||||
private:
|
||||
bool fullscreen_;
|
||||
|
||||
LPDIRECTDRAW ddobj_;
|
||||
LPDIRECTDRAWSURFACE prim_surface_;
|
||||
LPDIRECTDRAWSURFACE back_surface_;
|
||||
DDSURFACEDESC back_surface_obj_;
|
||||
|
||||
DDraw_VideoModeVector video_modes_;
|
||||
};
|
||||
|
||||
#endif /* __DDRAW_GR_DISPATCHER_H__ */
|
||||
|
||||
@@ -0,0 +1,240 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "gdi_gr_dispatcher.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
GDI_grDispatcher::GDI_grDispatcher() : dibPtr(0),
|
||||
dibHandle(0)
|
||||
{
|
||||
palette_mode_ = false;
|
||||
|
||||
sys_palette_ = NULL;
|
||||
sys_pal_handle_ = NULL;
|
||||
palette_ = NULL;
|
||||
pal_handle_ = NULL;
|
||||
}
|
||||
|
||||
GDI_grDispatcher::~GDI_grDispatcher()
|
||||
{
|
||||
}
|
||||
|
||||
bool GDI_grDispatcher::init(int sx,int sy,grPixelFormat pixel_format,void* hwnd,bool fullscreen)
|
||||
{
|
||||
grDispatcher::init(sx,sy,pixel_format,hwnd,fullscreen);
|
||||
|
||||
HDC hdc = GetDC(NULL);
|
||||
|
||||
char* ptr;
|
||||
BITMAPINFO* bi;
|
||||
|
||||
switch(pixel_format_){
|
||||
case GR_RGB565:
|
||||
ptr = new char[sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 3];
|
||||
memset(ptr,0,sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 3);
|
||||
bi = (BITMAPINFO*)ptr;
|
||||
bi -> bmiHeader.biCompression = BI_BITFIELDS;
|
||||
|
||||
*(DWORD*)&(bi -> bmiColors[0]) = mask_565_r;
|
||||
*(DWORD*)&(bi -> bmiColors[1]) = mask_565_g;
|
||||
*(DWORD*)&(bi -> bmiColors[2]) = mask_565_b;
|
||||
break;
|
||||
case GR_ARGB1555:
|
||||
ptr = new char[sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 3];
|
||||
memset(ptr,0,sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 3);
|
||||
bi = (BITMAPINFO*)ptr;
|
||||
bi -> bmiHeader.biCompression = BI_BITFIELDS;
|
||||
|
||||
*(DWORD*)&(bi -> bmiColors[0]) = mask_555_r;
|
||||
*(DWORD*)&(bi -> bmiColors[1]) = mask_555_g;
|
||||
*(DWORD*)&(bi -> bmiColors[2]) = mask_555_b;
|
||||
break;
|
||||
case GR_RGB888:
|
||||
case GR_ARGB8888:
|
||||
ptr = new char[sizeof(BITMAPINFO)];
|
||||
memset(ptr,0,sizeof(BITMAPINFO));
|
||||
bi = (BITMAPINFO*)ptr;
|
||||
bi -> bmiHeader.biCompression = BI_RGB;
|
||||
break;
|
||||
}
|
||||
|
||||
dibPtr = ptr;
|
||||
|
||||
int dsx = SizeX * bytes_per_pixel();
|
||||
if(dsx % 4) dsx += 4 - (dsx % 4);
|
||||
|
||||
bi -> bmiHeader.biBitCount = bytes_per_pixel() * 8;
|
||||
bi -> bmiHeader.biClrUsed = 0;
|
||||
|
||||
bi -> bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bi -> bmiHeader.biWidth = SizeX;
|
||||
bi -> bmiHeader.biHeight = -SizeY;
|
||||
bi -> bmiHeader.biPlanes = 1;
|
||||
bi -> bmiHeader.biSizeImage = dsx * SizeY;
|
||||
bi -> bmiHeader.biXPelsPerMeter = SizeX;
|
||||
bi -> bmiHeader.biYPelsPerMeter = SizeY;
|
||||
bi -> bmiHeader.biClrImportant = 0;
|
||||
|
||||
dibHandle = CreateDIBSection(hdc,bi,DIB_RGB_COLORS,(void**)&(screenBuf),NULL,NULL);
|
||||
|
||||
delete yTable;
|
||||
yTable = new int[SizeY + 1];
|
||||
for(int i = 0; i < SizeY; i ++)
|
||||
yTable[i] = i * dsx;
|
||||
|
||||
int caps = GetDeviceCaps(hdc,RASTERCAPS);
|
||||
|
||||
if(caps & RC_PALETTE){
|
||||
palette_mode_ = true;
|
||||
|
||||
char* ptr = new char[sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * 256];
|
||||
memset(ptr,0,sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * 256);
|
||||
|
||||
sys_palette_ = (LOGPALETTE*)ptr;
|
||||
|
||||
sys_palette_ -> palVersion = 0x300;
|
||||
sys_palette_ -> palNumEntries = 256;
|
||||
|
||||
sys_pal_handle_ = CreatePalette(sys_palette_);
|
||||
|
||||
ptr = new char[sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * 256];
|
||||
memset(ptr,0,sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * 256);
|
||||
|
||||
palette_ = (LOGPALETTE*)ptr;
|
||||
|
||||
palette_ -> palVersion = 0x300;
|
||||
palette_ -> palNumEntries = 256;
|
||||
|
||||
pal_handle_ = CreatePalette(palette_);
|
||||
GetSystemPaletteEntries(hdc,0,256,palette_ -> palPalEntry);
|
||||
|
||||
for(int i = 0; i < 256; i ++){
|
||||
palette_ -> palPalEntry[i].peRed = (unsigned)(i);
|
||||
palette_ -> palPalEntry[i].peGreen = (unsigned)(i);
|
||||
palette_ -> palPalEntry[i].peBlue = (unsigned)(i);
|
||||
palette_ -> palPalEntry[i].peFlags = PC_NOCOLLAPSE;
|
||||
}
|
||||
|
||||
SetPaletteEntries(pal_handle_,0,256,palette_ -> palPalEntry);
|
||||
|
||||
GetSystemPaletteEntries(hdc,0,256,sys_palette_ -> palPalEntry);
|
||||
SetPaletteEntries(sys_pal_handle_,0,256,sys_palette_ -> palPalEntry);
|
||||
}
|
||||
|
||||
ReleaseDC(NULL,hdc);
|
||||
|
||||
SetClip();
|
||||
|
||||
flags |= GR_INITED;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GDI_grDispatcher::Flush(int x,int y,int sx,int sy)
|
||||
{
|
||||
if(flags & GR_INITED && hWnd){
|
||||
int x_src = wndPosX + x;
|
||||
int y_src = wndPosY + y;
|
||||
|
||||
HDC hdc = GetDC((HWND)hWnd);
|
||||
|
||||
if(palette_mode_){
|
||||
SelectPalette(hdc,pal_handle_,1);
|
||||
RealizePalette(hdc);
|
||||
}
|
||||
|
||||
HDC hbmp = CreateCompatibleDC(hdc);
|
||||
HGDIOBJ holdbmp = SelectObject(hbmp,dibHandle);
|
||||
|
||||
BitBlt(hdc,x,y,sx,sy,hbmp,x_src,y_src,SRCCOPY);
|
||||
SelectObject(hbmp,holdbmp);
|
||||
DeleteDC(hbmp);
|
||||
|
||||
ReleaseDC((HWND)hWnd,hdc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GDI_grDispatcher::StretchFlush(int x_dest,int y_dest,int sx_dest,int sy_dest,int x_src,int y_src,int sx_src,int sy_src)
|
||||
{
|
||||
if(flags & GR_INITED && hWnd){
|
||||
HDC hdc = GetDC((HWND)hWnd);
|
||||
|
||||
if(palette_mode_){
|
||||
SelectPalette(hdc,pal_handle_,1);
|
||||
RealizePalette(hdc);
|
||||
}
|
||||
|
||||
HDC hbmp = CreateCompatibleDC(hdc);
|
||||
HGDIOBJ holdbmp = SelectObject(hbmp,dibHandle);
|
||||
|
||||
StretchBlt(hdc,x_dest,y_dest,sx_dest,sy_dest,hbmp,x_src,y_src,sx_src,sy_src,SRCCOPY);
|
||||
SelectObject(hbmp,holdbmp);
|
||||
DeleteDC(hbmp);
|
||||
|
||||
ReleaseDC((HWND)hWnd,hdc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GDI_grDispatcher::Finit()
|
||||
{
|
||||
grDispatcher::Finit();
|
||||
|
||||
if(dibHandle)
|
||||
DeleteObject(dibHandle);
|
||||
|
||||
if(dibPtr){
|
||||
char* p = (char*)dibPtr;
|
||||
delete p;
|
||||
}
|
||||
|
||||
dibPtr = NULL;
|
||||
dibHandle = NULL;
|
||||
|
||||
if(palette_mode_){
|
||||
HDC hdc = GetDC(NULL);
|
||||
SelectPalette(hdc,sys_pal_handle_,1);
|
||||
RealizePalette(hdc);
|
||||
ReleaseDC(NULL,hdc);
|
||||
|
||||
delete sys_palette_;
|
||||
sys_palette_ = NULL;
|
||||
delete palette_;
|
||||
palette_ = NULL;
|
||||
|
||||
sys_pal_handle_ = NULL;
|
||||
pal_handle_ = NULL;
|
||||
|
||||
palette_mode_ = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GDI_grDispatcher::set_palette(const char* pal,int start_col,int pal_size)
|
||||
{
|
||||
if(!palette_mode_)
|
||||
return false;
|
||||
|
||||
for(int i = 0; i < pal_size; i ++){
|
||||
palette_ -> palPalEntry[start_col + i].peRed = (unsigned)(pal[i * 3 + 0]) * 4;
|
||||
palette_ -> palPalEntry[start_col + i].peGreen = (unsigned)(pal[i * 3 + 1]) * 4;
|
||||
palette_ -> palPalEntry[start_col + i].peBlue = (unsigned)(pal[i * 3 + 2]) * 4;
|
||||
palette_ -> palPalEntry[start_col + i].peFlags = PC_NOCOLLAPSE;
|
||||
}
|
||||
|
||||
SetPaletteEntries(pal_handle_,start_col,pal_size,palette_ -> palPalEntry);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef __GDI_GR_DISPATCHER_H__
|
||||
#define __GDI_GR_DISPATCHER_H__
|
||||
|
||||
#include "gr_dispatcher.h"
|
||||
|
||||
class GDI_grDispatcher : public grDispatcher
|
||||
{
|
||||
public:
|
||||
GDI_grDispatcher();
|
||||
~GDI_grDispatcher();
|
||||
|
||||
bool Flush(int x,int y,int sx,int sy);
|
||||
bool StretchFlush(int x_dest,int y_dest,int sx_dest,int sy_dest,int x_src,int y_src,int sx_src,int sy_src);
|
||||
|
||||
bool init(int sx,int sy,grPixelFormat pixel_format,void* hwnd,bool fullscreen = false);
|
||||
|
||||
bool InitScreen(int sx,int sy);
|
||||
bool Finit();
|
||||
|
||||
bool is_in_fullscreen_mode() const { return false; }
|
||||
bool is_mode_supported(int sx,int sy,grPixelFormat pixel_format) const { return true; }
|
||||
bool is_mode_supported(grPixelFormat pixel_format) const { return true; }
|
||||
|
||||
bool palette_mode() const { return palette_mode_; }
|
||||
bool set_palette(const char* pal,int start_col,int pal_size);
|
||||
|
||||
private:
|
||||
|
||||
void* dibPtr;
|
||||
void* dibHandle;
|
||||
|
||||
bool palette_mode_;
|
||||
LOGPALETTE* sys_palette_;
|
||||
HPALETTE sys_pal_handle_;
|
||||
LOGPALETTE* palette_;
|
||||
HPALETTE pal_handle_;
|
||||
};
|
||||
|
||||
#endif /* __GDI_GR_DISPATCHER_H__ */
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "gr_dispatcher.h"
|
||||
#include "mouse_input.h"
|
||||
#include "keyboard_input.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
|
||||
LRESULT CALLBACK grWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
|
||||
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
void* grDispatcher::default_mouse_cursor_;
|
||||
char* grDispatcher::wnd_class_name_ = "grWndClass";
|
||||
|
||||
LRESULT CALLBACK GR_WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
|
||||
{
|
||||
grDispatcher* p = grDispatcher::instance(hwnd);
|
||||
bool hittest = false;
|
||||
|
||||
switch(uMsg){
|
||||
case WM_SYSKEYDOWN:
|
||||
if((int)wParam != VK_F4)
|
||||
return 0;
|
||||
break;
|
||||
case WM_NCHITTEST:
|
||||
hittest = true;
|
||||
break;
|
||||
case WM_CHAR:
|
||||
if(grDispatcher::handle_char_input(int(wParam)))
|
||||
return 0;
|
||||
break;
|
||||
case WM_SYSCOMMAND:
|
||||
if(wParam == SC_MAXIMIZE){
|
||||
if(p && p -> maximize_handler())
|
||||
(*p -> maximize_handler())();
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#ifndef _QUEST_EDITOR
|
||||
case WM_CLOSE:
|
||||
ShowWindow(hwnd,SW_HIDE);
|
||||
DestroyWindow(hwnd);
|
||||
return 0;
|
||||
#endif
|
||||
case WM_DESTROY:
|
||||
if(!grDispatcher::instance() || !grDispatcher::instance() -> is_in_reinit_mode())
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
case WM_ACTIVATEAPP:
|
||||
if(wParam)
|
||||
grDispatcher::activate(true);
|
||||
else
|
||||
grDispatcher::activate(false);
|
||||
break;
|
||||
case WM_SETCURSOR:
|
||||
if(p){
|
||||
#ifndef _QUEST_EDITOR
|
||||
SetCursor((HCURSOR)p -> mouse_cursor());
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case WM_PAINT:
|
||||
if(p){
|
||||
PAINTSTRUCT pc;
|
||||
HDC hdc = BeginPaint(hwnd,&pc);
|
||||
p -> Flush(pc.rcPaint.left,pc.rcPaint.top,pc.rcPaint.right - pc.rcPaint.left,pc.rcPaint.bottom - pc.rcPaint.top);
|
||||
EndPaint(hwnd,&pc);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
LRESULT res = DefWindowProc(hwnd,uMsg,wParam,lParam);
|
||||
|
||||
if(hittest && p){
|
||||
if(res == HTCLIENT && p -> is_mouse_hidden())
|
||||
p -> set_null_mouse_cursor();
|
||||
else
|
||||
p -> set_default_mouse_cursor();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
grDispatcher* grDispatcher::instance(void* hwnd)
|
||||
{
|
||||
return reinterpret_cast<grDispatcher*>(GetWindowLong((HWND)hwnd,GWL_USERDATA));
|
||||
}
|
||||
|
||||
bool grDispatcher::sys_init()
|
||||
{
|
||||
WNDCLASS wc;
|
||||
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC;
|
||||
wc.lpfnWndProc = GR_WindowProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = GetModuleHandle(0);
|
||||
wc.hIcon = NULL;
|
||||
wc.hCursor = NULL;
|
||||
wc.hbrBackground = NULL;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = grDispatcher::wnd_class_name();
|
||||
|
||||
if(!RegisterClass(&wc)) return false;
|
||||
|
||||
default_mouse_cursor_ = LoadCursor(NULL,IDC_ARROW);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool grDispatcher::sys_finit()
|
||||
{
|
||||
UnregisterClass(grDispatcher::wnd_class_name(),GetModuleHandle(0));
|
||||
DestroyCursor((HCURSOR)default_mouse_cursor_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,533 @@
|
||||
|
||||
#ifndef __GR_DISPATCHER_H__
|
||||
#define __GR_DISPATCHER_H__
|
||||
|
||||
#include "gr_screen_region.h"
|
||||
|
||||
// Directions for LineTo()
|
||||
enum GR_LINEDIR
|
||||
{
|
||||
GR_LEFT,
|
||||
GR_TOP,
|
||||
GR_RIGHT,
|
||||
GR_BOTTOM
|
||||
};
|
||||
|
||||
// Modes for PutSpr()
|
||||
const int GR_BLACK_FON = 0x01;
|
||||
const int GR_CLIPPED = 0x02;
|
||||
const int GR_NOCLIP = 0x04;
|
||||
const int GR_FLIP_HORIZONTAL = 0x08;
|
||||
const int GR_FLIP_VERTICAL = 0x10;
|
||||
const int GR_IGNORE_ALPHA = 0x20;
|
||||
|
||||
// Modes for Rectangle()
|
||||
const int GR_FILLED = 0x00;
|
||||
const int GR_OUTLINED = 0x01;
|
||||
|
||||
// grDispatcher::flags
|
||||
const int GR_INITED = 0x01;
|
||||
const int GR_PALETTE = 0x02;
|
||||
const int GR_REINIT = 0x04;
|
||||
|
||||
#ifdef _GR_ENABLE_ZBUFFER
|
||||
typedef short zbuf_t;
|
||||
const GR_ZBUFFFER_MASK = 0xFFFF;
|
||||
const GR_ZBUFFER_MAX_Z = 30000;
|
||||
#endif
|
||||
|
||||
enum grTextAlign
|
||||
{
|
||||
GR_ALIGN_LEFT,
|
||||
GR_ALIGN_CENTER,
|
||||
GR_ALIGN_RIGHT
|
||||
};
|
||||
|
||||
enum grPixelFormat {
|
||||
GR_RGB565 = 0,
|
||||
GR_ARGB1555,
|
||||
GR_RGB888,
|
||||
GR_ARGB8888
|
||||
};
|
||||
|
||||
class grFont;
|
||||
class grTileSprite;
|
||||
class rleBuffer;
|
||||
class UI_TextParser;
|
||||
|
||||
class grDispatcher
|
||||
{
|
||||
public:
|
||||
grDispatcher();
|
||||
virtual ~grDispatcher();
|
||||
|
||||
static bool sys_init();
|
||||
static bool sys_finit();
|
||||
|
||||
virtual bool is_in_fullscreen_mode() const = 0;
|
||||
virtual bool is_mode_supported(int sx,int sy,grPixelFormat pixel_format) const = 0;
|
||||
virtual bool is_mode_supported(grPixelFormat pixel_format) const = 0;
|
||||
grPixelFormat adjust_mode(grPixelFormat pixel_format) const {
|
||||
if(!is_mode_supported(pixel_format)){
|
||||
switch(pixel_format){
|
||||
case GR_RGB565:
|
||||
return GR_ARGB1555;
|
||||
case GR_ARGB1555:
|
||||
return GR_RGB565;
|
||||
case GR_RGB888:
|
||||
return GR_ARGB8888;
|
||||
case GR_ARGB8888:
|
||||
return GR_RGB888;
|
||||
}
|
||||
}
|
||||
|
||||
return pixel_format;
|
||||
}
|
||||
|
||||
virtual bool init(int sx,int sy,grPixelFormat pixel_format,void* hwnd,bool fullscreen = false);
|
||||
|
||||
void toggle_reinit(){ flags |= GR_REINIT; }
|
||||
bool is_in_reinit_mode() const { return flags & GR_REINIT; }
|
||||
|
||||
bool create_window(int sx,int sy);
|
||||
bool resize_window(int sx,int sy);
|
||||
bool resize_window(){ return resize_window(SizeX,SizeY); }
|
||||
|
||||
bool destroy_window();
|
||||
|
||||
void set_flag(int fl){ flags |= fl; }
|
||||
void drop_flag(int fl){ flags &= ~fl; }
|
||||
bool check_flag(int fl){ if(flags & fl) return true; return false; }
|
||||
|
||||
bool set_window(void* hwnd);
|
||||
|
||||
virtual bool Finit();
|
||||
|
||||
void* Get_hWnd() const { return hWnd; }
|
||||
int Get_SizeX() const { return SizeX; }
|
||||
int Get_SizeY() const { return SizeY; }
|
||||
|
||||
void SetClipMode(int m){ clipMode = m; }
|
||||
int GetClipMode() const { return clipMode; }
|
||||
|
||||
void SetClip(){ SetClip(0,0,SizeX,SizeY); }
|
||||
|
||||
void GetClip(int& l,int& t,int& r,int& b) const {
|
||||
l = clipCoords[GR_LEFT];
|
||||
t = clipCoords[GR_TOP];
|
||||
r = clipCoords[GR_RIGHT];
|
||||
b = clipCoords[GR_BOTTOM];
|
||||
}
|
||||
|
||||
void SetClip(int l,int t,int r,int b){
|
||||
if(l < 0) l = 0;
|
||||
if(r > SizeX) r = SizeX;
|
||||
|
||||
if(t < 0) t = 0;
|
||||
if(b > SizeY) b = SizeY;
|
||||
|
||||
clipCoords[GR_LEFT] = l; clipCoords[GR_TOP] = t;
|
||||
clipCoords[GR_RIGHT] = r; clipCoords[GR_BOTTOM] = b;
|
||||
}
|
||||
|
||||
void LimitClip(int l,int t,int r,int b){
|
||||
if(clipCoords[GR_LEFT] < l) clipCoords[GR_LEFT] = l;
|
||||
if(clipCoords[GR_TOP] < t) clipCoords[GR_TOP] = t;
|
||||
if(clipCoords[GR_RIGHT] > r) clipCoords[GR_RIGHT] = r;
|
||||
if(clipCoords[GR_BOTTOM] > b) clipCoords[GR_BOTTOM] = b;
|
||||
}
|
||||
|
||||
int ClipCheck(int x,int y){
|
||||
if(x >= clipCoords[GR_LEFT] && x < clipCoords[GR_RIGHT] && y >= clipCoords[GR_TOP] && y < clipCoords[GR_BOTTOM])
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ClipCheck(int x,int y,int sx,int sy){
|
||||
if(x - sx >= clipCoords[GR_LEFT] && x + sx < clipCoords[GR_RIGHT] && y - sy >= clipCoords[GR_TOP] && y + sy < clipCoords[GR_BOTTOM])
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual bool Flush(int x,int y,int sx,int sy) = 0;
|
||||
virtual bool StretchFlush(int x_dest,int y_dest,int sx_dest,int sy_dest,int x_src,int y_src,int sx_src,int sy_src) = 0;
|
||||
|
||||
bool Flush(){ return Flush(0,0,SizeX,SizeY); }
|
||||
bool FlushChanges();
|
||||
|
||||
void Fill(int val);
|
||||
|
||||
void PutSpr(int x,int y,int sx,int sy,const unsigned char* p,int mode);
|
||||
void PutSpr(int x,int y,int sx,int sy,const unsigned char* p,int mode,float scale);
|
||||
void PutSpr_rle(int x,int y,int sx,int sy,const rleBuffer* p,int mode,bool alpha_flag);
|
||||
void PutSpr_rle(int x,int y,int sx,int sy,const rleBuffer* p,int mode,float scale,bool alpha_flag);
|
||||
void PutSpr_a(int x,int y,int sx,int sy,const unsigned char* p,int mode);
|
||||
void PutSpr_a(int x,int y,int sx,int sy,const unsigned char* p,int mode,float scale);
|
||||
|
||||
void PutSpr_rot(const Vect2i& pos, const Vect2i& size, const unsigned char* data, bool has_alpha, int mode, float angle);
|
||||
void PutSpr_rot(const Vect2i& pos, const Vect2i& size, const unsigned char* data, bool has_alpha, int mode, float angle, const Vect2f& scale);
|
||||
void PutSpr_rle_rot(const Vect2i& pos, const Vect2i& size, const rleBuffer* data, bool has_alpha, int mode, float angle);
|
||||
void PutSpr_rle_rot(const Vect2i& pos, const Vect2i& size, const rleBuffer* data, bool has_alpha, int mode, float angle, const Vect2f& scale);
|
||||
|
||||
void PutSprMask_rot(const Vect2i& pos, const Vect2i& size, const unsigned char* data, bool has_alpha, unsigned mask_color, int mask_alpha, int mode, float angle);
|
||||
void PutSprMask_rot(const Vect2i& pos, const Vect2i& size, const unsigned char* data, bool has_alpha, unsigned mask_color, int mask_alpha, int mode, float angle, const Vect2f& scale);
|
||||
void PutSprMask_rle_rot(const Vect2i& pos, const Vect2i& size, const rleBuffer* data, bool has_alpha, unsigned mask_color, int mask_alpha, int mode, float angle);
|
||||
void PutSprMask_rle_rot(const Vect2i& pos, const Vect2i& size, const rleBuffer* data, bool has_alpha, unsigned mask_color, int mask_alpha, int mode, float angle, const Vect2f& scale);
|
||||
|
||||
void PutSprMask(int x,int y,int sx,int sy,const unsigned char* p,unsigned mask_color,int mask_alpha,int mode);
|
||||
void PutSprMask(int x,int y,int sx,int sy,const unsigned char* p,unsigned mask_color,int mask_alpha,int mode,float scale);
|
||||
void PutSprMask_rle(int x,int y,int sx,int sy,const rleBuffer* p,unsigned mask_color,int mask_alpha,int mode,bool alpha_flag);
|
||||
void PutSprMask_rle(int x,int y,int sx,int sy,const rleBuffer* p,unsigned mask_color,int mask_alpha,int mode,float scale,bool alpha_flag);
|
||||
void PutSprMask_a(int x,int y,int sx,int sy,const unsigned char* p,unsigned mask_color,int mask_alpha,int mode);
|
||||
void PutSprMask_a(int x,int y,int sx,int sy,const unsigned char* p,unsigned mask_color,int mask_alpha,int mode,float scale);
|
||||
|
||||
void PutTileSpr(int x, int y, const grTileSprite& sprite, bool has_alpha, int mode);
|
||||
|
||||
void PutChar(int x,int y,unsigned color,int font_sx,int font_sy,const unsigned char* font_alpha,const grScreenRegion& char_region);
|
||||
|
||||
void DrawSprContour_a(int x,int y,int sx,int sy,const unsigned char* p,int contour_color,int mode);
|
||||
void DrawSprContour_a(int x,int y,int sx,int sy,const unsigned char* p,int contour_color,int mode,float scale);
|
||||
void DrawSprContour(int x,int y,int sx,int sy,const unsigned char* p,int contour_color,int mode);
|
||||
void DrawSprContour(int x,int y,int sx,int sy,const unsigned char* p,int contour_color,int mode,float scale);
|
||||
void DrawSprContour(int x,int y,int sx,int sy,const rleBuffer* p,int contour_color,int mode,bool alpha_flag);
|
||||
void DrawSprContour(int x,int y,int sx,int sy,const rleBuffer* p,int contour_color,int mode,float scale,bool alpha_flag);
|
||||
|
||||
bool DrawText(int x,int y,unsigned color,const char* str,int hspace = 0,int vspace = 0,const grFont* font = NULL);
|
||||
bool DrawAlignedText(int x,int y,int sx,int sy,unsigned color,const char* str,grTextAlign align = GR_ALIGN_LEFT,int hspace = 0,int vspace = 0,const grFont* font = NULL);
|
||||
bool DrawParsedText(int x,int y,int sx,int sy,unsigned color,const UI_TextParser* parser,grTextAlign align = GR_ALIGN_LEFT,const grFont* font = NULL);
|
||||
int TextWidth(const char* str,int hspace = 0,const grFont* font = NULL,bool first_string_only = false) const;
|
||||
int TextHeight(const char* str,int vspace = 0,const grFont* font = NULL) const;
|
||||
|
||||
#ifdef _GR_ENABLE_ZBUFFER
|
||||
void PutSpr_z(int x,int y,int z,int sx,int sy,const unsigned char* p,int mode);
|
||||
void PutSpr_z(int x,int y,int z,int sx,int sy,const unsigned char* p,int mode,float scale);
|
||||
void PutSpr_rle_z(int x,int y,int z,int sx,int sy,const rleBuffer* p,int mode,bool alpha_flag);
|
||||
void PutSpr_rle_z(int x,int y,int z,int sx,int sy,const rleBuffer* p,int mode,float scale,bool alpha_flag);
|
||||
void PutSpr_a_z(int x,int y,int z,int sx,int sy,const unsigned char* p,int mode);
|
||||
void PutSpr_a_z(int x,int y,int z,int sx,int sy,const unsigned char* p,int mode,float scale);
|
||||
#endif
|
||||
|
||||
void Erase(int x,int y,int sx,int sy,int col);
|
||||
void Erase(int x,int y,int sx,int sy,int r,int g,int b);
|
||||
|
||||
void SetPixel(int x,int y,int col);
|
||||
void SetPixelFast(int x,int y,int col);
|
||||
void SetPixelFast(int x,int y,int r,int g,int b);
|
||||
|
||||
void SetPixel(int x,int y,int r,int g,int b);
|
||||
|
||||
void GetPixel(int x,int y,unsigned& col);
|
||||
void GetPixel(int x,int y,unsigned& r,unsigned& g,unsigned& b);
|
||||
|
||||
void Line(int x1,int y1,int x2,int y2,int col,int line_style = 0,bool inverse_col = false);
|
||||
|
||||
#ifdef _GR_ENABLE_ZBUFFER
|
||||
void Line_z(int x1,int y1,int z1,int x2,int y2,int z2,int col,int line_style = 0);
|
||||
#endif
|
||||
|
||||
void LineTo(int x,int y,int len,int dir,int col,int line_style = 0);
|
||||
void Rectangle(int x,int y,int sx,int sy,int outcol,int incol,int mode,int line_style = 0);
|
||||
void RectangleAlpha(int x,int y,int sx,int sy,unsigned color,int alpha);
|
||||
|
||||
int PalettedMode() const { return (flags & GR_PALETTE); }
|
||||
|
||||
grPixelFormat pixel_format() const { return pixel_format_; }
|
||||
void set_pixel_format(grPixelFormat mode){ pixel_format_ = mode; }
|
||||
|
||||
inline int bytes_per_pixel() const {
|
||||
switch(pixel_format_){
|
||||
case GR_RGB565:
|
||||
case GR_ARGB1555:
|
||||
return 2;
|
||||
case GR_RGB888:
|
||||
return 3;
|
||||
case GR_ARGB8888:
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum { // ìàñêè äëÿ high color ðåæèìîâ
|
||||
mask_565_r = 0xFFFF & (0x001F << 11),
|
||||
mask_565_g = 0xFFFF & (0x003F << 5),
|
||||
mask_565_b = 0xFFFF & (0x001F << 0),
|
||||
|
||||
mask_555_r = 0xFFFF & (0x001F << 10),
|
||||
mask_555_g = 0xFFFF & (0x001F << 5),
|
||||
mask_555_b = 0xFFFF & (0x001F << 0)
|
||||
};
|
||||
|
||||
inline unsigned make_rgb(unsigned color) const {
|
||||
switch(pixel_format_){
|
||||
case GR_RGB565:
|
||||
return make_rgb565u((color >> 0) & 0xFF,(color >> 8) & 0xFF,(color >> 16) & 0xFF);
|
||||
case GR_ARGB1555:
|
||||
return make_rgb555u((color >> 0) & 0xFF,(color >> 8) & 0xFF,(color >> 16) & 0xFF);
|
||||
case GR_RGB888:
|
||||
case GR_ARGB8888:
|
||||
return color;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline unsigned make_rgb(unsigned r,unsigned g,unsigned b) const {
|
||||
switch(pixel_format_){
|
||||
case GR_RGB565:
|
||||
return make_rgb565u(r,g,b);
|
||||
case GR_ARGB1555:
|
||||
return make_rgb555u(r,g,b);
|
||||
case GR_RGB888:
|
||||
case GR_ARGB8888:
|
||||
return ((b << 16) | (g << 8) | r);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/// Îáðàáîò÷èê ââîäà ñèìâîëà
|
||||
typedef bool (*char_input_hanler_t)(int input);
|
||||
static char_input_hanler_t set_input_handler(char_input_hanler_t h){
|
||||
char_input_hanler_t old_h = input_handler_;
|
||||
input_handler_ = h;
|
||||
return old_h;
|
||||
}
|
||||
|
||||
static bool handle_char_input(int input){
|
||||
if(input_handler_) return (*input_handler_)(input);
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline unsigned make_rgb888(unsigned r,unsigned g,unsigned b){ return ((b << 16) | (g << 8) | r); }
|
||||
|
||||
static inline unsigned short make_rgb565u(unsigned r,unsigned g,unsigned b){ return (((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3) << 0)); }
|
||||
static inline unsigned short make_rgb555u(unsigned r,unsigned g,unsigned b){ return (((r >> 3) << 10) | ((g >> 3) << 5) | ((b >> 3) << 0)); }
|
||||
|
||||
static inline void split_rgb565u(unsigned col,unsigned& r,unsigned& g,unsigned& b){
|
||||
r = ((col & mask_565_r) >> 11) << 3;
|
||||
g = ((col & mask_565_g) >> 5) << 2;
|
||||
b = ((col & mask_565_b) >> 0) << 3;
|
||||
}
|
||||
static inline void split_rgb555u(unsigned col,unsigned& r,unsigned& g,unsigned& b){
|
||||
r = ((col & mask_555_r) >> 10) << 3;
|
||||
g = ((col & mask_555_g) >> 5) << 3;
|
||||
b = ((col & mask_555_b) >> 0) << 3;
|
||||
}
|
||||
|
||||
static inline void split_rgb888(unsigned col,unsigned& r,unsigned& g,unsigned& b){
|
||||
r = (col >> 0) & 0xFF;
|
||||
g = (col >> 8) & 0xFF;
|
||||
b = (col >> 16) & 0xFF;
|
||||
}
|
||||
|
||||
static inline unsigned short make_rgb565(unsigned r,unsigned g,unsigned b){ return ((r << 11) | (g << 5) | (b << 0)); }
|
||||
static inline unsigned short make_rgb555(unsigned r,unsigned g,unsigned b){ return ((r << 10) | (g << 5) | (b << 0)); }
|
||||
|
||||
static inline unsigned short alpha_blend_565(unsigned short pic_col,unsigned short scr_col,unsigned a){
|
||||
if(a != 255){
|
||||
if(a)
|
||||
return pic_col + (((((scr_col & mask_565_r) * a) >> 8) & mask_565_r) |
|
||||
((((scr_col & mask_565_g) * a) >> 8) & mask_565_g) |
|
||||
((((scr_col & mask_565_b) * a) >> 8) & mask_565_b));
|
||||
else
|
||||
return pic_col;
|
||||
}
|
||||
else
|
||||
return scr_col;
|
||||
}
|
||||
|
||||
static inline unsigned short alpha_blend_555(unsigned short pic_col,unsigned short scr_col,unsigned a){
|
||||
if(a != 255){
|
||||
if(a)
|
||||
return pic_col + (((((scr_col & mask_555_r) * a) >> 8) & mask_555_r) |
|
||||
((((scr_col & mask_555_g) * a) >> 8) & mask_555_g) |
|
||||
((((scr_col & mask_555_b) * a) >> 8) & mask_555_b));
|
||||
else
|
||||
return pic_col;
|
||||
}
|
||||
else
|
||||
return scr_col;
|
||||
}
|
||||
|
||||
const void* mouse_cursor() const { return mouse_cursor_; }
|
||||
void set_default_mouse_cursor(){ mouse_cursor_ = default_mouse_cursor_; }
|
||||
void set_null_mouse_cursor(){ mouse_cursor_ = NULL; }
|
||||
|
||||
static grDispatcher* instance(void* hwnd);
|
||||
|
||||
bool is_mouse_hidden() const { return hide_mouse_; }
|
||||
void HideMouse(){ hide_mouse_ = true; }
|
||||
void ShowMouse(){ hide_mouse_ = false; }
|
||||
|
||||
bool clip_line(int& x0,int& y0,int& x1,int& y1) const;
|
||||
bool clip_line(int& x0,int& y0,int& z0,int& x1,int& y1,int& z1) const;
|
||||
bool clip_rectangle(int& x,int& y,int& pic_x,int& pic_y,int& pic_sx,int& pic_sy) const;
|
||||
|
||||
bool is_rectangle_visible(int x,int y,int sx,int sy) const {
|
||||
if(x + sx < 0 || x >= SizeX || y + sy < 0 || y >= SizeY) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool clip_rectangle(int& x,int& y,int& sx,int& sy) const {
|
||||
int x1 = x + sx;
|
||||
int y1 = y + sy;
|
||||
|
||||
if(x < clipCoords[0]) x = clipCoords[0];
|
||||
if(x1 >= clipCoords[2]) x1 = clipCoords[2] - 1;
|
||||
|
||||
if(y < clipCoords[1]) y = clipCoords[1];
|
||||
if(y1 >= clipCoords[3]) y1 = clipCoords[3] - 1;
|
||||
|
||||
sx = x1 - x;
|
||||
sy = y1 - y;
|
||||
|
||||
if(sx <= 0 || sy <= 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void clear_changes_mask();
|
||||
|
||||
typedef std::vector<grScreenRegion> regions_container_t;
|
||||
typedef regions_container_t::const_iterator region_iterator;
|
||||
|
||||
const regions_container_t& changed_regions() const { return changed_regions_; }
|
||||
void build_changed_regions();
|
||||
bool invalidate_region(const grScreenRegion& reg);
|
||||
|
||||
static inline grDispatcher* instance(){ return dispatcher_ptr_; }
|
||||
static inline grDispatcher* set_instance(grDispatcher* p){ grDispatcher* old_p = dispatcher_ptr_; dispatcher_ptr_ = p; return old_p; }
|
||||
|
||||
static inline const char* wnd_class_name(){ return wnd_class_name_; }
|
||||
|
||||
typedef void (*restore_handler_t)();
|
||||
static restore_handler_t set_restore_handler(restore_handler_t h){
|
||||
restore_handler_t old_h = restore_handler_;
|
||||
restore_handler_ = h;
|
||||
return old_h;
|
||||
}
|
||||
|
||||
static bool is_active(){ return is_active_; }
|
||||
static void activate(bool state){
|
||||
if(state && !is_active_){
|
||||
if(restore_handler_)
|
||||
(*restore_handler_)();
|
||||
}
|
||||
is_active_ = state;
|
||||
}
|
||||
|
||||
typedef void (*maximize_handler_t)();
|
||||
maximize_handler_t set_maximize_handler(maximize_handler_t p)
|
||||
{
|
||||
maximize_handler_t old_handler = maximize_handler_;
|
||||
maximize_handler_ = p;
|
||||
return old_handler;
|
||||
}
|
||||
maximize_handler_t maximize_handler() const { return maximize_handler_; }
|
||||
|
||||
char* temp_buffer(int size);
|
||||
|
||||
static bool convert_sprite(grPixelFormat src_fmt,grPixelFormat& dest_fmt,int sx,int sy,unsigned char* data,bool& has_alpha);
|
||||
|
||||
static grFont* load_font(const char* file_name);
|
||||
static void set_default_font(grFont* p){ default_font_ = p; }
|
||||
static grFont* get_default_font() { return default_font_; }
|
||||
protected:
|
||||
|
||||
int flags;
|
||||
|
||||
int wndPosX;
|
||||
int wndPosY;
|
||||
int wndSizeX;
|
||||
int wndSizeY;
|
||||
|
||||
int SizeX;
|
||||
int SizeY;
|
||||
|
||||
grPixelFormat pixel_format_;
|
||||
void* hWnd;
|
||||
|
||||
char* screenBuf;
|
||||
int* yTable;
|
||||
|
||||
char* temp_buffer_;
|
||||
int temp_buffer_size_;
|
||||
|
||||
private:
|
||||
|
||||
int clipMode;
|
||||
int clipCoords[4];
|
||||
|
||||
bool hide_mouse_;
|
||||
void* mouse_cursor_;
|
||||
static void* default_mouse_cursor_;
|
||||
|
||||
enum
|
||||
{
|
||||
clLEFT = 1,
|
||||
clRIGHT = 2,
|
||||
clBOTTOM = 4,
|
||||
clTOP = 8
|
||||
};
|
||||
|
||||
inline int clip_out_code(int x,int y) const
|
||||
{
|
||||
int code = 0;
|
||||
if(y >= clipCoords[3])
|
||||
code |= clTOP;
|
||||
else if(y < clipCoords[1])
|
||||
code |= clBOTTOM;
|
||||
if(x >= clipCoords[2])
|
||||
code |= clRIGHT;
|
||||
else if(x < clipCoords[0])
|
||||
code |= clLEFT;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
#ifdef _GR_ENABLE_ZBUFFER
|
||||
zbuf_t* zbuffer_;
|
||||
|
||||
bool alloc_zbuffer(int sx,int sy);
|
||||
bool free_zbuffer();
|
||||
bool clear_zbuffer();
|
||||
|
||||
zbuf_t get_z(int x,int y){ return zbuffer_[x + y * SizeX]; }
|
||||
void put_z(int x,int y,int z){ zbuffer_[x + y * SizeX] = z; }
|
||||
#endif
|
||||
|
||||
typedef std::vector<char> changes_mask_t;
|
||||
|
||||
enum {
|
||||
changes_mask_tile_ = 16,
|
||||
changes_mask_tile_shift_ = 4
|
||||
};
|
||||
|
||||
int changes_mask_size_x_;
|
||||
int changes_mask_size_y_;
|
||||
|
||||
changes_mask_t changes_mask_;
|
||||
|
||||
regions_container_t changed_regions_;
|
||||
|
||||
maximize_handler_t maximize_handler_;
|
||||
|
||||
static char_input_hanler_t input_handler_;
|
||||
|
||||
static grFont* default_font_;
|
||||
|
||||
static bool is_active_;
|
||||
static restore_handler_t restore_handler_;
|
||||
|
||||
static grDispatcher* dispatcher_ptr_;
|
||||
static char* wnd_class_name_;
|
||||
|
||||
void PutSpr_rot90(const Vect2i& pos, const Vect2i& size, const unsigned char* data, bool has_alpha, int mode, float angle);
|
||||
};
|
||||
|
||||
#endif /* __GR_DISPATCHER_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,604 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "gr_dispatcher.h"
|
||||
#include "rle_compress.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
#ifdef _GR_ENABLE_ZBUFFER
|
||||
void grDispatcher::PutSpr_rle_z(int x,int y,int z,int sx,int sy,const class rleBuffer* p,int mode,bool alpha_flag)
|
||||
{
|
||||
int px = 0;
|
||||
int py = 0;
|
||||
|
||||
int psx = sx;
|
||||
int psy = sy;
|
||||
|
||||
if(!clip_rectangle(x,y,px,py,psx,psy)) return;
|
||||
|
||||
if(bytes_per_pixel() == 4){
|
||||
int dx = -4;
|
||||
int zdx = -1;
|
||||
int dy = -1;
|
||||
|
||||
int x3 = x * 4;
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
x3 += (psx - 1) * 4;
|
||||
x += psx - 1;
|
||||
px = sx - px - psx;
|
||||
}
|
||||
else {
|
||||
dx = 4;
|
||||
zdx = 1;
|
||||
}
|
||||
|
||||
psx += px;
|
||||
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
y += psy - 1;
|
||||
py = sy - py - psy;
|
||||
}
|
||||
else
|
||||
dy = 1;
|
||||
|
||||
for(int i = 0; i < psy; i ++){
|
||||
unsigned char* scr_buf = reinterpret_cast<unsigned char*>(screenBuf + yTable[y] + x3);
|
||||
zbuf_t* z_buf = zbuffer_ + SizeX * y + x;
|
||||
|
||||
const char* rle_header = p -> header_ptr(py + i);
|
||||
const unsigned* rle_data = p -> data_ptr(py + i);
|
||||
|
||||
int j = 0;
|
||||
char count = 0;
|
||||
while(j < px){
|
||||
count = *rle_header++;
|
||||
if(count > 0){
|
||||
if(count + j <= px){
|
||||
j += count;
|
||||
rle_data++;
|
||||
count = 0;
|
||||
}
|
||||
else {
|
||||
count -= px - j;
|
||||
j = px;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(j - count <= px){
|
||||
j -= count;
|
||||
rle_data -= count;
|
||||
count = 0;
|
||||
}
|
||||
else {
|
||||
count += px - j;
|
||||
rle_data += px - j;
|
||||
j = px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!alpha_flag){
|
||||
while(j < psx){
|
||||
if(count > 0){
|
||||
while(count && j < psx){
|
||||
if(*rle_data){
|
||||
*reinterpret_cast<unsigned*>(scr_buf) = *rle_data;
|
||||
*z_buf = z;
|
||||
}
|
||||
z_buf += zdx;
|
||||
scr_buf += dx;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
rle_data++;
|
||||
}
|
||||
else {
|
||||
if(count < 0){
|
||||
count = -count;
|
||||
while(count && j < psx){
|
||||
if(*rle_data){
|
||||
*reinterpret_cast<unsigned*>(scr_buf) = *rle_data++;
|
||||
*z_buf = z;
|
||||
}
|
||||
z_buf += zdx;
|
||||
scr_buf += dx;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = *rle_header++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while(j < psx){
|
||||
if(count > 0){
|
||||
while(count && j < psx){
|
||||
unsigned a = reinterpret_cast<const unsigned char*>(rle_data)[3];
|
||||
if(a != 255){
|
||||
scr_buf[0] = reinterpret_cast<const unsigned char*>(rle_data)[0] + ((a * scr_buf[0]) >> 8);
|
||||
scr_buf[1] = reinterpret_cast<const unsigned char*>(rle_data)[1] + ((a * scr_buf[1]) >> 8);
|
||||
scr_buf[2] = reinterpret_cast<const unsigned char*>(rle_data)[2] + ((a * scr_buf[2]) >> 8);
|
||||
*z_buf = z;
|
||||
}
|
||||
z_buf += zdx;
|
||||
scr_buf += dx;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
rle_data++;
|
||||
}
|
||||
else {
|
||||
if(count < 0){
|
||||
count = -count;
|
||||
while(count && j < psx){
|
||||
unsigned a = reinterpret_cast<const unsigned char*>(rle_data)[3];
|
||||
if(a != 255){
|
||||
scr_buf[0] = reinterpret_cast<const unsigned char*>(rle_data)[0] + ((a * scr_buf[0]) >> 8);
|
||||
scr_buf[1] = reinterpret_cast<const unsigned char*>(rle_data)[1] + ((a * scr_buf[1]) >> 8);
|
||||
scr_buf[2] = reinterpret_cast<const unsigned char*>(rle_data)[2] + ((a * scr_buf[2]) >> 8);
|
||||
*z_buf = z;
|
||||
}
|
||||
rle_data++;
|
||||
z_buf += zdx;
|
||||
scr_buf += dx;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = *rle_header++;
|
||||
}
|
||||
}
|
||||
y += dy;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(bytes_per_pixel() == 3){
|
||||
int dx = -3;
|
||||
int zdx = -1;
|
||||
int dy = -1;
|
||||
|
||||
int x3 = x * 3;
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
x3 += psx * 3 - 3;
|
||||
x += psx - 1;
|
||||
px = sx - px - psx;
|
||||
}
|
||||
else {
|
||||
dx = 3;
|
||||
zdx = 1;
|
||||
}
|
||||
|
||||
psx += px;
|
||||
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
y += psy - 1;
|
||||
py = sy - py - psy;
|
||||
}
|
||||
else
|
||||
dy = 1;
|
||||
|
||||
for(int i = 0; i < psy; i ++){
|
||||
unsigned char* scr_buf = reinterpret_cast<unsigned char*>(screenBuf + yTable[y] + x3);
|
||||
zbuf_t* z_buf = zbuffer_ + SizeX * y + x;
|
||||
|
||||
const char* rle_header = p -> header_ptr(py + i);
|
||||
const unsigned* rle_data = p -> data_ptr(py + i);
|
||||
|
||||
int j = 0;
|
||||
char count = 0;
|
||||
while(j < px){
|
||||
count = *rle_header++;
|
||||
if(count > 0){
|
||||
if(count + j <= px){
|
||||
j += count;
|
||||
rle_data++;
|
||||
count = 0;
|
||||
}
|
||||
else {
|
||||
count -= px - j;
|
||||
j = px;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(j - count <= px){
|
||||
j -= count;
|
||||
rle_data -= count;
|
||||
count = 0;
|
||||
}
|
||||
else {
|
||||
count += px - j;
|
||||
rle_data += px - j;
|
||||
j = px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!alpha_flag){
|
||||
while(j < psx){
|
||||
if(count > 0){
|
||||
while(count && j < psx){
|
||||
if(*rle_data){
|
||||
scr_buf[0] = reinterpret_cast<const unsigned char*>(rle_data)[0];
|
||||
scr_buf[1] = reinterpret_cast<const unsigned char*>(rle_data)[1];
|
||||
scr_buf[2] = reinterpret_cast<const unsigned char*>(rle_data)[2];
|
||||
*z_buf = z;
|
||||
}
|
||||
z_buf += zdx;
|
||||
scr_buf += dx;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
rle_data++;
|
||||
}
|
||||
else {
|
||||
if(count < 0){
|
||||
count = -count;
|
||||
while(count && j < psx){
|
||||
if(*rle_data){
|
||||
scr_buf[0] = reinterpret_cast<const unsigned char*>(rle_data)[0];
|
||||
scr_buf[1] = reinterpret_cast<const unsigned char*>(rle_data)[1];
|
||||
scr_buf[2] = reinterpret_cast<const unsigned char*>(rle_data)[2];
|
||||
*z_buf = z;
|
||||
}
|
||||
scr_buf += dx;
|
||||
z_buf += zdx;
|
||||
rle_data++;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = *rle_header++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while(j < psx){
|
||||
if(count > 0){
|
||||
while(count && j < psx){
|
||||
unsigned a = reinterpret_cast<const unsigned char*>(rle_data)[3];
|
||||
if(a != 255){
|
||||
scr_buf[0] = reinterpret_cast<const unsigned char*>(rle_data)[0] + ((a * scr_buf[0]) >> 8);
|
||||
scr_buf[1] = reinterpret_cast<const unsigned char*>(rle_data)[1] + ((a * scr_buf[1]) >> 8);
|
||||
scr_buf[2] = reinterpret_cast<const unsigned char*>(rle_data)[2] + ((a * scr_buf[2]) >> 8);
|
||||
*z_buf = z;
|
||||
}
|
||||
scr_buf += dx;
|
||||
z_buf += zdx;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
rle_data++;
|
||||
}
|
||||
else {
|
||||
if(count < 0){
|
||||
count = -count;
|
||||
while(count && j < psx){
|
||||
unsigned a = reinterpret_cast<const unsigned char*>(rle_data)[3];
|
||||
if(a != 255){
|
||||
scr_buf[0] = reinterpret_cast<const unsigned char*>(rle_data)[0] + ((a * scr_buf[0]) >> 8);
|
||||
scr_buf[1] = reinterpret_cast<const unsigned char*>(rle_data)[1] + ((a * scr_buf[1]) >> 8);
|
||||
scr_buf[2] = reinterpret_cast<const unsigned char*>(rle_data)[2] + ((a * scr_buf[2]) >> 8);
|
||||
*z_buf = z;
|
||||
}
|
||||
scr_buf += dx;
|
||||
z_buf += zdx;
|
||||
rle_data++;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = *rle_header++;
|
||||
}
|
||||
}
|
||||
y += dy;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(bytes_per_pixel() == 2){
|
||||
int dx = -1;
|
||||
int dy = -1;
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
x += (psx - 1) * 2;
|
||||
px = sx - px - psx;
|
||||
}
|
||||
else
|
||||
dx = 1;
|
||||
|
||||
psx += px;
|
||||
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
y += psy - 1;
|
||||
py = sy - py - psy;
|
||||
}
|
||||
else
|
||||
dy = 1;
|
||||
|
||||
for(int i = 0; i < psy; i ++){
|
||||
unsigned short* scr_buf = reinterpret_cast<unsigned short*>(screenBuf + yTable[y] + x * 2);
|
||||
zbuf_t* z_buf = zbuffer_ + y * SizeX + x;
|
||||
|
||||
const char* rle_header = p -> header_ptr(py + i);
|
||||
const unsigned* rle_data = p -> data_ptr(py + i);
|
||||
|
||||
int j = 0;
|
||||
char count = 0;
|
||||
while(j < px){
|
||||
count = *rle_header++;
|
||||
if(count > 0){
|
||||
if(count + j <= px){
|
||||
j += count;
|
||||
rle_data++;
|
||||
count = 0;
|
||||
}
|
||||
else {
|
||||
count -= px - j;
|
||||
j = px;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(j - count <= px){
|
||||
j -= count;
|
||||
rle_data -= count;
|
||||
count = 0;
|
||||
}
|
||||
else {
|
||||
count += px - j;
|
||||
rle_data += px - j;
|
||||
j = px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!alpha_flag){
|
||||
while(j < psx){
|
||||
if(count > 0){
|
||||
while(count && j < psx){
|
||||
if(*rle_data){
|
||||
*scr_buf = reinterpret_cast<const unsigned short*>(rle_data)[0];
|
||||
*z_buf = z;
|
||||
}
|
||||
scr_buf += dx;
|
||||
z_buf += dx;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
rle_data++;
|
||||
}
|
||||
else {
|
||||
if(count < 0){
|
||||
count = -count;
|
||||
while(count && j < psx){
|
||||
if(*rle_data){
|
||||
*scr_buf = reinterpret_cast<const unsigned short*>(rle_data)[0];
|
||||
*z_buf = z;
|
||||
}
|
||||
scr_buf += dx;
|
||||
z_buf += dx;
|
||||
rle_data++;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = *rle_header++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const unsigned mask_r = (pixel_format_ == GR_RGB565) ? mask_565_r : mask_555_r;
|
||||
const unsigned mask_g = (pixel_format_ == GR_RGB565) ? mask_565_g : mask_555_g;
|
||||
const unsigned mask_b = (pixel_format_ == GR_RGB565) ? mask_565_b : mask_555_b;
|
||||
|
||||
while(j < psx){
|
||||
if(count > 0){
|
||||
while(count && j < psx){
|
||||
unsigned a = reinterpret_cast<const unsigned short*>(rle_data)[1];
|
||||
if(a != 255){
|
||||
unsigned sc = *scr_buf;
|
||||
*scr_buf = reinterpret_cast<const unsigned short*>(rle_data)[0] +
|
||||
(((((sc & mask_r) * a) >> 8) & mask_r) |
|
||||
((((sc & mask_g) * a) >> 8) & mask_g) |
|
||||
((((sc & mask_b) * a) >> 8) & mask_b));
|
||||
*z_buf = z;
|
||||
}
|
||||
scr_buf += dx;
|
||||
z_buf += dx;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
rle_data++;
|
||||
}
|
||||
else {
|
||||
if(count < 0){
|
||||
count = -count;
|
||||
while(count && j < psx){
|
||||
unsigned a = reinterpret_cast<const unsigned short*>(rle_data)[1];
|
||||
if(a != 255){
|
||||
unsigned sc = *scr_buf;
|
||||
*scr_buf = reinterpret_cast<const unsigned short*>(rle_data)[0] +
|
||||
(((((sc & mask_r) * a) >> 8) & mask_r) |
|
||||
((((sc & mask_g) * a) >> 8) & mask_g) |
|
||||
((((sc & mask_b) * a) >> 8) & mask_b));
|
||||
*z_buf = z;
|
||||
}
|
||||
scr_buf += dx;
|
||||
z_buf += dx;
|
||||
rle_data++;
|
||||
count--;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = *rle_header++;
|
||||
}
|
||||
}
|
||||
y += dy;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void grDispatcher::PutSpr_rle_z(int x,int y,int z,int sx,int sy,const class rleBuffer* p,int mode,float scale,bool alpha_flag)
|
||||
{
|
||||
int sx_dest = round(float(sx) * scale);
|
||||
int sy_dest = round(float(sy) * scale);
|
||||
|
||||
if(!sx_dest || !sy_dest) return;
|
||||
|
||||
int dx = (sx << 16) / sx_dest;
|
||||
int dy = (sy << 16) / sy_dest;
|
||||
int fx = (1 << 15);
|
||||
int fy = (1 << 15);
|
||||
|
||||
int x0 = 0;
|
||||
int x1 = sx_dest;
|
||||
int ix = 1;
|
||||
|
||||
int y0 = 0;
|
||||
int y1 = sy_dest;
|
||||
int iy = 1;
|
||||
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
y0 = sy_dest,
|
||||
y1 = 0;
|
||||
iy = -1;
|
||||
}
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
x0 = sx_dest,
|
||||
x1 = 0;
|
||||
ix = -1;
|
||||
}
|
||||
|
||||
if(bytes_per_pixel() == 2){
|
||||
if(!alpha_flag){
|
||||
const unsigned short* line_src = reinterpret_cast<const unsigned short*>(rleBuffer::get_buffer(0));
|
||||
|
||||
for(int i = y0; i != y1; i += iy){
|
||||
p -> decode_line(fy >> 16);
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
for(int j = x0; j != x1; j += ix){
|
||||
if(ClipCheck(x + j,y + i)){
|
||||
unsigned cl = line_src[(fx >> 16) << 1];
|
||||
if(cl){
|
||||
SetPixelFast(x + j,y + i,cl);
|
||||
put_z(x + j,y + i,z);
|
||||
}
|
||||
}
|
||||
fx += dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
const unsigned short* line_src = reinterpret_cast<const unsigned short*>(rleBuffer::get_buffer(0));
|
||||
|
||||
const unsigned mask_r = (pixel_format_ == GR_RGB565) ? mask_565_r : mask_555_r;
|
||||
const unsigned mask_g = (pixel_format_ == GR_RGB565) ? mask_565_g : mask_555_g;
|
||||
const unsigned mask_b = (pixel_format_ == GR_RGB565) ? mask_565_b : mask_555_b;
|
||||
|
||||
for(int i = y0; i != y1; i += iy){
|
||||
p -> decode_line(fy >> 16);
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
for(int j = x0; j != x1; j += ix){
|
||||
if(ClipCheck(x + j,y + i)){
|
||||
unsigned a = line_src[((fx >> 16) << 1) + 1];
|
||||
if(a != 255){
|
||||
unsigned cl = line_src[(fx >> 16) << 1];
|
||||
|
||||
unsigned scl;
|
||||
GetPixel(x + j,y + i,scl);
|
||||
|
||||
scl = cl +
|
||||
(((((scl & mask_r) * a) >> 8) & mask_r) |
|
||||
((((scl & mask_g) * a) >> 8) & mask_g) |
|
||||
((((scl & mask_b) * a) >> 8) & mask_b));
|
||||
|
||||
SetPixelFast(x + j,y + i,scl);
|
||||
put_z(x + j,y + i,z);
|
||||
}
|
||||
}
|
||||
fx += dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(bytes_per_pixel() == 3 || bytes_per_pixel() == 4){
|
||||
int sx3 = sx * 3;
|
||||
const unsigned char* line_src = rleBuffer::get_buffer(0);
|
||||
|
||||
if(!alpha_flag){
|
||||
for(int i = y0; i != y1; i += iy){
|
||||
p -> decode_line(fy >> 16);
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
for(int j = x0; j != x1; j += ix){
|
||||
if(ClipCheck(x + j,y + i)){
|
||||
int idx = (fx >> 16) << 2;
|
||||
|
||||
unsigned r = line_src[idx + 2];
|
||||
unsigned g = line_src[idx + 1];
|
||||
unsigned b = line_src[idx + 0];
|
||||
|
||||
if(r || g || b){
|
||||
SetPixelFast(x + j,y + i,r,g,b);
|
||||
put_z(x + j,y + i,z);
|
||||
}
|
||||
}
|
||||
fx += dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(int i = y0; i != y1; i += iy){
|
||||
p -> decode_line(fy >> 16);
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
for(int j = x0; j != x1; j += ix){
|
||||
if(ClipCheck(x + j,y + i)){
|
||||
int idx = (fx >> 16) << 2;
|
||||
|
||||
unsigned a = line_src[idx + 3];
|
||||
if(a != 255){
|
||||
unsigned sr,sg,sb;
|
||||
GetPixel(x + j,y + i,sr,sg,sb);
|
||||
|
||||
unsigned r = line_src[idx + 2] + ((a * sr) >> 8);
|
||||
unsigned g = line_src[idx + 1] + ((a * sg) >> 8);
|
||||
unsigned b = line_src[idx + 0] + ((a * sb) >> 8);
|
||||
|
||||
SetPixelFast(x + j,y + i,r,g,b);
|
||||
put_z(x + j,y + i,z);
|
||||
}
|
||||
}
|
||||
|
||||
fx += dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,568 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "gr_dispatcher.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
#ifdef _GR_ENABLE_ZBUFFER
|
||||
void grDispatcher::PutSpr_a_z(int x,int y,int z,int sx,int sy,const unsigned char* p,int mode,float scale)
|
||||
{
|
||||
int i,j,sx_dest,sy_dest;
|
||||
|
||||
sx_dest = round(float(sx) * scale);
|
||||
sy_dest = round(float(sy) * scale);
|
||||
|
||||
if(!sx_dest || !sy_dest) return;
|
||||
|
||||
int dx = (sx << 16) / sx_dest;
|
||||
int dy = (sy << 16) / sy_dest;
|
||||
int fx = (1 << 15);
|
||||
int fy = (1 << 15);
|
||||
|
||||
int x0 = 0;
|
||||
int x1 = sx_dest;
|
||||
int ix = 1;
|
||||
|
||||
int y0 = 0;
|
||||
int y1 = sy_dest;
|
||||
int iy = 1;
|
||||
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
y0 = sy_dest,
|
||||
y1 = 0;
|
||||
iy = -1;
|
||||
}
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
x0 = sx_dest,
|
||||
x1 = 0;
|
||||
ix = -1;
|
||||
}
|
||||
|
||||
if(bytes_per_pixel() == 2){
|
||||
const unsigned short* src = reinterpret_cast<const unsigned short*>(p);
|
||||
sx <<= 1;
|
||||
if(pixel_format_ == GR_ARGB1555){
|
||||
for(i = y0; i != y1; i += iy){
|
||||
const unsigned short* line_src = src + ((fy >> 16) * sx);
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
for(j = x0; j != x1; j += ix){
|
||||
unsigned a = line_src[((fx >> 16) << 1) + 1];
|
||||
if(a != 255 && ClipCheck(x + j,y + i)){
|
||||
unsigned sc;
|
||||
GetPixel(x + j,y + i,sc);
|
||||
SetPixel(x + j,y + i,alpha_blend_555(line_src[(fx >> 16) << 1],sc,a));
|
||||
put_z(x + j,y + i,z);
|
||||
}
|
||||
fx += dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(i = y0; i != y1; i += iy){
|
||||
const unsigned short* line_src = src + ((fy >> 16) * sx);
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
for(j = x0; j != x1; j += ix){
|
||||
unsigned a = line_src[((fx >> 16) << 1) + 1];
|
||||
if(a != 255 && ClipCheck(x + j,y + i)){
|
||||
unsigned sc;
|
||||
GetPixel(x + j,y + i,sc);
|
||||
SetPixel(x + j,y + i,alpha_blend_565(line_src[(fx >> 16) << 1],sc,a));
|
||||
put_z(x + j,y + i,z);
|
||||
}
|
||||
fx += dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(bytes_per_pixel() == 3 || bytes_per_pixel() == 4){
|
||||
int sx3 = sx * 4;
|
||||
|
||||
for(i = y0; i != y1; i += iy){
|
||||
const unsigned char* line_src = p + ((fy >> 16) * sx3);
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
for(j = x0; j != x1; j += ix){
|
||||
int idx = (fx >> 16) << 2;
|
||||
unsigned a = line_src[idx + 3];
|
||||
if(a != 255 && ClipCheck(x + j,y + i)){
|
||||
unsigned sr,sg,sb;
|
||||
GetPixel(x + j,y + i,sr,sg,sb);
|
||||
|
||||
unsigned r = line_src[idx + 2] + ((a * sr) >> 8);
|
||||
unsigned g = line_src[idx + 1] + ((a * sg) >> 8);
|
||||
unsigned b = line_src[idx + 0] + ((a * sb) >> 8);
|
||||
|
||||
SetPixel(x + j,y + i,r,g,b);
|
||||
put_z(x + j,y + i,z);
|
||||
}
|
||||
|
||||
fx += dx;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void grDispatcher::PutSpr_z(int x,int y,int z,int sx,int sy,const unsigned char* p,int mode,float scale)
|
||||
{
|
||||
int sx_dest = round(float(sx) * scale);
|
||||
int sy_dest = round(float(sy) * scale);
|
||||
|
||||
if(!sx_dest || !sy_dest) return;
|
||||
|
||||
int dx = (sx << 16) / sx_dest;
|
||||
int dy = (sy << 16) / sy_dest;
|
||||
int fx = (1 << 15);
|
||||
int fy = (1 << 15);
|
||||
|
||||
int x0 = 0;
|
||||
int x1 = sx_dest;
|
||||
int ix = 1;
|
||||
|
||||
int y0 = 0;
|
||||
int y1 = sy_dest;
|
||||
int iy = 1;
|
||||
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
y0 = sy_dest,
|
||||
y1 = 0;
|
||||
iy = -1;
|
||||
}
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
x0 = sx_dest,
|
||||
x1 = 0;
|
||||
ix = -1;
|
||||
}
|
||||
|
||||
if(bytes_per_pixel() == 2){
|
||||
const unsigned short* src = reinterpret_cast<const unsigned short*>(p);
|
||||
|
||||
for(int i = y0; i != y1; i += iy){
|
||||
const unsigned short* line_src = src + ((fy >> 16) * sx);
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
for(int j = x0; j != x1; j += ix){
|
||||
unsigned cl = line_src[fx >> 16];
|
||||
if(cl){
|
||||
SetPixel(x + j,y + i,cl);
|
||||
put_z(x + j,y + i,z);
|
||||
}
|
||||
fx += dx;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(bytes_per_pixel() == 3){
|
||||
int sx3 = sx * 3;
|
||||
for(int i = y0; i != y1; i += iy){
|
||||
const unsigned char* line_src = p + ((fy >> 16) * sx3);
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
for(int j = x0; j != x1; j += ix){
|
||||
int idx = (fx >> 16) * 3;
|
||||
|
||||
unsigned r = line_src[idx + 2];
|
||||
unsigned g = line_src[idx + 1];
|
||||
unsigned b = line_src[idx + 0];
|
||||
|
||||
if(r || g || b){
|
||||
SetPixel(x + j,y + i,r,g,b);
|
||||
put_z(x + j,y + i,z);
|
||||
}
|
||||
|
||||
fx += dx;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(bytes_per_pixel() == 4){
|
||||
const unsigned* src = reinterpret_cast<const unsigned*>(p);
|
||||
|
||||
for(int i = y0; i != y1; i += iy){
|
||||
const unsigned* line_src = src + ((fy >> 16) * sx);
|
||||
|
||||
fy += dy;
|
||||
fx = (1 << 15);
|
||||
|
||||
for(int j = x0; j != x1; j += ix){
|
||||
unsigned cl = line_src[fx >> 16];
|
||||
if(cl){
|
||||
SetPixel(x + j,y + i,cl);
|
||||
put_z(x + j,y + i,z);
|
||||
}
|
||||
fx += dx;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void grDispatcher::PutSpr_a_z(int x,int y,int z,int sx,int sy,const unsigned char* p,int mode)
|
||||
{
|
||||
int px = 0;
|
||||
int py = 0;
|
||||
|
||||
int psx = sx;
|
||||
int psy = sy;
|
||||
|
||||
if(!clip_rectangle(x,y,px,py,psx,psy)) return;
|
||||
|
||||
if(bytes_per_pixel() == 4){
|
||||
int dx = -4;
|
||||
int zdx = -1;
|
||||
int dy = -1;
|
||||
|
||||
int x4 = x * 4;
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
x4 += (psx - 1) * 4;
|
||||
x += psx - 1;
|
||||
px = sx - px - psx;
|
||||
}
|
||||
else {
|
||||
dx = 4;
|
||||
zdx = 1;
|
||||
}
|
||||
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
y += psy - 1;
|
||||
py = sy - py - psy;
|
||||
}
|
||||
else
|
||||
dy = 1;
|
||||
|
||||
int px3 = px * 4;
|
||||
int sx3 = sx * 4;
|
||||
|
||||
const unsigned char* data_ptr = p + py * sx3;
|
||||
|
||||
for(int i = 0; i < psy; i ++){
|
||||
unsigned char* scr_buf = reinterpret_cast<unsigned char*>(screenBuf + yTable[y] + x4);
|
||||
zbuf_t* zbuf = zbuffer_ + y * SizeX + x;
|
||||
const unsigned char* data_line = data_ptr + px3;
|
||||
|
||||
for(int j = 0; j < psx; j ++){
|
||||
unsigned a = data_line[3];
|
||||
if(a != 255){
|
||||
if(a){
|
||||
scr_buf[0] = data_line[0] + ((a * scr_buf[0]) >> 8);
|
||||
scr_buf[1] = data_line[1] + ((a * scr_buf[1]) >> 8);
|
||||
scr_buf[2] = data_line[2] + ((a * scr_buf[2]) >> 8);
|
||||
}
|
||||
else {
|
||||
scr_buf[0] = data_line[0];
|
||||
scr_buf[1] = data_line[1];
|
||||
scr_buf[2] = data_line[2];
|
||||
}
|
||||
*zbuf = z;
|
||||
}
|
||||
scr_buf += dx;
|
||||
zbuf += zdx;
|
||||
data_line += 4;
|
||||
}
|
||||
data_ptr += sx3;
|
||||
y += dy;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(bytes_per_pixel() == 3){
|
||||
int dx = -3;
|
||||
int zdx = -1;
|
||||
int dy = -1;
|
||||
|
||||
int x3 = x * 3;
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
x3 += (psx - 1) * 3;
|
||||
x += psx - 1;
|
||||
px = sx - px - psx;
|
||||
}
|
||||
else {
|
||||
dx = 3;
|
||||
zdx = 1;
|
||||
}
|
||||
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
y += psy - 1;
|
||||
py = sy - py - psy;
|
||||
}
|
||||
else
|
||||
dy = 1;
|
||||
|
||||
int px3 = px * 4;
|
||||
int sx3 = sx * 4;
|
||||
|
||||
const unsigned char* data_ptr = p + py * sx3;
|
||||
|
||||
for(int i = 0; i < psy; i ++){
|
||||
unsigned char* scr_buf = reinterpret_cast<unsigned char*>(screenBuf + yTable[y] + x3);
|
||||
zbuf_t* zbuf = zbuffer_ + y * SizeX + x;
|
||||
const unsigned char* data_line = data_ptr + px3;
|
||||
|
||||
for(int j = 0; j < psx; j ++){
|
||||
unsigned a = data_line[3];
|
||||
if(a != 255){
|
||||
if(a){
|
||||
scr_buf[0] = data_line[0] + ((a * scr_buf[0]) >> 8);
|
||||
scr_buf[1] = data_line[1] + ((a * scr_buf[1]) >> 8);
|
||||
scr_buf[2] = data_line[2] + ((a * scr_buf[2]) >> 8);
|
||||
}
|
||||
else {
|
||||
scr_buf[0] = data_line[0];
|
||||
scr_buf[1] = data_line[1];
|
||||
scr_buf[2] = data_line[2];
|
||||
}
|
||||
*zbuf = z;
|
||||
}
|
||||
scr_buf += dx;
|
||||
zbuf += zdx;
|
||||
data_line += 4;
|
||||
}
|
||||
data_ptr += sx3;
|
||||
y += dy;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(bytes_per_pixel() == 2){
|
||||
int dx = -1;
|
||||
int dy = -1;
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
x += psx - 1;
|
||||
px = sx - px - psx;
|
||||
}
|
||||
else
|
||||
dx = 1;
|
||||
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
y += psy - 1;
|
||||
py = sy - py - psy;
|
||||
}
|
||||
else
|
||||
dy = 1;
|
||||
|
||||
x <<= 1;
|
||||
sx <<= 1;
|
||||
px <<= 1;
|
||||
|
||||
const unsigned short* data_ptr = reinterpret_cast<const unsigned short*>(p) + py * sx;
|
||||
|
||||
if(pixel_format_ == GR_RGB565){
|
||||
for(int i = 0; i < psy; i ++){
|
||||
unsigned short* scr_buf = reinterpret_cast<unsigned short*>(screenBuf + yTable[y] + x);
|
||||
zbuf_t* zbuf = zbuffer_ + y * SizeX + (x >> 1);
|
||||
const unsigned short* data_line = data_ptr + px;
|
||||
|
||||
for(int j = 0; j < psx; j ++){
|
||||
unsigned a = data_line[1];
|
||||
*scr_buf = alpha_blend_565(*data_line,*scr_buf,a);
|
||||
if(a != 255) *zbuf = z;
|
||||
scr_buf += dx;
|
||||
zbuf += dx;
|
||||
data_line += 2;
|
||||
}
|
||||
data_ptr += sx;
|
||||
y += dy;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(int i = 0; i < psy; i ++){
|
||||
unsigned short* scr_buf = reinterpret_cast<unsigned short*>(screenBuf + yTable[y] + x);
|
||||
zbuf_t* zbuf = zbuffer_ + y * SizeX + (x >> 1);
|
||||
const unsigned short* data_line = data_ptr + px;
|
||||
|
||||
for(int j = 0; j < psx; j ++){
|
||||
unsigned a = data_line[1];
|
||||
*scr_buf = alpha_blend_555(*data_line,*scr_buf,a);
|
||||
if(a != 255) *zbuf = z;
|
||||
scr_buf += dx;
|
||||
zbuf += dx;
|
||||
data_line += 2;
|
||||
}
|
||||
data_ptr += sx;
|
||||
y += dy;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void grDispatcher::PutSpr_z(int x,int y,int z,int sx,int sy,const unsigned char* p,int mode)
|
||||
{
|
||||
int px = 0;
|
||||
int py = 0;
|
||||
|
||||
int psx = sx;
|
||||
int psy = sy;
|
||||
|
||||
if(!clip_rectangle(x,y,px,py,psx,psy)) return;
|
||||
|
||||
if(bytes_per_pixel() == 4){
|
||||
int dx = -4;
|
||||
int zdx = -1;
|
||||
int dy = -1;
|
||||
|
||||
int x4 = x * 4;
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
x4 += psx * 4 - 4;
|
||||
x += psx - 1;
|
||||
px = sx - px - psx;
|
||||
}
|
||||
else {
|
||||
dx = 4;
|
||||
zdx = 1;
|
||||
}
|
||||
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
y += psy - 1;
|
||||
py = sy - py - psy;
|
||||
}
|
||||
else
|
||||
dy = 1;
|
||||
|
||||
int px3 = px * 3;
|
||||
int sx3 = sx * 3;
|
||||
|
||||
const unsigned char* data_ptr = p + py * sx3;
|
||||
|
||||
for(int i = 0; i < psy; i ++){
|
||||
unsigned char* scr_buf = reinterpret_cast<unsigned char*>(screenBuf + yTable[y] + x4);
|
||||
zbuf_t* zbuf = zbuffer_ + y * SizeX + x;
|
||||
const unsigned char* data_line = data_ptr + px3;
|
||||
|
||||
for(int j = 0; j < psx; j ++){
|
||||
if(data_line[0] || data_line[1] || data_line[2]){
|
||||
scr_buf[0] = data_line[0];
|
||||
scr_buf[1] = data_line[1];
|
||||
scr_buf[2] = data_line[2];
|
||||
*zbuf = z;
|
||||
}
|
||||
scr_buf += dx;
|
||||
zbuf += zdx;
|
||||
data_line += 3;
|
||||
}
|
||||
|
||||
data_ptr += sx3;
|
||||
y += dy;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(bytes_per_pixel() == 3){
|
||||
int dx = -3;
|
||||
int zdx = -1;
|
||||
int dy = -1;
|
||||
|
||||
int x3 = x * 3;
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
x3 += psx * 3 - 3;
|
||||
x += psx - 1;
|
||||
px = sx - px - psx;
|
||||
}
|
||||
else {
|
||||
dx = 3;
|
||||
zdx = 1;
|
||||
}
|
||||
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
y += psy - 1;
|
||||
py = sy - py - psy;
|
||||
}
|
||||
else
|
||||
dy = 1;
|
||||
|
||||
int px3 = px * 3;
|
||||
int sx3 = sx * 3;
|
||||
|
||||
const unsigned char* data_ptr = p + py * sx3;
|
||||
|
||||
for(int i = 0; i < psy; i ++){
|
||||
unsigned char* scr_buf = reinterpret_cast<unsigned char*>(screenBuf + yTable[y] + x3);
|
||||
zbuf_t* zbuf = zbuffer_ + y * SizeX + x;
|
||||
const unsigned char* data_line = data_ptr + px3;
|
||||
|
||||
for(int j = 0; j < psx; j ++){
|
||||
if(data_line[0] || data_line[1] || data_line[2]){
|
||||
scr_buf[0] = data_line[0];
|
||||
scr_buf[1] = data_line[1];
|
||||
scr_buf[2] = data_line[2];
|
||||
*zbuf = z;
|
||||
}
|
||||
scr_buf += dx;
|
||||
zbuf += zdx;
|
||||
data_line += 3;
|
||||
}
|
||||
|
||||
data_ptr += sx3;
|
||||
y += dy;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(bytes_per_pixel() == 2){
|
||||
int dx = -1;
|
||||
int dy = -1;
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
x += psx - 1;
|
||||
px = sx - px - psx;
|
||||
}
|
||||
else
|
||||
dx = 1;
|
||||
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
y += psy - 1;
|
||||
py = sy - py - psy;
|
||||
}
|
||||
else
|
||||
dy = 1;
|
||||
|
||||
x <<= 1;
|
||||
|
||||
const unsigned short* data_ptr = reinterpret_cast<const unsigned short*>(p) + py * sx;
|
||||
|
||||
for(int i = 0; i < psy; i ++){
|
||||
unsigned short* scr_buf = reinterpret_cast<unsigned short*>(screenBuf + yTable[y] + x);
|
||||
zbuf_t* zbuf = zbuffer_ + y * SizeX + x;
|
||||
const unsigned short* data_line = data_ptr + px;
|
||||
|
||||
for(int j = 0; j < psx; j ++){
|
||||
if(*data_line){
|
||||
*scr_buf = *data_line;
|
||||
*zbuf = z;
|
||||
}
|
||||
zbuf += dx;
|
||||
scr_buf += dx;
|
||||
data_line++;
|
||||
}
|
||||
|
||||
data_ptr += sx;
|
||||
y += dy;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "gr_dispatcher.h"
|
||||
#include "gr_font.h"
|
||||
|
||||
#include "qd_file_manager.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
grFont::grFont() : alpha_buffer_(NULL)
|
||||
{
|
||||
size_x_ = size_y_ = 0;
|
||||
alpha_buffer_sx_ = alpha_buffer_sy_ = 0;
|
||||
|
||||
chars_.reserve(256);
|
||||
}
|
||||
|
||||
grFont::~grFont()
|
||||
{
|
||||
delete alpha_buffer_;
|
||||
}
|
||||
|
||||
bool grFont::load(const char* fname)
|
||||
{
|
||||
XBuffer str(MAX_PATH);
|
||||
str < fname < ".tga";
|
||||
|
||||
XStream fh;
|
||||
|
||||
fh.open(str, XS_IN);
|
||||
if(load_alpha(fh)){
|
||||
str.init();
|
||||
str < fname <".idx";
|
||||
|
||||
fh.open(str, XS_IN);
|
||||
if(load_index(fh))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool grFont::load_index(XStream& fh)
|
||||
{
|
||||
int buf_sz = fh.size();
|
||||
char* buf = new char[buf_sz];
|
||||
|
||||
fh.read(buf,buf_sz);
|
||||
fh.close();
|
||||
|
||||
XBuffer XBuf(buf,buf_sz);
|
||||
|
||||
int num_ch,sx,sy;
|
||||
XBuf >= sx >= sy >= num_ch;
|
||||
|
||||
grFontChar chr;
|
||||
for(int i = 0; i < num_ch; i ++){
|
||||
int x,y,sx,sy;
|
||||
XBuf >= chr.code_ >= x >= y >= sx >= sy;
|
||||
chr.region_ = grScreenRegion(x,y,sx,sy);
|
||||
chars_.push_back(chr);
|
||||
|
||||
if(sx > size_x_) size_x_ = sx;
|
||||
if(sy > size_y_) size_y_ = sy;
|
||||
}
|
||||
|
||||
delete buf;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool grFont::load_index(XZipStream& fh)
|
||||
{
|
||||
int buf_sz = fh.size();
|
||||
char* buf = new char[buf_sz];
|
||||
|
||||
fh.read(buf,buf_sz);
|
||||
fh.close();
|
||||
|
||||
XBuffer XBuf(buf,buf_sz);
|
||||
|
||||
int num_ch,sx,sy;
|
||||
XBuf >= sx >= sy >= num_ch;
|
||||
|
||||
grFontChar chr;
|
||||
for(int i = 0; i < num_ch; i ++){
|
||||
int x,y,sx,sy;
|
||||
XBuf >= chr.code_ >= x >= y >= sx >= sy;
|
||||
chr.region_ = grScreenRegion(x,y,sx,sy);
|
||||
chars_.push_back(chr);
|
||||
|
||||
if(sx > size_x_) size_x_ = sx;
|
||||
if(sy > size_y_) size_y_ = sy;
|
||||
}
|
||||
|
||||
delete buf;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool grFont::load_alpha(XStream& fh)
|
||||
{
|
||||
unsigned char header[18];
|
||||
fh.read(header,18);
|
||||
|
||||
if(header[0]) // Length of Image ID field
|
||||
fh.seek(header[0],XS_CUR);
|
||||
|
||||
if(header[1]) // Color map type (0 is no color map)
|
||||
return false;
|
||||
|
||||
if(header[2] != 2 && header[2] != 3) // TGA file type
|
||||
return false;
|
||||
|
||||
int sx = alpha_buffer_sx_ = header[12] + (header[13] << 8);
|
||||
int sy = alpha_buffer_sy_ = header[14] + (header[15] << 8);
|
||||
|
||||
int colors = header[16];
|
||||
int flags = header[17];
|
||||
|
||||
int ssx = sx * colors / 8;
|
||||
|
||||
alpha_buffer_ = new unsigned char[ssx * sy];
|
||||
|
||||
if(!(flags & 0x20)){
|
||||
int idx = (sy - 1) * ssx;
|
||||
for(int i = 0; i < sy; i ++){
|
||||
fh.read(alpha_buffer_ + idx,ssx);
|
||||
idx -= ssx;
|
||||
}
|
||||
}
|
||||
else
|
||||
fh.read(alpha_buffer_,ssx * sy);
|
||||
|
||||
fh.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool grFont::load_alpha(XZipStream& fh)
|
||||
{
|
||||
unsigned char header[18];
|
||||
fh.read(header,18);
|
||||
|
||||
if(header[0]) // Length of Image ID field
|
||||
return false;
|
||||
// fh.seek(header[0],XS_CUR);
|
||||
|
||||
if(header[1]) // Color map type (0 is no color map)
|
||||
return false;
|
||||
|
||||
if(header[2] != 2 && header[2] != 3) // TGA file type
|
||||
return false;
|
||||
|
||||
int sx = alpha_buffer_sx_ = header[12] + (header[13] << 8);
|
||||
int sy = alpha_buffer_sy_ = header[14] + (header[15] << 8);
|
||||
|
||||
int colors = header[16];
|
||||
int flags = header[17];
|
||||
|
||||
int ssx = sx * colors / 8;
|
||||
|
||||
alpha_buffer_ = new unsigned char[ssx * sy];
|
||||
|
||||
if(!(flags & 0x20)){
|
||||
int idx = (sy - 1) * ssx;
|
||||
for(int i = 0; i < sy; i ++){
|
||||
fh.read(alpha_buffer_ + idx,ssx);
|
||||
idx -= ssx;
|
||||
}
|
||||
}
|
||||
else
|
||||
fh.read(alpha_buffer_,ssx * sy);
|
||||
|
||||
fh.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifndef __GR_FONT_H__
|
||||
#define __GR_FONT_H__
|
||||
|
||||
#include "gr_screen_region.h"
|
||||
|
||||
class XZipStream;
|
||||
|
||||
class grFont
|
||||
{
|
||||
public:
|
||||
grFont();
|
||||
~grFont();
|
||||
|
||||
bool load(const char* fname);
|
||||
|
||||
bool load_index(XStream& fh);
|
||||
bool load_alpha(XStream& fh);
|
||||
|
||||
bool load_index(XZipStream& fh);
|
||||
bool load_alpha(XZipStream& fh);
|
||||
|
||||
int size_x() const { return size_x_; }
|
||||
int size_y() const { return size_y_; }
|
||||
|
||||
int alpha_buffer_size_x() const { return alpha_buffer_sx_; }
|
||||
int alpha_buffer_size_y() const { return alpha_buffer_sy_; }
|
||||
|
||||
const unsigned char* alpha_buffer() const { return alpha_buffer_; }
|
||||
|
||||
const grScreenRegion& find_char(int code) const
|
||||
{
|
||||
grFontCharVector::const_iterator it = std::find(chars_.begin(),chars_.end(),code);
|
||||
if(it != chars_.end()) return it -> region_;
|
||||
|
||||
return grScreenRegion::EMPTY;
|
||||
}
|
||||
|
||||
int char_width(int code) const { return code == ' ' ? size_x()/2 : find_char(code).size_x(); }
|
||||
|
||||
private:
|
||||
|
||||
int size_x_;
|
||||
int size_y_;
|
||||
|
||||
int alpha_buffer_sx_;
|
||||
int alpha_buffer_sy_;
|
||||
unsigned char* alpha_buffer_;
|
||||
|
||||
struct grFontChar
|
||||
{
|
||||
grFontChar() : code_(-1) { }
|
||||
|
||||
int code_;
|
||||
grScreenRegion region_;
|
||||
|
||||
bool operator == (int code) const { return (code_ == code); }
|
||||
};
|
||||
|
||||
typedef std::vector<grFontChar> grFontCharVector;
|
||||
grFontCharVector chars_;
|
||||
};
|
||||
|
||||
#endif /* __GR_FONT_H__ */
|
||||
@@ -0,0 +1,13 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "gr_screen_region.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
const grScreenRegion grScreenRegion::EMPTY = grScreenRegion(0,0,0,0);
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
|
||||
#ifndef __GR_SCREEN_REGION_H__
|
||||
#define __GR_SCREEN_REGION_H__
|
||||
|
||||
//! Ïðÿìîóãîëüíàÿ îáëàñòü íà ýêðàíå.
|
||||
class grScreenRegion
|
||||
{
|
||||
public:
|
||||
grScreenRegion() : x_(0), y_(0), size_x_(0), size_y_(0) {}
|
||||
grScreenRegion(int x,int y,int sx,int sy) : x_(x), y_(y), size_x_(sx), size_y_(sy) {}
|
||||
|
||||
bool operator == (const grScreenRegion& reg) const {
|
||||
if(x_ == reg.x_ && y_ == reg.y_ && size_x_ == reg.size_x_ && size_y_ == reg.size_y_)
|
||||
return true;
|
||||
|
||||
if(is_empty() && reg.is_empty())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator != (const grScreenRegion& reg) const {
|
||||
if(is_empty() && reg.is_empty())
|
||||
return false;
|
||||
|
||||
if(x_ != reg.x_ || y_ != reg.y_ || size_x_ != reg.size_x_ || size_y_ != reg.size_y_)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
grScreenRegion& operator += (const grScreenRegion& reg){
|
||||
if(reg.is_empty()) return *this;
|
||||
|
||||
if(is_empty()){
|
||||
*this = reg;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int x0 = (min_x() < reg.min_x()) ? min_x() : reg.min_x();
|
||||
int x1 = (max_x() > reg.max_x()) ? max_x() : reg.max_x();
|
||||
|
||||
int y0 = (min_y() < reg.min_y()) ? min_y() : reg.min_y();
|
||||
int y1 = (max_y() > reg.max_y()) ? max_y() : reg.max_y();
|
||||
|
||||
x_ = (x0 + x1)/2;
|
||||
y_ = (y0 + y1)/2;
|
||||
|
||||
size_x_ = x1 - x0;
|
||||
size_y_ = y1 - y0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
int x() const { return x_; }
|
||||
int y() const { return y_; }
|
||||
|
||||
int size_x() const { return size_x_; }
|
||||
int size_y() const { return size_y_; }
|
||||
|
||||
int min_x() const { return x_ - size_x_/2; }
|
||||
int max_x() const { return x_ + size_x_/2; }
|
||||
|
||||
int min_y() const { return y_ - size_y_/2; }
|
||||
int max_y() const { return y_ + size_y_/2; }
|
||||
|
||||
void move(int dx,int dy){
|
||||
x_ += dx;
|
||||
y_ += dy;
|
||||
}
|
||||
|
||||
bool is_empty() const { return (!size_x_ || !size_y_); }
|
||||
|
||||
bool is_inside(int x,int y) const { if(x >= min_x() && x < max_x() && y >= min_y() && y < max_y()) return true; return false; }
|
||||
|
||||
void clear(){ size_x_ = 0; }
|
||||
|
||||
static const grScreenRegion EMPTY;
|
||||
|
||||
private:
|
||||
|
||||
//! êîîðäèíàòû öåíòðà îáëàñòè
|
||||
int x_;
|
||||
int y_;
|
||||
|
||||
int size_x_;
|
||||
int size_y_;
|
||||
};
|
||||
|
||||
#endif /* __GR_SCREEN_REGION_H__ */
|
||||
@@ -0,0 +1,285 @@
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "gr_dispatcher.h"
|
||||
#include "gr_tile_animation.h"
|
||||
|
||||
CompressionProgressHandler grTileAnimation::progressHandler_;
|
||||
void* grTileAnimation::progressHandlerContext_;
|
||||
|
||||
grTileAnimation::grTileAnimation()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void grTileAnimation::clear()
|
||||
{
|
||||
hasAlpha_ = false;
|
||||
|
||||
compression_ = TILE_UNCOMPRESSED;
|
||||
|
||||
frameCount_ = 0;
|
||||
frameSize_ = Vect2i(0,0);
|
||||
frameTileSize_ = Vect2i(0,0);
|
||||
|
||||
frameIndex_.clear();
|
||||
FrameIndex(frameIndex_).swap(frameIndex_);
|
||||
|
||||
tileOffsets_.clear();
|
||||
TileOffsets(tileOffsets_).swap(tileOffsets_);
|
||||
|
||||
tileData_.clear();
|
||||
TileData(tileData_).swap(tileData_);
|
||||
}
|
||||
|
||||
void grTileAnimation::init(int frame_count, const Vect2i& frame_size, bool alpha_flag)
|
||||
{
|
||||
clear();
|
||||
|
||||
hasAlpha_ = alpha_flag;
|
||||
|
||||
frameSize_ = frame_size;
|
||||
|
||||
frameTileSize_.x = (frame_size.x + GR_TILE_SPRITE_SIZE_X/2) / GR_TILE_SPRITE_SIZE_X;
|
||||
frameTileSize_.y = (frame_size.y + GR_TILE_SPRITE_SIZE_Y/2) / GR_TILE_SPRITE_SIZE_Y;
|
||||
|
||||
frameIndex_.reserve(frame_count * frameTileSize_.x * frameTileSize_.y);
|
||||
|
||||
tileOffsets_.reserve(frame_count * frameTileSize_.x * frameTileSize_.y + 1);
|
||||
tileOffsets_.push_back(0);
|
||||
|
||||
tileData_.reserve(frame_count * frameTileSize_.x * frameTileSize_.y * GR_TILE_SPRITE_SIZE);
|
||||
|
||||
frameCount_ = frame_count;
|
||||
}
|
||||
|
||||
void grTileAnimation::compact()
|
||||
{
|
||||
TileOffsets(tileOffsets_).swap(tileOffsets_);
|
||||
TileData(tileData_).swap(tileData_);
|
||||
|
||||
__QDBG(appLog::default_log() << "òàéëîâàÿ àíèìàöèÿ: " << (frameIndex_.size() + tileData_.size() + tileOffsets_.size()) * 4 /1024 << " êáàéò\r\n");
|
||||
}
|
||||
|
||||
bool grTileAnimation::compress(grTileCompressionMethod method)
|
||||
{
|
||||
if(compression_ != TILE_UNCOMPRESSED)
|
||||
return false;
|
||||
|
||||
compression_ = method;
|
||||
|
||||
TileData tile_data;
|
||||
tile_data.reserve(tileData_.size());
|
||||
|
||||
TileOffsets tile_offsets;
|
||||
tile_offsets.reserve(tileOffsets_.size());
|
||||
tile_offsets.push_back(0);
|
||||
|
||||
TileData tile_vector = TileData(GR_TILE_SPRITE_SIZE * 4, 0);
|
||||
|
||||
int count = tileCount();
|
||||
for(int i = 0; i < count; i++){
|
||||
if(progressHandler_){
|
||||
int percent_done = 100 * (i + 1) / count;
|
||||
(*progressHandler_)(percent_done, progressHandlerContext_);
|
||||
}
|
||||
|
||||
unsigned* data = &*tileData_.begin() + i * GR_TILE_SPRITE_SIZE;
|
||||
|
||||
unsigned offs = tile_offsets.back();
|
||||
unsigned sz = grTileSprite::compress(data, &*tile_vector.begin(), method);
|
||||
tile_data.insert(tile_data.end(), tile_vector.begin(), tile_vector.begin() + sz);
|
||||
tile_offsets.push_back(offs + sz);
|
||||
}
|
||||
|
||||
tileData_.swap(tile_data);
|
||||
tileOffsets_.swap(tile_offsets);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
grTileSprite grTileAnimation::getTile(int tile_index) const
|
||||
{
|
||||
static unsigned tile_buf[GR_TILE_SPRITE_SIZE];
|
||||
|
||||
switch(compression_){
|
||||
case TILE_UNCOMPRESSED:
|
||||
return grTileSprite(&*tileData_.begin() + tileOffsets_[tile_index]);
|
||||
default:
|
||||
if(!grTileSprite::uncompress(&*tileData_.begin() + tileOffsets_[tile_index], GR_TILE_SPRITE_SIZE, tile_buf, compression_)){
|
||||
xassert(0 && "Íåèçâåñòíûé àëãîðèòì ñæàòèÿ");
|
||||
}
|
||||
return grTileSprite(tile_buf);
|
||||
}
|
||||
}
|
||||
|
||||
void grTileAnimation::addFrame(const unsigned* frame_data)
|
||||
{
|
||||
TileData tile_vector = TileData(GR_TILE_SPRITE_SIZE, 0);
|
||||
TileData tile_vector2 = TileData(GR_TILE_SPRITE_SIZE * 4, 0);
|
||||
|
||||
if(progressHandler_){
|
||||
int percent_done = 100 * (frameIndex_.size() / (frameTileSize_.x * frameTileSize_.y) + 1) / (frameCount_ ? frameCount_ : 1);
|
||||
(*progressHandler_)(percent_done, progressHandlerContext_);
|
||||
}
|
||||
|
||||
for(int i = 0; i < frameTileSize_.y; i ++){
|
||||
for(int j = 0; j < frameTileSize_.x; j ++){
|
||||
std::fill(tile_vector.begin(), tile_vector.end(), 0);
|
||||
|
||||
const unsigned* data_ptr = frame_data + j * GR_TILE_SPRITE_SIZE_X
|
||||
+ i * GR_TILE_SPRITE_SIZE_Y * frameSize_.x;
|
||||
|
||||
unsigned* tile_ptr = &tile_vector[0];
|
||||
for(int y = 0; y < GR_TILE_SPRITE_SIZE_Y; y++){
|
||||
if(y + i * GR_TILE_SPRITE_SIZE_Y >= frameSize_.y) break;
|
||||
|
||||
for(int x = 0; x < GR_TILE_SPRITE_SIZE_X; x++){
|
||||
if(x + j * GR_TILE_SPRITE_SIZE_X >= frameSize_.x) break;
|
||||
tile_ptr[x] = data_ptr[x];
|
||||
}
|
||||
|
||||
data_ptr += frameSize_.x;
|
||||
tile_ptr += GR_TILE_SPRITE_SIZE_X;
|
||||
}
|
||||
|
||||
int tile_id = -1;
|
||||
int tile_count = tileCount();
|
||||
for(int tile_idx = 0; tile_idx < tile_count; tile_idx++){
|
||||
grTileSprite tile = getTile(tile_idx);
|
||||
if(tile == grTileSprite(&tile_vector[0])){
|
||||
tile_id = tile_idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(tile_id == -1){
|
||||
unsigned sz = GR_TILE_SPRITE_SIZE;
|
||||
unsigned offs = tileOffsets_.back();
|
||||
|
||||
tileData_.insert(tileData_.end(), tile_vector.begin(), tile_vector.end());
|
||||
tileOffsets_.push_back(offs + sz);
|
||||
frameIndex_.push_back(tile_count);
|
||||
}
|
||||
else
|
||||
frameIndex_.push_back(tile_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool grTileAnimation::save(XStream& fh) const
|
||||
{
|
||||
fh < frameCount_ < frameSize_.x < frameSize_.y < frameTileSize_.x < frameTileSize_.y < (int)compression_;
|
||||
|
||||
fh < (int)frameIndex_.size();
|
||||
fh.write(&frameIndex_[0], frameIndex_.size() * sizeof(unsigned));
|
||||
|
||||
fh < (int)tileOffsets_.size();
|
||||
fh.write(&tileOffsets_[0], tileOffsets_.size() * sizeof(unsigned));
|
||||
|
||||
fh < (int)tileData_.size();
|
||||
fh.write(&tileData_[0], tileData_.size() * sizeof(unsigned));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool grTileAnimation::load(XStream& fh)
|
||||
{
|
||||
int size;
|
||||
fh > frameCount_ > frameSize_.x > frameSize_.y > frameTileSize_.x > frameTileSize_.y > size;
|
||||
|
||||
compression_ = grTileCompressionMethod(size);
|
||||
|
||||
fh > size;
|
||||
frameIndex_.resize(size);
|
||||
fh.read(&frameIndex_[0], size * sizeof(unsigned));
|
||||
|
||||
fh > size;
|
||||
tileOffsets_.resize(size);
|
||||
fh.read(&tileOffsets_[0], size * sizeof(unsigned));
|
||||
|
||||
fh > size;
|
||||
tileData_.resize(size);
|
||||
fh.read(&tileData_[0], size * sizeof(unsigned));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool grTileAnimation::load(XZipStream& fh)
|
||||
{
|
||||
int size;
|
||||
fh > frameCount_ > frameSize_.x > frameSize_.y > frameTileSize_.x > frameTileSize_.y > size;
|
||||
|
||||
compression_ = grTileCompressionMethod(size);
|
||||
|
||||
fh > size;
|
||||
frameIndex_.resize(size);
|
||||
fh.read(&frameIndex_[0], size * sizeof(unsigned));
|
||||
|
||||
fh > size;
|
||||
tileOffsets_.resize(size);
|
||||
fh.read(&tileOffsets_[0], size * sizeof(unsigned));
|
||||
|
||||
fh > size;
|
||||
tileData_.resize(size);
|
||||
fh.read(&tileData_[0], size * sizeof(unsigned));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void grTileAnimation::drawFrame(const Vect2i& position, int frame_index, int mode) const
|
||||
{
|
||||
Vect2i pos0 = position - frameSize_/2;
|
||||
|
||||
int dx = GR_TILE_SPRITE_SIZE_X;
|
||||
int dy = GR_TILE_SPRITE_SIZE_Y;
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
pos0.x += frameSize_.x - GR_TILE_SPRITE_SIZE_X;
|
||||
dx = -dx;
|
||||
}
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
pos0.y += frameSize_.y - GR_TILE_SPRITE_SIZE_Y;
|
||||
dy = -dy;
|
||||
}
|
||||
|
||||
// grDispatcher::instance()->Rectangle(position.x - frameSize_.x/2, position.y - frameSize_.y/2, frameSize_.x, frameSize_.y, 0xFFFFF, 0, GR_OUTLINED);
|
||||
|
||||
const unsigned* index_ptr = &frameIndex_[0] + frameTileSize_.x * frameTileSize_.y * frame_index;
|
||||
|
||||
Vect2i pos = pos0;
|
||||
for(int i = 0; i < frameTileSize_.y; i++){
|
||||
pos.x = pos0.x;
|
||||
|
||||
for(int j = 0; j < frameTileSize_.x; j++){
|
||||
grDispatcher::instance()->PutTileSpr(pos.x, pos.y, getTile(*index_ptr++), hasAlpha_, mode);
|
||||
pos.x += dx;
|
||||
}
|
||||
|
||||
pos.y += dy;
|
||||
}
|
||||
}
|
||||
|
||||
void grTileAnimation::drawFrame(const Vect2i& position, int frame_index, float angle, int mode) const
|
||||
{
|
||||
unsigned char* buf = (unsigned char*)grDispatcher::instance()->temp_buffer(frameSize_.x * frameSize_.y * 4);
|
||||
|
||||
const unsigned* index_ptr = &frameIndex_[0] + frameTileSize_.x * frameTileSize_.y * frame_index;
|
||||
|
||||
for(int i = 0; i < frameTileSize_.y; i++){
|
||||
for(int j = 0; j < frameTileSize_.x; j++){
|
||||
unsigned char* buf_ptr = buf + (i * frameSize_.x + j) * 4;
|
||||
const unsigned char* data_ptr = (const unsigned char*)getTile(*index_ptr++).data();
|
||||
int dx = min(frameSize_.x - j * GR_TILE_SPRITE_SIZE_X, GR_TILE_SPRITE_SIZE_X) * 4;
|
||||
int dy = min(frameSize_.y - i * GR_TILE_SPRITE_SIZE_Y, GR_TILE_SPRITE_SIZE_Y);
|
||||
for(int k = 0; k < GR_TILE_SPRITE_SIZE_Y; k++){
|
||||
memcpy(buf_ptr, data_ptr, dx);
|
||||
data_ptr += GR_TILE_SPRITE_SIZE_X * 4;
|
||||
buf_ptr += frameSize_.x * 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
grDispatcher::instance()->PutSpr_rot(position, frameSize_, buf, hasAlpha_, mode, angle);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#ifndef __GR_TILE_ANIMATION_H__
|
||||
#define __GR_TILE_ANIMATION_H__
|
||||
|
||||
#include "gr_tile_sprite.h"
|
||||
|
||||
typedef void (*CompressionProgressHandler)(int percents_loaded, void* context);
|
||||
|
||||
class grTileAnimation
|
||||
{
|
||||
public:
|
||||
grTileAnimation();
|
||||
|
||||
bool isEmpty() const { return !frameCount_; }
|
||||
|
||||
void clear();
|
||||
|
||||
int frameCount() const { return frameCount_; }
|
||||
const Vect2i& frameSize() const { return frameSize_; }
|
||||
const Vect2i& frameTileSize() const { return frameTileSize_; }
|
||||
int tileCount() const { return tileOffsets_.size() - 1; }
|
||||
|
||||
void init(int frame_count, const Vect2i& frame_size, bool alpha_flag);
|
||||
|
||||
void compact();
|
||||
|
||||
bool compress(grTileCompressionMethod method);
|
||||
|
||||
grTileSprite getTile(int tile_index) const;
|
||||
|
||||
void addFrame(const unsigned* frame_data);
|
||||
|
||||
bool save(XStream& fh) const;
|
||||
bool load(XStream& fh);
|
||||
bool load(XZipStream& fh);
|
||||
|
||||
void drawFrame(const Vect2i& position, int frame_index, int mode = 0) const;
|
||||
void drawFrame(const Vect2i& position, int frame_index, float angle, int mode = 0) const;
|
||||
|
||||
static void setProgressHandler(CompressionProgressHandler handler, void* context){
|
||||
progressHandler_ = handler;
|
||||
progressHandlerContext_ = context;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
grTileCompressionMethod compression_;
|
||||
|
||||
/// true åñëè åñòü àëüôà-êàíàë
|
||||
bool hasAlpha_;
|
||||
|
||||
/// ðàçìåðû êàäðà â ïèêñåëàõ
|
||||
/// ìîãóò áûòü íåâûðîâíåííûìè ïî ðàìåðàì òàéëà
|
||||
Vect2i frameSize_;
|
||||
|
||||
/// ðàçìåðû êàäðà â òàéëàõ
|
||||
Vect2i frameTileSize_;
|
||||
|
||||
/// êîëè÷åñòâî êàäðîâ
|
||||
int frameCount_;
|
||||
|
||||
typedef std::vector<unsigned> FrameIndex;
|
||||
/// èíäåêñ êàäðîâ - íîìåðà òàéëîâ, èç êîòîðûõ ñîñòîÿò êàäðû
|
||||
/// frameTileSize_.x * frameTileSize_.y íà êàäð
|
||||
FrameIndex frameIndex_;
|
||||
|
||||
typedef std::vector<unsigned> TileOffsets;
|
||||
/// ñìåùåíèÿ äî äàííûõ êàæäîãî òàéëà
|
||||
TileOffsets tileOffsets_;
|
||||
typedef std::vector<unsigned> TileData;
|
||||
/// äàííûå òàéëîâ
|
||||
TileData tileData_;
|
||||
|
||||
static CompressionProgressHandler progressHandler_;
|
||||
static void* progressHandlerContext_;
|
||||
};
|
||||
|
||||
#endif /* __GR_TILE_ANIMATION_H__ */
|
||||
@@ -0,0 +1,302 @@
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "gr_dispatcher.h"
|
||||
#include "gr_tile_sprite.h"
|
||||
|
||||
#include "LZ77.h"
|
||||
|
||||
unsigned grTileSprite::comprasionTolerance_ = 2;
|
||||
|
||||
namespace tile_compress
|
||||
{
|
||||
|
||||
const unsigned RLE_SEQUENCE_MASK = 1 << (GR_TILE_SPRITE_SIZE_SHIFT * 2 + 1);
|
||||
|
||||
unsigned encodeRLE(const unsigned* in_data, unsigned* out_data)
|
||||
{
|
||||
unsigned size = 0;
|
||||
|
||||
int count = 0;
|
||||
while(count < GR_TILE_SPRITE_SIZE){
|
||||
int index = count;
|
||||
unsigned pixel = in_data[index ++];
|
||||
|
||||
while(index < GR_TILE_SPRITE_SIZE && in_data[index] == pixel)
|
||||
index ++;
|
||||
|
||||
if(index - count == 1){
|
||||
while(index < GR_TILE_SPRITE_SIZE && (in_data[index] != in_data[index - 1] || index > 1 && in_data[index] != in_data[index - 2]))
|
||||
index ++;
|
||||
|
||||
while(index < GR_TILE_SPRITE_SIZE && in_data[index] == in_data[index - 1])
|
||||
index --;
|
||||
|
||||
out_data[size] = index - count;
|
||||
out_data[size] |= RLE_SEQUENCE_MASK;
|
||||
size++;
|
||||
|
||||
for(int i = count; i < index; i ++)
|
||||
out_data[size++] = in_data[i];
|
||||
}
|
||||
else {
|
||||
out_data[size++] = index - count;
|
||||
out_data[size++] = pixel;
|
||||
}
|
||||
|
||||
count = index;
|
||||
xassert(index < GR_TILE_SPRITE_SIZE * 4);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
bool decodeRLE(const unsigned* in_data, unsigned* out_data)
|
||||
{
|
||||
const unsigned* in_buf = in_data;
|
||||
unsigned* out_buf = out_data;
|
||||
|
||||
int out_size = 0;
|
||||
while(out_size < GR_TILE_SPRITE_SIZE){
|
||||
unsigned count = *in_buf++;
|
||||
if(count & RLE_SEQUENCE_MASK){
|
||||
count ^= RLE_SEQUENCE_MASK;
|
||||
for(int i = 0; i < count; i++)
|
||||
*out_buf++ = *in_buf++;
|
||||
}
|
||||
else {
|
||||
unsigned color = *in_buf++;
|
||||
for(int i = 0; i < count; i++)
|
||||
*out_buf++ = color;
|
||||
}
|
||||
|
||||
out_size += count;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // namespace tile_compress
|
||||
|
||||
void grDispatcher::PutTileSpr(int x, int y, const grTileSprite& sprite, bool has_alpha, int mode)
|
||||
{
|
||||
int px = 0;
|
||||
int py = 0;
|
||||
|
||||
int psx = GR_TILE_SPRITE_SIZE_X;
|
||||
int psy = GR_TILE_SPRITE_SIZE_Y;
|
||||
|
||||
if(!clip_rectangle(x,y,px,py,psx,psy)) return;
|
||||
|
||||
if(bytes_per_pixel() == 4){
|
||||
int dx = -4;
|
||||
int dy = -1;
|
||||
|
||||
x *= 4;
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
x += (psx - 1) * 4;
|
||||
px = GR_TILE_SPRITE_SIZE_X - px - psx;
|
||||
}
|
||||
else
|
||||
dx = 4;
|
||||
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
y += psy - 1;
|
||||
py = GR_TILE_SPRITE_SIZE_Y - py - psy;
|
||||
}
|
||||
else
|
||||
dy = 1;
|
||||
|
||||
const unsigned char* data_ptr = (const unsigned char*)sprite.data() + px*4 + py * GR_TILE_SPRITE_SIZE_X*4;
|
||||
|
||||
for(int i = 0; i < psy; i ++){
|
||||
unsigned char* scr_buf = (unsigned char*)(screenBuf + yTable[y] + x);
|
||||
const unsigned char* data_line = data_ptr;
|
||||
|
||||
for(int j = 0; j < psx; j ++){
|
||||
unsigned a = data_line[3];
|
||||
if(a != 255){
|
||||
if(a){
|
||||
scr_buf[0] = data_line[0] + ((a * scr_buf[0]) >> 8);
|
||||
scr_buf[1] = data_line[1] + ((a * scr_buf[1]) >> 8);
|
||||
scr_buf[2] = data_line[2] + ((a * scr_buf[2]) >> 8);
|
||||
}
|
||||
else {
|
||||
scr_buf[0] = data_line[0];
|
||||
scr_buf[1] = data_line[1];
|
||||
scr_buf[2] = data_line[2];
|
||||
}
|
||||
}
|
||||
scr_buf += dx;
|
||||
data_line += 4;
|
||||
}
|
||||
data_ptr += GR_TILE_SPRITE_SIZE_X*4;
|
||||
y += dy;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if(bytes_per_pixel() == 3){
|
||||
int dx = -3;
|
||||
int dy = -1;
|
||||
|
||||
x *= 3;
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
x += (psx - 1) * 3;
|
||||
px = GR_TILE_SPRITE_SIZE_X - px - psx;
|
||||
}
|
||||
else
|
||||
dx = 3;
|
||||
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
y += psy - 1;
|
||||
py = GR_TILE_SPRITE_SIZE_Y - py - psy;
|
||||
}
|
||||
else
|
||||
dy = 1;
|
||||
|
||||
const unsigned char* data_ptr = (const unsigned char*)sprite.data() + px*4 + py * GR_TILE_SPRITE_SIZE_X*4;
|
||||
|
||||
for(int i = 0; i < psy; i ++){
|
||||
unsigned char* scr_buf = (unsigned char*)(screenBuf + yTable[y] + x);
|
||||
const unsigned char* data_line = data_ptr;
|
||||
|
||||
for(int j = 0; j < psx; j ++){
|
||||
unsigned a = data_line[3];
|
||||
if(a != 255){
|
||||
if(a){
|
||||
scr_buf[0] = data_line[0] + ((a * scr_buf[0]) >> 8);
|
||||
scr_buf[1] = data_line[1] + ((a * scr_buf[1]) >> 8);
|
||||
scr_buf[2] = data_line[2] + ((a * scr_buf[2]) >> 8);
|
||||
}
|
||||
else {
|
||||
scr_buf[0] = data_line[0];
|
||||
scr_buf[1] = data_line[1];
|
||||
scr_buf[2] = data_line[2];
|
||||
}
|
||||
}
|
||||
scr_buf += dx;
|
||||
data_line += 4;
|
||||
}
|
||||
data_ptr += GR_TILE_SPRITE_SIZE_X*4;
|
||||
y += dy;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if(bytes_per_pixel() == 2){
|
||||
int dx = -1;
|
||||
int dy = -1;
|
||||
|
||||
if(mode & GR_FLIP_HORIZONTAL){
|
||||
x += psx - 1;
|
||||
px = GR_TILE_SPRITE_SIZE_X - px - psx;
|
||||
}
|
||||
else
|
||||
dx = 1;
|
||||
|
||||
if(mode & GR_FLIP_VERTICAL){
|
||||
y += psy - 1;
|
||||
py = GR_TILE_SPRITE_SIZE_Y - py - psy;
|
||||
}
|
||||
else
|
||||
dy = 1;
|
||||
|
||||
x *= 2;
|
||||
|
||||
const unsigned char* data_ptr = (unsigned char*)(sprite.data() + px + py * GR_TILE_SPRITE_SIZE_X);
|
||||
|
||||
if(pixel_format_ == GR_RGB565){
|
||||
for(int i = 0; i < psy; i ++){
|
||||
unsigned short* scr_buf = reinterpret_cast<unsigned short*>(screenBuf + yTable[y] + x);
|
||||
const unsigned char* data_line = data_ptr;
|
||||
|
||||
for(int j = 0; j < psx; j ++){
|
||||
unsigned a = data_line[3];
|
||||
if(a != 255){
|
||||
if(a)
|
||||
*scr_buf = alpha_blend_565(make_rgb565u(data_line[2], data_line[1], data_line[0]),*scr_buf,a);
|
||||
else
|
||||
*scr_buf = make_rgb565u(data_line[2], data_line[1], data_line[0]);
|
||||
}
|
||||
scr_buf += dx;
|
||||
data_line += 4;
|
||||
}
|
||||
data_ptr += GR_TILE_SPRITE_SIZE_X*4;
|
||||
y += dy;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(int i = 0; i < psy; i ++){
|
||||
unsigned short* scr_buf = reinterpret_cast<unsigned short*>(screenBuf + yTable[y] + x);
|
||||
const unsigned char* data_line = data_ptr;
|
||||
|
||||
for(int j = 0; j < psx; j ++){
|
||||
unsigned a = data_line[3];
|
||||
if(a != 255){
|
||||
if(a)
|
||||
*scr_buf = alpha_blend_555(make_rgb555u(data_line[2], data_line[1], data_line[0]),*scr_buf,a);
|
||||
else
|
||||
*scr_buf = make_rgb555u(data_line[2], data_line[1], data_line[0]);
|
||||
}
|
||||
scr_buf += dx;
|
||||
data_line += 4;
|
||||
}
|
||||
data_ptr += GR_TILE_SPRITE_SIZE_X*4;
|
||||
y += dy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
grTileSprite::grTileSprite(const unsigned* data_ptr) : data_(data_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
bool grTileSprite::operator == (const grTileSprite& sprite) const
|
||||
{
|
||||
if(isEmpty() || sprite.isEmpty())
|
||||
return (isEmpty() && sprite.isEmpty());
|
||||
|
||||
const unsigned char* ptr0 = (const unsigned char*)data_;
|
||||
const unsigned char* ptr1 = (const unsigned char*)sprite.data_;
|
||||
|
||||
for(int i = 0; i < GR_TILE_SPRITE_SIZE_BYTES; i++, ptr0++, ptr1++){
|
||||
if(abs(*ptr0 - *ptr1) > comprasionTolerance_)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned grTileSprite::compress(const unsigned* in_data, unsigned* out_data, grTileCompressionMethod compress_method)
|
||||
{
|
||||
if(compress_method == TILE_COMPRESS_RLE){
|
||||
return tile_compress::encodeRLE(in_data, out_data);
|
||||
}
|
||||
else if(compress_method == TILE_COMPRESS_LZ77){
|
||||
CLZ77 encoder;
|
||||
long len = 0;
|
||||
encoder.Encode((unsigned char*)(out_data + 1), len, (const unsigned char*)in_data, GR_TILE_SPRITE_SIZE_BYTES);
|
||||
xassert(len);
|
||||
out_data[0] = len;
|
||||
return len / 4 + 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool grTileSprite::uncompress(const unsigned* in_data, unsigned in_data_length, unsigned* out_data, grTileCompressionMethod compress_method)
|
||||
{
|
||||
if(compress_method == TILE_COMPRESS_RLE){
|
||||
return tile_compress::decodeRLE(in_data, out_data);
|
||||
}
|
||||
else if(compress_method == TILE_COMPRESS_LZ77){
|
||||
CLZ77 decoder;
|
||||
long len = 0;
|
||||
in_data_length = in_data[0];
|
||||
decoder.Decode((unsigned char*)out_data, len, (const unsigned char*)(in_data + 1), in_data_length);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifndef __GR_TILE_SPRITE_H__
|
||||
#define __GR_TILE_SPRITE_H__
|
||||
|
||||
const GR_TILE_SPRITE_SIZE_SHIFT = 4;
|
||||
const GR_TILE_SPRITE_SIZE_X = 1 << GR_TILE_SPRITE_SIZE_SHIFT;
|
||||
const GR_TILE_SPRITE_SIZE_Y = 1 << GR_TILE_SPRITE_SIZE_SHIFT;
|
||||
|
||||
const GR_TILE_SPRITE_SIZE = GR_TILE_SPRITE_SIZE_X * GR_TILE_SPRITE_SIZE_Y;
|
||||
const GR_TILE_SPRITE_SIZE_BYTES = GR_TILE_SPRITE_SIZE * 4;
|
||||
|
||||
enum grTileCompressionMethod
|
||||
{
|
||||
TILE_UNCOMPRESSED,
|
||||
TILE_COMPRESS_RLE,
|
||||
TILE_COMPRESS_LZ77
|
||||
};
|
||||
|
||||
/// Òàéë-ñïðàéò
|
||||
|
||||
/// Êâàäðàòíûé 32õ áèòíûé ñïðàéò ôèêñèðîâàííîãî ðàçìåðà.
|
||||
/// Äàííûå âíåøíèå.
|
||||
class grTileSprite
|
||||
{
|
||||
public:
|
||||
grTileSprite(const unsigned* data_ptr = 0);
|
||||
|
||||
bool operator == (const grTileSprite& sprite) const;
|
||||
|
||||
bool isEmpty() const { return !data_; }
|
||||
|
||||
const unsigned* data() const { return data_; }
|
||||
|
||||
static unsigned comprasionTolerance() { return comprasionTolerance_; }
|
||||
static void setComprasionTolerance(unsigned value){ comprasionTolerance_ = value; }
|
||||
|
||||
static unsigned compress(const unsigned* in_data, unsigned* out_data, grTileCompressionMethod compress_method);
|
||||
static bool uncompress(const unsigned* in_data, unsigned in_data_length, unsigned* out_data, grTileCompressionMethod compress_method);
|
||||
|
||||
private:
|
||||
|
||||
const unsigned* data_;
|
||||
|
||||
/// òîëåðàíòíîñòü ïîáàéòîâîãî ñðàâíåíèÿ äàííûõ, [0, 255]
|
||||
static unsigned comprasionTolerance_;
|
||||
};
|
||||
|
||||
#endif /*__GR_TILE_SPRITE_H__ */
|
||||
@@ -0,0 +1,355 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
#include "rle_compress.h"
|
||||
#include "gr_dispatcher.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
std::vector<unsigned char> rleBuffer::buffer0_(4096);
|
||||
std::vector<unsigned char> rleBuffer::buffer1_(4096);
|
||||
|
||||
bool operator == (const rleBuffer& buf1,const rleBuffer& buf2)
|
||||
{
|
||||
if(!(buf1.header_offset_ == buf2.header_offset_)) return false;
|
||||
if(!(buf1.data_offset_ == buf2.data_offset_)) return false;
|
||||
if(!(buf1.header_ == buf2.header_)) return false;
|
||||
if(!(buf1.data_ == buf2.data_)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
rleBuffer::rleBuffer() : bits_per_pixel_(32)
|
||||
{
|
||||
}
|
||||
|
||||
rleBuffer::rleBuffer(const rleBuffer& buf) : header_offset_(buf.header_offset_),
|
||||
data_offset_(buf.data_offset_),
|
||||
header_(buf.header_),
|
||||
data_(buf.data_),
|
||||
bits_per_pixel_(buf.bits_per_pixel_)
|
||||
{
|
||||
}
|
||||
|
||||
rleBuffer::~rleBuffer()
|
||||
{
|
||||
header_offset_.clear();
|
||||
data_offset_.clear();
|
||||
header_.clear();
|
||||
|
||||
data_.clear();
|
||||
}
|
||||
|
||||
rleBuffer& rleBuffer::operator = (const rleBuffer& buf)
|
||||
{
|
||||
if(this == &buf) return *this;
|
||||
|
||||
header_offset_ = buf.header_offset_;
|
||||
data_offset_ = buf.data_offset_;
|
||||
|
||||
header_ = buf.header_;
|
||||
data_ = buf.data_;
|
||||
|
||||
bits_per_pixel_ = buf.bits_per_pixel_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool rleBuffer::encode(int sx,int sy,const unsigned char* buf)
|
||||
{
|
||||
header_offset_.resize(sy);
|
||||
data_offset_.resize(sy);
|
||||
|
||||
header_.clear();
|
||||
data_.clear();
|
||||
|
||||
data_.reserve(sx * sy);
|
||||
|
||||
const unsigned* buffer = reinterpret_cast<const unsigned*>(buf);
|
||||
|
||||
for(int y = 0; y < sy; y ++){
|
||||
int count = 0;
|
||||
|
||||
header_offset_[y] = header_.size();
|
||||
data_offset_[y] = data_.size();
|
||||
|
||||
while(count < sx){
|
||||
int index = count;
|
||||
unsigned pixel = buffer[index ++];
|
||||
|
||||
while(index < sx && index - count < 127 && buffer[index] == pixel)
|
||||
index ++;
|
||||
|
||||
if(index - count == 1){
|
||||
while(index < sx && index - count < 127 && (buffer[index] != buffer[index - 1] || index > 1 && buffer[index] != buffer[index - 2]))
|
||||
index ++;
|
||||
|
||||
while(index < sx && buffer[index] == buffer[index - 1])
|
||||
index --;
|
||||
|
||||
header_.push_back(static_cast<char>(count - index));
|
||||
for(int i = count; i < index; i ++)
|
||||
data_.push_back(buffer[i]);
|
||||
}
|
||||
else {
|
||||
header_.push_back(static_cast<char>(index - count));
|
||||
data_.push_back(pixel);
|
||||
}
|
||||
|
||||
count = index;
|
||||
}
|
||||
buffer += sx;
|
||||
}
|
||||
std::vector<unsigned>(data_).swap(data_);
|
||||
|
||||
resize_buffers();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rleBuffer::decode_line(int y,unsigned char* out_buf) const
|
||||
{
|
||||
const char* header_ptr = &*(header_.begin() + header_offset_[y]);
|
||||
const unsigned* data_ptr = &*(data_.begin() + data_offset_[y]);
|
||||
|
||||
unsigned* out_ptr = reinterpret_cast<unsigned*>(out_buf);
|
||||
|
||||
int size = line_header_length(y);
|
||||
|
||||
int line_len = 0;
|
||||
|
||||
for(int i = 0; i < size; i ++){
|
||||
char count = *header_ptr++;
|
||||
if(count > 0){
|
||||
for(int j = 0; j < count; j ++)
|
||||
*out_ptr++ = *data_ptr;
|
||||
data_ptr ++;
|
||||
}
|
||||
else {
|
||||
count = -count;
|
||||
memcpy(out_ptr,data_ptr,count * sizeof(unsigned));
|
||||
|
||||
out_ptr += count;
|
||||
data_ptr += count;
|
||||
}
|
||||
|
||||
line_len += abs(count);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rleBuffer::decode_pixel(int x,int y,unsigned& pixel)
|
||||
{
|
||||
const char* header_ptr = &*(header_.begin() + header_offset_[y]);
|
||||
const unsigned* data_ptr = &*(data_.begin() + data_offset_[y]);
|
||||
|
||||
int xx = 0;
|
||||
char count = *header_ptr++;
|
||||
|
||||
while(xx + abs(count) < x){
|
||||
if(count > 0){
|
||||
data_ptr ++;
|
||||
}
|
||||
else {
|
||||
count = -count;
|
||||
data_ptr += count;
|
||||
}
|
||||
xx += count;
|
||||
count = *header_ptr++;
|
||||
}
|
||||
|
||||
if(count > 0){
|
||||
pixel = *data_ptr;
|
||||
}
|
||||
else {
|
||||
data_ptr += x - xx;
|
||||
pixel = *data_ptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned rleBuffer::size()
|
||||
{
|
||||
return data_.size() * sizeof(unsigned) + data_offset_.size() + header_offset_.size() * sizeof(unsigned) + header_.size();
|
||||
}
|
||||
|
||||
bool rleBuffer::convert_data(int bits_per_pixel)
|
||||
{
|
||||
if(bits_per_pixel_ == bits_per_pixel)
|
||||
return true;
|
||||
|
||||
int sz = data_.size();
|
||||
|
||||
switch(bits_per_pixel_){
|
||||
case 15:
|
||||
case 16:
|
||||
if(bits_per_pixel == 24 || bits_per_pixel == 32){
|
||||
unsigned short* short_ptr = reinterpret_cast<unsigned short*>(&*data_.begin());
|
||||
|
||||
for(int i = 0; i < sz; i ++){
|
||||
short_ptr++;
|
||||
*short_ptr++ <<= 8;
|
||||
}
|
||||
|
||||
short_ptr = reinterpret_cast<unsigned short*>(&*data_.begin());
|
||||
unsigned char* char_ptr = reinterpret_cast<unsigned char*>(&*data_.begin());
|
||||
|
||||
for(int i = 0; i < sz; i ++){
|
||||
unsigned r,g,b;
|
||||
|
||||
if(bits_per_pixel_ == 15)
|
||||
grDispatcher::split_rgb555u(*short_ptr++,r,g,b);
|
||||
else
|
||||
grDispatcher::split_rgb565u(*short_ptr++,r,g,b);
|
||||
|
||||
short_ptr++;
|
||||
|
||||
char_ptr[0] = b;
|
||||
char_ptr[1] = g;
|
||||
char_ptr[2] = r;
|
||||
|
||||
char_ptr += 4;
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned short* short_ptr = reinterpret_cast<unsigned short*>(&*data_.begin());
|
||||
|
||||
for(int i = 0; i < sz; i ++){
|
||||
unsigned r,g,b;
|
||||
|
||||
if(bits_per_pixel_ == 15){
|
||||
grDispatcher::split_rgb555u(*short_ptr,r,g,b);
|
||||
*short_ptr++ = grDispatcher::make_rgb565u(r,g,b);
|
||||
}
|
||||
else {
|
||||
grDispatcher::split_rgb565u(*short_ptr,r,g,b);
|
||||
*short_ptr++ = grDispatcher::make_rgb555u(r,g,b);
|
||||
}
|
||||
|
||||
short_ptr++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
if(bits_per_pixel == 15 || bits_per_pixel == 16){
|
||||
unsigned char* src_ptr = reinterpret_cast<unsigned char*>(&*data_.begin());
|
||||
unsigned short* dest_ptr = reinterpret_cast<unsigned short*>(&*data_.begin());
|
||||
|
||||
for(int i = 0; i < sz; i ++){
|
||||
*dest_ptr++ = (bits_per_pixel == 15) ? grDispatcher::make_rgb555u(src_ptr[2],src_ptr[1],src_ptr[0]) : grDispatcher::make_rgb565u(src_ptr[2],src_ptr[1],src_ptr[0]);
|
||||
*dest_ptr++ >>= 8;
|
||||
src_ptr += 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
bits_per_pixel_ = bits_per_pixel;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void rleBuffer::resize_buffers()
|
||||
{
|
||||
unsigned len = line_length() * sizeof(unsigned);
|
||||
|
||||
if(buffer0_.size() < len)
|
||||
buffer0_.resize(len);
|
||||
if(buffer1_.size() < len)
|
||||
buffer1_.resize(len);
|
||||
}
|
||||
|
||||
int rleBuffer::line_length()
|
||||
{
|
||||
if(header_offset_.empty()) return 0;
|
||||
|
||||
int sz = (header_offset_.size() > 1) ? header_offset_[1] : header_.size();
|
||||
|
||||
int len = 0;
|
||||
for(int i = 0; i < sz; i ++){
|
||||
len += abs(header_[i]);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int rleBuffer::line_header_length(int line_num) const
|
||||
{
|
||||
if(line_num < header_offset_.size() - 1)
|
||||
return header_offset_[line_num + 1] - header_offset_[line_num];
|
||||
else
|
||||
return header_.size() - header_offset_[line_num];
|
||||
}
|
||||
|
||||
bool rleBuffer::save(class XStream& fh)
|
||||
{
|
||||
fh < header_offset_.size() < data_offset_.size() < header_.size() < data_.size();
|
||||
|
||||
fh.write(&*header_offset_.begin(),header_offset_.size() * sizeof(unsigned));
|
||||
fh.write(&*data_offset_.begin(),data_offset_.size() * sizeof(unsigned));
|
||||
fh.write(&*header_.begin(),header_.size());
|
||||
fh.write(&*data_.begin(),data_.size() * sizeof(unsigned));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rleBuffer::load(XStream& fh)
|
||||
{
|
||||
int sz;
|
||||
fh > sz;
|
||||
header_offset_.resize(sz);
|
||||
|
||||
fh > sz;
|
||||
data_offset_.resize(sz);
|
||||
|
||||
fh > sz;
|
||||
header_.resize(sz + 1);
|
||||
header_[sz] = 0;
|
||||
|
||||
fh > sz;
|
||||
data_.resize(sz);
|
||||
|
||||
fh.read(&*header_offset_.begin(),header_offset_.size() * sizeof(unsigned));
|
||||
fh.read(&*data_offset_.begin(),data_offset_.size() * sizeof(unsigned));
|
||||
fh.read(&*header_.begin(),header_.size() - 1);
|
||||
fh.read(&*data_.begin(),data_.size() * sizeof(unsigned));
|
||||
|
||||
resize_buffers();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rleBuffer::load(XZipStream& fh)
|
||||
{
|
||||
int sz;
|
||||
fh > sz;
|
||||
header_offset_.resize(sz);
|
||||
|
||||
fh > sz;
|
||||
data_offset_.resize(sz);
|
||||
|
||||
fh > sz;
|
||||
header_.resize(sz + 1);
|
||||
header_[sz] = 0;
|
||||
|
||||
fh > sz;
|
||||
data_.resize(sz);
|
||||
|
||||
fh.read(&*header_offset_.begin(),header_offset_.size() * sizeof(unsigned));
|
||||
fh.read(&*data_offset_.begin(),data_offset_.size() * sizeof(unsigned));
|
||||
fh.read(&*header_.begin(),header_.size() - 1);
|
||||
fh.read(&*data_.begin(),data_.size() * sizeof(unsigned));
|
||||
|
||||
resize_buffers();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#ifndef __RLE_COMPRESS_H__
|
||||
#define __RLE_COMPRESS_H__
|
||||
|
||||
//#include <vector>
|
||||
|
||||
//! Ìàññèâ, ñæàòûé ìåòîäîì RLE.
|
||||
class rleBuffer
|
||||
{
|
||||
public:
|
||||
rleBuffer();
|
||||
rleBuffer(const rleBuffer& buf);
|
||||
~rleBuffer();
|
||||
|
||||
rleBuffer& operator = (const rleBuffer& buf);
|
||||
|
||||
bool encode(int sx,int sy,const unsigned char* buf);
|
||||
|
||||
bool decode_line(int y,unsigned char* out_buf) const;
|
||||
|
||||
inline bool decode_line(int y,int buffer_id = 0) const {
|
||||
if(buffer_id)
|
||||
return decode_line(y,&*buffer1_.begin());
|
||||
else
|
||||
return decode_line(y,&*buffer0_.begin());
|
||||
}
|
||||
|
||||
bool decode_pixel(int x,int y,unsigned& pixel);
|
||||
|
||||
static inline const unsigned char* get_buffer(int buffer_id){
|
||||
if(buffer_id) return &*buffer1_.begin();
|
||||
else return &*buffer0_.begin();
|
||||
}
|
||||
|
||||
void resize_buffers();
|
||||
|
||||
unsigned size();
|
||||
int line_length();
|
||||
int line_header_length(int line_num) const;
|
||||
|
||||
unsigned header_size() const { return header_.size(); }
|
||||
unsigned data_size() const { return data_.size(); }
|
||||
|
||||
const char* header_ptr(int y = 0) const { return &*(header_.begin() + header_offset_[y]); }
|
||||
const unsigned* data_ptr(int y = 0) const { return &*(data_.begin() + data_offset_[y]); }
|
||||
|
||||
bool save(class XStream& fh);
|
||||
bool load(class XStream& fh);
|
||||
bool load(class XZipStream& fh);
|
||||
|
||||
bool convert_data(int bits_per_pixel = 16);
|
||||
|
||||
private:
|
||||
std::vector<unsigned> header_offset_;
|
||||
std::vector<unsigned> data_offset_;
|
||||
|
||||
std::vector<char> header_;
|
||||
std::vector<unsigned> data_;
|
||||
|
||||
int bits_per_pixel_;
|
||||
|
||||
static std::vector<unsigned char> buffer0_;
|
||||
static std::vector<unsigned char> buffer1_;
|
||||
|
||||
friend bool operator == (const rleBuffer& buf1,const rleBuffer& buf2);
|
||||
};
|
||||
|
||||
#endif /* __RLE_COMPRESS_H__ */
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "input_recorder.h"
|
||||
#include "input_wndproc.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
inputRecorder::inputRecorder()
|
||||
{
|
||||
time_ = 0;
|
||||
recorder_mode_ = RECORDER_NONE;
|
||||
|
||||
buffer_size_ = current_message_ = 0;
|
||||
}
|
||||
|
||||
inputRecorder::~inputRecorder()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
bool inputRecorder::open(const char* file_name,recorder_mode_t mode)
|
||||
{
|
||||
close();
|
||||
|
||||
recorder_mode_ = mode;
|
||||
|
||||
switch(mode){
|
||||
case RECORDER_WRITE:
|
||||
file_.open(file_name,XS_OUT);
|
||||
break;
|
||||
case RECORDER_PLAY:
|
||||
file_.open(file_name,XS_IN);
|
||||
read();
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void inputRecorder::close()
|
||||
{
|
||||
if(recorder_mode_ == RECORDER_WRITE)
|
||||
write();
|
||||
|
||||
file_.close();
|
||||
|
||||
time_ = 0;
|
||||
recorder_mode_ = RECORDER_NONE;
|
||||
|
||||
buffer_size_ = current_message_ = 0;
|
||||
}
|
||||
|
||||
int inputRecorder::read()
|
||||
{
|
||||
assert(recorder_mode_ == RECORDER_PLAY);
|
||||
|
||||
int count = 0;
|
||||
|
||||
current_message_ = buffer_size_ = 0;
|
||||
|
||||
inputRecorderMessage msg;
|
||||
while(!is_buffer_full() && !file_.eof()){
|
||||
msg.read(file_);
|
||||
add_message(msg);
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int inputRecorder::write()
|
||||
{
|
||||
assert(recorder_mode_ == RECORDER_WRITE);
|
||||
|
||||
for(int i = 0; i < buffer_size_; i++)
|
||||
messages_buffer_[i].write(file_);
|
||||
|
||||
int count = buffer_size_;
|
||||
|
||||
buffer_size_ = 0;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool inputRecorder::add_message(const inputRecorderMessage& msg)
|
||||
{
|
||||
if(recorder_mode_ == RECORDER_WRITE && is_buffer_full())
|
||||
write();
|
||||
|
||||
if(!is_buffer_full()){
|
||||
messages_buffer_[buffer_size_++] = msg;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool inputRecorder::dispatch_message(const MSG& msg)
|
||||
{
|
||||
if(recorder_mode_ != RECORDER_WRITE) return false;
|
||||
|
||||
inputRecorderMessage::message_id_t msg_id = inputRecorderMessage::MSG_MOUSE_MOVE;
|
||||
int key_id = -1;
|
||||
int cursor_x = 0;
|
||||
int cursor_y = 0;
|
||||
int flags = 0;
|
||||
|
||||
switch(msg.message){
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
msg_id = inputRecorderMessage::MSG_KEY_PRESS;
|
||||
break;
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
msg_id = inputRecorderMessage::MSG_KEY_RELESASE;
|
||||
break;
|
||||
case WM_LBUTTONDOWN:
|
||||
msg_id = inputRecorderMessage::MSG_MOUSE_LBUTTON_PRESS;
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
msg_id = inputRecorderMessage::MSG_MOUSE_RBUTTON_PRESS;
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
msg_id = inputRecorderMessage::MSG_MOUSE_LBUTTON_RELEASE;
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
msg_id = inputRecorderMessage::MSG_MOUSE_RBUTTON_RELEASE;
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if(inputRecorderMessage::is_mouse_message(msg_id)){
|
||||
flags = int(msg.wParam);
|
||||
cursor_x = LOWORD(msg.lParam);
|
||||
cursor_y = HIWORD(msg.lParam);
|
||||
}
|
||||
else {
|
||||
key_id = int(msg.wParam);
|
||||
flags = int(msg.lParam);
|
||||
}
|
||||
|
||||
return add_message(inputRecorderMessage(msg_id,time_,key_id,cursor_x,cursor_y,flags));
|
||||
}
|
||||
|
||||
bool inputRecorder::dispatch_message(const inputRecorderMessage& imsg)
|
||||
{
|
||||
MSG msg;
|
||||
ZeroMemory(&msg,sizeof(MSG));
|
||||
|
||||
switch(imsg.message_id()){
|
||||
case inputRecorderMessage::MSG_KEY_PRESS:
|
||||
msg.message = WM_KEYDOWN;
|
||||
break;
|
||||
case inputRecorderMessage::MSG_KEY_RELESASE:
|
||||
msg.message = WM_KEYUP;
|
||||
break;
|
||||
case inputRecorderMessage::MSG_MOUSE_LBUTTON_PRESS:
|
||||
msg.message = WM_LBUTTONDOWN;
|
||||
break;
|
||||
case inputRecorderMessage::MSG_MOUSE_RBUTTON_PRESS:
|
||||
msg.message = WM_RBUTTONDOWN;
|
||||
break;
|
||||
case inputRecorderMessage::MSG_MOUSE_LBUTTON_RELEASE:
|
||||
msg.message = WM_LBUTTONUP;
|
||||
break;
|
||||
case inputRecorderMessage::MSG_MOUSE_RBUTTON_RELEASE:
|
||||
msg.message = WM_RBUTTONUP;
|
||||
break;
|
||||
case inputRecorderMessage::MSG_MOUSE_MOVE:
|
||||
msg.message = WM_MOUSEMOVE;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if(inputRecorderMessage::is_mouse_message(imsg.message_id())){
|
||||
msg.wParam = (WPARAM)imsg.flags();
|
||||
msg.lParam = MAKELPARAM(imsg.cursor_x(),imsg.cursor_y());
|
||||
return input::mouse_wndproc(msg,mouseDispatcher::instance());
|
||||
}
|
||||
else {
|
||||
msg.wParam = (WPARAM)imsg.key_id();
|
||||
msg.lParam = (LPARAM)imsg.flags();
|
||||
return input::keyboard_wndproc(msg,keyboardDispatcher::instance());
|
||||
}
|
||||
}
|
||||
|
||||
void inputRecorder::quant()
|
||||
{
|
||||
time_++;
|
||||
|
||||
if(recorder_mode_ == RECORDER_PLAY){
|
||||
if(current_message_ >= buffer_size_ - 1){
|
||||
read();
|
||||
}
|
||||
|
||||
if(current_message_ < buffer_size_ - 1){
|
||||
while(messages_buffer_[current_message_].time() == time_){
|
||||
dispatch_message(messages_buffer_[current_message_]);
|
||||
if(++current_message_ >= buffer_size_){
|
||||
if(!read())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inputRecorder& inputRecorder::instance()
|
||||
{
|
||||
static inputRecorder rec;
|
||||
return rec;
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
#ifndef __INPUT_RECORDER_H__
|
||||
#define __INPUT_RECORDER_H__
|
||||
|
||||
class inputRecorderMessage
|
||||
{
|
||||
public:
|
||||
enum message_id_t {
|
||||
MSG_MOUSE_LBUTTON_PRESS,
|
||||
MSG_MOUSE_LBUTTON_RELEASE,
|
||||
MSG_MOUSE_RBUTTON_PRESS,
|
||||
MSG_MOUSE_RBUTTON_RELEASE,
|
||||
MSG_MOUSE_MOVE,
|
||||
MSG_KEY_PRESS,
|
||||
MSG_KEY_RELESASE
|
||||
};
|
||||
|
||||
inputRecorderMessage(){ init(MSG_MOUSE_MOVE,0,-1,0,0,0); }
|
||||
inputRecorderMessage(message_id_t id,unsigned time,int key_id,int x,int y,int flags){ init(id,time,key_id,x,y,flags); }
|
||||
|
||||
message_id_t message_id() const { return message_id_; }
|
||||
|
||||
unsigned time() const { return time_; }
|
||||
|
||||
int key_id() const { return key_id_; }
|
||||
|
||||
unsigned short cursor_x() const { return cursor_pos_.x; }
|
||||
unsigned short cursor_y() const { return cursor_pos_.y; }
|
||||
|
||||
int flags() const { return flags_; }
|
||||
|
||||
void read(XStream& fh)
|
||||
{
|
||||
char msg_id;
|
||||
fh > msg_id > time_ > flags_;
|
||||
|
||||
message_id_ = message_id_t(msg_id);
|
||||
if(is_mouse_message(message_id_))
|
||||
fh > cursor_pos_.x > cursor_pos_.y;
|
||||
else
|
||||
fh > key_id_;
|
||||
}
|
||||
|
||||
void write(XStream& fh) const
|
||||
{
|
||||
fh < (char)message_id_ < time_ < flags_;
|
||||
|
||||
if(is_mouse_message(message_id_))
|
||||
fh < cursor_pos_.x < cursor_pos_.y;
|
||||
else
|
||||
fh < key_id_;
|
||||
}
|
||||
|
||||
static bool is_mouse_message(message_id_t id){ if(id == MSG_KEY_PRESS || id == MSG_KEY_RELESASE) return false; return true; }
|
||||
|
||||
private:
|
||||
|
||||
message_id_t message_id_;
|
||||
|
||||
unsigned time_;
|
||||
|
||||
struct cursorPos {
|
||||
unsigned short x;
|
||||
unsigned short y;
|
||||
};
|
||||
|
||||
union {
|
||||
int key_id_;
|
||||
cursorPos cursor_pos_;
|
||||
};
|
||||
|
||||
int flags_;
|
||||
|
||||
void init(message_id_t id,unsigned time,int key_id,int x,int y,int flags)
|
||||
{
|
||||
message_id_ = id;
|
||||
|
||||
time_ = time;
|
||||
|
||||
if(is_mouse_message(id)){
|
||||
cursor_pos_.x = x;
|
||||
cursor_pos_.y = y;
|
||||
}
|
||||
else
|
||||
key_id_ = key_id;
|
||||
|
||||
flags_ = flags;
|
||||
}
|
||||
};
|
||||
|
||||
class inputRecorder
|
||||
{
|
||||
public:
|
||||
~inputRecorder();
|
||||
|
||||
enum recorder_mode_t {
|
||||
RECORDER_NONE,
|
||||
RECORDER_WRITE,
|
||||
RECORDER_PLAY
|
||||
};
|
||||
|
||||
bool open(const char* file_name,recorder_mode_t mode);
|
||||
void close();
|
||||
|
||||
bool add_message(const inputRecorderMessage& msg);
|
||||
bool dispatch_message(const MSG& msg);
|
||||
|
||||
void quant();
|
||||
|
||||
static const char* write_comline(){ static const char* p = "write_replay"; return p; }
|
||||
static const char* play_comline(){ static const char* p = "show_replay"; return p; }
|
||||
|
||||
static inputRecorder& instance();
|
||||
|
||||
private:
|
||||
|
||||
unsigned time_;
|
||||
recorder_mode_t recorder_mode_;
|
||||
|
||||
XStream file_;
|
||||
|
||||
enum {
|
||||
RECORDER_BUFFER_SIZE = 1024
|
||||
};
|
||||
|
||||
inputRecorderMessage messages_buffer_[RECORDER_BUFFER_SIZE];
|
||||
|
||||
int buffer_size_;
|
||||
int current_message_;
|
||||
|
||||
int read();
|
||||
int write();
|
||||
|
||||
inputRecorder();
|
||||
|
||||
bool is_buffer_full() const { return (buffer_size_ >= RECORDER_BUFFER_SIZE - 1); }
|
||||
bool dispatch_message(const inputRecorderMessage& msg);
|
||||
};
|
||||
|
||||
#endif /* __INPUT_RECORDER_H__ */
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "input_wndproc.h"
|
||||
#include "keyboard_input.h"
|
||||
#include "input_recorder.h"
|
||||
#include "mouse_input.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
namespace input
|
||||
{
|
||||
|
||||
bool keyboard_wndproc(const MSG& msg,keyboardDispatcher* dsp)
|
||||
{
|
||||
switch(msg.message){
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
dsp->handle_event((int)msg.wParam,true);
|
||||
inputRecorder::instance().dispatch_message(msg);
|
||||
return true;
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
dsp->handle_event((int)msg.wParam,false);
|
||||
inputRecorder::instance().dispatch_message(msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mouse_wndproc(const MSG& msg,mouseDispatcher* dsp)
|
||||
{
|
||||
int x,y;
|
||||
switch(msg.message){
|
||||
case WM_MOUSEMOVE:
|
||||
x = LOWORD(msg.lParam);
|
||||
y = HIWORD(msg.lParam);
|
||||
dsp->handle_event(mouseDispatcher::EV_MOUSE_MOVE,x,y,msg.wParam);
|
||||
inputRecorder::instance().dispatch_message(msg);
|
||||
return true;
|
||||
case WM_LBUTTONDOWN:
|
||||
x = LOWORD(msg.lParam);
|
||||
y = HIWORD(msg.lParam);
|
||||
dsp->handle_event(mouseDispatcher::EV_LEFT_DOWN,x,y,msg.wParam);
|
||||
inputRecorder::instance().dispatch_message(msg);
|
||||
return true;
|
||||
case WM_RBUTTONDOWN:
|
||||
x = LOWORD(msg.lParam);
|
||||
y = HIWORD(msg.lParam);
|
||||
dsp->handle_event(mouseDispatcher::EV_RIGHT_DOWN,x,y,msg.wParam);
|
||||
inputRecorder::instance().dispatch_message(msg);
|
||||
return true;
|
||||
case WM_LBUTTONUP:
|
||||
x = LOWORD(msg.lParam);
|
||||
y = HIWORD(msg.lParam);
|
||||
dsp->handle_event(mouseDispatcher::EV_LEFT_UP,x,y,msg.wParam);
|
||||
inputRecorder::instance().dispatch_message(msg);
|
||||
return true;
|
||||
case WM_RBUTTONUP:
|
||||
x = LOWORD(msg.lParam);
|
||||
y = HIWORD(msg.lParam);
|
||||
dsp->handle_event(mouseDispatcher::EV_RIGHT_UP,x,y,msg.wParam);
|
||||
inputRecorder::instance().dispatch_message(msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}; /* namespace input */
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef __INPUT_WNDPROC_H__
|
||||
#define __INPUT_WNDPROC_H__
|
||||
|
||||
class mouseDispatcher;
|
||||
class keyboardDispatcher;
|
||||
|
||||
namespace input {
|
||||
|
||||
//! Обработка сообщений ввода с клавиатуры.
|
||||
/**
|
||||
Возвращает true, если сообщение обработано.
|
||||
|
||||
Обрабатываемые сообщения:
|
||||
WM_KEYDOWN
|
||||
WM_KEYUP
|
||||
WM_SYSKEYDOWN
|
||||
WM_SYSKEYUP
|
||||
*/
|
||||
bool keyboard_wndproc(const MSG& msg,keyboardDispatcher* dsp);
|
||||
|
||||
//! Обработка сообщений мыши.
|
||||
/**
|
||||
Возвращает true, если сообщение обработано.
|
||||
|
||||
Обрабатываемые сообщения:
|
||||
WM_MOUSEMOVE
|
||||
WM_LBUTTONDOWN
|
||||
WM_RBUTTONDOWN
|
||||
WM_LBUTTONUP
|
||||
WM_RBUTTONUP
|
||||
*/
|
||||
bool mouse_wndproc(const MSG& msg,mouseDispatcher* dsp);
|
||||
|
||||
};
|
||||
|
||||
#endif /* __INPUT_WNDPROC_H__ */
|
||||
@@ -0,0 +1,25 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "keyboard_input.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
keyboardDispatcher::keyboardDispatcher() : handler_(0)
|
||||
{
|
||||
for(int i = 0; i < 256; i ++) key_states_[i] = false;
|
||||
}
|
||||
|
||||
keyboardDispatcher::~keyboardDispatcher()
|
||||
{
|
||||
}
|
||||
|
||||
keyboardDispatcher* keyboardDispatcher::instance()
|
||||
{
|
||||
static keyboardDispatcher dsp;
|
||||
return &dsp;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef __KEYBOARD_INPUT_H__
|
||||
#define __KEYBOARD_INPUT_H__
|
||||
|
||||
//! Îáðàáîò÷èê ââîäà ñ êëàâèàòóðû.
|
||||
class keyboardDispatcher
|
||||
{
|
||||
public:
|
||||
//! Îáðàáîò÷èê íàæàòèé/îòæàòèé êíîïîê.
|
||||
/**
|
||||
Âîçâðàùàåò true ïðè óñïåøíîé îáðàáîòêå ñîáûòèÿ.
|
||||
*/
|
||||
typedef bool (*event_handler_t)(int key_vcode, bool event);
|
||||
|
||||
keyboardDispatcher();
|
||||
~keyboardDispatcher();
|
||||
|
||||
//! Âîçâðàùàåò true, åñëè êíîïêà ñ êîäîì vkey â äàííûé ìîìåíò íàæàòà.
|
||||
bool is_pressed(int vkey) const {
|
||||
assert(vkey >= 0 && vkey < 256);
|
||||
return key_states_[vkey];
|
||||
}
|
||||
|
||||
//! Óñòàíàâëèâàåò îáðàáîò÷èê íàæàòèé/îòæàòèé êíîïîê.
|
||||
event_handler_t set_handler(event_handler_t h){
|
||||
event_handler_t old_h = handler_;
|
||||
handler_ = h;
|
||||
return old_h;
|
||||
}
|
||||
|
||||
//! Îáðàáàòûâàåò íàæàòèå (event == true) èëè îòæàòèå (event == false) êíîïêè ñ êîäîì vkey.
|
||||
bool handle_event(int vkey, bool event){
|
||||
key_states_[vkey] = event;
|
||||
if(handler_) return (*handler_)(vkey,event);
|
||||
return false;
|
||||
}
|
||||
|
||||
//! Âîçâðàùàåò äèñïåò÷åð ïî-óìîë÷àíèþ.
|
||||
static keyboardDispatcher* instance();
|
||||
|
||||
private:
|
||||
|
||||
//! Îáðàáîò÷èê íàæàòèé/îòæàòèé êíîïîê.
|
||||
event_handler_t handler_;
|
||||
|
||||
//! Ñîñòîÿíèÿ êíîïîê - key_states_[vkey] == true åñëè êíîïêà ñ êîäîì vkey íàæàòà.
|
||||
bool key_states_[256];
|
||||
};
|
||||
|
||||
#endif /* __KEYBOARD_INPUT_H__ */
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "mouse_input.h"
|
||||
#include "gr_dispatcher.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
mouseDispatcher::mouseDispatcher() : events_(0), active_events_(0), mouse_x_(0), mouse_y_(0), button_status_(0)
|
||||
{
|
||||
for(int i = 0; i < EV_MOUSE_MOVE + 1; i++)
|
||||
event_handlers_[i] = 0;
|
||||
}
|
||||
|
||||
mouseDispatcher::~mouseDispatcher()
|
||||
{
|
||||
}
|
||||
|
||||
mouseDispatcher* mouseDispatcher::instance()
|
||||
{
|
||||
static mouseDispatcher dsp;
|
||||
return &dsp;
|
||||
}
|
||||
|
||||
|
||||
bool mouseDispatcher::handle_event(mouseEvent ev,int x,int y,int flags)
|
||||
{
|
||||
if(x >= grDispatcher::instance()->Get_SizeX())
|
||||
x = grDispatcher::instance()->Get_SizeX() - 1;
|
||||
if(y >= grDispatcher::instance()->Get_SizeY())
|
||||
y = grDispatcher::instance()->Get_SizeY() - 1;
|
||||
|
||||
if(event_handlers_[ev])
|
||||
(*event_handlers_[ev])(x,y,flags);
|
||||
|
||||
if(flags & MK_LBUTTON) button_status_ |= 1 << (ID_BUTTON_LEFT);
|
||||
else button_status_ &= ~(1 << ID_BUTTON_LEFT);
|
||||
|
||||
if(flags & MK_MBUTTON) button_status_ |= 1 << (ID_BUTTON_MIDDLE);
|
||||
else button_status_ &= ~(1 << ID_BUTTON_MIDDLE);
|
||||
|
||||
if(flags & MK_RBUTTON) button_status_ |= 1 << (ID_BUTTON_RIGHT);
|
||||
else button_status_ &= ~(1 << ID_BUTTON_RIGHT);
|
||||
|
||||
toggle_event(ev);
|
||||
mouse_x_ = x;
|
||||
mouse_y_ = y;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
#ifndef __MOUSE_INPUT_H__
|
||||
#define __MOUSE_INPUT_H__
|
||||
|
||||
//! Îáðàáîò÷èê ìûøè.
|
||||
class mouseDispatcher
|
||||
{
|
||||
public:
|
||||
mouseDispatcher();
|
||||
~mouseDispatcher();
|
||||
|
||||
//! Îáðàáîò÷èê ñîáûòèé.
|
||||
/**
|
||||
Âîçâðàùàåò true ïðè óñïåøíîé îáðàáîòêå ñîáûòèÿ.
|
||||
*/
|
||||
typedef bool (*event_handler_t)(int x,int y,int flags);
|
||||
|
||||
//! Ñîáûòèÿ.
|
||||
enum mouseEvent {
|
||||
//! Íàæàòèå ëåâîé êíîïêè.
|
||||
EV_LEFT_DOWN = 0,
|
||||
//! Íàæàòèå ïðàâîé êíîïêè.
|
||||
EV_RIGHT_DOWN,
|
||||
//! Äâîéíîå íàæàòèå ëåâîé êíîïêè.
|
||||
EV_LEFT_DBLCLICK,
|
||||
//! Äâîéíîå íàæàòèå ïðàâîé êíîïêè.
|
||||
EV_RIGHT_DBLCLICK,
|
||||
//! Îòæàòèå ëåâîé êíîïêè.
|
||||
EV_LEFT_UP,
|
||||
//! Îòæàòèå ïðàâîé êíîïêè.
|
||||
EV_RIGHT_UP,
|
||||
//! Ïåðåìåùåíèå ìûøè.
|
||||
EV_MOUSE_MOVE
|
||||
};
|
||||
|
||||
//! Èäåíòèôèêàòîðû êíîïîê.
|
||||
enum mouseButtonID {
|
||||
ID_BUTTON_LEFT,
|
||||
ID_BUTTON_MIDDLE,
|
||||
ID_BUTTON_RIGHT
|
||||
};
|
||||
|
||||
//! Óñòàíîâêà îáðàáîò÷èêà ñîáûòèÿ.
|
||||
event_handler_t set_event_handler(mouseEvent ev,event_handler_t h){
|
||||
event_handler_t old_h = event_handlers_[ev];
|
||||
event_handlers_[ev] = h;
|
||||
return old_h;
|
||||
}
|
||||
|
||||
//! Îáðàáîòêà ñîáûòèÿ.
|
||||
bool handle_event(mouseEvent ev,int x,int y,int flags);
|
||||
|
||||
//! Âîçâðàùàåò true, åñëè ñîáûòèå ïðîèñõîäèëî è ïîêà íå îáðàáîòàíî.
|
||||
bool check_event(mouseEvent ev) const { if(events_ & (1 << ev)) return true; else return false; }
|
||||
//! Âîçâðàùàåò true, åñëè ñîáûòèå ïðîèñõîäèëî ñ ìîìåíòà âûçîâà clear_events().
|
||||
bool is_event_active(mouseEvent ev) const { if(active_events_ & (1 << ev)) return true; else return false; }
|
||||
//! Î÷èùàåò èíôîðìàöèþ î ñîáûòèÿõ.
|
||||
bool clear_events(){ events_ = active_events_ = 0; return true; }
|
||||
//! Î÷èùàåò èíôîðìàöèþ î ñîáûòèè ev.
|
||||
bool clear_event(mouseEvent ev){ events_ &= ~(1 << ev); return true; }
|
||||
//! Ïîìå÷àåò ñîáûòèå, êàê íåïðîèñõîäèâøåå.
|
||||
bool deactivate_event(mouseEvent ev){ active_events_ &= ~(1 << ev); return true; }
|
||||
//! Ïîìå÷àåò ñîáûòèå êàê ïðîèçîøåäøåå.
|
||||
void toggle_event(mouseEvent ev){ events_ |= (1 << ev); active_events_ |= (1 << ev); }
|
||||
|
||||
//! Âîçâðàùàåò ãîðèçîíòàëüíóþ êîîðäèíàòó ìûøèíîãî êóðñîðà.
|
||||
int mouse_x() const { return mouse_x_; }
|
||||
//! Âîçâðàùàåò âåðòèêàëüíóþ êîîðäèíàòó ìûøèíîãî êóðñîðà.
|
||||
int mouse_y() const { return mouse_y_; }
|
||||
|
||||
//! Âîçâðàùàåò true, åñëè êíîïêà bt_id íàæàòà.
|
||||
bool is_pressed(mouseButtonID bt_id){ return (button_status_ & (1 << bt_id)); }
|
||||
|
||||
//! Âîçâðàùàåò îáðàáîò÷èê ïî-óìîë÷àíèþ.
|
||||
static mouseDispatcher* instance();
|
||||
|
||||
//! Âîçâðàùàåò èäåíòèôèêàòîð ïåðâîãî ñîáûòèÿ.
|
||||
static mouseEvent first_event_ID(){ return EV_LEFT_DOWN; }
|
||||
//! Âîçâðàùàåò èäåíòèôèêàòîð ïîñëåäíåãî ñîáûòèÿ.
|
||||
static mouseEvent last_event_ID(){ return EV_MOUSE_MOVE; }
|
||||
|
||||
private:
|
||||
//! Ñîáûòèÿ - ïðè óñïåøíîé îáðàáîòêå ñîáûòèÿ êëèåíòîì îí ñêèäûâàåò ñîîòâåòñâóþùèé ôëàã.
|
||||
int events_;
|
||||
//! Ñîáûòèÿ - äëÿ ïðîâåðêè, ïðîèñõîäèëî ëè ñîáûòèå ñ ìîìåíòà âûçîâà clear_events()
|
||||
int active_events_;
|
||||
|
||||
//! Ñòàòóñ êíîïîê - íàæàòû èëè íåò.
|
||||
int button_status_;
|
||||
|
||||
//! Ãîðèçîíòàëüíàÿ êîîðäèíàòà ìûøèíîãî êóðñîðà.
|
||||
int mouse_x_;
|
||||
//! Âåðòèêàëüíàÿ êîîðäèíàòà ìûøèíîãî êóðñîðà.
|
||||
int mouse_y_;
|
||||
|
||||
//! Îáðàáîò÷èêè ñîáûòèé.
|
||||
event_handler_t event_handlers_[EV_MOUSE_MOVE + 1];
|
||||
};
|
||||
|
||||
#endif /* __MOUSE_INPUT_H__ */
|
||||
@@ -0,0 +1,915 @@
|
||||
//Balmer
|
||||
#include "qd_precomp.h"
|
||||
#include <windows.h>
|
||||
#include <dsound.h>
|
||||
#include "PlayOgg.h"
|
||||
#include <vorbis/vorbisfile.h>
|
||||
|
||||
#ifdef MPP_STAT
|
||||
#include <xutil.h>
|
||||
#endif MPP_STAT
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <aclapi.h>
|
||||
|
||||
#define BLK_SIZE (36 * 32)
|
||||
void MpegCreateWindowTable();
|
||||
|
||||
static LPDIRECTSOUND g_pDS=NULL;
|
||||
const maximal_len=BLK_SIZE*2;
|
||||
|
||||
static HANDLE hWaitEvent=INVALID_HANDLE_VALUE;
|
||||
static HANDLE hThread=INVALID_HANDLE_VALUE;
|
||||
static int b_thread_must_stop=0;
|
||||
static bool b_pause_if_null_volume=false;
|
||||
MpegSound* pFirstSound=NULL;
|
||||
|
||||
//#define MPEG_PROFILE
|
||||
#ifdef MPEG_PROFILE
|
||||
#include <stdio.h>
|
||||
FILE* mpeg_error=NULL;
|
||||
void mprintf(char *format, ...)
|
||||
{
|
||||
if(mpeg_error==NULL)return;
|
||||
va_list args;
|
||||
char buffer[512];
|
||||
va_start(args,format);
|
||||
vsprintf(buffer,format,args);
|
||||
fprintf(mpeg_error,buffer);
|
||||
}
|
||||
#endif MPEG_PROFILE
|
||||
|
||||
#ifdef MPP_STAT
|
||||
|
||||
static double all_time=0,mpeg_time=0;
|
||||
|
||||
static int time_index=0;
|
||||
static double prev_time=0,sum_mpeg_time=0;
|
||||
|
||||
const MPP_BUF_SIZE=8192;
|
||||
class MppLoad
|
||||
{
|
||||
char buffer[MPP_BUF_SIZE];
|
||||
OggVorbis_File vf;
|
||||
FILE* file;
|
||||
int bitstream;
|
||||
int channels;//0-mono,1-stereo
|
||||
float time_len;
|
||||
public:
|
||||
enum MppDeferredRet
|
||||
{
|
||||
MDR_ERROR=0,
|
||||
MDR_WAIT=1,
|
||||
MDR_OK=2,
|
||||
};
|
||||
|
||||
MppLoad()
|
||||
{
|
||||
file=NULL;
|
||||
bitstream=0;
|
||||
channels=2;
|
||||
time_len=0.0f;
|
||||
}
|
||||
~MppLoad()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool Open(const char* fname)
|
||||
{
|
||||
Close();
|
||||
if(!fname || fname[0]==0)
|
||||
return false;
|
||||
file=fopen(fname,"rb");
|
||||
if(file==NULL)
|
||||
return false;
|
||||
if(ov_open(file, &vf, NULL, 0) < 0)
|
||||
{
|
||||
fclose(file);
|
||||
file=NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
vorbis_info* info=ov_info(&vf,-1);
|
||||
channels=info->channels;
|
||||
time_len=(float)ov_time_total(&vf,bitstream);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Close()
|
||||
{
|
||||
if(file)
|
||||
{
|
||||
ov_clear(&vf);
|
||||
fclose(file);
|
||||
file=NULL;
|
||||
bitstream=0;
|
||||
}
|
||||
}
|
||||
|
||||
//len - âåëè÷ííà áóôôåðà buffer â short
|
||||
bool GetNextFrame(short*& buffer_,int& len)
|
||||
{
|
||||
int ret = ov_read(&vf, buffer, MPP_BUF_SIZE, 0, 2, 1, &bitstream);
|
||||
len=ret;
|
||||
buffer_=(short*)buffer;
|
||||
return ret>0;
|
||||
}
|
||||
|
||||
float GetLen()
|
||||
{
|
||||
return time_len;
|
||||
}
|
||||
|
||||
float GetCurPos()
|
||||
{
|
||||
return (float)ov_time_tell(&vf);
|
||||
}
|
||||
|
||||
int GetChannels()
|
||||
{
|
||||
return channels;
|
||||
}
|
||||
};
|
||||
|
||||
double MpegCPUUsing()
|
||||
{
|
||||
if(all_time<0.1)
|
||||
return 0;
|
||||
return mpeg_time/all_time;
|
||||
}
|
||||
#endif MPP_STAT
|
||||
|
||||
class EWait
|
||||
{
|
||||
public:
|
||||
EWait()
|
||||
{
|
||||
if(hWaitEvent==INVALID_HANDLE_VALUE)return;
|
||||
WaitForSingleObject(hWaitEvent,INFINITE);
|
||||
}
|
||||
~EWait()
|
||||
{
|
||||
if(hWaitEvent==INVALID_HANDLE_VALUE)return;
|
||||
SetEvent(hWaitEvent);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#define DB_MIN -10000
|
||||
#define DB_MAX 0
|
||||
#define DB_SIZE 10000
|
||||
|
||||
static int FromDirectVolume(long vol)
|
||||
{
|
||||
double v=exp((exp(((vol-DB_MIN)/(double)DB_SIZE)*log(10.0f))-1.0)*log(2.0)*8/9.0)-1;
|
||||
|
||||
return (int)(v+0.5);
|
||||
}
|
||||
|
||||
static long ToDirectVolume(int vol)
|
||||
{
|
||||
|
||||
int v = DB_MIN + (int)(0.5+
|
||||
log10(
|
||||
9.0*log(double(vol + 1))/(log(2.0)*8) + 1.0
|
||||
)*DB_SIZE
|
||||
);
|
||||
return v;
|
||||
}
|
||||
|
||||
void MpegSetPauseIfNullVolume(bool set)
|
||||
{
|
||||
b_pause_if_null_volume=set;
|
||||
}
|
||||
|
||||
__int64 tick_per_sec2=0;
|
||||
__int64 beg_tick2=0;
|
||||
|
||||
__declspec (noinline)
|
||||
__int64 getRDTSC2()
|
||||
{
|
||||
#define RDTSC __asm _emit 0xf __asm _emit 0x31
|
||||
__int64 timeRDTS;
|
||||
__asm {
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
RDTSC
|
||||
mov dword ptr [timeRDTS],eax
|
||||
mov dword ptr [timeRDTS+4],edx
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
}
|
||||
return timeRDTS;
|
||||
}
|
||||
|
||||
double clockf()
|
||||
{
|
||||
return (double)(getRDTSC2()-beg_tick2)/(double)tick_per_sec2;
|
||||
}
|
||||
|
||||
DWORD WINAPI MpegThreadProc(LPVOID lpParameter)
|
||||
{
|
||||
SetThreadPriority(hThread,THREAD_PRIORITY_TIME_CRITICAL);
|
||||
|
||||
prev_time=clockf();
|
||||
|
||||
while(b_thread_must_stop==0)
|
||||
{
|
||||
#ifdef MPP_STAT
|
||||
time_index++;
|
||||
if(time_index%400==0)
|
||||
{
|
||||
all_time=clockf()-prev_time;
|
||||
mpeg_time=sum_mpeg_time;
|
||||
sum_mpeg_time=0;
|
||||
prev_time=clockf();
|
||||
}
|
||||
#endif MPP_STAT
|
||||
{
|
||||
EWait w;
|
||||
#ifdef MPP_STAT
|
||||
double tbeg=clockf();
|
||||
#endif MPP_STAT
|
||||
|
||||
#ifdef MPEG_PROFILE
|
||||
static int cur_quant=0;
|
||||
mprintf("%i: ",cur_quant++);
|
||||
#endif MPEG_PROFILE
|
||||
for(MpegSound* cur=pFirstSound;cur;cur=cur->next)
|
||||
{
|
||||
cur->TimeCallbackTrue();
|
||||
}
|
||||
|
||||
#ifdef MPEG_PROFILE
|
||||
mprintf("\n");
|
||||
#endif MPEG_PROFILE
|
||||
#ifdef MPP_STAT
|
||||
sum_mpeg_time+=clockf()-tbeg;
|
||||
#endif MPP_STAT
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
}
|
||||
|
||||
b_thread_must_stop=2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool MpegInitLibrary(void* pDS)
|
||||
{
|
||||
MpegCreateWindowTable();
|
||||
#ifdef MPEG_PROFILE
|
||||
mpeg_error=fopen("mpeg_info.txt","w");
|
||||
#endif MPEG_PROFILE
|
||||
b_thread_must_stop=0;
|
||||
#ifdef MPP_STAT
|
||||
// initclock();
|
||||
#endif MPP_STAT
|
||||
g_pDS=(LPDIRECTSOUND)pDS;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MpegDeinitLibrary()
|
||||
{
|
||||
{
|
||||
EWait w;
|
||||
for(MpegSound* cur=pFirstSound;cur;cur=cur->next)
|
||||
{
|
||||
cur->InternalMpegStop();
|
||||
if(cur->pDSBuffer)cur->pDSBuffer->Release();
|
||||
cur->pDSBuffer=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(hThread!=INVALID_HANDLE_VALUE)
|
||||
{
|
||||
b_thread_must_stop=1;
|
||||
while(b_thread_must_stop==1)
|
||||
Sleep(10);
|
||||
}
|
||||
|
||||
if(hWaitEvent!=INVALID_HANDLE_VALUE)
|
||||
CloseHandle(hWaitEvent);
|
||||
hWaitEvent=INVALID_HANDLE_VALUE;
|
||||
hThread=INVALID_HANDLE_VALUE;
|
||||
|
||||
g_pDS=NULL;
|
||||
}
|
||||
|
||||
//////////////////////MpegSound////////////////////////////////
|
||||
MpegSound::MpegSound()
|
||||
{
|
||||
EWait w;
|
||||
prev=NULL;
|
||||
next=pFirstSound;
|
||||
pFirstSound=this;
|
||||
if(next)next->prev=this;
|
||||
////
|
||||
//Ïîäõîäèòü ê èçìåíåíèþ sizeDSBuffer î÷åíü îñòîðîæíî
|
||||
//óâåëè÷åíèå åãî ìîæåò ñêàçàòüñÿ íà èíòåðàêòèâíîñòè
|
||||
//óìåíüøåíèå - íà çàèêàíèè çâóêà
|
||||
sizeDSBuffer=128*1024;//256*1024;
|
||||
volume=255;
|
||||
b_cycled=false;
|
||||
pDSBuffer=NULL;
|
||||
|
||||
clear_end_buffer=false;
|
||||
mpeg_state=MPEG_STOP;
|
||||
|
||||
dwWriteOffset=0;
|
||||
Wraps=OldWraps=0;
|
||||
BeginBufferOffset=OldBeginBufferOffset=0;
|
||||
OffsetBeginPlayFile=0;
|
||||
SeekSkipByte=0;
|
||||
|
||||
pMppLoad=new MppLoad;
|
||||
|
||||
last_signal_is_full=false;
|
||||
last_signal_offset=0;
|
||||
enable_fade=false;
|
||||
fade_begin_time=fade_time=0;
|
||||
fade_begin_volume=fade_end_volume=0;
|
||||
fname[0]=0;
|
||||
memset(&wave_format,0,sizeof(wave_format));
|
||||
}
|
||||
|
||||
MpegSound::~MpegSound()
|
||||
{
|
||||
EWait w;
|
||||
//
|
||||
if(prev)prev->next=next;
|
||||
else pFirstSound=next;
|
||||
if(next)next->prev=prev;
|
||||
//
|
||||
if(pDSBuffer)pDSBuffer->Release();
|
||||
delete pMppLoad;
|
||||
}
|
||||
|
||||
void MpegSound::InternalMpegSetVolume(int _volume)
|
||||
{
|
||||
volume=_volume;
|
||||
if(pDSBuffer)
|
||||
{
|
||||
HRESULT hr;
|
||||
long ddvol=ToDirectVolume(_volume);
|
||||
hr=pDSBuffer->SetVolume(ddvol);
|
||||
|
||||
if(b_pause_if_null_volume && mpeg_state==MPEG_PLAY)
|
||||
{
|
||||
DWORD status;
|
||||
if(pDSBuffer->GetStatus(&status)==DS_OK)
|
||||
{
|
||||
bool b_play=(status&DSBSTATUS_PLAYING)?true:false;
|
||||
|
||||
if(volume==0)
|
||||
{
|
||||
if(b_play)pDSBuffer->Stop();
|
||||
}else
|
||||
{
|
||||
if(!b_play)pDSBuffer->Play(0,0,DSBPLAY_LOOPING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MpegSound::DebugRealPlay()
|
||||
{
|
||||
if(pDSBuffer==NULL)return false;
|
||||
EWait w;
|
||||
DWORD status;
|
||||
if(pDSBuffer->GetStatus(&status)==DS_OK)
|
||||
{
|
||||
return (status&DSBSTATUS_PLAYING)?true:false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MpegSound::InitSoundBuffer()
|
||||
{
|
||||
|
||||
if(pDSBuffer)
|
||||
{
|
||||
if(wave_format.nChannels==pMppLoad->GetChannels())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
/*
|
||||
Çäåñü ñîçäàâàòü DirectSoundBuffer
|
||||
*/
|
||||
WAVEFORMATEX& wfx=wave_format;
|
||||
|
||||
wfx.wFormatTag=WAVE_FORMAT_PCM;
|
||||
wfx.nChannels=pMppLoad->GetChannels();
|
||||
wfx.nSamplesPerSec=44100;
|
||||
wfx.nAvgBytesPerSec=44100*2*wfx.nChannels;
|
||||
wfx.nBlockAlign=2*wfx.nChannels;
|
||||
wfx.wBitsPerSample=16;
|
||||
wfx.cbSize=0;
|
||||
|
||||
DSBUFFERDESC dsbd;
|
||||
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbd.dwFlags = //DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY |
|
||||
DSBCAPS_CTRLVOLUME |DSBCAPS_GETCURRENTPOSITION2;
|
||||
dsbd.dwBufferBytes = sizeDSBuffer;
|
||||
dsbd.lpwfxFormat = &wfx;
|
||||
|
||||
// Create the static DirectSound buffer using the focus set by the UI
|
||||
if( FAILED( hr = g_pDS->CreateSoundBuffer( &dsbd, &pDSBuffer, NULL ) ) )
|
||||
{
|
||||
pDSBuffer=NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
InternalMpegSetVolume(volume);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MpegSound::InternalMpegStop()
|
||||
{
|
||||
mpeg_state=MPEG_STOP;
|
||||
if(g_pDS==NULL)return;
|
||||
if(pDSBuffer)
|
||||
pDSBuffer->Stop();
|
||||
}
|
||||
|
||||
bool MpegSound::InternalMpegOpenToPlay(const char* _fname,bool cycled)
|
||||
{
|
||||
if(_fname==NULL)return false;
|
||||
b_cycled=cycled;
|
||||
if(fname!=_fname)
|
||||
strcpy(fname,_fname);
|
||||
|
||||
// if(mpeg_state==MPEG_PLAY)return MpegOpen(fname);
|
||||
|
||||
bool is_initialize=pMppLoad->Open(fname);
|
||||
InternalMpegStop();
|
||||
if(!is_initialize)
|
||||
return false;
|
||||
if(g_pDS==NULL)return false;
|
||||
|
||||
if(!InitSoundBuffer())return false;
|
||||
InternalMpegStop();
|
||||
Sleep(20);
|
||||
|
||||
OldWraps=Wraps=0;
|
||||
BeginBufferOffset=OldBeginBufferOffset=0;
|
||||
dwWriteOffset=0;
|
||||
OffsetBeginPlayFile=0;
|
||||
SeekSkipByte=0;
|
||||
|
||||
last_signal_is_full=false;
|
||||
last_signal_offset=0;
|
||||
|
||||
int n=sizeDSBuffer/2/(wave_format.nChannels*maximal_len);
|
||||
for(int i=0;i<n;i++)
|
||||
{
|
||||
short* pData;
|
||||
int len;
|
||||
if(!pMppLoad->GetNextFrame(pData,len))
|
||||
break;
|
||||
|
||||
BYTE *AudioPtr1,*AudioPtr2;
|
||||
DWORD AudioBytes1,AudioBytes2;
|
||||
|
||||
if(FAILED(pDSBuffer->Lock(
|
||||
dwWriteOffset,
|
||||
len,
|
||||
(LPVOID*)&AudioPtr1,
|
||||
&AudioBytes1,
|
||||
(LPVOID*)&AudioPtr2,
|
||||
&AudioBytes2,
|
||||
0
|
||||
)))
|
||||
return false;
|
||||
|
||||
if(AudioBytes1+AudioBytes2==(DWORD)len)
|
||||
{
|
||||
memcpy(AudioPtr1,pData,AudioBytes1);
|
||||
memcpy(AudioPtr2,pData+AudioBytes1,AudioBytes2);
|
||||
}
|
||||
|
||||
|
||||
pDSBuffer->Unlock(
|
||||
(LPVOID)AudioPtr1,
|
||||
AudioBytes1,
|
||||
(LPVOID)AudioPtr2,
|
||||
AudioBytes2);
|
||||
|
||||
dwWriteOffset=(dwWriteOffset+len)%sizeDSBuffer;
|
||||
}
|
||||
|
||||
ClearFade();
|
||||
if(pDSBuffer && i>0)
|
||||
{
|
||||
pDSBuffer->SetCurrentPosition(0);
|
||||
InternalMpegSetVolume(volume);
|
||||
|
||||
if(b_pause_if_null_volume && volume==0)
|
||||
pDSBuffer->Stop();
|
||||
else
|
||||
pDSBuffer->Play(0,0,DSBPLAY_LOOPING);
|
||||
}
|
||||
|
||||
if(is_initialize)
|
||||
mpeg_state=MPEG_PLAY;
|
||||
return is_initialize;
|
||||
}
|
||||
|
||||
void MpegSound::AddWriteOffset(DWORD offset)
|
||||
{
|
||||
dwWriteOffset=dwWriteOffset+offset;
|
||||
if(dwWriteOffset>=sizeDSBuffer)
|
||||
{
|
||||
DWORD add_wrap=dwWriteOffset/sizeDSBuffer;
|
||||
Wraps+=add_wrap;
|
||||
OldWraps+=add_wrap;
|
||||
dwWriteOffset=dwWriteOffset%sizeDSBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
void MpegSound::TimeCallbackTrue()
|
||||
{
|
||||
if(pDSBuffer==NULL)return;
|
||||
|
||||
FadeQuant();
|
||||
|
||||
DWORD dwPlayCursor,dwWriteCursor;
|
||||
short* pData;
|
||||
int len;
|
||||
|
||||
int num_get_bytes=0;
|
||||
Retry:
|
||||
|
||||
if(FAILED(pDSBuffer->GetCurrentPosition(
|
||||
&dwPlayCursor,
|
||||
&dwWriteCursor
|
||||
)))
|
||||
return;
|
||||
|
||||
if(dwPlayCursor<=dwWriteOffset)
|
||||
dwPlayCursor+=sizeDSBuffer;
|
||||
|
||||
if(dwWriteOffset+maximal_len*wave_format.nChannels>=dwPlayCursor ||
|
||||
num_get_bytes>2*maximal_len*wave_format.nChannels)
|
||||
{
|
||||
#ifdef MPEG_PROFILE
|
||||
mprintf("%i ",num_get_sample);
|
||||
#endif MPEG_PROFILE
|
||||
// OutputDebugString(temp_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
if(pMppLoad->GetNextFrame(pData,len))
|
||||
{
|
||||
num_get_bytes+=len;
|
||||
|
||||
HammingCorrect(pData,len/wave_format.nChannels);
|
||||
|
||||
DWORD cur_write_byte=len;
|
||||
if(cur_write_byte>SeekSkipByte)
|
||||
cur_write_byte-=SeekSkipByte;
|
||||
|
||||
BYTE *AudioPtr1,*AudioPtr2;
|
||||
DWORD AudioBytes1,AudioBytes2;
|
||||
|
||||
if(FAILED(pDSBuffer->Lock(
|
||||
dwWriteOffset,
|
||||
cur_write_byte,
|
||||
(LPVOID*)&AudioPtr1,
|
||||
&AudioBytes1,
|
||||
(LPVOID*)&AudioPtr2,
|
||||
&AudioBytes2,
|
||||
0
|
||||
)))
|
||||
{
|
||||
// OutputDebugString("Failed\n");
|
||||
SeekSkipByte=0;
|
||||
return;
|
||||
}
|
||||
|
||||
if(AudioBytes1+AudioBytes2==cur_write_byte)
|
||||
{
|
||||
if(AudioPtr1)memcpy(AudioPtr1,
|
||||
SeekSkipByte+(BYTE*)pData,AudioBytes1);
|
||||
if(AudioPtr2)memcpy(AudioPtr2,
|
||||
AudioBytes1+SeekSkipByte+(BYTE*)pData,AudioBytes2);
|
||||
}
|
||||
|
||||
pDSBuffer->Unlock((LPVOID)AudioPtr1,AudioBytes1,(LPVOID)AudioPtr2,AudioBytes2);
|
||||
|
||||
SeekSkipByte=0;
|
||||
|
||||
AddWriteOffset(cur_write_byte);
|
||||
|
||||
clear_end_buffer=true;
|
||||
goto Retry;
|
||||
}
|
||||
|
||||
#ifdef MPEG_PROFILE
|
||||
mprintf("%i ",num_get_sample);
|
||||
#endif MPEG_PROFILE
|
||||
|
||||
if(clear_end_buffer && !b_cycled)
|
||||
{//Î÷èñòèòü êîíåö áóôåðà
|
||||
clear_end_buffer=false;
|
||||
|
||||
BYTE *AudioPtr1,*AudioPtr2;
|
||||
DWORD AudioBytes1,AudioBytes2;
|
||||
|
||||
if(FAILED(pDSBuffer->Lock(
|
||||
dwWriteOffset,
|
||||
maximal_len*wave_format.nChannels,
|
||||
(LPVOID*)&AudioPtr1,
|
||||
&AudioBytes1,
|
||||
(LPVOID*)&AudioPtr2,
|
||||
&AudioBytes2,
|
||||
0
|
||||
)))
|
||||
{
|
||||
// OutputDebugString("Failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(AudioBytes1+AudioBytes2==(DWORD)maximal_len*wave_format.nChannels)
|
||||
{
|
||||
if(AudioPtr1)memset(AudioPtr1,0,AudioBytes1);
|
||||
if(AudioPtr2)memset(AudioPtr2,0,AudioBytes2);
|
||||
}
|
||||
|
||||
pDSBuffer->Unlock((LPVOID)AudioPtr1,AudioBytes1,(LPVOID)AudioPtr2,AudioBytes2);
|
||||
}
|
||||
|
||||
if(FAILED(pDSBuffer->GetCurrentPosition(&dwPlayCursor,&dwWriteCursor)))
|
||||
return;
|
||||
|
||||
pMppLoad->Close();
|
||||
if(b_cycled)
|
||||
{
|
||||
if(pMppLoad->Open(fname))
|
||||
{
|
||||
mpeg_state=MPEG_PLAY;
|
||||
OldWraps=Wraps;
|
||||
OldBeginBufferOffset=BeginBufferOffset;
|
||||
BeginBufferOffset=dwWriteOffset;
|
||||
Wraps=0;
|
||||
OffsetBeginPlayFile=0;
|
||||
SeekSkipByte=0;
|
||||
}else
|
||||
InternalMpegStop();
|
||||
}else
|
||||
{
|
||||
// if(dwPlayCursor>dwWriteOffset || dwPlayCursor+maximal_len*wave_format.nChannels<dwWriteOffset)
|
||||
// return;
|
||||
int mi=dwPlayCursor;
|
||||
int ma=mi+maximal_len*wave_format.nChannels;
|
||||
int cmp=dwWriteOffset;
|
||||
if(mi>cmp)
|
||||
cmp+=sizeDSBuffer;
|
||||
|
||||
if(mi<=cmp&& ma>=cmp)
|
||||
InternalMpegStop();
|
||||
}
|
||||
}
|
||||
|
||||
bool MpegSound::OpenToPlay(const char* _fname,bool cycled)
|
||||
{
|
||||
Stop();
|
||||
|
||||
bool is_ok;
|
||||
{
|
||||
EWait w;
|
||||
is_ok=InternalMpegOpenToPlay(_fname,cycled);
|
||||
}
|
||||
|
||||
if(is_ok)
|
||||
{
|
||||
if(hThread==INVALID_HANDLE_VALUE)
|
||||
{
|
||||
b_thread_must_stop=0;
|
||||
DWORD ThreadId;
|
||||
hThread=CreateThread(
|
||||
NULL,
|
||||
0,
|
||||
MpegThreadProc,
|
||||
NULL,
|
||||
0,
|
||||
&ThreadId);
|
||||
|
||||
hWaitEvent=CreateEvent(NULL,FALSE,TRUE,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return is_ok ;
|
||||
}
|
||||
|
||||
void MpegSound::Stop()
|
||||
{
|
||||
EWait w;
|
||||
InternalMpegStop();
|
||||
}
|
||||
|
||||
void MpegSound::SetVolume(int _volume)
|
||||
{
|
||||
EWait w;
|
||||
ClearFade();
|
||||
InternalMpegSetVolume(_volume);
|
||||
}
|
||||
|
||||
int MpegSound::GetVolume()
|
||||
{
|
||||
EWait w;
|
||||
return enable_fade?fade_begin_volume:volume;
|
||||
}
|
||||
|
||||
void MpegSound::Pause()
|
||||
{
|
||||
EWait w;
|
||||
if(pDSBuffer==NULL)return;
|
||||
pDSBuffer->Stop();
|
||||
mpeg_state=MPEG_PAUSE;
|
||||
}
|
||||
|
||||
void MpegSound::Resume()
|
||||
{
|
||||
EWait w;
|
||||
if(pDSBuffer==NULL)return;
|
||||
if(mpeg_state==MPEG_STOP)return;
|
||||
|
||||
if(b_pause_if_null_volume && volume==0)
|
||||
pDSBuffer->Stop();
|
||||
else
|
||||
if(SUCCEEDED(pDSBuffer->Play(0,0,DSBPLAY_LOOPING)))
|
||||
{
|
||||
}
|
||||
|
||||
mpeg_state=MPEG_PLAY;
|
||||
}
|
||||
|
||||
MpegState MpegSound::IsPlay()
|
||||
{
|
||||
EWait w;
|
||||
if(pDSBuffer==NULL)return MPEG_STOP;
|
||||
/*
|
||||
DWORD status;
|
||||
if(FAILED(pDSBuffer->GetStatus(&status)))
|
||||
return MPEG_STOP;
|
||||
*/
|
||||
return mpeg_state;//(status&DSBSTATUS_PLAYING)?true:false;
|
||||
}
|
||||
|
||||
double MpegGetLen(const char* fname)
|
||||
{
|
||||
OggVorbis_File vf;
|
||||
FILE* in=fopen(fname,"rb");
|
||||
if(in==NULL)
|
||||
return -1;
|
||||
|
||||
if(ov_open(in, &vf, NULL, 0) < 0) {
|
||||
fclose(in);
|
||||
return -1;
|
||||
}
|
||||
|
||||
double time=ov_time_total(&vf,-1);
|
||||
ov_clear(&vf);
|
||||
fclose(in);
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
|
||||
int window_hamming[BLK_SIZE];//Îêíî Õýììèíãà
|
||||
const h_shift=14;
|
||||
|
||||
void MpegCreateWindowTable()
|
||||
{
|
||||
const int mul=1<<h_shift;
|
||||
const double PI=3.14159265358979323846;
|
||||
for(int i=0;i<BLK_SIZE;i++)
|
||||
{
|
||||
double t=double(i)/(2*BLK_SIZE);
|
||||
double w=0.5+0.5*cos(2*PI*t);//0.54+0.46*cos(2*PI*t);
|
||||
window_hamming[i]=(int)(w*mul);
|
||||
}
|
||||
}
|
||||
|
||||
void MpegSound::HammingCorrect(short* pData,int len)
|
||||
{
|
||||
if(!last_signal_is_full)return;
|
||||
|
||||
len=len>>1;
|
||||
|
||||
int max_offset=last_signal_offset+len;
|
||||
if(max_offset>BLK_SIZE)max_offset=BLK_SIZE;
|
||||
|
||||
short* out=pData;
|
||||
short* in=last_signal+last_signal_offset*2;
|
||||
|
||||
for(int i=last_signal_offset;i<max_offset;i++)
|
||||
{
|
||||
for(int j=0;j<2;j++)
|
||||
{
|
||||
int o=//window_hamming[i]<<h_shift;
|
||||
*out*window_hamming[BLK_SIZE-i-1]
|
||||
+ *in *window_hamming[i];
|
||||
|
||||
o=o>>h_shift;
|
||||
if(o>32767)
|
||||
o=32767;
|
||||
if(o<-32768)
|
||||
o=32768;
|
||||
|
||||
*out=o;
|
||||
in++;out++;
|
||||
}
|
||||
}
|
||||
|
||||
last_signal_offset=max_offset;
|
||||
if(last_signal_offset>=BLK_SIZE)
|
||||
{
|
||||
last_signal_is_full=false;
|
||||
last_signal_offset=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool MpegSound::FadeVolume(float time,int new_volume)
|
||||
{
|
||||
if(time<=0.05f)
|
||||
{
|
||||
ClearFade();
|
||||
return false;
|
||||
}
|
||||
|
||||
enable_fade=true;
|
||||
fade_begin_time=clockf();
|
||||
fade_time=time*1000.0f;
|
||||
fade_begin_volume=volume;
|
||||
fade_end_volume=new_volume;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MpegSound::FadeQuant()
|
||||
{
|
||||
if(!enable_fade)return;
|
||||
|
||||
long vol=0;
|
||||
double cur_time=(clockf()-fade_begin_time)/fade_time;
|
||||
if(cur_time<0)
|
||||
vol=fade_begin_volume;
|
||||
else
|
||||
if(cur_time<1)
|
||||
{
|
||||
vol=round((1-cur_time)*fade_begin_volume+cur_time*fade_end_volume);
|
||||
}else
|
||||
{
|
||||
vol=fade_end_volume;
|
||||
enable_fade=false;
|
||||
}
|
||||
|
||||
InternalMpegSetVolume(vol);
|
||||
|
||||
if(!enable_fade)
|
||||
{
|
||||
volume=fade_begin_volume;
|
||||
}
|
||||
}
|
||||
|
||||
void MpegSound::ClearFade()
|
||||
{
|
||||
if(enable_fade)
|
||||
volume=fade_begin_volume;
|
||||
|
||||
enable_fade=false;
|
||||
}
|
||||
|
||||
const char* MpegSound::GetFileName()
|
||||
{
|
||||
if(fname[0]==NULL)
|
||||
return NULL;
|
||||
|
||||
return fname;
|
||||
}
|
||||
|
||||
float MpegSound::GetLen()
|
||||
{
|
||||
return pMppLoad->GetLen();
|
||||
}
|
||||
|
||||
float MpegSound::GetCurPos()
|
||||
{
|
||||
return pMppLoad->GetCurPos();
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
#ifndef _PLAYMPP_H_
|
||||
#define _PLAYMPP_H_
|
||||
#pragma once
|
||||
//Balmer
|
||||
|
||||
#include <dsound.h>
|
||||
|
||||
#define MPP_STAT
|
||||
#ifdef MPP_STAT
|
||||
double MpegCPUUsing();//Âîçâðàùàåò èñïîëüçóåìîå íà ïðîèãðûâàíèå Mpeg âðåìÿ (1 - âñ¸ âðåìÿ çàãðóçêè)
|
||||
#endif MPP_STAT
|
||||
|
||||
//
|
||||
bool MpegInitLibrary(void* LPDIRECTSOUND_pDS);
|
||||
void MpegDeinitLibrary();
|
||||
|
||||
enum MpegState
|
||||
{
|
||||
MPEG_STOP=0,
|
||||
MPEG_PLAY=1,
|
||||
MPEG_PAUSE=2,
|
||||
};
|
||||
|
||||
//Âîçâðàùàåò äëèííó â ñåêóíäàõ (íî íå î÷åíü òî÷íî,
|
||||
//ìîæåò îøèáàòüñÿ íà 26 ìñ)
|
||||
//Õîòü ýòà ôîíêöèÿ è ñóùåñòâóåò, ïîëüçîâàòüñÿ åé íå
|
||||
//ðåêîìåíäóåòñÿ. Â ïðàâèëüíî íàïèñàííîì êîäå èãðû
|
||||
//òàêàÿ ôóíêöèÿ íå íóæíà
|
||||
double MpegGetLen(const char* fname);
|
||||
|
||||
typedef double MpegPos;
|
||||
|
||||
class MpegSound
|
||||
{
|
||||
class MppLoad* pMppLoad;
|
||||
MpegSound *prev,*next;
|
||||
|
||||
DWORD sizeDSBuffer;
|
||||
bool b_cycled;
|
||||
long volume;
|
||||
|
||||
WAVEFORMATEX wave_format;
|
||||
LPDIRECTSOUNDBUFFER pDSBuffer;
|
||||
DWORD dwWriteOffset;
|
||||
DWORD Wraps;//Ñêîëüêî ðàç áûë çàïèñàí çâóêîâîé áóôôåð
|
||||
DWORD BeginBufferOffset;
|
||||
DWORD OldWraps,OldBeginBufferOffset;
|
||||
DWORD OffsetBeginPlayFile;//Ñ êàêîãî ìåñòà íà÷àë èãðàòüñÿ ôàéë
|
||||
|
||||
bool bOldFrame;//Óñòàíîâëåí, åñëè èãðàþòñÿ ñòàðûå äàííûå, à ïèøóòñÿ íîâûå
|
||||
|
||||
char fname[260];
|
||||
|
||||
bool clear_end_buffer;
|
||||
MpegState mpeg_state;
|
||||
|
||||
DWORD deferred_prev_sample;
|
||||
DWORD SeekSkipByte;//Ñêîëüêî áàéò íåîáõîäèìî ïðîïóñòèòü ñ íà÷àëà ôðýéìà
|
||||
MpegPos deferred_sample;
|
||||
char deferred_fname[260];
|
||||
|
||||
enum {block_size=36*32};//block_size==BLK_SIZE
|
||||
short last_signal[block_size*2];
|
||||
bool last_signal_is_full;
|
||||
int last_signal_offset;
|
||||
|
||||
void HammingCorrect(short* pData,int len);
|
||||
|
||||
bool enable_fade;
|
||||
double fade_begin_time,fade_time;
|
||||
long fade_begin_volume,fade_end_volume;
|
||||
public:
|
||||
MpegSound();
|
||||
~MpegSound();
|
||||
|
||||
bool OpenToPlay(const char* fname,bool cycled=true);
|
||||
void Stop();
|
||||
void Pause();
|
||||
void Resume();
|
||||
|
||||
const char* GetFileName();
|
||||
//Íå èãðàòü ìóçûêó, åñëè ãðîìêîñòü ìóçûêè ðàâíà 0
|
||||
//(ïî óìîë÷àíèþ ìóçûêà èãðàåòñÿ)
|
||||
void SetPauseIfNullVolume(bool set=true);
|
||||
|
||||
MpegState IsPlay();
|
||||
|
||||
bool DebugRealPlay();//Äåéñòâèòåëüíî ëè ïðîèãðûâàåòñÿ ìóçûêà
|
||||
|
||||
void SetVolume(int volume);//0..255
|
||||
int GetVolume();
|
||||
|
||||
inline int GetSamplePerSecond(){return 44100;}
|
||||
//Âðåìÿ ñ÷èòàåòñÿ â ñåêóíäàõ
|
||||
|
||||
//Âîçâðàùàåò âåëè÷èíó áóôåðà â ñýìïëàõ
|
||||
inline int GetBufferLen(){return sizeDSBuffer/4;}
|
||||
|
||||
//Ïîñòåïåííî èçìåíèòü ãðîìêîñòü ñ òåêóùåé äî new_volume çà âðåìÿ time
|
||||
//î÷èùàåòñÿ ïðè ñìåíå ôàéëà èëè âûçîâå SetVolume
|
||||
//Êðèâî ðàáîòàåò ñ DeferredSeek
|
||||
bool FadeVolume(float time,int new_volume=0);
|
||||
|
||||
float GetLen();//â ñåêóíäàõ
|
||||
float GetCurPos();//â ñåêóíäàõ (íåòî÷íî)
|
||||
protected:
|
||||
void InternalMpegSetVolume(int _volume);
|
||||
bool InitSoundBuffer();
|
||||
void InternalMpegStop();
|
||||
bool InternalMpegOpenToPlay(const char* _fname,bool cycled);
|
||||
|
||||
void TimeCallbackTrue();
|
||||
|
||||
//Â êàêîå ìåñòî áóôåðà íàäî áóäåò ïèñàòü,
|
||||
//åñëè â íåãî çàïèñàëè offset áàéò
|
||||
void AddWriteOffset(DWORD offset);
|
||||
|
||||
friend DWORD WINAPI MpegThreadProc(LPVOID lpParameter);
|
||||
friend void MpegDeinitLibrary();
|
||||
|
||||
bool DefferredSeek(DWORD cur_pos,DWORD cur_write_byte);
|
||||
|
||||
void ClearFade();
|
||||
void FadeQuant();
|
||||
};
|
||||
|
||||
#endif // _PLAYMPP_H_
|
||||
@@ -0,0 +1,206 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "app_core.h"
|
||||
#include "gr_dispatcher.h"
|
||||
#include "ds_snd_dispatcher.h"
|
||||
|
||||
#include "plaympp_api.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
static bool operator == (const dsSound& snd0,const sndSound& snd1)
|
||||
{
|
||||
return snd0.sound() == snd1.sound();
|
||||
}
|
||||
|
||||
static bool operator == (const dsSound& snd,const sndHandle& h)
|
||||
{
|
||||
return snd.handle() == &h;
|
||||
}
|
||||
|
||||
ds_sndDispatcher::ds_sndDispatcher() : sound_device_(NULL)
|
||||
{
|
||||
HRESULT res = DirectSoundCreate(NULL,&sound_device_,NULL);
|
||||
|
||||
if(FAILED(res) || sound_device_ == NULL)
|
||||
return;
|
||||
|
||||
HWND hWnd = static_cast<HWND>(appGetHandle());
|
||||
|
||||
grDispatcher* gp = grDispatcher::instance();
|
||||
|
||||
if(gp && gp -> is_in_fullscreen_mode()){
|
||||
res = sound_device_ -> SetCooperativeLevel(hWnd,DSSCL_EXCLUSIVE);
|
||||
if(FAILED(res))
|
||||
sound_device_ -> SetCooperativeLevel(hWnd,DSSCL_PRIORITY);
|
||||
}
|
||||
else
|
||||
sound_device_ -> SetCooperativeLevel(hWnd,DSSCL_PRIORITY);
|
||||
|
||||
mpegPlayer::init_library(sound_device_);
|
||||
}
|
||||
|
||||
ds_sndDispatcher::~ds_sndDispatcher()
|
||||
{
|
||||
sounds_.clear();
|
||||
|
||||
mpegPlayer::deinit_library();
|
||||
|
||||
if(sound_device_)
|
||||
sound_device_-> Release();
|
||||
}
|
||||
|
||||
void ds_sndDispatcher::quant()
|
||||
{
|
||||
sounds_.remove_if(std::mem_fun_ref(dsSound::is_stopped));
|
||||
}
|
||||
|
||||
bool ds_sndDispatcher::play_sound(const sndSound* snd,bool loop,float start_position,int vol)
|
||||
{
|
||||
if(!sound_device_) return false;
|
||||
|
||||
if(is_enabled()){
|
||||
sounds_.push_back(dsSound(*snd,sound_device_));
|
||||
dsSound& p = sounds_.back();
|
||||
|
||||
if(loop)
|
||||
p.toggle_looping();
|
||||
|
||||
int snd_volume = (vol == 255) ? volume_dB() : convert_volume_to_dB((volume() * vol) >> 8);
|
||||
|
||||
p.create_sound_buffer();
|
||||
p.set_volume(snd_volume);
|
||||
p.change_frequency(frequency_coeff());
|
||||
p.set_position(start_position);
|
||||
|
||||
if(!is_paused()){
|
||||
if(!p.play()) return false;
|
||||
}
|
||||
else
|
||||
p.pause();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ds_sndDispatcher::stop_sound(const sndSound* snd)
|
||||
{
|
||||
if(!sound_device_) return false;
|
||||
|
||||
sound_list_t::iterator it = std::find(sounds_.begin(),sounds_.end(),*snd);
|
||||
|
||||
if(it != sounds_.end()){
|
||||
it -> stop();
|
||||
sounds_.erase(it);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ds_sndDispatcher::stop_sound(const sndHandle* handle)
|
||||
{
|
||||
if(!sound_device_) return false;
|
||||
|
||||
sound_list_t::iterator it = std::find(sounds_.begin(),sounds_.end(),*handle);
|
||||
|
||||
if(it != sounds_.end()){
|
||||
it -> stop();
|
||||
sounds_.erase(it);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
sndSound::status_t ds_sndDispatcher::sound_status(const sndHandle* handle) const
|
||||
{
|
||||
sound_list_t::const_iterator it = std::find(sounds_.begin(),sounds_.end(),*handle);
|
||||
|
||||
if(it != sounds_.end()){
|
||||
if(is_paused())
|
||||
return sndSound::SOUND_PAUSED;
|
||||
|
||||
return sndSound::SOUND_PLAYING;
|
||||
}
|
||||
|
||||
return sndSound::SOUND_STOPPED;
|
||||
}
|
||||
|
||||
sndSound::status_t ds_sndDispatcher::sound_status(const sndSound* snd) const
|
||||
{
|
||||
sound_list_t::const_iterator it = std::find(sounds_.begin(),sounds_.end(),*snd);
|
||||
|
||||
if(it != sounds_.end())
|
||||
return it -> status();
|
||||
|
||||
return sndSound::SOUND_STOPPED;
|
||||
}
|
||||
|
||||
bool ds_sndDispatcher::update_volume()
|
||||
{
|
||||
for(sound_list_t::iterator it = sounds_.begin(); it != sounds_.end(); ++it)
|
||||
it -> set_volume(volume_dB());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ds_sndDispatcher::update_frequency()
|
||||
{
|
||||
for(sound_list_t::iterator it = sounds_.begin(); it != sounds_.end(); ++it)
|
||||
it -> change_frequency(frequency_coeff());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ds_sndDispatcher::stop_sounds()
|
||||
{
|
||||
for(sound_list_t::iterator it = sounds_.begin(); it != sounds_.end(); ++it)
|
||||
it -> stop();
|
||||
|
||||
sounds_.clear();
|
||||
}
|
||||
|
||||
bool ds_sndDispatcher::set_sound_frequency(const sndHandle* snd,float coeff)
|
||||
{
|
||||
sound_list_t::iterator it = std::find(sounds_.begin(),sounds_.end(),*snd);
|
||||
|
||||
if(it != sounds_.end()){
|
||||
it -> change_frequency(frequency_coeff() * coeff);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
float ds_sndDispatcher::sound_position(const sndHandle* snd) const
|
||||
{
|
||||
sound_list_t::const_iterator it = std::find(sounds_.begin(),sounds_.end(),*snd);
|
||||
|
||||
if(it != sounds_.end())
|
||||
return it -> position();
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void ds_sndDispatcher::pause_sounds()
|
||||
{
|
||||
for(sound_list_t::iterator it = sounds_.begin(); it != sounds_.end(); ++it)
|
||||
it -> pause();
|
||||
}
|
||||
|
||||
void ds_sndDispatcher::resume_sounds()
|
||||
{
|
||||
for(sound_list_t::iterator it = sounds_.begin(); it != sounds_.end(); ++it){
|
||||
if(it -> is_paused())
|
||||
it -> resume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef __DS_SND_DISPATCHER_H__
|
||||
#define __DS_SND_DISPATCHER_H__
|
||||
|
||||
#include "snd_dispatcher.h"
|
||||
#include "ds_sound.h"
|
||||
|
||||
//! Äèñïåò÷åð çâóêîâ íà DirectSound.
|
||||
class ds_sndDispatcher : public sndDispatcher
|
||||
{
|
||||
public:
|
||||
ds_sndDispatcher();
|
||||
~ds_sndDispatcher();
|
||||
|
||||
//! Ëîãè÷åñêèé êâàíò.
|
||||
void quant();
|
||||
//! Çàïóñêàåò ïðîèãðûâàíèå çâóêà.
|
||||
bool play_sound(const sndSound* snd,bool loop,float start_position = 0.0f,int vol = 255);
|
||||
//! Îñòàíàâëèâàåò ïðîèãðûâàíèå çâóêà.
|
||||
bool stop_sound(const sndSound* snd);
|
||||
//! Îñòàíàâëèâàåò ïðîèãðûâàíèå çâóêà.
|
||||
bool stop_sound(const sndHandle* handle);
|
||||
//! Âîçâðàùàåò ñîñòîÿíèå çâóêà (èãðàåòñÿ/îñòàíîâëåí è ò.ä.).
|
||||
sndSound::status_t sound_status(const sndHandle* handle) const;
|
||||
//! Âîçâðàùàåò ñîñòîÿíèå çâóêà (èãðàåòñÿ/îñòàíîâëåí è ò.ä.).
|
||||
sndSound::status_t sound_status(const sndSound* snd) const;
|
||||
//! Âîçâðàùàåò òåêóùóþ ïîçèöèþ çâóêà, îò 0.0 (íà÷àëî) äî 1.0 (êîíåö).
|
||||
float sound_position(const sndHandle* snd) const;
|
||||
//! Èçìåíåíèå ÷àñòîòû çâóêà.
|
||||
bool set_sound_frequency(const sndHandle* snd,float coeff);
|
||||
|
||||
//! Îñòàíàâëèâàåò âñå çâóêè.
|
||||
void stop_sounds();
|
||||
//! Ñòàâèò âñå èãðàþùèå â äàííûé ìîìåíò çâóêè íà ïàóçó.
|
||||
void pause_sounds();
|
||||
//! Âîçîáíîâëÿåò ïðîèãðûâàíèå âñåõ çâóêîâ, êîòîðûå áûëè ïîñòàâëåíû íà ïàóçó.
|
||||
void resume_sounds();
|
||||
|
||||
protected:
|
||||
|
||||
//! Îáíîâëåíèå óñòàíîâêè ãðîìêîñòè.
|
||||
bool update_volume();
|
||||
|
||||
bool update_frequency();
|
||||
|
||||
private:
|
||||
|
||||
typedef std::list<dsSound> sound_list_t;
|
||||
//! Ñïèñîê àêòèâíûõ çâóêîâ.
|
||||
sound_list_t sounds_;
|
||||
|
||||
//! Óêàçàòåëü íà DirectSound èíòåðôåéñ.
|
||||
LPDIRECTSOUND sound_device_;
|
||||
};
|
||||
|
||||
#endif /* __DS_SND_DISPATCHER_H__ */
|
||||
@@ -0,0 +1,204 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "ds_sound.h"
|
||||
#include "wav_sound.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
dsSound::dsSound(const sndSound& snd,LPDIRECTSOUND sound_device) : sndSound(snd),
|
||||
sound_device_(sound_device),
|
||||
sound_buffer_(NULL),
|
||||
flags_(0)
|
||||
{
|
||||
}
|
||||
|
||||
dsSound::dsSound(const dsSound& snd) : sndSound(snd),
|
||||
sound_device_(snd.sound_device_),
|
||||
sound_buffer_(snd.sound_buffer_),
|
||||
flags_(snd.flags_)
|
||||
{
|
||||
}
|
||||
|
||||
dsSound::~dsSound()
|
||||
{
|
||||
release_sound_buffer();
|
||||
}
|
||||
|
||||
bool dsSound::create_sound_buffer()
|
||||
{
|
||||
if(!sound())
|
||||
return false;
|
||||
|
||||
WAVEFORMATEX wfx;
|
||||
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.nChannels = WORD(sound() -> channels());
|
||||
wfx.nSamplesPerSec = sound() -> samples_per_sec();
|
||||
wfx.wBitsPerSample = WORD(sound() -> bits_per_sample());
|
||||
wfx.nBlockAlign = (wfx.nChannels * wfx.wBitsPerSample) / 8;
|
||||
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
||||
wfx.cbSize = 0;
|
||||
|
||||
DSBUFFERDESC desc;
|
||||
memset(&desc,0,sizeof(DSBUFFERDESC));
|
||||
|
||||
desc.dwSize = sizeof(DSBUFFERDESC);
|
||||
desc.dwFlags = DSBCAPS_STATIC | DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_CTRLVOLUME | DSBCAPS_GETCURRENTPOSITION2;
|
||||
desc.dwBufferBytes = sound() -> data_length();
|
||||
desc.lpwfxFormat = &wfx;
|
||||
|
||||
release_sound_buffer();
|
||||
|
||||
HRESULT res = sound_device_ -> CreateSoundBuffer(&desc,&sound_buffer_,NULL);
|
||||
if(FAILED(res))
|
||||
return false;
|
||||
|
||||
LPVOID ptr_1 = NULL,ptr_2 = NULL;
|
||||
DWORD size_1,size_2;
|
||||
|
||||
res = sound_buffer_ -> Lock(0,sound() -> data_length(),&ptr_1,&size_1,&ptr_2,&size_2,0L);
|
||||
if(FAILED(res) || ptr_1 == NULL)
|
||||
return false;
|
||||
|
||||
memcpy(ptr_1,sound() -> data(),sound() -> data_length());
|
||||
|
||||
res = sound_buffer_ -> Unlock(ptr_1,sound() -> data_length(),NULL,0L);
|
||||
if(FAILED(res))
|
||||
return false;
|
||||
|
||||
sound_buffer_ -> SetCurrentPosition(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dsSound::release_sound_buffer()
|
||||
{
|
||||
if(sound_buffer_){
|
||||
if(!is_stopped())
|
||||
stop();
|
||||
|
||||
sound_buffer_ -> Release();
|
||||
sound_buffer_ = NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dsSound::play()
|
||||
{
|
||||
flags_ &= ~SOUND_FLAG_PAUSED;
|
||||
|
||||
if(!sound_buffer_) return false;
|
||||
|
||||
DWORD flags = (flags_ & SOUND_FLAG_LOOPING) ? DSBPLAY_LOOPING : 0;
|
||||
sound_buffer_ -> Play(0,0,flags);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dsSound::stop()
|
||||
{
|
||||
if(!sound_buffer_) return false;
|
||||
sound_buffer_ -> Stop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dsSound::pause()
|
||||
{
|
||||
flags_ |= SOUND_FLAG_PAUSED;
|
||||
stop();
|
||||
}
|
||||
|
||||
void dsSound::resume()
|
||||
{
|
||||
play();
|
||||
}
|
||||
|
||||
sndSound::status_t dsSound::status() const
|
||||
{
|
||||
if(!sound_buffer_) return sndSound::SOUND_STOPPED;
|
||||
|
||||
if(is_paused()) return sndSound::SOUND_PAUSED;
|
||||
|
||||
DWORD st;
|
||||
sound_buffer_ -> GetStatus(&st);
|
||||
|
||||
if(st & (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING)) return SOUND_PLAYING;
|
||||
|
||||
return SOUND_STOPPED;
|
||||
}
|
||||
|
||||
bool dsSound::is_stopped() const
|
||||
{
|
||||
switch(status()){
|
||||
case SOUND_PLAYING:
|
||||
case SOUND_PAUSED:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool dsSound::set_volume(int vol)
|
||||
{
|
||||
if(!sound_buffer_) return false;
|
||||
|
||||
sound_buffer_ -> SetVolume(vol);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dsSound::change_frequency(float coeff)
|
||||
{
|
||||
if(!sound_buffer_) return false;
|
||||
|
||||
DWORD freq;
|
||||
if(sound_buffer_ -> GetFrequency(&freq) != DS_OK)
|
||||
return false;
|
||||
|
||||
freq = round(float(freq) * coeff);
|
||||
if(freq > DSBFREQUENCY_MAX)
|
||||
freq = DSBFREQUENCY_MAX;
|
||||
else if(freq < DSBFREQUENCY_MIN)
|
||||
freq = DSBFREQUENCY_MIN;
|
||||
|
||||
if(sound_buffer_ -> SetFrequency(freq) != DS_OK)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
float dsSound::position() const
|
||||
{
|
||||
if(!sound_buffer_) return 0.0f;
|
||||
|
||||
DWORD pos = 0;
|
||||
if(sound_buffer_ -> GetCurrentPosition(&pos,NULL) == DS_OK){
|
||||
float norm_pos = float(pos) / float(sound() -> data_length());
|
||||
|
||||
if(norm_pos < 0.0f) norm_pos = 0.0f;
|
||||
if(norm_pos > 1.0f) norm_pos = 1.0f;
|
||||
|
||||
return norm_pos;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
bool dsSound::set_position(float pos)
|
||||
{
|
||||
if(sound_buffer_){
|
||||
DWORD npos = DWORD(float(sound() -> data_length() * pos));
|
||||
|
||||
if(sound_buffer_ -> SetCurrentPosition(npos) == DS_OK)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#ifndef __DS_SOUND_H__
|
||||
#define __DS_SOUND_H__
|
||||
|
||||
#include <dsound.h>
|
||||
|
||||
#include "snd_sound.h"
|
||||
|
||||
class wavSound;
|
||||
|
||||
//! DirectSound çâóê.
|
||||
class dsSound : public sndSound
|
||||
{
|
||||
public:
|
||||
dsSound(const sndSound& snd,LPDIRECTSOUND sound_device);
|
||||
dsSound(const dsSound& snd);
|
||||
~dsSound();
|
||||
|
||||
//! Çàïóñêàåò ïðîèãðûâàíèå çâóêà.
|
||||
bool play();
|
||||
//! Îñòàíàâëèâàåò ïðîèãðûâàíèå çâóêà.
|
||||
bool stop();
|
||||
//! Ñòàâèò çâóê íà ïàóçó.
|
||||
void pause();
|
||||
//! Âîçîáíîâëÿåò ïðîèãðûâàíèå.
|
||||
void resume();
|
||||
//! Âîçâðàùàåò true, åñëè çâóê íà ïàóçå.
|
||||
bool is_paused() const { if(flags_ & SOUND_FLAG_PAUSED) return true; else return false; }
|
||||
|
||||
//! Âîçâðàùàåò true, åñëè çâóê íå ïðîèãðûâàåòñÿ.
|
||||
bool is_stopped() const;
|
||||
//! Âîçâðàùàåò ñîñòîÿíèå çâóêà.
|
||||
sndSound::status_t status() const;
|
||||
|
||||
//! Óñòàíàâëèâàåò ãðîìêîñòü çâóêà, ïàðàìåòð - â äåöèáåëàõ.
|
||||
/**
|
||||
Äèàïàçîí çíà÷åíèé ãðîìêîñòè - [-10000, 0]
|
||||
|
||||
-10000 - çâóê ñîâñåì íå ñëûøåí,
|
||||
0 - ãðîìêîñòü ñàìîãî çâóêà ïî óìîë÷àíèþ.
|
||||
*/
|
||||
bool set_volume(int vol);
|
||||
|
||||
bool change_frequency(float coeff = 1.0f);
|
||||
|
||||
//! Âîçâðàùàåò òåêóùóþ ïîçèöèþ çâóêà, äèàïàçîí âîçâðàùàåìûõ çíà÷åíèé - [0.0, 1.0].
|
||||
float position() const;
|
||||
//! Óñòàíàâëèâàåò òåêóùóþ ïîçèöèþ çâóêà, äèàïàçîí çíà÷åíèé ïàðàìåòðà - [0.0, 1.0].
|
||||
bool set_position(float pos);
|
||||
|
||||
//! Ñîçäàåò DirectSoundBuffer.
|
||||
bool create_sound_buffer();
|
||||
//! Óäàëÿåò DirectSoundBuffer.
|
||||
bool release_sound_buffer();
|
||||
|
||||
//! Âêëþ÷àåò/âûêëþ÷àåò çàöèêëèâàíèå çâóêà.
|
||||
void toggle_looping(){ flags_ ^= SOUND_FLAG_LOOPING; }
|
||||
|
||||
private:
|
||||
//! Óêàçàòåëü íà îáúåêò DirectSound.
|
||||
const LPDIRECTSOUND sound_device_;
|
||||
//! Óêàçàòåëü íà DirectSoundBuffer.
|
||||
LPDIRECTSOUNDBUFFER sound_buffer_;
|
||||
|
||||
//! ôëàãè
|
||||
enum {
|
||||
SOUND_FLAG_LOOPING = 0x01,
|
||||
SOUND_FLAG_PAUSED = 0x02
|
||||
};
|
||||
|
||||
//! ôëàãè
|
||||
int flags_;
|
||||
};
|
||||
|
||||
#endif /* __DS_SOUND_H__ */
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "snd_dispatcher.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
sndDispatcher* sndDispatcher::dispatcher_ptr_;
|
||||
|
||||
#ifdef _QUEST_EDITOR
|
||||
sndDispatcher::SoundDisabler::SoundDisabler(){
|
||||
if(sndDispatcher* p = sndDispatcher::get_dispatcher())
|
||||
{
|
||||
soundEnabled_ = p->is_enabled();
|
||||
p -> disable();
|
||||
}
|
||||
}
|
||||
sndDispatcher::SoundDisabler::~SoundDisabler(){
|
||||
if(sndDispatcher* p = sndDispatcher::get_dispatcher())
|
||||
if (soundEnabled_) p ->enable();
|
||||
}
|
||||
#endif // _QUEST_EDITOR
|
||||
|
||||
sndDispatcher::sndDispatcher() : is_enabled_(true),
|
||||
is_paused_(false),
|
||||
volume_(255),
|
||||
volume_dB_(0),
|
||||
frequency_coeff_(1.0f)
|
||||
{
|
||||
if(!dispatcher_ptr_) dispatcher_ptr_ = this;
|
||||
}
|
||||
|
||||
sndDispatcher::~sndDispatcher()
|
||||
{
|
||||
if(dispatcher_ptr_ == this) dispatcher_ptr_ = NULL;
|
||||
}
|
||||
|
||||
void sndDispatcher::set_volume(unsigned int vol)
|
||||
{
|
||||
volume_ = vol & 0xFF;
|
||||
|
||||
volume_dB_ = convert_volume_to_dB(volume_);
|
||||
|
||||
update_volume();
|
||||
}
|
||||
|
||||
int sndDispatcher::convert_volume_to_dB(int vol)
|
||||
{
|
||||
if(vol > 255) vol = 255;
|
||||
if(vol < 0) vol = 0;
|
||||
|
||||
if(vol != 255){
|
||||
const int DB_MIN = -10000;
|
||||
const int DB_MAX = 0;
|
||||
const int DB_SIZE = DB_MAX - DB_MIN;
|
||||
|
||||
return (DB_MIN + round(log10(9.0*log(double(vol + 1))/(log(2.0)*8) + 1.0)*DB_SIZE));
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
#ifndef __SND_DISPATCHER_H__
|
||||
#define __SND_DISPATCHER_H__
|
||||
|
||||
#include "snd_sound.h"
|
||||
|
||||
class wavSound;
|
||||
|
||||
//! Äèñïåò÷åð çâóêà.
|
||||
class sndDispatcher
|
||||
{
|
||||
public:
|
||||
sndDispatcher();
|
||||
virtual ~sndDispatcher();
|
||||
|
||||
//! Ëîãè÷åñêèé êâàíò.
|
||||
virtual void quant() = 0;
|
||||
//! Çàïóñêàåò ïðîèãðûâàíèå çâóêà.
|
||||
virtual bool play_sound(const sndSound* snd,bool loop,float start_position = 0.0f,int vol = 255) = 0;
|
||||
//! Îñòàíàâëèâàåò ïðîèãðûâàíèå çâóêà.
|
||||
virtual bool stop_sound(const sndSound* snd) = 0;
|
||||
//! Îñòàíàâëèâàåò ïðîèãðûâàíèå çâóêà.
|
||||
virtual bool stop_sound(const sndHandle* handle) = 0;
|
||||
//! Âîçâðàùàåò ñîñòîÿíèå çâóêà (èãðàåòñÿ/îñòàíîâëåí è ò.ä.).
|
||||
virtual sndSound::status_t sound_status(const sndHandle* handle) const = 0;
|
||||
//! Âîçâðàùàåò ñîñòîÿíèå çâóêà (èãðàåòñÿ/îñòàíîâëåí è ò.ä.).
|
||||
virtual sndSound::status_t sound_status(const sndSound* snd) const = 0;
|
||||
//! Âîçâðàùàåò òåêóùóþ ïîçèöèþ çâóêà, îò 0.0 (íà÷àëî) äî 1.0 (êîíåö).
|
||||
virtual float sound_position(const sndHandle* snd) const = 0;
|
||||
//! Èçìåíåíèå ÷àñòîòû çâóêà.
|
||||
virtual bool set_sound_frequency(const sndHandle* snd,float coeff) = 0;
|
||||
|
||||
//! Èçìåíåíèå ãðîìêîñòè, äèàïàçîí çíà÷åíèé - [0, 255].
|
||||
void set_volume(unsigned int vol);
|
||||
//! Âîçâðàùàåò óñòàíîâëåííóþ ãðîìêîñòü, äèàïàçîí çíà÷åíèé - [0, 255].
|
||||
unsigned int volume() const { return volume_; }
|
||||
|
||||
//! Âîçâðàùàåò óñòàíîâëåííóþ ãðîìêîñòü â äåöèáåëàõ.
|
||||
int volume_dB() const { return volume_dB_; }
|
||||
|
||||
void set_frequency_coeff(float coeff){ frequency_coeff_ = coeff; update_frequency(); }
|
||||
float frequency_coeff() const { return frequency_coeff_; }
|
||||
|
||||
//! Ïåðåñ÷åò ãðîìêîñòè â äåöèáåëû.
|
||||
static int convert_volume_to_dB(int vol);
|
||||
|
||||
//! Îñòàíàâëèâàåò âñå çâóêè.
|
||||
virtual void stop_sounds() = 0;
|
||||
//! Ñòàâèò âñå èãðàþùèå â äàííûé ìîìåíò çâóêè íà ïàóçó.
|
||||
virtual void pause_sounds() = 0;
|
||||
//! Âîçîáíîâëÿåò ïðîèãðûâàíèå âñåõ çâóêîâ, êîòîðûå áûëè ïîñòàâëåíû íà ïàóçó.
|
||||
virtual void resume_sounds() = 0;
|
||||
|
||||
//! Ñòàâèò âñå çâóêè íà ïàóçó äî âûçîâà resume().
|
||||
void pause(){
|
||||
is_paused_ = true;
|
||||
pause_sounds();
|
||||
}
|
||||
//! Âîçîáíîâëÿåò ïðîèãðûâàíèå âñåõ çâóêîâ.
|
||||
void resume(){
|
||||
is_paused_ = false;
|
||||
resume_sounds();
|
||||
}
|
||||
//! Âîçâðàùàåò true, åñëè çâóêè ïîñòàâëåíû íà ïàóçó.
|
||||
bool is_paused() const { return is_paused_; }
|
||||
|
||||
//! Âîçâðàùàåò true, åñëè çâóê âûêëþ÷åí.
|
||||
bool is_enabled() const { return is_enabled_; }
|
||||
//! Âêëþ÷àåò çâóê.
|
||||
void enable(){ is_enabled_ = true; }
|
||||
//! Âûêëþ÷àåò çâóê.
|
||||
void disable(){ is_enabled_ = false; stop_sounds(); }
|
||||
|
||||
//! Âîçâðàùàåò óêàçàòåëü íà òåêóùèé äèñïåò÷åð.
|
||||
static inline sndDispatcher* get_dispatcher(){ return dispatcher_ptr_; }
|
||||
//! Óñòàíàâëèâàåò óêàçàòåëü íà òåêóùèé äèñïåò÷åð.
|
||||
static inline sndDispatcher* set_dispatcher(sndDispatcher* p){ sndDispatcher* old_p = dispatcher_ptr_; dispatcher_ptr_ = p; return old_p; }
|
||||
|
||||
#ifdef _QUEST_EDITOR
|
||||
//! \brief â êîñòðóêòîðå çâóê îòêëþ÷àåòñÿ(åñëè áûë âêëþ÷åí). â äåñòðóêòîðå âêëþ÷àåòñÿ,
|
||||
//! åñëè áûë îòêëþ÷åí
|
||||
class SoundDisabler{
|
||||
bool soundEnabled_;
|
||||
public:
|
||||
SoundDisabler();
|
||||
~SoundDisabler();
|
||||
};
|
||||
#endif // _QUEST_EDITOR
|
||||
protected:
|
||||
|
||||
//! Îáíîâëåíèå óñòàíîâêè ãðîìêîñòè.
|
||||
virtual bool update_volume() = 0;
|
||||
virtual bool update_frequency() = 0;
|
||||
|
||||
private:
|
||||
|
||||
//! Çâóê âûêëþ÷åí, åñëè false.
|
||||
bool is_enabled_;
|
||||
|
||||
//! Ãðîìêîñòü, äèàïàçîí çíà÷åíèé - [0, 255].
|
||||
/**
|
||||
0 - çâóê ïîëíîñòüþ äàâèòñÿ
|
||||
255 - çâóê èãðàåòñÿ â ïîëíóþ ãðîìêîñòü
|
||||
*/
|
||||
unsigned int volume_;
|
||||
|
||||
//! Ãðîìêîñòü â äåöèáåëàõ, äèàïàçîí çíà÷åíèé - [-10000, 0].
|
||||
/**
|
||||
-10000 - çâóê ïîëíîñòüþ äàâèòñÿ
|
||||
0 - çâóê èãðàåòñÿ â ïîëíóþ ãðîìêîñòü
|
||||
*/
|
||||
int volume_dB_;
|
||||
|
||||
float frequency_coeff_;
|
||||
|
||||
//! Ïàóçà.
|
||||
bool is_paused_;
|
||||
|
||||
//! Òåêóùèé äèñïåò÷åð.
|
||||
static sndDispatcher* dispatcher_ptr_;
|
||||
};
|
||||
|
||||
#endif /* __SND_DISPATCHER_H__ */
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
|
||||
#ifndef __SND_SOUND_H__
|
||||
#define __SND_SOUND_H__
|
||||
|
||||
class wavSound;
|
||||
class qdNamedObject;
|
||||
|
||||
//! Êëàññ äëÿ óïðàâëåíèÿ çâóêàìè.
|
||||
class sndHandle
|
||||
{
|
||||
public:
|
||||
sndHandle(){ };
|
||||
virtual ~sndHandle(){ };
|
||||
};
|
||||
|
||||
//! Áàçîâûé êëàññ äëÿ çâóêîâ.
|
||||
class sndSound
|
||||
{
|
||||
public:
|
||||
explicit sndSound(const wavSound* snd,const sndHandle* h = NULL) : sound_(snd), handle_(h) { }
|
||||
sndSound(const sndSound& snd) : sound_(snd.sound_), handle_(snd.handle_) { }
|
||||
virtual ~sndSound(){ };
|
||||
|
||||
sndSound& operator = (const sndSound& s){
|
||||
if(this == &s) return *this;
|
||||
|
||||
sound_ = s.sound_;
|
||||
handle_ = s.handle_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Ñîñòîÿíèå çâóêà.
|
||||
enum status_t {
|
||||
//! çâóê íå ïðîèãðûâàåòñÿ
|
||||
SOUND_STOPPED,
|
||||
//! çâóê ïðèîñòàíîâëåí
|
||||
SOUND_PAUSED,
|
||||
//! çâóê ïðèãðûâàåòñÿ
|
||||
SOUND_PLAYING
|
||||
};
|
||||
|
||||
//! Âîçâðàùàåò ñîñòîÿíèå çâóêà.
|
||||
virtual status_t status() const { return SOUND_STOPPED; }
|
||||
|
||||
//! Âîçâðàùàåò óêàçàòåëü íà äàííûå çâóêà.
|
||||
const wavSound* sound() const { return sound_; }
|
||||
//! Âîçâðàùàåò óêàçàòåëü íà õýíäë çâóêà.
|
||||
const sndHandle* handle() const { return handle_; }
|
||||
|
||||
private:
|
||||
//! Óêàçàòåëü íà äàííûå.
|
||||
const wavSound* sound_;
|
||||
//! Óêàçàòåëü íà õýíäë çâóêà.
|
||||
const sndHandle* handle_;
|
||||
};
|
||||
|
||||
#endif /* __SND_SOUND_H__ */
|
||||
@@ -0,0 +1,219 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "wav_file.h"
|
||||
#include "wav_sound.h"
|
||||
|
||||
#include "qd_file_manager.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
|
||||
LRESULT PASCAL wav_IO_proc(LPSTR lpmmioinfo,UINT wMsg,LPARAM lParam1,LPARAM lParam2);
|
||||
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
bool ReadWaveFormat (const HMMIO hmmio,const char * sFileName,WAVEFORMATEX* pwfx,int* iDataSize,MMCKINFO* ckRiff)
|
||||
{
|
||||
// read 'RIFF' chunk
|
||||
if(mmioDescend(hmmio,ckRiff,NULL,0) != 0){
|
||||
// Log("(winFormatWAVE_c::Import): can't find 'RIFF' chunk, file %s",sFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check to make sure this is a valid wave file
|
||||
if(ckRiff -> ckid != FOURCC_RIFF || ckRiff -> fccType != mmioFOURCC ('W','A','V','E')){
|
||||
// Log("(winFormatWAVE_c::Import): invalid 'RIFF' chunk, file %s",sFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// search the input file for for the 'fmt ' chunk.
|
||||
MMCKINFO ckInfo;
|
||||
ckInfo.ckid = mmioFOURCC('f','m','t',' ');
|
||||
if(mmioDescend(hmmio,&ckInfo,ckRiff,MMIO_FINDCHUNK ) != 0){
|
||||
// Log("(winFormatWAVE_c::Import): can't find 'fmt ' chunk, file %s",sFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// expect the 'fmt ' chunk to be at least as large as <PCMWAVEFORMAT>.
|
||||
// if there are extra parameters at the end, we'll ignore them.
|
||||
if(ckInfo.cksize < static_cast <LONG>(sizeof(PCMWAVEFORMAT))){
|
||||
// Log("(winFormatWAVE_c::Import): invalid 'fmt ' chunk, file %s",sFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// read the 'fmt ' chunk
|
||||
if(mmioRead(hmmio,reinterpret_cast <HPSTR>(pwfx),sizeof(PCMWAVEFORMAT)) != sizeof(PCMWAVEFORMAT)){
|
||||
// Log("(winFormatWAVE_c::Import): can't read information from 'fmt ' chunk, file %s",sFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
pwfx -> cbSize = 0; // ignore extra bytes
|
||||
|
||||
// ascend the input file out of the 'fmt ' chunk
|
||||
if(mmioAscend(hmmio,&ckInfo,0) != 0){
|
||||
// Log("(winFormatWAVE_c::Import): Ascend failed, file %s",sFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check format tag
|
||||
if(pwfx -> wFormatTag != WAVE_FORMAT_PCM){
|
||||
// Log("(winFormatWAVE_c::Import): invalid wave format (%i), file %s", static_cast <int> (pwfx->wFormatTag),sFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check channels
|
||||
if(pwfx -> nChannels != 1 && pwfx->nChannels != 2){
|
||||
// Log("(winFormatWAVE_c::Import): invalid channels (%i), file %s", static_cast <int> (pwfx->nChannels), sFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check bits per sample
|
||||
if(pwfx -> wBitsPerSample != 8 && pwfx->wBitsPerSample != 16){
|
||||
// Log("(winFormatWAVE_c::Import): invalid bits per sample (%i), file %s", static_cast <int> (pwfx->wBitsPerSample), sFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// seek to the data
|
||||
if(mmioSeek(hmmio,ckRiff -> dwDataOffset + sizeof(FOURCC),SEEK_SET) == -1){
|
||||
// Log("(winFormatWAVE_c::Import): can't seek to the data, file %s", sFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// search the input file for the 'data' chunk.
|
||||
MMCKINFO ck;
|
||||
ck.ckid = mmioFOURCC('d','a','t','a');
|
||||
if(mmioDescend(hmmio,&ck,ckRiff,MMIO_FINDCHUNK) != 0){
|
||||
// Log("(winFormatWAVE_c::Import): can't find 'data' chunk, file %s", sFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check size of sound data
|
||||
if(ck.cksize == 0){
|
||||
// Log ("(winFormatWAVE_c::Import): invalid data size, file %s", sFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
*iDataSize = ck.cksize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadWaveData(const HMMIO hmmio,const char* sFileName,char* pBuffer,int iSize,MMCKINFO* ckRiff)
|
||||
{
|
||||
MMIOINFO info; // current status of hmmio
|
||||
|
||||
if(mmioGetInfo(hmmio,&info,0) != 0){
|
||||
// Log("(winFormatWAVE_c::Import): mmioGetInfo failed, file %s", sFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int i = 0; i < iSize; i ++){
|
||||
// copy the bytes from the io to the buffer.
|
||||
if(info.pchNext == info.pchEndRead){
|
||||
if(mmioAdvance(hmmio,&info,MMIO_READ) != 0){
|
||||
// Log("(winFormatWAVE_c::Import): mmioAdvance failed, file %s", sFileName);
|
||||
return false;
|
||||
}
|
||||
if(info.pchNext == info.pchEndRead){
|
||||
// Log("(winFormatWAVE_c::Import): invalid info.pchNext, file %s", sFileName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// actual copy
|
||||
*((BYTE*)pBuffer + i) = *((BYTE*)info.pchNext);
|
||||
info.pchNext ++;
|
||||
}
|
||||
|
||||
if(mmioSetInfo(hmmio,&info,0) != 0){
|
||||
// Log("(winFormatWAVE_c::Import): mmioSetInfo failed, file %s", sFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wav_file_load(const char* fname,class wavSound* snd)
|
||||
{
|
||||
if(!fname)
|
||||
return false;
|
||||
|
||||
MMIOINFO inf;
|
||||
memset(&inf,0,sizeof(MMIOINFO));
|
||||
|
||||
inf.pIOProc = wav_IO_proc;
|
||||
|
||||
HMMIO hmmio = mmioOpen(const_cast<char*>(fname),&inf,MMIO_ALLOCBUF | MMIO_READ);
|
||||
if(hmmio == NULL)
|
||||
return false;
|
||||
|
||||
// read the wave format
|
||||
WAVEFORMATEX wfx;
|
||||
MMCKINFO ckRiff;
|
||||
int iDataSize = 0;
|
||||
|
||||
memset(&wfx,0,sizeof(wfx));
|
||||
if(!ReadWaveFormat(hmmio,fname,&wfx,&iDataSize,&ckRiff)){
|
||||
mmioClose(hmmio,0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// create the wave
|
||||
snd -> init(iDataSize,wfx.wBitsPerSample,wfx.nChannels,wfx.nSamplesPerSec);
|
||||
|
||||
// read the wave data
|
||||
if(!ReadWaveData(hmmio,fname,snd -> data_,iDataSize,&ckRiff)){
|
||||
mmioClose(hmmio,0);
|
||||
return false;
|
||||
}
|
||||
|
||||
mmioClose(hmmio,0);
|
||||
return true;
|
||||
}
|
||||
|
||||
LRESULT PASCAL wav_IO_proc(LPSTR lpmmioinfo,UINT wMsg,LPARAM lParam1,LPARAM lParam2)
|
||||
{
|
||||
MMIOINFO* inf = (MMIOINFO*)lpmmioinfo;
|
||||
|
||||
static XZipStream fh;
|
||||
|
||||
switch(wMsg){
|
||||
case MMIOM_OPEN:
|
||||
if(!qdFileManager::instance().open_file(fh, (const char*)lParam1, false))
|
||||
return MMSYSERR_ERROR;
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
case MMIOM_CLOSE:
|
||||
fh.close();
|
||||
return 0;
|
||||
case MMIOM_READ:
|
||||
fh.read((void*)lParam1,lParam2);
|
||||
inf -> lDiskOffset = fh.tell();
|
||||
return lParam2;
|
||||
case MMIOM_WRITE:
|
||||
return 0;
|
||||
case MMIOM_SEEK:
|
||||
switch(lParam2){
|
||||
case SEEK_CUR:
|
||||
fh.seek(lParam1, XS_CUR);
|
||||
inf -> lDiskOffset = fh.tell();
|
||||
return fh.tell();
|
||||
case SEEK_SET:
|
||||
fh.seek(lParam1, XS_BEG);
|
||||
inf -> lDiskOffset = fh.tell();
|
||||
return fh.tell();
|
||||
case SEEK_END:
|
||||
fh.seek(lParam1, XS_END);
|
||||
inf -> lDiskOffset = fh.tell();
|
||||
return fh.tell();
|
||||
}
|
||||
assert(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef __WAV_FILE_H__
|
||||
#define __WAV_FILE_H__
|
||||
|
||||
bool wav_file_load(const char* fname,class wavSound* snd);
|
||||
|
||||
#endif /* __WAV_FILE_H__ */
|
||||
@@ -0,0 +1,50 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "wav_sound.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
wavSound::wavSound() : data_(NULL)
|
||||
{
|
||||
data_length_ = 0;
|
||||
bits_per_sample_ = 0;
|
||||
channels_ = 0;
|
||||
samples_per_sec_ = 0;
|
||||
}
|
||||
|
||||
wavSound::~wavSound()
|
||||
{
|
||||
free_data();
|
||||
}
|
||||
|
||||
bool wavSound::init(int data_len,int bits,int chn,int samples)
|
||||
{
|
||||
free_data();
|
||||
|
||||
data_length_ = data_len;
|
||||
data_ = new char[data_length_];
|
||||
|
||||
channels_ = chn;
|
||||
bits_per_sample_ = bits;
|
||||
samples_per_sec_ = samples;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wavSound::free_data()
|
||||
{
|
||||
if(data_){
|
||||
delete [] data_;
|
||||
data_ = NULL;
|
||||
}
|
||||
|
||||
data_length_ = 0;
|
||||
bits_per_sample_ = 0;
|
||||
channels_ = 0;
|
||||
samples_per_sec_ = 0;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
#ifndef __WAV_SOUND_H__
|
||||
#define __WAV_SOUND_H__
|
||||
|
||||
//! Çâóê èç WAV ôàéëà.
|
||||
class wavSound
|
||||
{
|
||||
public:
|
||||
wavSound();
|
||||
~wavSound();
|
||||
|
||||
const char* data() const { return data_; }
|
||||
int data_length() const { return data_length_; }
|
||||
int bits_per_sample() const { return bits_per_sample_; }
|
||||
int channels() const { return channels_; }
|
||||
int samples_per_sec() const { return samples_per_sec_; }
|
||||
|
||||
bool init(int data_len,int bits,int chn,int samples);
|
||||
void free_data();
|
||||
|
||||
//! Âîçâðàùàåò true, åñëè çâóê âàëèäåí (ò.å. ïàðàìåòðû äîïóñòèìûå).
|
||||
bool is_valid() const {
|
||||
if(bits_per_sample_ != 8 && bits_per_sample_ != 16) return false;
|
||||
if(channels_ != 1 && channels_ != 2) return false;
|
||||
if(!samples_per_sec_) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Âîçâðàùàåò äëèòåëüíîñòü çâóêà â ñåêóíäàõ.
|
||||
float length() const {
|
||||
if(!is_valid()) return 0.0f;
|
||||
return float(data_length_ / channels_ / (bits_per_sample_ >> 3)) / float(samples_per_sec_);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//! Äàííûå.
|
||||
char* data_;
|
||||
//! Äëèíà äàííûõ.
|
||||
int data_length_;
|
||||
//! Êîëè÷åñòâî áèò íà ñýìïë (8/16).
|
||||
int bits_per_sample_;
|
||||
//! Êîëè÷åñòâî êàíàëîâ (1/2 - ìîíî/ñòåðåî).
|
||||
int channels_;
|
||||
//! ×àñòîòà äèñêðåòèçàöèè - êîëè÷åñòâî ñýìïëîâ â ñåêóíäó.
|
||||
/**
|
||||
Çíà÷åíèÿ: 8.0, 11.025, 22.05, 44.1 x1000 Hz.
|
||||
*/
|
||||
int samples_per_sec_;
|
||||
|
||||
friend bool wav_file_load(const char* fname,class wavSound* snd);
|
||||
|
||||
};
|
||||
|
||||
#endif /* __WAV_SOUND_H__ */
|
||||
|
||||
@@ -0,0 +1,355 @@
|
||||
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "app_core.h"
|
||||
// #include "psapi.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
void* app_hWnd = 0;
|
||||
|
||||
void* appGetHandle()
|
||||
{
|
||||
return app_hWnd;
|
||||
}
|
||||
|
||||
void appSetHandle(void* hwnd)
|
||||
{
|
||||
app_hWnd = hwnd;
|
||||
}
|
||||
|
||||
unsigned app_memory_usage()
|
||||
{
|
||||
SYSTEM_INFO SystemInfo;
|
||||
GetSystemInfo(&SystemInfo);
|
||||
|
||||
unsigned size = 0;
|
||||
MEMORY_BASIC_INFORMATION Buffer;
|
||||
VirtualQuery(SystemInfo.lpMinimumApplicationAddress, &Buffer, sizeof(Buffer) );
|
||||
while(Buffer.BaseAddress < SystemInfo.lpMaximumApplicationAddress){
|
||||
if(Buffer.State == MEM_COMMIT && !(Buffer.Type & MEM_MAPPED) && Buffer.Protect & (PAGE_READWRITE | PAGE_EXECUTE_READ) )
|
||||
size += Buffer.RegionSize;
|
||||
void* prev_address = Buffer.BaseAddress;
|
||||
VirtualQuery((char*)Buffer.BaseAddress + Buffer.RegionSize, &Buffer, sizeof(Buffer) );
|
||||
if(prev_address == Buffer.BaseAddress)
|
||||
break;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
namespace app_io {
|
||||
|
||||
bool is_file_exist(const char* file_name)
|
||||
{
|
||||
/* XStream fh(0);
|
||||
|
||||
if(fh.open(file_name,XS_IN)){
|
||||
fh.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;*/
|
||||
|
||||
return (GetFileAttributes(file_name) != -1);
|
||||
}
|
||||
|
||||
bool set_current_directory(const char* file_name)
|
||||
{
|
||||
char fpath[_MAX_PATH];
|
||||
_fullpath(fpath,file_name,_MAX_PATH);
|
||||
|
||||
char drive[_MAX_DRIVE];
|
||||
char dir[_MAX_DIR];
|
||||
|
||||
_splitpath(fpath,drive,dir,NULL,NULL);
|
||||
|
||||
XBuffer buf(fpath,_MAX_PATH);
|
||||
buf.operator< (drive).operator< (dir);
|
||||
|
||||
SetCurrentDirectory(buf.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* strip_path(const char* file_name)
|
||||
{
|
||||
char fname[_MAX_FNAME];
|
||||
char ext[_MAX_EXT];
|
||||
|
||||
static XBuffer name_buf(_MAX_PATH);
|
||||
|
||||
_splitpath(file_name,NULL,NULL,fname,ext);
|
||||
|
||||
name_buf.init();
|
||||
name_buf.operator<(fname).operator < (ext);
|
||||
|
||||
return name_buf.c_str();
|
||||
}
|
||||
|
||||
bool is_directory_exist(const char* dir_name)
|
||||
{
|
||||
DWORD attr = GetFileAttributes(dir_name);
|
||||
if(attr != -1 && attr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* strip_file_name(const char* path)
|
||||
{
|
||||
char drive[_MAX_DRIVE];
|
||||
char dir[_MAX_DIR];
|
||||
|
||||
static XBuffer name_buf(_MAX_PATH);
|
||||
|
||||
_splitpath(path,drive,dir,NULL,NULL);
|
||||
|
||||
name_buf.init();
|
||||
name_buf.operator < (drive ).operator< (dir);
|
||||
|
||||
return name_buf.c_str();
|
||||
}
|
||||
|
||||
const char* get_ext(const char* file_name)
|
||||
{
|
||||
char fname[_MAX_FNAME];
|
||||
char ext[_MAX_EXT];
|
||||
|
||||
static XBuffer name_buf(_MAX_PATH);
|
||||
|
||||
_splitpath(file_name,NULL,NULL,fname,ext);
|
||||
|
||||
name_buf.init();
|
||||
name_buf.operator < (ext);
|
||||
|
||||
return name_buf.c_str();
|
||||
}
|
||||
|
||||
const char* change_ext(const char* file_name, const char* new_ext)
|
||||
{
|
||||
char drive[_MAX_DRIVE];
|
||||
char dir[_MAX_DIR];
|
||||
char fname[_MAX_FNAME];
|
||||
|
||||
static XBuffer name_buf(_MAX_PATH);
|
||||
|
||||
_splitpath(file_name,drive,dir,fname,NULL);
|
||||
|
||||
name_buf.init();
|
||||
name_buf.operator< (drive).operator< (dir).operator< (fname).operator< (new_ext);
|
||||
|
||||
return name_buf.c_str();
|
||||
}
|
||||
|
||||
bool create_directory(const char* path)
|
||||
{
|
||||
static char cur_path[MAX_PATH];
|
||||
|
||||
GetCurrentDirectory(MAX_PATH,cur_path);
|
||||
|
||||
int path_length = strlen(path);
|
||||
int idx = 0;
|
||||
static char dir_name[MAX_PATH];
|
||||
|
||||
if(path_length && path[0] == '\\'){
|
||||
SetCurrentDirectory("\\");
|
||||
idx++;
|
||||
}
|
||||
else if(path_length > 3 && path[1] == ':'){
|
||||
int dir_idx = 0;
|
||||
while(idx < 3) dir_name[dir_idx++] = path[idx++];
|
||||
dir_name[dir_idx] = 0;
|
||||
SetCurrentDirectory(dir_name);
|
||||
}
|
||||
|
||||
while(idx < path_length){
|
||||
int dir_idx = 0;
|
||||
while(path[idx] != '\\'){
|
||||
dir_name[dir_idx++] = path[idx++];
|
||||
if(idx >= path_length)
|
||||
break;
|
||||
}
|
||||
|
||||
idx++;
|
||||
|
||||
if(dir_idx){
|
||||
dir_name[dir_idx] = 0;
|
||||
CreateDirectory(dir_name,NULL);
|
||||
bool ret = SetCurrentDirectory(dir_name);
|
||||
}
|
||||
}
|
||||
|
||||
SetCurrentDirectory(cur_path);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool remove_directory(const char* path)
|
||||
{
|
||||
char cur_path[MAX_PATH];
|
||||
GetCurrentDirectory(MAX_PATH,cur_path);
|
||||
|
||||
if(!SetCurrentDirectory(path)) return false;
|
||||
|
||||
WIN32_FIND_DATA fd;
|
||||
HANDLE fh = FindFirstFile("*.*",&fd);
|
||||
|
||||
if(fh != INVALID_HANDLE_VALUE){
|
||||
do {
|
||||
if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
|
||||
if(fd.cFileName[0] != '.'){
|
||||
remove_directory(fd.cFileName);
|
||||
RemoveDirectory(fd.cFileName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
SetFileAttributes(fd.cFileName,FILE_ATTRIBUTE_ARCHIVE);
|
||||
DeleteFile(fd.cFileName);
|
||||
}
|
||||
}
|
||||
while(FindNextFile(fh,&fd));
|
||||
FindClose(fh);
|
||||
}
|
||||
|
||||
SetCurrentDirectory(cur_path);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool full_remove_directory(const char* path)
|
||||
{
|
||||
char cur_path[MAX_PATH];
|
||||
GetCurrentDirectory(MAX_PATH,cur_path);
|
||||
|
||||
if(!SetCurrentDirectory(path)) return false;
|
||||
|
||||
WIN32_FIND_DATA fd;
|
||||
HANDLE fh = FindFirstFile("*.*",&fd);
|
||||
|
||||
if(fh != INVALID_HANDLE_VALUE){
|
||||
do {
|
||||
if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
|
||||
if(fd.cFileName[0] != '.')
|
||||
remove_directory(fd.cFileName);
|
||||
}
|
||||
else {
|
||||
SetFileAttributes(fd.cFileName,FILE_ATTRIBUTE_ARCHIVE);
|
||||
DeleteFile(fd.cFileName);
|
||||
}
|
||||
}
|
||||
while(FindNextFile(fh,&fd));
|
||||
FindClose(fh);
|
||||
}
|
||||
|
||||
SetCurrentDirectory(cur_path);
|
||||
// Óäàëÿåì è òåêóùóþ äèðåêòîðèþ, â êîòîðóþ çàëåçëè
|
||||
SetFileAttributes(path,FILE_ATTRIBUTE_ARCHIVE);
|
||||
RemoveDirectory(path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned file_size(const char* file_name)
|
||||
{
|
||||
XStream fh(0);
|
||||
if(fh.open(file_name,XS_IN))
|
||||
return fh.size();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Âñïîìîãàòåëüíàÿ ôóíêöèÿ êîïèðîâàíèÿ (äîïîëíèòåëüíî ñîçäàåò äèððåêòîðèþ è
|
||||
// åñëè ôàéë óæå ñóùåñòâóåò óáèðàåò ñ íåãî read-only/system/hidden àòòðèáóòû)
|
||||
bool copy_file(const char* target,const char* source)
|
||||
{
|
||||
app_io::create_directory(app_io::strip_file_name(target));
|
||||
|
||||
DWORD attr = GetFileAttributes(target);
|
||||
if(attr != -1)
|
||||
SetFileAttributes(target,attr & ~(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM));
|
||||
|
||||
return CopyFile(source,target,0);
|
||||
}
|
||||
|
||||
std::string path_to_file_name(const std::string& str)
|
||||
{
|
||||
std::string conv_str = str;
|
||||
for (int i = 0; i < conv_str.length(); i++)
|
||||
if ('\\' == conv_str[i])
|
||||
conv_str[i] = '_';
|
||||
return conv_str;
|
||||
}
|
||||
|
||||
bool dupe_resolve_file_copy(std::string& target,const char* source)
|
||||
{
|
||||
if (false == is_file_exist(target.c_str()))
|
||||
return copy_file(target.c_str(), source);
|
||||
|
||||
std::string correct_path = target;
|
||||
char drive[_MAX_DRIVE];
|
||||
char dir[_MAX_DIR];
|
||||
char fname[_MAX_FNAME];
|
||||
char ext[_MAX_EXT];
|
||||
while ((true == is_file_exist(correct_path.c_str())) && (correct_path.size() < MAX_PATH))
|
||||
{
|
||||
_splitpath(correct_path.c_str(),drive,dir,fname,ext);
|
||||
correct_path = drive;
|
||||
correct_path += dir;
|
||||
correct_path += fname;
|
||||
correct_path += '2'; // Äîáàâëÿåì äâîå÷êó ïåðåä èìåíåì ôàéëà
|
||||
correct_path += ext;
|
||||
}
|
||||
|
||||
if (true == is_file_exist(correct_path.c_str()))
|
||||
return false;
|
||||
|
||||
if (copy_file(correct_path.c_str(), source))
|
||||
{
|
||||
target = correct_path;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool copy_file_list(const std::list<std::string>& file_list,const char* target_dir,const char* file_extension)
|
||||
{
|
||||
bool copy_ok = true;
|
||||
std::string save_str;
|
||||
for (qdFileNameList::const_iterator it = file_list.begin(); it != file_list.end(); it++)
|
||||
if ( 0 == stricmp(file_extension, get_ext(it->c_str())) )
|
||||
{
|
||||
// Ôîðìèðóåì èìÿ ôàéëà è ïðèêðåïëÿåì ê íåìó ïóòü ïàïêè-õðàíèëèùà ôàéëîâ
|
||||
save_str = app_io::path_to_file_name(it->c_str());
|
||||
save_str = '\\' + save_str;
|
||||
save_str = target_dir + save_str;
|
||||
// Êîïèðóåì è ñîîáùàåì îá îøèáêå, åñëè ïðîèçîøëà
|
||||
if ( !app_io::copy_file(save_str.c_str(), it->c_str()) )
|
||||
{
|
||||
appLog::default_log() << "Error: could not copy " << it->c_str()
|
||||
<< " to directory " << target_dir << "\r\n";
|
||||
copy_ok = false;
|
||||
}
|
||||
}
|
||||
return copy_ok;
|
||||
}
|
||||
|
||||
bool relat_path(const char* path)
|
||||
{
|
||||
int len = strlen(path);
|
||||
if (len < 2) return true;
|
||||
|
||||
if (('.' == path[0]) && ('.' == path[1])) return false;
|
||||
if (':' == path[1]) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void adjust_dir_end_slash(std::string& str)
|
||||
{
|
||||
if ((str.size() > 0) && ('\\' != str[str.size()-1]))
|
||||
str = str + '\\';
|
||||
}
|
||||
|
||||
}; /* namespace app_io */
|
||||
@@ -0,0 +1,70 @@
|
||||
#ifndef __APP_CORE_H__
|
||||
#define __APP_CORE_H__
|
||||
|
||||
// Main window handle
|
||||
void* appGetHandle();
|
||||
void appSetHandle(void* hwnd);
|
||||
|
||||
unsigned app_memory_usage();
|
||||
|
||||
typedef void (*SetFunc)(const char*);
|
||||
typedef const char* (*GetFunc)(void);
|
||||
|
||||
// Macroses
|
||||
#define QD_ADJUST_TO_REL_FILE_MEMBER(res_dir, get_file, set_file, can_overwrite, ret) {\
|
||||
if (false == app_io::relat_path(get_file())){ \
|
||||
std::string str = res_dir + app_io::strip_path(get_file()); \
|
||||
if (!can_overwrite && app_io::dupe_resolve_file_copy(str, get_file()))\
|
||||
set_file(str.c_str()); \
|
||||
else if (can_overwrite) { \
|
||||
std::string msg = "Program attempt copy file:\n"; \
|
||||
msg += get_file(), msg += "\n\n"; \
|
||||
msg += "to: \n"; \
|
||||
msg += str, msg += "\n\n"; \
|
||||
msg += "But file already exist. Overwrite?"; \
|
||||
if (!app_io::is_file_exist(str.c_str()) || \
|
||||
IDYES == MessageBox(NULL, msg.c_str(), "Message", \
|
||||
MB_YESNO | MB_TASKMODAL)) \
|
||||
{ \
|
||||
if (app_io::copy_file(str.c_str(), get_file())) \
|
||||
set_file(str.c_str()); \
|
||||
else ret = false; \
|
||||
} \
|
||||
else if (app_io::dupe_resolve_file_copy(str, get_file())) \
|
||||
set_file(str.c_str()); \
|
||||
else ret = false; \
|
||||
} \
|
||||
else ret = false; \
|
||||
} \
|
||||
}
|
||||
|
||||
namespace app_io {
|
||||
|
||||
bool is_file_exist(const char* file_name);
|
||||
bool is_directory_exist(const char* dir_name);
|
||||
|
||||
bool set_current_directory(const char* file_name);
|
||||
const char* strip_path(const char* file_name);
|
||||
const char* strip_file_name(const char* path);
|
||||
const char* get_ext(const char* file_name);
|
||||
const char* change_ext(const char* file_name, const char* new_ext);
|
||||
|
||||
bool create_directory(const char* path);
|
||||
bool remove_directory(const char* path);
|
||||
bool full_remove_directory(const char* path);
|
||||
|
||||
unsigned file_size(const char* file_name);
|
||||
|
||||
bool copy_file(const char* target,const char* source);
|
||||
bool copy_file_list(const std::list<std::string>& file_list,const char* target_dir,const char* file_extension);
|
||||
//! Ïðè óñïåøíîì êîïèðîâàíèè â target ïîìåùàåòñÿ ïóòü, ïî êîòîðîìó ñêîïèðîâàëè
|
||||
bool dupe_resolve_file_copy(std::string& target, const char* source);
|
||||
std::string path_to_file_name(const std::string& str);
|
||||
|
||||
bool relat_path(const char* path);
|
||||
void adjust_dir_end_slash(std::string& str);
|
||||
};
|
||||
|
||||
#endif /* __APP_CORE_H__ */
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "app_core.h"
|
||||
#include "app_error_handler.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
std::string appErrorHandler::message_buf_(1024,0);
|
||||
|
||||
const char* appErrorHandler::error_messages_[ERR_MAX_TYPE] =
|
||||
{
|
||||
"Ôàéë íå íàéäåí",
|
||||
"Íåèçâåñòíûé ôîðìàò ôàéëà",
|
||||
"Íåñîâìåñòèìàÿ âåðñèÿ èíòåðôåéñà ìèíèèãðû",
|
||||
"Îøèáêà"
|
||||
};
|
||||
|
||||
bool appErrorHandler::is_disabled_;
|
||||
|
||||
appErrorHandler app_errH;
|
||||
|
||||
appErrorHandler::appErrorHandler()
|
||||
{
|
||||
}
|
||||
|
||||
appErrorHandler::~appErrorHandler()
|
||||
{
|
||||
}
|
||||
|
||||
void appErrorHandler::show_error(const char* subject,error_t err_code)
|
||||
{
|
||||
message_box(subject,err_code,ERR_MB_OK);
|
||||
|
||||
#ifndef _QUEST_EDITOR
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
appErrorHandler::handler_result_t appErrorHandler::message_box(const char* subject,error_t err_code,int format)
|
||||
{
|
||||
if(is_disabled_) return ERR_IGNORE;
|
||||
|
||||
xassert(err_code < ERR_MAX_TYPE);
|
||||
|
||||
message_buf_ = error_messages_[err_code];
|
||||
if(subject){
|
||||
message_buf_ += "\n";
|
||||
message_buf_ += subject;
|
||||
}
|
||||
|
||||
int mb_type = MB_ICONERROR;
|
||||
|
||||
if(format & ERR_MB_OK)
|
||||
mb_type |= MB_OK;
|
||||
if(format & ERR_MB_ABORTRETRYIGNORE)
|
||||
mb_type |= MB_ABORTRETRYIGNORE;
|
||||
|
||||
switch(MessageBox(static_cast<HWND>(appGetHandle()),message_buf_.c_str(),"Îøèáêà",mb_type)){
|
||||
case IDIGNORE:
|
||||
return ERR_IGNORE;
|
||||
case IDRETRY:
|
||||
return ERR_RETRY;
|
||||
default:
|
||||
return ERR_ABORT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef __APP_ERROR_HANDLER_H__
|
||||
#define __APP_ERROR_HANDLER_H__
|
||||
|
||||
//! Îáðàáîò÷èê îøèáîê.
|
||||
class appErrorHandler
|
||||
{
|
||||
public:
|
||||
appErrorHandler();
|
||||
~appErrorHandler();
|
||||
|
||||
//! Êîäû îøèáîê
|
||||
enum error_t {
|
||||
ERR_FILE_NOT_FOUND,
|
||||
ERR_BAD_FILE_FORMAT,
|
||||
ERR_MINIGAME_VERSION,
|
||||
ERR_OTHER,
|
||||
|
||||
ERR_MAX_TYPE
|
||||
};
|
||||
|
||||
//! Çíà÷åíèÿ, âîçâðàùàåìûå îáðàáîò÷èêîì.
|
||||
enum handler_result_t {
|
||||
ERR_ABORT,
|
||||
ERR_RETRY,
|
||||
ERR_IGNORE
|
||||
};
|
||||
|
||||
//! Ôîðìàò îêíà ñîîáùåíèÿ îá îøèáêå.
|
||||
enum {
|
||||
ERR_MB_OK = 1,
|
||||
ERR_MB_ABORTRETRYIGNORE = 2
|
||||
};
|
||||
|
||||
handler_result_t message_box(const char* subject = NULL,error_t err_code = ERR_OTHER,int format = ERR_MB_OK);
|
||||
|
||||
void show_error(const char* subject = NULL,error_t err_code = ERR_OTHER);
|
||||
|
||||
static void enable(){ is_disabled_ = false; }
|
||||
static void disable(){ is_disabled_ = true; }
|
||||
|
||||
private:
|
||||
static bool is_disabled_;
|
||||
static std::string message_buf_;
|
||||
static const char* error_messages_[];
|
||||
};
|
||||
|
||||
extern appErrorHandler app_errH;
|
||||
|
||||
#endif /* __APP_ERROR_HANDLER_H__ */
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "app_log_file.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
appLog::appLog() : time_(0)
|
||||
{
|
||||
}
|
||||
|
||||
appLog::~appLog()
|
||||
{
|
||||
}
|
||||
|
||||
appLog& appLog::default_log()
|
||||
{
|
||||
static appLogFile log("qd_engine.log");
|
||||
return log;
|
||||
}
|
||||
|
||||
const char* appLog::time_string() const
|
||||
{
|
||||
static XBuffer text(1024,1);
|
||||
text.init();
|
||||
|
||||
#ifndef _FINAL_VERSION_
|
||||
int hrs = time_ / (1000 * 60 * 60);
|
||||
if(hrs < 10) text < "0";
|
||||
text <= hrs < ":";
|
||||
|
||||
int min = (time_ % (1000 * 60 * 60)) / (1000 * 60);
|
||||
if(min < 10) text < "0";
|
||||
text <= min < ":";
|
||||
|
||||
int sec = (time_ % (1000 * 60)) / 1000;
|
||||
if(sec < 10) text < "0";
|
||||
text <= sec < ":";
|
||||
|
||||
int hsec = (time_ % 1000) / 10;
|
||||
if(hsec < 10) text < "0";
|
||||
text <= hsec < " ";
|
||||
#endif
|
||||
|
||||
return text.c_str();
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef __APP_LOG_H__
|
||||
#define __APP_LOG_H__
|
||||
|
||||
//! Îòëàäî÷íûé ëîã - áàçîâûé êëàññ.
|
||||
/**
|
||||
Âêëþ÷àåòñÿ òîëüêî â èãðå (íå â ðåäàêòîðå) êëþ÷åì /log â êîìàíäíîé ñòðîêå.
|
||||
Ïî óìîë÷àíèþ ïèøåò â ôàéë qd_engine.log, ïðè ïåðåçàïóñêå èãðû ëîã îáíóëÿåòñÿ.
|
||||
*/
|
||||
class appLog
|
||||
{
|
||||
public:
|
||||
appLog();
|
||||
virtual ~appLog() = 0;
|
||||
|
||||
//! Âîçâðàùàåò ññûëêó íà ëîã ïî óìîë÷àíèþ (qd_engine.log).
|
||||
static appLog& default_log();
|
||||
|
||||
//! Âîçâðàùàåò true, åñëè çàïèñü â ëîã ðàçðåøåíà.
|
||||
bool is_enabled() const { return is_enabled_; }
|
||||
//! Ðàçðåøàåò çàïèñü â ëîã.
|
||||
void enable(){ is_enabled_ = true; }
|
||||
|
||||
//! Ïèøåò â ëîã ñòðîêó òåêñòà.
|
||||
virtual appLog& operator << (const char* str){ return *this; }
|
||||
//! Ïèøåò â ëîã öåëîå ÷èñëî.
|
||||
virtual appLog& operator << (int data){ return *this; }
|
||||
//! Ïèøåò â ëîã ïîëîæèòåëüíîå öåëîå ÷èñëî.
|
||||
virtual appLog& operator << (unsigned int data){ return *this; }
|
||||
//! Ïèøåò â ëîã ÷èñëî ñ ïëàâàþùåé òî÷êîé.
|
||||
virtual appLog& operator << (float data){ return *this; }
|
||||
|
||||
void set_time(unsigned tm){ time_ = tm; }
|
||||
const char* time_string() const;
|
||||
|
||||
private:
|
||||
//! Ðàâíî true, åñëè çàïèñü â ëîã-ôàéë ðàçðåøåíà.
|
||||
bool is_enabled_;
|
||||
|
||||
//! Òåêóùåå âðåìÿ.
|
||||
unsigned time_;
|
||||
};
|
||||
|
||||
#endif /* __APP_LOG_H__ */
|
||||
@@ -0,0 +1,75 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "app_log_file.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
appLogFile::appLogFile(const char* fname) : file_(NULL)
|
||||
{
|
||||
if(fname)
|
||||
file_name_ = fname;
|
||||
}
|
||||
|
||||
appLogFile::~appLogFile()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
bool appLogFile::open(const char* fname)
|
||||
{
|
||||
close();
|
||||
|
||||
if(fname)
|
||||
file_name_ = fname;
|
||||
|
||||
file_ = new XStream(file_name_.c_str(),XS_OUT);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool appLogFile::close()
|
||||
{
|
||||
if(file_){
|
||||
file_ -> close();
|
||||
delete file_;
|
||||
file_ = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
appLog& appLogFile::operator << (const char* str)
|
||||
{
|
||||
#ifdef __APP_LOG_ENABLE__
|
||||
if(is_enabled() && str) *file() < str;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
appLog& appLogFile::operator << (int data)
|
||||
{
|
||||
#ifdef __APP_LOG_ENABLE__
|
||||
if(is_enabled()) *file() <= data;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
appLog& appLogFile::operator << (unsigned int data)
|
||||
{
|
||||
#ifdef __APP_LOG_ENABLE__
|
||||
if(is_enabled()) *file() <= data;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
appLog& appLogFile::operator << (float data)
|
||||
{
|
||||
#ifdef __APP_LOG_ENABLE__
|
||||
if(is_enabled()) *file() <= data;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef __APP_LOG_FILE_H__
|
||||
#define __APP_LOG_FILE_H__
|
||||
|
||||
#ifndef _QUEST_EDITOR
|
||||
#define __APP_LOG_ENABLE__
|
||||
#endif
|
||||
|
||||
class XStream;
|
||||
|
||||
//! Îòëàäî÷íûé ëîã-ôàéë.
|
||||
/**
|
||||
Âêëþ÷àåòñÿ òîëüêî â èãðå (íå â ðåäàêòîðå) êëþ÷åì /log â êîìàíäíîé ñòðîêå.
|
||||
Ïî óìîë÷àíèþ ïèøåò â ôàéë qd_engine.log, ïðè ïåðåçàïóñêå èãðû ëîã îáíóëÿåòñÿ.
|
||||
*/
|
||||
class appLogFile : public appLog
|
||||
{
|
||||
public:
|
||||
explicit appLogFile(const char* fname = NULL);
|
||||
~appLogFile();
|
||||
|
||||
//! Îòêðûòâàåò ëîã-ôàéë ñ èìåíåì fname.
|
||||
bool open(const char* fname = NULL);
|
||||
//! Âîçâðàùàåò true, åñëè ëîã-ôàéë îòêðûò.
|
||||
bool is_opened() const { if(file_) return true; else return false; }
|
||||
//! Çàêðûâàåò ëîã-ôàéë.
|
||||
bool close();
|
||||
|
||||
//! Ïèøåò â ëîã-ôàéë ñòðîêó òåêñòà.
|
||||
appLog& operator << (const char* str);
|
||||
//! Ïèøåò â ëîã-ôàéë öåëîå ÷èñëî.
|
||||
appLog& operator << (int data);
|
||||
//! Ïèøåò â ëîã-ôàéë ïîëîæèòåëüíîå öåëîå ÷èñëî.
|
||||
appLog& operator << (unsigned int data);
|
||||
//! Ïèøåò â ëîã-ôàéë ÷èñëî ñ ïëàâàþùåé òî÷êîé.
|
||||
appLog& operator << (float data);
|
||||
|
||||
private:
|
||||
//! Ïîòîê äëÿ çàïèñè â ëîã-ôàéë.
|
||||
XStream* file_;
|
||||
//! Èìÿ ëîã-ôàéëà.
|
||||
std::string file_name_;
|
||||
|
||||
XStream* file(){ if(!is_opened()) open(); return file_; }
|
||||
};
|
||||
|
||||
#endif /* __APP_LOG_FILE_H__ */
|
||||
@@ -0,0 +1,644 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
#include <shellapi.h>
|
||||
|
||||
#include "XUtil.h"
|
||||
|
||||
#include "gr_dispatcher.h"
|
||||
#include "ar_button.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
|
||||
extern HWND hmainWnd;
|
||||
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
|
||||
char* getIniKey(const char* fname,const char* section,const char* key);
|
||||
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
HANDLE abtProcess = NULL;
|
||||
|
||||
int arButton::current_language_id_ = -1;
|
||||
|
||||
arButton::arButton(void)
|
||||
{
|
||||
state = -1;
|
||||
need_redraw_ = true;
|
||||
|
||||
type = ABT_URL;
|
||||
obj_name = cmd_line = NULL;
|
||||
obj_name_regvalue = NULL;
|
||||
|
||||
cmd_show = -1;
|
||||
|
||||
reg_key = NULL;
|
||||
|
||||
check_after_exec = NULL;
|
||||
reg_exec_path_value = NULL;
|
||||
|
||||
language_dependency_ = false;
|
||||
language_id_ = AR_LANGUAGE_NONE;
|
||||
|
||||
is_enabled_ = true;
|
||||
}
|
||||
|
||||
arButton::~arButton(void)
|
||||
{
|
||||
}
|
||||
|
||||
arButton::resource_container_t& arButton::resource_container()
|
||||
{
|
||||
static resource_container_t rct;
|
||||
return rct;
|
||||
}
|
||||
|
||||
void arButton::load_resources()
|
||||
{
|
||||
resource_container_t::resource_list_t lst = resource_container().resource_list();
|
||||
std::for_each(lst.begin(),lst.end(),std::mem_fun(qdResource::load_resource));
|
||||
}
|
||||
|
||||
void arButton::init(const char* ini_file,const char* section)
|
||||
{
|
||||
char* fname = getIniKey(ini_file,section,"state0");
|
||||
if(strlen(fname))
|
||||
load_image(fname,0);
|
||||
|
||||
fname = getIniKey(ini_file,section,"state1");
|
||||
if(strlen(fname))
|
||||
load_image(fname,1);
|
||||
|
||||
Vect2i pos(0,0);
|
||||
|
||||
pos.x = atoi(getIniKey(ini_file,section,"x0"));
|
||||
pos.y = atoi(getIniKey(ini_file,section,"y0"));
|
||||
|
||||
states_[0].set_pos(pos);
|
||||
|
||||
pos.x = atoi(getIniKey(ini_file,section,"x1"));
|
||||
pos.y = atoi(getIniKey(ini_file,section,"y1"));
|
||||
|
||||
states_[1].set_pos(pos);
|
||||
|
||||
XBuffer buf;
|
||||
int sz = atoi(getIniKey(ini_file,section,"url_num"));
|
||||
exec_objects_.reserve(sz);
|
||||
for(int i = 0; i < sz; i++){
|
||||
buf.init();
|
||||
buf < "url" <= i < "_language";
|
||||
int lng_id = atoi(getIniKey(ini_file,section,buf.c_str()));
|
||||
|
||||
buf.init();
|
||||
buf < "url" <= i < "_string";
|
||||
|
||||
exec_objects_.push_back(arButtonExecObject(lng_id,getIniKey(ini_file,section,buf.c_str())));
|
||||
}
|
||||
|
||||
fname = getIniKey(ini_file,section,"url");
|
||||
if(strlen(fname)){
|
||||
type = ABT_URL;
|
||||
set_obj(fname);
|
||||
}
|
||||
else {
|
||||
fname = getIniKey(ini_file,section,"exec");
|
||||
|
||||
if(strlen(fname)){
|
||||
if(stricmp(fname,"exit")){
|
||||
if(stricmp(fname,"language")){
|
||||
type = ABT_EXEC;
|
||||
|
||||
set_obj(fname);
|
||||
fname = getIniKey(ini_file,section,"args");
|
||||
if(strlen(fname))
|
||||
set_cmdline(fname);
|
||||
}
|
||||
else {
|
||||
type = ABT_LANGUAGE;
|
||||
|
||||
fname = getIniKey(ini_file,section,"args");
|
||||
if(strlen(fname))
|
||||
language_id_ = atoi(fname);
|
||||
}
|
||||
}
|
||||
else
|
||||
type = ABT_EXIT;
|
||||
}
|
||||
else {
|
||||
fname = getIniKey(ini_file,section,"exec_from_regval");
|
||||
if(strlen(fname)){
|
||||
type = ABT_EXEC;
|
||||
set_obj_regvalue(fname);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(atoi(getIniKey(ini_file,section,"minimize")))
|
||||
cmd_show = 0;
|
||||
|
||||
if(atoi(getIniKey(ini_file,section,"exit")))
|
||||
cmd_show = 1;
|
||||
|
||||
fname = getIniKey(ini_file,section,"regkey");
|
||||
if(strlen(fname)) set_regkey(fname);
|
||||
|
||||
fname = getIniKey(ini_file,section,"exec_path_regvalue");
|
||||
if(strlen(fname)) set_reg_exec_path(fname);
|
||||
|
||||
if(atoi(getIniKey(ini_file,section,"regkey_check_on_startup"))){
|
||||
if(!check_regkey()) enable(0);
|
||||
}
|
||||
|
||||
fname = getIniKey(ini_file,section,"check_after_exec");
|
||||
if(strlen(fname)) set_checkstr(fname);
|
||||
|
||||
fname = getIniKey(ini_file,section,"language_dependency");
|
||||
if(atoi(fname)) language_dependency_ = true;
|
||||
}
|
||||
|
||||
HKEY arButton::open_regkey(const char* regkey_name)
|
||||
{
|
||||
int i;
|
||||
const char* subkey_name;
|
||||
HKEY key = NULL,subkey;
|
||||
|
||||
if(!regkey_name) return 0;
|
||||
|
||||
static char* key_names[] = { "HKCR\\", "HKCU\\", "HKLM\\", "HKU\\" };
|
||||
static HKEY keys[] = { HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS };
|
||||
|
||||
for(i = 0; i < 4; i ++){
|
||||
if(!strnicmp(regkey_name,key_names[i],strlen(key_names[i]))){
|
||||
key = keys[i];
|
||||
subkey_name = regkey_name + strlen(key_names[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!key) return 0;
|
||||
|
||||
if(RegOpenKeyEx(key,subkey_name,0,KEY_READ,&subkey) != ERROR_SUCCESS)
|
||||
return 0;
|
||||
|
||||
return subkey;
|
||||
}
|
||||
|
||||
int arButton::check_regkey(void)
|
||||
{
|
||||
HKEY key = open_regkey(reg_key);
|
||||
|
||||
if(!key)
|
||||
return 0;
|
||||
|
||||
RegCloseKey(key);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int arButton::click(void)
|
||||
{
|
||||
SHELLEXECUTEINFO inf;
|
||||
DWORD exit_code;
|
||||
static char str[MAX_PATH * 2];
|
||||
char* p0,*p1;
|
||||
|
||||
switch(type){
|
||||
case ABT_URL:
|
||||
if(!exec_objects_.empty()){
|
||||
exec_objects_container_t::const_iterator it = std::find(exec_objects_.begin(),exec_objects_.end(),current_language_id_);
|
||||
if(it != exec_objects_.end()){
|
||||
ShellExecute(hmainWnd,NULL,it -> exec_string(),NULL,NULL,SW_SHOWMAXIMIZED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(obj_name)
|
||||
ShellExecute(hmainWnd,NULL,obj_name,NULL,NULL,SW_SHOWMAXIMIZED);
|
||||
break;
|
||||
case ABT_EXEC:
|
||||
if(!obj_name && !obj_name_regvalue)
|
||||
return 0;
|
||||
|
||||
if(abtProcess){
|
||||
if(GetExitCodeProcess(abtProcess,&exit_code)){
|
||||
if(exit_code == STILL_ACTIVE)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inf.cbSize = sizeof(SHELLEXECUTEINFO);
|
||||
inf.fMask = SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS;
|
||||
inf.hwnd = hmainWnd;
|
||||
inf.lpVerb = NULL;
|
||||
|
||||
if(obj_name){
|
||||
inf.lpFile = obj_name;
|
||||
inf.lpParameters = cmd_line;
|
||||
if(reg_exec_path_value && get_exec_path(str,MAX_PATH * 2))
|
||||
inf.lpDirectory = str;
|
||||
else
|
||||
inf.lpDirectory = NULL;
|
||||
}
|
||||
else {
|
||||
if(get_exec_obj(str,MAX_PATH * 2) && split_cmdline(str,p0,p1)){
|
||||
inf.lpFile = p0;
|
||||
inf.lpParameters = p1;
|
||||
inf.lpDirectory = NULL;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
inf.nShow = SW_SHOWDEFAULT;
|
||||
|
||||
ShellExecuteEx(&inf);
|
||||
|
||||
abtProcess = inf.hProcess;
|
||||
|
||||
break;
|
||||
case ABT_EXIT:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
|
||||
switch(cmd_show){
|
||||
case 0:
|
||||
ShowWindow(hmainWnd,SW_MINIMIZE);
|
||||
break;
|
||||
case 1:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
case -1:
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void arButton::load_image(const char* fname,int state)
|
||||
{
|
||||
if(states_[state].has_animation())
|
||||
resource_container().remove_resource(states_[state].animation_name(),this);
|
||||
|
||||
states_[state].set_animation_name(fname);
|
||||
states_[state].set_animation(dynamic_cast<const qdAnimation*>(resource_container().add_resource(states_[state].animation_name(),this)));
|
||||
}
|
||||
|
||||
void arButton::redraw()
|
||||
{
|
||||
animation_.redraw(states_[state].pos().x + animation_.size_x()/2,states_[state].pos().y + animation_.size_y()/2,0);
|
||||
need_redraw_ = false;
|
||||
}
|
||||
|
||||
void arButtonDispatcher::init(const char* ini_file)
|
||||
{
|
||||
const char* fname = getIniKey(ini_file,"settings","background");
|
||||
background_ = dynamic_cast<const qdAnimation*>(arButton::resource_container().add_resource(fname,NULL));
|
||||
|
||||
int sz = atoi(getIniKey(ini_file,"settings","buttons"));
|
||||
btList.resize(sz);
|
||||
|
||||
|
||||
XBuffer name;
|
||||
for(int i = 0; i < sz; i ++){
|
||||
name.init();
|
||||
name < "button" <= i;
|
||||
btList[i].set_ID(i);
|
||||
btList[i].init(ini_file,name);
|
||||
}
|
||||
|
||||
arButton::load_resources();
|
||||
|
||||
for(int i = 0; i < sz; i ++){
|
||||
if(btList[i].is_enabled())
|
||||
btList[i].set_state(0);
|
||||
}
|
||||
|
||||
sz = atoi(getIniKey(ini_file,"settings","languages"));
|
||||
languages_.resize(sz);
|
||||
for(int i = 0; i < sz; i ++){
|
||||
name.init();
|
||||
name < "language" <= i;
|
||||
languages_[i].init(ini_file,name);
|
||||
}
|
||||
}
|
||||
|
||||
bool arButtonDispatcher::init_language(const char* ini_file)
|
||||
{
|
||||
char* str = getIniKey(ini_file,"settings","language_regkey");
|
||||
if(strlen(str)){
|
||||
if(HKEY key = arButton::open_regkey(str)){
|
||||
str = getIniKey(ini_file,"settings","language_regvalue");
|
||||
char lng_str[256];
|
||||
DWORD len = 256;
|
||||
|
||||
int ret = RegQueryValueEx(key,str,NULL,NULL,(LPBYTE)lng_str,&len);
|
||||
RegCloseKey(key);
|
||||
|
||||
if(ret == ERROR_SUCCESS)
|
||||
return set_language(lng_str);
|
||||
}
|
||||
}
|
||||
|
||||
switch(PRIMARYLANGID(GetUserDefaultLangID())){
|
||||
case LANG_GERMAN:
|
||||
return set_language("german");
|
||||
case LANG_ITALIAN:
|
||||
return set_language("italian");
|
||||
case LANG_ENGLISH:
|
||||
return set_language("english");
|
||||
case LANG_SPANISH:
|
||||
return set_language("spanish");
|
||||
case LANG_FRENCH:
|
||||
return set_language("french");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool arButtonDispatcher::hit(int x,int y)
|
||||
{
|
||||
bool flag = false,redraw_flag = false;
|
||||
for(buttons_container_t::iterator it = btList.begin(); it != btList.end(); ++it){
|
||||
if(!flag && it -> hit(x,y)){
|
||||
if(it -> get_state() != -1){
|
||||
it -> set_state(1);
|
||||
flag = true;
|
||||
|
||||
if(!redraw_flag)
|
||||
redraw_flag = it -> redraw_needed();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(it -> get_state() != -1)
|
||||
it -> set_state(0);
|
||||
|
||||
if(!redraw_flag)
|
||||
redraw_flag = it -> redraw_needed();
|
||||
}
|
||||
}
|
||||
|
||||
if(redraw_flag)
|
||||
redraw();
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
void arButtonDispatcher::click(int x,int y)
|
||||
{
|
||||
for(buttons_container_t::iterator it = btList.begin(); it != btList.end(); ++it){
|
||||
if(it -> hit(x,y)){
|
||||
if(it -> get_state() != -1)
|
||||
if(it -> click()){
|
||||
if(abtProcess)
|
||||
curButton = &*it;
|
||||
|
||||
if(it -> has_language_id())
|
||||
set_language(it -> language_id());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void arButtonDispatcher::redraw()
|
||||
{
|
||||
if(background_)
|
||||
background_ -> redraw(background_ -> size_x()/2,background_ -> size_y()/2,0);
|
||||
|
||||
for(buttons_container_t::iterator it1 = btList.begin(); it1 != btList.end(); ++it1)
|
||||
it1 -> redraw();
|
||||
|
||||
grDispatcher::instance() -> Flush();
|
||||
}
|
||||
|
||||
arButtonDispatcher::arButtonDispatcher(void)
|
||||
{
|
||||
curButton = NULL;
|
||||
current_language_ = -1;
|
||||
}
|
||||
|
||||
arButtonDispatcher::~arButtonDispatcher(void)
|
||||
{
|
||||
btList.clear();
|
||||
}
|
||||
|
||||
void arButtonDispatcher::check_exec(void)
|
||||
{
|
||||
DWORD exit_code;
|
||||
|
||||
if(!abtProcess){
|
||||
curButton = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if(GetExitCodeProcess(abtProcess,&exit_code)){
|
||||
if(exit_code != STILL_ACTIVE){
|
||||
switch(curButton -> exec_show_mode()){
|
||||
case 0:
|
||||
ShowWindow(hmainWnd,SW_SHOWNORMAL);
|
||||
break;
|
||||
case -1:
|
||||
break;
|
||||
}
|
||||
if(curButton -> get_checkstr()){
|
||||
XBuffer check_str(curButton -> get_checkstr(),strlen(curButton -> get_checkstr()));
|
||||
while(check_str.tell() < check_str.size()){
|
||||
int id;
|
||||
check_str >= id;
|
||||
buttons_container_t::iterator it = std::find(btList.begin(),btList.end(),id);
|
||||
if(it != btList.end()){
|
||||
if(it -> check_regkey())
|
||||
it -> enable(true);
|
||||
else
|
||||
it -> enable(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
curButton = NULL;
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
else
|
||||
curButton = NULL;
|
||||
}
|
||||
|
||||
int arButton::get_exec_path(char* path,int path_len)
|
||||
{
|
||||
int ret;
|
||||
HKEY key = open_regkey(reg_key);
|
||||
DWORD len = path_len;
|
||||
|
||||
if(!key) return 0;
|
||||
|
||||
ret = RegQueryValueEx(key,reg_exec_path_value,NULL,NULL,(LPBYTE)path,&len);
|
||||
RegCloseKey(key);
|
||||
|
||||
return (ret == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
int arButton::get_exec_obj(char* str,int str_len)
|
||||
{
|
||||
int ret;
|
||||
HKEY key = open_regkey(reg_key);
|
||||
DWORD len = str_len;
|
||||
|
||||
if(!key) return 0;
|
||||
|
||||
ret = RegQueryValueEx(key,obj_name_regvalue,NULL,NULL,(LPBYTE)str,&len);
|
||||
RegCloseKey(key);
|
||||
|
||||
return (ret == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
int arButton::split_cmdline(char* str,char*& exec,char*& args)
|
||||
{
|
||||
int i,sz = strlen(str);
|
||||
|
||||
if(str[sz - 1] == '\"'){
|
||||
for(i = sz - 2; i >= 0; i --){
|
||||
if(str[i] == '\"'){
|
||||
str[i - 1] = 0;
|
||||
|
||||
exec = str;
|
||||
args = str + i;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(i = 0; i < sz; i ++){
|
||||
if(str[i] == ' '){
|
||||
//if(i > 5 && !strnicmp(str + i - 4,".exe",4)){
|
||||
str[i] = 0;
|
||||
|
||||
exec = str;
|
||||
args = str + i + 1;
|
||||
|
||||
return 1;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool arButton::hit(int x,int y) const
|
||||
{
|
||||
if(!is_enabled()) return false;
|
||||
|
||||
if(!state){
|
||||
if(x >= states_[0].pos().x && x < states_[0].pos().x + size_x(0) && y >= states_[0].pos().y && y < states_[0].pos().y + size_y(0)){
|
||||
if(states_[0].animation()){
|
||||
int x1 = x - states_[0].pos().x - size_x(0)/2;
|
||||
int y1 = y - states_[0].pos().y - size_y(0)/2;
|
||||
|
||||
return states_[0].animation() -> hit(x1,y1);
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(x >= states_[1].pos().x && x < states_[1].pos().x + size_x(1) && y >= states_[1].pos().y && y < states_[1].pos().y + size_y(1)){
|
||||
if(states_[1].animation()){
|
||||
int x1 = x - states_[1].pos().x - size_x(1)/2;
|
||||
int y1 = y - states_[1].pos().y - size_y(1)/2;
|
||||
|
||||
return states_[1].animation() -> hit(x1,y1);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void arButton::set_state(int st,bool forced)
|
||||
{
|
||||
if(state != st || forced){
|
||||
state = st;
|
||||
need_redraw_ = true;
|
||||
|
||||
if(st != -1 && states_[st].animation())
|
||||
states_[st].animation() -> create_reference(&animation_);
|
||||
else
|
||||
animation_.clear();
|
||||
|
||||
animation_.start();
|
||||
}
|
||||
}
|
||||
|
||||
void arButton::change_animation_folder(const char* folder)
|
||||
{
|
||||
char drive[_MAX_DRIVE];
|
||||
char dir[_MAX_DIR];
|
||||
char fname[_MAX_FNAME];
|
||||
char ext[_MAX_EXT];
|
||||
|
||||
static XBuffer name_buf(_MAX_PATH);
|
||||
|
||||
if(states_[0].has_animation()){
|
||||
_splitpath(states_[0].animation_name(),drive,dir,fname,ext);
|
||||
|
||||
name_buf.init();
|
||||
name_buf < drive < folder < "\\" < fname < ext;
|
||||
|
||||
load_image(name_buf.c_str(),0);
|
||||
}
|
||||
|
||||
if(states_[1].has_animation()){
|
||||
_splitpath(states_[1].animation_name(),drive,dir,fname,ext);
|
||||
|
||||
name_buf.init();
|
||||
name_buf < drive < folder < "\\" < fname < ext;
|
||||
|
||||
load_image(name_buf.c_str(),1);
|
||||
}
|
||||
}
|
||||
|
||||
bool arButtonDispatcher::set_language(int language_id)
|
||||
{
|
||||
if(language_id < 0 || language_id >= languages_.size())
|
||||
return false;
|
||||
if(language_id == current_language_)
|
||||
return true;
|
||||
|
||||
current_language_ = language_id;
|
||||
arButton::set_current_language_id(language_id);
|
||||
|
||||
const char* folder = languages_[current_language_].resources_folder();
|
||||
|
||||
for(buttons_container_t::iterator it = btList.begin(); it != btList.end(); ++it){
|
||||
if(it -> language_dependency())
|
||||
it -> change_animation_folder(folder);
|
||||
}
|
||||
|
||||
arButton::load_resources();
|
||||
|
||||
for(buttons_container_t::iterator it = btList.begin(); it != btList.end(); ++it){
|
||||
if(it -> language_dependency())
|
||||
it -> set_state(it -> get_state(),true);
|
||||
}
|
||||
|
||||
redraw();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool arButtonDispatcher::set_language(const char* language_name)
|
||||
{
|
||||
for(languages_container_t::const_iterator it = languages_.begin(); it != languages_.end(); ++it){
|
||||
if(!stricmp(it -> name(),language_name)){
|
||||
return set_language(it - languages_.begin());
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void arLanguageInfo::init(const char* ini_file,const char* section)
|
||||
{
|
||||
set_name(getIniKey(ini_file,section,"name"));
|
||||
set_resources_folder(getIniKey(ini_file,section,"resources"));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
#ifndef __AR_BUTTON_H__
|
||||
#define __AR_BUTTON_H__
|
||||
|
||||
#include "qd_animation.h"
|
||||
#include "qd_resource_container.h"
|
||||
|
||||
class arLanguageInfo
|
||||
{
|
||||
public:
|
||||
arLanguageInfo(){ };
|
||||
~arLanguageInfo(){ };
|
||||
|
||||
const char* name() const { return name_.c_str(); }
|
||||
void set_name(const char* name){ name_ = name; }
|
||||
|
||||
const char* resources_folder() const { return resources_folder_.c_str(); }
|
||||
void set_resources_folder(const char* folder){ resources_folder_ = folder; }
|
||||
|
||||
void init(const char* ini_file,const char* section);
|
||||
|
||||
private:
|
||||
|
||||
std::string name_;
|
||||
std::string resources_folder_;
|
||||
};
|
||||
|
||||
enum arButtonType
|
||||
{
|
||||
ABT_URL,
|
||||
ABT_EXEC,
|
||||
ABT_EXIT,
|
||||
ABT_LANGUAGE
|
||||
};
|
||||
|
||||
class arButtonState
|
||||
{
|
||||
public:
|
||||
arButtonState() : pos_(0,0), animation_(NULL){ }
|
||||
~arButtonState(){ }
|
||||
|
||||
const Vect2i& pos() const { return pos_; }
|
||||
void set_pos(const Vect2i& pos){ pos_ = pos; }
|
||||
|
||||
bool has_animation() const { return !animation_name_.empty(); }
|
||||
const char* animation_name() const { return animation_name_.c_str(); }
|
||||
void set_animation_name(const char* name){ animation_name_ = name; }
|
||||
|
||||
const qdAnimation* animation() const { return animation_; }
|
||||
void set_animation(const qdAnimation* p){ animation_ = p; }
|
||||
|
||||
private:
|
||||
|
||||
Vect2i pos_;
|
||||
|
||||
std::string animation_name_;
|
||||
const qdAnimation* animation_;
|
||||
};
|
||||
|
||||
class arButtonExecObject
|
||||
{
|
||||
public:
|
||||
arButtonExecObject(int id,const char* str) : language_id_(id), exec_string_(str) { }
|
||||
~arButtonExecObject(){ }
|
||||
|
||||
bool operator == (int lng_id) const { return (language_id_ == lng_id); }
|
||||
|
||||
const char* exec_string() const { return exec_string_.c_str(); }
|
||||
|
||||
private:
|
||||
|
||||
std::string exec_string_;
|
||||
int language_id_;
|
||||
};
|
||||
|
||||
const int AR_LANGUAGE_NONE = -1;
|
||||
|
||||
class arButton
|
||||
{
|
||||
public:
|
||||
arButton(void);
|
||||
~arButton(void);
|
||||
|
||||
bool operator == (int id) const { return ID == id; }
|
||||
|
||||
void set_ID(int id){ ID = id; }
|
||||
|
||||
int exec_show_mode(void) const { return cmd_show; }
|
||||
bool redraw_needed(void) const { return need_redraw_; }
|
||||
|
||||
void load_image(const char* fname,int state);
|
||||
void init(const char* ini_file,const char* section);
|
||||
|
||||
void redraw();
|
||||
|
||||
void set_state(int st,bool forced = false);
|
||||
int get_state(void) const { return state; }
|
||||
|
||||
void set_type(int tp){ type = tp; }
|
||||
int get_type(void) const { return type; }
|
||||
|
||||
void set_obj(const char* p){ if(obj_name) free(obj_name); obj_name = strdup(p); }
|
||||
char* get_obj(void){ return obj_name; }
|
||||
|
||||
void set_obj_regvalue(const char* p){ if(obj_name_regvalue) free(obj_name_regvalue); obj_name_regvalue = strdup(p); }
|
||||
|
||||
void set_cmdline(const char* p){ if(cmd_line) free(cmd_line); cmd_line = strdup(p); }
|
||||
char* get_cmdline(void){ return cmd_line; }
|
||||
|
||||
void set_regkey(const char* p){ if(reg_key) free(reg_key); reg_key = strdup(p); }
|
||||
char* get_regkey(void){ return reg_key; }
|
||||
|
||||
void set_reg_exec_path(const char* p){ if(reg_exec_path_value) free(reg_exec_path_value); reg_exec_path_value = strdup(p); }
|
||||
|
||||
void set_checkstr(const char* p){ if(check_after_exec) free(check_after_exec); check_after_exec = strdup(p); }
|
||||
char* get_checkstr(void){ return check_after_exec; }
|
||||
|
||||
int check_regkey(void);
|
||||
static HKEY open_regkey(const char* regkey_name);
|
||||
|
||||
int get_exec_path(char* path,int path_len);
|
||||
int get_exec_obj(char* str,int str_len);
|
||||
|
||||
void enable(bool st = true){ is_enabled_ = st; if(!st) set_state(-1); else set_state(0); }
|
||||
bool is_enabled() const { return is_enabled_; }
|
||||
|
||||
int size_x(int state) const { if(states_[state].animation()) return states_[state].animation() -> size_x(); return 0; }
|
||||
int size_y(int state) const { if(states_[state].animation()) return states_[state].animation() -> size_y(); return 0; }
|
||||
|
||||
bool hit(int x,int y) const;
|
||||
int click(void);
|
||||
|
||||
static void load_resources();
|
||||
|
||||
bool language_dependency() const { return language_dependency_; }
|
||||
void set_language_dependency(bool state){ language_dependency_ = state; }
|
||||
|
||||
int language_id() const { return language_id_; }
|
||||
void set_language_id(int id){ language_id_ = id; }
|
||||
|
||||
bool has_language_id() const { return (language_id_ != AR_LANGUAGE_NONE); }
|
||||
|
||||
void change_animation_folder(const char* folder);
|
||||
|
||||
static void set_current_language_id(int id){ current_language_id_ = id; }
|
||||
|
||||
typedef qdResourceContainer<arButton> resource_container_t;
|
||||
static resource_container_t& resource_container();
|
||||
|
||||
private:
|
||||
|
||||
int ID;
|
||||
|
||||
int type;
|
||||
char* obj_name;
|
||||
char* obj_name_regvalue;
|
||||
|
||||
char* cmd_line;
|
||||
int cmd_show;
|
||||
|
||||
char* reg_key;
|
||||
char* reg_exec_path_value;
|
||||
|
||||
char* check_after_exec;
|
||||
|
||||
bool is_enabled_;
|
||||
|
||||
int state;
|
||||
bool need_redraw_;
|
||||
|
||||
bool language_dependency_;
|
||||
|
||||
int language_id_;
|
||||
|
||||
typedef std::vector<arButtonExecObject> exec_objects_container_t;
|
||||
exec_objects_container_t exec_objects_;
|
||||
|
||||
arButtonState states_[2];
|
||||
|
||||
qdAnimation animation_;
|
||||
|
||||
static int current_language_id_;
|
||||
|
||||
int split_cmdline(char* str,char*& exec,char*& args);
|
||||
};
|
||||
|
||||
class arButtonDispatcher
|
||||
{
|
||||
public:
|
||||
arButtonDispatcher(void);
|
||||
~arButtonDispatcher(void);
|
||||
|
||||
void init(const char* ini_file);
|
||||
bool init_language(const char* ini_file);
|
||||
|
||||
bool hit(int x,int y);
|
||||
void click(int x,int y);
|
||||
void redraw();
|
||||
|
||||
int need_check(void){ if(curButton) return 1; return 0; }
|
||||
void check_exec(void);
|
||||
|
||||
const qdAnimation* background() const { return background_; }
|
||||
|
||||
bool set_language(int language_id);
|
||||
bool set_language(const char* language_name);
|
||||
|
||||
private:
|
||||
|
||||
typedef std::vector<arLanguageInfo> languages_container_t;
|
||||
languages_container_t languages_;
|
||||
int current_language_;
|
||||
|
||||
typedef std::vector<arButton> buttons_container_t;
|
||||
buttons_container_t btList;
|
||||
|
||||
const qdAnimation* background_;
|
||||
|
||||
arButton* curButton;
|
||||
};
|
||||
|
||||
#endif /* __AR_BUTTON_H__ */
|
||||
@@ -0,0 +1,153 @@
|
||||
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "gdi_gr_dispatcher.h"
|
||||
#include "qd_file_manager.h"
|
||||
|
||||
#include "ar_button.h"
|
||||
#include "input_wndproc.h"
|
||||
|
||||
#include "..\Resource.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
|
||||
bool mouseMove(int x,int y,int flags);
|
||||
bool mouseClick(int x,int y,int flags);
|
||||
|
||||
char* getIniKey(const char* fname,const char* section,const char* key);
|
||||
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
HWND hmainWnd;
|
||||
|
||||
arButtonDispatcher* arbt_D;
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdLine, int nCmdShow)
|
||||
{
|
||||
const char* const autorun_event_name = "K-D Lab Game Launcher";
|
||||
if(HANDLE event = OpenEvent(EVENT_ALL_ACCESS,FALSE,autorun_event_name))
|
||||
return 0;
|
||||
else
|
||||
event = CreateEvent(0,TRUE,TRUE,autorun_event_name);
|
||||
|
||||
const char* event_name = getIniKey("autorun.ini","settings","game_event_name");
|
||||
if(strlen(event_name)){
|
||||
if(HANDLE event = OpenEvent(EVENT_ALL_ACCESS,FALSE,event_name))
|
||||
return 0;
|
||||
}
|
||||
|
||||
XStream fh;
|
||||
|
||||
qdFileManager::instance().toggle_silent_update_mode(true);
|
||||
|
||||
arbt_D = new arButtonDispatcher;
|
||||
arbt_D -> init("autorun.ini");
|
||||
|
||||
grDispatcher::sys_init();
|
||||
|
||||
GDI_grDispatcher* gr_D = new GDI_grDispatcher;
|
||||
|
||||
if(!arbt_D -> background()) return 1;
|
||||
|
||||
int sx = arbt_D -> background() -> size_x();
|
||||
int sy = arbt_D -> background() -> size_y();
|
||||
|
||||
int x = (GetSystemMetrics(SM_CXSCREEN) - sx)/2;
|
||||
int y = (GetSystemMetrics(SM_CYSCREEN) - sy)/2;
|
||||
|
||||
hmainWnd = CreateWindow(grDispatcher::wnd_class_name(),getIniKey("autorun.ini","settings","wnd_title"),WS_POPUP,x,y,sx,sy,NULL,NULL,hInstance,NULL);
|
||||
|
||||
if(!grDispatcher::instance() -> init(sx,sy,GR_RGB888,hmainWnd,false))
|
||||
return 1;
|
||||
|
||||
if(gr_D -> palette_mode()){
|
||||
XStream fh(0);
|
||||
const char* pal_file = getIniKey("autorun.ini","settings","palette_file");
|
||||
if(pal_file[0] && fh.open(pal_file)){
|
||||
char pal_buf[768];
|
||||
fh.read(pal_buf,768);
|
||||
fh.close();
|
||||
gr_D -> set_palette(pal_buf,0,256);
|
||||
}
|
||||
}
|
||||
|
||||
mouseDispatcher::instance() -> set_event_handler(mouseDispatcher::EV_LEFT_DOWN,mouseClick);
|
||||
mouseDispatcher::instance() -> set_event_handler(mouseDispatcher::EV_MOUSE_MOVE,mouseMove);
|
||||
|
||||
if(!arbt_D -> init_language("autorun.ini"))
|
||||
arbt_D -> redraw();
|
||||
|
||||
SetTimer(hmainWnd,1,300,NULL);
|
||||
|
||||
ShowWindow(hmainWnd,SW_SHOWNORMAL);
|
||||
UpdateWindow(hmainWnd);
|
||||
|
||||
MSG msg;
|
||||
while(GetMessage(&msg,NULL,0,0)){
|
||||
switch(msg.message){
|
||||
case WM_TIMER:
|
||||
if(arbt_D -> need_check())
|
||||
arbt_D -> check_exec();
|
||||
break;
|
||||
case WM_KEYDOWN:
|
||||
if(msg.wParam == VK_ESCAPE)
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
|
||||
input::keyboard_wndproc(msg,keyboardDispatcher::instance());
|
||||
input::mouse_wndproc(msg,mouseDispatcher::instance());
|
||||
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
KillTimer(hmainWnd,1);
|
||||
|
||||
delete gr_D;
|
||||
grDispatcher::sys_finit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool mouseMove(int x,int y,int flags)
|
||||
{
|
||||
int dx,dy;
|
||||
static RECT rc;
|
||||
static int mx = -1;
|
||||
static int my = -1;
|
||||
|
||||
if(mx == -1){
|
||||
mx = x;
|
||||
my = y;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if(flags & MK_LBUTTON){
|
||||
dx = x - mx;
|
||||
dy = y - my;
|
||||
|
||||
if(dx || dy){
|
||||
GetWindowRect(hmainWnd,&rc);
|
||||
SetWindowPos(hmainWnd,NULL,rc.left + dx,rc.top + dy,0,0,SWP_NOZORDER | SWP_NOSIZE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
arbt_D -> hit(x,y);
|
||||
|
||||
mx = x;
|
||||
my = y;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mouseClick(int x,int y,int flags)
|
||||
{
|
||||
arbt_D -> click(x,y);
|
||||
return true;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,119 @@
|
||||
# Microsoft Developer Studio Project File - Name="autorun" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=autorun - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "autorun.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "autorun.mak" CFG="autorun - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "autorun - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "autorun - Win32 Debug" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""$/qdEngine", HIKAAAAA"
|
||||
# PROP Scc_LocalPath "..\.."
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "autorun - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "..\..\..\Bin"
|
||||
# PROP Intermediate_Dir "\Garbage\qdEngine\Autorun\Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GR /GX /O2 /I "Source" /I "." /I "..\..\\" /I "..\..\qdCore" /I "..\..\qdCore\Util" /I "..\..\System" /I "..\..\System\Graphics" /I "..\..\System\Sound" /I "..\..\Parser" /I "..\..\System\Input" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 XUtil.lib XMath.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "autorun - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "..\..\..\Bin\dbg"
|
||||
# PROP Intermediate_Dir "\Garbage\qdEngine\Autorun\Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GR /GX /ZI /Od /I "Source" /I "." /I "..\..\\" /I "..\..\qdCore" /I "..\..\qdCore\Util" /I "..\..\System" /I "..\..\System\Graphics" /I "..\..\System\Sound" /I "..\..\Parser" /I "..\..\System\Input" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 PlayMppDBG.lib libexpatd.lib XUtilDBG.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"..\..\..\Bin\dbg\autorunDBG.exe" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "autorun - Win32 Release"
|
||||
# Name "autorun - Win32 Debug"
|
||||
# Begin Group "arButton"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Source\ar_button.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Source\ar_button.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\autorun.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\autorun.ini
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\autorun.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Source\runtime.cpp
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
@@ -0,0 +1,251 @@
|
||||
[settings]
|
||||
buttons = 16
|
||||
|
||||
game_event_name = "Maelstrom"
|
||||
|
||||
wnd_title = "Maelstrom"
|
||||
background = "Resource\BACKGROUND.tga"
|
||||
palette_file = "Resource\autorun.pal"
|
||||
|
||||
languages = 5
|
||||
language_regkey = "HKCU\Software\Codemasters\Maelstrom\Intf"
|
||||
language_regvalue = "Locale"
|
||||
|
||||
[language0]
|
||||
name = "English"
|
||||
resources = "resource\eng"
|
||||
|
||||
[language1]
|
||||
name = "French"
|
||||
resources = "resource\fr"
|
||||
|
||||
[language2]
|
||||
name = "German"
|
||||
resources = "resource\germ"
|
||||
|
||||
[language3]
|
||||
name = "Italian"
|
||||
resources = "resource\it"
|
||||
|
||||
[language4]
|
||||
name = "Spanish"
|
||||
resources = "resource\esp"
|
||||
|
||||
[button0] ; Install
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\eng\install_off.qda"
|
||||
state1 = "Resource\eng\install_on.qda"
|
||||
|
||||
exec = "Setup.exe"
|
||||
;exit = 1
|
||||
|
||||
language_dependency = 1
|
||||
|
||||
check_after_exec = "1 2 4"
|
||||
|
||||
[button1] ; Run
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\eng\run_off.qda"
|
||||
state1 = "Resource\eng\run_on.qda"
|
||||
|
||||
exec = "Maelstrom.exe"
|
||||
exit = 1
|
||||
|
||||
language_dependency = 1
|
||||
|
||||
regkey_check_on_startup = 1
|
||||
regkey = "HKLM\Software\Codemasters\Maelstrom"
|
||||
exec_path_regvalue = "Install_Path"
|
||||
|
||||
[button2] ; Settings
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\eng\settings_off.qda"
|
||||
state1 = "Resource\eng\settings_on.qda"
|
||||
|
||||
exec = "config.exe"
|
||||
minimize = 0
|
||||
|
||||
language_dependency = 1
|
||||
|
||||
regkey_check_on_startup = 1
|
||||
regkey = "HKLM\Software\Codemasters\Maelstrom"
|
||||
exec_path_regvalue = "Install_Path"
|
||||
|
||||
[button3] ; Maelstrom
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\maelstrom_off.qda"
|
||||
state1 = "Resource\maelstrom_on.qda"
|
||||
|
||||
url = "http://www.codemasters.co.uk/maelstrom/"
|
||||
|
||||
url_num = 1
|
||||
url0_language = 2
|
||||
url0_string = "http://www.codemasters.de/maelstrom/"
|
||||
|
||||
[button4] ; Uninstall
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\eng\uninstall_off.qda"
|
||||
state1 = "Resource\eng\uninstall_on.qda"
|
||||
|
||||
exec_from_regval = "UninstallString"
|
||||
check_after_exec = "1 2 4"
|
||||
|
||||
regkey_check_on_startup = 1
|
||||
regkey = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{A3D5D8C4-122F-41C3-BB03-B738601615EE}"
|
||||
|
||||
language_dependency = 1
|
||||
|
||||
[button5] ; NVidia
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\nvidia_off.qda"
|
||||
state1 = "Resource\nvidia_on.qda"
|
||||
|
||||
url = "http://www.nvidia.com/ "
|
||||
|
||||
[button6] ; Exit
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\eng\exit_off.qda"
|
||||
state1 = "Resource\eng\exit_on.qda"
|
||||
|
||||
exec = "exit"
|
||||
|
||||
language_dependency = 1
|
||||
|
||||
[button7] ; KDV
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\kdv_off.qda"
|
||||
state1 = "Resource\kdv_on.qda"
|
||||
|
||||
url = "http://www.kdvgames.com/eng"
|
||||
|
||||
[button8] ; Codemasters
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\codemasters_off.qda"
|
||||
state1 = "Resource\codemasters_on.qda"
|
||||
|
||||
url = "http://www.codemasters.co.uk"
|
||||
|
||||
url_num = 1
|
||||
url0_language = 2
|
||||
url0_string = "http://www.codemasters.de"
|
||||
|
||||
[button9] ; Bonus
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\bonus_off.qda"
|
||||
state1 = "Resource\bonus_on.qda"
|
||||
|
||||
language_dependency = 0
|
||||
|
||||
url = "http://www.codemasters.co.uk/perimeter/downloads/"
|
||||
|
||||
[button10] ; GB
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\flag_eng_off.qda"
|
||||
state1 = "Resource\flag_eng_on.qda"
|
||||
|
||||
exec = language
|
||||
args = 0
|
||||
|
||||
[button11] ; USA
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\flag_amer_off.qda"
|
||||
state1 = "Resource\flag_amer_on.qda"
|
||||
|
||||
exec = language
|
||||
args = 0
|
||||
|
||||
[button12] ; Germany
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\flag_ger_off.qda"
|
||||
state1 = "Resource\flag_ger_on.qda"
|
||||
|
||||
exec = language
|
||||
args = 2
|
||||
|
||||
[button13] ; France
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\flag_fr_off.qda"
|
||||
state1 = "Resource\flag_fr_on.qda"
|
||||
|
||||
exec = language
|
||||
args = 1
|
||||
|
||||
[button14] ; Italy
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\flag_it_off.qda"
|
||||
state1 = "Resource\flag_it_on.qda"
|
||||
|
||||
exec = language
|
||||
args = 3
|
||||
|
||||
[button15] ; Spain
|
||||
x0 = 0
|
||||
y0 = 0
|
||||
x1 = 0
|
||||
y1 = 0
|
||||
|
||||
state0 = "Resource\flag_esp_off.qda"
|
||||
state1 = "Resource\flag_esp_on.qda"
|
||||
|
||||
exec = language
|
||||
args = 4
|
||||
@@ -0,0 +1,72 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Russian resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
||||
#pragma code_page(1251)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_APP ICON DISCARDABLE "autorun.ico"
|
||||
#endif // Russian resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="autorun"
|
||||
SccProjectName=""$/qdEngine", HIKAAAAA"
|
||||
SccLocalPath="..\..">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\..\..\..\Bin\dbg"
|
||||
IntermediateDirectory="../../.garbage/$(ProjectName)/$(ConfigurationName)/"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="Source,.,..\..\,..\..\qdCore,..\..\qdCore\Util,..\..\System,..\..\System\Graphics,..\..\System\Sound,..\..\Parser,..\..\System\Input"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderFile="$(IntDir)/autorun.pch"
|
||||
AssemblerListingLocation="$(IntDir)"
|
||||
ObjectFile="$(IntDir)"
|
||||
ProgramDataBaseFileName="$(IntDir)"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="..\..\..\Bin\dbg\autorunDBG.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
IgnoreDefaultLibraryNames="msvcrtd"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\..\..\..\Bin\dbg/autorunDBG.pdb"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\..\..\..\Bin\dbg/autorun.tlb"
|
||||
HeaderFileName=""/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1049"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\..\..\..\Bin"
|
||||
IntermediateDirectory="../../.garbage/$(ProjectName)/$(ConfigurationName)/"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="Source,.,..\..\,..\..\qdCore,..\..\qdCore\Util,..\..\System,..\..\System\Graphics,..\..\System\Sound,..\..\Parser,..\..\System\Input"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderFile="$(IntDir)/autorun.pch"
|
||||
AssemblerListingLocation="$(IntDir)"
|
||||
ObjectFile="$(IntDir)"
|
||||
ProgramDataBaseFileName="$(IntDir)"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="XUtilVC7MT.lib odbc32.lib odbccp32.lib"
|
||||
OutputFile=".\..\..\..\Bin/autorun.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
IgnoreDefaultLibraryNames="libc, msvcrt, libcmtd"
|
||||
ProgramDatabaseFile=".\..\..\..\Bin/autorun.pdb"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\..\..\..\Bin/autorun.tlb"
|
||||
HeaderFileName=""/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1049"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="arButton"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="Source\ar_button.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
BasicRuntimeChecks="3"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Source\ar_button.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath="autorun.ico">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="autorun.ini">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="autorun.rc">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Source\runtime.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
BasicRuntimeChecks="3"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by autorun.rc
|
||||
//
|
||||
#define IDI_APP 101
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,99 @@
|
||||
# Microsoft Developer Studio Project File - Name="MinigameSample" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=MinigameSample - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "MinigameSample.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "MinigameSample.mak" CFG="MinigameSample - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "MinigameSample - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "MinigameSample - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "MinigameSample - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "."
|
||||
# PROP Intermediate_Dir "\Garbage\qdEngine\MinigameSample\Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\qdCore" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "MinigameSample - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "."
|
||||
# PROP Intermediate_Dir "\Garbage\qdEngine\MinigameSample\Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\qdCore" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"./MinigameSampleDBG.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "MinigameSample - Win32 Release"
|
||||
# Name "MinigameSample - Win32 Debug"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\minigame_sample.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\source\minigame_sample.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,171 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="MinigameSample"
|
||||
SccProjectName=""
|
||||
SccLocalPath="">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\."
|
||||
IntermediateDirectory="../../.garbage/$(ProjectName)/$(ConfigurationName)/"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\qdCore"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderFile="$(IntDir)/MinigameSample.pch"
|
||||
AssemblerListingLocation="$(IntDir)"
|
||||
ObjectFile="$(IntDir)"
|
||||
ProgramDataBaseFileName="$(IntDir)"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="./MinigameSampleDBG.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\./MinigameSampleDBG.pdb"
|
||||
SubSystem="2"
|
||||
ImportLibrary=".\./MinigameSampleDBG.lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\./MinigameSample.tlb"
|
||||
HeaderFileName=""/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1049"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\."
|
||||
IntermediateDirectory="../../.garbage/$(ProjectName)/$(ConfigurationName)/"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="..\..\qdCore"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderFile="$(IntDir)/MinigameSample.pch"
|
||||
AssemblerListingLocation="$(IntDir)"
|
||||
ObjectFile="$(IntDir)"
|
||||
ProgramDataBaseFileName="$(IntDir)"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile=".\./MinigameSample.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
ProgramDatabaseFile=".\./MinigameSample.pdb"
|
||||
SubSystem="2"
|
||||
ImportLibrary=".\./MinigameSample.lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\./MinigameSample.tlb"
|
||||
HeaderFileName=""/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1049"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath="source\minigame_sample.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;$(NoInherit)"
|
||||
BasicRuntimeChecks="3"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;$(NoInherit)"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="source\minigame_sample.h">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,313 @@
|
||||
|
||||
#include <list>
|
||||
#include <fstream>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "qd_minigame_interface.h"
|
||||
|
||||
class minigameSample : public qdMiniGameInterface
|
||||
{
|
||||
public:
|
||||
minigameSample();
|
||||
~minigameSample(){ }
|
||||
|
||||
/// Èíèöèàëèçàöèÿ èãðû.
|
||||
bool init(const qdEngineInterface* p);
|
||||
|
||||
/// Îáñ÷¸ò ëîãèêè èãðû, ïàðàìåòð - âðåìÿ, êîòîðîå äîëæíî ïðîéòè â èãðå (â ñåêóíäàõ).
|
||||
bool quant(float dt);
|
||||
|
||||
/// Äåèíèöèàëèçàöèÿ èãðû.
|
||||
bool finit();
|
||||
private:
|
||||
|
||||
qdMinigameObjectInterface* ball_object_;
|
||||
qdMinigameObjectInterface* board_object_;
|
||||
qdMinigameObjectInterface* field_object_;
|
||||
|
||||
enum {
|
||||
BALL_LOCKED,
|
||||
BALL_FREE
|
||||
} ball_movement_mode_;
|
||||
|
||||
mgVect2f ball_speed_;
|
||||
mgVect2f ball_speed_initial_;
|
||||
mgVect2f ball_speed_initial_rnd_;
|
||||
|
||||
typedef std::list<qdMinigameObjectInterface*> brick_objects_container_t;
|
||||
brick_objects_container_t brick_objects_;
|
||||
|
||||
const qdEngineInterface* engine_;
|
||||
qdMinigameSceneInterface* scene_;
|
||||
|
||||
bool constrain_object_position(qdMinigameObjectInterface* object, const qdMinigameObjectInterface* bound_object);
|
||||
bool ball_collision(qdMinigameObjectInterface* object);
|
||||
bool vertical_edge_collision(const mgVect3f& v0, const mgVect3f& v1) const;
|
||||
bool horizontal_edge_collision(const mgVect3f& v0, const mgVect3f& v1) const;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
__declspec(dllexport) qdMiniGameInterface* open_game_interface(const char*);
|
||||
__declspec(dllexport) bool close_game_interface(qdMiniGameInterface* p);
|
||||
};
|
||||
|
||||
qdMiniGameInterface* open_game_interface(const char*)
|
||||
{
|
||||
return new minigameSample;
|
||||
}
|
||||
|
||||
bool close_game_interface(qdMiniGameInterface* p)
|
||||
{
|
||||
delete p;
|
||||
return true;
|
||||
}
|
||||
|
||||
minigameSample::minigameSample() : ball_object_(0),
|
||||
board_object_(0),
|
||||
field_object_(0),
|
||||
ball_movement_mode_(BALL_LOCKED)
|
||||
{
|
||||
}
|
||||
|
||||
bool minigameSample::init(const qdEngineInterface* p)
|
||||
{
|
||||
engine_ = p;
|
||||
if(scene_ = p -> current_scene_interface()){
|
||||
ball_object_ = scene_ -> object_interface(scene_ -> minigame_parameter("ball_object_name"));
|
||||
board_object_ = scene_ -> object_interface(scene_ -> minigame_parameter("board_object_name"));
|
||||
field_object_ = scene_ -> object_interface(scene_ -> minigame_parameter("field_object_name"));
|
||||
|
||||
sscanf(scene_ -> minigame_parameter("ball_speed"),"%f%f",&ball_speed_initial_.x,&ball_speed_initial_.y);
|
||||
sscanf(scene_ -> minigame_parameter("ball_speed_rnd"),"%f%f",&ball_speed_initial_rnd_.x,&ball_speed_initial_rnd_.y);
|
||||
|
||||
float x = field_object_ -> R().x;
|
||||
float y = field_object_ -> R().y - field_object_ -> bound().y/2;
|
||||
|
||||
board_object_ -> set_R(mgVect3f(x,y,0));
|
||||
|
||||
y += ball_object_ -> bound().y/2 + board_object_ -> bound().y/2;
|
||||
ball_object_ -> set_R(mgVect3f(x,y,0));
|
||||
|
||||
ball_movement_mode_ = BALL_LOCKED;
|
||||
|
||||
char name[256];
|
||||
mgVect3f v0 = field_object_ -> R() - field_object_ -> bound()/2;
|
||||
v0 += mgVect3f(16,field_object_ -> bound().y - 32,0);
|
||||
|
||||
for(int i = 0; i < 10; i ++){
|
||||
sprintf(name,"%s%.4d",scene_ -> minigame_parameter("brick_object"),i);
|
||||
if(qdMinigameObjectInterface* obj = scene_ -> object_interface(name)){
|
||||
obj -> set_state(3);
|
||||
obj -> set_R(v0 + obj -> bound()/2);
|
||||
v0.x += obj -> bound().x + 6;
|
||||
|
||||
brick_objects_.push_back(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool minigameSample::quant(float dt)
|
||||
{
|
||||
mgVect3f r = board_object_ -> R();
|
||||
r.x = scene_ -> screen2grid_coords(engine_ -> mouse_cursor_position()).x;
|
||||
board_object_ -> set_R(r);
|
||||
constrain_object_position(board_object_, field_object_);
|
||||
|
||||
switch(ball_movement_mode_){
|
||||
case BALL_LOCKED:
|
||||
r = board_object_ -> R();
|
||||
r.y += ball_object_ -> bound().y/2 + board_object_ -> bound().y/2;
|
||||
ball_object_ -> set_R(r);
|
||||
if(engine_->is_mouse_event_active(qdEngineInterface::MOUSE_EV_LEFT_DOWN)){
|
||||
ball_movement_mode_ = BALL_FREE;
|
||||
|
||||
ball_speed_ = ball_speed_initial_;
|
||||
ball_speed_.x += engine_ -> frnd(ball_speed_initial_rnd_.x);
|
||||
ball_speed_.y += engine_ -> frnd(ball_speed_initial_rnd_.y);
|
||||
}
|
||||
break;
|
||||
case BALL_FREE:
|
||||
r = ball_object_ -> R();
|
||||
r.x += ball_speed_.x * dt;
|
||||
r.y += ball_speed_.y * dt;
|
||||
ball_object_ -> set_R(r);
|
||||
|
||||
ball_collision(board_object_);
|
||||
for(brick_objects_container_t::iterator it = brick_objects_.begin(); it != brick_objects_.end(); ++it){
|
||||
if((*it) -> is_visible() && ball_collision(*it)){
|
||||
int idx = (*it) -> current_state_index();
|
||||
(*it) -> set_state(idx ? idx - 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
if(r.x > field_object_ -> R().x + field_object_ -> bound().x/2 - ball_object_ -> bound().x/2 && ball_speed_.x > 0)
|
||||
ball_speed_.x = -ball_speed_.x + engine_ -> frnd(1);
|
||||
if(r.x < field_object_ -> R().x - field_object_ -> bound().x/2 + ball_object_ -> bound().x/2 && ball_speed_.x < 0)
|
||||
ball_speed_.x = -ball_speed_.x + engine_ -> frnd(1);
|
||||
|
||||
if(r.y > field_object_ -> R().y + field_object_ -> bound().y/2 - ball_object_ -> bound().y/2 && ball_speed_.y > 0)
|
||||
ball_speed_.y = -ball_speed_.y + engine_ -> frnd(1);
|
||||
if(r.y < field_object_ -> R().y - field_object_ -> bound().y/2 - ball_object_ -> bound().y)
|
||||
ball_movement_mode_ = BALL_LOCKED;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool minigameSample::finit()
|
||||
{
|
||||
engine_ -> release_scene_interface(scene_);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool minigameSample::constrain_object_position(qdMinigameObjectInterface* object, const qdMinigameObjectInterface* bound_object)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
mgVect3f r = object -> R();
|
||||
mgVect3f bound = object -> bound();
|
||||
|
||||
mgVect3f r0 = bound_object -> R();
|
||||
mgVect3f bound0 = bound_object -> bound();
|
||||
|
||||
if(r.x - bound.x/2 < r0.x - bound0.x/2){
|
||||
ret = true;
|
||||
r.x = r0.x - bound0.x/2 + bound.x/2;
|
||||
}
|
||||
if(r.x + bound.x/2 > r0.x + bound0.x/2){
|
||||
ret = true;
|
||||
r.x = r0.x + bound0.x/2 - bound.x/2;
|
||||
}
|
||||
|
||||
if(r.y - bound.y/2 < r0.y - bound0.y/2){
|
||||
ret = true;
|
||||
r.y = r0.y - bound0.y/2 + bound.y/2;
|
||||
}
|
||||
if(r.y + bound.y/2 > r0.y + bound0.y/2){
|
||||
ret = true;
|
||||
r.y = r0.y + bound0.y/2 - bound.y/2;
|
||||
}
|
||||
|
||||
if(ret)
|
||||
object -> set_R(r);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool minigameSample::ball_collision(qdMinigameObjectInterface* object)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
mgVect3f d = object -> R() - ball_object_ -> R();
|
||||
mgVect3f bound = ball_object_ -> bound()/2 + object -> bound()/2;
|
||||
|
||||
if(fabs(d.x) < bound.x && fabs(d.y) < bound.y){
|
||||
if(d.x < 0 && ball_speed_.x < 0){
|
||||
mgVect3f v0 = object -> R() + object->bound()/2;
|
||||
mgVect3f v1 = object -> R() + object->bound()/2;
|
||||
|
||||
v1.y -= object -> bound().y;
|
||||
|
||||
if(vertical_edge_collision(v0, v1)){
|
||||
ret = true;
|
||||
ball_speed_.x = -ball_speed_.x + engine_ -> frnd(1);
|
||||
}
|
||||
}
|
||||
if(d.x > 0 && ball_speed_.x > 0){
|
||||
mgVect3f v0 = object -> R() - object->bound()/2;
|
||||
mgVect3f v1 = object -> R() - object->bound()/2;
|
||||
|
||||
v1.y += object -> bound().y;
|
||||
|
||||
if(vertical_edge_collision(v0, v1)){
|
||||
ret = true;
|
||||
ball_speed_.x = -ball_speed_.x + engine_ -> frnd(1);
|
||||
}
|
||||
}
|
||||
|
||||
if(d.y < 0 && ball_speed_.y < 0){
|
||||
mgVect3f v0 = object -> R() + object->bound()/2;
|
||||
mgVect3f v1 = object -> R() + object->bound()/2;
|
||||
|
||||
v1.x -= object -> bound().x;
|
||||
|
||||
if(horizontal_edge_collision(v0, v1)){
|
||||
ret = true;
|
||||
ball_speed_.y = -ball_speed_.y + engine_ -> frnd(1);
|
||||
}
|
||||
}
|
||||
if(d.y > 0 && ball_speed_.y > 0){
|
||||
mgVect3f v0 = object -> R() - object->bound()/2;
|
||||
mgVect3f v1 = object -> R() - object->bound()/2;
|
||||
|
||||
v1.x += object -> bound().x;
|
||||
|
||||
if(horizontal_edge_collision(v0, v1)){
|
||||
ret = true;
|
||||
ball_speed_.y = -ball_speed_.y + engine_ -> frnd(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool minigameSample::vertical_edge_collision(const mgVect3f& v0, const mgVect3f& v1) const
|
||||
{
|
||||
float y = ball_object_ -> R().y;
|
||||
float y0 = (v0.y < v1.y) ? v0.y : v1.y;
|
||||
float y1 = (v0.y < v1.y) ? v1.y : v0.y;
|
||||
|
||||
float r = ball_object_ -> bound().x/2;
|
||||
float r2 = r * r;
|
||||
|
||||
float dx = fabs(ball_object_ -> R().x - v0.x);
|
||||
|
||||
if(y < y0){
|
||||
return (dx * dx + (y - y0) * (y - y0) < r2);
|
||||
}
|
||||
else {
|
||||
if(y < y1){
|
||||
return (dx < r);
|
||||
}
|
||||
else {
|
||||
return (dx * dx + (y - y1) * (y - y1) < r2);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool minigameSample::horizontal_edge_collision(const mgVect3f& v0, const mgVect3f& v1) const
|
||||
{
|
||||
float x = ball_object_ -> R().x;
|
||||
float x0 = (v0.x < v1.x) ? v0.x : v1.x;
|
||||
float x1 = (v0.x < v1.x) ? v1.x : v0.x;
|
||||
|
||||
float r = ball_object_ -> bound().x/2;
|
||||
float r2 = r * r;
|
||||
|
||||
float dy = fabs(ball_object_ -> R().y - v0.y);
|
||||
|
||||
if(x < x0){
|
||||
return (dy * dy + (x - x0) * (x - x0) < r2);
|
||||
}
|
||||
else {
|
||||
if(x < x1){
|
||||
return (dy < r);
|
||||
}
|
||||
else {
|
||||
return (dy * dy + (x - x1) * (x - x1) < r2);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef __MINIGAME_SAMPLE_H__
|
||||
#define __MINIGAME_SAMPLE_H__
|
||||
|
||||
#endif /* __MINIGAME_SAMPLE_H__ */
|
||||
@@ -0,0 +1,151 @@
|
||||
# Microsoft Developer Studio Project File - Name="ParserDLL" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=ParserDLL - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ParserDLL.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ParserDLL.mak" CFG="ParserDLL - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "ParserDLL - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "ParserDLL - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""$/qdEngine", HIKAAAAA"
|
||||
# PROP Scc_LocalPath "..\.."
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "ParserDLL - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "..\..\..\Bin"
|
||||
# PROP Intermediate_Dir "\Garbage\qdEngine\ParserDLL\Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PARSERDLL_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PARSERDLL_EXPORTS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=xilink6.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 XUtil.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\..\Bin\parser.dll"
|
||||
|
||||
!ELSEIF "$(CFG)" == "ParserDLL - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "..\..\..\Bin\dbg"
|
||||
# PROP Intermediate_Dir "\Garbage\qdEngine\ParserDLL\Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PARSERDLL_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PARSERDLL_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=xilink6.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 XUtilDBG.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\..\Bin\dbg\parser_dbg.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "ParserDLL - Win32 Release"
|
||||
# Name "ParserDLL - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Source\qdscr_define.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Source\qdscr_error.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Source\qdscr_keywords.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Source\qdscr_mathexp.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Source\qdscr_parser.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Source\qdscr_prepare.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Source\qd_precomp.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Source\qdscr_define.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Source\qdscr_error.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Source\qdscr_keywords.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Source\qdscr_mathexp.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Source\qdscr_parser.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,284 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="ParserDLL"
|
||||
SccProjectName=""$/qdEngine", HIKAAAAA"
|
||||
SccLocalPath="..\..">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\..\..\..\Bin\dbg"
|
||||
IntermediateDirectory="\Garbage\qdEngine\ParserDLL\Debug"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PARSERDLL_EXPORTS"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderFile="\Garbage\qdEngine\ParserDLL\Debug/ParserDLL.pch"
|
||||
AssemblerListingLocation="\Garbage\qdEngine\ParserDLL\Debug/"
|
||||
ObjectFile="\Garbage\qdEngine\ParserDLL\Debug/"
|
||||
ProgramDataBaseFileName="\Garbage\qdEngine\ParserDLL\Debug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="1"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="XUtilDBG.lib odbc32.lib odbccp32.lib"
|
||||
OutputFile="..\..\..\Bin\dbg\parser_dbg.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\..\..\..\Bin\dbg/parser_dbg.pdb"
|
||||
ImportLibrary=".\..\..\..\Bin\dbg/parser_dbg.lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\..\..\..\Bin\dbg/ParserDLL.tlb"
|
||||
HeaderFileName=""/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1049"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\..\..\..\Bin"
|
||||
IntermediateDirectory="\Garbage\qdEngine\ParserDLL\Release"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PARSERDLL_EXPORTS"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderFile="\Garbage\qdEngine\ParserDLL\Release/ParserDLL.pch"
|
||||
AssemblerListingLocation="\Garbage\qdEngine\ParserDLL\Release/"
|
||||
ObjectFile="\Garbage\qdEngine\ParserDLL\Release/"
|
||||
ProgramDataBaseFileName="\Garbage\qdEngine\ParserDLL\Release/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="XUtil.lib odbc32.lib odbccp32.lib"
|
||||
OutputFile="..\..\..\Bin\parser.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
ProgramDatabaseFile=".\..\..\..\Bin/parser.pdb"
|
||||
ImportLibrary=".\..\..\..\Bin/parser.lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\..\..\..\Bin/ParserDLL.tlb"
|
||||
HeaderFileName=""/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1049"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
|
||||
<File
|
||||
RelativePath="Source\qdscr_define.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;PARSERDLL_EXPORTS;$(NoInherit)"
|
||||
BasicRuntimeChecks="3"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;PARSERDLL_EXPORTS;$(NoInherit)"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Source\qdscr_error.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;PARSERDLL_EXPORTS;$(NoInherit)"
|
||||
BasicRuntimeChecks="3"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;PARSERDLL_EXPORTS;$(NoInherit)"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Source\qdscr_keywords.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;PARSERDLL_EXPORTS;$(NoInherit)"
|
||||
BasicRuntimeChecks="3"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;PARSERDLL_EXPORTS;$(NoInherit)"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Source\qdscr_mathexp.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;PARSERDLL_EXPORTS;$(NoInherit)"
|
||||
BasicRuntimeChecks="3"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;PARSERDLL_EXPORTS;$(NoInherit)"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Source\qdscr_parser.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;PARSERDLL_EXPORTS;$(NoInherit)"
|
||||
BasicRuntimeChecks="3"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;PARSERDLL_EXPORTS;$(NoInherit)"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Source\qdscr_prepare.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;PARSERDLL_EXPORTS;$(NoInherit)"
|
||||
BasicRuntimeChecks="3"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;PARSERDLL_EXPORTS;$(NoInherit)"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl">
|
||||
<File
|
||||
RelativePath="Source\qd_precomp.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Source\qdscr_define.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Source\qdscr_error.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Source\qdscr_keywords.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Source\qdscr_mathexp.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Source\qdscr_parser.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef __QD_PRECOMP_H__
|
||||
#define __QD_PRECOMP_H__
|
||||
|
||||
#include <crtdbg.h>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DBGCHECK _ASSERTE(_CrtCheckMemory())
|
||||
#else
|
||||
#define DBGCHECK
|
||||
#endif
|
||||
|
||||
//#define _GR_ENABLE_ZBUFFER
|
||||
|
||||
#include <Additional\addition.h>
|
||||
#include <assert.h>
|
||||
|
||||
//#define _STLP_NO_NEW_IOSTREAMS 1
|
||||
|
||||
#ifdef _STLP_NO_NEW_IOSTREAMS
|
||||
#define _STLP_NO_OWN_NAMESPACE 1
|
||||
#else
|
||||
# define _STLP_USE_OWN_NAMESPACE 1
|
||||
# define _STLP_REDEFINE_STD 1
|
||||
#endif
|
||||
|
||||
#if _MSC_VER < 1300
|
||||
#define for if(false); else for
|
||||
#endif
|
||||
|
||||
#pragma warning(disable : 4786)
|
||||
#pragma warning(disable : 4018)
|
||||
#pragma warning(disable : 4244)
|
||||
|
||||
#include <windows.h>
|
||||
#include <XUtil.h>
|
||||
|
||||
#endif /* __QD_PRECOMP_H__ */
|
||||
@@ -0,0 +1,150 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "qdscr_define.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
const char* const def_str = "#define";
|
||||
const char* const text_str = "#text";
|
||||
const char* const end_str = "#end";
|
||||
|
||||
qdscrDefineData::qdscrDefineData(void) : src_data_(0), dest_data_(0),
|
||||
beg_index_(0), end_index_(0), flags_(0),
|
||||
src_length_(0), dest_length_(0)
|
||||
{
|
||||
}
|
||||
|
||||
qdscrDefineData::~qdscrDefineData(void)
|
||||
{
|
||||
delete src_data_;
|
||||
delete dest_data_;
|
||||
}
|
||||
|
||||
bool qdscrDefineData::init(char* ptr,int sz)
|
||||
{
|
||||
if(!(flags_ & TEXT_FLAG)){
|
||||
int index0 = strlen(def_str);
|
||||
while(isspace(ptr[index0])){
|
||||
index0 ++;
|
||||
if(index0 >= sz) break;
|
||||
}
|
||||
if(index0 >= sz) return false;
|
||||
|
||||
int index1 = index0;
|
||||
while(!isspace(ptr[index1])){
|
||||
index1 ++;
|
||||
if(index1 >= sz) break;
|
||||
}
|
||||
if(index1 >= sz) return false;
|
||||
|
||||
src_length_ = index1 - index0;
|
||||
src_data_ = new char[src_length_];
|
||||
memcpy(src_data_,ptr + index0,src_length_);
|
||||
|
||||
index0 = index1;
|
||||
|
||||
int next_flag = 1;
|
||||
while(next_flag){
|
||||
next_flag = 0;
|
||||
while(ptr[index1] != '\n'){
|
||||
index1 ++;
|
||||
if(index1 >= sz) break;
|
||||
}
|
||||
if(index1 >= sz) return false;
|
||||
|
||||
for(int index2 = index1; index2 > index0; index2 --){
|
||||
if(!isspace(ptr[index2])){
|
||||
if(ptr[index2] == '\\'){
|
||||
ptr[index2] = ' ';
|
||||
next_flag = 1;
|
||||
index1 ++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(isspace(ptr[index0])){
|
||||
index0 ++;
|
||||
if(index0 >= sz) break;
|
||||
}
|
||||
if(index0 >= sz) return false;
|
||||
|
||||
dest_length_ = index1 - index0 + 1;
|
||||
dest_data_ = new char[dest_length_];
|
||||
memcpy(dest_data_,ptr + index0,dest_length_);
|
||||
memset(ptr,' ',index1);
|
||||
}
|
||||
else {
|
||||
int index0 = strlen(text_str);
|
||||
while(isspace(ptr[index0])){
|
||||
index0 ++;
|
||||
if(index0 >= sz) break;
|
||||
}
|
||||
if(index0 >= sz) return false;
|
||||
|
||||
int index1 = index0;
|
||||
while(!isspace(ptr[index1])){
|
||||
index1 ++;
|
||||
if(index1 >= sz) break;
|
||||
}
|
||||
if(index1 >= sz) return false;
|
||||
|
||||
src_length_ = index1 - index0;
|
||||
src_data_ = new char[src_length_];
|
||||
memcpy(src_data_,ptr + index0,src_length_);
|
||||
|
||||
while(ptr[index1] != '\n'){
|
||||
index1 ++;
|
||||
if(index1 >= sz) break;
|
||||
}
|
||||
if(++index1 >= sz) return false;
|
||||
|
||||
index0 = index1;
|
||||
|
||||
int next_flag = 1;
|
||||
while(next_flag){
|
||||
while(ptr[index1] != '\n'){
|
||||
if(++index1 >= sz) return false;
|
||||
}
|
||||
index1 += 1;
|
||||
if(index1 >= sz) return false;
|
||||
|
||||
if(ptr[index1] == '#' && !strncmp(ptr + index1,end_str,strlen(end_str))){
|
||||
memset(ptr + index1,' ',strlen(end_str));
|
||||
next_flag = 0;
|
||||
|
||||
index1 --;
|
||||
|
||||
while(ptr[index1] == '\n' || ptr[index1] == '\r')
|
||||
ptr[index1 --] = ' ';
|
||||
|
||||
index1 ++;
|
||||
}
|
||||
}
|
||||
|
||||
if(ptr[index0] != '\"'){
|
||||
dest_length_ = index1 - index0 + 2;
|
||||
dest_data_ = new char[dest_length_];
|
||||
dest_data_[0] = '\"';
|
||||
memcpy(dest_data_ + 1,ptr + index0,dest_length_ - 1);
|
||||
dest_data_[dest_length_ - 1] = '\"';
|
||||
}
|
||||
else {
|
||||
dest_length_ = index1 - index0 + 1;
|
||||
dest_data_ = new char[dest_length_];
|
||||
memcpy(dest_data_,ptr + index0,dest_length_);
|
||||
}
|
||||
memset(ptr,' ',index1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
#ifndef __QDSCR_DEFINE_H__
|
||||
#define __QDSCR_DEFINE_H__
|
||||
|
||||
class qdscrDefineData
|
||||
{
|
||||
public:
|
||||
enum { // flags
|
||||
TEXT_FLAG = 0x01
|
||||
};
|
||||
|
||||
qdscrDefineData(void);
|
||||
~qdscrDefineData(void);
|
||||
|
||||
bool init(char* ptr,int sz);
|
||||
|
||||
int beg_index(void) const { return beg_index_; }
|
||||
void set_beg_index(int idx){ beg_index_ = idx; }
|
||||
|
||||
int end_index(void) const { return end_index_; }
|
||||
void set_end_index(int idx){ end_index_ = idx; }
|
||||
|
||||
int src_length(void) const { return src_length_; }
|
||||
const char* src_data(void) const { return src_data_; }
|
||||
|
||||
int dest_length(void) const { return dest_length_; }
|
||||
const char* dest_data(void) const { return dest_data_; }
|
||||
|
||||
void set_flag(int fl){ flags_ |= fl; }
|
||||
|
||||
private:
|
||||
int flags_;
|
||||
|
||||
int beg_index_;
|
||||
int end_index_;
|
||||
|
||||
int src_length_;
|
||||
char* src_data_;
|
||||
|
||||
int dest_length_;
|
||||
char* dest_data_;
|
||||
};
|
||||
|
||||
typedef std::list<qdscrDefineData*> qdscrDefineDataList;
|
||||
|
||||
#endif /* __QDSCR_DEFINE_H__ */
|
||||
@@ -0,0 +1,47 @@
|
||||
/* ---------------------------- INCLUDE SECTION ----------------------------- */
|
||||
|
||||
#include "qd_precomp.h"
|
||||
|
||||
#include "qdscr_error.h"
|
||||
|
||||
/* ----------------------------- STRUCT SECTION ----------------------------- */
|
||||
/* ----------------------------- EXTERN SECTION ----------------------------- */
|
||||
/* --------------------------- PROTOTYPE SECTION ---------------------------- */
|
||||
/* --------------------------- DEFINITION SECTION --------------------------- */
|
||||
|
||||
void (*qdscr_ErrFnc)(char*) = 0;
|
||||
|
||||
int qdscr_ErrMode = 1;
|
||||
|
||||
void qdscr_SetErrorOutHandler(void (*hfnc)(char*))
|
||||
{
|
||||
qdscr_ErrFnc = hfnc;
|
||||
}
|
||||
|
||||
void qdscr_SetErrorMode(int mode)
|
||||
{
|
||||
qdscr_ErrMode = mode;
|
||||
}
|
||||
|
||||
void qdscr_Error(char* msg)
|
||||
{
|
||||
if(qdscr_ErrFnc)
|
||||
(*qdscr_ErrFnc)(msg);
|
||||
else
|
||||
ErrH.Abort(msg);
|
||||
// printf(msg);
|
||||
|
||||
if(qdscr_ErrMode)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void qdscr_Error(char* msg,int code,char* text)
|
||||
{
|
||||
static char msg_buf[1024];
|
||||
if(text)
|
||||
sprintf(msg_buf,msg,code,text);
|
||||
else
|
||||
sprintf(msg_buf,msg,code);
|
||||
|
||||
qdscr_Error(msg_buf);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user