init commit

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

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.
+224
View File
@@ -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();
}
+11
View File
@@ -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__ */
+170
View File
@@ -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__ */
+376
View File
@@ -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,"&amp;");
} 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,"&lt;");
} 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,"&gt;");
} 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,"&quot;");
} 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,"&#039;");
} while(pos != std::string::npos);
return conv_str.c_str();
}
+344
View File
@@ -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__ */
+11
View File
@@ -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__ */
+404
View File
@@ -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 */
+81
View File
@@ -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__ */
+141
View File
@@ -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__ */
+105
View File
@@ -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 */
+113
View File
@@ -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

+170
View File
@@ -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.
+204
View File
@@ -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__
+17
View File
@@ -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__
+64
View File
@@ -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;
}
+50
View File
@@ -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__ */
+181
View File
@@ -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;
}
+99
View File
@@ -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__ */
+188
View File
@@ -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
+11
View File
@@ -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__ */
+484
View File
@@ -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));
}
+132
View File
@@ -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__ */
+127
View File
@@ -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
+533
View File
@@ -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
+184
View File
@@ -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;
}
+63
View File
@@ -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__ */
+221
View File
@@ -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;
}
+140
View File
@@ -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 */
+36
View File
@@ -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;
}
+50
View File
@@ -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__ */
+54
View File
@@ -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;
}
+99
View File
@@ -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__ */
+915
View File
@@ -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();
}
+127
View File
@@ -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__ */
+204
View File
@@ -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;
}
+75
View File
@@ -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;
}
+123
View File
@@ -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__ */
+58
View File
@@ -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__ */
+219
View File
@@ -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;
}
+6
View File
@@ -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__ */
+50
View File
@@ -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;
}
+56
View File
@@ -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__ */
+355
View File
@@ -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 */
+70
View File
@@ -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__ */
+71
View File
@@ -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;
}
}
+50
View File
@@ -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__ */
+50
View File
@@ -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();
}
+43
View File
@@ -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__ */
+75
View File
@@ -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;
}
+46
View File
@@ -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"));
}
+221
View File
@@ -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__ */
+153
View File
@@ -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.
+119
View File
@@ -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

+251
View File
@@ -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
+72
View File
@@ -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
+209
View File
@@ -0,0 +1,209 @@
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="autorun"
SccProjectName="&quot;$/qdEngine&quot;, 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>
+16
View File
@@ -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__ */
+151
View File
@@ -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
+284
View File
@@ -0,0 +1,284 @@
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="ParserDLL"
SccProjectName="&quot;$/qdEngine&quot;, 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