Merge branch 'master' of github.com:FacialTurd/PowderToypp
This commit is contained in:
commit
058a2edd75
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
54
.gitignore
vendored
Normal file
54
.gitignore
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
*nohup.out
|
||||
*.swp
|
||||
*.o
|
||||
*.exe
|
||||
*.user
|
||||
*.dll
|
||||
*.a
|
||||
*.la
|
||||
*~
|
||||
*.pref
|
||||
stdout.txt
|
||||
stderr.txt
|
||||
build/*
|
||||
stamps/*
|
||||
Saves/*
|
||||
generated/*
|
||||
includes/*
|
||||
generate
|
||||
Makefile.me
|
||||
*.xcodeproj
|
||||
.DS_Store
|
||||
*.plist
|
||||
*.lproj
|
||||
*.vcxproj*
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.user
|
||||
*.filter
|
||||
*.sln
|
||||
*.suo
|
||||
*.manifest
|
||||
*.manifest.res
|
||||
*manifest.rc
|
||||
*res.res
|
||||
*.obj
|
||||
*.tlog
|
||||
*.lib
|
||||
*.ipch
|
||||
*.log
|
||||
*.lastbuildstate
|
||||
*.unsuccessfulbuild
|
||||
*.pdb
|
||||
*.sublime-*
|
||||
*.project
|
||||
*.cproject
|
||||
*.settings
|
||||
config.log
|
||||
*.sconsign.dblite
|
||||
*.sconf_temp
|
||||
*.gch
|
||||
*.pyc
|
||||
site_scons/site_tools/mfprogram/*.pyc
|
||||
site_scons/site_tools/gch/*.pyc
|
||||
others*
|
19
Changelog.txt
Normal file
19
Changelog.txt
Normal file
@ -0,0 +1,19 @@
|
||||
- Special brush types
|
||||
- Special brush delete
|
||||
- LOVE
|
||||
- LOLZ
|
||||
- Property edit
|
||||
- Saving, loading, thumbnailing, etc
|
||||
- HEAT/COOL
|
||||
- Streamlines
|
||||
- Grid
|
||||
- Sign moving
|
||||
- Electron fancyness with glass, fire_r-g-b now out of scope
|
||||
- Grav fancyness, use current frame index to determine colour, not globals!
|
||||
- Emp flash
|
||||
- Stickman HP
|
||||
|
||||
To do:
|
||||
See TODO's
|
||||
Char * and string, hmm....
|
||||
Vectors for things like signs, stamp list, etc where appropriate
|
674
LICENSE
Normal file
674
LICENSE
Normal file
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://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 <http://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
|
||||
<http://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
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
99
README
Normal file
99
README
Normal file
@ -0,0 +1,99 @@
|
||||
The Powder Toy - November 2012
|
||||
|
||||
Get the latest version here: http://powdertoy.co.uk/Download.html
|
||||
|
||||
To use online features such as saving, you need to register at: http://powdertoy.co.uk/Register.html
|
||||
|
||||
|
||||
Have you ever wanted to blow something up? Or maybe you always dreamt of operating an atomic power plant? Do you have a will to develop your own CPU? The Powder Toy lets you to do all of these, and even more!
|
||||
|
||||
The Powder Toy is a free physics sandbox game, which simulates air pressure and velocity, heat, gravity and a countless number of interactions between different substances! The game provides you with various building materials, liquids, gases and electronic components which can be used to construct complex machines, guns, bombs, realistic terrains and almost anything else. You can then mine them and watch cool explosions, add intricate wirings, play with little stickmen or operate your machine. You can browse and play thousands of different saves made by the community or upload your own – we welcome your creations!
|
||||
|
||||
There is a Lua API – you can automate your work or even make plugins for the game. The Powder Toy is free and the source code is distributed under the GNU General Public License, so you can modify the game yourself or help with development. Tpt is compiled using scons.
|
||||
|
||||
|
||||
Thanks:
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Stanislaw K Skowronek - Designed the original
|
||||
Simon Robertshaw
|
||||
Skresanov Savely
|
||||
cracker64
|
||||
Catelite
|
||||
Bryan Hoyle
|
||||
Nathan Cousins
|
||||
jacksonmj
|
||||
Lieuwe Mosch
|
||||
Anthony Boot
|
||||
Matthew Miller
|
||||
MaksProg
|
||||
jacob1
|
||||
|
||||
|
||||
Instructions:
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Click on the elements with the mouse and draw in the field, like in MS Paint. The rest of the game is learning what happens next.
|
||||
|
||||
|
||||
Controls:
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
||||
TAB Switch between circle/square/triangle brush
|
||||
Space Pause
|
||||
Q Quit
|
||||
Esc Quit
|
||||
Z Zoom
|
||||
S Save stamp (+ Ctrl when STK2 is out)
|
||||
L Load last saved stamp
|
||||
K Stamp library
|
||||
1-9 Set view mode
|
||||
P Save screenshot to .png
|
||||
F Pause and go to next frame
|
||||
G Increase grid size
|
||||
Shift + G Decrease grid size
|
||||
H Show/Hide HUD
|
||||
Ctrl + H Show intro text
|
||||
F1 Show intro text
|
||||
D Debug mode (+ Ctrl when STK2 is out)
|
||||
I Invert Pressure and Velocity map
|
||||
W Toggle gravity modes (+ Ctrl when STK2 is out)
|
||||
Y Toggle air modes
|
||||
Ctrl + B Toggle decorations on/off
|
||||
U Toggle ambient heat on/off
|
||||
Ctrl + I Install powder toy, for loading saves/stamps by double clicking
|
||||
~ Console
|
||||
= Reset pressure and velocity map
|
||||
Ctrl + = Reset Electricity
|
||||
[ Decrease brush size
|
||||
] Increase brush size
|
||||
Alt + [ Decrease brush size by 1
|
||||
Alt + ] Increase brush size by 1
|
||||
|
||||
Ctrl + C/V/X Copy/Paste/Cut
|
||||
Ctrl + Z Undo
|
||||
Ctrl + Cursor drag Rectangle
|
||||
Shift + Cursor drag Line
|
||||
Middle click Sample element
|
||||
Alt + Left click Sample element
|
||||
Mouse scroll Change brush size
|
||||
Ctrl + Mouse scroll Change vertical brush size
|
||||
Shift + Mouse scroll Change horizontal brush size
|
||||
Shift + Ctrl + R Horizontal mirror for selected area
|
||||
Ctrl + R Rotate selected area counterclockwise
|
||||
|
||||
Only the left Ctrl, Shift, and Alt buttons are enabled to work, not the ones on the right
|
||||
|
||||
|
||||
Command Line:
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
scale:1 Normal window resolution
|
||||
scale:2 Doubled window resolution
|
||||
kiosk Fullscreen mode
|
||||
proxy:server[:port] Proxy server to use [Example: proxy:wwwcache.lancs.ac.uk:8080]
|
||||
open <file> Opens the file as a stamp or game save
|
||||
ddir <directory> Directory used for saving stamps and preferences
|
||||
ptsave:<save id>#<name(Optional)> (ex. ptsave:2198#Destroyable_city_5_wth_metro~dima-gord)
|
||||
|
296
SConscript
Normal file
296
SConscript
Normal file
@ -0,0 +1,296 @@
|
||||
import os, sys, subprocess, time
|
||||
|
||||
|
||||
##Fix for long command line - http://scons.org/wiki/LongCmdLinesOnWin32
|
||||
class ourSpawn:
|
||||
def ourspawn(self, sh, escape, cmd, args, env):
|
||||
newargs = ' '.join(args[1:])
|
||||
cmdline = cmd + " " + newargs
|
||||
startupinfo = subprocess.STARTUPINFO()
|
||||
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env)
|
||||
data, err = proc.communicate()
|
||||
rv = proc.wait()
|
||||
if rv:
|
||||
print "====="
|
||||
print err
|
||||
print "====="
|
||||
return rv
|
||||
|
||||
def SetupSpawn( env ):
|
||||
if sys.platform == 'win32':
|
||||
buf = ourSpawn()
|
||||
buf.ourenv = env
|
||||
env['SPAWN'] = buf.ourspawn
|
||||
|
||||
AddOption('--opengl',dest="opengl",action='store_true',default=False,help="Build with OpenGL interface support.")
|
||||
AddOption('--opengl-renderer',dest="opengl-renderer",action='store_true',default=False,help="Build with OpenGL renderer support. (requires --opengl)")
|
||||
AddOption('--renderer',dest="renderer",action='store_true',default=False,help="Save renderer")
|
||||
AddOption('--win',dest="win",action='store_true',default=False,help="Windows platform target.")
|
||||
AddOption('--lin',dest="lin",action='store_true',default=False,help="Linux platform target")
|
||||
AddOption('--macosx',dest="macosx",action='store_true',default=False,help="Mac OS X platform target")
|
||||
AddOption('--64bit',dest="_64bit",action='store_true',default=False,help="64-bit platform target")
|
||||
AddOption('--static',dest="static",action="store_true",default=False,help="Static linking, reduces external library dependancies but increased file size")
|
||||
AddOption('--pthreadw32-static',dest="ptw32-static",action="store_true",default=False,help="Use PTW32_STATIC_LIB for pthreadw32 headers")
|
||||
AddOption('--release',dest="release",action='store_true',default=False,help="Enable optimisations (Will slow down compiling)")
|
||||
AddOption('--lua-dir',dest="lua-dir",default=False,help="Directory for lua includes")
|
||||
AddOption('--sdl-dir',dest="sdl-dir",default=False,help="Directory for SDL includes")
|
||||
AddOption('--tool',dest="toolprefix",default=False,help="Prefix")
|
||||
AddOption('--sse',dest="sse",action='store_true',default=False,help="Enable SSE optimisations")
|
||||
AddOption('--sse2',dest="sse2",action='store_true',default=False,help="Enable SSE2 optimisations")
|
||||
AddOption('--sse3',dest="sse3",action='store_true',default=False,help="Enable SSE3 optimisations")
|
||||
AddOption('--x86',dest="x86",action='store_true',default=True,help="Target Intel x86 platform")
|
||||
|
||||
AddOption('--debugging', dest="debug", action="store_true", default=False, help="Enable debug options")
|
||||
AddOption('--beta',dest="beta",action='store_true',default=False,help="Beta build.")
|
||||
AddOption('--save-version',dest="save-version",default=False,help="Save version.")
|
||||
AddOption('--minor-version',dest="minor-version",default=False,help="Minor version.")
|
||||
AddOption('--build-number',dest="build-number",default=False,help="Build number.")
|
||||
AddOption('--snapshot',dest="snapshot",action='store_true',default=False,help="Snapshot build.")
|
||||
AddOption('--snapshot-id',dest="snapshot-id",default=False,help="Snapshot build ID.")
|
||||
|
||||
AddOption('--aao', dest="everythingAtOnce", action='store_true', default=False, help="Compile the whole game without generating intermediate objects (very slow), enable this when using compilers like clang or mscc that don't support -fkeep-inline-functions")
|
||||
|
||||
if((not GetOption('lin')) and (not GetOption('win')) and (not GetOption('macosx'))):
|
||||
print "You must specify a platform to target"
|
||||
raise SystemExit(1)
|
||||
|
||||
if(GetOption('win')):
|
||||
env = Environment(tools = ['mingw'], ENV = os.environ)
|
||||
else:
|
||||
env = Environment(tools = ['default'], ENV = os.environ)
|
||||
|
||||
if GetOption("toolprefix"):
|
||||
env['CC'] = GetOption("toolprefix")+env['CC']
|
||||
env['CXX'] = GetOption("toolprefix")+env['CXX']
|
||||
if GetOption('win'):
|
||||
env['RC'] = GetOption("toolprefix")+env['RC']
|
||||
|
||||
#Check for headers and libraries
|
||||
if not GetOption("macosx"):
|
||||
conf = Configure(env)
|
||||
|
||||
try:
|
||||
env.ParseConfig('sdl-config --cflags')
|
||||
env.ParseConfig('sdl-config --libs')
|
||||
except:
|
||||
conf.CheckLib("SDL")
|
||||
if(GetOption("sdl-dir")):
|
||||
if not conf.CheckCHeader(GetOption("sdl-dir") + '/SDL.h'):
|
||||
print "sdl headers not found or not installed"
|
||||
raise SystemExit(1)
|
||||
else:
|
||||
env.Append(CPPPATH=GetOption("sdl-dir"))
|
||||
|
||||
#Find correct lua include dir
|
||||
try:
|
||||
env.ParseConfig('pkg-config --cflags lua5.1')
|
||||
except:
|
||||
if(GetOption("lua-dir")):
|
||||
if not conf.CheckCHeader(GetOption("lua-dir") + '/lua.h'):
|
||||
print "lua5.1 headers not found or not installed"
|
||||
raise SystemExit(1)
|
||||
else:
|
||||
env.Append(CPPPATH=GetOption("lua-dir"))
|
||||
|
||||
#Check for FFT lib
|
||||
if not conf.CheckLib('fftw3f') and not conf.CheckLib('fftw3f-3'):
|
||||
print "libfftw3f not found or not installed"
|
||||
raise SystemExit(1)
|
||||
|
||||
#Check for Bzip lib
|
||||
if not conf.CheckLib('bz2'):
|
||||
print "libbz2 not found or not installed"
|
||||
raise SystemExit(1)
|
||||
|
||||
#Check for zlib
|
||||
if not conf.CheckLib('z'):
|
||||
print "libz not found or not installed"
|
||||
raise SystemExit(1)
|
||||
|
||||
if not conf.CheckCHeader("bzlib.h"):
|
||||
print "bzip2 headers not found"
|
||||
raise SystemExit(1)
|
||||
|
||||
#Check for Lua lib
|
||||
if not GetOption("macosx"):
|
||||
if not conf.CheckLib('lua') and not conf.CheckLib('lua5.1') and not conf.CheckLib('lua51') and not conf.CheckLib('lua-5.1'):
|
||||
print "liblua not found or not installed"
|
||||
raise SystemExit(1)
|
||||
|
||||
env = conf.Finish();
|
||||
else:
|
||||
env.Append(LIBS=['z', 'bz2', 'fftw3f'])
|
||||
|
||||
env.Append(CPPPATH=['src/', 'data/', 'generated/'])
|
||||
env.Append(CCFLAGS=['-w', '-std=c++98', '-fkeep-inline-functions'])
|
||||
env.Append(LIBS=['pthread', 'm'])
|
||||
env.Append(CPPDEFINES=["LUACONSOLE", "GRAVFFT", "_GNU_SOURCE", "USE_STDINT", "_POSIX_C_SOURCE=200112L"])
|
||||
|
||||
if GetOption("ptw32-static"):
|
||||
env.Append(CPPDEFINES=['PTW32_STATIC_LIB']);
|
||||
|
||||
if(GetOption('static')):
|
||||
env.Append(LINKFLAGS=['-static-libgcc'])
|
||||
|
||||
if(GetOption('renderer')):
|
||||
env.Append(CPPDEFINES=['RENDERER'])
|
||||
else:
|
||||
env.Append(CPPDEFINES=["USE_SDL"])
|
||||
|
||||
if(GetOption('win')):
|
||||
openGLLibs = ['opengl32', 'glew32']
|
||||
env.Prepend(LIBS=['mingw32', 'ws2_32', 'SDLmain', 'regex'])
|
||||
env.Append(CCFLAGS=['-std=gnu++98'])
|
||||
env.Append(LIBS=['winmm', 'gdi32'])
|
||||
env.Append(CPPDEFINES=["WIN"])
|
||||
env.Append(LINKFLAGS=['-mwindows'])
|
||||
if(GetOption('_64bit')):
|
||||
env.Append(CPPDEFINES=['__CRT__NO_INLINE'])
|
||||
env.Append(LINKFLAGS=['-Wl,--stack=16777216'])
|
||||
if(GetOption('lin')):
|
||||
if(GetOption('opengl')):
|
||||
env.ParseConfig('pkg-config --libs glew gl glu')
|
||||
openGLLibs = ['GL']
|
||||
env.Append(LIBS=['X11', 'rt'])
|
||||
env.Append(CPPDEFINES=["LIN"])
|
||||
if GetOption('_64bit'):
|
||||
env.Append(LINKFAGS=['-m64'])
|
||||
env.Append(CCFLAGS=['-m64'])
|
||||
else:
|
||||
env.Append(LINKFLAGS=['-m32'])
|
||||
env.Append(CCFLAGS=['-m32'])
|
||||
if(GetOption('macosx')):
|
||||
env.Append(CPPDEFINES=["MACOSX"])
|
||||
env.Append(CCFLAGS=['-I/Library/Frameworks/SDL.framework/Headers'])
|
||||
env.Append(CCFLAGS=['-I/Library/Frameworks/Lua.framework/Headers'])
|
||||
env.Append(LINKFLAGS=['-lfftw3f'])
|
||||
env.Append(LINKFLAGS=['-framework'])
|
||||
env.Append(LINKFLAGS=['SDL'])
|
||||
env.Append(LINKFLAGS=['-framework'])
|
||||
env.Append(LINKFLAGS=['Lua'])
|
||||
env.Append(LINKFLAGS=['-framework']);
|
||||
env.Append(LINKFLAGS=['Cocoa'])
|
||||
#env.Append(LINKFLAGS=['-framework SDL'])
|
||||
#env.Append(LINKFLAGS=['-framework Lua'])
|
||||
#env.Append(LINKFLAGS=['-framework Cocoa'])
|
||||
if GetOption('_64bit'):
|
||||
env.Append(LINKFAGS=['-m64'])
|
||||
env.Append(CCFLAGS=['-m64'])
|
||||
else:
|
||||
env.Append(LINKFLAGS=['-m32'])
|
||||
env.Append(CCFLAGS=['-m32'])
|
||||
|
||||
if GetOption('_64bit'):
|
||||
env.Append(CPPDEFINES=["_64BIT"])
|
||||
|
||||
if(GetOption('beta')):
|
||||
env.Append(CPPDEFINES='BETA')
|
||||
|
||||
|
||||
if(not GetOption('snapshot') and not GetOption('beta') and not GetOption('release')):
|
||||
env.Append(CPPDEFINES='SNAPSHOT_ID=0')
|
||||
env.Append(CPPDEFINES='SNAPSHOT')
|
||||
elif(GetOption('snapshot') or GetOption('snapshot-id')):
|
||||
if(GetOption('snapshot-id')):
|
||||
env.Append(CPPDEFINES=['SNAPSHOT_ID=' + GetOption('snapshot-id')])
|
||||
else:
|
||||
env.Append(CPPDEFINES=['SNAPSHOT_ID=' + str(int(time.time()))])
|
||||
env.Append(CPPDEFINES='SNAPSHOT')
|
||||
|
||||
if(GetOption('save-version')):
|
||||
env.Append(CPPDEFINES=['SAVE_VERSION=' + GetOption('save-version')])
|
||||
|
||||
if(GetOption('minor-version')):
|
||||
env.Append(CPPDEFINES=['MINOR_VERSION=' + GetOption('minor-version')])
|
||||
|
||||
if(GetOption('build-number')):
|
||||
env.Append(CPPDEFINES=['BUILD_NUM=' + GetOption('build-number')])
|
||||
|
||||
if(GetOption('x86')):
|
||||
env.Append(CPPDEFINES='X86')
|
||||
|
||||
if(GetOption('debug')):
|
||||
env.Append(CPPDEFINES='DEBUG')
|
||||
env.Append(CCFLAGS='-g')
|
||||
|
||||
if(GetOption('sse')):
|
||||
env.Append(CCFLAGS='-msse')
|
||||
env.Append(CPPDEFINES='X86_SSE')
|
||||
|
||||
if(GetOption('sse2')):
|
||||
env.Append(CCFLAGS='-msse2')
|
||||
env.Append(CPPDEFINES='X86_SSE2')
|
||||
|
||||
if(GetOption('sse3')):
|
||||
env.Append(CCFLAGS='-msse3')
|
||||
env.Append(CPPDEFINES='X86_SSE3')
|
||||
|
||||
if(GetOption('opengl')):
|
||||
env.Append(CPPDEFINES=["OGLI", "PIX32OGL"])
|
||||
env.Append(LIBS=openGLLibs)
|
||||
|
||||
if(GetOption('opengl') and GetOption('opengl-renderer')):
|
||||
env.Append(CPPDEFINES=["OGLR"])
|
||||
elif(GetOption('opengl-renderer')):
|
||||
print "opengl-renderer requires opengl"
|
||||
raise SystemExit(1)
|
||||
|
||||
sources=Glob("src/*.cpp")
|
||||
if(GetOption('macosx')):
|
||||
sources +=["SDLMain.m"]
|
||||
if(GetOption('win')):
|
||||
sources += env.RES('resources/powder-res.rc')
|
||||
sources+=Glob("src/*/*.cpp")
|
||||
sources+=Glob("src/simulation/elements/*.cpp")
|
||||
sources+=Glob("src/simulation/tools/*.cpp")
|
||||
|
||||
if(GetOption('win')):
|
||||
sources = filter(lambda source: str(source) != 'src/simulation/Gravity.cpp', sources)
|
||||
|
||||
SetupSpawn(env)
|
||||
|
||||
programName = "powder"
|
||||
|
||||
if(GetOption('renderer')):
|
||||
programName = "render"
|
||||
|
||||
if(GetOption('win')):
|
||||
if(GetOption('renderer')):
|
||||
programName = "Render"
|
||||
else:
|
||||
programName = "Powder"
|
||||
|
||||
if(GetOption('_64bit')):
|
||||
programName += "64"
|
||||
|
||||
if(not (GetOption('sse2') or GetOption('sse3'))):
|
||||
programName += "-legacy"
|
||||
|
||||
if(GetOption('macosx')):
|
||||
programName += "-x"
|
||||
|
||||
if(GetOption('win')):
|
||||
programName += ".exe"
|
||||
|
||||
if(GetOption('release')):
|
||||
if GetOption('macosx'):
|
||||
env.Append(CCFLAGS=['-O3', '-ftree-vectorize', '-funsafe-math-optimizations', '-ffast-math', '-fomit-frame-pointer'])
|
||||
else:
|
||||
env.Append(CCFLAGS=['-O3', '-ftree-vectorize', '-funsafe-math-optimizations', '-ffast-math', '-fomit-frame-pointer', '-funsafe-loop-optimizations', '-Wunsafe-loop-optimizations'])
|
||||
|
||||
if(GetOption('win')):
|
||||
envCopy = env.Clone()
|
||||
envCopy.Append(CCFLAGS=['-mincoming-stack-boundary=2'])
|
||||
sources+=envCopy.Object('src/simulation/Gravity.cpp')
|
||||
|
||||
env.Command(['generated/ElementClasses.cpp', 'generated/ElementClasses.h'], Glob('src/simulation/elements/*.cpp'), "python2 generator.py elements $TARGETS $SOURCES")
|
||||
sources+=Glob("generated/ElementClasses.cpp")
|
||||
|
||||
env.Command(['generated/ToolClasses.cpp', 'generated/ToolClasses.h'], Glob('src/simulation/tools/*.cpp'), "python2 generator.py tools $TARGETS $SOURCES")
|
||||
sources+=Glob("generated/ToolClasses.cpp")
|
||||
|
||||
env.Decider('MD5')
|
||||
t=env.Program(target=programName, source=sources)
|
||||
Default(t)
|
1
SConstruct
Normal file
1
SConstruct
Normal file
@ -0,0 +1 @@
|
||||
SConscript('SConscript', variant_dir='build')
|
16
SDLMain.h
Normal file
16
SDLMain.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
|
||||
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
|
||||
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
|
||||
|
||||
Feel free to customize this file to suit your needs
|
||||
*/
|
||||
|
||||
#ifndef _SDLMain_h_
|
||||
#define _SDLMain_h_
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface SDLMain : NSObject
|
||||
@end
|
||||
|
||||
#endif /* _SDLMain_h_ */
|
381
SDLMain.m
Normal file
381
SDLMain.m
Normal file
@ -0,0 +1,381 @@
|
||||
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
|
||||
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
|
||||
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
|
||||
|
||||
Feel free to customize this file to suit your needs
|
||||
*/
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDLMain.h"
|
||||
#include <sys/param.h> /* for MAXPATHLEN */
|
||||
#include <unistd.h>
|
||||
|
||||
/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
|
||||
but the method still is there and works. To avoid warnings, we declare
|
||||
it ourselves here. */
|
||||
@interface NSApplication(SDL_Missing_Methods)
|
||||
- (void)setAppleMenu:(NSMenu *)menu;
|
||||
@end
|
||||
|
||||
/* Use this flag to determine whether we use SDLMain.nib or not */
|
||||
#define SDL_USE_NIB_FILE 0
|
||||
|
||||
/* Use this flag to determine whether we use CPS (docking) or not */
|
||||
#define SDL_USE_CPS 1
|
||||
#ifdef SDL_USE_CPS
|
||||
/* Portions of CPS.h */
|
||||
typedef struct CPSProcessSerNum
|
||||
{
|
||||
UInt32 lo;
|
||||
UInt32 hi;
|
||||
} CPSProcessSerNum;
|
||||
|
||||
extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
|
||||
extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
|
||||
extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
|
||||
|
||||
#endif /* SDL_USE_CPS */
|
||||
|
||||
static int gArgc;
|
||||
static char **gArgv;
|
||||
static BOOL gFinderLaunch;
|
||||
static BOOL gCalledAppMainline = FALSE;
|
||||
|
||||
static NSString *getApplicationName(void)
|
||||
{
|
||||
const NSDictionary *dict;
|
||||
NSString *appName = 0;
|
||||
|
||||
/* Determine the application name */
|
||||
dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
|
||||
if (dict)
|
||||
appName = [dict objectForKey: @"CFBundleName"];
|
||||
|
||||
if (![appName length])
|
||||
appName = [[NSProcessInfo processInfo] processName];
|
||||
|
||||
return appName;
|
||||
}
|
||||
|
||||
#if SDL_USE_NIB_FILE
|
||||
/* A helper category for NSString */
|
||||
@interface NSString (ReplaceSubString)
|
||||
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
|
||||
@end
|
||||
#endif
|
||||
|
||||
@interface NSApplication (SDLApplication)
|
||||
@end
|
||||
|
||||
@implementation NSApplication (SDLApplication)
|
||||
/* Invoked from the Quit menu item */
|
||||
- (void)terminate:(id)sender
|
||||
{
|
||||
/* Post a SDL_QUIT event */
|
||||
SDL_Event event;
|
||||
event.type = SDL_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
@end
|
||||
|
||||
/* The main class of the application, the application's delegate */
|
||||
@implementation SDLMain
|
||||
|
||||
/* Set the working directory to the .app's parent directory */
|
||||
- (void) setupWorkingDirectory:(BOOL)shouldChdir
|
||||
{
|
||||
if (shouldChdir)
|
||||
{
|
||||
char parentdir[MAXPATHLEN];
|
||||
CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
|
||||
CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
|
||||
if (CFURLGetFileSystemRepresentation(url2, 1, (UInt8 *)parentdir, MAXPATHLEN)) {
|
||||
chdir(parentdir); /* chdir to the binary app's parent */
|
||||
}
|
||||
CFRelease(url);
|
||||
CFRelease(url2);
|
||||
}
|
||||
}
|
||||
|
||||
#if SDL_USE_NIB_FILE
|
||||
|
||||
/* Fix menu to contain the real app name instead of "SDL App" */
|
||||
- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
|
||||
{
|
||||
NSRange aRange;
|
||||
NSEnumerator *enumerator;
|
||||
NSMenuItem *menuItem;
|
||||
|
||||
aRange = [[aMenu title] rangeOfString:@"SDL App"];
|
||||
if (aRange.length != 0)
|
||||
[aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
|
||||
|
||||
enumerator = [[aMenu itemArray] objectEnumerator];
|
||||
while ((menuItem = [enumerator nextObject]))
|
||||
{
|
||||
aRange = [[menuItem title] rangeOfString:@"SDL App"];
|
||||
if (aRange.length != 0)
|
||||
[menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
|
||||
if ([menuItem hasSubmenu])
|
||||
[self fixMenu:[menuItem submenu] withAppName:appName];
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void setApplicationMenu(void)
|
||||
{
|
||||
/* warning: this code is very odd */
|
||||
NSMenu *appleMenu;
|
||||
NSMenuItem *menuItem;
|
||||
NSString *title;
|
||||
NSString *appName;
|
||||
|
||||
appName = getApplicationName();
|
||||
appleMenu = [[NSMenu alloc] initWithTitle:@""];
|
||||
|
||||
/* Add menu items */
|
||||
title = [@"About " stringByAppendingString:appName];
|
||||
[appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
|
||||
|
||||
[appleMenu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
title = [@"Hide " stringByAppendingString:appName];
|
||||
[appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
|
||||
|
||||
menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
|
||||
[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
|
||||
|
||||
[appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
|
||||
|
||||
[appleMenu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
title = [@"Quit " stringByAppendingString:appName];
|
||||
[appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
|
||||
|
||||
|
||||
/* Put menu into the menubar */
|
||||
menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
|
||||
[menuItem setSubmenu:appleMenu];
|
||||
[[NSApp mainMenu] addItem:menuItem];
|
||||
|
||||
/* Tell the application object that this is now the application menu */
|
||||
[NSApp setAppleMenu:appleMenu];
|
||||
|
||||
/* Finally give up our references to the objects */
|
||||
[appleMenu release];
|
||||
[menuItem release];
|
||||
}
|
||||
|
||||
/* Create a window menu */
|
||||
static void setupWindowMenu(void)
|
||||
{
|
||||
NSMenu *windowMenu;
|
||||
NSMenuItem *windowMenuItem;
|
||||
NSMenuItem *menuItem;
|
||||
|
||||
windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
|
||||
|
||||
/* "Minimize" item */
|
||||
menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
|
||||
[windowMenu addItem:menuItem];
|
||||
[menuItem release];
|
||||
|
||||
/* Put menu into the menubar */
|
||||
windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
|
||||
[windowMenuItem setSubmenu:windowMenu];
|
||||
[[NSApp mainMenu] addItem:windowMenuItem];
|
||||
|
||||
/* Tell the application object that this is now the window menu */
|
||||
[NSApp setWindowsMenu:windowMenu];
|
||||
|
||||
/* Finally give up our references to the objects */
|
||||
[windowMenu release];
|
||||
[windowMenuItem release];
|
||||
}
|
||||
|
||||
/* Replacement for NSApplicationMain */
|
||||
static void CustomApplicationMain (int argc, char **argv)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
SDLMain *sdlMain;
|
||||
|
||||
/* Ensure the application object is initialised */
|
||||
[NSApplication sharedApplication];
|
||||
|
||||
#ifdef SDL_USE_CPS
|
||||
{
|
||||
CPSProcessSerNum PSN;
|
||||
/* Tell the dock about us */
|
||||
if (!CPSGetCurrentProcess(&PSN))
|
||||
if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
|
||||
if (!CPSSetFrontProcess(&PSN))
|
||||
[NSApplication sharedApplication];
|
||||
}
|
||||
#endif /* SDL_USE_CPS */
|
||||
|
||||
/* Set up the menubar */
|
||||
[NSApp setMainMenu:[[NSMenu alloc] init]];
|
||||
setApplicationMenu();
|
||||
setupWindowMenu();
|
||||
|
||||
/* Create SDLMain and make it the app delegate */
|
||||
sdlMain = [[SDLMain alloc] init];
|
||||
[NSApp setDelegate:sdlMain];
|
||||
|
||||
/* Start the main event loop */
|
||||
[NSApp run];
|
||||
|
||||
[sdlMain release];
|
||||
[pool release];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Catch document open requests...this lets us notice files when the app
|
||||
* was launched by double-clicking a document, or when a document was
|
||||
* dragged/dropped on the app's icon. You need to have a
|
||||
* CFBundleDocumentsType section in your Info.plist to get this message,
|
||||
* apparently.
|
||||
*
|
||||
* Files are added to gArgv, so to the app, they'll look like command line
|
||||
* arguments. Previously, apps launched from the finder had nothing but
|
||||
* an argv[0].
|
||||
*
|
||||
* This message may be received multiple times to open several docs on launch.
|
||||
*
|
||||
* This message is ignored once the app's mainline has been called.
|
||||
*/
|
||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
|
||||
{
|
||||
const char *temparg;
|
||||
size_t arglen;
|
||||
char *arg;
|
||||
char **newargv;
|
||||
|
||||
if (!gFinderLaunch) /* MacOS is passing command line args. */
|
||||
return FALSE;
|
||||
|
||||
if (gCalledAppMainline) /* app has started, ignore this document. */
|
||||
return FALSE;
|
||||
|
||||
temparg = [filename UTF8String];
|
||||
arglen = SDL_strlen(temparg) + 1;
|
||||
arg = (char *) SDL_malloc(arglen);
|
||||
if (arg == NULL)
|
||||
return FALSE;
|
||||
|
||||
newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
|
||||
if (newargv == NULL)
|
||||
{
|
||||
SDL_free(arg);
|
||||
return FALSE;
|
||||
}
|
||||
gArgv = newargv;
|
||||
|
||||
SDL_strlcpy(arg, temparg, arglen);
|
||||
gArgv[gArgc++] = arg;
|
||||
gArgv[gArgc] = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Called when the internal event loop has just started running */
|
||||
- (void) applicationDidFinishLaunching: (NSNotification *) note
|
||||
{
|
||||
int status;
|
||||
|
||||
/* Set the working directory to the .app's parent directory */
|
||||
[self setupWorkingDirectory:gFinderLaunch];
|
||||
|
||||
#if SDL_USE_NIB_FILE
|
||||
/* Set the main menu to contain the real app name instead of "SDL App" */
|
||||
[self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
|
||||
#endif
|
||||
|
||||
/* Hand off to main application code */
|
||||
gCalledAppMainline = TRUE;
|
||||
status = SDL_main (gArgc, gArgv);
|
||||
|
||||
/* We're done, thank you for playing */
|
||||
exit(status);
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSString (ReplaceSubString)
|
||||
|
||||
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
|
||||
{
|
||||
unsigned int bufferSize;
|
||||
unsigned int selfLen = [self length];
|
||||
unsigned int aStringLen = [aString length];
|
||||
unichar *buffer;
|
||||
NSRange localRange;
|
||||
NSString *result;
|
||||
|
||||
bufferSize = selfLen + aStringLen - aRange.length;
|
||||
buffer = (unichar *)NSAllocateMemoryPages(bufferSize*sizeof(unichar));
|
||||
|
||||
/* Get first part into buffer */
|
||||
localRange.location = 0;
|
||||
localRange.length = aRange.location;
|
||||
[self getCharacters:buffer range:localRange];
|
||||
|
||||
/* Get middle part into buffer */
|
||||
localRange.location = 0;
|
||||
localRange.length = aStringLen;
|
||||
[aString getCharacters:(buffer+aRange.location) range:localRange];
|
||||
|
||||
/* Get last part into buffer */
|
||||
localRange.location = aRange.location + aRange.length;
|
||||
localRange.length = selfLen - localRange.location;
|
||||
[self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
|
||||
|
||||
/* Build output string */
|
||||
result = [NSString stringWithCharacters:buffer length:bufferSize];
|
||||
|
||||
NSDeallocateMemoryPages(buffer, bufferSize);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
#ifdef main
|
||||
# undef main
|
||||
#endif
|
||||
|
||||
|
||||
/* Main entry point to executable - should *not* be SDL_main! */
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* Copy the arguments into a global variable */
|
||||
/* This is passed if we are launched by double-clicking */
|
||||
if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
|
||||
gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
|
||||
gArgv[0] = argv[0];
|
||||
gArgv[1] = NULL;
|
||||
gArgc = 1;
|
||||
gFinderLaunch = YES;
|
||||
} else {
|
||||
int i;
|
||||
gArgc = argc;
|
||||
gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
|
||||
for (i = 0; i <= argc; i++)
|
||||
gArgv[i] = argv[i];
|
||||
gFinderLaunch = NO;
|
||||
}
|
||||
|
||||
#if SDL_USE_NIB_FILE
|
||||
NSApplicationMain (argc, argv);
|
||||
#else
|
||||
CustomApplicationMain (argc, argv);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
52
data/IntroText.h
Normal file
52
data/IntroText.h
Normal file
@ -0,0 +1,52 @@
|
||||
static const char *introTextData =
|
||||
"\blThe Powder Toy - Version " MTOS(SAVE_VERSION) "." MTOS(MINOR_VERSION) " - http://powdertoy.co.uk, irc.freenode.net #powder\n"
|
||||
"\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F\n"
|
||||
"\n"
|
||||
"\bgControl+C/V/X are Copy, Paste and cut respectively.\n"
|
||||
"\bgTo choose a material, hover over one of the icons on the right, it will show a selection of elements in that group.\n"
|
||||
"\bgPick your material from the menu using mouse left/right buttons.\n"
|
||||
"Draw freeform lines by dragging your mouse left/right button across the drawing area.\n"
|
||||
"Shift+drag will create straight lines of particles.\n"
|
||||
"Ctrl+drag will result in filled rectangles.\n"
|
||||
"Ctrl+Shift+click will flood-fill a closed area.\n"
|
||||
"Ctrl+Z will act as Undo.\n"
|
||||
"Middle click or Alt+Click to \"sample\" the particles.\n"
|
||||
"\n\boUse 'Z' for a zoom tool. Click to make the drawable zoom window stay around. Use the wheel to change the zoom strength\n"
|
||||
"Use 'S' to save parts of the window as 'stamps'.\n"
|
||||
"'L' will load the most recent stamp, 'K' shows a library of stamps you saved.\n"
|
||||
"Use the mouse scroll wheel to change the tool size for particles.\n"
|
||||
"The spacebar can be used to pause physics.\n"
|
||||
"'P' will take a screenshot and save it into the current directory.\n"
|
||||
"\n"
|
||||
"Contributors: \bgStanislaw K Skowronek (\brhttp://powder.unaligned.org\bg, \bbirc.unaligned.org #wtf\bg),\n"
|
||||
"\bgSimon Robertshaw, Skresanov Savely, cracker64, Catelite, Bryan Hoyle, Nathan Cousins, jacksonmj,\n"
|
||||
"\bgLieuwe Mosch, Anthony Boot, Matthew \"me4502\", MaksProg, jacob1\n"
|
||||
"\n"
|
||||
"\bgTo use online features such as saving, you need to register at: \brhttp://powdertoy.co.uk/Register.html\n"
|
||||
"\n"
|
||||
"\bt" MTOS(SAVE_VERSION) "." MTOS(MINOR_VERSION) "." MTOS(BUILD_NUM) " " IDENT_PLATFORM " "
|
||||
#ifdef X86
|
||||
"X86 "
|
||||
#endif
|
||||
#ifdef X86_SSE
|
||||
"X86_SSE "
|
||||
#endif
|
||||
#ifdef X86_SSE2
|
||||
"X86_SSE2 "
|
||||
#endif
|
||||
#ifdef X86_SSE3
|
||||
"X86_SSE3 "
|
||||
#endif
|
||||
#ifdef MACOSX
|
||||
"MACOSX "
|
||||
#endif
|
||||
#ifdef LUACONSOLE
|
||||
"LUACONSOLE "
|
||||
#endif
|
||||
#ifdef GRAVFFT
|
||||
"GRAVFFT "
|
||||
#endif
|
||||
#ifdef REALISTIC
|
||||
"REALISTIC"
|
||||
#endif
|
||||
;
|
99
data/Shaders.h
Normal file
99
data/Shaders.h
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Shaders.h
|
||||
*
|
||||
* Created on: Jan 7, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#ifndef SHADERS_H_
|
||||
#define SHADERS_H_
|
||||
|
||||
const char * fireFragment = "#version 120\n\
|
||||
uniform sampler2D fireAlpha;\
|
||||
void main () {\
|
||||
vec4 texColor = texture2D(fireAlpha, gl_PointCoord);\
|
||||
gl_FragColor = vec4(gl_Color.rgb, texColor.a*gl_Color.a);\
|
||||
}";
|
||||
const char * fireVertex = "#version 120\n\
|
||||
void main(void)\
|
||||
{\
|
||||
gl_Position = ftransform();;\
|
||||
gl_FrontColor = gl_Color;\
|
||||
}";
|
||||
const char * lensFragment = "#version 120\n\
|
||||
uniform sampler2D pTex;\
|
||||
uniform sampler2D tfX;\
|
||||
uniform sampler2D tfY;\
|
||||
uniform float xres;\
|
||||
uniform float yres;\
|
||||
void main () {\
|
||||
vec4 transformX = texture2D(tfX, vec2(gl_TexCoord[0].s, -gl_TexCoord[0].t));\
|
||||
vec4 transformY = -texture2D(tfY, vec2(gl_TexCoord[0].s, -gl_TexCoord[0].t));\
|
||||
transformX.r /= xres;\
|
||||
transformY.g /= yres;\
|
||||
vec4 texColor = vec4(\
|
||||
texture2D(pTex, gl_TexCoord[0].st-vec2(transformX.r*0.75, transformY.g*0.75)).r,\
|
||||
texture2D(pTex, gl_TexCoord[0].st-vec2(transformX.r*0.875, transformY.g*0.875)).g,\
|
||||
texture2D(pTex, gl_TexCoord[0].st-vec2(transformX.r, transformY.g)).b,\
|
||||
1.0\
|
||||
);\
|
||||
gl_FragColor = texColor;\
|
||||
}";
|
||||
const char * lensVertex = "#version 120\n\
|
||||
void main(void)\
|
||||
{\
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;\
|
||||
gl_Position = ftransform();;\
|
||||
gl_FrontColor = gl_Color;\
|
||||
}";
|
||||
const char * airVFragment = "#version 120\n\
|
||||
uniform sampler2D airX;\
|
||||
uniform sampler2D airY;\
|
||||
uniform sampler2D airP;\
|
||||
void main () {\
|
||||
vec4 texX = texture2D(airX, gl_TexCoord[0].st);\
|
||||
vec4 texY = texture2D(airY, gl_TexCoord[0].st);\
|
||||
vec4 texP = texture2D(airP, gl_TexCoord[0].st);\
|
||||
gl_FragColor = vec4(abs(texX.r)/2.0, texP.b/2.0, abs(texY.g)/2.0, 1.0);\
|
||||
}";
|
||||
const char * airVVertex = "#version 120\n\
|
||||
void main(void)\
|
||||
{\
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;\
|
||||
gl_Position = ftransform();;\
|
||||
gl_FrontColor = gl_Color;\
|
||||
}";
|
||||
const char * airPFragment = "#version 120\n\
|
||||
uniform sampler2D airX;\
|
||||
uniform sampler2D airY;\
|
||||
uniform sampler2D airP;\
|
||||
void main () {\
|
||||
vec4 texP = texture2D(airP, gl_TexCoord[0].st);\
|
||||
gl_FragColor = vec4(max(texP.b/2.0, 0), 0, abs(min(texP.b/2.0, 0)), 1.0);\
|
||||
}";
|
||||
const char * airPVertex = "#version 120\n\
|
||||
void main(void)\
|
||||
{\
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;\
|
||||
gl_Position = ftransform();;\
|
||||
gl_FrontColor = gl_Color;\
|
||||
}";
|
||||
const char * airCFragment = "#version 120\n\
|
||||
uniform sampler2D airX;\
|
||||
uniform sampler2D airY;\
|
||||
uniform sampler2D airP;\
|
||||
void main () {\
|
||||
vec4 texX = texture2D(airX, gl_TexCoord[0].st);\
|
||||
vec4 texY = texture2D(airY, gl_TexCoord[0].st);\
|
||||
vec4 texP = texture2D(airP, gl_TexCoord[0].st);\
|
||||
gl_FragColor = vec4(max(texP.b/2.0, 0), 0, abs(min(texP.b/2.0, 0)), 1.0) + vec4(abs(texX.r)/8.0, abs(texX.r)/8.0, abs(texX.r)/8.0, 1.0) + vec4(abs(texY.g)/8.0, abs(texY.g)/8.0, abs(texY.g)/8.0, 1.0);\
|
||||
}";
|
||||
const char * airCVertex = "#version 120\n\
|
||||
void main(void)\
|
||||
{\
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;\
|
||||
gl_Position = ftransform();;\
|
||||
gl_FrontColor = gl_Color;\
|
||||
}";
|
||||
|
||||
#endif /* SHADERS_H_ */
|
301
data/font.h
Normal file
301
data/font.h
Normal file
@ -0,0 +1,301 @@
|
||||
#ifndef FONT_H_CHECK
|
||||
#define FONT_H_CHECK
|
||||
#define FONT_H 10
|
||||
#ifdef INCLUDE_FONTDATA
|
||||
char font_data[] = {
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0xC7, 0x31, 0x0C, 0x02, 0x70, 0x04, 0x00, 0x00,
|
||||
0x05, 0xCC, 0x74, 0x23, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x80, 0x19, 0xCC, 0xE0, 0x3F, 0xCC, 0xF0, 0x2F, 0xCC, 0x90, 0x09, 0x00, 0x00, 0x00,
|
||||
0x06, 0x30, 0xD0, 0x3F, 0x33, 0xE1, 0x07, 0xF4, 0x12, 0x33, 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x07, 0x2D, 0xCE, 0xCC, 0xE1, 0x1D, 0xC0, 0x03, 0x74, 0x4B, 0x33, 0xB3, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x7D, 0x30, 0x0C, 0x13, 0xD0, 0x32, 0xB3, 0x33, 0x1C, 0x7D, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x4C, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x34, 0x1D, 0x07, 0x03, 0x07, 0x1D, 0x34, 0x00, 0x00, 0x00,
|
||||
0x04, 0x07, 0x1D, 0x34, 0x30, 0x34, 0x1D, 0x07, 0x00, 0x00, 0x00,
|
||||
0x06, 0x44, 0xD0, 0x1C, 0x64, 0xF0, 0x3F, 0x64, 0xD0, 0x1C, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x02, 0x30, 0xE0, 0x2F, 0x30, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0D, 0x03, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x40, 0x70, 0x00, 0x00, 0x00,
|
||||
0x06, 0x80, 0x02, 0x0C, 0xA0, 0x00, 0x03, 0x28, 0xC0, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xF8, 0xE0, 0x39, 0x07, 0x33, 0x32, 0x03, 0xB3, 0x38, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x30, 0xF0, 0x60, 0x03, 0x0C, 0x30, 0xC0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xFC, 0xB1, 0x34, 0x41, 0x03, 0x0A, 0x2C, 0x70, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xFC, 0x71, 0x34, 0x01, 0x03, 0x1E, 0x00, 0x33, 0x34, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xC0, 0x03, 0x37, 0x1C, 0x73, 0x34, 0xBF, 0x03, 0x30, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xFF, 0x33, 0x00, 0x57, 0xE0, 0x2F, 0x00, 0x13, 0x30, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xF4, 0xD3, 0x00, 0x07, 0xF0, 0x1F, 0x03, 0x33, 0x34, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xFF, 0x07, 0x34, 0x80, 0x03, 0x0E, 0x38, 0xD0, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xFC, 0xB1, 0x34, 0x03, 0xD3, 0x1F, 0x03, 0x73, 0x34, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xFC, 0xB1, 0x34, 0x03, 0xC3, 0x3F, 0x40, 0x23, 0x30, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x70, 0x04, 0x40, 0x70, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x1C, 0x04, 0x00, 0x0C, 0x0D, 0x03, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0xC0, 0xC3, 0x0B, 0x1B, 0xC0, 0x0B, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x0F, 0x90, 0x83, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xFD, 0x71, 0x30, 0x81, 0x03, 0x0E, 0x34, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x08, 0xF8, 0x0F, 0x1D, 0x30, 0xE7, 0x37, 0x73, 0x1C, 0xE3, 0x2F, 0x07, 0x00, 0xFD, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x74, 0xD0, 0x1D, 0x47, 0x33, 0x30, 0xFF, 0x33, 0x30, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xBF, 0x30, 0x38, 0x43, 0xF3, 0x1F, 0x43, 0x33, 0x34, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xF4, 0xD1, 0x34, 0x03, 0x31, 0x00, 0x03, 0x70, 0x34, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x7F, 0x30, 0x1D, 0x43, 0x33, 0x30, 0x03, 0x33, 0x34, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xFF, 0x32, 0x00, 0x03, 0xF0, 0x0B, 0x03, 0x30, 0x10, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xFF, 0x33, 0x10, 0x03, 0xF0, 0x0B, 0x03, 0x30, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xF4, 0xD1, 0x34, 0x03, 0x30, 0x3E, 0x03, 0x73, 0x34, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x47, 0x33, 0x30, 0x03, 0xF3, 0x3F, 0x03, 0x33, 0x30, 0x47, 0x03, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x1D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1D, 0x00, 0x00, 0x00,
|
||||
0x06, 0xD0, 0x01, 0x0C, 0xC0, 0x00, 0x0C, 0xC0, 0x10, 0x0D, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0x47, 0xC3, 0x34, 0x70, 0x03, 0xBC, 0x00, 0xB3, 0xC0, 0xB0, 0x70, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x07, 0x30, 0x00, 0x03, 0x30, 0x00, 0x03, 0x30, 0x10, 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x08, 0x03, 0x30, 0x1F, 0x3D, 0x7B, 0x3B, 0xE3, 0x32, 0x83, 0x30, 0x03, 0x30, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0x07, 0xCD, 0x03, 0x73, 0xC3, 0x8C, 0x32, 0xC3, 0xCD, 0xC0, 0x33, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0xF4, 0x41, 0xC7, 0x71, 0xD0, 0x0C, 0x30, 0x03, 0xCD, 0xD1, 0xD1, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x7F, 0x30, 0x1D, 0x43, 0x73, 0x34, 0xFF, 0x31, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0xF4, 0x41, 0xD3, 0x71, 0xD0, 0x0C, 0x30, 0xC3, 0xCD, 0xD1, 0xD1, 0xDF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xFF, 0x31, 0x34, 0x03, 0xF3, 0x0F, 0xD7, 0x30, 0x34, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xFC, 0xB1, 0x31, 0x07, 0xD0, 0x0F, 0x90, 0x23, 0x34, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0xFF, 0x13, 0x13, 0x30, 0x00, 0x03, 0x30, 0x00, 0x03, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0x03, 0xCC, 0x00, 0x33, 0xC0, 0x0C, 0x30, 0x03, 0xCD, 0xD2, 0xD1, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x03, 0x33, 0x30, 0x03, 0xB3, 0x38, 0xCD, 0xC1, 0x0D, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x08, 0x03, 0x30, 0x43, 0x30, 0xC7, 0x34, 0xCD, 0x1C, 0xED, 0x1E, 0x2C, 0x0E, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0x03, 0x4C, 0xC3, 0x81, 0x3B, 0xD0, 0x03, 0xDC, 0x42, 0xC3, 0x31, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x03, 0xB3, 0x38, 0xDC, 0x40, 0x07, 0x30, 0x00, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0xFF, 0x0F, 0xD0, 0x02, 0x2C, 0xC0, 0x02, 0x2D, 0xC0, 0x06, 0xF0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x2F, 0x03, 0x03, 0x03, 0x03, 0x03, 0x2F, 0x00, 0x00, 0x00,
|
||||
0x05, 0x03, 0x28, 0xC0, 0x00, 0x0A, 0x30, 0x80, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x3E, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3E, 0x00, 0x00, 0x00,
|
||||
0x04, 0x1D, 0x37, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x83, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xD0, 0x47, 0x30, 0xFC, 0x0C, 0xD3, 0x1F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x07, 0x0C, 0xF0, 0xC7, 0x35, 0xC3, 0x0C, 0xF3, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xD0, 0xC3, 0x25, 0x03, 0x4C, 0xD2, 0x03, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0xD0, 0x00, 0x83, 0x8F, 0x33, 0xC3, 0x1C, 0xD3, 0x1F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xD0, 0xC7, 0x30, 0xBF, 0x0C, 0xD0, 0x0B, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x3D, 0x07, 0x03, 0x2F, 0x03, 0x03, 0x07, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xC0, 0xCB, 0x32, 0xC3, 0xF4, 0x03, 0x4C, 0x30, 0x7E, 0x00, 0x00,
|
||||
0x05, 0x03, 0x0C, 0xF0, 0xC7, 0x39, 0xC3, 0x0C, 0x73, 0x1C, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x04, 0x1C, 0x00, 0x0D, 0x0C, 0x0C, 0x1D, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x30, 0x00, 0x34, 0x30, 0x30, 0x30, 0x30, 0x1E, 0x00,
|
||||
0x05, 0x03, 0x0C, 0x31, 0xCE, 0x0E, 0x1F, 0xCC, 0x31, 0x1C, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x47, 0x3D, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0x9B, 0x71, 0x37, 0x33, 0x33, 0x32, 0x43, 0x03, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xF0, 0xC7, 0x31, 0xC3, 0x0C, 0x33, 0x0D, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xD0, 0xC7, 0x31, 0xC3, 0x4C, 0xD3, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xF0, 0xC7, 0x31, 0xC3, 0x4C, 0xF3, 0xC7, 0x00, 0x03, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xD0, 0xDF, 0x31, 0xC3, 0x4C, 0xD3, 0x0F, 0x30, 0xC0, 0x00, 0x05,
|
||||
0x04, 0x00, 0x00, 0x33, 0x1F, 0x07, 0x03, 0x03, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xC0, 0xC7, 0x10, 0x3C, 0x04, 0xF3, 0x03, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x1C, 0x74, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x70, 0xDC, 0x30, 0xC3, 0x4C, 0xD3, 0x1F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x30, 0xCC, 0x30, 0xD3, 0xDC, 0xC2, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0x47, 0x33, 0x32, 0x33, 0x73, 0x37, 0xCD, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x30, 0xCD, 0x32, 0x7D, 0x8C, 0x73, 0x0C, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x30, 0xCC, 0x30, 0xC7, 0x74, 0x43, 0x07, 0x0C, 0x1F, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xF0, 0x4F, 0x2C, 0x2C, 0x2C, 0xF1, 0x0F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x38, 0x0C, 0x0C, 0x03, 0x0C, 0x0C, 0x38, 0x00, 0x00, 0x00,
|
||||
0x02, 0x32, 0x33, 0x33, 0x13, 0x00,
|
||||
0x04, 0x0B, 0x0C, 0x0C, 0x30, 0x0C, 0x0C, 0x0B, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0x1D, 0x72, 0x37, 0xD2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x08, 0x07, 0x00, 0x1F, 0x00, 0x7F, 0x00, 0xFF, 0x01, 0xFF, 0x07, 0xFF, 0x1F, 0xFF, 0x7F, 0xFF, 0x1B, 0xBF, 0x01, 0x1B, 0x00,
|
||||
0x0C, 0x00, 0x40, 0xFF, 0x00, 0x00, 0xF8, 0xF0, 0x3F, 0xEE, 0x2C, 0x30, 0xCB, 0x0B, 0x30, 0x42, 0xC3, 0x33, 0x00, 0x03, 0x30, 0x00, 0xF3, 0x33, 0x00, 0x03, 0x30, 0x00, 0xFF, 0x3F, 0x00,
|
||||
0x0C, 0xC2, 0x00, 0x00, 0xCB, 0x00, 0x00, 0xEE, 0xC0, 0xFF, 0xF8, 0xB0, 0xC0, 0xFF, 0x2C, 0xC0, 0x00, 0x0C, 0xCF, 0x00, 0x0C, 0xC0, 0x00, 0xCC, 0xCF, 0x00, 0x0C, 0xC0, 0x00, 0xFC, 0xFF,
|
||||
0x0A, 0x00, 0x00, 0x0D, 0x00, 0x70, 0x00, 0x00, 0xF3, 0xFF, 0xD3, 0x03, 0xE0, 0x3C, 0x3F, 0x38, 0x03, 0xD0, 0x33, 0xFF, 0x38, 0x03, 0xE0, 0xF0, 0xFF, 0x03,
|
||||
0x0C, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x8B, 0xF7, 0x0C, 0x13, 0x9F, 0x3B, 0x37, 0x00, 0xC0, 0x23, 0xFF, 0xFF, 0x8B, 0x03, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0A, 0xD0, 0x7F, 0x80, 0x03, 0x2C, 0x0D, 0x00, 0x37, 0x00, 0xC0, 0xF3, 0xFF, 0x3C, 0xFF, 0xCF, 0x03, 0x00, 0xDC, 0x00, 0x70, 0x38, 0xC0, 0x02, 0xFD, 0x07,
|
||||
0x0A, 0x00, 0x00, 0x00, 0xFC, 0x03, 0xF0, 0xFF, 0xC0, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, 0xFC, 0xFF, 0x03, 0xFF, 0x0F, 0xC0, 0x3F, 0x00, 0x00, 0x00,
|
||||
0x0A, 0xFF, 0xFF, 0x3F, 0x00, 0xC0, 0x03, 0x00, 0x3C, 0xF0, 0xC0, 0xC3, 0x3A, 0x3C, 0x0B, 0xCE, 0x2B, 0x80, 0x7E, 0x00, 0xD0, 0x03, 0x00, 0xFC, 0xFF, 0xFF,
|
||||
0x0A, 0x00, 0x00, 0xC0, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, 0xFC, 0xFF, 0x03, 0x00, 0x00,
|
||||
0x0A, 0xD0, 0x7F, 0x80, 0x03, 0x2C, 0x0D, 0x0F, 0x37, 0xF0, 0xC0, 0xF3, 0xFF, 0x3C, 0xFF, 0xCF, 0x03, 0x0F, 0xDC, 0xF0, 0x70, 0x38, 0xC0, 0x02, 0xFD, 0x07,
|
||||
0x0A, 0x40, 0x1F, 0x00, 0xAD, 0x07, 0xB0, 0xC5, 0x00, 0x17, 0x0C, 0x70, 0xD0, 0x00, 0x0C, 0x03, 0xBC, 0xEF, 0xB3, 0x11, 0xE0, 0x07, 0x05, 0x3C, 0x52, 0xC8,
|
||||
0x0A, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xC0, 0x3F, 0x00, 0xFC, 0x03, 0xC0, 0x3F, 0x00, 0xF0, 0x00, 0xC0, 0x30, 0xC0, 0xFF, 0x3F, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F,
|
||||
0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0xFF, 0x0F, 0xFC, 0xFF, 0x3F, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0xB8, 0xE0, 0x2F, 0xFF, 0xE3, 0x2F, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0A, 0xD0, 0x7F, 0x80, 0xFF, 0x2F, 0xFD, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0x7F, 0xF8, 0xFF, 0x02, 0xFD, 0x07,
|
||||
0x0A, 0x40, 0x01, 0x00, 0x02, 0x00, 0xC8, 0x07, 0x10, 0xC3, 0x00, 0x31, 0x0D, 0x00, 0xFD, 0x01, 0x00, 0x74, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0xF0, 0xF0, 0x00, 0x0F, 0x0F, 0xF0, 0xF0, 0x00, 0x0F, 0x0F, 0xF0, 0xF0, 0x00, 0x0F, 0x0F, 0xF0, 0xF0, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x40, 0x05, 0x80, 0xFF, 0x8B, 0x1E, 0xD0, 0x2E, 0x00, 0xF0, 0x00, 0xE0, 0xFF, 0x0B, 0x00, 0x0F, 0x00, 0xB8, 0x03, 0xB0, 0xE2, 0xFF, 0x02, 0x50, 0x01,
|
||||
0x08, 0xFF, 0x07, 0x03, 0x1E, 0x03, 0x73, 0x03, 0xEF, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0xFF, 0xFF,
|
||||
0x0B, 0x00, 0x00, 0x00, 0xE4, 0x2F, 0xE0, 0x1B, 0x0C, 0x1D, 0x00, 0xFF, 0x03, 0xBE, 0xF0, 0xC1, 0x01, 0xAD, 0x34, 0xC0, 0x36, 0x0B, 0x30, 0xDC, 0xE4, 0x07, 0xFD, 0x1B, 0x00,
|
||||
0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x02, 0xA0, 0xAA, 0x00, 0xA8, 0xC2, 0x0F, 0x2A, 0xFF, 0x03, 0xCA, 0x3F, 0x80, 0xFC, 0x0F, 0x20, 0x0F, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0C, 0x00, 0xC0, 0x01, 0x00, 0xC0, 0x07, 0xAA, 0xEA, 0x1F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xAA, 0xEA, 0x1F, 0x00, 0xC0, 0x07, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00,
|
||||
0x0C, 0x40, 0x03, 0x00, 0xD0, 0x03, 0x00, 0xF4, 0xAB, 0xAA, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF4, 0xAB, 0xAA, 0xD0, 0x03, 0x00, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00,
|
||||
0x09, 0xFE, 0xFF, 0xE3, 0xFF, 0x0F, 0xAA, 0x3E, 0x0A, 0xF8, 0x2E, 0xE0, 0xBF, 0x80, 0xFF, 0xAA, 0xFE, 0xFF, 0xE2, 0xFF, 0x02, 0x02, 0x00, 0x00,
|
||||
0x09, 0x00, 0x80, 0x04, 0xD0, 0xE2, 0xFF, 0x02, 0x00, 0x00, 0xFF, 0x6F, 0x00, 0x40, 0xE6, 0xAF, 0x50, 0x00, 0x09, 0x00, 0x20, 0x00, 0x64, 0x00,
|
||||
0x09, 0xE0, 0x3F, 0x70, 0x60, 0x63, 0xC0, 0xE4, 0x80, 0xC2, 0x03, 0x07, 0x0F, 0x1E, 0x6C, 0xFF, 0x27, 0xFF, 0x3F, 0xE0, 0x2F, 0x00, 0x00, 0x00,
|
||||
0x09, 0x44, 0x44, 0x00, 0x12, 0x41, 0x88, 0x04, 0x21, 0x21, 0x84, 0x48, 0x20, 0x23, 0xC2, 0xCC, 0x08, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x09, 0x00, 0x1D, 0x00, 0x1D, 0x00, 0x78, 0x00, 0xB4, 0x07, 0xF0, 0x2F, 0xC0, 0xFB, 0x00, 0xBE, 0x02, 0xF4, 0x07, 0xFD, 0xFF, 0x01, 0x00, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, 0x00, 0x19, 0x00, 0xA8, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x09, 0x00, 0x00, 0xFC, 0xFF, 0x3F, 0x00, 0xF0, 0xDC, 0xCB, 0x03, 0x00, 0xFF, 0xFF, 0x4F, 0x07, 0x40, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x0F, 0xFF, 0x3F, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0A, 0xFF, 0xFF, 0x3F, 0x00, 0xC0, 0x07, 0x00, 0xBD, 0x02, 0xE8, 0xB3, 0xE0, 0x3C, 0xAC, 0xC3, 0x03, 0x0F, 0x3C, 0x00, 0xC0, 0x03, 0x00, 0xFC, 0xFF, 0xFF,
|
||||
0x0B, 0xC0, 0xC8, 0xC0, 0x91, 0x1B, 0xCD, 0x36, 0xE7, 0x00, 0x47, 0x03, 0xA7, 0x80, 0x36, 0xFD, 0xFF, 0xC1, 0x9B, 0xF9, 0xB8, 0xB8, 0xB8, 0xB7, 0x99, 0xF7, 0xFF, 0xFF, 0x0F,
|
||||
0x0B, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xF0, 0x03, 0x00, 0xFC, 0x00, 0xC0, 0xFF, 0x00, 0xF0, 0x3F, 0x00, 0xFF, 0x3F, 0xF0, 0xFF, 0x3F, 0xFC, 0xFF, 0xCF, 0xFF, 0xFF, 0x0F,
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x1F, 0xCB, 0x30, 0xC3, 0x3F, 0xC7, 0x00, 0x7E, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0A, 0xFC, 0xFF, 0xC3, 0xFF, 0x3F, 0x0C, 0x00, 0xC3, 0xFC, 0x33, 0x0C, 0x24, 0xC3, 0xC0, 0x31, 0x0C, 0x06, 0xC3, 0x30, 0x30, 0x0C, 0x00, 0xC3, 0xFF, 0x3F,
|
||||
0x0A, 0xFF, 0x3F, 0x30, 0x00, 0x03, 0xC3, 0x30, 0x30, 0x3F, 0xFF, 0xFF, 0x3F, 0x3C, 0x00, 0xFF, 0xFF, 0xFF, 0x0C, 0x0C, 0xC3, 0xC0, 0x00, 0x0C, 0xFC, 0xFF,
|
||||
0x0A, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0xFC, 0x0F, 0xC0, 0xFF, 0x00, 0xFC, 0x0F, 0xC0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x3C, 0x00, 0xC0, 0x03, 0xF0, 0x3F, 0x00, 0xFF, 0x03, 0x00, 0x00,
|
||||
0x09, 0xE0, 0x2F, 0xF0, 0xFF, 0xE3, 0xB8, 0xEC, 0x9B, 0xF9, 0xBF, 0xF8, 0xBF, 0x99, 0xEF, 0xB8, 0x2C, 0xFF, 0x3F, 0xE0, 0x2F, 0x00, 0x00, 0x00,
|
||||
0x04, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
|
||||
0x03, 0x87, 0x87, 0xC3, 0x30, 0x0C, 0xE3, 0xDE, 0x01,
|
||||
0x03, 0x74, 0xBB, 0x0C, 0xC3, 0x30, 0x2C, 0x2D, 0x0D,
|
||||
0x05, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0F,
|
||||
0x05, 0x00, 0x00, 0xD0, 0xC7, 0x34, 0xC3, 0x0C, 0x73, 0x4C, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x39, 0xC0, 0x00, 0x43, 0x2F, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xD0, 0x87, 0x30, 0x60, 0x60, 0x60, 0xC0, 0x3F, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xD0, 0x87, 0x30, 0xB8, 0x00, 0x23, 0x4C, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x0E, 0x36, 0xC6, 0xFC, 0x03, 0x0C, 0x30, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xF0, 0xCB, 0x00, 0x7F, 0x40, 0x13, 0x8C, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xD0, 0xCB, 0x10, 0x2F, 0x4C, 0x33, 0x4C, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xF0, 0x0F, 0x30, 0x60, 0x60, 0xC0, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xD0, 0xC7, 0x30, 0x7D, 0x4C, 0x33, 0x4C, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0xD0, 0xC7, 0x30, 0xC6, 0xE0, 0x03, 0x8C, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
0x03, 0xC0, 0xF0, 0x3C, 0xCF, 0xF3, 0x3C, 0x03, 0x00,
|
||||
0x03, 0x00, 0xCC, 0xF3, 0x3C, 0xCF, 0xF3, 0x30, 0x00,
|
||||
0x05, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x03, 0x30, 0xC0, 0x0F, 0x30, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0xD0, 0x7F, 0x40, 0xFF, 0x1F, 0xFC, 0xFF, 0x43, 0xFF, 0x1F, 0x40, 0x15, 0x00, 0x00, 0x00,
|
||||
0x0A, 0xE4, 0x06, 0x90, 0x91, 0x01, 0x06, 0x24, 0x30, 0x90, 0x1B, 0x46, 0x6E, 0x96, 0xB9, 0x91, 0xE4, 0x06, 0x0C, 0x18, 0x90, 0x40, 0x46, 0x06, 0x90, 0x1B,
|
||||
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x02, 0xC2, 0xAB, 0xAA, 0x3E, 0x20, 0xE0, 0xAB, 0xAA, 0x3E, 0x02, 0xC2, 0xFF, 0xFF, 0x0F, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x00, 0x00, 0x08, 0x02, 0xC0, 0x30, 0x00, 0x0C, 0x03, 0xF0, 0xFF, 0x00, 0xFE, 0x0B, 0xD0, 0x7F, 0x00, 0xA4, 0x01, 0x00, 0x0A, 0x00, 0xA0, 0x00,
|
||||
0x0A, 0x00, 0x80, 0x00, 0x81, 0x24, 0x10, 0x85, 0x00, 0x20, 0x66, 0x40, 0x15, 0x45, 0x62, 0x90, 0x4D, 0xD0, 0xF1, 0x23, 0x01, 0xFD, 0x41, 0x41, 0x07, 0x00,
|
||||
0x0A, 0x00, 0x05, 0x00, 0xA0, 0x00, 0x40, 0x1F, 0x00, 0xF8, 0x02, 0xD0, 0x7F, 0x00, 0xFE, 0x0B, 0xF0, 0xEF, 0x00, 0xFF, 0x0D, 0xD0, 0x77, 0x00, 0xF4, 0x01,
|
||||
0x0A, 0x00, 0x20, 0x00, 0x00, 0x3C, 0x00, 0xD4, 0x01, 0xD0, 0x06, 0x40, 0x7F, 0x00, 0xFD, 0x01, 0xF4, 0x07, 0xD0, 0x1F, 0x00, 0x7F, 0x00, 0xD0, 0x01, 0x00,
|
||||
0x0A, 0x40, 0x15, 0x00, 0xFE, 0x0B, 0x88, 0x2F, 0x52, 0xF0, 0x50, 0x01, 0x0A, 0xD4, 0xAF, 0x7F, 0xFD, 0xF5, 0xC7, 0x0B, 0x3E, 0x70, 0xD0, 0x00, 0xA8, 0x02,
|
||||
0x0A, 0x80, 0x2F, 0x80, 0x5F, 0x2F, 0x0C, 0x00, 0xC3, 0x00, 0x30, 0x0C, 0x00, 0xC3, 0x01, 0x34, 0x34, 0xC0, 0x01, 0x07, 0x0D, 0xD0, 0x75, 0x00, 0xF4, 0x01,
|
||||
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0xF4, 0x01, 0xC0, 0x3F, 0x00, 0xF0, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xE0, 0xEF, 0x00, 0xBB, 0x0B, 0xA0, 0xAA, 0x00, 0xAA, 0x0A, 0x80, 0x19, 0x00, 0x64, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x10, 0x2D, 0x80, 0xE7, 0x0B, 0xBE, 0xF8, 0xFA, 0x02, 0xFE, 0x0B, 0x80, 0x2F, 0x00, 0x50, 0x00,
|
||||
0x0A, 0x00, 0x05, 0x00, 0xF8, 0x02, 0xE0, 0xBF, 0x80, 0xAF, 0x2F, 0xBE, 0xE0, 0xDB, 0x02, 0x78, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x05, 0x00, 0xA0, 0x00, 0x40, 0x1F, 0x50, 0xFE, 0x5B, 0xFD, 0xFF, 0x47, 0xFF, 0x1F, 0xE0, 0xBF, 0x00, 0xFE, 0x0B, 0xF0, 0xF5, 0x40, 0x01, 0x14,
|
||||
0x0A, 0x40, 0x1A, 0x00, 0x09, 0x06, 0x20, 0x80, 0x00, 0x02, 0x08, 0xFC, 0xFF, 0xC3, 0x00, 0x30, 0x0C, 0x00, 0xC3, 0x00, 0x30, 0x0C, 0x00, 0xC3, 0xFF, 0x3F,
|
||||
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x0A, 0xF0, 0xFF, 0x00, 0xAA, 0x0A, 0xF0, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x09, 0xE0, 0x2F, 0xF0, 0xFF, 0xE3, 0xFF, 0xED, 0xFF, 0xE1, 0xDF, 0xE1, 0x2F, 0xE1, 0xEF, 0xE2, 0x2F, 0xEF, 0x3F, 0xE0, 0x2F, 0x00, 0x00, 0x00,
|
||||
0x0A, 0xC0, 0x31, 0x00, 0x30, 0x01, 0x40, 0x34, 0x00, 0xCC, 0x00, 0x00, 0x0A, 0x00, 0xF8, 0x02, 0xE0, 0xBF, 0x80, 0xFF, 0x2F, 0xFE, 0xFF, 0xFB, 0xFF, 0xFF,
|
||||
0x0A, 0x00, 0x00, 0x80, 0xFF, 0x2F, 0xFC, 0xFF, 0xC3, 0x07, 0x3D, 0x3C, 0xC0, 0xC3, 0x03, 0x3C, 0x7C, 0xD0, 0xC3, 0xFF, 0x3F, 0xF8, 0xFF, 0x02, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x3C, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0xC0, 0xF3, 0x3C, 0x3C, 0xCF, 0x03, 0x00, 0x00,
|
||||
0x0A, 0xB9, 0x91, 0xE3, 0x46, 0x2E, 0x1B, 0xB9, 0x61, 0xE4, 0x06, 0x91, 0x1B, 0x41, 0x6E, 0x24, 0xB9, 0x91, 0xE3, 0x46, 0x2E, 0x1B, 0xB9, 0x01, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x0C, 0xC0, 0x23, 0x00, 0x80, 0x08, 0x00, 0x20, 0x0F, 0xC0, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0A, 0xE0, 0x2F, 0xC0, 0x01, 0x0D, 0x06, 0x40, 0x32, 0x00, 0x30, 0x03, 0x00, 0x33, 0x00, 0x30, 0x06, 0x40, 0xC2, 0x01, 0x0D, 0xE0, 0x2F, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x23, 0x80, 0x32, 0x0A, 0x0D, 0xC3, 0xD1, 0x10, 0x1C, 0x0D, 0xC0, 0x81, 0x02, 0x0A, 0xE0, 0x2F, 0x00, 0x54, 0x00,
|
||||
0x0A, 0x00, 0x00, 0x00, 0xFC, 0x03, 0xB0, 0xE0, 0x00, 0x03, 0x0C, 0x30, 0xC0, 0x00, 0x0B, 0x0E, 0xC0, 0x3F, 0x00, 0xAC, 0x03, 0xC0, 0x3A, 0x00, 0xAC, 0x03,
|
||||
0x05, 0x6F, 0xBC, 0xF1, 0xC6, 0x1B, 0x6F, 0xBC, 0xF1, 0xC6, 0x1B, 0x6F, 0x00, 0x00,
|
||||
0x08, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0xE4, 0x6F, 0x00, 0x00,
|
||||
0x09, 0x00, 0xE4, 0x03, 0x90, 0x0F, 0x40, 0x3E, 0x00, 0xF9, 0x00, 0xE4, 0x03, 0x90, 0x0F, 0x40, 0x3E, 0x00, 0xF9, 0x00, 0xE4, 0x03, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0xFF, 0x03, 0xF0, 0x3F, 0x00, 0xFF, 0x03, 0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x08, 0x82, 0xE0, 0xBA, 0x2E, 0x08, 0x82, 0x80, 0x20, 0x08, 0xAE, 0xEB, 0x82, 0x20, 0x08, 0x08, 0x82, 0xE0, 0xBA, 0x2E, 0x08, 0x82, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x30, 0x00, 0x00, 0x03, 0x30, 0xFC, 0x00, 0x43, 0x07, 0xFC, 0x20, 0x40, 0x07, 0x30, 0x20, 0x00, 0x03, 0x00, 0xFC, 0x00, 0x40, 0x07, 0x00, 0x20,
|
||||
0x0A, 0x00, 0x43, 0xC0, 0x20, 0x1D, 0x20, 0x61, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x84, 0x01, 0x24, 0xB4, 0xF1, 0x01, 0xFE, 0x0F, 0xD0, 0x0F, 0x00, 0xFC,
|
||||
0x0A, 0x00, 0x00, 0x00, 0x54, 0x00, 0x90, 0x1A, 0x40, 0xFE, 0x06, 0xE4, 0x6F, 0x40, 0xFE, 0x06, 0x90, 0x1A, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x88, 0x88, 0x88, 0x55, 0x55, 0x55, 0xFF, 0x00, 0x54, 0x55, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x64, 0x00, 0xA5, 0x6B, 0x01, 0x64, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x00, 0xC0, 0x00, 0x00, 0xFF, 0x86, 0xC0, 0x00, 0x2C, 0x40, 0xFE, 0x0B, 0xE4, 0xBF, 0x0C, 0xC0, 0xF2, 0x6F, 0x08, 0x0C, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x05, 0x00, 0xF4, 0x01, 0xC0, 0x30, 0x00, 0x0D, 0x07, 0xF0, 0xF0, 0x40, 0x5F, 0x1F, 0xFC, 0xFA, 0xD3, 0xFF, 0x7F, 0xFF, 0xF0, 0xDF, 0xFF, 0x7F,
|
||||
0x0C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1E, 0x00, 0x80, 0x07, 0x00, 0xE0, 0x01, 0x00, 0x78, 0x60, 0x00, 0x24, 0x98, 0x01, 0x80, 0x42, 0x06, 0x00, 0x00, 0x19, 0x00, 0x00, 0x04,
|
||||
0x0A, 0x00, 0x00, 0x40, 0x7F, 0x00, 0x5C, 0x0D, 0xC0, 0xC1, 0x00, 0x1C, 0x0C, 0x40, 0xFF, 0x01, 0x00, 0x74, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0A, 0x00, 0x00, 0x01, 0x00, 0x68, 0x00, 0xA2, 0x02, 0x80, 0x0A, 0x00, 0x25, 0x00, 0x44, 0x08, 0x10, 0x01, 0x40, 0x04, 0x00, 0x14, 0x00, 0x10, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x03, 0x08, 0x00, 0x00,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x05, 0x74, 0x30, 0xC3, 0x0D, 0x33, 0xDC, 0x30, 0x93, 0xD9, 0xC0, 0x89, 0xD1, 0x01,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
0x06, 0x74, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0xDC, 0xC0, 0x0C, 0x99, 0x31, 0x30, 0x89, 0x41, 0x07,
|
||||
};
|
||||
short font_ptrs[] = {
|
||||
0x0000, 0x000E, 0x001C, 0x002A, 0x0038, 0x0046, 0x0054, 0x0062,
|
||||
0x0070, 0x007E, 0x008C, 0x009A, 0x00A8, 0x00B6, 0x00C4, 0x00D2,
|
||||
0x00E0, 0x00EE, 0x00FC, 0x010A, 0x0118, 0x0126, 0x0134, 0x0142,
|
||||
0x0150, 0x015E, 0x016C, 0x017A, 0x0188, 0x0196, 0x01A4, 0x01B2,
|
||||
0x01C0, 0x01CE, 0x01D7, 0x01E5, 0x01F5, 0x0205, 0x0218, 0x0228,
|
||||
0x0231, 0x023C, 0x0247, 0x0257, 0x0267, 0x0272, 0x0280, 0x0289,
|
||||
0x0299, 0x02A9, 0x02B7, 0x02C7, 0x02D7, 0x02E7, 0x02F7, 0x0307,
|
||||
0x0317, 0x0327, 0x0337, 0x0340, 0x034B, 0x035B, 0x036B, 0x037B,
|
||||
0x038B, 0x03A0, 0x03B0, 0x03C0, 0x03D0, 0x03E0, 0x03F0, 0x0400,
|
||||
0x0410, 0x0420, 0x042B, 0x043B, 0x044E, 0x045E, 0x0473, 0x0486,
|
||||
0x0499, 0x04A9, 0x04BC, 0x04CC, 0x04DC, 0x04EC, 0x04FF, 0x050F,
|
||||
0x0524, 0x0537, 0x0547, 0x055A, 0x0565, 0x0573, 0x057E, 0x0589,
|
||||
0x0599, 0x05A2, 0x05B0, 0x05BE, 0x05CC, 0x05DA, 0x05E8, 0x05F3,
|
||||
0x0601, 0x060F, 0x061A, 0x0625, 0x0633, 0x063E, 0x064E, 0x065C,
|
||||
0x066A, 0x0678, 0x0686, 0x0691, 0x069F, 0x06AA, 0x06B8, 0x06C6,
|
||||
0x06D6, 0x06E4, 0x06F2, 0x0700, 0x070B, 0x0711, 0x071C, 0x072C,
|
||||
0x0737, 0x074C, 0x076B, 0x078A, 0x07A4, 0x07C3, 0x07DD, 0x07F7,
|
||||
0x0811, 0x082B, 0x0845, 0x085F, 0x0879, 0x0898, 0x08A8, 0x08C2,
|
||||
0x08DC, 0x08F6, 0x0910, 0x0925, 0x0942, 0x095F, 0x097E, 0x099D,
|
||||
0x09B5, 0x09CD, 0x09E5, 0x09FD, 0x0A15, 0x0A2D, 0x0A45, 0x0A5D,
|
||||
0x0A75, 0x0A8D, 0x0AA5, 0x0ABF, 0x0ADC, 0x0AF9, 0x0B0E, 0x0B28,
|
||||
0x0B42, 0x0B5C, 0x0B76, 0x0B8E, 0x0B99, 0x0BA2, 0x0BAB, 0x0BB9,
|
||||
0x0BC7, 0x0BD5, 0x0BE3, 0x0BF1, 0x0BFF, 0x0C0D, 0x0C1B, 0x0C29,
|
||||
0x0C37, 0x0C45, 0x0C50, 0x0C59, 0x0C62, 0x0C70, 0x0C80, 0x0C90,
|
||||
0x0CAA, 0x0CC4, 0x0CDE, 0x0CF8, 0x0D12, 0x0D2C, 0x0D46, 0x0D60,
|
||||
0x0D7A, 0x0D94, 0x0DAE, 0x0DC8, 0x0DE2, 0x0DFC, 0x0E16, 0x0E30,
|
||||
0x0E48, 0x0E62, 0x0E7C, 0x0E96, 0x0EB0, 0x0ECA, 0x0EE4, 0x0EFE,
|
||||
0x0F18, 0x0F26, 0x0F3B, 0x0F53, 0x0F6D, 0x0F87, 0x0FA1, 0x0FBB,
|
||||
0x0FD5, 0x0FF2, 0x100C, 0x1026, 0x1040, 0x105F, 0x1079, 0x1093,
|
||||
0x10A3, 0x10B3, 0x10C3, 0x10D3, 0x10E1, 0x10F1, 0x1101, 0x1111,
|
||||
0x1121, 0x1131, 0x1141, 0x1151, 0x1161, 0x1171, 0x1181, 0x1191,
|
||||
0x11A1, 0x11B1, 0x11C1, 0x11D1, 0x11E1, 0x11F1, 0x1201, 0x1211,
|
||||
};
|
||||
#else
|
||||
extern char font_data[];
|
||||
extern short font_ptrs[];
|
||||
#endif
|
||||
#endif
|
26
data/hmap.h
Normal file
26
data/hmap.h
Normal file
File diff suppressed because one or more lines are too long
22
data/icon.h
Normal file
22
data/icon.h
Normal file
File diff suppressed because one or more lines are too long
138
data/icondoc.h
Normal file
138
data/icondoc.h
Normal file
@ -0,0 +1,138 @@
|
||||
/**
|
||||
* Powder Toy - Main source
|
||||
*
|
||||
* Copyright (c) 2008 - 2010 Stanislaw Skowronek.
|
||||
* Copyright (c) 2010 Simon Robertshaw
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
static unsigned char icon_doc_32_png[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
|
||||
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a,
|
||||
0xf4, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
|
||||
0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93,
|
||||
0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13,
|
||||
0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x04,
|
||||
0x06, 0x11, 0x21, 0x0c, 0xfc, 0x0b, 0x2f, 0xdf, 0x00, 0x00, 0x04, 0x65, 0x49, 0x44, 0x41, 0x54,
|
||||
0x58, 0xc3, 0xb5, 0x96, 0x7f, 0x4c, 0xd4, 0x65, 0x1c, 0xc7, 0x5f, 0xcf, 0x73, 0xdf, 0xe3, 0x7e,
|
||||
0x90, 0x8b, 0x98, 0xb8, 0x36, 0x12, 0xb8, 0x38, 0x69, 0x03, 0x4c, 0x64, 0xec, 0x6a, 0xa2, 0xd3,
|
||||
0xb5, 0x74, 0x78, 0x4c, 0x42, 0x33, 0x51, 0xda, 0x5c, 0xe3, 0x97, 0x72, 0x79, 0xcc, 0x5c, 0xfd,
|
||||
0x53, 0xcb, 0x50, 0x69, 0x93, 0xda, 0x9a, 0x3a, 0x0d, 0x0d, 0x99, 0xf3, 0x9f, 0x3b, 0x98, 0x89,
|
||||
0x72, 0x14, 0x64, 0xb2, 0x62, 0x2b, 0x56, 0xad, 0x56, 0x20, 0xbf, 0x06, 0x3a, 0xe1, 0x1c, 0x8b,
|
||||
0xed, 0x86, 0x89, 0x77, 0x96, 0x7f, 0x30, 0xf6, 0xed, 0x0f, 0xb9, 0x1b, 0xe6, 0x1d, 0x7c, 0x39,
|
||||
0xe8, 0xb3, 0x3d, 0x7b, 0xbe, 0xcf, 0xb3, 0xef, 0xf3, 0x7c, 0x5f, 0xcf, 0xfb, 0xf3, 0xe3, 0xf9,
|
||||
0x0a, 0x9e, 0xb4, 0xd5, 0x40, 0x0a, 0x0b, 0x37, 0x3f, 0x30, 0x0a, 0x78, 0x17, 0xb2, 0x48, 0x09,
|
||||
0x33, 0x97, 0x52, 0x52, 0x52, 0xe2, 0x11, 0x42, 0xa0, 0xaa, 0x2a, 0x42, 0x08, 0x80, 0xd0, 0xb3,
|
||||
0xaa, 0xaa, 0xa1, 0x17, 0x55, 0x55, 0x45, 0x55, 0x55, 0xcc, 0x66, 0x33, 0x05, 0x05, 0x05, 0x3e,
|
||||
0xa7, 0xd3, 0x59, 0x73, 0xf3, 0xe6, 0xcd, 0xd6, 0x19, 0x90, 0xa8, 0x01, 0xa4, 0x10, 0x82, 0xce,
|
||||
0xce, 0x4e, 0x4d, 0x1b, 0x5c, 0xe8, 0xed, 0x61, 0x6f, 0x7a, 0x26, 0x89, 0x89, 0x89, 0x2b, 0xda,
|
||||
0xdb, 0xdb, 0x3f, 0xcd, 0xcb, 0xcb, 0xd3, 0xdf, 0xba, 0x75, 0xab, 0x59, 0x2b, 0x84, 0x0c, 0x33,
|
||||
0xa7, 0x9f, 0x7d, 0xca, 0xf9, 0xec, 0xfc, 0xa9, 0xd3, 0x08, 0x21, 0x68, 0x68, 0x68, 0xc0, 0xe7,
|
||||
0xf3, 0x19, 0x3a, 0x3a, 0x3a, 0x6a, 0xad, 0x56, 0xeb, 0x0e, 0xad, 0x6e, 0x94, 0x91, 0x14, 0xd0,
|
||||
0xd2, 0x00, 0xba, 0xea, 0xeb, 0x11, 0x42, 0x30, 0x35, 0x35, 0x45, 0x57, 0x57, 0x17, 0x89, 0x89,
|
||||
0x89, 0x4a, 0x5b, 0x5b, 0x5b, 0xad, 0xc5, 0x62, 0x79, 0x5d, 0x0b, 0x84, 0x24, 0x4a, 0xeb, 0x77,
|
||||
0x55, 0x86, 0x20, 0x84, 0x10, 0x48, 0x29, 0x19, 0x1e, 0x1e, 0x46, 0x4a, 0x49, 0x52, 0x52, 0x92,
|
||||
0xd2, 0xda, 0xda, 0x7a, 0x5c, 0x0b, 0x44, 0xd4, 0x00, 0x19, 0xc5, 0x75, 0xa1, 0x8f, 0x03, 0x48,
|
||||
0x29, 0x19, 0x1f, 0x1f, 0x0f, 0xc1, 0x58, 0x2c, 0x16, 0xa5, 0xb9, 0xb9, 0x79, 0x5e, 0x25, 0xa2,
|
||||
0x06, 0x98, 0x6d, 0x41, 0x97, 0x04, 0x01, 0x14, 0x45, 0x41, 0x51, 0x14, 0x52, 0x53, 0x53, 0x75,
|
||||
0x4d, 0x4d, 0x4d, 0xb5, 0xc9, 0xc9, 0xc9, 0x11, 0x21, 0x16, 0x05, 0x30, 0xe0, 0x7e, 0xfb, 0x31,
|
||||
0x08, 0x9f, 0xcf, 0x47, 0x42, 0x42, 0x02, 0xf1, 0xf1, 0xf1, 0x58, 0xad, 0x56, 0xb2, 0xb3, 0xb3,
|
||||
0x71, 0x3a, 0x9d, 0x3a, 0x87, 0xc3, 0x71, 0x24, 0x21, 0x21, 0xe1, 0x9d, 0x70, 0x10, 0x32, 0xd2,
|
||||
0x89, 0xe6, 0x8d, 0x01, 0xb7, 0x83, 0xf4, 0x3d, 0x67, 0x1e, 0x5b, 0xa3, 0xd7, 0xeb, 0x31, 0x9b,
|
||||
0xcd, 0xc4, 0xc6, 0xc6, 0x32, 0x3d, 0x3d, 0x4d, 0x20, 0x10, 0x60, 0x64, 0x64, 0x84, 0x93, 0x27,
|
||||
0x4f, 0xc6, 0x66, 0x66, 0x66, 0x96, 0x6a, 0x06, 0x98, 0x2d, 0x6b, 0xb8, 0x76, 0x65, 0x70, 0x90,
|
||||
0xcc, 0xe2, 0xba, 0xd0, 0x78, 0xc0, 0xed, 0x08, 0xf9, 0x3e, 0x26, 0x26, 0x06, 0xa3, 0xd1, 0x88,
|
||||
0xc1, 0x60, 0xc0, 0x64, 0x32, 0x61, 0x30, 0x18, 0x1e, 0x15, 0x1c, 0x45, 0x89, 0x05, 0xe2, 0x16,
|
||||
0xed, 0x82, 0x6a, 0xcf, 0x55, 0x76, 0xa4, 0xa7, 0x87, 0xc6, 0x6f, 0x1c, 0x3b, 0xfa, 0x44, 0x40,
|
||||
0x06, 0x61, 0xa4, 0x94, 0xe8, 0x74, 0x3a, 0xf4, 0x7a, 0x3d, 0x26, 0x93, 0x09, 0x40, 0xa7, 0xa5,
|
||||
0x12, 0x22, 0x65, 0x64, 0xae, 0xea, 0x82, 0xc2, 0xc7, 0xc6, 0x97, 0x3e, 0x3c, 0xfc, 0x84, 0x72,
|
||||
0xb3, 0x4b, 0xb8, 0x94, 0x12, 0x55, 0x55, 0x31, 0x1a, 0x8d, 0x61, 0x0f, 0xac, 0xf0, 0x3f, 0xd8,
|
||||
0x7f, 0x21, 0x66, 0x5c, 0x00, 0x20, 0x16, 0x1d, 0x03, 0x59, 0x7b, 0x76, 0xa3, 0xb5, 0x52, 0x06,
|
||||
0x9b, 0x94, 0x32, 0x08, 0xc0, 0xa2, 0xb3, 0xa0, 0xa7, 0xb1, 0x29, 0xf4, 0x5c, 0x7a, 0xea, 0x04,
|
||||
0xfd, 0x2e, 0x07, 0x73, 0xed, 0x11, 0xec, 0x75, 0x3a, 0x9d, 0xe6, 0xdb, 0x10, 0xad, 0x97, 0x51,
|
||||
0x43, 0xd5, 0x41, 0x1a, 0xe6, 0x71, 0x45, 0xd0, 0x22, 0x01, 0x44, 0x5d, 0x07, 0xa2, 0xa9, 0x94,
|
||||
0x0b, 0xaa, 0x84, 0x5a, 0xfd, 0xbb, 0xab, 0xe6, 0x98, 0xa6, 0x5b, 0x33, 0x52, 0x66, 0x45, 0xad,
|
||||
0x40, 0xb5, 0xe7, 0x2a, 0xa5, 0xa7, 0x4e, 0x60, 0x2f, 0x2c, 0x5c, 0x7a, 0x05, 0xe6, 0x02, 0x08,
|
||||
0x06, 0xdd, 0xd8, 0xa8, 0x97, 0x86, 0xaa, 0x83, 0xd8, 0x7a, 0xcf, 0x92, 0xb5, 0xbb, 0x48, 0x13,
|
||||
0x84, 0x66, 0x80, 0xb9, 0x82, 0x70, 0x5f, 0xe7, 0x14, 0x17, 0x7a, 0x7b, 0xe8, 0xfc, 0xe6, 0x1a,
|
||||
0xab, 0xf2, 0xed, 0x68, 0x0d, 0x97, 0x48, 0x7b, 0x2a, 0x0b, 0x91, 0xcc, 0xba, 0x75, 0x2b, 0x5d,
|
||||
0xf5, 0xe7, 0xe9, 0xaa, 0x3f, 0xcf, 0x85, 0x1b, 0x3d, 0x20, 0xa0, 0xb8, 0xe6, 0x63, 0xfe, 0x0e,
|
||||
0x04, 0xd8, 0x75, 0xec, 0x28, 0x97, 0x0e, 0x7f, 0xb4, 0x34, 0x0a, 0x44, 0x32, 0xcf, 0x5e, 0x0b,
|
||||
0xd5, 0x9e, 0x16, 0x06, 0xdc, 0x0e, 0x6c, 0x7d, 0xe7, 0x98, 0xbc, 0x37, 0x49, 0x4e, 0x6e, 0x2e,
|
||||
0x4f, 0x2d, 0x5b, 0x86, 0x7d, 0xfb, 0x76, 0xaa, 0x3d, 0x57, 0xb1, 0xda, 0xed, 0x54, 0x7b, 0x5a,
|
||||
0x34, 0xef, 0xa9, 0x09, 0x20, 0xe8, 0xe3, 0x8a, 0xef, 0xa7, 0x00, 0x95, 0xa1, 0x35, 0x07, 0xb8,
|
||||
0xfe, 0x5c, 0x11, 0x5b, 0xc6, 0x9a, 0x58, 0x99, 0x92, 0xc2, 0x2b, 0xf9, 0xf9, 0xd8, 0x7a, 0xcf,
|
||||
0xd2, 0xe2, 0x72, 0x03, 0x2a, 0x63, 0xa3, 0xa3, 0xac, 0xaf, 0x28, 0xd7, 0xa4, 0x80, 0xa2, 0x45,
|
||||
0xae, 0xee, 0xc6, 0x26, 0xd6, 0xee, 0x2e, 0xa2, 0xcc, 0xe9, 0xc4, 0x7b, 0xfb, 0x36, 0x69, 0xdd,
|
||||
0xa7, 0x39, 0xf7, 0xbb, 0x09, 0xef, 0x6a, 0x1b, 0x65, 0x0f, 0xae, 0x71, 0xc4, 0xfb, 0x2c, 0x5f,
|
||||
0xae, 0xd9, 0x42, 0x61, 0x31, 0xec, 0x7c, 0xf0, 0x2d, 0x30, 0xc4, 0x91, 0x95, 0x2b, 0x97, 0x46,
|
||||
0x81, 0x0d, 0xfb, 0x2a, 0x38, 0x74, 0xf1, 0x22, 0x55, 0x1f, 0xbc, 0x8f, 0xad, 0xef, 0x2c, 0x77,
|
||||
0xbc, 0x5e, 0xf6, 0x77, 0x4e, 0xb1, 0xaf, 0xa4, 0x14, 0x21, 0x04, 0xc3, 0x59, 0x07, 0x58, 0xb7,
|
||||
0x69, 0x23, 0x57, 0x5c, 0x6e, 0x9e, 0x8e, 0x7b, 0x06, 0x21, 0x1e, 0x05, 0xea, 0x56, 0x0d, 0xe9,
|
||||
0x39, 0x67, 0x1a, 0x0a, 0x21, 0xd8, 0x50, 0x51, 0x4e, 0xc0, 0xef, 0xa7, 0x2c, 0xe6, 0x17, 0x4a,
|
||||
0x5e, 0xcc, 0x22, 0xa3, 0xb8, 0x8e, 0xa1, 0xbe, 0x3e, 0x02, 0x81, 0x00, 0x3f, 0xfc, 0xf6, 0x2b,
|
||||
0xdf, 0xb5, 0xb5, 0xe1, 0xbd, 0x3b, 0x41, 0x5f, 0x77, 0x0f, 0x39, 0xb9, 0xeb, 0x38, 0x73, 0xbc,
|
||||
0x96, 0x8c, 0xe2, 0x3a, 0x6c, 0xeb, 0xd7, 0x73, 0x67, 0x64, 0x84, 0x55, 0xf9, 0x76, 0xec, 0xef,
|
||||
0xbd, 0x3b, 0x67, 0x5a, 0x47, 0x54, 0x20, 0xb7, 0xbc, 0x8c, 0x07, 0x7e, 0x3f, 0x69, 0x19, 0x19,
|
||||
0xbc, 0xe9, 0xf9, 0x8b, 0x7e, 0x57, 0x25, 0xcd, 0x03, 0x03, 0x6c, 0xde, 0xb6, 0x0d, 0x57, 0x41,
|
||||
0x3c, 0x83, 0x37, 0x7a, 0x71, 0xbf, 0xb6, 0x9c, 0x2d, 0x63, 0x8d, 0xe4, 0xbf, 0xba, 0x99, 0x43,
|
||||
0xcb, 0x87, 0x10, 0x42, 0xd0, 0xef, 0xaa, 0xc4, 0x7f, 0x7f, 0x92, 0xfb, 0x93, 0x93, 0x6c, 0xcc,
|
||||
0xcb, 0x23, 0xe0, 0xf7, 0xcf, 0x59, 0x09, 0x23, 0xfe, 0x0f, 0x7c, 0x51, 0xf8, 0x02, 0x8d, 0xe3,
|
||||
0x71, 0xdc, 0x9b, 0xb8, 0xcb, 0x8a, 0xac, 0x2c, 0xba, 0x9f, 0xdf, 0xc4, 0x1f, 0x1d, 0xd7, 0x11,
|
||||
0x42, 0xf0, 0xd9, 0xc4, 0x0a, 0xf6, 0xbf, 0xb5, 0x93, 0x31, 0x9d, 0x0e, 0xef, 0xf8, 0x9f, 0x74,
|
||||
0x7b, 0x5a, 0x90, 0xf9, 0x0e, 0x3e, 0xa9, 0x85, 0xcf, 0xbf, 0xfe, 0x0a, 0x23, 0x0f, 0xc9, 0xb1,
|
||||
0xbd, 0xc4, 0xda, 0xbb, 0x3f, 0xa2, 0xa6, 0xa6, 0xd1, 0x5d, 0xf2, 0x13, 0x6d, 0x97, 0x2f, 0x87,
|
||||
0x4f, 0xcf, 0x30, 0x73, 0x2f, 0x03, 0x99, 0x80, 0x69, 0x89, 0xff, 0x53, 0x1e, 0x02, 0x7d, 0xc0,
|
||||
0xcf, 0xf3, 0x01, 0x98, 0x81, 0x65, 0x33, 0xfd, 0x52, 0xda, 0x3f, 0x40, 0x60, 0xa6, 0x0f, 0xd9,
|
||||
0xbf, 0x2f, 0x89, 0x69, 0x46, 0x25, 0x68, 0x1c, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e,
|
||||
0x44, 0xae, 0x42, 0x60, 0x82
|
||||
};
|
||||
static unsigned char icon_doc_16_png[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
|
||||
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff,
|
||||
0x61, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
|
||||
0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93,
|
||||
0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13,
|
||||
0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x04,
|
||||
0x06, 0x11, 0x21, 0x22, 0x20, 0xdd, 0x22, 0x10, 0x00, 0x00, 0x01, 0x95, 0x49, 0x44, 0x41, 0x54,
|
||||
0x38, 0xcb, 0x95, 0x93, 0x3d, 0x4b, 0x82, 0x51, 0x14, 0xc7, 0x7f, 0xc7, 0x24, 0x4d, 0x7c, 0x96,
|
||||
0x96, 0x50, 0x48, 0x14, 0x8a, 0x86, 0x16, 0x23, 0x28, 0xea, 0x23, 0xd8, 0xd0, 0xcb, 0x20, 0x86,
|
||||
0x6b, 0x11, 0xb4, 0xd8, 0x10, 0x6d, 0x81, 0xbd, 0x7c, 0x02, 0x5b, 0xa2, 0x10, 0x47, 0x6b, 0x2a,
|
||||
0xa7, 0x1c, 0x0b, 0x24, 0xb3, 0xa9, 0xf7, 0xa1, 0x25, 0xb2, 0x20, 0xe4, 0x59, 0xad, 0xd0, 0xb2,
|
||||
0xdb, 0x50, 0x8f, 0x3c, 0xbe, 0x3c, 0x50, 0x07, 0x2e, 0xdc, 0x73, 0xef, 0x39, 0xff, 0xf3, 0x3b,
|
||||
0x87, 0x7b, 0x45, 0x29, 0x05, 0x80, 0x88, 0x0c, 0x02, 0x1a, 0x16, 0xa6, 0x94, 0x3a, 0x6b, 0x77,
|
||||
0x6e, 0x37, 0xed, 0xb5, 0x68, 0x34, 0x9a, 0x37, 0x1c, 0x8f, 0xcf, 0xc7, 0x4b, 0xb1, 0x08, 0x40,
|
||||
0xa9, 0x54, 0x42, 0x44, 0xc6, 0xda, 0x89, 0x98, 0x05, 0x04, 0xa0, 0x50, 0x28, 0x10, 0xcf, 0x1c,
|
||||
0x12, 0x9f, 0x9c, 0xaa, 0x5f, 0xf4, 0x0e, 0x05, 0xd1, 0x75, 0x3d, 0x2f, 0x22, 0xe3, 0x4a, 0xa9,
|
||||
0xbc, 0x59, 0xc0, 0x66, 0x76, 0x44, 0x04, 0xa0, 0x21, 0x19, 0xe0, 0xfe, 0x34, 0x8f, 0xcb, 0xe5,
|
||||
0x42, 0xd7, 0xf5, 0x53, 0x11, 0x19, 0xb3, 0x12, 0x10, 0x43, 0xa4, 0x79, 0x01, 0x38, 0x1c, 0x0e,
|
||||
0xb3, 0xc8, 0x78, 0xdb, 0x16, 0x8c, 0xe0, 0xe0, 0x6c, 0x84, 0x8b, 0xf4, 0x5e, 0x03, 0x99, 0xd7,
|
||||
0xeb, 0x05, 0x20, 0x10, 0x08, 0xd4, 0x8b, 0x35, 0x13, 0xd8, 0x8c, 0x8a, 0x97, 0x7b, 0xfb, 0xf5,
|
||||
0xea, 0xf3, 0x5b, 0x09, 0x1e, 0x0e, 0x96, 0xd1, 0x34, 0x0d, 0x4d, 0xd3, 0xf0, 0xfb, 0xfd, 0x0d,
|
||||
0x79, 0x2d, 0x04, 0x06, 0x85, 0x61, 0xc9, 0xd8, 0x12, 0x49, 0xc0, 0x6e, 0xff, 0x09, 0x75, 0x3a,
|
||||
0x9d, 0x96, 0x04, 0xd2, 0x9c, 0xdc, 0xce, 0x7e, 0x63, 0xe4, 0x5f, 0x43, 0x0c, 0x6f, 0xac, 0xd3,
|
||||
0x44, 0xf7, 0x37, 0x82, 0x78, 0x26, 0xc3, 0x5c, 0x22, 0x41, 0x68, 0x7a, 0xfa, 0x4f, 0x04, 0xf5,
|
||||
0x21, 0xde, 0xa5, 0x17, 0x11, 0x11, 0x9e, 0x8b, 0x8f, 0x24, 0x63, 0x31, 0x46, 0x6f, 0xb6, 0x19,
|
||||
0x9a, 0x8d, 0x98, 0x29, 0x6c, 0x96, 0x2d, 0x00, 0x2c, 0x1c, 0x7f, 0x92, 0xba, 0xbe, 0xe2, 0x24,
|
||||
0x9b, 0xa5, 0x7f, 0x22, 0x64, 0xbe, 0x6a, 0x89, 0x6d, 0x79, 0xca, 0x7d, 0xa1, 0x10, 0xb9, 0x9d,
|
||||
0x5d, 0x72, 0x3b, 0xbb, 0xa4, 0xae, 0xaf, 0x00, 0x88, 0x6e, 0x6e, 0xf2, 0x5a, 0x2e, 0x13, 0x5e,
|
||||
0x5f, 0xe3, 0xe9, 0x28, 0x6b, 0x29, 0x40, 0xad, 0x56, 0x63, 0xb8, 0xf3, 0x8b, 0x81, 0x99, 0x19,
|
||||
0xdc, 0x5f, 0x6f, 0x64, 0x57, 0x57, 0x78, 0xb3, 0xbb, 0xe9, 0xa9, 0x54, 0xa8, 0x54, 0x3f, 0xa8,
|
||||
0xde, 0xde, 0xd1, 0xed, 0xf1, 0x34, 0xa2, 0x98, 0xbe, 0xf3, 0x08, 0xe0, 0x01, 0xba, 0x00, 0x37,
|
||||
0xe0, 0x00, 0x3a, 0x0c, 0x6d, 0xa0, 0x02, 0x94, 0x81, 0x77, 0xe0, 0x45, 0x29, 0x75, 0x0e, 0xf0,
|
||||
0x0d, 0xff, 0x1c, 0x7a, 0x37, 0x5c, 0xfd, 0x46, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e,
|
||||
0x44, 0xae, 0x42, 0x60, 0x82
|
||||
};
|
29
data/images.h
Normal file
29
data/images.h
Normal file
File diff suppressed because one or more lines are too long
208
generator.py
Normal file
208
generator.py
Normal file
@ -0,0 +1,208 @@
|
||||
import re, os, shutil, string, sys
|
||||
|
||||
def generateElements(elementFiles, outputCpp, outputH):
|
||||
|
||||
elementClasses = dict()
|
||||
baseClasses = dict()
|
||||
|
||||
elementHeader = """#ifndef ELEMENTCLASSES_H
|
||||
#define ELEMENTCLASSES_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "simulation/Element.h"
|
||||
#include "simulation/elements/Element.h"
|
||||
|
||||
"""
|
||||
|
||||
directives = []
|
||||
|
||||
for elementFile in elementFiles:
|
||||
f = open(elementFile, "r")
|
||||
fileData = f.read()
|
||||
f.close()
|
||||
|
||||
directiveMatcher = '//#TPT-Directive\s+([^\r\n]+)'
|
||||
matcher = re.compile(directiveMatcher)
|
||||
directiveMatches = matcher.findall(fileData)
|
||||
|
||||
for match in directiveMatches:
|
||||
directives.append(match.split(" "))
|
||||
|
||||
classDirectives = []
|
||||
for d in directives:
|
||||
if d[0] == "ElementClass":
|
||||
d[3] = string.atoi(d[3])
|
||||
classDirectives.append(d)
|
||||
|
||||
elementIDs = sorted(classDirectives, key=lambda directive: directive[3])
|
||||
|
||||
for d in elementIDs:
|
||||
tmpClass = d[1]
|
||||
newClass = ""
|
||||
baseClass = "Element"
|
||||
if ':' in tmpClass:
|
||||
classBits = tmpClass.split(':')
|
||||
newClass = classBits[0]
|
||||
baseClass = classBits[1]
|
||||
else:
|
||||
newClass = tmpClass
|
||||
|
||||
elementClasses[newClass] = []
|
||||
baseClasses[newClass] = baseClass
|
||||
elementHeader += "#define %s %s\n" % (d[2], d[3])
|
||||
|
||||
for d in directives:
|
||||
if d[0] == "ElementHeader":
|
||||
tmpClass = d[1]
|
||||
newClass = ""
|
||||
baseClass = "Element"
|
||||
if ':' in tmpClass:
|
||||
classBits = tmpClass.split(':')
|
||||
newClass = classBits[0]
|
||||
baseClass = classBits[1]
|
||||
else:
|
||||
newClass = tmpClass
|
||||
elementClasses[newClass].append(string.join(d[2:], " ")+";")
|
||||
|
||||
#for className, classMembers in elementClasses.items():
|
||||
for d in elementIDs:
|
||||
tmpClass = d[1]
|
||||
newClass = ""
|
||||
baseClass = "Element"
|
||||
if ':' in tmpClass:
|
||||
classBits = tmpClass.split(':')
|
||||
newClass = classBits[0]
|
||||
baseClass = classBits[1]
|
||||
else:
|
||||
newClass = tmpClass
|
||||
|
||||
className = newClass
|
||||
classMembers = elementClasses[newClass]
|
||||
elementBase = baseClass
|
||||
elementHeader += """
|
||||
class {0}: public {1}
|
||||
{{
|
||||
public:
|
||||
{0}();
|
||||
virtual ~{0}();
|
||||
{2}
|
||||
}};
|
||||
""".format(className, elementBase, string.join(classMembers, "\n\t"))
|
||||
|
||||
elementHeader += """
|
||||
std::vector<Element> GetElements();
|
||||
|
||||
#endif
|
||||
"""
|
||||
|
||||
elementContent = """#include "ElementClasses.h"
|
||||
|
||||
std::vector<Element> GetElements()
|
||||
{
|
||||
std::vector<Element> elements;
|
||||
""";
|
||||
|
||||
for d in elementIDs:
|
||||
tmpClass = d[1]
|
||||
newClass = ""
|
||||
baseClass = "Element"
|
||||
if ':' in tmpClass:
|
||||
classBits = tmpClass.split(':')
|
||||
newClass = classBits[0]
|
||||
baseClass = classBits[1]
|
||||
else:
|
||||
newClass = tmpClass
|
||||
elementContent += """elements.push_back(%s());
|
||||
""" % (newClass)
|
||||
|
||||
elementContent += """ return elements;
|
||||
}
|
||||
""";
|
||||
|
||||
f = open(outputH, "w")
|
||||
f.write(elementHeader)
|
||||
f.close()
|
||||
|
||||
f = open(outputCpp, "w")
|
||||
f.write(elementContent)
|
||||
f.close()
|
||||
|
||||
def generateTools(toolFiles, outputCpp, outputH):
|
||||
toolClasses = dict()
|
||||
|
||||
toolHeader = """#ifndef TOOLCLASSES_H
|
||||
#define TOOLCLASSES_H
|
||||
#include <vector>
|
||||
#include "simulation/Tools.h"
|
||||
#include "simulation/tools/SimTool.h"
|
||||
"""
|
||||
|
||||
directives = []
|
||||
|
||||
for toolFile in toolFiles:
|
||||
f = open(toolFile, "r")
|
||||
fileData = f.read()
|
||||
f.close()
|
||||
|
||||
directiveMatcher = '//#TPT-Directive\s+([^\r\n]+)'
|
||||
matcher = re.compile(directiveMatcher)
|
||||
directiveMatches = matcher.findall(fileData)
|
||||
|
||||
for match in directiveMatches:
|
||||
directives.append(match.split(" "))
|
||||
|
||||
classDirectives = []
|
||||
for d in directives:
|
||||
if d[0] == "ToolClass":
|
||||
toolClasses[d[1]] = []
|
||||
toolHeader += "#define %s %s\n" % (d[2], d[3])
|
||||
d[3] = string.atoi(d[3])
|
||||
classDirectives.append(d)
|
||||
|
||||
for d in directives:
|
||||
if d[0] == "ToolHeader":
|
||||
toolClasses[d[1]].append(string.join(d[2:], " ")+";")
|
||||
|
||||
for className, classMembers in toolClasses.items():
|
||||
toolHeader += """class {0}: public SimTool
|
||||
{{
|
||||
public:
|
||||
{0}();
|
||||
virtual ~{0}();
|
||||
virtual int Perform(Simulation * sim, Particle * cpart, int x, int y, float strength);
|
||||
{1}
|
||||
}};
|
||||
""".format(className, string.join(classMembers, "\n"))
|
||||
|
||||
toolHeader += """std::vector<SimTool*> GetTools();
|
||||
#endif
|
||||
"""
|
||||
|
||||
toolContent = """#include "ToolClasses.h"
|
||||
std::vector<SimTool*> GetTools()
|
||||
{
|
||||
std::vector<SimTool*> tools;
|
||||
""";
|
||||
|
||||
toolIDs = sorted(classDirectives, key=lambda directive: directive[3])
|
||||
for d in toolIDs:
|
||||
toolContent += """ tools.push_back(new %s());
|
||||
""" % (d[1])
|
||||
|
||||
toolContent += """ return tools;
|
||||
}
|
||||
""";
|
||||
|
||||
f = open(outputH, "w")
|
||||
f.write(toolHeader)
|
||||
f.close()
|
||||
|
||||
f = open(outputCpp, "w")
|
||||
f.write(toolContent)
|
||||
f.close()
|
||||
|
||||
if(sys.argv[1] == "elements"):
|
||||
generateElements(sys.argv[4:], sys.argv[2], sys.argv[3])
|
||||
elif(sys.argv[1] == "tools"):
|
||||
generateTools(sys.argv[4:], sys.argv[2], sys.argv[3])
|
BIN
resources/document.icns
Normal file
BIN
resources/document.icns
Normal file
Binary file not shown.
BIN
resources/document.ico
Normal file
BIN
resources/document.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
4
resources/powder-res.rc
Normal file
4
resources/powder-res.rc
Normal file
@ -0,0 +1,4 @@
|
||||
#define IDI_ICON1 101
|
||||
#define IDI_ICON2 102
|
||||
IDI_ICON1 ICON DISCARDABLE "powder.ico"
|
||||
IDI_ICON2 ICON DISCARDABLE "document.ico"
|
BIN
resources/powder.icns
Executable file
BIN
resources/powder.icns
Executable file
Binary file not shown.
BIN
resources/powder.ico
Normal file
BIN
resources/powder.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 88 KiB |
126
site_scons/site_tools/gch/__init__.py
Normal file
126
site_scons/site_tools/gch/__init__.py
Normal file
@ -0,0 +1,126 @@
|
||||
#
|
||||
# SCons builder for gcc's precompiled headers
|
||||
# Copyright (C) 2006 Tim Blechmann
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
# 1.1
|
||||
#
|
||||
# 09-11-2011 Pedro Larroy: Fixed dependency emitter not working with variant dir
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
||||
import SCons.Scanner.C
|
||||
import SCons.Util
|
||||
import SCons.Script
|
||||
import os
|
||||
|
||||
SCons.Script.EnsureSConsVersion(0,96,92)
|
||||
|
||||
GchAction = SCons.Action.Action('$GCHCOM', '$GCHCOMSTR')
|
||||
GchShAction = SCons.Action.Action('$GCHSHCOM', '$GCHSHCOMSTR')
|
||||
|
||||
def gen_suffix(env, sources):
|
||||
return sources[0].get_suffix() + env['GCHSUFFIX']
|
||||
|
||||
GchShBuilder = SCons.Builder.Builder(action = GchShAction,
|
||||
source_scanner = SCons.Scanner.C.CScanner(),
|
||||
suffix = gen_suffix)
|
||||
|
||||
GchBuilder = SCons.Builder.Builder(action = GchAction,
|
||||
source_scanner = SCons.Scanner.C.CScanner(),
|
||||
suffix = gen_suffix)
|
||||
|
||||
def header_path(node):
|
||||
h_path = node.abspath
|
||||
idx = h_path.rfind('.gch')
|
||||
if idx != -1:
|
||||
h_path = h_path[0:idx]
|
||||
if not os.path.isfile(h_path):
|
||||
raise SCons.Errors.StopError("can't find header file: {0}".format(h_path))
|
||||
return h_path
|
||||
|
||||
else:
|
||||
raise SCons.Errors.StopError("{0} file doesn't have .gch extension".format(h_path))
|
||||
|
||||
|
||||
def static_pch_emitter(target,source,env):
|
||||
SCons.Defaults.StaticObjectEmitter( target, source, env )
|
||||
scanner = SCons.Scanner.C.CScanner()
|
||||
path = scanner.path(env)
|
||||
|
||||
deps = scanner(source[0], env, path)
|
||||
if env.get('Gch'):
|
||||
h_path = header_path(env['Gch'])
|
||||
if h_path in [x.abspath for x in deps]:
|
||||
#print 'Found dep. on pch: ', target[0], ' -> ', env['Gch']
|
||||
env.Depends(target, env['Gch'])
|
||||
|
||||
return (target, source)
|
||||
|
||||
def shared_pch_emitter(target,source,env):
|
||||
SCons.Defaults.SharedObjectEmitter( target, source, env )
|
||||
|
||||
scanner = SCons.Scanner.C.CScanner()
|
||||
path = scanner.path(env)
|
||||
deps = scanner(source[0], env, path)
|
||||
|
||||
if env.get('GchSh'):
|
||||
h_path = header_path(env['GchSh'])
|
||||
if h_path in [x.abspath for x in deps]:
|
||||
#print 'Found dep. on pch (shared): ', target[0], ' -> ', env['Gch']
|
||||
env.Depends(target, env['GchSh'])
|
||||
|
||||
return (target, source)
|
||||
|
||||
def generate(env):
|
||||
"""
|
||||
Add builders and construction variables for the Gch builder.
|
||||
"""
|
||||
env.Append(BUILDERS = {
|
||||
'gch': env.Builder(
|
||||
action = GchAction,
|
||||
target_factory = env.fs.File,
|
||||
),
|
||||
'gchsh': env.Builder(
|
||||
action = GchShAction,
|
||||
target_factory = env.fs.File,
|
||||
),
|
||||
})
|
||||
|
||||
try:
|
||||
bld = env['BUILDERS']['Gch']
|
||||
bldsh = env['BUILDERS']['GchSh']
|
||||
except KeyError:
|
||||
bld = GchBuilder
|
||||
bldsh = GchShBuilder
|
||||
env['BUILDERS']['Gch'] = bld
|
||||
env['BUILDERS']['GchSh'] = bldsh
|
||||
|
||||
env['GCHCOM'] = '$CXX -Wall -o $TARGET -x c++-header -c $CXXFLAGS $CCFLAGS $_CCCOMCOM $SOURCE'
|
||||
env['GCHSHCOM'] = '$CXX -o $TARGET -x c++-header -c $SHCXXFLAGS $CCFLAGS $_CCCOMCOM $SOURCE'
|
||||
env['GCHSUFFIX'] = '.gch'
|
||||
|
||||
for suffix in SCons.Util.Split('.c .C .cc .cxx .cpp .c++'):
|
||||
env['BUILDERS']['StaticObject'].add_emitter( suffix, static_pch_emitter )
|
||||
env['BUILDERS']['SharedObject'].add_emitter( suffix, shared_pch_emitter )
|
||||
|
||||
|
||||
def exists(env):
|
||||
return env.Detect('g++')
|
BIN
site_scons/site_tools/gch/__init__.pyc
Normal file
BIN
site_scons/site_tools/gch/__init__.pyc
Normal file
Binary file not shown.
241
site_scons/site_tools/mfprogram/__init__.py
Normal file
241
site_scons/site_tools/mfprogram/__init__.py
Normal file
@ -0,0 +1,241 @@
|
||||
#
|
||||
# Copyright (c) 2010 Western Digital Corporation
|
||||
# Alan Somers asomers (at) gmail (dot) com
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
####
|
||||
import os
|
||||
import new
|
||||
import sys
|
||||
##
|
||||
import SCons
|
||||
|
||||
if sys.version_info < (2,6,0):
|
||||
from relpath import relpath
|
||||
else:
|
||||
from os.path import relpath
|
||||
|
||||
|
||||
def sc_relpath(src, destdir):
|
||||
"""Like relpath but aware of SCons convention regarding '#' in pathnames"""
|
||||
if src[0] == '#':
|
||||
return relpath(src[1:], destdir)
|
||||
else:
|
||||
return relpath(os.path.join(destdir, src), destdir)
|
||||
|
||||
|
||||
|
||||
class MF_Executor(SCons.Executor.Executor):
|
||||
"""Custom Executor that can scan each target file for its dependencies
|
||||
individually, rather than giving every target the same deps.
|
||||
Assumes that there is a one-to-one relationship between sources and targets
|
||||
and the targets have the same basenames as their respective sources
|
||||
ie. [[foo.o, bar.o], [foo.c, bar.c]]"""
|
||||
def scan(self, scanner, node_list):
|
||||
tgt_names = [os.path.splitext(
|
||||
os.path.basename(str(i)))[0] for i in self.targets]
|
||||
env = self.get_build_env()
|
||||
|
||||
if scanner:
|
||||
for node in node_list:
|
||||
tgt = \
|
||||
self.targets[tgt_names.index(
|
||||
os.path.splitext(
|
||||
os.path.basename(str(node)))[0])]
|
||||
node.disambiguate()
|
||||
s = scanner.select(node)
|
||||
if not s:
|
||||
continue
|
||||
path = self.get_build_scanner_path(s)
|
||||
tgt.add_to_implicit(node.get_implicit_deps(env, s, path))
|
||||
else:
|
||||
kw = self.get_kw()
|
||||
for node in node_list:
|
||||
tgt = \
|
||||
self.targets[tgt_names.index(
|
||||
os.path.splitext(
|
||||
os.path.basename(str(node)))[0])]
|
||||
node.disambiguate()
|
||||
scanner = node.get_env_scanner(env, kw)
|
||||
if not scanner:
|
||||
continue
|
||||
scanner = scanner.select(node)
|
||||
if not scanner:
|
||||
continue
|
||||
path = self.get_build_scanner_path(scanner)
|
||||
tgt.add_to_implicit(node.get_implicit_deps(env, scanner, path))
|
||||
|
||||
|
||||
def MF_get_single_executor(self, env, tlist, slist, executor_kw):
|
||||
if not self.action:
|
||||
raise UserError, "Builder %s must have an action to build %s." % \
|
||||
(self.get_name(env or self.env), map(str,tlist))
|
||||
return MF_Executor(self.action, env, [], tlist, slist, executor_kw)
|
||||
|
||||
def exists(env):
|
||||
return env.WhereIs(env.subst['$CC']) or env.WhereIs(env.subst['$CXX'])
|
||||
|
||||
def MFProgramEmitter(target, source, env):
|
||||
"""Ensures that target list is complete, and does validity checking. Sets precious"""
|
||||
if len(target) == 1 and len(source) > 1:
|
||||
#Looks like the user specified many sources and SCons created 1 target
|
||||
#targets are implicit, but the builder doesn't know how to handle
|
||||
#suffixes for multiple target files, so we'll do it here
|
||||
objdir = env.get('OBJDIR', '')
|
||||
#target = [os.path.join(
|
||||
# objdir,
|
||||
# os.path.splitext(
|
||||
# os.path.basename(str(i)))[0] + '.o' ) for i in source]
|
||||
elif len(source) == 1 and 'OBJDIR' in env:
|
||||
target = os.path.join(
|
||||
env['OBJDIR'],
|
||||
os.path.splitext(
|
||||
os.path.basename(str(source[0])))[0] + '.o' )
|
||||
else:
|
||||
#targets are explicit, we need to check their validity
|
||||
tgt_names = [os.path.splitext(
|
||||
os.path.basename(str(i)))[0] for i in target]
|
||||
src_names = [os.path.splitext(
|
||||
os.path.basename(str(i)))[0] for i in source]
|
||||
tgt_dirs = [os.path.dirname(str(i)) for i in target]
|
||||
if sorted(tgt_names) != sorted(src_names):
|
||||
raise ValueError, "target files do not have obvious one-one relationship to source files"
|
||||
if len(set(src_names)) != len(src_names):
|
||||
raise ValueError, "source files may not include identically named files in different directories"
|
||||
if len(set(tgt_dirs)) != 1:
|
||||
raise ValueError, "Target files must all be in same directory"
|
||||
|
||||
for t in target:
|
||||
env.Precious(t)
|
||||
return target, source
|
||||
|
||||
def MFProgramGenerator(source, target, env, for_signature):
|
||||
#Rebuild everything if
|
||||
# a) the number of dependencies has changed
|
||||
# b) any target does not exist
|
||||
# c) the build command has changed
|
||||
#Else rebuild only those c files that have changed_since_last_build
|
||||
#The signature of this builder should always be the same, because the
|
||||
#multifile compile is always functionally equivalent to rebuilding
|
||||
#everything
|
||||
|
||||
if for_signature:
|
||||
pared_sources = source
|
||||
else:
|
||||
#First a sanity check
|
||||
assert len(set([os.path.splitext(str(i))[1] for i in source])) == 1, \
|
||||
"All source files must have the same extension."
|
||||
pared_sources = []
|
||||
src_names = [os.path.splitext(os.path.basename(str(i)))[0]
|
||||
for i in source]
|
||||
tgt_names = [os.path.splitext(os.path.basename(str(t)))[0]
|
||||
for t in target]
|
||||
ni = target[0].get_binfo()
|
||||
oi = target[0].get_stored_info().binfo
|
||||
if ni.bactsig != oi.bactsig:
|
||||
#Command line has changed
|
||||
pared_sources = source
|
||||
else:
|
||||
for i in range(len(tgt_names)):
|
||||
t = target[i]
|
||||
tgt_name = tgt_names[i]
|
||||
if not t.exists():
|
||||
#a target does not exist
|
||||
pared_sources = source
|
||||
break
|
||||
bi = t.get_stored_info().binfo
|
||||
then = bi.bsourcesigs + bi.bdependsigs + bi.bimplicitsigs
|
||||
children = t.children()
|
||||
if len(children) != len(then):
|
||||
#the number of dependencies has changed
|
||||
pared_sources = source
|
||||
break
|
||||
for child, prev_ni in zip(children, then):
|
||||
if child.changed_since_last_build(t, prev_ni) and \
|
||||
not t in pared_sources:
|
||||
#If child is a source file, not an explicit or implicit
|
||||
#dependency, then it is not truly a dependency of any target
|
||||
#except that with the same basename. This is a limitation
|
||||
#of SCons.node, which assumes that all sources of a Node
|
||||
#are dependencies of all targets. So we check for that case
|
||||
#here and only rebuild as necessary.
|
||||
src_name = os.path.splitext(os.path.basename(str(child)))[0]
|
||||
if src_name not in tgt_names or src_name == tgt_name:
|
||||
s = source[src_names.index(tgt_name)]
|
||||
pared_sources.append(s)
|
||||
assert len(pared_sources) > 0
|
||||
destdir = str(target[0].dir)
|
||||
#finding sconscript_dir is a bit of a hack. It assumes that the source
|
||||
#files are always going to be in the same directory as the SConscript file
|
||||
#which is not necessarily true. BUG BY Alan Somers
|
||||
sconscript_dir = os.path.dirname(str(pared_sources[0]))
|
||||
prefixed_sources = [relpath(str(i), destdir) for i in pared_sources]
|
||||
prefixed_sources_str = ' '.join([str(i) for i in prefixed_sources])
|
||||
lang_ext = os.path.splitext(prefixed_sources[0])[1]
|
||||
tgt_names2 = [os.path.splitext(os.path.basename(str(t)))[0]
|
||||
for t in target]
|
||||
|
||||
_CPPPATH = []
|
||||
if 'CPPPATH' in env:
|
||||
for i in env['CPPPATH']:
|
||||
#if i[0] == '#':
|
||||
##_CPPPATH.append(relpath(i[1:], destdir))
|
||||
_CPPPATH.append(i)
|
||||
#else:
|
||||
# _CPPPATH.append(relpath(os.path.join(sconscript_dir, i),
|
||||
# destdir))
|
||||
|
||||
defines = ""
|
||||
for t in env['CPPDEFINES']:
|
||||
defines += ("-D"+str(t)+" ")
|
||||
|
||||
_CPPINCFLAGS = ['-I' + i for i in _CPPPATH]
|
||||
_CCOMCOM = '$CPPFLAGS $_CPPDEFFLAGS $defines %s' % ' '.join(_CPPINCFLAGS)
|
||||
|
||||
libstr = ""
|
||||
for t in env['LIBS']:
|
||||
libstr += ("-l"+t+" ")
|
||||
|
||||
if lang_ext == '.c' :
|
||||
_CCCOM = 'cd %s && $CC $CFLAGS $CCFLAGS %s %s $LINKFLAGS %s -o %s' % \
|
||||
(destdir, _CCOMCOM, prefixed_sources_str, libstr, tgt_names2[0])
|
||||
#XXX BUG BY Alan Somers. $CCCOMSTR gets substituted using the full list of target files,
|
||||
#not prefixed_sources
|
||||
cmd = SCons.Script.Action(env.subst(_CCCOM), "$CCCOMSTR")
|
||||
elif lang_ext in ['.cc', '.cpp']:
|
||||
_CXXCOM = 'cd %s && $CXX $CXXFLAGS $CCFLAGS %s %s $LINKFLAGS %s -o %s' % \
|
||||
(destdir, _CCOMCOM, prefixed_sources_str, libstr, tgt_names2[0])
|
||||
cmd = SCons.Script.Action(env.subst(_CXXCOM), "$CXXCOMSTR")
|
||||
else:
|
||||
assert False, "Unknown source file extension %s" % lang_ext
|
||||
return cmd
|
||||
|
||||
def generate(env):
|
||||
"""Adds the MFObject builder to your environment"""
|
||||
MFProgramBld = env.Builder(generator = MFProgramGenerator,
|
||||
emitter = MFProgramEmitter,
|
||||
suffix = '.o',
|
||||
source_scanner=SCons.Tool.SourceFileScanner)
|
||||
MFProgramBld.get_single_executor = new.instancemethod(MF_get_single_executor,
|
||||
MFProgramBld, MFProgramBld.__class__)
|
||||
|
||||
env.Append(BUILDERS = {'MFProgram': MFProgramBld})
|
BIN
site_scons/site_tools/mfprogram/__init__.pyc
Normal file
BIN
site_scons/site_tools/mfprogram/__init__.pyc
Normal file
Binary file not shown.
73
site_scons/site_tools/mfprogram/relpath.py
Normal file
73
site_scons/site_tools/mfprogram/relpath.py
Normal file
@ -0,0 +1,73 @@
|
||||
#PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
|
||||
#--------------------------------------------
|
||||
#
|
||||
#1. This LICENSE AGREEMENT is between the Python Software Foundation
|
||||
#("PSF"), and the Individual or Organization ("Licensee") accessing and
|
||||
#otherwise using this software ("Python") in source or binary form and
|
||||
#its associated documentation.
|
||||
#
|
||||
#2. Subject to the terms and conditions of this License Agreement, PSF hereby
|
||||
#grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
|
||||
#analyze, test, perform and/or display publicly, prepare derivative works,
|
||||
#distribute, and otherwise use Python alone or in any derivative version,
|
||||
#provided, however, that PSF's License Agreement and PSF's notice of copyright,
|
||||
#i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||
#Python Software Foundation; All Rights Reserved" are retained in Python alone or
|
||||
#in any derivative version prepared by Licensee.
|
||||
#
|
||||
#3. In the event Licensee prepares a derivative work that is based on
|
||||
#or incorporates Python or any part thereof, and wants to make
|
||||
#the derivative work available to others as provided herein, then
|
||||
#Licensee hereby agrees to include in any such work a brief summary of
|
||||
#the changes made to Python.
|
||||
#
|
||||
#4. PSF is making Python available to Licensee on an "AS IS"
|
||||
#basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||
#IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
|
||||
#DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||
#FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
|
||||
#INFRINGE ANY THIRD PARTY RIGHTS.
|
||||
#
|
||||
#5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
||||
#FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
||||
#A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
|
||||
#OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||
#
|
||||
#6. This License Agreement will automatically terminate upon a material
|
||||
#breach of its terms and conditions.
|
||||
#
|
||||
#7. Nothing in this License Agreement shall be deemed to create any
|
||||
#relationship of agency, partnership, or joint venture between PSF and
|
||||
#Licensee. This License Agreement does not grant permission to use PSF
|
||||
#trademarks or trade name in a trademark sense to endorse or promote
|
||||
#products or services of Licensee, or any third party.
|
||||
#
|
||||
#8. By copying, installing or otherwise using Python, Licensee
|
||||
#agrees to be bound by the terms and conditions of this License
|
||||
#Agreement.
|
||||
|
||||
|
||||
|
||||
# Changelog:
|
||||
# 3-12-2010 Alan Somers Copied verbatim from posixpath.py in Python 2.6.4
|
||||
|
||||
|
||||
|
||||
from os.path import *
|
||||
|
||||
def relpath(path, start=curdir):
|
||||
"""Return a relative version of a path"""
|
||||
|
||||
if not path:
|
||||
raise ValueError("no path specified")
|
||||
|
||||
start_list = abspath(start).split(sep)
|
||||
path_list = abspath(path).split(sep)
|
||||
|
||||
# Work out how much of the filepath is shared by start and path.
|
||||
i = len(commonprefix([start_list, path_list]))
|
||||
|
||||
rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
|
||||
if not rel_list:
|
||||
return curdir
|
||||
return join(*rel_list)
|
42
src/Activity.h
Normal file
42
src/Activity.h
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "interface/Window.h"
|
||||
|
||||
class Activity
|
||||
{
|
||||
public:
|
||||
virtual void Exit() {}
|
||||
virtual void Show() {}
|
||||
virtual void Hide() {}
|
||||
virtual ~Activity() {}
|
||||
};
|
||||
|
||||
class WindowActivity: public ui::Window, public Activity
|
||||
{
|
||||
public:
|
||||
WindowActivity(ui::Point position, ui::Point size) :
|
||||
ui::Window(position, size)
|
||||
{
|
||||
Show();
|
||||
}
|
||||
virtual void Exit()
|
||||
{
|
||||
Hide();
|
||||
SelfDestruct();
|
||||
}
|
||||
virtual void Show()
|
||||
{
|
||||
if(ui::Engine::Ref().GetWindow() != this)
|
||||
{
|
||||
ui::Engine::Ref().ShowWindow(this);
|
||||
}
|
||||
}
|
||||
virtual void Hide()
|
||||
{
|
||||
if(ui::Engine::Ref().GetWindow() == this)
|
||||
{
|
||||
ui::Engine::Ref().CloseWindow();
|
||||
}
|
||||
}
|
||||
virtual ~WindowActivity() {}
|
||||
};
|
214
src/Config.h
Normal file
214
src/Config.h
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Config.h
|
||||
*
|
||||
* Created on: Jan 5, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
//#ifndef CONFIG_H_
|
||||
//#define CONFIG_H_
|
||||
|
||||
|
||||
#ifdef WIN
|
||||
#define PATH_SEP "\\"
|
||||
#else
|
||||
#define PATH_SEP "/"
|
||||
#endif
|
||||
|
||||
//VersionInfoStart
|
||||
#ifndef SAVE_VERSION
|
||||
#define SAVE_VERSION 84
|
||||
#endif
|
||||
|
||||
#ifndef MINOR_VERSION
|
||||
#define MINOR_VERSION 2
|
||||
#endif
|
||||
|
||||
#ifndef BUILD_NUM
|
||||
#define BUILD_NUM 248
|
||||
#endif
|
||||
|
||||
#ifndef SNAPSHOT_ID
|
||||
#define SNAPSHOT_ID 0
|
||||
#endif
|
||||
|
||||
#ifndef STABLE
|
||||
#ifndef BETA
|
||||
#define BETA
|
||||
#define SNAPSHOT
|
||||
#endif
|
||||
#endif
|
||||
//VersionInfoEnd
|
||||
|
||||
#if defined(SNAPSHOT)
|
||||
#define IDENT_RELTYPE "S"
|
||||
#elif defined(BETA)
|
||||
#define IDENT_RELTYPE "B"
|
||||
#else
|
||||
#define IDENT_RELTYPE "R"
|
||||
#endif
|
||||
|
||||
#if defined(WIN)
|
||||
#if defined(_64BIT)
|
||||
#define IDENT_PLATFORM "WIN64"
|
||||
#else
|
||||
#define IDENT_PLATFORM "WIN32"
|
||||
#endif
|
||||
#elif defined(LIN)
|
||||
#if defined(_64BIT)
|
||||
#define IDENT_PLATFORM "LIN64"
|
||||
#else
|
||||
#define IDENT_PLATFORM "LIN32"
|
||||
#endif
|
||||
#elif defined(MACOSX)
|
||||
#define IDENT_PLATFORM "MACOSX"
|
||||
#else
|
||||
#define IDENT_PLATFORM "UNKNOWN"
|
||||
#endif
|
||||
|
||||
#if defined(X86_SSE3)
|
||||
#define IDENT_BUILD "SSE3"
|
||||
#elif defined(X86_SSE2)
|
||||
#define IDENT_BUILD "SSE2"
|
||||
#elif defined(X86_SSE)
|
||||
#define IDENT_BUILD "SSE"
|
||||
#else
|
||||
#define IDENT_BUILD "NO"
|
||||
#endif
|
||||
|
||||
#define IDENT_VERSION "G" //Change this if you're not Simon! It should be a single letter
|
||||
|
||||
#define MTOS_EXPAND(str) #str
|
||||
#define MTOS(str) MTOS_EXPAND(str)
|
||||
|
||||
#define SERVER "powdertoy.co.uk"
|
||||
#define SCRIPTSERVER "powdertoy.co.uk"
|
||||
#define STATICSERVER "static.powdertoy.co.uk"
|
||||
|
||||
#define LOCAL_SAVE_DIR "Saves"
|
||||
|
||||
#define STAMPS_DIR "stamps"
|
||||
|
||||
#define APPDATA_SUBDIR "\\HardWIRED"
|
||||
|
||||
//Number of unique thumbnails to have in cache at one time
|
||||
#define THUMB_CACHE_SIZE 256
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265f
|
||||
#endif
|
||||
#ifndef M_GRAV
|
||||
#define M_GRAV 6.67300e-1
|
||||
#endif
|
||||
|
||||
//Number of asynchronous connections used to retrieve thumnails
|
||||
#define IMGCONNS 5
|
||||
//Not sure
|
||||
#define TIMEOUT 100
|
||||
//HTTP request timeout in seconds
|
||||
#define HTTP_TIMEOUT 10
|
||||
|
||||
#ifdef RENDERER
|
||||
#define MENUSIZE 0
|
||||
#define BARSIZE 0
|
||||
#else
|
||||
#define MENUSIZE 40
|
||||
//#define MENUSIZE 20
|
||||
//#define BARSIZE 50
|
||||
#define BARSIZE 17
|
||||
#endif
|
||||
#define XRES 612
|
||||
#define YRES 384
|
||||
#define NPART XRES*YRES
|
||||
|
||||
#define XCNTR 306
|
||||
#define YCNTR 192
|
||||
|
||||
#define MAX_DISTANCE sqrt(pow((float)XRES, 2)+pow((float)YRES, 2))
|
||||
|
||||
#define GRAV_DIFF
|
||||
|
||||
#define MAXSIGNS 16
|
||||
#define TAG_MAX 256
|
||||
|
||||
#define ZSIZE_D 16
|
||||
#define ZFACTOR_D 8
|
||||
extern unsigned char ZFACTOR;
|
||||
extern unsigned char ZSIZE;
|
||||
|
||||
#define CELL 4
|
||||
#define ISTP (CELL/2)
|
||||
#define CFDS (4.0f/CELL)
|
||||
|
||||
#define AIR_TSTEPP 0.3f
|
||||
#define AIR_TSTEPV 0.4f
|
||||
#define AIR_VADV 0.3f
|
||||
#define AIR_VLOSS 0.999f
|
||||
#define AIR_PLOSS 0.9999f
|
||||
|
||||
#define GRID_X 5
|
||||
#define GRID_Y 4
|
||||
#define GRID_P 3
|
||||
#define GRID_S 6
|
||||
#define GRID_Z 3
|
||||
|
||||
#define CATALOGUE_X 4
|
||||
#define CATALOGUE_Y 3
|
||||
#define CATALOGUE_S 6
|
||||
#define CATALOGUE_Z 3
|
||||
|
||||
#define STAMP_MAX 240
|
||||
|
||||
#define SAVE_OPS
|
||||
|
||||
#define NGOL 24
|
||||
#define NGOLALT 24 //NGOL should be 24, but use this var until I find out why
|
||||
|
||||
#define CIRCLE_BRUSH 0
|
||||
#define SQUARE_BRUSH 1
|
||||
#define TRI_BRUSH 2
|
||||
#define BRUSH_NUM 3
|
||||
|
||||
#define SURF_RANGE 10
|
||||
#define NORMAL_MIN_EST 3
|
||||
#define NORMAL_INTERP 20
|
||||
#define NORMAL_FRAC 16
|
||||
|
||||
#define REFRACT 0x80000000
|
||||
|
||||
/* heavy flint glass, for awesome refraction/dispersion
|
||||
this way you can make roof prisms easily */
|
||||
#define GLASS_IOR 1.9
|
||||
#define GLASS_DISP 0.07
|
||||
|
||||
#ifdef WIN
|
||||
#define strcasecmp stricmp
|
||||
#endif
|
||||
#if defined(_MSC_VER)
|
||||
#define fmin min
|
||||
#define fminf min
|
||||
#define fmax max
|
||||
#define fmaxf max
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define TPT_INLINE _inline
|
||||
#define TPT_NO_INLINE
|
||||
#elif defined(__llvm__)
|
||||
#define TPT_INLINE
|
||||
#define TPT_NO_INLINE
|
||||
#else
|
||||
#define TPT_INLINE inline
|
||||
#define TPT_NO_INLINE inline
|
||||
#endif
|
||||
|
||||
#define SDEUT
|
||||
//#define REALHEAT
|
||||
|
||||
#define DEBUG_PARTS 0x0001
|
||||
#define DEBUG_PARTCOUNT 0x0002
|
||||
#define DEBUG_DRAWTOOL 0x0004
|
||||
#define DEBUG_PERFORMANCE_CALC 0x0008
|
||||
#define DEBUG_PERFORMANCE_FRAME 0x0010
|
||||
|
||||
//#endif /* CONFIG_H_ */
|
27
src/Controller.h
Normal file
27
src/Controller.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Controller.h
|
||||
*
|
||||
* Created on: Jan 25, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#ifndef CONTROLLER_H_
|
||||
#define CONTROLLER_H_
|
||||
|
||||
class ControllerCallback
|
||||
{
|
||||
public:
|
||||
ControllerCallback() {}
|
||||
virtual void ControllerExit() {}
|
||||
virtual ~ControllerCallback() {}
|
||||
};
|
||||
|
||||
class Controller
|
||||
{
|
||||
private:
|
||||
virtual void Exit();
|
||||
virtual void Show();
|
||||
virtual void Hide();
|
||||
};
|
||||
|
||||
#endif /* CONTROLLER_H_ */
|
369
src/Format.cpp
Normal file
369
src/Format.cpp
Normal file
@ -0,0 +1,369 @@
|
||||
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <zlib.h>
|
||||
#include <stdio.h>
|
||||
#include "Format.h"
|
||||
#include "graphics/Graphics.h"
|
||||
|
||||
std::string format::URLEncode(std::string source)
|
||||
{
|
||||
char * src = (char *)source.c_str();
|
||||
char * dst = new char[(source.length()*3)+2];
|
||||
std::fill(dst, dst+(source.length()*3)+2, 0);
|
||||
|
||||
char *d;
|
||||
unsigned char *s;
|
||||
|
||||
for (d=dst; *d; d++) ;
|
||||
|
||||
for (s=(unsigned char *)src; *s; s++)
|
||||
{
|
||||
if ((*s>='0' && *s<='9') ||
|
||||
(*s>='a' && *s<='z') ||
|
||||
(*s>='A' && *s<='Z'))
|
||||
*(d++) = *s;
|
||||
else
|
||||
{
|
||||
*(d++) = '%';
|
||||
*(d++) = hex[*s>>4];
|
||||
*(d++) = hex[*s&15];
|
||||
}
|
||||
}
|
||||
*d = 0;
|
||||
|
||||
std::string finalString(dst);
|
||||
delete[] dst;
|
||||
return finalString;
|
||||
}
|
||||
|
||||
std::string format::UnixtimeToDate(time_t unixtime, std::string dateFormat)
|
||||
{
|
||||
struct tm * timeData;
|
||||
char buffer[128];
|
||||
|
||||
timeData = localtime(&unixtime);
|
||||
|
||||
strftime(buffer, 128, dateFormat.c_str(), timeData);
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
std::string format::UnixtimeToDateMini(time_t unixtime)
|
||||
{
|
||||
time_t currentTime = time(NULL);
|
||||
struct tm currentTimeData = *localtime(¤tTime);
|
||||
struct tm timeData = *localtime(&unixtime);
|
||||
|
||||
if(currentTimeData.tm_year != timeData.tm_year)
|
||||
{
|
||||
return UnixtimeToDate(unixtime, "%b %Y");
|
||||
}
|
||||
else if(currentTimeData.tm_mon != timeData.tm_mon || currentTimeData.tm_mday != timeData.tm_mday)
|
||||
{
|
||||
return UnixtimeToDate(unixtime, "%d %B");
|
||||
}
|
||||
else
|
||||
{
|
||||
return UnixtimeToDate(unixtime, "%H:%M:%S");
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<char> format::VideoBufferToPTI(const VideoBuffer & vidBuf)
|
||||
{
|
||||
std::vector<char> data;
|
||||
int dataSize = 0;
|
||||
char * buffer = (char*)Graphics::ptif_pack(vidBuf.Buffer, vidBuf.Width, vidBuf.Height, &dataSize);
|
||||
|
||||
if(buffer)
|
||||
{
|
||||
data.insert(data.end(), buffer, buffer+dataSize);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
std::vector<char> format::VideoBufferToPPM(const VideoBuffer & vidBuf)
|
||||
{
|
||||
std::vector<char> data;
|
||||
char buffer[256];
|
||||
sprintf(buffer, "P6\n%d %d\n255\n", vidBuf.Width, vidBuf.Height);
|
||||
data.insert(data.end(), buffer, buffer+strlen(buffer));
|
||||
|
||||
unsigned char * currentRow = new unsigned char[vidBuf.Width*3];
|
||||
for(int y = 0; y < vidBuf.Height; y++)
|
||||
{
|
||||
int rowPos = 0;
|
||||
for(int x = 0; x < vidBuf.Width; x++)
|
||||
{
|
||||
currentRow[rowPos++] = PIXR(vidBuf.Buffer[(y*vidBuf.Width)+x]);
|
||||
currentRow[rowPos++] = PIXG(vidBuf.Buffer[(y*vidBuf.Width)+x]);
|
||||
currentRow[rowPos++] = PIXB(vidBuf.Buffer[(y*vidBuf.Width)+x]);
|
||||
}
|
||||
data.insert(data.end(), currentRow, currentRow+(vidBuf.Width*3));
|
||||
}
|
||||
delete currentRow;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
struct PNGChunk
|
||||
{
|
||||
int Length;
|
||||
char Name[4];
|
||||
char * Data;
|
||||
|
||||
//char[4] CRC();
|
||||
|
||||
PNGChunk(int length, std::string name)
|
||||
{
|
||||
if(name.length()!=4)
|
||||
throw std::runtime_error("Invalid chunk name");
|
||||
std::copy(name.begin(), name.begin()+4, Name);
|
||||
Length = length;
|
||||
if(length)
|
||||
{
|
||||
Data = new char[length];
|
||||
std::fill(Data, Data+length, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Data = NULL;
|
||||
}
|
||||
}
|
||||
unsigned long CRC()
|
||||
{
|
||||
if(!Data)
|
||||
{
|
||||
return format::CalculateCRC((unsigned char*)Name, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char * temp = new unsigned char[4+Length];
|
||||
std::copy(Name, Name+4, temp);
|
||||
std::copy(Data, Data+Length, temp+4);
|
||||
unsigned long tempRet = format::CalculateCRC(temp, 4+Length);
|
||||
delete[] temp;
|
||||
return tempRet;
|
||||
}
|
||||
}
|
||||
~PNGChunk()
|
||||
{
|
||||
if(Data)
|
||||
delete[] Data;
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<char> format::VideoBufferToPNG(const VideoBuffer & vidBuf)
|
||||
{
|
||||
std::vector<PNGChunk*> chunks;
|
||||
|
||||
//Begin IHDR (Image header) chunk (Image size and depth)
|
||||
PNGChunk IHDRChunk = PNGChunk(13, "IHDR");
|
||||
|
||||
//Image Width
|
||||
IHDRChunk.Data[0] = (vidBuf.Width>>24)&0xFF;
|
||||
IHDRChunk.Data[1] = (vidBuf.Width>>16)&0xFF;
|
||||
IHDRChunk.Data[2] = (vidBuf.Width>>8)&0xFF;
|
||||
IHDRChunk.Data[3] = (vidBuf.Width)&0xFF;
|
||||
|
||||
//Image Height
|
||||
IHDRChunk.Data[4] = (vidBuf.Height>>24)&0xFF;
|
||||
IHDRChunk.Data[5] = (vidBuf.Height>>16)&0xFF;
|
||||
IHDRChunk.Data[6] = (vidBuf.Height>>8)&0xFF;
|
||||
IHDRChunk.Data[7] = (vidBuf.Height)&0xFF;
|
||||
|
||||
//Bit depth
|
||||
IHDRChunk.Data[8] = 8; //8bits per channel or 24bpp
|
||||
|
||||
//Colour type
|
||||
IHDRChunk.Data[9] = 2; //RGB triple
|
||||
|
||||
//Everything else is default
|
||||
chunks.push_back(&IHDRChunk);
|
||||
|
||||
//Begin image data, format is 8bit RGB (24bit pixel)
|
||||
int dataPos = 0;
|
||||
unsigned char * uncompressedData = new unsigned char[(vidBuf.Width*vidBuf.Height*3)+vidBuf.Height];
|
||||
|
||||
//Byte ordering and filtering
|
||||
unsigned char * previousRow = new unsigned char[vidBuf.Width*3];
|
||||
std::fill(previousRow, previousRow+(vidBuf.Width*3), 0);
|
||||
unsigned char * currentRow = new unsigned char[vidBuf.Width*3];
|
||||
for(int y = 0; y < vidBuf.Height; y++)
|
||||
{
|
||||
int rowPos = 0;
|
||||
for(int x = 0; x < vidBuf.Width; x++)
|
||||
{
|
||||
currentRow[rowPos++] = PIXR(vidBuf.Buffer[(y*vidBuf.Width)+x]);
|
||||
currentRow[rowPos++] = PIXG(vidBuf.Buffer[(y*vidBuf.Width)+x]);
|
||||
currentRow[rowPos++] = PIXB(vidBuf.Buffer[(y*vidBuf.Width)+x]);
|
||||
}
|
||||
|
||||
uncompressedData[dataPos++] = 2; //Up Sub(x) filter
|
||||
for(int b = 0; b < rowPos; b++)
|
||||
{
|
||||
int filteredByte = (currentRow[b]-previousRow[b])&0xFF;
|
||||
uncompressedData[dataPos++] = filteredByte;
|
||||
}
|
||||
|
||||
unsigned char * tempRow = previousRow;
|
||||
previousRow = currentRow;
|
||||
currentRow = tempRow;
|
||||
}
|
||||
delete[] currentRow;
|
||||
delete[] previousRow;
|
||||
|
||||
//Compression
|
||||
int compressedBufferSize = (vidBuf.Width*vidBuf.Height*3)*2;
|
||||
unsigned char * compressedData = new unsigned char[compressedBufferSize];
|
||||
|
||||
int result;
|
||||
z_stream zipStream;
|
||||
zipStream.zalloc = Z_NULL;
|
||||
zipStream.zfree = Z_NULL;
|
||||
zipStream.opaque = Z_NULL;
|
||||
|
||||
result = deflateInit2(&zipStream,
|
||||
9, // level
|
||||
Z_DEFLATED, // method
|
||||
10, // windowBits
|
||||
1, // memLevel
|
||||
Z_DEFAULT_STRATEGY // strategy
|
||||
);
|
||||
|
||||
if (result != Z_OK) exit(result);
|
||||
|
||||
zipStream.next_in = uncompressedData;
|
||||
zipStream.avail_in = dataPos;
|
||||
|
||||
zipStream.next_out = compressedData;
|
||||
zipStream.avail_out = compressedBufferSize;
|
||||
|
||||
|
||||
result = deflate(&zipStream, Z_FINISH);
|
||||
if (result != Z_STREAM_END) exit(result);
|
||||
|
||||
int compressedSize = compressedBufferSize-zipStream.avail_out;
|
||||
PNGChunk IDATChunk = PNGChunk(compressedSize, "IDAT");
|
||||
std::copy(compressedData, compressedData+compressedSize, IDATChunk.Data);
|
||||
chunks.push_back(&IDATChunk);
|
||||
|
||||
deflateEnd(&zipStream);
|
||||
|
||||
delete[] compressedData;
|
||||
delete[] uncompressedData;
|
||||
|
||||
PNGChunk IENDChunk = PNGChunk(0, "IEND");
|
||||
chunks.push_back(&IENDChunk);
|
||||
|
||||
//Write chunks to output buffer
|
||||
int finalDataSize = 8;
|
||||
for(std::vector<PNGChunk*>::iterator iter = chunks.begin(), end = chunks.end(); iter != end; ++iter)
|
||||
{
|
||||
PNGChunk * cChunk = *iter;
|
||||
finalDataSize += 4 + 4 + 4;
|
||||
finalDataSize += cChunk->Length;
|
||||
}
|
||||
unsigned char * finalData = new unsigned char[finalDataSize];
|
||||
int finalDataPos = 0;
|
||||
|
||||
//PNG File header
|
||||
finalData[finalDataPos++] = 0x89;
|
||||
finalData[finalDataPos++] = 0x50;
|
||||
finalData[finalDataPos++] = 0x4E;
|
||||
finalData[finalDataPos++] = 0x47;
|
||||
finalData[finalDataPos++] = 0x0D;
|
||||
finalData[finalDataPos++] = 0x0A;
|
||||
finalData[finalDataPos++] = 0x1A;
|
||||
finalData[finalDataPos++] = 0x0A;
|
||||
|
||||
for(std::vector<PNGChunk*>::iterator iter = chunks.begin(), end = chunks.end(); iter != end; ++iter)
|
||||
{
|
||||
PNGChunk * cChunk = *iter;
|
||||
|
||||
//Chunk length
|
||||
finalData[finalDataPos++] = (cChunk->Length>>24)&0xFF;
|
||||
finalData[finalDataPos++] = (cChunk->Length>>16)&0xFF;
|
||||
finalData[finalDataPos++] = (cChunk->Length>>8)&0xFF;
|
||||
finalData[finalDataPos++] = (cChunk->Length)&0xFF;
|
||||
|
||||
//Chunk name
|
||||
std::copy(cChunk->Name, cChunk->Name+4, finalData+finalDataPos);
|
||||
finalDataPos += 4;
|
||||
|
||||
//Chunk data
|
||||
if(cChunk->Data)
|
||||
{
|
||||
std::copy(cChunk->Data, cChunk->Data+cChunk->Length, finalData+finalDataPos);
|
||||
finalDataPos += cChunk->Length;
|
||||
}
|
||||
|
||||
//Chunk CRC
|
||||
unsigned long tempCRC = cChunk->CRC();
|
||||
finalData[finalDataPos++] = (tempCRC>>24)&0xFF;
|
||||
finalData[finalDataPos++] = (tempCRC>>16)&0xFF;
|
||||
finalData[finalDataPos++] = (tempCRC>>8)&0xFF;
|
||||
finalData[finalDataPos++] = (tempCRC)&0xFF;
|
||||
}
|
||||
|
||||
std::vector<char> outputData(finalData, finalData+finalDataPos);
|
||||
|
||||
delete[] finalData;
|
||||
|
||||
return outputData;
|
||||
}
|
||||
|
||||
//CRC functions, copypasta from W3 PNG spec.
|
||||
|
||||
/* Table of CRCs of all 8-bit messages. */
|
||||
unsigned long crc_table[256];
|
||||
|
||||
/* Flag: has the table been computed? Initially false. */
|
||||
int crc_table_computed = 0;
|
||||
|
||||
/* Make the table for a fast CRC. */
|
||||
void make_crc_table(void)
|
||||
{
|
||||
unsigned long c;
|
||||
int n, k;
|
||||
|
||||
for (n = 0; n < 256; n++) {
|
||||
c = (unsigned long) n;
|
||||
for (k = 0; k < 8; k++) {
|
||||
if (c & 1)
|
||||
c = 0xedb88320L ^ (c >> 1);
|
||||
else
|
||||
c = c >> 1;
|
||||
}
|
||||
crc_table[n] = c;
|
||||
}
|
||||
crc_table_computed = 1;
|
||||
}
|
||||
|
||||
/* Update a running CRC with the bytes buf[0..len-1]--the CRC
|
||||
should be initialized to all 1's, and the transmitted value
|
||||
is the 1's complement of the final running CRC (see the
|
||||
crc() routine below)). */
|
||||
|
||||
unsigned long update_crc(unsigned long crc, unsigned char *buf, int len)
|
||||
{
|
||||
unsigned long c = crc;
|
||||
int n;
|
||||
|
||||
if (!crc_table_computed)
|
||||
make_crc_table();
|
||||
for (n = 0; n < len; n++)
|
||||
{
|
||||
c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
unsigned long format::CalculateCRC(unsigned char * data, int len)
|
||||
{
|
||||
return update_crc(0xffffffffL, data, len) ^ 0xffffffffL;
|
||||
}
|
33
src/Format.h
Normal file
33
src/Format.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
class VideoBuffer;
|
||||
|
||||
namespace format
|
||||
{
|
||||
static char hex[] = "0123456789ABCDEF";
|
||||
|
||||
template <typename T> std::string NumberToString(T number)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << number;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template <typename T> T StringToNumber(const std::string & text)
|
||||
{
|
||||
std::stringstream ss(text);
|
||||
T number;
|
||||
return (ss >> number)?number:0;
|
||||
}
|
||||
|
||||
std::string URLEncode(std::string value);
|
||||
std::string UnixtimeToDate(time_t unixtime, std::string dateFomat = "%d %b %Y");
|
||||
std::string UnixtimeToDateMini(time_t unixtime);
|
||||
std::vector<char> VideoBufferToPNG(const VideoBuffer & vidBuf);
|
||||
std::vector<char> VideoBufferToPPM(const VideoBuffer & vidBuf);
|
||||
std::vector<char> VideoBufferToPTI(const VideoBuffer & vidBuf);
|
||||
unsigned long CalculateCRC(unsigned char * data, int length);
|
||||
}
|
717
src/Misc.cpp
Normal file
717
src/Misc.cpp
Normal file
@ -0,0 +1,717 @@
|
||||
#include <stdio.h>
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <regex.h>
|
||||
#include <sys/types.h>
|
||||
#include <cmath>
|
||||
#include "Config.h"
|
||||
#include "Misc.h"
|
||||
#include "icondoc.h"
|
||||
#if defined(WIN)
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef MACOSX
|
||||
#include <mach-o/dyld.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
std::string URLEscape(std::string source)
|
||||
{
|
||||
char * src = (char *)source.c_str();
|
||||
char * dst = (char *)calloc((source.length()*3)+2, 1);
|
||||
char *d;
|
||||
unsigned char *s;
|
||||
|
||||
for (d=dst; *d; d++) ;
|
||||
|
||||
for (s=(unsigned char *)src; *s; s++)
|
||||
{
|
||||
if ((*s>='0' && *s<='9') ||
|
||||
(*s>='a' && *s<='z') ||
|
||||
(*s>='A' && *s<='Z'))
|
||||
*(d++) = *s;
|
||||
else
|
||||
{
|
||||
*(d++) = '%';
|
||||
*(d++) = hex[*s>>4];
|
||||
*(d++) = hex[*s&15];
|
||||
}
|
||||
}
|
||||
*d = 0;
|
||||
|
||||
std::string finalString(dst);
|
||||
free(dst);
|
||||
return finalString;
|
||||
}
|
||||
|
||||
#if defined(USE_SDL) && defined(LIN) && defined(SDL_VIDEO_DRIVER_X11)
|
||||
#include <SDL/SDL_syswm.h>
|
||||
SDL_SysWMinfo sdl_wminfo;
|
||||
Atom XA_CLIPBOARD, XA_TARGETS;
|
||||
#endif
|
||||
|
||||
char *clipboard_text = NULL;
|
||||
|
||||
char *exe_name(void)
|
||||
{
|
||||
#if defined(WIN)
|
||||
char *name= (char *)malloc(64);
|
||||
DWORD max=64, res;
|
||||
while ((res = GetModuleFileName(NULL, name, max)) >= max)
|
||||
{
|
||||
#elif defined MACOSX
|
||||
char *fn=(char*)malloc(64),*name=(char*)malloc(PATH_MAX);
|
||||
uint32_t max=64, res;
|
||||
if (_NSGetExecutablePath(fn, &max) != 0)
|
||||
{
|
||||
fn = (char*)realloc(fn, max);
|
||||
_NSGetExecutablePath(fn, &max);
|
||||
}
|
||||
if (realpath(fn, name) == NULL)
|
||||
{
|
||||
free(fn);
|
||||
free(name);
|
||||
return NULL;
|
||||
}
|
||||
res = 1;
|
||||
#else
|
||||
char fn[64], *name=(char *)malloc(64);
|
||||
size_t max=64, res;
|
||||
sprintf(fn, "/proc/self/exe");
|
||||
memset(name, 0, max);
|
||||
while ((res = readlink(fn, name, max)) >= max-1)
|
||||
{
|
||||
#endif
|
||||
#ifndef MACOSX
|
||||
max *= 2;
|
||||
name = (char *)realloc(name, max);
|
||||
memset(name, 0, max);
|
||||
}
|
||||
#endif
|
||||
if (res <= 0)
|
||||
{
|
||||
free(name);
|
||||
return NULL;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
//Signum function
|
||||
int isign(float i) //TODO: INline or macro
|
||||
{
|
||||
if (i<0)
|
||||
return -1;
|
||||
if (i>0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
TPT_NO_INLINE unsigned clamp_flt(float f, float min, float max) //TODO: Also inline/macro
|
||||
{
|
||||
if (f<min)
|
||||
return 0;
|
||||
if (f>max)
|
||||
return 255;
|
||||
return (int)(255.0f*(f-min)/(max-min));
|
||||
}
|
||||
|
||||
TPT_NO_INLINE float restrict_flt(float f, float min, float max) //TODO Inline or macro or something
|
||||
{
|
||||
if (f<min)
|
||||
return min;
|
||||
if (f>max)
|
||||
return max;
|
||||
return f;
|
||||
}
|
||||
|
||||
char *mystrdup(char *s)
|
||||
{
|
||||
char *x;
|
||||
if (s)
|
||||
{
|
||||
x = (char*)malloc(strlen(s)+1);
|
||||
strcpy(x, s);
|
||||
return x;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void strlist_add(struct strlist **list, char *str)
|
||||
{
|
||||
struct strlist *item = (struct strlist*)malloc(sizeof(struct strlist));
|
||||
item->str = mystrdup(str);
|
||||
item->next = *list;
|
||||
*list = item;
|
||||
}
|
||||
|
||||
int strlist_find(struct strlist **list, char *str)
|
||||
{
|
||||
struct strlist *item;
|
||||
for (item=*list; item; item=item->next)
|
||||
if (!strcmp(item->str, str))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void strlist_free(struct strlist **list)
|
||||
{
|
||||
struct strlist *item;
|
||||
while (*list)
|
||||
{
|
||||
item = *list;
|
||||
*list = (*list)->next;
|
||||
free(item);
|
||||
}
|
||||
}
|
||||
|
||||
void clean_text(char *text, int vwidth)
|
||||
{
|
||||
int i = 0;
|
||||
if(strlen(text)*10 > vwidth){
|
||||
text[vwidth/10] = 0;
|
||||
}
|
||||
for(i = 0; i < strlen(text); i++){
|
||||
if(! (text[i]>=' ' && text[i]<127)){
|
||||
text[i] = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int sregexp(const char *str, char *pattern)
|
||||
{
|
||||
int result;
|
||||
regex_t patternc;
|
||||
if (regcomp(&patternc, pattern, 0)!=0)
|
||||
return 1;
|
||||
result = regexec(&patternc, str, 0, NULL, 0);
|
||||
regfree(&patternc);
|
||||
return result;
|
||||
}
|
||||
|
||||
void save_string(FILE *f, char *str)
|
||||
{
|
||||
int li = strlen(str);
|
||||
unsigned char lb[2];
|
||||
lb[0] = li;
|
||||
lb[1] = li >> 8;
|
||||
fwrite(lb, 2, 1, f);
|
||||
fwrite(str, li, 1, f);
|
||||
}
|
||||
|
||||
int load_string(FILE *f, char *str, int max)
|
||||
{
|
||||
int li;
|
||||
unsigned char lb[2];
|
||||
fread(lb, 2, 1, f);
|
||||
li = lb[0] | (lb[1] << 8);
|
||||
if (li > max)
|
||||
{
|
||||
str[0] = 0;
|
||||
return 1;
|
||||
}
|
||||
fread(str, li, 1, f);
|
||||
str[li] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void strcaturl(char *dst, char *src)
|
||||
{
|
||||
char *d;
|
||||
unsigned char *s;
|
||||
|
||||
for (d=dst; *d; d++) ;
|
||||
|
||||
for (s=(unsigned char *)src; *s; s++)
|
||||
{
|
||||
if ((*s>='0' && *s<='9') ||
|
||||
(*s>='a' && *s<='z') ||
|
||||
(*s>='A' && *s<='Z'))
|
||||
*(d++) = *s;
|
||||
else
|
||||
{
|
||||
*(d++) = '%';
|
||||
*(d++) = hex[*s>>4];
|
||||
*(d++) = hex[*s&15];
|
||||
}
|
||||
}
|
||||
*d = 0;
|
||||
}
|
||||
|
||||
void strappend(char *dst, char *src)
|
||||
{
|
||||
char *d;
|
||||
unsigned char *s;
|
||||
|
||||
for (d=dst; *d; d++) ;
|
||||
|
||||
for (s=(unsigned char *)src; *s; s++)
|
||||
{
|
||||
*(d++) = *s;
|
||||
}
|
||||
*d = 0;
|
||||
}
|
||||
|
||||
void *file_load(char *fn, int *size)
|
||||
{
|
||||
FILE *f = fopen(fn, "rb");
|
||||
void *s;
|
||||
|
||||
if (!f)
|
||||
return NULL;
|
||||
fseek(f, 0, SEEK_END);
|
||||
*size = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
s = malloc(*size);
|
||||
if (!s)
|
||||
{
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
fread(s, *size, 1, f);
|
||||
fclose(f);
|
||||
return s;
|
||||
}
|
||||
|
||||
int cpu_check(void)
|
||||
{
|
||||
#ifdef MACOSX
|
||||
return 0;
|
||||
#else
|
||||
#ifdef X86
|
||||
unsigned af,bf,cf,df;
|
||||
x86_cpuid(0, af, bf, cf, df);
|
||||
//if (bf==0x68747541 && cf==0x444D4163 && df==0x69746E65)
|
||||
// amd = 1;
|
||||
x86_cpuid(1, af, bf, cf, df);
|
||||
#ifdef X86_SSE
|
||||
if (!(df&(1<<25)))
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef X86_SSE2
|
||||
if (!(df&(1<<26)))
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef X86_SSE3
|
||||
if (!(cf&1))
|
||||
return 1;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
matrix2d m2d_multiply_m2d(matrix2d m1, matrix2d m2)
|
||||
{
|
||||
matrix2d result = {
|
||||
m1.a*m2.a+m1.b*m2.c, m1.a*m2.b+m1.b*m2.d,
|
||||
m1.c*m2.a+m1.d*m2.c, m1.c*m2.b+m1.d*m2.d
|
||||
};
|
||||
return result;
|
||||
}
|
||||
vector2d m2d_multiply_v2d(matrix2d m, vector2d v)
|
||||
{
|
||||
vector2d result = {
|
||||
m.a*v.x+m.b*v.y,
|
||||
m.c*v.x+m.d*v.y
|
||||
};
|
||||
return result;
|
||||
}
|
||||
matrix2d m2d_multiply_float(matrix2d m, float s)
|
||||
{
|
||||
matrix2d result = {
|
||||
m.a*s, m.b*s,
|
||||
m.c*s, m.d*s,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
vector2d v2d_multiply_float(vector2d v, float s)
|
||||
{
|
||||
vector2d result = {
|
||||
v.x*s,
|
||||
v.y*s
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
vector2d v2d_add(vector2d v1, vector2d v2)
|
||||
{
|
||||
vector2d result = {
|
||||
v1.x+v2.x,
|
||||
v1.y+v2.y
|
||||
};
|
||||
return result;
|
||||
}
|
||||
vector2d v2d_sub(vector2d v1, vector2d v2)
|
||||
{
|
||||
vector2d result = {
|
||||
v1.x-v2.x,
|
||||
v1.y-v2.y
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
matrix2d m2d_new(float me0, float me1, float me2, float me3)
|
||||
{
|
||||
matrix2d result = {me0,me1,me2,me3};
|
||||
return result;
|
||||
}
|
||||
vector2d v2d_new(float x, float y)
|
||||
{
|
||||
vector2d result = {x, y};
|
||||
return result;
|
||||
}
|
||||
|
||||
void clipboard_push_text(char * text)
|
||||
{
|
||||
#ifdef MACOSX
|
||||
PasteboardRef newclipboard;
|
||||
|
||||
if (PasteboardCreate(kPasteboardClipboard, &newclipboard)!=noErr) return;
|
||||
if (PasteboardClear(newclipboard)!=noErr) return;
|
||||
PasteboardSynchronize(newclipboard);
|
||||
|
||||
CFDataRef data = CFDataCreate(kCFAllocatorDefault, (const UInt8*)text, strlen(text));
|
||||
PasteboardPutItemFlavor(newclipboard, (PasteboardItemID)1, CFSTR("com.apple.traditional-mac-plain-text"), data, 0);
|
||||
#elif defined(WIN)
|
||||
if (OpenClipboard(NULL))
|
||||
{
|
||||
HGLOBAL cbuffer;
|
||||
char * glbuffer;
|
||||
|
||||
EmptyClipboard();
|
||||
|
||||
cbuffer = GlobalAlloc(GMEM_DDESHARE, strlen(text)+1);
|
||||
glbuffer = (char*)GlobalLock(cbuffer);
|
||||
|
||||
strcpy(glbuffer, text);
|
||||
|
||||
GlobalUnlock(cbuffer);
|
||||
SetClipboardData(CF_TEXT, cbuffer);
|
||||
CloseClipboard();
|
||||
}
|
||||
#elif defined(LIN) && defined(SDL_VIDEO_DRIVER_X11)
|
||||
if (clipboard_text!=NULL) {
|
||||
free(clipboard_text);
|
||||
clipboard_text = NULL;
|
||||
}
|
||||
clipboard_text = mystrdup(text);
|
||||
sdl_wminfo.info.x11.lock_func();
|
||||
XSetSelectionOwner(sdl_wminfo.info.x11.display, XA_CLIPBOARD, sdl_wminfo.info.x11.window, CurrentTime);
|
||||
XFlush(sdl_wminfo.info.x11.display);
|
||||
sdl_wminfo.info.x11.unlock_func();
|
||||
#else
|
||||
printf("Not implemented: put text on clipboard \"%s\"\n", text);
|
||||
#endif
|
||||
}
|
||||
|
||||
char * clipboard_pull_text()
|
||||
{
|
||||
#ifdef MACOSX
|
||||
printf("Not implemented: get text from clipboard\n");
|
||||
#elif defined(WIN)
|
||||
if (OpenClipboard(NULL))
|
||||
{
|
||||
HANDLE cbuffer;
|
||||
char * glbuffer;
|
||||
|
||||
cbuffer = GetClipboardData(CF_TEXT);
|
||||
glbuffer = (char*)GlobalLock(cbuffer);
|
||||
GlobalUnlock(cbuffer);
|
||||
CloseClipboard();
|
||||
if(glbuffer!=NULL){
|
||||
return mystrdup(glbuffer);
|
||||
} else {
|
||||
return mystrdup("");
|
||||
}
|
||||
}
|
||||
#elif defined(LIN) && defined(SDL_VIDEO_DRIVER_X11)
|
||||
printf("Not implemented: get text from clipboard\n");
|
||||
#else
|
||||
printf("Not implemented: get text from clipboard\n");
|
||||
#endif
|
||||
return mystrdup("");
|
||||
}
|
||||
|
||||
int register_extension()
|
||||
{
|
||||
#if defined(WIN)
|
||||
int returnval;
|
||||
LONG rresult;
|
||||
HKEY newkey;
|
||||
char *currentfilename = exe_name();
|
||||
char *iconname = NULL;
|
||||
char *opencommand = NULL;
|
||||
//char AppDataPath[MAX_PATH];
|
||||
char *AppDataPath = NULL;
|
||||
iconname = (char*)malloc(strlen(currentfilename)+6);
|
||||
sprintf(iconname, "%s,-102", currentfilename);
|
||||
|
||||
//Create Roaming application data folder
|
||||
/*if(!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, AppDataPath)))
|
||||
{
|
||||
returnval = 0;
|
||||
goto finalise;
|
||||
}*/
|
||||
|
||||
//AppDataPath = _getcwd(NULL, 0);
|
||||
|
||||
//Move Game executable into application data folder
|
||||
//TODO: Implement
|
||||
|
||||
opencommand = (char*)malloc(strlen(currentfilename)+53+strlen(AppDataPath));
|
||||
/*if((strlen(AppDataPath)+strlen(APPDATA_SUBDIR "\\Powder Toy"))<MAX_PATH)
|
||||
{
|
||||
strappend(AppDataPath, APPDATA_SUBDIR);
|
||||
_mkdir(AppDataPath);
|
||||
strappend(AppDataPath, "\\Powder Toy");
|
||||
_mkdir(AppDataPath);
|
||||
} else {
|
||||
returnval = 0;
|
||||
goto finalise;
|
||||
}*/
|
||||
sprintf(opencommand, "\"%s\" open \"%%1\" ddir \"%s\"", currentfilename, AppDataPath);
|
||||
|
||||
//Create extension entry
|
||||
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\.cps", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
||||
if (rresult != ERROR_SUCCESS) {
|
||||
returnval = 0;
|
||||
goto finalise;
|
||||
}
|
||||
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"PowderToySave", strlen("PowderToySave")+1);
|
||||
if (rresult != ERROR_SUCCESS) {
|
||||
RegCloseKey(newkey);
|
||||
returnval = 0;
|
||||
goto finalise;
|
||||
}
|
||||
RegCloseKey(newkey);
|
||||
|
||||
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\.stm", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
||||
if (rresult != ERROR_SUCCESS) {
|
||||
returnval = 0;
|
||||
goto finalise;
|
||||
}
|
||||
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"PowderToySave", strlen("PowderToySave")+1);
|
||||
if (rresult != ERROR_SUCCESS) {
|
||||
RegCloseKey(newkey);
|
||||
returnval = 0;
|
||||
goto finalise;
|
||||
}
|
||||
RegCloseKey(newkey);
|
||||
|
||||
//Create program entry
|
||||
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
||||
if (rresult != ERROR_SUCCESS) {
|
||||
returnval = 0;
|
||||
goto finalise;
|
||||
}
|
||||
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"Powder Toy Save", strlen("Powder Toy Save")+1);
|
||||
if (rresult != ERROR_SUCCESS) {
|
||||
RegCloseKey(newkey);
|
||||
returnval = 0;
|
||||
goto finalise;
|
||||
}
|
||||
RegCloseKey(newkey);
|
||||
|
||||
//Set DefaultIcon
|
||||
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave\\DefaultIcon", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
||||
if (rresult != ERROR_SUCCESS) {
|
||||
returnval = 0;
|
||||
goto finalise;
|
||||
}
|
||||
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)iconname, strlen(iconname)+1);
|
||||
if (rresult != ERROR_SUCCESS) {
|
||||
RegCloseKey(newkey);
|
||||
returnval = 0;
|
||||
goto finalise;
|
||||
}
|
||||
RegCloseKey(newkey);
|
||||
|
||||
//Set Launch command
|
||||
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave\\shell\\open\\command", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
|
||||
if (rresult != ERROR_SUCCESS) {
|
||||
returnval = 0;
|
||||
goto finalise;
|
||||
}
|
||||
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)opencommand, strlen(opencommand)+1);
|
||||
if (rresult != ERROR_SUCCESS) {
|
||||
RegCloseKey(newkey);
|
||||
returnval = 0;
|
||||
goto finalise;
|
||||
}
|
||||
RegCloseKey(newkey);
|
||||
|
||||
returnval = 1;
|
||||
finalise:
|
||||
|
||||
if(iconname) free(iconname);
|
||||
if(opencommand) free(opencommand);
|
||||
if(currentfilename) free(currentfilename);
|
||||
|
||||
return returnval;
|
||||
#elif defined(LIN)
|
||||
char *currentfilename = exe_name();
|
||||
FILE *f;
|
||||
char *mimedata =
|
||||
"<?xml version=\"1.0\"?>\n"
|
||||
" <mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>\n"
|
||||
" <mime-type type=\"application/vnd.powdertoy.save\">\n"
|
||||
" <comment>Powder Toy save</comment>\n"
|
||||
" <glob pattern=\"*.cps\"/>\n"
|
||||
" <glob pattern=\"*.stm\"/>\n"
|
||||
" </mime-type>\n"
|
||||
"</mime-info>\n";
|
||||
f = fopen("powdertoy-save.xml", "wb");
|
||||
if (!f)
|
||||
return 0;
|
||||
fwrite(mimedata, 1, strlen(mimedata), f);
|
||||
fclose(f);
|
||||
|
||||
char *desktopfiledata_tmp =
|
||||
"[Desktop Entry]\n"
|
||||
"Type=Application\n"
|
||||
"Name=Powder Toy\n"
|
||||
"Comment=Physics sandbox game\n"
|
||||
"MimeType=application/vnd.powdertoy.save;\n"
|
||||
"NoDisplay=true\n";
|
||||
char *desktopfiledata = (char *)malloc(strlen(desktopfiledata_tmp)+strlen(currentfilename)+100);
|
||||
strcpy(desktopfiledata, desktopfiledata_tmp);
|
||||
strappend(desktopfiledata, "Exec=");
|
||||
strappend(desktopfiledata, currentfilename);
|
||||
strappend(desktopfiledata, " open %f\n");
|
||||
f = fopen("powdertoy-tpt.desktop", "wb");
|
||||
if (!f)
|
||||
return 0;
|
||||
fwrite(desktopfiledata, 1, strlen(desktopfiledata), f);
|
||||
fclose(f);
|
||||
system("xdg-mime install powdertoy-save.xml");
|
||||
system("xdg-desktop-menu install powdertoy-tpt.desktop");
|
||||
f = fopen("powdertoy-save-32.png", "wb");
|
||||
if (!f)
|
||||
return 0;
|
||||
fwrite(icon_doc_32_png, 1, sizeof(icon_doc_32_png), f);
|
||||
fclose(f);
|
||||
f = fopen("powdertoy-save-16.png", "wb");
|
||||
if (!f)
|
||||
return 0;
|
||||
fwrite(icon_doc_16_png, 1, sizeof(icon_doc_16_png), f);
|
||||
fclose(f);
|
||||
system("xdg-icon-resource install --noupdate --context mimetypes --size 32 powdertoy-save-32.png application-vnd.powdertoy.save");
|
||||
system("xdg-icon-resource install --noupdate --context mimetypes --size 16 powdertoy-save-16.png application-vnd.powdertoy.save");
|
||||
system("xdg-icon-resource forceupdate");
|
||||
system("xdg-mime default powdertoy-tpt.desktop application/vnd.powdertoy.save");
|
||||
unlink("powdertoy-save-32.png");
|
||||
unlink("powdertoy-save-16.png");
|
||||
unlink("powdertoy-save.xml");
|
||||
unlink("powdertoy-tpt.desktop");
|
||||
return 1;
|
||||
#elif defined MACOSX
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void HSV_to_RGB(int h,int s,int v,int *r,int *g,int *b)//convert 0-255(0-360 for H) HSV values to 0-255 RGB
|
||||
{
|
||||
float hh, ss, vv, c, x;
|
||||
int m;
|
||||
hh = h/60.0f;//normalize values
|
||||
ss = s/255.0f;
|
||||
vv = v/255.0f;
|
||||
c = vv * ss;
|
||||
x = c * ( 1 - fabs(fmod(hh,2.0f) -1) );
|
||||
if(hh<1){
|
||||
*r = (int)(c*255.0);
|
||||
*g = (int)(x*255.0);
|
||||
*b = 0;
|
||||
}
|
||||
else if(hh<2){
|
||||
*r = (int)(x*255.0);
|
||||
*g = (int)(c*255.0);
|
||||
*b = 0;
|
||||
}
|
||||
else if(hh<3){
|
||||
*r = 0;
|
||||
*g = (int)(c*255.0);
|
||||
*b = (int)(x*255.0);
|
||||
}
|
||||
else if(hh<4){
|
||||
*r = 0;
|
||||
*g = (int)(x*255.0);
|
||||
*b = (int)(c*255.0);
|
||||
}
|
||||
else if(hh<5){
|
||||
*r = (int)(x*255.0);
|
||||
*g = 0;
|
||||
*b = (int)(c*255.0);
|
||||
}
|
||||
else if(hh<6){
|
||||
*r = (int)(c*255.0);
|
||||
*g = 0;
|
||||
*b = (int)(x*255.0);
|
||||
}
|
||||
m = (int)((vv-c)*255.0);
|
||||
*r += m;
|
||||
*g += m;
|
||||
*b += m;
|
||||
}
|
||||
|
||||
void OpenURI(std::string uri) {
|
||||
#if defined(WIN)
|
||||
ShellExecute(0, "OPEN", uri.c_str(), NULL, NULL, 0);
|
||||
#elif defined(MACOSX)
|
||||
char *cmd = (char*)malloc(7+uri.length());
|
||||
strcpy(cmd, "open ");
|
||||
strappend(cmd, (char*)uri.c_str());
|
||||
system(cmd);
|
||||
#elif defined(LIN)
|
||||
char *cmd = (char*)malloc(11+uri.length());
|
||||
strcpy(cmd, "xdg-open ");
|
||||
strappend(cmd, (char*)uri.c_str());
|
||||
system(cmd);
|
||||
#else
|
||||
printf("Cannot open browser\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void RGB_to_HSV(int r,int g,int b,int *h,int *s,int *v)//convert 0-255 RGB values to 0-255(0-360 for H) HSV
|
||||
{
|
||||
float rr, gg, bb, a,x,c,d;
|
||||
rr = r/255.0f;//normalize values
|
||||
gg = g/255.0f;
|
||||
bb = b/255.0f;
|
||||
a = fmin(rr,gg);
|
||||
a = fmin(a,bb);
|
||||
x = fmax(rr,gg);
|
||||
x = fmax(x,bb);
|
||||
if (a==x)//greyscale
|
||||
{
|
||||
*h = 0;
|
||||
*s = 0;
|
||||
*v = (int)(a*255.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
c = (rr==a) ? gg-bb : ((bb==a) ? rr-gg : bb-rr);
|
||||
d = (rr==a) ? 3 : ((bb==a) ? 1 : 5);
|
||||
*h = (int)(60.0*(d - c/(x - a)));
|
||||
*s = (int)(255.0*((x - a)/x));
|
||||
*v = (int)(255.0*x);
|
||||
}
|
||||
}
|
||||
|
||||
void membwand(void * destv, void * srcv, size_t destsize, size_t srcsize)
|
||||
{
|
||||
size_t i;
|
||||
unsigned char * dest = (unsigned char*)destv;
|
||||
unsigned char * src = (unsigned char*)srcv;
|
||||
for(i = 0; i < destsize; i++){
|
||||
dest[i] = dest[i] & src[i%srcsize];
|
||||
}
|
||||
}
|
||||
vector2d v2d_zero = {0,0};
|
||||
matrix2d m2d_identity = {1,0,0,1};
|
115
src/Misc.h
Normal file
115
src/Misc.h
Normal file
@ -0,0 +1,115 @@
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#if defined(WIN) && !defined(__GNUC__)
|
||||
#define x86_cpuid(func,af,bf,cf,df) \
|
||||
do {\
|
||||
__asm mov eax, func\
|
||||
__asm cpuid\
|
||||
__asm mov af, eax\
|
||||
__asm mov bf, ebx\
|
||||
__asm mov cf, ecx\
|
||||
__asm mov df, edx\
|
||||
} while(0)
|
||||
#else
|
||||
#define x86_cpuid(func,af,bf,cf,df) \
|
||||
__asm__ __volatile ("cpuid":\
|
||||
"=a" (af), "=b" (bf), "=c" (cf), "=d" (df) : "a" (func));
|
||||
#endif
|
||||
|
||||
static char hex[] = "0123456789ABCDEF";
|
||||
|
||||
char *exe_name(void);
|
||||
|
||||
//Signum function
|
||||
int isign(float i);
|
||||
|
||||
unsigned clamp_flt(float f, float min, float max);
|
||||
|
||||
float restrict_flt(float f, float min, float max);
|
||||
|
||||
char *mystrdup(char *s);
|
||||
|
||||
struct strlist
|
||||
{
|
||||
char *str;
|
||||
struct strlist *next;
|
||||
};
|
||||
|
||||
void strlist_add(struct strlist **list, char *str);
|
||||
|
||||
int strlist_find(struct strlist **list, char *str);
|
||||
|
||||
void strlist_free(struct strlist **list);
|
||||
|
||||
void save_presets(int do_update);
|
||||
|
||||
void clean_text(char *text, int vwidth);
|
||||
|
||||
void load_presets(void);
|
||||
|
||||
void save_string(FILE *f, char *str);
|
||||
|
||||
int sregexp(const char *str, char *pattern);
|
||||
|
||||
int load_string(FILE *f, char *str, int max);
|
||||
|
||||
void strcaturl(char *dst, char *src);
|
||||
|
||||
std::string URLEscape(std::string source);
|
||||
|
||||
void strappend(char *dst, char *src);
|
||||
|
||||
void *file_load(char *fn, int *size);
|
||||
|
||||
void clipboard_push_text(char * text);
|
||||
|
||||
char * clipboard_pull_text();
|
||||
|
||||
extern char *clipboard_text;
|
||||
|
||||
int register_extension();
|
||||
|
||||
int cpu_check(void);
|
||||
|
||||
void HSV_to_RGB(int h,int s,int v,int *r,int *g,int *b);
|
||||
|
||||
void RGB_to_HSV(int r,int g,int b,int *h,int *s,int *v);
|
||||
|
||||
void OpenURI(std::string uri);
|
||||
|
||||
void membwand(void * dest, void * src, size_t destsize, size_t srcsize);
|
||||
// a b
|
||||
// c d
|
||||
|
||||
struct matrix2d {
|
||||
float a,b,c,d;
|
||||
};
|
||||
typedef struct matrix2d matrix2d;
|
||||
|
||||
// column vector
|
||||
struct vector2d {
|
||||
float x,y;
|
||||
};
|
||||
typedef struct vector2d vector2d;
|
||||
|
||||
matrix2d m2d_multiply_m2d(matrix2d m1, matrix2d m2);
|
||||
vector2d m2d_multiply_v2d(matrix2d m, vector2d v);
|
||||
matrix2d m2d_multiply_float(matrix2d m, float s);
|
||||
vector2d v2d_multiply_float(vector2d v, float s);
|
||||
|
||||
vector2d v2d_add(vector2d v1, vector2d v2);
|
||||
vector2d v2d_sub(vector2d v1, vector2d v2);
|
||||
|
||||
matrix2d m2d_new(float me0, float me1, float me2, float me3);
|
||||
vector2d v2d_new(float x, float y);
|
||||
|
||||
extern vector2d v2d_zero;
|
||||
extern matrix2d m2d_identity;
|
||||
|
||||
#endif
|
3
src/PowderToy.h
Normal file
3
src/PowderToy.h
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void EngineProcess();
|
120
src/PowderToyRenderer.cpp
Normal file
120
src/PowderToyRenderer.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
#if defined(RENDERER)
|
||||
|
||||
#include <time.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#include "Config.h"
|
||||
#include "Format.h"
|
||||
#include "interface/Engine.h"
|
||||
#include "graphics/Graphics.h"
|
||||
#include "graphics/Renderer.h"
|
||||
|
||||
#include "client/GameSave.h"
|
||||
#include "simulation/Simulation.h"
|
||||
|
||||
|
||||
void EngineProcess() {}
|
||||
|
||||
void readFile(std::string filename, std::vector<char> & storage)
|
||||
{
|
||||
std::ifstream fileStream;
|
||||
fileStream.open(std::string(filename).c_str(), std::ios::binary);
|
||||
if(fileStream.is_open())
|
||||
{
|
||||
fileStream.seekg(0, std::ios::end);
|
||||
size_t fileSize = fileStream.tellg();
|
||||
fileStream.seekg(0);
|
||||
|
||||
unsigned char * tempData = new unsigned char[fileSize];
|
||||
fileStream.read((char *)tempData, fileSize);
|
||||
fileStream.close();
|
||||
|
||||
std::vector<unsigned char> fileData;
|
||||
storage.clear();
|
||||
storage.insert(storage.end(), tempData, tempData+fileSize);
|
||||
delete[] tempData;
|
||||
}
|
||||
}
|
||||
|
||||
void writeFile(std::string filename, std::vector<char> & fileData)
|
||||
{
|
||||
std::ofstream fileStream;
|
||||
fileStream.open(std::string(filename).c_str(), std::ios::binary);
|
||||
if(fileStream.is_open())
|
||||
{
|
||||
fileStream.write(&fileData[0], fileData.size());
|
||||
fileStream.close();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
ui::Engine * engine;
|
||||
std::string outputPrefix, inputFilename;
|
||||
std::vector<char> inputFile;
|
||||
std::string ppmFilename, ptiFilename, ptiSmallFilename, pngFilename, pngSmallFilename;
|
||||
std::vector<char> ppmFile, ptiFile, ptiSmallFile, pngFile, pngSmallFile;
|
||||
|
||||
inputFilename = std::string(argv[1]);
|
||||
outputPrefix = std::string(argv[2]);
|
||||
|
||||
ppmFilename = outputPrefix+".ppm";
|
||||
ptiFilename = outputPrefix+".pti";
|
||||
ptiSmallFilename = outputPrefix+"-small.pti";
|
||||
pngFilename = outputPrefix+".png";
|
||||
pngSmallFilename = outputPrefix+"-small.png";
|
||||
|
||||
readFile(inputFilename, inputFile);
|
||||
|
||||
ui::Engine::Ref().g = new Graphics();
|
||||
|
||||
engine = &ui::Engine::Ref();
|
||||
engine->Begin(XRES+BARSIZE, YRES+MENUSIZE);
|
||||
|
||||
GameSave * gameSave = new GameSave(inputFile);
|
||||
|
||||
Simulation * sim = new Simulation();
|
||||
Renderer * ren = new Renderer(ui::Engine::Ref().g, sim);
|
||||
|
||||
sim->Load(gameSave);
|
||||
|
||||
|
||||
//Render save
|
||||
ren->decorations_enable = true;
|
||||
ren->blackDecorations = true;
|
||||
|
||||
int frame = 15;
|
||||
while(frame)
|
||||
{
|
||||
frame--;
|
||||
ren->render_parts();
|
||||
ren->render_fire();
|
||||
ren->clearScreen(1.0f);
|
||||
}
|
||||
|
||||
ren->RenderBegin();
|
||||
ren->RenderEnd();
|
||||
|
||||
VideoBuffer screenBuffer = ren->DumpFrame();
|
||||
//ppmFile = format::VideoBufferToPPM(screenBuffer);
|
||||
ptiFile = format::VideoBufferToPTI(screenBuffer);
|
||||
pngFile = format::VideoBufferToPNG(screenBuffer);
|
||||
|
||||
screenBuffer.Resize(1.0f/3.0f, true);
|
||||
ptiSmallFile = format::VideoBufferToPTI(screenBuffer);
|
||||
pngSmallFile = format::VideoBufferToPNG(screenBuffer);
|
||||
|
||||
|
||||
|
||||
//writeFile(ppmFilename, ppmFile);
|
||||
writeFile(ptiFilename, ptiFile);
|
||||
writeFile(ptiSmallFilename, ptiSmallFile);
|
||||
writeFile(pngFilename, pngFile);
|
||||
writeFile(pngSmallFilename, pngSmallFile);
|
||||
}
|
||||
|
||||
#endif
|
606
src/PowderToySDL.cpp
Normal file
606
src/PowderToySDL.cpp
Normal file
@ -0,0 +1,606 @@
|
||||
#ifdef USE_SDL
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
#include "SDL.h"
|
||||
#ifdef WIN
|
||||
#include "SDL_syswm.h"
|
||||
#include <direct.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "Config.h"
|
||||
#include "graphics/Graphics.h"
|
||||
#if defined(LIN)
|
||||
#include "icon.h"
|
||||
#endif
|
||||
|
||||
#ifndef WIN
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "Format.h"
|
||||
#include "Style.h"
|
||||
#include "interface/Engine.h"
|
||||
#include "interface/Button.h"
|
||||
#include "interface/Panel.h"
|
||||
#include "interface/Point.h"
|
||||
#include "interface/Label.h"
|
||||
#include "interface/Keys.h"
|
||||
|
||||
#include "client/GameSave.h"
|
||||
#include "client/SaveFile.h"
|
||||
#include "simulation/SaveRenderer.h"
|
||||
#include "client/Client.h"
|
||||
#include "Misc.h"
|
||||
|
||||
#include "game/GameController.h"
|
||||
#include "game/GameView.h"
|
||||
|
||||
#include "dialogues/ErrorMessage.h"
|
||||
|
||||
#include "client/HTTP.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
#ifdef WIN
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
#endif
|
||||
|
||||
int desktopWidth = 1280, desktopHeight = 1024;
|
||||
|
||||
SDL_Surface * sdl_scrn;
|
||||
int scale = 1;
|
||||
bool fullscreen = false;
|
||||
|
||||
#ifdef OGLI
|
||||
void blit()
|
||||
{
|
||||
SDL_GL_SwapBuffers();
|
||||
}
|
||||
#else
|
||||
void blit(pixel * vid)
|
||||
{
|
||||
if(sdl_scrn)
|
||||
{
|
||||
pixel * src = vid;
|
||||
int j, x = 0, y = 0, w = XRES+BARSIZE, h = YRES+MENUSIZE, pitch = XRES+BARSIZE;
|
||||
pixel *dst;
|
||||
if (SDL_MUSTLOCK(sdl_scrn))
|
||||
if (SDL_LockSurface(sdl_scrn)<0)
|
||||
return;
|
||||
dst=(pixel *)sdl_scrn->pixels+y*sdl_scrn->pitch/PIXELSIZE+x;
|
||||
if (SDL_MapRGB(sdl_scrn->format,0x33,0x55,0x77)!=PIXPACK(0x335577))
|
||||
{
|
||||
//pixel format conversion
|
||||
int i;
|
||||
pixel px;
|
||||
SDL_PixelFormat *fmt = sdl_scrn->format;
|
||||
for (j=0; j<h; j++)
|
||||
{
|
||||
for (i=0; i<w; i++)
|
||||
{
|
||||
px = src[i];
|
||||
dst[i] = ((PIXR(px)>>fmt->Rloss)<<fmt->Rshift)|
|
||||
((PIXG(px)>>fmt->Gloss)<<fmt->Gshift)|
|
||||
((PIXB(px)>>fmt->Bloss)<<fmt->Bshift);
|
||||
}
|
||||
dst+=sdl_scrn->pitch/PIXELSIZE;
|
||||
src+=pitch;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j=0; j<h; j++)
|
||||
{
|
||||
memcpy(dst, src, w*PIXELSIZE);
|
||||
dst+=sdl_scrn->pitch/PIXELSIZE;
|
||||
src+=pitch;
|
||||
}
|
||||
}
|
||||
if (SDL_MUSTLOCK(sdl_scrn))
|
||||
SDL_UnlockSurface(sdl_scrn);
|
||||
SDL_UpdateRect(sdl_scrn,0,0,0,0);
|
||||
}
|
||||
}
|
||||
void blit2(pixel * vid, int currentScale)
|
||||
{
|
||||
if(sdl_scrn)
|
||||
{
|
||||
pixel * src = vid;
|
||||
int j, x = 0, y = 0, w = XRES+BARSIZE, h = YRES+MENUSIZE, pitch = XRES+BARSIZE;
|
||||
pixel *dst;
|
||||
int i,k;
|
||||
if (SDL_MUSTLOCK(sdl_scrn))
|
||||
if (SDL_LockSurface(sdl_scrn)<0)
|
||||
return;
|
||||
dst=(pixel *)sdl_scrn->pixels+y*sdl_scrn->pitch/PIXELSIZE+x;
|
||||
if (SDL_MapRGB(sdl_scrn->format,0x33,0x55,0x77)!=PIXPACK(0x335577))
|
||||
{
|
||||
//pixel format conversion
|
||||
pixel px;
|
||||
SDL_PixelFormat *fmt = sdl_scrn->format;
|
||||
for (j=0; j<h; j++)
|
||||
{
|
||||
for (k=0; k<currentScale; k++)
|
||||
{
|
||||
for (i=0; i<w; i++)
|
||||
{
|
||||
px = src[i];
|
||||
px = ((PIXR(px)>>fmt->Rloss)<<fmt->Rshift)|
|
||||
((PIXG(px)>>fmt->Gloss)<<fmt->Gshift)|
|
||||
((PIXB(px)>>fmt->Bloss)<<fmt->Bshift);
|
||||
dst[i*2]=px;
|
||||
dst[i*2+1]=px;
|
||||
}
|
||||
dst+=sdl_scrn->pitch/PIXELSIZE;
|
||||
}
|
||||
src+=pitch;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j=0; j<h; j++)
|
||||
{
|
||||
for (k=0; k<currentScale; k++)
|
||||
{
|
||||
for (i=0; i<w; i++)
|
||||
{
|
||||
dst[i*2]=src[i];
|
||||
dst[i*2+1]=src[i];
|
||||
}
|
||||
dst+=sdl_scrn->pitch/PIXELSIZE;
|
||||
}
|
||||
src+=pitch;
|
||||
}
|
||||
}
|
||||
if (SDL_MUSTLOCK(sdl_scrn))
|
||||
SDL_UnlockSurface(sdl_scrn);
|
||||
SDL_UpdateRect(sdl_scrn,0,0,0,0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int SDLOpen()
|
||||
{
|
||||
SDL_Surface * surface;
|
||||
#if defined(WIN) && defined(WINCONSOLE)
|
||||
FILE * console = fopen("CON", "w" );
|
||||
#endif
|
||||
if (SDL_Init(SDL_INIT_VIDEO)<0)
|
||||
{
|
||||
fprintf(stderr, "Initializing SDL: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
const SDL_VideoInfo * vidInfo = SDL_GetVideoInfo();
|
||||
desktopWidth = vidInfo->current_w;
|
||||
desktopHeight = vidInfo->current_h;
|
||||
SDL_EnableUNICODE(1);
|
||||
#if defined(WIN) && defined(WINCONSOLE)
|
||||
//On Windows, SDL redirects stdout to stdout.txt, which can be annoying when debugging, here we redirect back to the console
|
||||
if (console)
|
||||
{
|
||||
freopen("CON", "w", stdout);
|
||||
freopen("CON", "w", stderr);
|
||||
//fclose(console);
|
||||
}
|
||||
#endif
|
||||
#ifdef WIN
|
||||
SDL_SysWMinfo SysInfo;
|
||||
SDL_VERSION(&SysInfo.version);
|
||||
if(SDL_GetWMInfo(&SysInfo) <= 0) {
|
||||
printf("%s : %d\n", SDL_GetError(), SysInfo.window);
|
||||
exit(-1);
|
||||
}
|
||||
HWND WindowHandle = SysInfo.window;
|
||||
HICON hIconSmall = (HICON)LoadImage(reinterpret_cast<HMODULE>(&__ImageBase), MAKEINTRESOURCE(101), IMAGE_ICON, 16, 16, LR_SHARED);
|
||||
HICON hIconBig = (HICON)LoadImage(reinterpret_cast<HMODULE>(&__ImageBase), MAKEINTRESOURCE(101), IMAGE_ICON, 32, 32, LR_SHARED);
|
||||
SendMessage(WindowHandle, WM_SETICON, ICON_SMALL, (LPARAM)hIconSmall);
|
||||
SendMessage(WindowHandle, WM_SETICON, ICON_BIG, (LPARAM)hIconBig);
|
||||
#elif defined(LIN)
|
||||
SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(app_icon, 16, 16, 32, 64, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
|
||||
SDL_WM_SetIcon(icon, NULL);
|
||||
#endif
|
||||
|
||||
SDL_WM_SetCaption("The Powder Toy", "Powder Toy");
|
||||
//SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
||||
atexit(SDL_Quit);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_Surface * SDLSetScreen(int newScale, bool newFullscreen)
|
||||
{
|
||||
scale = newScale;
|
||||
fullscreen = newFullscreen;
|
||||
SDL_Surface * surface;
|
||||
#ifndef OGLI
|
||||
surface = SDL_SetVideoMode((XRES + BARSIZE) * newScale, (YRES + MENUSIZE) * newScale, 32, SDL_SWSURFACE | (newFullscreen?SDL_FULLSCREEN:0));
|
||||
#else
|
||||
surface = SDL_SetVideoMode((XRES + BARSIZE) * newScale, (YRES + MENUSIZE) * newScale, 32, SDL_OPENGL | SDL_RESIZABLE | (newFullscreen?SDL_FULLSCREEN:0));
|
||||
#endif
|
||||
return surface;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> readArguments(int argc, char * argv[])
|
||||
{
|
||||
std::map<std::string, std::string> arguments;
|
||||
|
||||
//Defaults
|
||||
arguments["scale"] = "";
|
||||
arguments["proxy"] = "";
|
||||
arguments["nohud"] = "false"; //the nohud, sound, and scripts commands currently do nothing.
|
||||
arguments["sound"] = "false";
|
||||
arguments["kiosk"] = "false";
|
||||
arguments["scripts"] = "false";
|
||||
arguments["open"] = "";
|
||||
arguments["ddir"] = "";
|
||||
arguments["ptsave"] = "";
|
||||
|
||||
for (int i=1; i<argc; i++)
|
||||
{
|
||||
if (!strncmp(argv[i], "scale:", 6) && argv[i]+6)
|
||||
{
|
||||
arguments["scale"] = std::string(argv[i]+6);
|
||||
}
|
||||
else if (!strncmp(argv[i], "proxy:", 6))
|
||||
{
|
||||
if(argv[i]+6)
|
||||
arguments["proxy"] = std::string(argv[i]+6);
|
||||
else
|
||||
arguments["proxy"] = "false";
|
||||
}
|
||||
else if (!strncmp(argv[i], "nohud", 5))
|
||||
{
|
||||
arguments["nohud"] = "true";
|
||||
}
|
||||
else if (!strncmp(argv[i], "kiosk", 5))
|
||||
{
|
||||
arguments["kiosk"] = "true";
|
||||
}
|
||||
else if (!strncmp(argv[i], "sound", 5))
|
||||
{
|
||||
arguments["sound"] = "true";
|
||||
}
|
||||
else if (!strncmp(argv[i], "scripts", 8))
|
||||
{
|
||||
arguments["scripts"] = "true";
|
||||
}
|
||||
else if (!strncmp(argv[i], "open", 5) && i+1<argc)
|
||||
{
|
||||
arguments["open"] = std::string(argv[i+1]);;
|
||||
i++;
|
||||
}
|
||||
else if (!strncmp(argv[i], "ddir", 5) && i+1<argc)
|
||||
{
|
||||
arguments["ddir"] = std::string(argv[i+1]);
|
||||
i++;
|
||||
}
|
||||
else if (!strncmp(argv[i], "ptsave", 7) && i+1<argc)
|
||||
{
|
||||
arguments["ptsave"] = std::string(argv[i+1]);
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return arguments;
|
||||
}
|
||||
|
||||
int elapsedTime = 0, currentTime = 0, lastTime = 0, currentFrame = 0;
|
||||
unsigned int lastTick = 0;
|
||||
float fps = 0, delta = 1.0f, inputScale = 1.0f;
|
||||
ui::Engine * engine = NULL;
|
||||
float currentWidth, currentHeight;
|
||||
void EngineProcess()
|
||||
{
|
||||
int frameStart;
|
||||
float frameTime;
|
||||
float frameTimeAvg = 0.0f, correctedFrameTimeAvg = 0.0f;
|
||||
SDL_Event event;
|
||||
while(engine->Running())
|
||||
{
|
||||
if(engine->Broken()) { engine->UnBreak(); break; }
|
||||
event.type = 0;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
if (engine->GetFastQuit() || engine->CloseWindow())
|
||||
engine->Exit();
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
engine->onKeyPress(event.key.keysym.sym, event.key.keysym.unicode, event.key.keysym.mod&KEY_MOD_LSHIFT, event.key.keysym.mod&KEY_MOD_LCONTROL, event.key.keysym.mod&KEY_MOD_LALT);
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
engine->onKeyRelease(event.key.keysym.sym, event.key.keysym.unicode, event.key.keysym.mod&KEY_MOD_LSHIFT, event.key.keysym.mod&KEY_MOD_LCONTROL, event.key.keysym.mod&KEY_MOD_LALT);
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
engine->onMouseMove(event.motion.x*inputScale, event.motion.y*inputScale);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if(event.button.button == SDL_BUTTON_WHEELUP)
|
||||
{
|
||||
engine->onMouseWheel(event.motion.x*inputScale, event.motion.y*inputScale, 1);
|
||||
}
|
||||
else if (event.button.button == SDL_BUTTON_WHEELDOWN)
|
||||
{
|
||||
engine->onMouseWheel(event.motion.x*inputScale, event.motion.y*inputScale, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
engine->onMouseClick(event.motion.x*inputScale, event.motion.y*inputScale, event.button.button);
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if(event.button.button != SDL_BUTTON_WHEELUP && event.button.button != SDL_BUTTON_WHEELDOWN)
|
||||
engine->onMouseUnclick(event.motion.x*inputScale, event.motion.y*inputScale, event.button.button);
|
||||
break;
|
||||
#ifdef OGLI
|
||||
case SDL_VIDEORESIZE:
|
||||
float ratio = float(XRES+BARSIZE) / float(YRES+MENUSIZE);
|
||||
float width = event.resize.w;
|
||||
float height = width/ratio;
|
||||
|
||||
sdl_scrn = SDL_SetVideoMode(event.resize.w, height, 32, SDL_OPENGL | SDL_RESIZABLE);
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
engine->g->Reset();
|
||||
//glScaled(width/currentWidth, height/currentHeight, 1.0f);
|
||||
|
||||
currentWidth = width;
|
||||
currentHeight = height;
|
||||
inputScale = float(XRES+BARSIZE)/currentWidth;
|
||||
|
||||
glLineWidth(currentWidth/float(XRES+BARSIZE));
|
||||
if(sdl_scrn == NULL)
|
||||
{
|
||||
std::cerr << "Oh bugger" << std::endl;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
event.type = 0; //Clear last event
|
||||
}
|
||||
if(engine->Broken()) { engine->UnBreak(); break; }
|
||||
|
||||
frameStart = SDL_GetTicks();
|
||||
engine->Tick();
|
||||
engine->Draw();
|
||||
frameTime = SDL_GetTicks() - frameStart;
|
||||
|
||||
frameTimeAvg = (frameTimeAvg*(1.0f-0.2f)) + (0.2f*frameTime);
|
||||
if(ui::Engine::Ref().FpsLimit > 2.0f)
|
||||
{
|
||||
float targetFrameTime = 1000.0f/((float)ui::Engine::Ref().FpsLimit);
|
||||
if(targetFrameTime - frameTimeAvg > 0)
|
||||
{
|
||||
SDL_Delay((targetFrameTime - frameTimeAvg) + 0.5f);
|
||||
frameTime = SDL_GetTicks() - frameStart;//+= (int)(targetFrameTime - frameTimeAvg);
|
||||
}
|
||||
}
|
||||
|
||||
correctedFrameTimeAvg = (correctedFrameTimeAvg*(1.0f-0.05f)) + (0.05f*frameTime);
|
||||
fps = 1000.0f/correctedFrameTimeAvg;
|
||||
engine->SetFps(fps);
|
||||
|
||||
if(frameStart-lastTick>250)
|
||||
{
|
||||
//Run client tick every second
|
||||
lastTick = frameStart;
|
||||
Client::Ref().Tick();
|
||||
}
|
||||
|
||||
if(scale != engine->Scale || fullscreen != engine->Fullscreen)
|
||||
{
|
||||
sdl_scrn = SDLSetScreen(engine->Scale, engine->Fullscreen);
|
||||
inputScale = 1.0f/float(scale);
|
||||
}
|
||||
|
||||
#ifdef OGLI
|
||||
blit();
|
||||
#else
|
||||
if(engine->Scale==2)
|
||||
blit2(engine->g->vid, engine->Scale);
|
||||
else
|
||||
blit(engine->g->vid);
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG
|
||||
std::cout << "Breaking out of EngineProcess" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
currentWidth = XRES+BARSIZE;
|
||||
currentHeight = YRES+MENUSIZE;
|
||||
|
||||
|
||||
std::map<std::string, std::string> arguments = readArguments(argc, argv);
|
||||
|
||||
if(arguments["ddir"].length())
|
||||
#ifdef WIN
|
||||
_chdir(arguments["ddir"].c_str());
|
||||
#else
|
||||
chdir(arguments["ddir"].c_str());
|
||||
#endif
|
||||
|
||||
int tempScale = 1;
|
||||
bool tempFullscreen = false;
|
||||
|
||||
tempScale = Client::Ref().GetPrefInteger("Scale", 1);
|
||||
tempFullscreen = Client::Ref().GetPrefBool("Fullscreen", false);
|
||||
|
||||
|
||||
if(arguments["kiosk"] == "true")
|
||||
{
|
||||
tempFullscreen = true;
|
||||
Client::Ref().SetPref("Fullscreen", tempFullscreen);
|
||||
}
|
||||
|
||||
if(arguments["scale"].length())
|
||||
{
|
||||
tempScale = format::StringToNumber<int>(arguments["scale"]);
|
||||
Client::Ref().SetPref("Scale", tempScale);
|
||||
}
|
||||
|
||||
std::string proxyString = "";
|
||||
if(arguments["proxy"].length())
|
||||
{
|
||||
if(arguments["proxy"] == "false")
|
||||
{
|
||||
proxyString = "";
|
||||
Client::Ref().SetPref("Proxy", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
proxyString = (arguments["proxy"]);
|
||||
Client::Ref().SetPref("Proxy", arguments["proxy"]);
|
||||
}
|
||||
}
|
||||
else if(Client::Ref().GetPrefString("Proxy", "").length())
|
||||
{
|
||||
proxyString = (Client::Ref().GetPrefString("Proxy", ""));
|
||||
}
|
||||
|
||||
Client::Ref().Initialise(proxyString);
|
||||
|
||||
if(tempScale != 1 && tempScale != 2)
|
||||
tempScale = 1;
|
||||
|
||||
int sdlStatus = SDLOpen();
|
||||
sdl_scrn = SDLSetScreen(tempScale, tempFullscreen);
|
||||
#ifdef OGLI
|
||||
SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
|
||||
//glScaled(2.0f, 2.0f, 1.0f);
|
||||
#endif
|
||||
#if defined(OGLI)
|
||||
int status = glewInit();
|
||||
if(status != GLEW_OK)
|
||||
{
|
||||
fprintf(stderr, "Initializing Glew: %d\n", status);
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
ui::Engine::Ref().g = new Graphics();
|
||||
ui::Engine::Ref().Scale = scale;
|
||||
inputScale = 1.0f/float(scale);
|
||||
ui::Engine::Ref().Fullscreen = fullscreen;
|
||||
|
||||
engine = &ui::Engine::Ref();
|
||||
engine->SetMaxSize(desktopWidth, desktopHeight);
|
||||
engine->Begin(XRES+BARSIZE, YRES+MENUSIZE);
|
||||
engine->SetFastQuit(Client::Ref().GetPrefBool("FastQuit", true));
|
||||
|
||||
GameController * gameController = new GameController();
|
||||
engine->ShowWindow(gameController->GetView());
|
||||
|
||||
if(arguments["open"].length())
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cout << "Loading " << arguments["open"] << std::endl;
|
||||
#endif
|
||||
if(Client::Ref().FileExists(arguments["open"]))
|
||||
{
|
||||
try
|
||||
{
|
||||
std::vector<unsigned char> gameSaveData = Client::Ref().ReadFile(arguments["open"]);
|
||||
if(!gameSaveData.size())
|
||||
{
|
||||
new ErrorMessage("Error", "Could not read file");
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveFile * newFile = new SaveFile(arguments["open"]);
|
||||
GameSave * newSave = new GameSave(gameSaveData);
|
||||
newFile->SetGameSave(newSave);
|
||||
gameController->LoadSaveFile(newFile);
|
||||
delete newFile;
|
||||
}
|
||||
|
||||
}
|
||||
catch(std::exception & e)
|
||||
{
|
||||
new ErrorMessage("Error", "Could not open save file:\n"+std::string(e.what())) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new ErrorMessage("Error", "Could not open file");
|
||||
}
|
||||
}
|
||||
|
||||
if(arguments["ptsave"].length())
|
||||
{
|
||||
engine->g->fillrect((engine->GetWidth()/2)-101, (engine->GetHeight()/2)-26, 202, 52, 0, 0, 0, 210);
|
||||
engine->g->drawrect((engine->GetWidth()/2)-100, (engine->GetHeight()/2)-25, 200, 50, 255, 255, 255, 180);
|
||||
engine->g->drawtext((engine->GetWidth()/2)-(Graphics::textwidth("Loading save...")/2), (engine->GetHeight()/2)-5, "Loading save...", style::Colour::InformationTitle.Red, style::Colour::InformationTitle.Green, style::Colour::InformationTitle.Blue, 255);
|
||||
|
||||
#ifdef OGLI
|
||||
blit();
|
||||
#else
|
||||
if(engine->Scale==2)
|
||||
blit2(engine->g->vid, engine->Scale);
|
||||
else
|
||||
blit(engine->g->vid);
|
||||
#endif
|
||||
std::string ptsaveArg = arguments["ptsave"];
|
||||
try
|
||||
{
|
||||
if(!ptsaveArg.find("ptsave:"))
|
||||
{
|
||||
std::string saveIdPart = "";
|
||||
int saveId;
|
||||
int hashPos = ptsaveArg.find('#');
|
||||
if(hashPos != std::string::npos)
|
||||
{
|
||||
saveIdPart = ptsaveArg.substr(7, hashPos-7);
|
||||
}
|
||||
else
|
||||
{
|
||||
saveIdPart = ptsaveArg.substr(7);
|
||||
}
|
||||
if(saveIdPart.length())
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cout << "Got Ptsave: id: " << saveIdPart << std::endl;
|
||||
#endif
|
||||
saveId = format::StringToNumber<int>(saveIdPart);
|
||||
if(!saveId)
|
||||
throw std::runtime_error("Invalid Save ID");
|
||||
|
||||
SaveInfo * newSave = Client::Ref().GetSave(saveId, 0);
|
||||
GameSave * newGameSave = new GameSave(Client::Ref().GetSaveData(saveId, 0));
|
||||
newSave->SetGameSave(newGameSave);
|
||||
if(!newSave)
|
||||
throw std::runtime_error("Could not load save");
|
||||
|
||||
gameController->LoadSave(newSave);
|
||||
delete newSave;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("No Save ID");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception & e)
|
||||
{
|
||||
new ErrorMessage("Error", "Invalid save link");
|
||||
}
|
||||
}
|
||||
|
||||
EngineProcess();
|
||||
|
||||
ui::Engine::Ref().CloseWindow();
|
||||
delete gameController;
|
||||
delete ui::Engine::Ref().g;
|
||||
Client::Ref().Shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
16
src/Singleton.h
Normal file
16
src/Singleton.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef SINGLETON_H
|
||||
#define SINGLETON_H
|
||||
|
||||
template<typename T>
|
||||
|
||||
class Singleton
|
||||
{
|
||||
public:
|
||||
static T& Ref()
|
||||
{
|
||||
static T instance;
|
||||
return instance;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SINGLETON_H
|
26
src/Style.cpp
Normal file
26
src/Style.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
//
|
||||
// Style.cpp
|
||||
// The Powder Toy
|
||||
//
|
||||
// Created by Simon Robertshaw on 14/05/2012.
|
||||
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Style.h"
|
||||
#include "interface/Colour.h"
|
||||
|
||||
namespace style {
|
||||
ui::Colour Colour::InformationTitle = ui::Colour(140, 140, 255);
|
||||
ui::Colour Colour::WarningTitle = ui::Colour(255, 216, 32);
|
||||
ui::Colour Colour::ErrorTitle = ui::Colour(255, 64, 32);
|
||||
|
||||
ui::Colour Colour::ConfirmButton = ui::Colour(255, 255, 50);
|
||||
|
||||
ui::Colour Colour::ActiveBorder = ui::Colour(255, 255, 255);
|
||||
ui::Colour Colour::InactiveBorder = ui::Colour(100, 100, 100);
|
||||
|
||||
ui::Colour Colour::ActiveBackground = ui::Colour(50, 50, 50);
|
||||
ui::Colour Colour::InactiveBackground = ui::Colour(0, 0, 0);
|
||||
}
|
35
src/Style.h
Normal file
35
src/Style.h
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// Style.h
|
||||
// The Powder Toy
|
||||
//
|
||||
// Created by Simon Robertshaw on 14/05/2012.
|
||||
//
|
||||
|
||||
#ifndef The_Powder_Toy_Style_h
|
||||
#define The_Powder_Toy_Style_h
|
||||
|
||||
namespace ui { class Colour; }
|
||||
|
||||
namespace style
|
||||
{
|
||||
class Colour
|
||||
{
|
||||
public:
|
||||
static ui::Colour InformationTitle;
|
||||
static ui::Colour WarningTitle;
|
||||
static ui::Colour ErrorTitle;
|
||||
|
||||
static ui::Colour ConfirmButton;
|
||||
|
||||
static ui::Colour ActiveBorder;
|
||||
static ui::Colour InactiveBorder;
|
||||
|
||||
static ui::Colour ActiveBackground;
|
||||
static ui::Colour InactiveBackground;
|
||||
};
|
||||
class Metrics
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
200
src/Update.cpp
Normal file
200
src/Update.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef WIN
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#if !defined(MACOSX) && !defined(BSD)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WIN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef MACOSX
|
||||
#include <mach-o/dyld.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include <Update.h>
|
||||
#include <Misc.h>
|
||||
|
||||
/*char *exe_name(void)
|
||||
{
|
||||
#if defined(WIN)
|
||||
char *name= (char *)malloc(64);
|
||||
DWORD max=64, res;
|
||||
while ((res = GetModuleFileName(NULL, name, max)) >= max)
|
||||
{
|
||||
#elif defined MACOSX
|
||||
char *fn=malloc(64),*name=malloc(PATH_MAX);
|
||||
uint32_t max=64, res;
|
||||
if (_NSGetExecutablePath(fn, &max) != 0)
|
||||
{
|
||||
fn = realloc(fn, max);
|
||||
_NSGetExecutablePath(fn, &max);
|
||||
}
|
||||
if (realpath(fn, name) == NULL)
|
||||
{
|
||||
free(fn);
|
||||
free(name);
|
||||
return NULL;
|
||||
}
|
||||
res = 1;
|
||||
#else
|
||||
char fn[64], *name=malloc(64);
|
||||
size_t max=64, res;
|
||||
sprintf(fn, "/proc/self/exe");
|
||||
memset(name, 0, max);
|
||||
while ((res = readlink(fn, name, max)) >= max-1)
|
||||
{
|
||||
#endif
|
||||
#ifndef MACOSX
|
||||
max *= 2;
|
||||
name = (char*)realloc(name, max);
|
||||
memset(name, 0, max);
|
||||
}
|
||||
#endif
|
||||
if (res <= 0)
|
||||
{
|
||||
free(name);
|
||||
return NULL;
|
||||
}
|
||||
return name;
|
||||
}*/
|
||||
|
||||
int update_start(char *data, int len)
|
||||
{
|
||||
char *self=exe_name(), *temp;
|
||||
#ifdef WIN
|
||||
char *p;
|
||||
#endif
|
||||
FILE *f;
|
||||
int res = 1;
|
||||
|
||||
if (!self)
|
||||
return 1;
|
||||
|
||||
#ifdef WIN
|
||||
temp = (char*)malloc(strlen(self)+12);
|
||||
strcpy(temp, self);
|
||||
p = temp + strlen(temp) - 4;
|
||||
if (_stricmp(p, ".exe"))
|
||||
p += 4;
|
||||
strcpy(p, "_update.exe");
|
||||
|
||||
if (!MoveFile(self, temp))
|
||||
goto fail;
|
||||
|
||||
f = fopen(self, "wb");
|
||||
if (!f)
|
||||
goto fail;
|
||||
if (fwrite(data, 1, len, f) != len)
|
||||
{
|
||||
fclose(f);
|
||||
DeleteFile(self);
|
||||
goto fail;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
if ((uintptr_t)ShellExecute(NULL, "open", self, NULL, NULL, SW_SHOWNORMAL) <= 32)
|
||||
{
|
||||
DeleteFile(self);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
temp = (char*)malloc(strlen(self)+8);
|
||||
strcpy(temp, self);
|
||||
strcat(temp, "-update");
|
||||
|
||||
f = fopen(temp, "w");
|
||||
if (!f)
|
||||
goto fail;
|
||||
if (fwrite(data, 1, len, f) != len)
|
||||
{
|
||||
fclose(f);
|
||||
unlink(temp);
|
||||
goto fail;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
if (chmod(temp, 0755))
|
||||
{
|
||||
unlink(temp);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (rename(temp, self))
|
||||
{
|
||||
unlink(temp);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
execl(self, "powder-update", NULL);
|
||||
#endif
|
||||
|
||||
fail:
|
||||
free(temp);
|
||||
free(self);
|
||||
return res;
|
||||
}
|
||||
|
||||
int update_finish(void)
|
||||
{
|
||||
#ifdef WIN
|
||||
char *temp, *self=exe_name(), *p;
|
||||
int timeout = 60, err;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Update: Current EXE name: %s\n", self);
|
||||
#endif
|
||||
|
||||
temp = (char*)malloc(strlen(self)+12);
|
||||
strcpy(temp, self);
|
||||
p = temp + strlen(temp) - 4;
|
||||
if (_stricmp(p, ".exe"))
|
||||
p += 4;
|
||||
strcpy(p, "_update.exe");
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Update: Temp EXE name: %s\n", temp);
|
||||
#endif
|
||||
|
||||
while (!DeleteFile(temp))
|
||||
{
|
||||
err = GetLastError();
|
||||
if (err == ERROR_FILE_NOT_FOUND)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Update: Temp file deleted\n");
|
||||
#endif
|
||||
free(temp);
|
||||
return 0;
|
||||
}
|
||||
Sleep(500);
|
||||
timeout--;
|
||||
if (timeout <= 0)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Update: Delete timeout\n");
|
||||
#endif
|
||||
free(temp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
free(temp);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void update_cleanup(void)
|
||||
{
|
||||
#ifdef WIN
|
||||
update_finish();
|
||||
#endif
|
||||
}
|
16
src/Update.h
Normal file
16
src/Update.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Update.h
|
||||
*
|
||||
* Created on: Jun 21, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#ifndef UPDATE_H_
|
||||
#define UPDATE_H_
|
||||
|
||||
//char *exe_name(void);
|
||||
int update_start(char *data, int len);
|
||||
int update_finish(void);
|
||||
void update_cleanup(void);
|
||||
|
||||
#endif /* UPDATE_H_ */
|
1122
src/bson/BSON.cpp
Normal file
1122
src/bson/BSON.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1205
src/bson/BSON.h
Normal file
1205
src/bson/BSON.h
Normal file
File diff suppressed because it is too large
Load Diff
403
src/cajun/elements.cpp
Normal file
403
src/cajun/elements.cpp
Normal file
@ -0,0 +1,403 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2009-2010, Terry Caton
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the projecct nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include "visitor.h"
|
||||
#include "reader.h"
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
* better documentation
|
||||
|
||||
*/
|
||||
|
||||
namespace json
|
||||
{
|
||||
|
||||
|
||||
TPT_NO_INLINE Exception::Exception(const std::string& sMessage) :
|
||||
std::runtime_error(sMessage) {}
|
||||
|
||||
|
||||
/////////////////////////
|
||||
// UnknownElement members
|
||||
|
||||
class UnknownElement::Imp
|
||||
{
|
||||
public:
|
||||
virtual ~Imp() {}
|
||||
virtual Imp* Clone() const = 0;
|
||||
|
||||
virtual bool Compare(const Imp& imp) const = 0;
|
||||
|
||||
virtual void Accept(ConstVisitor& visitor) const = 0;
|
||||
virtual void Accept(Visitor& visitor) = 0;
|
||||
};
|
||||
|
||||
|
||||
template <typename ElementTypeT>
|
||||
class UnknownElement::Imp_T : public UnknownElement::Imp
|
||||
{
|
||||
public:
|
||||
Imp_T(const ElementTypeT& element) : m_Element(element) {}
|
||||
virtual Imp* Clone() const { return new Imp_T<ElementTypeT>(*this); }
|
||||
|
||||
virtual void Accept(ConstVisitor& visitor) const { visitor.Visit(m_Element); }
|
||||
virtual void Accept(Visitor& visitor) { visitor.Visit(m_Element); }
|
||||
|
||||
virtual bool Compare(const Imp& imp) const
|
||||
{
|
||||
ConstCastVisitor_T<ElementTypeT> castVisitor;
|
||||
imp.Accept(castVisitor);
|
||||
return castVisitor.m_pElement &&
|
||||
m_Element == *castVisitor.m_pElement;
|
||||
}
|
||||
|
||||
private:
|
||||
ElementTypeT m_Element;
|
||||
};
|
||||
|
||||
|
||||
class UnknownElement::ConstCastVisitor : public ConstVisitor
|
||||
{
|
||||
virtual void Visit(const Array& array) {}
|
||||
virtual void Visit(const Object& object) {}
|
||||
virtual void Visit(const Number& number) {}
|
||||
virtual void Visit(const String& string) {}
|
||||
virtual void Visit(const Boolean& boolean) {}
|
||||
virtual void Visit(const Null& null) {}
|
||||
};
|
||||
|
||||
template <typename ElementTypeT>
|
||||
class UnknownElement::ConstCastVisitor_T : public ConstCastVisitor
|
||||
{
|
||||
public:
|
||||
ConstCastVisitor_T() : m_pElement(0) {}
|
||||
virtual void Visit(const ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions
|
||||
const ElementTypeT* m_pElement;
|
||||
};
|
||||
|
||||
|
||||
class UnknownElement::CastVisitor : public Visitor
|
||||
{
|
||||
virtual void Visit(Array& array) {}
|
||||
virtual void Visit(Object& object) {}
|
||||
virtual void Visit(Number& number) {}
|
||||
virtual void Visit(String& string) {}
|
||||
virtual void Visit(Boolean& boolean) {}
|
||||
virtual void Visit(Null& null) {}
|
||||
};
|
||||
|
||||
template <typename ElementTypeT>
|
||||
class UnknownElement::CastVisitor_T : public CastVisitor
|
||||
{
|
||||
public:
|
||||
CastVisitor_T() : m_pElement(0) {}
|
||||
virtual void Visit(ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions
|
||||
ElementTypeT* m_pElement;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
TPT_NO_INLINE UnknownElement::UnknownElement() : m_pImp( new Imp_T<Null>( Null() ) ) {}
|
||||
TPT_NO_INLINE UnknownElement::UnknownElement(const UnknownElement& unknown) : m_pImp( unknown.m_pImp->Clone()) {}
|
||||
TPT_NO_INLINE UnknownElement::UnknownElement(const Object& object) : m_pImp( new Imp_T<Object>(object) ) {}
|
||||
TPT_NO_INLINE UnknownElement::UnknownElement(const Array& array) : m_pImp( new Imp_T<Array>(array) ) {}
|
||||
TPT_NO_INLINE UnknownElement::UnknownElement(const Number& number) : m_pImp( new Imp_T<Number>(number) ) {}
|
||||
TPT_NO_INLINE UnknownElement::UnknownElement(const Boolean& boolean) : m_pImp( new Imp_T<Boolean>(boolean) ) {}
|
||||
TPT_NO_INLINE UnknownElement::UnknownElement(const String& string) : m_pImp( new Imp_T<String>(string) ) {}
|
||||
TPT_NO_INLINE UnknownElement::UnknownElement(const Null& null) : m_pImp( new Imp_T<Null>(null) ) {}
|
||||
|
||||
TPT_NO_INLINE UnknownElement::~UnknownElement() { delete m_pImp; }
|
||||
|
||||
TPT_NO_INLINE UnknownElement::operator const Object& () const { return CastTo<Object>(); }
|
||||
TPT_NO_INLINE UnknownElement::operator const Array& () const { return CastTo<Array>(); }
|
||||
TPT_NO_INLINE UnknownElement::operator const Number& () const { return CastTo<Number>(); }
|
||||
TPT_NO_INLINE UnknownElement::operator const Boolean& () const { return CastTo<Boolean>(); }
|
||||
TPT_NO_INLINE UnknownElement::operator const String& () const { return CastTo<String>(); }
|
||||
TPT_NO_INLINE UnknownElement::operator const Null& () const { return CastTo<Null>(); }
|
||||
|
||||
TPT_NO_INLINE UnknownElement::operator Object& () { return ConvertTo<Object>(); }
|
||||
TPT_NO_INLINE UnknownElement::operator Array& () { return ConvertTo<Array>(); }
|
||||
TPT_NO_INLINE UnknownElement::operator Number& () { return ConvertTo<Number>(); }
|
||||
TPT_NO_INLINE UnknownElement::operator Boolean& () { return ConvertTo<Boolean>(); }
|
||||
TPT_NO_INLINE UnknownElement::operator String& () { return ConvertTo<String>(); }
|
||||
TPT_NO_INLINE UnknownElement::operator Null& () { return ConvertTo<Null>(); }
|
||||
|
||||
TPT_NO_INLINE UnknownElement& UnknownElement::operator = (const UnknownElement& unknown)
|
||||
{
|
||||
// always check for this
|
||||
if (&unknown != this)
|
||||
{
|
||||
// we might be copying from a subtree of ourselves. delete the old imp
|
||||
// only after the clone operation is complete. yes, this could be made
|
||||
// more efficient, but isn't worth the complexity
|
||||
Imp* pOldImp = m_pImp;
|
||||
m_pImp = unknown.m_pImp->Clone();
|
||||
delete pOldImp;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
TPT_NO_INLINE UnknownElement& UnknownElement::operator[] (const std::string& key)
|
||||
{
|
||||
// the people want an object. make us one if we aren't already
|
||||
Object& object = ConvertTo<Object>();
|
||||
return object[key];
|
||||
}
|
||||
|
||||
TPT_NO_INLINE const UnknownElement& UnknownElement::operator[] (const std::string& key) const
|
||||
{
|
||||
// throws if we aren't an object
|
||||
const Object& object = CastTo<Object>();
|
||||
return object[key];
|
||||
}
|
||||
|
||||
TPT_NO_INLINE UnknownElement& UnknownElement::operator[] (size_t index)
|
||||
{
|
||||
// the people want an array. make us one if we aren't already
|
||||
Array& array = ConvertTo<Array>();
|
||||
return array[index];
|
||||
}
|
||||
|
||||
TPT_NO_INLINE const UnknownElement& UnknownElement::operator[] (size_t index) const
|
||||
{
|
||||
// throws if we aren't an array
|
||||
const Array& array = CastTo<Array>();
|
||||
return array[index];
|
||||
}
|
||||
|
||||
|
||||
template <typename ElementTypeT>
|
||||
const ElementTypeT& UnknownElement::CastTo() const
|
||||
{
|
||||
ConstCastVisitor_T<ElementTypeT> castVisitor;
|
||||
m_pImp->Accept(castVisitor);
|
||||
if (castVisitor.m_pElement == 0)
|
||||
throw Exception("Bad cast");
|
||||
return *castVisitor.m_pElement;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename ElementTypeT>
|
||||
ElementTypeT& UnknownElement::ConvertTo()
|
||||
{
|
||||
CastVisitor_T<ElementTypeT> castVisitor;
|
||||
m_pImp->Accept(castVisitor);
|
||||
if (castVisitor.m_pElement == 0)
|
||||
{
|
||||
// we're not the right type. fix it & try again
|
||||
*this = ElementTypeT();
|
||||
m_pImp->Accept(castVisitor);
|
||||
}
|
||||
|
||||
return *castVisitor.m_pElement;
|
||||
}
|
||||
|
||||
|
||||
TPT_NO_INLINE void UnknownElement::Accept(ConstVisitor& visitor) const { m_pImp->Accept(visitor); }
|
||||
TPT_NO_INLINE void UnknownElement::Accept(Visitor& visitor) { m_pImp->Accept(visitor); }
|
||||
|
||||
|
||||
TPT_NO_INLINE bool UnknownElement::operator == (const UnknownElement& element) const
|
||||
{
|
||||
return m_pImp->Compare(*element.m_pImp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////
|
||||
// Object members
|
||||
|
||||
|
||||
TPT_NO_INLINE Object::Member::Member(const std::string& nameIn, const UnknownElement& elementIn) :
|
||||
name(nameIn), element(elementIn) {}
|
||||
|
||||
TPT_NO_INLINE bool Object::Member::operator == (const Member& member) const
|
||||
{
|
||||
return name == member.name &&
|
||||
element == member.element;
|
||||
}
|
||||
|
||||
class Object::Finder : public std::unary_function<Object::Member, bool>
|
||||
{
|
||||
public:
|
||||
Finder(const std::string& name) : m_name(name) {}
|
||||
bool operator () (const Object::Member& member) {
|
||||
return member.name == m_name;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
|
||||
|
||||
TPT_NO_INLINE Object::iterator Object::Begin() { return m_Members.begin(); }
|
||||
TPT_NO_INLINE Object::iterator Object::End() { return m_Members.end(); }
|
||||
TPT_NO_INLINE Object::const_iterator Object::Begin() const { return m_Members.begin(); }
|
||||
TPT_NO_INLINE Object::const_iterator Object::End() const { return m_Members.end(); }
|
||||
|
||||
TPT_NO_INLINE size_t Object::Size() const { return m_Members.size(); }
|
||||
TPT_NO_INLINE bool Object::Empty() const { return m_Members.empty(); }
|
||||
|
||||
TPT_NO_INLINE Object::iterator Object::Find(const std::string& name)
|
||||
{
|
||||
return std::find_if(m_Members.begin(), m_Members.end(), Finder(name));
|
||||
}
|
||||
|
||||
TPT_NO_INLINE Object::const_iterator Object::Find(const std::string& name) const
|
||||
{
|
||||
return std::find_if(m_Members.begin(), m_Members.end(), Finder(name));
|
||||
}
|
||||
|
||||
TPT_NO_INLINE Object::iterator Object::Insert(const Member& member)
|
||||
{
|
||||
return Insert(member, End());
|
||||
}
|
||||
|
||||
TPT_NO_INLINE Object::iterator Object::Insert(const Member& member, iterator itWhere)
|
||||
{
|
||||
iterator it = Find(member.name);
|
||||
if (it != m_Members.end())
|
||||
throw Exception(std::string("Object member already exists: ") + member.name);
|
||||
|
||||
it = m_Members.insert(itWhere, member);
|
||||
return it;
|
||||
}
|
||||
|
||||
TPT_NO_INLINE Object::iterator Object::Erase(iterator itWhere)
|
||||
{
|
||||
return m_Members.erase(itWhere);
|
||||
}
|
||||
|
||||
TPT_NO_INLINE UnknownElement& Object::operator [](const std::string& name)
|
||||
{
|
||||
|
||||
iterator it = Find(name);
|
||||
if (it == m_Members.end())
|
||||
{
|
||||
Member member(name);
|
||||
it = Insert(member, End());
|
||||
}
|
||||
return it->element;
|
||||
}
|
||||
|
||||
TPT_NO_INLINE const UnknownElement& Object::operator [](const std::string& name) const
|
||||
{
|
||||
const_iterator it = Find(name);
|
||||
if (it == End())
|
||||
throw Exception(std::string("Object member not found: ") + name);
|
||||
return it->element;
|
||||
}
|
||||
|
||||
TPT_NO_INLINE void Object::Clear()
|
||||
{
|
||||
m_Members.clear();
|
||||
}
|
||||
|
||||
TPT_NO_INLINE bool Object::operator == (const Object& object) const
|
||||
{
|
||||
return m_Members == object.m_Members;
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
// Array members
|
||||
|
||||
TPT_NO_INLINE Array::iterator Array::Begin() { return m_Elements.begin(); }
|
||||
TPT_NO_INLINE Array::iterator Array::End() { return m_Elements.end(); }
|
||||
TPT_NO_INLINE Array::const_iterator Array::Begin() const { return m_Elements.begin(); }
|
||||
TPT_NO_INLINE Array::const_iterator Array::End() const { return m_Elements.end(); }
|
||||
|
||||
TPT_NO_INLINE Array::iterator Array::Insert(const UnknownElement& element, iterator itWhere)
|
||||
{
|
||||
return m_Elements.insert(itWhere, element);
|
||||
}
|
||||
|
||||
TPT_NO_INLINE Array::iterator Array::Insert(const UnknownElement& element)
|
||||
{
|
||||
return Insert(element, End());
|
||||
}
|
||||
|
||||
TPT_NO_INLINE Array::iterator Array::Erase(iterator itWhere)
|
||||
{
|
||||
return m_Elements.erase(itWhere);
|
||||
}
|
||||
|
||||
TPT_NO_INLINE void Array::Resize(size_t newSize)
|
||||
{
|
||||
m_Elements.resize(newSize);
|
||||
}
|
||||
|
||||
TPT_NO_INLINE size_t Array::Size() const { return m_Elements.size(); }
|
||||
TPT_NO_INLINE bool Array::Empty() const { return m_Elements.empty(); }
|
||||
|
||||
TPT_NO_INLINE UnknownElement& Array::operator[] (size_t index)
|
||||
{
|
||||
size_t nMinSize = index + 1; // zero indexed
|
||||
if (m_Elements.size() < nMinSize)
|
||||
m_Elements.resize(nMinSize);
|
||||
return m_Elements[index];
|
||||
}
|
||||
|
||||
TPT_NO_INLINE const UnknownElement& Array::operator[] (size_t index) const
|
||||
{
|
||||
if (index >= m_Elements.size())
|
||||
throw Exception("Array out of bounds");
|
||||
return m_Elements[index];
|
||||
}
|
||||
|
||||
TPT_NO_INLINE void Array::Clear() {
|
||||
m_Elements.clear();
|
||||
}
|
||||
|
||||
TPT_NO_INLINE bool Array::operator == (const Array& array) const
|
||||
{
|
||||
return m_Elements == array.m_Elements;
|
||||
}
|
||||
|
||||
|
||||
//////////////////
|
||||
// Null members
|
||||
|
||||
TPT_NO_INLINE bool Null::operator == (const Null& trivial) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // End namespace
|
337
src/cajun/elements.h
Normal file
337
src/cajun/elements.h
Normal file
@ -0,0 +1,337 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2009-2010, Terry Caton
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the projecct nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
#include <list>
|
||||
//#include <iterator>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include "Config.h"
|
||||
/*
|
||||
|
||||
TODO:
|
||||
* better documentation (doxygen?)
|
||||
* Unicode support
|
||||
* parent element accessors
|
||||
|
||||
*/
|
||||
|
||||
namespace json
|
||||
{
|
||||
|
||||
namespace Version
|
||||
{
|
||||
enum { MAJOR = 2 };
|
||||
enum { MINOR = 0 };
|
||||
enum {ENGINEERING = 2 };
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// forward declarations (more info further below)
|
||||
|
||||
|
||||
class Visitor;
|
||||
class ConstVisitor;
|
||||
|
||||
template <typename ValueTypeT>
|
||||
class TrivialType_T;
|
||||
|
||||
typedef TrivialType_T<double> Number;
|
||||
typedef TrivialType_T<bool> Boolean;
|
||||
typedef TrivialType_T<std::string> String;
|
||||
|
||||
class Object;
|
||||
class Array;
|
||||
class Null;
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Exception - base class for all JSON-related runtime errors
|
||||
|
||||
class Exception : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
Exception(const std::string& sMessage);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// UnknownElement - provides a typesafe surrogate for any of the JSON-
|
||||
// sanctioned element types. This class allows the Array and Object
|
||||
// class to effectively contain a heterogeneous set of child elements.
|
||||
// The cast operators provide convenient implicit downcasting, while
|
||||
// preserving dynamic type safety by throwing an exception during a
|
||||
// a bad cast.
|
||||
// The object & array element index operators (operators [std::string]
|
||||
// and [size_t]) provide convenient, quick access to child elements.
|
||||
// They are a logical extension of the cast operators. These child
|
||||
// element accesses can be chained together, allowing the following
|
||||
// (when document structure is well-known):
|
||||
// String str = objInvoices[1]["Customer"]["Company"];
|
||||
|
||||
|
||||
class UnknownElement
|
||||
{
|
||||
public:
|
||||
UnknownElement();
|
||||
UnknownElement(const UnknownElement& unknown);
|
||||
UnknownElement(const Object& object);
|
||||
UnknownElement(const Array& array);
|
||||
UnknownElement(const Number& number);
|
||||
UnknownElement(const Boolean& boolean);
|
||||
UnknownElement(const String& string);
|
||||
UnknownElement(const Null& null);
|
||||
|
||||
~UnknownElement();
|
||||
|
||||
UnknownElement& operator = (const UnknownElement& unknown);
|
||||
|
||||
// implicit cast to actual element type. throws on failure
|
||||
operator const Object& () const;
|
||||
operator const Array& () const;
|
||||
operator const Number& () const;
|
||||
operator const Boolean& () const;
|
||||
operator const String& () const;
|
||||
operator const Null& () const;
|
||||
|
||||
// implicit cast to actual element type. *converts* on failure, and always returns success
|
||||
operator Object& ();
|
||||
operator Array& ();
|
||||
operator Number& ();
|
||||
operator Boolean& ();
|
||||
operator String& ();
|
||||
operator Null& ();
|
||||
|
||||
// provides quick access to children when real element type is object
|
||||
UnknownElement& operator[] (const std::string& key);
|
||||
const UnknownElement& operator[] (const std::string& key) const;
|
||||
|
||||
// provides quick access to children when real element type is array
|
||||
UnknownElement& operator[] (size_t index);
|
||||
const UnknownElement& operator[] (size_t index) const;
|
||||
|
||||
// implements visitor pattern
|
||||
void Accept(ConstVisitor& visitor) const;
|
||||
void Accept(Visitor& visitor);
|
||||
|
||||
// tests equality. first checks type, then value if possible
|
||||
bool operator == (const UnknownElement& element) const;
|
||||
|
||||
private:
|
||||
class Imp;
|
||||
|
||||
template <typename ElementTypeT>
|
||||
class Imp_T;
|
||||
|
||||
class CastVisitor;
|
||||
class ConstCastVisitor;
|
||||
|
||||
template <typename ElementTypeT>
|
||||
class CastVisitor_T;
|
||||
|
||||
template <typename ElementTypeT>
|
||||
class ConstCastVisitor_T;
|
||||
|
||||
template <typename ElementTypeT>
|
||||
const ElementTypeT& CastTo() const;
|
||||
|
||||
template <typename ElementTypeT>
|
||||
ElementTypeT& ConvertTo();
|
||||
|
||||
Imp* m_pImp;
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Array - mimics std::deque<UnknownElement>. The array contents are effectively
|
||||
// heterogeneous thanks to the ElementUnknown class. push_back has been replaced
|
||||
// by more generic insert functions.
|
||||
|
||||
class Array
|
||||
{
|
||||
public:
|
||||
typedef std::deque<UnknownElement> Elements;
|
||||
typedef Elements::iterator iterator;
|
||||
typedef Elements::const_iterator const_iterator;
|
||||
|
||||
iterator Begin();
|
||||
iterator End();
|
||||
const_iterator Begin() const;
|
||||
const_iterator End() const;
|
||||
|
||||
iterator Insert(const UnknownElement& element, iterator itWhere);
|
||||
iterator Insert(const UnknownElement& element);
|
||||
iterator Erase(iterator itWhere);
|
||||
void Resize(size_t newSize);
|
||||
void Clear();
|
||||
|
||||
size_t Size() const;
|
||||
bool Empty() const;
|
||||
|
||||
UnknownElement& operator[] (size_t index);
|
||||
const UnknownElement& operator[] (size_t index) const;
|
||||
|
||||
bool operator == (const Array& array) const;
|
||||
|
||||
private:
|
||||
Elements m_Elements;
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Object - mimics std::map<std::string, UnknownElement>. The member value
|
||||
// contents are effectively heterogeneous thanks to the UnknownElement class
|
||||
|
||||
class Object
|
||||
{
|
||||
public:
|
||||
struct Member {
|
||||
Member(const std::string& nameIn = std::string(), const UnknownElement& elementIn = UnknownElement());
|
||||
|
||||
bool operator == (const Member& member) const;
|
||||
|
||||
std::string name;
|
||||
UnknownElement element;
|
||||
};
|
||||
|
||||
typedef std::list<Member> Members; // map faster, but does not preserve order
|
||||
typedef Members::iterator iterator;
|
||||
typedef Members::const_iterator const_iterator;
|
||||
|
||||
bool operator == (const Object& object) const;
|
||||
|
||||
iterator Begin();
|
||||
iterator End();
|
||||
const_iterator Begin() const;
|
||||
const_iterator End() const;
|
||||
|
||||
size_t Size() const;
|
||||
bool Empty() const;
|
||||
|
||||
iterator Find(const std::string& name);
|
||||
const_iterator Find(const std::string& name) const;
|
||||
|
||||
iterator Insert(const Member& member);
|
||||
iterator Insert(const Member& member, iterator itWhere);
|
||||
iterator Erase(iterator itWhere);
|
||||
void Clear();
|
||||
|
||||
UnknownElement& operator [](const std::string& name);
|
||||
const UnknownElement& operator [](const std::string& name) const;
|
||||
|
||||
private:
|
||||
class Finder;
|
||||
|
||||
Members m_Members;
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// TrivialType_T - class template for encapsulates a simple data type, such as
|
||||
// a string, number, or boolean. Provides implicit const & noncost cast operators
|
||||
// for that type, allowing "DataTypeT type = trivialType;"
|
||||
|
||||
|
||||
template <typename DataTypeT>
|
||||
class TrivialType_T
|
||||
{
|
||||
public:
|
||||
TrivialType_T(const DataTypeT& t = DataTypeT());
|
||||
|
||||
operator DataTypeT&();
|
||||
operator const DataTypeT&() const;
|
||||
|
||||
DataTypeT& Value();
|
||||
const DataTypeT& Value() const;
|
||||
|
||||
bool operator == (const TrivialType_T<DataTypeT>& trivial) const;
|
||||
|
||||
private:
|
||||
DataTypeT m_tValue;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Null - doesn't do much of anything but satisfy the JSON spec. It is the default
|
||||
// element type of UnknownElement
|
||||
|
||||
class Null
|
||||
{
|
||||
public:
|
||||
bool operator == (const Null& trivial) const;
|
||||
};
|
||||
|
||||
////////////////////////
|
||||
// TrivialType_T members
|
||||
|
||||
template <typename DataTypeT>
|
||||
TrivialType_T<DataTypeT>::TrivialType_T(const DataTypeT& t) :
|
||||
m_tValue(t) {}
|
||||
|
||||
template <typename DataTypeT>
|
||||
TrivialType_T<DataTypeT>::operator DataTypeT&()
|
||||
{
|
||||
return Value();
|
||||
}
|
||||
|
||||
template <typename DataTypeT>
|
||||
TrivialType_T<DataTypeT>::operator const DataTypeT&() const
|
||||
{
|
||||
return Value();
|
||||
}
|
||||
|
||||
template <typename DataTypeT>
|
||||
DataTypeT& TrivialType_T<DataTypeT>::Value()
|
||||
{
|
||||
return m_tValue;
|
||||
}
|
||||
|
||||
template <typename DataTypeT>
|
||||
const DataTypeT& TrivialType_T<DataTypeT>::Value() const
|
||||
{
|
||||
return m_tValue;
|
||||
}
|
||||
|
||||
template <typename DataTypeT>
|
||||
bool TrivialType_T<DataTypeT>::operator == (const TrivialType_T<DataTypeT>& trivial) const
|
||||
{
|
||||
return m_tValue == trivial.m_tValue;
|
||||
}
|
||||
|
||||
|
||||
} // End namespace
|
||||
|
||||
|
||||
//#include "elements.inl"
|
534
src/cajun/reader.cpp
Normal file
534
src/cajun/reader.cpp
Normal file
@ -0,0 +1,534 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2009-2010, Terry Caton
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the projecct nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include <cassert>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include "reader.h"
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
* better documentation
|
||||
* unicode character decoding
|
||||
|
||||
*/
|
||||
|
||||
namespace json
|
||||
{
|
||||
|
||||
TPT_NO_INLINE std::istream& operator >> (std::istream& istr, UnknownElement& elementRoot) {
|
||||
Reader::Read(elementRoot, istr);
|
||||
return istr;
|
||||
}
|
||||
|
||||
TPT_NO_INLINE Reader::Location::Location() :
|
||||
m_nLine(0),
|
||||
m_nLineOffset(0),
|
||||
m_nDocOffset(0)
|
||||
{}
|
||||
|
||||
|
||||
//////////////////////
|
||||
// Reader::InputStream
|
||||
|
||||
class Reader::InputStream // would be cool if we could inherit from std::istream & override "get"
|
||||
{
|
||||
public:
|
||||
InputStream(std::istream& iStr) :
|
||||
m_iStr(iStr) {}
|
||||
|
||||
// protect access to the input stream, so we can keeep track of document/line offsets
|
||||
char Get(); // big, define outside
|
||||
char Peek() {
|
||||
assert(m_iStr.eof() == false); // enforce reading of only valid stream data
|
||||
return m_iStr.peek();
|
||||
}
|
||||
|
||||
bool EOS() {
|
||||
m_iStr.peek(); // apparently eof flag isn't set until a character read is attempted. whatever.
|
||||
return m_iStr.eof();
|
||||
}
|
||||
|
||||
const Location& GetLocation() const { return m_Location; }
|
||||
|
||||
private:
|
||||
std::istream& m_iStr;
|
||||
Location m_Location;
|
||||
};
|
||||
|
||||
|
||||
TPT_NO_INLINE char Reader::InputStream::Get()
|
||||
{
|
||||
assert(m_iStr.eof() == false); // enforce reading of only valid stream data
|
||||
char c = m_iStr.get();
|
||||
|
||||
++m_Location.m_nDocOffset;
|
||||
if (c == '\n') {
|
||||
++m_Location.m_nLine;
|
||||
m_Location.m_nLineOffset = 0;
|
||||
}
|
||||
else {
|
||||
++m_Location.m_nLineOffset;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////
|
||||
// Reader::TokenStream
|
||||
|
||||
class Reader::TokenStream
|
||||
{
|
||||
public:
|
||||
TokenStream(const Tokens& tokens);
|
||||
|
||||
const Token& Peek();
|
||||
const Token& Get();
|
||||
|
||||
bool EOS() const;
|
||||
|
||||
private:
|
||||
const Tokens& m_Tokens;
|
||||
Tokens::const_iterator m_itCurrent;
|
||||
};
|
||||
|
||||
|
||||
TPT_NO_INLINE Reader::TokenStream::TokenStream(const Tokens& tokens) :
|
||||
m_Tokens(tokens),
|
||||
m_itCurrent(tokens.begin())
|
||||
{}
|
||||
|
||||
TPT_NO_INLINE const Reader::Token& Reader::TokenStream::Peek() {
|
||||
if (EOS())
|
||||
{
|
||||
const Token& lastToken = *m_Tokens.rbegin();
|
||||
std::string sMessage = "Unexpected end of token stream";
|
||||
throw ParseException(sMessage, lastToken.locBegin, lastToken.locEnd); // nowhere to point to
|
||||
}
|
||||
return *(m_itCurrent);
|
||||
}
|
||||
|
||||
TPT_NO_INLINE const Reader::Token& Reader::TokenStream::Get() {
|
||||
const Token& token = Peek();
|
||||
++m_itCurrent;
|
||||
return token;
|
||||
}
|
||||
|
||||
TPT_NO_INLINE bool Reader::TokenStream::EOS() const {
|
||||
return m_itCurrent == m_Tokens.end();
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// Reader (finally)
|
||||
|
||||
|
||||
TPT_NO_INLINE void Reader::Read(Object& object, std::istream& istr) { Read_i(object, istr); }
|
||||
TPT_NO_INLINE void Reader::Read(Array& array, std::istream& istr) { Read_i(array, istr); }
|
||||
TPT_NO_INLINE void Reader::Read(String& string, std::istream& istr) { Read_i(string, istr); }
|
||||
TPT_NO_INLINE void Reader::Read(Number& number, std::istream& istr) { Read_i(number, istr); }
|
||||
TPT_NO_INLINE void Reader::Read(Boolean& boolean, std::istream& istr) { Read_i(boolean, istr); }
|
||||
TPT_NO_INLINE void Reader::Read(Null& null, std::istream& istr) { Read_i(null, istr); }
|
||||
TPT_NO_INLINE void Reader::Read(UnknownElement& unknown, std::istream& istr) { Read_i(unknown, istr); }
|
||||
|
||||
|
||||
template <typename ElementTypeT>
|
||||
void Reader::Read_i(ElementTypeT& element, std::istream& istr)
|
||||
{
|
||||
Reader reader;
|
||||
|
||||
Tokens tokens;
|
||||
InputStream inputStream(istr);
|
||||
reader.Scan(tokens, inputStream);
|
||||
|
||||
TokenStream tokenStream(tokens);
|
||||
reader.Parse(element, tokenStream);
|
||||
|
||||
if (tokenStream.EOS() == false)
|
||||
{
|
||||
const Token& token = tokenStream.Peek();
|
||||
std::string sMessage = std::string("Expected End of token stream; found ") + token.sValue;
|
||||
throw ParseException(sMessage, token.locBegin, token.locEnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TPT_NO_INLINE void Reader::Scan(Tokens& tokens, InputStream& inputStream)
|
||||
{
|
||||
while (EatWhiteSpace(inputStream), // ignore any leading white space...
|
||||
inputStream.EOS() == false) // ...before checking for EOS
|
||||
{
|
||||
// if all goes well, we'll create a token each pass
|
||||
Token token;
|
||||
token.locBegin = inputStream.GetLocation();
|
||||
|
||||
// gives us null-terminated string
|
||||
char sChar = inputStream.Peek();
|
||||
switch (sChar)
|
||||
{
|
||||
case '{':
|
||||
token.sValue = MatchExpectedString(inputStream, "{");
|
||||
token.nType = Token::TOKEN_OBJECT_BEGIN;
|
||||
break;
|
||||
|
||||
case '}':
|
||||
token.sValue = MatchExpectedString(inputStream, "}");
|
||||
token.nType = Token::TOKEN_OBJECT_END;
|
||||
break;
|
||||
|
||||
case '[':
|
||||
token.sValue = MatchExpectedString(inputStream, "[");
|
||||
token.nType = Token::TOKEN_ARRAY_BEGIN;
|
||||
break;
|
||||
|
||||
case ']':
|
||||
token.sValue = MatchExpectedString(inputStream, "]");
|
||||
token.nType = Token::TOKEN_ARRAY_END;
|
||||
break;
|
||||
|
||||
case ',':
|
||||
token.sValue = MatchExpectedString(inputStream, ",");
|
||||
token.nType = Token::TOKEN_NEXT_ELEMENT;
|
||||
break;
|
||||
|
||||
case ':':
|
||||
token.sValue = MatchExpectedString(inputStream, ":");
|
||||
token.nType = Token::TOKEN_MEMBER_ASSIGN;
|
||||
break;
|
||||
|
||||
case '"':
|
||||
token.sValue = MatchString(inputStream);
|
||||
token.nType = Token::TOKEN_STRING;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
token.sValue = MatchNumber(inputStream);
|
||||
token.nType = Token::TOKEN_NUMBER;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
token.sValue = MatchExpectedString(inputStream, "true");
|
||||
token.nType = Token::TOKEN_BOOLEAN;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
token.sValue = MatchExpectedString(inputStream, "false");
|
||||
token.nType = Token::TOKEN_BOOLEAN;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
token.sValue = MatchExpectedString(inputStream, "null");
|
||||
token.nType = Token::TOKEN_NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
std::string sErrorMessage = std::string("Unexpected character in stream: ") + sChar;
|
||||
throw ScanException(sErrorMessage, inputStream.GetLocation());
|
||||
}
|
||||
}
|
||||
|
||||
token.locEnd = inputStream.GetLocation();
|
||||
tokens.push_back(token);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TPT_NO_INLINE void Reader::EatWhiteSpace(InputStream& inputStream)
|
||||
{
|
||||
while (inputStream.EOS() == false &&
|
||||
::isspace(inputStream.Peek()))
|
||||
inputStream.Get();
|
||||
}
|
||||
|
||||
TPT_NO_INLINE std::string Reader::MatchExpectedString(InputStream& inputStream, const std::string& sExpected)
|
||||
{
|
||||
std::string::const_iterator it(sExpected.begin()),
|
||||
itEnd(sExpected.end());
|
||||
for ( ; it != itEnd; ++it) {
|
||||
if (inputStream.EOS() || // did we reach the end before finding what we're looking for...
|
||||
inputStream.Get() != *it) // ...or did we find something different?
|
||||
{
|
||||
std::string sMessage = std::string("Expected string: ") + sExpected;
|
||||
throw ScanException(sMessage, inputStream.GetLocation());
|
||||
}
|
||||
}
|
||||
|
||||
// all's well if we made it here
|
||||
return sExpected;
|
||||
}
|
||||
|
||||
|
||||
TPT_NO_INLINE std::string Reader::MatchString(InputStream& inputStream)
|
||||
{
|
||||
MatchExpectedString(inputStream, "\"");
|
||||
|
||||
std::string string;
|
||||
while (inputStream.EOS() == false &&
|
||||
inputStream.Peek() != '"')
|
||||
{
|
||||
char c = inputStream.Get();
|
||||
|
||||
// escape?
|
||||
if (c == '\\' &&
|
||||
inputStream.EOS() == false) // shouldn't have reached the end yet
|
||||
{
|
||||
c = inputStream.Get();
|
||||
switch (c) {
|
||||
case '/': string.push_back('/'); break;
|
||||
case '"': string.push_back('"'); break;
|
||||
case '\\': string.push_back('\\'); break;
|
||||
case 'b': string.push_back('\b'); break;
|
||||
case 'f': string.push_back('\f'); break;
|
||||
case 'n': string.push_back('\n'); break;
|
||||
case 'r': string.push_back('\r'); break;
|
||||
case 't': string.push_back('\t'); break;
|
||||
//case 'u': string.push_back('\u'); break; // TODO: what do we do with this?
|
||||
default: {
|
||||
std::string sMessage = std::string("Unrecognized escape sequence found in string: \\") + c;
|
||||
throw ScanException(sMessage, inputStream.GetLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
string.push_back(c);
|
||||
}
|
||||
}
|
||||
|
||||
// eat the last '"' that we just peeked
|
||||
MatchExpectedString(inputStream, "\"");
|
||||
|
||||
// all's well if we made it here
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
TPT_NO_INLINE std::string Reader::MatchNumber(InputStream& inputStream)
|
||||
{
|
||||
const char sNumericChars[] = "0123456789.eE-+";
|
||||
std::set<char> numericChars;
|
||||
numericChars.insert(sNumericChars, sNumericChars + sizeof(sNumericChars));
|
||||
|
||||
std::string sNumber;
|
||||
while (inputStream.EOS() == false &&
|
||||
numericChars.find(inputStream.Peek()) != numericChars.end())
|
||||
{
|
||||
sNumber.push_back(inputStream.Get());
|
||||
}
|
||||
|
||||
return sNumber;
|
||||
}
|
||||
|
||||
|
||||
TPT_NO_INLINE void Reader::Parse(UnknownElement& element, Reader::TokenStream& tokenStream)
|
||||
{
|
||||
const Token& token = tokenStream.Peek();
|
||||
switch (token.nType) {
|
||||
case Token::TOKEN_OBJECT_BEGIN:
|
||||
{
|
||||
// implicit non-const cast will perform conversion for us (if necessary)
|
||||
Object& object = element;
|
||||
Parse(object, tokenStream);
|
||||
break;
|
||||
}
|
||||
|
||||
case Token::TOKEN_ARRAY_BEGIN:
|
||||
{
|
||||
Array& array = element;
|
||||
Parse(array, tokenStream);
|
||||
break;
|
||||
}
|
||||
|
||||
case Token::TOKEN_STRING:
|
||||
{
|
||||
String& string = element;
|
||||
Parse(string, tokenStream);
|
||||
break;
|
||||
}
|
||||
|
||||
case Token::TOKEN_NUMBER:
|
||||
{
|
||||
Number& number = element;
|
||||
Parse(number, tokenStream);
|
||||
break;
|
||||
}
|
||||
|
||||
case Token::TOKEN_BOOLEAN:
|
||||
{
|
||||
Boolean& boolean = element;
|
||||
Parse(boolean, tokenStream);
|
||||
break;
|
||||
}
|
||||
|
||||
case Token::TOKEN_NULL:
|
||||
{
|
||||
Null& null = element;
|
||||
Parse(null, tokenStream);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
std::string sMessage = std::string("Unexpected token: ") + token.sValue;
|
||||
throw ParseException(sMessage, token.locBegin, token.locEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TPT_NO_INLINE void Reader::Parse(Object& object, Reader::TokenStream& tokenStream)
|
||||
{
|
||||
MatchExpectedToken(Token::TOKEN_OBJECT_BEGIN, tokenStream);
|
||||
|
||||
bool bContinue = (tokenStream.EOS() == false &&
|
||||
tokenStream.Peek().nType != Token::TOKEN_OBJECT_END);
|
||||
while (bContinue)
|
||||
{
|
||||
Object::Member member;
|
||||
|
||||
// first the member name. save the token in case we have to throw an exception
|
||||
const Token& tokenName = tokenStream.Peek();
|
||||
member.name = MatchExpectedToken(Token::TOKEN_STRING, tokenStream);
|
||||
|
||||
// ...then the key/value separator...
|
||||
MatchExpectedToken(Token::TOKEN_MEMBER_ASSIGN, tokenStream);
|
||||
|
||||
// ...then the value itself (can be anything).
|
||||
Parse(member.element, tokenStream);
|
||||
|
||||
// try adding it to the object (this could throw)
|
||||
try
|
||||
{
|
||||
object.Insert(member);
|
||||
}
|
||||
catch (Exception&)
|
||||
{
|
||||
// must be a duplicate name
|
||||
std::string sMessage = std::string("Duplicate object member token: ") + member.name;
|
||||
throw ParseException(sMessage, tokenName.locBegin, tokenName.locEnd);
|
||||
}
|
||||
|
||||
bContinue = (tokenStream.EOS() == false &&
|
||||
tokenStream.Peek().nType == Token::TOKEN_NEXT_ELEMENT);
|
||||
if (bContinue)
|
||||
MatchExpectedToken(Token::TOKEN_NEXT_ELEMENT, tokenStream);
|
||||
}
|
||||
|
||||
MatchExpectedToken(Token::TOKEN_OBJECT_END, tokenStream);
|
||||
}
|
||||
|
||||
|
||||
TPT_NO_INLINE void Reader::Parse(Array& array, Reader::TokenStream& tokenStream)
|
||||
{
|
||||
MatchExpectedToken(Token::TOKEN_ARRAY_BEGIN, tokenStream);
|
||||
|
||||
bool bContinue = (tokenStream.EOS() == false &&
|
||||
tokenStream.Peek().nType != Token::TOKEN_ARRAY_END);
|
||||
while (bContinue)
|
||||
{
|
||||
// ...what's next? could be anything
|
||||
Array::iterator itElement = array.Insert(UnknownElement());
|
||||
UnknownElement& element = *itElement;
|
||||
Parse(element, tokenStream);
|
||||
|
||||
bContinue = (tokenStream.EOS() == false &&
|
||||
tokenStream.Peek().nType == Token::TOKEN_NEXT_ELEMENT);
|
||||
if (bContinue)
|
||||
MatchExpectedToken(Token::TOKEN_NEXT_ELEMENT, tokenStream);
|
||||
}
|
||||
|
||||
MatchExpectedToken(Token::TOKEN_ARRAY_END, tokenStream);
|
||||
}
|
||||
|
||||
|
||||
TPT_NO_INLINE void Reader::Parse(String& string, Reader::TokenStream& tokenStream)
|
||||
{
|
||||
string = MatchExpectedToken(Token::TOKEN_STRING, tokenStream);
|
||||
}
|
||||
|
||||
|
||||
TPT_NO_INLINE void Reader::Parse(Number& number, Reader::TokenStream& tokenStream)
|
||||
{
|
||||
const Token& currentToken = tokenStream.Peek(); // might need this later for throwing exception
|
||||
const std::string& sValue = MatchExpectedToken(Token::TOKEN_NUMBER, tokenStream);
|
||||
|
||||
std::istringstream iStr(sValue);
|
||||
double dValue;
|
||||
iStr >> dValue;
|
||||
|
||||
// did we consume all characters in the token?
|
||||
if (iStr.eof() == false)
|
||||
{
|
||||
char c = iStr.peek();
|
||||
std::string sMessage = std::string("Unexpected character in NUMBER token: ") + c;
|
||||
throw ParseException(sMessage, currentToken.locBegin, currentToken.locEnd);
|
||||
}
|
||||
|
||||
number = dValue;
|
||||
}
|
||||
|
||||
|
||||
TPT_NO_INLINE void Reader::Parse(Boolean& boolean, Reader::TokenStream& tokenStream)
|
||||
{
|
||||
const std::string& sValue = MatchExpectedToken(Token::TOKEN_BOOLEAN, tokenStream);
|
||||
boolean = (sValue == "true" ? true : false);
|
||||
}
|
||||
|
||||
|
||||
TPT_NO_INLINE void Reader::Parse(Null&, Reader::TokenStream& tokenStream)
|
||||
{
|
||||
MatchExpectedToken(Token::TOKEN_NULL, tokenStream);
|
||||
}
|
||||
|
||||
|
||||
TPT_NO_INLINE const std::string& Reader::MatchExpectedToken(Token::Type nExpected, Reader::TokenStream& tokenStream)
|
||||
{
|
||||
const Token& token = tokenStream.Get();
|
||||
if (token.nType != nExpected)
|
||||
{
|
||||
std::string sMessage = std::string("Unexpected token: ") + token.sValue;
|
||||
throw ParseException(sMessage, token.locBegin, token.locEnd);
|
||||
}
|
||||
|
||||
return token.sValue;
|
||||
}
|
||||
|
||||
} // End namespace
|
148
src/cajun/reader.h
Normal file
148
src/cajun/reader.h
Normal file
@ -0,0 +1,148 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2009-2010, Terry Caton
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the projecct nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "elements.h"
|
||||
|
||||
namespace json
|
||||
{
|
||||
|
||||
class Reader
|
||||
{
|
||||
public:
|
||||
// this structure will be reported in one of the exceptions defined below
|
||||
struct Location
|
||||
{
|
||||
Location();
|
||||
|
||||
unsigned int m_nLine; // document line, zero-indexed
|
||||
unsigned int m_nLineOffset; // character offset from beginning of line, zero indexed
|
||||
unsigned int m_nDocOffset; // character offset from entire document, zero indexed
|
||||
};
|
||||
|
||||
// thrown during the first phase of reading. generally catches low-level problems such
|
||||
// as errant characters or corrupt/incomplete documents
|
||||
class ScanException : public Exception
|
||||
{
|
||||
public:
|
||||
ScanException(const std::string& sMessage, const Reader::Location& locError) :
|
||||
Exception(sMessage),
|
||||
m_locError(locError) {}
|
||||
|
||||
Reader::Location m_locError;
|
||||
};
|
||||
|
||||
// thrown during the second phase of reading. generally catches higher-level problems such
|
||||
// as missing commas or brackets
|
||||
class ParseException : public Exception
|
||||
{
|
||||
public:
|
||||
ParseException(const std::string& sMessage, const Reader::Location& locTokenBegin, const Reader::Location& locTokenEnd) :
|
||||
Exception(sMessage),
|
||||
m_locTokenBegin(locTokenBegin),
|
||||
m_locTokenEnd(locTokenEnd) {}
|
||||
|
||||
Reader::Location m_locTokenBegin;
|
||||
Reader::Location m_locTokenEnd;
|
||||
};
|
||||
|
||||
|
||||
// if you know what the document looks like, call one of these...
|
||||
static void Read(Object& object, std::istream& istr);
|
||||
static void Read(Array& array, std::istream& istr);
|
||||
static void Read(String& string, std::istream& istr);
|
||||
static void Read(Number& number, std::istream& istr);
|
||||
static void Read(Boolean& boolean, std::istream& istr);
|
||||
static void Read(Null& null, std::istream& istr);
|
||||
|
||||
// ...otherwise, if you don't know, call this & visit it
|
||||
static void Read(UnknownElement& elementRoot, std::istream& istr);
|
||||
|
||||
private:
|
||||
struct Token
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
TOKEN_OBJECT_BEGIN, // {
|
||||
TOKEN_OBJECT_END, // }
|
||||
TOKEN_ARRAY_BEGIN, // [
|
||||
TOKEN_ARRAY_END, // ]
|
||||
TOKEN_NEXT_ELEMENT, // ,
|
||||
TOKEN_MEMBER_ASSIGN, // :
|
||||
TOKEN_STRING, // "xxx"
|
||||
TOKEN_NUMBER, // [+/-]000.000[e[+/-]000]
|
||||
TOKEN_BOOLEAN, // true -or- false
|
||||
TOKEN_NULL, // null
|
||||
};
|
||||
|
||||
Type nType;
|
||||
std::string sValue;
|
||||
|
||||
// for malformed file debugging
|
||||
Reader::Location locBegin;
|
||||
Reader::Location locEnd;
|
||||
};
|
||||
|
||||
class InputStream;
|
||||
class TokenStream;
|
||||
typedef std::vector<Token> Tokens;
|
||||
|
||||
template <typename ElementTypeT>
|
||||
static void Read_i(ElementTypeT& element, std::istream& istr);
|
||||
|
||||
// scanning istream into token sequence
|
||||
void Scan(Tokens& tokens, InputStream& inputStream);
|
||||
|
||||
void EatWhiteSpace(InputStream& inputStream);
|
||||
std::string MatchString(InputStream& inputStream);
|
||||
std::string MatchNumber(InputStream& inputStream);
|
||||
std::string MatchExpectedString(InputStream& inputStream, const std::string& sExpected);
|
||||
|
||||
// parsing token sequence into element structure
|
||||
void Parse(UnknownElement& element, TokenStream& tokenStream);
|
||||
void Parse(Object& object, TokenStream& tokenStream);
|
||||
void Parse(Array& array, TokenStream& tokenStream);
|
||||
void Parse(String& string, TokenStream& tokenStream);
|
||||
void Parse(Number& number, TokenStream& tokenStream);
|
||||
void Parse(Boolean& boolean, TokenStream& tokenStream);
|
||||
void Parse(Null& null, TokenStream& tokenStream);
|
||||
|
||||
const std::string& MatchExpectedToken(Token::Type nExpected, TokenStream& tokenStream);
|
||||
};
|
||||
|
||||
|
||||
} // End namespace
|
||||
|
||||
|
||||
//#include "reader.inl"
|
65
src/cajun/visitor.h
Normal file
65
src/cajun/visitor.h
Normal file
@ -0,0 +1,65 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2009-2010, Terry Caton
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the projecct nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "elements.h"
|
||||
|
||||
namespace json
|
||||
{
|
||||
|
||||
|
||||
class Visitor
|
||||
{
|
||||
public:
|
||||
virtual ~Visitor() {}
|
||||
|
||||
virtual void Visit(Array& array) = 0;
|
||||
virtual void Visit(Object& object) = 0;
|
||||
virtual void Visit(Number& number) = 0;
|
||||
virtual void Visit(String& string) = 0;
|
||||
virtual void Visit(Boolean& boolean) = 0;
|
||||
virtual void Visit(Null& null) = 0;
|
||||
};
|
||||
|
||||
class ConstVisitor
|
||||
{
|
||||
public:
|
||||
virtual ~ConstVisitor() {}
|
||||
|
||||
virtual void Visit(const Array& array) = 0;
|
||||
virtual void Visit(const Object& object) = 0;
|
||||
virtual void Visit(const Number& number) = 0;
|
||||
virtual void Visit(const String& string) = 0;
|
||||
virtual void Visit(const Boolean& boolean) = 0;
|
||||
virtual void Visit(const Null& null) = 0;
|
||||
};
|
||||
|
||||
|
||||
} // End namespace
|
178
src/cajun/writer.cpp
Normal file
178
src/cajun/writer.cpp
Normal file
@ -0,0 +1,178 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2009-2010, Terry Caton
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the projecct nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "writer.h"
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
* better documentation
|
||||
* unicode character encoding
|
||||
|
||||
*/
|
||||
|
||||
namespace json
|
||||
{
|
||||
|
||||
|
||||
TPT_NO_INLINE void Writer::Write(const UnknownElement& elementRoot, std::ostream& ostr) { Write_i(elementRoot, ostr); }
|
||||
TPT_NO_INLINE void Writer::Write(const Object& object, std::ostream& ostr) { Write_i(object, ostr); }
|
||||
TPT_NO_INLINE void Writer::Write(const Array& array, std::ostream& ostr) { Write_i(array, ostr); }
|
||||
TPT_NO_INLINE void Writer::Write(const Number& number, std::ostream& ostr) { Write_i(number, ostr); }
|
||||
TPT_NO_INLINE void Writer::Write(const String& string, std::ostream& ostr) { Write_i(string, ostr); }
|
||||
TPT_NO_INLINE void Writer::Write(const Boolean& boolean, std::ostream& ostr) { Write_i(boolean, ostr); }
|
||||
TPT_NO_INLINE void Writer::Write(const Null& null, std::ostream& ostr) { Write_i(null, ostr); }
|
||||
|
||||
|
||||
TPT_NO_INLINE Writer::Writer(std::ostream& ostr) :
|
||||
m_ostr(ostr),
|
||||
m_nTabDepth(0)
|
||||
{}
|
||||
|
||||
template <typename ElementTypeT>
|
||||
void Writer::Write_i(const ElementTypeT& element, std::ostream& ostr)
|
||||
{
|
||||
Writer writer(ostr);
|
||||
writer.Write_i(element);
|
||||
ostr.flush(); // all done
|
||||
}
|
||||
|
||||
TPT_NO_INLINE void Writer::Write_i(const Array& array)
|
||||
{
|
||||
if (array.Empty())
|
||||
m_ostr << "[]";
|
||||
else
|
||||
{
|
||||
m_ostr << '[' << std::endl;
|
||||
++m_nTabDepth;
|
||||
|
||||
Array::const_iterator it(array.Begin()),
|
||||
itEnd(array.End());
|
||||
while (it != itEnd) {
|
||||
m_ostr << std::string(m_nTabDepth, '\t');
|
||||
|
||||
Write_i(*it);
|
||||
|
||||
if (++it != itEnd)
|
||||
m_ostr << ',';
|
||||
m_ostr << std::endl;
|
||||
}
|
||||
|
||||
--m_nTabDepth;
|
||||
m_ostr << std::string(m_nTabDepth, '\t') << ']';
|
||||
}
|
||||
}
|
||||
|
||||
TPT_NO_INLINE void Writer::Write_i(const Object& object)
|
||||
{
|
||||
if (object.Empty())
|
||||
m_ostr << "{}";
|
||||
else
|
||||
{
|
||||
m_ostr << '{' << std::endl;
|
||||
++m_nTabDepth;
|
||||
|
||||
Object::const_iterator it(object.Begin()),
|
||||
itEnd(object.End());
|
||||
while (it != itEnd) {
|
||||
m_ostr << std::string(m_nTabDepth, '\t');
|
||||
|
||||
Write_i(it->name);
|
||||
|
||||
m_ostr << " : ";
|
||||
Write_i(it->element);
|
||||
|
||||
if (++it != itEnd)
|
||||
m_ostr << ',';
|
||||
m_ostr << std::endl;
|
||||
}
|
||||
|
||||
--m_nTabDepth;
|
||||
m_ostr << std::string(m_nTabDepth, '\t') << '}';
|
||||
}
|
||||
}
|
||||
|
||||
TPT_NO_INLINE void Writer::Write_i(const Number& numberElement)
|
||||
{
|
||||
m_ostr << std::setprecision(20) << numberElement.Value();
|
||||
}
|
||||
|
||||
TPT_NO_INLINE void Writer::Write_i(const Boolean& booleanElement)
|
||||
{
|
||||
m_ostr << (booleanElement.Value() ? "true" : "false");
|
||||
}
|
||||
|
||||
TPT_NO_INLINE void Writer::Write_i(const String& stringElement)
|
||||
{
|
||||
m_ostr << '"';
|
||||
|
||||
const std::string& s = stringElement.Value();
|
||||
std::string::const_iterator it(s.begin()),
|
||||
itEnd(s.end());
|
||||
for (; it != itEnd; ++it)
|
||||
{
|
||||
switch (*it)
|
||||
{
|
||||
case '"': m_ostr << "\\\""; break;
|
||||
case '\\': m_ostr << "\\\\"; break;
|
||||
case '\b': m_ostr << "\\b"; break;
|
||||
case '\f': m_ostr << "\\f"; break;
|
||||
case '\n': m_ostr << "\\n"; break;
|
||||
case '\r': m_ostr << "\\r"; break;
|
||||
case '\t': m_ostr << "\\t"; break;
|
||||
//case '\u': m_ostr << "\\u"; break; // uh...
|
||||
default: m_ostr << *it; break;
|
||||
}
|
||||
}
|
||||
|
||||
m_ostr << '"';
|
||||
}
|
||||
|
||||
TPT_NO_INLINE void Writer::Write_i(const Null& )
|
||||
{
|
||||
m_ostr << "null";
|
||||
}
|
||||
|
||||
TPT_NO_INLINE void Writer::Write_i(const UnknownElement& unknown)
|
||||
{
|
||||
unknown.Accept(*this);
|
||||
}
|
||||
|
||||
TPT_NO_INLINE void Writer::Visit(const Array& array) { Write_i(array); }
|
||||
TPT_NO_INLINE void Writer::Visit(const Object& object) { Write_i(object); }
|
||||
TPT_NO_INLINE void Writer::Visit(const Number& number) { Write_i(number); }
|
||||
TPT_NO_INLINE void Writer::Visit(const String& string) { Write_i(string); }
|
||||
TPT_NO_INLINE void Writer::Visit(const Boolean& boolean) { Write_i(boolean); }
|
||||
TPT_NO_INLINE void Writer::Visit(const Null& null) { Write_i(null); }
|
||||
|
||||
|
||||
|
||||
} // End namespace
|
78
src/cajun/writer.h
Normal file
78
src/cajun/writer.h
Normal file
@ -0,0 +1,78 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2009-2010, Terry Caton
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the projecct nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "elements.h"
|
||||
#include "visitor.h"
|
||||
|
||||
namespace json
|
||||
{
|
||||
|
||||
class Writer : private ConstVisitor
|
||||
{
|
||||
public:
|
||||
static void Write(const Object& object, std::ostream& ostr);
|
||||
static void Write(const Array& array, std::ostream& ostr);
|
||||
static void Write(const String& string, std::ostream& ostr);
|
||||
static void Write(const Number& number, std::ostream& ostr);
|
||||
static void Write(const Boolean& boolean, std::ostream& ostr);
|
||||
static void Write(const Null& null, std::ostream& ostr);
|
||||
static void Write(const UnknownElement& elementRoot, std::ostream& ostr);
|
||||
|
||||
private:
|
||||
Writer(std::ostream& ostr);
|
||||
|
||||
template <typename ElementTypeT>
|
||||
static void Write_i(const ElementTypeT& element, std::ostream& ostr);
|
||||
|
||||
void Write_i(const Object& object);
|
||||
void Write_i(const Array& array);
|
||||
void Write_i(const String& string);
|
||||
void Write_i(const Number& number);
|
||||
void Write_i(const Boolean& boolean);
|
||||
void Write_i(const Null& null);
|
||||
void Write_i(const UnknownElement& unknown);
|
||||
|
||||
virtual void Visit(const Array& array);
|
||||
virtual void Visit(const Object& object);
|
||||
virtual void Visit(const Number& number);
|
||||
virtual void Visit(const String& string);
|
||||
virtual void Visit(const Boolean& boolean);
|
||||
virtual void Visit(const Null& null);
|
||||
|
||||
std::ostream& m_ostr;
|
||||
int m_nTabDepth;
|
||||
};
|
||||
|
||||
|
||||
} // End namespace
|
||||
|
||||
|
||||
//#include "writer.inl"
|
118
src/cat/CommandInterface.cpp
Normal file
118
src/cat/CommandInterface.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Kitty.cpp
|
||||
*
|
||||
* Created on: Feb 2, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#if !defined(WIN) || defined(__GNUC__)
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#include "CommandInterface.h"
|
||||
#include "game/GameModel.h"
|
||||
#include "game/GameController.h"
|
||||
|
||||
CommandInterface::CommandInterface(GameController * c, GameModel * m) {
|
||||
this->m = m;
|
||||
this->c = c;
|
||||
}
|
||||
|
||||
/*void CommandInterface::AttachGameModel(GameModel * m)
|
||||
{
|
||||
this->m = m;
|
||||
}*/
|
||||
|
||||
int CommandInterface::Command(std::string command)
|
||||
{
|
||||
lastError = "No interpreter";
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string CommandInterface::FormatCommand(std::string command)
|
||||
{
|
||||
return command;
|
||||
}
|
||||
|
||||
void CommandInterface::Log(LogType type, std::string message)
|
||||
{
|
||||
m->Log(message);
|
||||
}
|
||||
|
||||
int CommandInterface::GetPropertyOffset(std::string key_, FormatType & format)
|
||||
{
|
||||
char * key = (char *)key_.c_str();
|
||||
int offset;
|
||||
if (strcmp(key, "type")==0){
|
||||
offset = offsetof(Particle, type);
|
||||
format = FormatInt;
|
||||
} else if (strcmp(key, "life")==0){
|
||||
offset = offsetof(Particle, life);
|
||||
format = FormatInt;
|
||||
} else if (strcmp(key, "ctype")==0){
|
||||
offset = offsetof(Particle, ctype);
|
||||
format = FormatInt;
|
||||
} else if (strcmp(key, "temp")==0){
|
||||
offset = offsetof(Particle, temp);
|
||||
format = FormatFloat;
|
||||
} else if (strcmp(key, "tmp2")==0){
|
||||
offset = offsetof(Particle, tmp2);
|
||||
format = FormatInt;
|
||||
} else if (strcmp(key, "tmp")==0){
|
||||
offset = offsetof(Particle, tmp);
|
||||
format = FormatInt;
|
||||
} else if (strcmp(key, "vy")==0){
|
||||
offset = offsetof(Particle, vy);
|
||||
format = FormatFloat;
|
||||
} else if (strcmp(key, "vx")==0){
|
||||
offset = offsetof(Particle, vx);
|
||||
format = FormatFloat;
|
||||
} else if (strcmp(key, "x")==0){
|
||||
offset = offsetof(Particle, x);
|
||||
format = FormatFloat;
|
||||
} else if (strcmp(key, "y")==0){
|
||||
offset = offsetof(Particle, y);
|
||||
format = FormatFloat;
|
||||
} else if (strcmp(key, "dcolour")==0){
|
||||
offset = offsetof(Particle, dcolour);
|
||||
format = FormatInt;
|
||||
} else if (strcmp(key, "dcolor")==0){
|
||||
offset = offsetof(Particle, dcolour);
|
||||
format = FormatInt;
|
||||
} else {
|
||||
offset = -1;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
int CommandInterface::GetParticleType(std::string type)
|
||||
{
|
||||
int i = -1;
|
||||
char * txt = (char*)type.c_str();
|
||||
|
||||
//Scope
|
||||
Element * elements = m->GetSimulation()->elements;
|
||||
|
||||
// alternative names for some elements
|
||||
if (strcasecmp(txt,"C4")==0) return PT_PLEX;
|
||||
else if (strcasecmp(txt,"C5")==0) return PT_C5;
|
||||
else if (strcasecmp(txt,"NONE")==0) return PT_NONE;
|
||||
for (i=1; i<PT_NUM; i++) {
|
||||
if (strcasecmp(txt, elements[i].Name)==0 && elements[i].Enabled)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string CommandInterface::GetLastError()
|
||||
{
|
||||
return lastError;
|
||||
}
|
||||
|
||||
CommandInterface::~CommandInterface() {
|
||||
}
|
||||
|
44
src/cat/CommandInterface.h
Normal file
44
src/cat/CommandInterface.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Kitty.h
|
||||
*
|
||||
* Created on: Feb 2, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#ifndef KITTY_H_
|
||||
#define KITTY_H_
|
||||
|
||||
#include <string>
|
||||
#include "interface/Engine.h"
|
||||
//#include "game/GameModel.h"
|
||||
|
||||
class GameModel;
|
||||
class GameController;
|
||||
class CommandInterface {
|
||||
protected:
|
||||
std::string lastError;
|
||||
GameModel * m;
|
||||
GameController * c;
|
||||
public:
|
||||
enum LogType { LogError, LogWarning, LogNotice };
|
||||
enum FormatType { FormatInt, FormatString, FormatChar, FormatFloat };
|
||||
CommandInterface(GameController * c, GameModel * m);
|
||||
int GetPropertyOffset(std::string key_, FormatType & format);
|
||||
int GetParticleType(std::string type);
|
||||
void Log(LogType type, std::string message);
|
||||
//void AttachGameModel(GameModel * m);
|
||||
virtual bool OnBrushChanged(int brushType, int rx, int ry) {return true;}
|
||||
virtual bool OnMouseMove(int x, int y, int dx, int dy) {return true;}
|
||||
virtual bool OnMouseDown(int x, int y, unsigned button) {return true;}
|
||||
virtual bool OnMouseUp(int x, int y, unsigned button) {return true;}
|
||||
virtual bool OnMouseWheel(int x, int y, int d) {return true;}
|
||||
virtual bool OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt) {return true;}
|
||||
virtual bool OnKeyRelease(int key, Uint16 character, bool shift, bool ctrl, bool alt) {return true;}
|
||||
virtual void OnTick() {}
|
||||
virtual int Command(std::string command);
|
||||
virtual std::string FormatCommand(std::string command);
|
||||
std::string GetLastError();
|
||||
virtual ~CommandInterface();
|
||||
};
|
||||
|
||||
#endif /* KITTY_H_ */
|
1828
src/cat/LegacyLuaAPI.cpp
Normal file
1828
src/cat/LegacyLuaAPI.cpp
Normal file
File diff suppressed because it is too large
Load Diff
192
src/cat/LuaBit.cpp
Normal file
192
src/cat/LuaBit.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
** Lua BitOp -- a bit operations library for Lua 5.1/5.2.
|
||||
** http://bitop.luajit.org/
|
||||
**
|
||||
** Copyright (C) 2008-2012 Mike Pall. All rights reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
|
||||
*/
|
||||
|
||||
#define LUA_BITOP_VERSION "1.0.2"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* MSVC is stuck in the last century and doesn't have C99's stdint.h. */
|
||||
typedef __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
typedef int32_t SBits;
|
||||
typedef uint32_t UBits;
|
||||
|
||||
typedef union {
|
||||
lua_Number n;
|
||||
#ifdef LUA_NUMBER_DOUBLE
|
||||
uint64_t b;
|
||||
#else
|
||||
UBits b;
|
||||
#endif
|
||||
} BitNum;
|
||||
|
||||
/* Convert argument to bit type. */
|
||||
static UBits barg(lua_State *L, int idx)
|
||||
{
|
||||
BitNum bn;
|
||||
UBits b;
|
||||
#if LUA_VERSION_NUM < 502
|
||||
bn.n = lua_tonumber(L, idx);
|
||||
#else
|
||||
bn.n = luaL_checknumber(L, idx);
|
||||
#endif
|
||||
#if defined(LUA_NUMBER_DOUBLE)
|
||||
bn.n += 6755399441055744.0; /* 2^52+2^51 */
|
||||
#ifdef SWAPPED_DOUBLE
|
||||
b = (UBits)(bn.b >> 32);
|
||||
#else
|
||||
b = (UBits)bn.b;
|
||||
#endif
|
||||
#elif defined(LUA_NUMBER_INT) || defined(LUA_NUMBER_LONG) || \
|
||||
defined(LUA_NUMBER_LONGLONG) || defined(LUA_NUMBER_LONG_LONG) || \
|
||||
defined(LUA_NUMBER_LLONG)
|
||||
if (sizeof(UBits) == sizeof(lua_Number))
|
||||
b = bn.b;
|
||||
else
|
||||
b = (UBits)(SBits)bn.n;
|
||||
#elif defined(LUA_NUMBER_FLOAT)
|
||||
#error "A 'float' lua_Number type is incompatible with this library"
|
||||
#else
|
||||
#error "Unknown number type, check LUA_NUMBER_* in luaconf.h"
|
||||
#endif
|
||||
#if LUA_VERSION_NUM < 502
|
||||
if (b == 0 && !lua_isnumber(L, idx)) {
|
||||
luaL_typerror(L, idx, "number");
|
||||
}
|
||||
#endif
|
||||
return b;
|
||||
}
|
||||
|
||||
/* Return bit type. */
|
||||
#define BRET(b) lua_pushnumber(L, (lua_Number)(SBits)(b)); return 1;
|
||||
|
||||
static int bit_tobit(lua_State *L) { BRET(barg(L, 1)) }
|
||||
static int bit_bnot(lua_State *L) { BRET(~barg(L, 1)) }
|
||||
|
||||
#define BIT_OP(func, opr) \
|
||||
static int func(lua_State *L) { int i; UBits b = barg(L, 1); \
|
||||
for (i = lua_gettop(L); i > 1; i--) b opr barg(L, i); BRET(b) }
|
||||
BIT_OP(bit_band, &=)
|
||||
BIT_OP(bit_bor, |=)
|
||||
BIT_OP(bit_bxor, ^=)
|
||||
|
||||
#define bshl(b, n) (b << n)
|
||||
#define bshr(b, n) (b >> n)
|
||||
#define bsar(b, n) ((SBits)b >> n)
|
||||
#define brol(b, n) ((b << n) | (b >> (32-n)))
|
||||
#define bror(b, n) ((b << (32-n)) | (b >> n))
|
||||
#define BIT_SH(func, fn) \
|
||||
static int func(lua_State *L) { \
|
||||
UBits b = barg(L, 1); UBits n = barg(L, 2) & 31; BRET(fn(b, n)) }
|
||||
BIT_SH(bit_lshift, bshl)
|
||||
BIT_SH(bit_rshift, bshr)
|
||||
BIT_SH(bit_arshift, bsar)
|
||||
BIT_SH(bit_rol, brol)
|
||||
BIT_SH(bit_ror, bror)
|
||||
|
||||
static int bit_bswap(lua_State *L)
|
||||
{
|
||||
UBits b = barg(L, 1);
|
||||
b = (b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24);
|
||||
BRET(b)
|
||||
}
|
||||
|
||||
static int bit_tohex(lua_State *L)
|
||||
{
|
||||
UBits b = barg(L, 1);
|
||||
SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2);
|
||||
const char *hexdigits = "0123456789abcdef";
|
||||
char buf[8];
|
||||
int i;
|
||||
if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
|
||||
if (n > 8) n = 8;
|
||||
for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; }
|
||||
lua_pushlstring(L, buf, (size_t)n);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg bit_funcs[] = {
|
||||
{ "tobit", bit_tobit },
|
||||
{ "bnot", bit_bnot },
|
||||
{ "band", bit_band },
|
||||
{ "bor", bit_bor },
|
||||
{ "bxor", bit_bxor },
|
||||
{ "lshift", bit_lshift },
|
||||
{ "rshift", bit_rshift },
|
||||
{ "arshift", bit_arshift },
|
||||
{ "rol", bit_rol },
|
||||
{ "ror", bit_ror },
|
||||
{ "bswap", bit_bswap },
|
||||
{ "tohex", bit_tohex },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/* Signed right-shifts are implementation-defined per C89/C99.
|
||||
** But the de facto standard are arithmetic right-shifts on two's
|
||||
** complement CPUs. This behaviour is required here, so test for it.
|
||||
*/
|
||||
#define BAD_SAR (bsar(-8, 2) != (SBits)-2)
|
||||
|
||||
int luaopen_bit(lua_State *L)
|
||||
{
|
||||
UBits b;
|
||||
lua_pushnumber(L, (lua_Number)1437217655L);
|
||||
b = barg(L, -1);
|
||||
if (b != (UBits)1437217655L || BAD_SAR) { /* Perform a simple self-test. */
|
||||
const char *msg = "compiled with incompatible luaconf.h";
|
||||
#ifdef LUA_NUMBER_DOUBLE
|
||||
#ifdef _WIN32
|
||||
if (b == (UBits)1610612736L)
|
||||
msg = "use D3DCREATE_FPU_PRESERVE with DirectX";
|
||||
#endif
|
||||
if (b == (UBits)1127743488L)
|
||||
msg = "not compiled with SWAPPED_DOUBLE";
|
||||
#endif
|
||||
if (BAD_SAR)
|
||||
msg = "arithmetic right-shift broken";
|
||||
luaL_error(L, "bit library self-test failed (%s)", msg);
|
||||
}
|
||||
#if LUA_VERSION_NUM < 502
|
||||
luaL_register(L, "bit", bit_funcs);
|
||||
#else
|
||||
luaL_newlib(L, bit_funcs);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
32
src/cat/LuaBit.h
Normal file
32
src/cat/LuaBit.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
** Lua BitOp -- a bit operations library for Lua 5.1/5.2.
|
||||
** http://bitop.luajit.org/
|
||||
**
|
||||
** Copyright (C) 2008-2012 Mike Pall. All rights reserved.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
|
||||
*/
|
||||
|
||||
#define LUA_BITOP_VERSION "1.0.2"
|
||||
|
||||
int luaopen_bit(lua_State *L);
|
||||
|
114
src/cat/LuaButton.cpp
Normal file
114
src/cat/LuaButton.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
extern "C"
|
||||
{
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
#include "LuaButton.h"
|
||||
#include "LuaScriptInterface.h"
|
||||
#include "interface/Button.h"
|
||||
|
||||
const char LuaButton::className[] = "Button";
|
||||
|
||||
#define method(class, name) {#name, &class::name}
|
||||
Luna<LuaButton>::RegType LuaButton::methods[] = {
|
||||
method(LuaButton, action),
|
||||
method(LuaButton, text),
|
||||
method(LuaButton, position),
|
||||
method(LuaButton, size),
|
||||
method(LuaButton, visible),
|
||||
method(LuaButton, enabled),
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
LuaButton::LuaButton(lua_State * l) :
|
||||
LuaComponent(l),
|
||||
actionFunction(0)
|
||||
{
|
||||
int posX = luaL_optinteger(l, 1, 0);
|
||||
int posY = luaL_optinteger(l, 2, 0);
|
||||
int sizeX = luaL_optinteger(l, 3, 10);
|
||||
int sizeY = luaL_optinteger(l, 4, 10);
|
||||
std::string text = luaL_optstring(l, 5, "");
|
||||
std::string toolTip = luaL_optstring(l, 6, "");
|
||||
|
||||
button = new ui::Button(ui::Point(posX, posY), ui::Point(sizeX, sizeY), text, toolTip);
|
||||
component = button;
|
||||
class ClickAction : public ui::ButtonAction
|
||||
{
|
||||
LuaButton * luaButton;
|
||||
public:
|
||||
ClickAction(LuaButton * luaButton) : luaButton(luaButton) {}
|
||||
void ActionCallback(ui::Button * sender)
|
||||
{
|
||||
luaButton->triggerAction();
|
||||
}
|
||||
};
|
||||
button->SetActionCallback(new ClickAction(this));
|
||||
}
|
||||
|
||||
int LuaButton::enabled(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TBOOLEAN);
|
||||
button->Enabled = lua_toboolean(l, 1);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushboolean(l, button->Enabled);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int LuaButton::action(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
actionFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
actionFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaButton::text(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TSTRING);
|
||||
button->SetText(lua_tostring(l, 1));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(l, button->GetText().c_str());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void LuaButton::triggerAction()
|
||||
{
|
||||
if(actionFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, actionFunction);
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, UserData);
|
||||
if (lua_pcall(l, 1, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LuaButton::~LuaButton()
|
||||
{
|
||||
}
|
33
src/cat/LuaButton.h
Normal file
33
src/cat/LuaButton.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include "LuaLuna.h"
|
||||
#include "LuaComponent.h"
|
||||
|
||||
namespace ui
|
||||
{
|
||||
class Button;
|
||||
}
|
||||
|
||||
class LuaScriptInterface;
|
||||
|
||||
class LuaButton: public LuaComponent
|
||||
{
|
||||
ui::Button * button;
|
||||
int actionFunction;
|
||||
void triggerAction();
|
||||
int action(lua_State * l);
|
||||
int text(lua_State * l);
|
||||
int enabled(lua_State * l);
|
||||
public:
|
||||
static const char className[];
|
||||
static Luna<LuaButton>::RegType methods[];
|
||||
|
||||
LuaButton(lua_State * l);
|
||||
~LuaButton();
|
||||
};
|
114
src/cat/LuaCheckbox.cpp
Normal file
114
src/cat/LuaCheckbox.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
extern "C"
|
||||
{
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
#include "LuaCheckbox.h"
|
||||
#include "LuaScriptInterface.h"
|
||||
#include "interface/Checkbox.h"
|
||||
|
||||
const char LuaCheckbox::className[] = "Checkbox";
|
||||
|
||||
#define method(class, name) {#name, &class::name}
|
||||
Luna<LuaCheckbox>::RegType LuaCheckbox::methods[] = {
|
||||
method(LuaCheckbox, action),
|
||||
method(LuaCheckbox, text),
|
||||
method(LuaCheckbox, position),
|
||||
method(LuaCheckbox, size),
|
||||
method(LuaCheckbox, visible),
|
||||
method(LuaCheckbox, checked),
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
LuaCheckbox::LuaCheckbox(lua_State * l) :
|
||||
LuaComponent(l),
|
||||
actionFunction(0)
|
||||
{
|
||||
int posX = luaL_optinteger(l, 1, 0);
|
||||
int posY = luaL_optinteger(l, 2, 0);
|
||||
int sizeX = luaL_optinteger(l, 3, 10);
|
||||
int sizeY = luaL_optinteger(l, 4, 10);
|
||||
std::string text = luaL_optstring(l, 5, "");
|
||||
|
||||
checkbox = new ui::Checkbox(ui::Point(posX, posY), ui::Point(sizeX, sizeY), text, "");
|
||||
component = checkbox;
|
||||
class ClickAction : public ui::CheckboxAction
|
||||
{
|
||||
LuaCheckbox * luaCheckbox;
|
||||
public:
|
||||
ClickAction(LuaCheckbox * luaCheckbox) : luaCheckbox(luaCheckbox) {}
|
||||
void ActionCallback(ui::Checkbox * sender)
|
||||
{
|
||||
luaCheckbox->triggerAction();
|
||||
}
|
||||
};
|
||||
checkbox->SetActionCallback(new ClickAction(this));
|
||||
}
|
||||
|
||||
int LuaCheckbox::checked(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TBOOLEAN);
|
||||
checkbox->SetChecked(lua_toboolean(l, 1));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushboolean(l, checkbox->GetChecked());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int LuaCheckbox::action(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
actionFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
actionFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaCheckbox::text(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TSTRING);
|
||||
checkbox->SetText(lua_tostring(l, 1));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(l, checkbox->GetText().c_str());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void LuaCheckbox::triggerAction()
|
||||
{
|
||||
if(actionFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, actionFunction);
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, UserData);
|
||||
lua_pushboolean(l, checkbox->GetChecked());
|
||||
if (lua_pcall(l, 2, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LuaCheckbox::~LuaCheckbox()
|
||||
{
|
||||
}
|
33
src/cat/LuaCheckbox.h
Normal file
33
src/cat/LuaCheckbox.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include "LuaLuna.h"
|
||||
#include "LuaComponent.h"
|
||||
|
||||
namespace ui
|
||||
{
|
||||
class Checkbox;
|
||||
}
|
||||
|
||||
class LuaScriptInterface;
|
||||
|
||||
class LuaCheckbox: public LuaComponent
|
||||
{
|
||||
ui::Checkbox * checkbox;
|
||||
int actionFunction;
|
||||
void triggerAction();
|
||||
int action(lua_State * l);
|
||||
int checked(lua_State * l);
|
||||
int text(lua_State * l);
|
||||
public:
|
||||
static const char className[];
|
||||
static Luna<LuaCheckbox>::RegType methods[];
|
||||
|
||||
LuaCheckbox(lua_State * l);
|
||||
~LuaCheckbox();
|
||||
};
|
82
src/cat/LuaComponent.cpp
Normal file
82
src/cat/LuaComponent.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
extern "C"
|
||||
{
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
#include "LuaComponent.h"
|
||||
#include "LuaScriptInterface.h"
|
||||
#include "interface/Component.h"
|
||||
|
||||
|
||||
LuaComponent::LuaComponent(lua_State * l)
|
||||
{
|
||||
this->l = l;
|
||||
|
||||
lua_pushstring(l, "Luacon_ci");
|
||||
lua_gettable(l, LUA_REGISTRYINDEX);
|
||||
ci = (LuaScriptInterface*)lua_touserdata(l, -1);
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
|
||||
int LuaComponent::position(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TNUMBER);
|
||||
luaL_checktype(l, 2, LUA_TNUMBER);
|
||||
component->Position = ui::Point(lua_tointeger(l, 1), lua_tointeger(l, 2));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushinteger(l, component->Position.X);
|
||||
lua_pushinteger(l, component->Position.Y);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
int LuaComponent::size(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TNUMBER);
|
||||
luaL_checktype(l, 2, LUA_TNUMBER);
|
||||
component->Size = ui::Point(lua_tointeger(l, 1), lua_tointeger(l, 2));
|
||||
component->Invalidate();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushinteger(l, component->Size.X);
|
||||
lua_pushinteger(l, component->Size.Y);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
int LuaComponent::visible(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TBOOLEAN);
|
||||
component->Visible = lua_toboolean(l, 1);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushboolean(l, component->Visible);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
LuaComponent::~LuaComponent()
|
||||
{
|
||||
if(component->GetParentWindow())
|
||||
component->GetParentWindow()->RemoveComponent(component);
|
||||
delete component;
|
||||
}
|
33
src/cat/LuaComponent.h
Normal file
33
src/cat/LuaComponent.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include "LuaLuna.h"
|
||||
|
||||
namespace ui
|
||||
{
|
||||
class Component;
|
||||
}
|
||||
|
||||
class LuaScriptInterface;
|
||||
|
||||
class LuaComponent
|
||||
{
|
||||
protected:
|
||||
ui::Component * component;
|
||||
lua_State * l;
|
||||
int position(lua_State * l);
|
||||
int size(lua_State * l);
|
||||
int visible(lua_State * l);
|
||||
public:
|
||||
LuaScriptInterface * ci;
|
||||
int UserData;
|
||||
|
||||
ui::Component * GetComponent() { return component; }
|
||||
LuaComponent(lua_State * l);
|
||||
~LuaComponent();
|
||||
};
|
56
src/cat/LuaLabel.cpp
Normal file
56
src/cat/LuaLabel.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
extern "C"
|
||||
{
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
#include "LuaScriptInterface.h"
|
||||
#include "LuaLabel.h"
|
||||
#include "interface/Label.h"
|
||||
|
||||
const char LuaLabel::className[] = "Label";
|
||||
|
||||
#define method(class, name) {#name, &class::name}
|
||||
Luna<LuaLabel>::RegType LuaLabel::methods[] = {
|
||||
method(LuaLabel, text),
|
||||
method(LuaLabel, position),
|
||||
method(LuaLabel, size),
|
||||
method(LuaLabel, visible),
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
LuaLabel::LuaLabel(lua_State * l) :
|
||||
LuaComponent(l)
|
||||
{
|
||||
this->l = l;
|
||||
int posX = luaL_optinteger(l, 1, 0);
|
||||
int posY = luaL_optinteger(l, 2, 0);
|
||||
int sizeX = luaL_optinteger(l, 3, 10);
|
||||
int sizeY = luaL_optinteger(l, 4, 10);
|
||||
std::string text = luaL_optstring(l, 5, "");
|
||||
|
||||
label = new ui::Label(ui::Point(posX, posY), ui::Point(sizeX, sizeY), text);
|
||||
component = label;
|
||||
}
|
||||
|
||||
int LuaLabel::text(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TSTRING);
|
||||
label->SetText(lua_tostring(l, 1));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(l, label->GetText().c_str());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
LuaLabel::~LuaLabel()
|
||||
{
|
||||
}
|
29
src/cat/LuaLabel.h
Normal file
29
src/cat/LuaLabel.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include "LuaLuna.h"
|
||||
#include "LuaComponent.h"
|
||||
|
||||
namespace ui
|
||||
{
|
||||
class Label;
|
||||
}
|
||||
|
||||
class LuaScriptInterface;
|
||||
|
||||
class LuaLabel: public LuaComponent
|
||||
{
|
||||
ui::Label * label;
|
||||
int text(lua_State * l);
|
||||
public:
|
||||
static const char className[];
|
||||
static Luna<LuaLabel>::RegType methods[];
|
||||
|
||||
LuaLabel(lua_State * l);
|
||||
~LuaLabel();
|
||||
};
|
160
src/cat/LuaLuna.h
Normal file
160
src/cat/LuaLuna.h
Normal file
@ -0,0 +1,160 @@
|
||||
#pragma once
|
||||
//http://lua-users.org/wiki/SimplerCppBinding
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
template <typename T> class Luna
|
||||
{
|
||||
typedef struct { T *pT; } userdataType;
|
||||
public:
|
||||
typedef int (T::*mfp)(lua_State *L);
|
||||
typedef struct { const char *name; mfp mfunc; } RegType;
|
||||
|
||||
static void Register(lua_State *L)
|
||||
{
|
||||
lua_newtable(L);
|
||||
int methods = lua_gettop(L);
|
||||
|
||||
luaL_newmetatable(L, T::className);
|
||||
int metatable = lua_gettop(L);
|
||||
|
||||
// store method table in globals so that
|
||||
// scripts can add functions written in Lua.
|
||||
lua_pushstring(L, T::className);
|
||||
lua_pushvalue(L, methods);
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
|
||||
lua_pushliteral(L, "__metatable");
|
||||
lua_pushvalue(L, methods);
|
||||
lua_settable(L, metatable); // hide metatable from Lua getmetatable()
|
||||
|
||||
lua_pushliteral(L, "__index");
|
||||
lua_pushvalue(L, methods);
|
||||
lua_settable(L, metatable);
|
||||
|
||||
lua_pushliteral(L, "__tostring");
|
||||
lua_pushcfunction(L, tostring_T);
|
||||
lua_settable(L, metatable);
|
||||
|
||||
lua_pushliteral(L, "__gc");
|
||||
lua_pushcfunction(L, gc_T);
|
||||
lua_settable(L, metatable);
|
||||
|
||||
lua_newtable(L); // mt for method table
|
||||
int mt = lua_gettop(L);
|
||||
lua_pushliteral(L, "__call");
|
||||
lua_pushcfunction(L, new_T);
|
||||
lua_pushliteral(L, "new");
|
||||
lua_pushvalue(L, -2); // dup new_T function
|
||||
lua_settable(L, methods); // add new_T to method table
|
||||
lua_settable(L, mt); // mt.__call = new_T
|
||||
lua_setmetatable(L, methods);
|
||||
|
||||
// fill method table with methods from class T
|
||||
for (RegType *l = T::methods; l->name; l++)
|
||||
{
|
||||
/* edited by Snaily: shouldn't it be const RegType *l ... ? */
|
||||
lua_pushstring(L, l->name);
|
||||
lua_pushlightuserdata(L, (void*)l);
|
||||
lua_pushcclosure(L, thunk, 1);
|
||||
lua_settable(L, methods);
|
||||
}
|
||||
|
||||
lua_pop(L, 2); // drop metatable and method table
|
||||
}
|
||||
|
||||
// get userdata from Lua stack and return pointer to T object
|
||||
static T * check(lua_State * L, int narg)
|
||||
{
|
||||
userdataType *ud = static_cast<userdataType*>(luaL_checkudata(L, narg, T::className));
|
||||
if(!ud)
|
||||
luaL_typerror(L, narg, T::className);
|
||||
return ud->pT; // pointer to T object
|
||||
}
|
||||
|
||||
static void * tryGet(lua_State * L, int narg)
|
||||
{
|
||||
if(checkType(L, narg, T::className))
|
||||
{
|
||||
userdataType *ud = static_cast<userdataType*>(luaL_checkudata(L, narg, T::className));
|
||||
if(!ud)
|
||||
luaL_typerror(L, narg, T::className);
|
||||
return ud; // pointer to T object
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static bool checkType (lua_State * L, int idx, const char *name)
|
||||
{
|
||||
// returns true if a userdata is of a certain type
|
||||
int res;
|
||||
if (lua_type(L, idx) != LUA_TUSERDATA) return false;
|
||||
lua_getmetatable(L, idx);
|
||||
luaL_newmetatable (L, name);
|
||||
res = lua_equal(L, -2, -1);
|
||||
lua_pop(L, 2); // pop both tables (metatables) off
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline T * get(void * userData)
|
||||
{
|
||||
return ((userdataType*)userData)->pT;
|
||||
}
|
||||
|
||||
private:
|
||||
Luna(); // hide default constructor
|
||||
|
||||
// member function dispatcher
|
||||
static int thunk(lua_State * L)
|
||||
{
|
||||
// stack has userdata, followed by method args
|
||||
T *obj = check(L, 1); // get 'self', or if you prefer, 'this'
|
||||
lua_remove(L, 1); // remove self so member function args start at index 1
|
||||
// get member function from upvalue
|
||||
RegType *l = static_cast<RegType*>(lua_touserdata(L, lua_upvalueindex(1)));
|
||||
return (obj->*(l->mfunc))(L); // call member function
|
||||
}
|
||||
|
||||
// create a new T object and
|
||||
// push onto the Lua stack a userdata containing a pointer to T object
|
||||
static int new_T(lua_State * L)
|
||||
{
|
||||
lua_remove(L, 1); // use classname:new(), instead of classname.new()
|
||||
|
||||
T *obj = new T(L); // call constructor for T objects
|
||||
userdataType *ud = static_cast<userdataType*>(lua_newuserdata(L, sizeof(userdataType)));
|
||||
ud->pT = obj; // store pointer to object in userdata
|
||||
|
||||
obj->UserData = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, obj->UserData);
|
||||
|
||||
luaL_getmetatable(L, T::className); // lookup metatable in Lua registry
|
||||
lua_setmetatable(L, -2);
|
||||
return 1; // userdata containing pointer to T object
|
||||
}
|
||||
|
||||
// garbage collection metamethod
|
||||
static int gc_T(lua_State *L)
|
||||
{
|
||||
userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, 1));
|
||||
T *obj = ud->pT;
|
||||
delete obj; // call destructor for T objects
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tostring_T (lua_State * L)
|
||||
{
|
||||
char buff[32];
|
||||
userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, 1));
|
||||
T *obj = ud->pT;
|
||||
sprintf(buff, "%p", obj);
|
||||
lua_pushfstring(L, "%s (%s)", T::className, buff);
|
||||
return 1;
|
||||
}
|
||||
};
|
71
src/cat/LuaProgressBar.cpp
Normal file
71
src/cat/LuaProgressBar.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
extern "C"
|
||||
{
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
#include "LuaProgressBar.h"
|
||||
#include "LuaScriptInterface.h"
|
||||
#include "interface/ProgressBar.h"
|
||||
|
||||
const char LuaProgressBar::className[] = "ProgressBar";
|
||||
|
||||
#define method(class, name) {#name, &class::name}
|
||||
Luna<LuaProgressBar>::RegType LuaProgressBar::methods[] = {
|
||||
method(LuaProgressBar, position),
|
||||
method(LuaProgressBar, size),
|
||||
method(LuaProgressBar, visible),
|
||||
method(LuaProgressBar, progress),
|
||||
method(LuaProgressBar, status),
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
LuaProgressBar::LuaProgressBar(lua_State * l) :
|
||||
LuaComponent(l)
|
||||
{
|
||||
int posX = luaL_optinteger(l, 1, 0);
|
||||
int posY = luaL_optinteger(l, 2, 0);
|
||||
int sizeX = luaL_optinteger(l, 3, 10);
|
||||
int sizeY = luaL_optinteger(l, 4, 10);
|
||||
int value = luaL_optinteger(l, 5, 0);
|
||||
std::string status = luaL_optstring(l, 6, "");
|
||||
|
||||
progressBar = new ui::ProgressBar(ui::Point(posX, posY), ui::Point(sizeX, sizeY), value, status);
|
||||
component = progressBar;
|
||||
}
|
||||
|
||||
int LuaProgressBar::progress(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
progressBar->SetProgress(lua_tointeger(l, 1));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushinteger(l, progressBar->GetProgress());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int LuaProgressBar::status(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
progressBar->SetStatus(std::string(lua_tostring(l, 1)));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(l, progressBar->GetStatus().c_str());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
LuaProgressBar::~LuaProgressBar()
|
||||
{
|
||||
}
|
30
src/cat/LuaProgressBar.h
Normal file
30
src/cat/LuaProgressBar.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include "LuaLuna.h"
|
||||
#include "LuaComponent.h"
|
||||
|
||||
namespace ui
|
||||
{
|
||||
class ProgressBar;
|
||||
}
|
||||
|
||||
class LuaScriptInterface;
|
||||
|
||||
class LuaProgressBar: public LuaComponent
|
||||
{
|
||||
ui::ProgressBar * progressBar;
|
||||
int progress(lua_State * l);
|
||||
int status(lua_State * l);
|
||||
public:
|
||||
static const char className[];
|
||||
static Luna<LuaProgressBar>::RegType methods[];
|
||||
|
||||
LuaProgressBar(lua_State * l);
|
||||
~LuaProgressBar();
|
||||
};
|
144
src/cat/LuaScriptHelper.h
Normal file
144
src/cat/LuaScriptHelper.h
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* LuaScriptHelper.h
|
||||
*
|
||||
* Created on: Feb 12, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#ifndef LUASCRIPTHELPER_H_
|
||||
#define LUASCRIPTHELPER_H_
|
||||
|
||||
extern GameModel * luacon_model;
|
||||
extern Simulation * luacon_sim;
|
||||
extern LuaScriptInterface * luacon_ci;
|
||||
extern Graphics * luacon_g;
|
||||
extern Renderer * luacon_ren;
|
||||
|
||||
extern bool *luacon_currentCommand;
|
||||
extern std::string *luacon_lastError;
|
||||
|
||||
extern int *lua_el_func, *lua_el_mode, *lua_gr_func;
|
||||
|
||||
extern int getPartIndex_curIdx;
|
||||
extern int step_functions[6];//[6] = {0, 0, 0, 0, 0, 0};
|
||||
extern int keypress_function_count;// = 0;
|
||||
extern int *keypress_functions;// = NULL;
|
||||
extern int mouseclick_function_count;// = 0;
|
||||
extern int *mouseclick_functions;// = NULL;
|
||||
extern int tptProperties; //Table for some TPT properties
|
||||
extern int tptPropertiesVersion;
|
||||
extern int tptElements; //Table for TPT element names
|
||||
extern int tptParts, tptPartsMeta, tptElementTransitions, tptPartsCData, tptPartMeta, tptPart, cIndex;
|
||||
|
||||
void luacon_hook(lua_State *L, lua_Debug *ar);
|
||||
int luacon_step(int mx, int my, int selectl, int selectr, int bsx, int bsy);
|
||||
int luacon_mouseevent(int mx, int my, int mb, int event, int mouse_wheel);
|
||||
int luacon_keyevent(int key, int modifier, int event);
|
||||
int luacon_eval(char *command);
|
||||
int luacon_part_update(int t, int i, int x, int y, int surround_space, int nt);
|
||||
char *luacon_geterror();
|
||||
void luacon_close();
|
||||
int luacon_partsread(lua_State* l);
|
||||
int luacon_partswrite(lua_State* l);
|
||||
int luacon_partread(lua_State* l);
|
||||
int luacon_partwrite(lua_State* l);
|
||||
int luacon_elementread(lua_State* l);
|
||||
int luacon_elementwrite(lua_State* l);
|
||||
int luacon_transitionread(lua_State* l);
|
||||
int luacon_transitionwrite(lua_State* l);
|
||||
int luacon_particle_getproperty(char * key, int * format);
|
||||
int luacon_transition_getproperty(char * key, int * format);
|
||||
int luacon_element_getproperty(char * key, int * format, unsigned int * modified_stuff);
|
||||
//int process_command_lua(pixel *vid_buf, char *console, char *console_error);
|
||||
|
||||
//Interface
|
||||
int luatpt_test(lua_State* l);
|
||||
int luatpt_getelement(lua_State *l);
|
||||
|
||||
int luacon_graphicsReplacement(GRAPHICS_FUNC_ARGS);
|
||||
int luatpt_graphics_func(lua_State *l);
|
||||
|
||||
int luacon_elementReplacement(UPDATE_FUNC_ARGS);
|
||||
int luatpt_element_func(lua_State *l);
|
||||
|
||||
int luatpt_error(lua_State* l);
|
||||
int luatpt_drawtext(lua_State* l);
|
||||
|
||||
int luatpt_create(lua_State* l);
|
||||
|
||||
int luatpt_setpause(lua_State* l);
|
||||
|
||||
int luatpt_togglepause(lua_State* l);
|
||||
|
||||
int luatpt_togglewater(lua_State* l);
|
||||
|
||||
int luatpt_setconsole(lua_State* l);
|
||||
int luatpt_log(lua_State* l);
|
||||
|
||||
int luatpt_set_pressure(lua_State* l);
|
||||
|
||||
int luatpt_set_gravity(lua_State* l);
|
||||
int luatpt_reset_gravity_field(lua_State* l);
|
||||
|
||||
int luatpt_reset_velocity(lua_State* l);
|
||||
|
||||
int luatpt_reset_spark(lua_State* l);
|
||||
|
||||
int luatpt_set_property(lua_State* l);
|
||||
|
||||
int luatpt_get_property(lua_State* l);
|
||||
|
||||
int luatpt_set_wallmap(lua_State* l);
|
||||
|
||||
int luatpt_get_wallmap(lua_State* l);
|
||||
|
||||
int luatpt_set_elecmap(lua_State* l);
|
||||
|
||||
int luatpt_get_elecmap(lua_State* l);
|
||||
|
||||
int luatpt_drawpixel(lua_State* l);
|
||||
|
||||
int luatpt_drawrect(lua_State* l);
|
||||
|
||||
int luatpt_fillrect(lua_State* l);
|
||||
|
||||
int luatpt_drawline(lua_State* l);
|
||||
|
||||
int luatpt_textwidth(lua_State* l);
|
||||
int luatpt_get_name(lua_State* l);
|
||||
|
||||
int luatpt_set_shortcuts(lua_State* l);
|
||||
|
||||
int luatpt_delete(lua_State* l);
|
||||
int luatpt_register_step(lua_State* l);
|
||||
int luatpt_unregister_step(lua_State* l);
|
||||
int luatpt_register_keypress(lua_State* l);
|
||||
int luatpt_unregister_keypress(lua_State* l);
|
||||
int luatpt_register_mouseclick(lua_State* l);
|
||||
int luatpt_unregister_mouseclick(lua_State* l);
|
||||
int luatpt_input(lua_State* l);
|
||||
int luatpt_message_box(lua_State* l);
|
||||
int luatpt_get_numOfParts(lua_State* l);
|
||||
int luatpt_start_getPartIndex(lua_State* l);
|
||||
int luatpt_next_getPartIndex(lua_State* l);
|
||||
int luatpt_getPartIndex(lua_State* l);
|
||||
int luatpt_hud(lua_State* l);
|
||||
int luatpt_gravity(lua_State* l);
|
||||
int luatpt_airheat(lua_State* l);
|
||||
int luatpt_active_menu(lua_State* l);
|
||||
int luatpt_decorations_enable(lua_State* l);
|
||||
|
||||
int luatpt_heat(lua_State* l);
|
||||
int luatpt_cmode_set(lua_State* l);
|
||||
int luatpt_setfire(lua_State* l);
|
||||
int luatpt_setdebug(lua_State* l);
|
||||
|
||||
int luatpt_setfpscap(lua_State* l);
|
||||
|
||||
int luatpt_getscript(lua_State* l);
|
||||
|
||||
int luatpt_setwindowsize(lua_State* l);
|
||||
|
||||
int luatpt_screenshot(lua_State* l);
|
||||
|
||||
#endif /* LUASCRIPTHELPER_H_ */
|
1706
src/cat/LuaScriptInterface.cpp
Normal file
1706
src/cat/LuaScriptInterface.cpp
Normal file
File diff suppressed because it is too large
Load Diff
128
src/cat/LuaScriptInterface.h
Normal file
128
src/cat/LuaScriptInterface.h
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* LuaScriptInterface.h
|
||||
*
|
||||
* Created on: Feb 11, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#ifndef LUASCRIPTINTERFACE_H_
|
||||
#define LUASCRIPTINTERFACE_H_
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include "CommandInterface.h"
|
||||
#include "simulation/Simulation.h"
|
||||
|
||||
namespace ui
|
||||
{
|
||||
class Window;
|
||||
}
|
||||
|
||||
namespace pim
|
||||
{
|
||||
class VirtualMachine;
|
||||
}
|
||||
|
||||
|
||||
//Because lua only has bindings for C, we're going to have to go outside "outside" the LuaScriptInterface, this means we can only have one instance :(
|
||||
|
||||
#define LOCAL_LUA_DIR "Lua"
|
||||
|
||||
#define LUACON_MDOWN 1
|
||||
#define LUACON_MUP 2
|
||||
#define LUACON_MPRESS 3
|
||||
#define LUACON_KDOWN 1
|
||||
#define LUACON_KUP 2
|
||||
|
||||
//Bitmasks for things that might need recalculating after changes to tpt.el
|
||||
#define LUACON_EL_MODIFIED_CANMOVE 0x1
|
||||
#define LUACON_EL_MODIFIED_GRAPHICS 0x2
|
||||
#define LUACON_EL_MODIFIED_MENUS 0x4
|
||||
|
||||
class TPTScriptInterface;
|
||||
class LuaScriptInterface: public CommandInterface
|
||||
{
|
||||
int luacon_mousex, luacon_mousey, luacon_selectedl, luacon_selectedr, luacon_mousebutton, luacon_brushx, luacon_brushy;
|
||||
bool luacon_mousedown;
|
||||
bool currentCommand;
|
||||
TPTScriptInterface * legacy;
|
||||
|
||||
//Simulation
|
||||
void initSimulationAPI();
|
||||
static int simulation_partNeighbours(lua_State * l);
|
||||
static int simulation_partChangeType(lua_State * l);
|
||||
static int simulation_partCreate(lua_State * l);
|
||||
static int simulation_partKill(lua_State * l);
|
||||
|
||||
//Renderer
|
||||
void initRendererAPI();
|
||||
static int renderer_renderModes(lua_State * l);
|
||||
static int renderer_displayModes(lua_State * l);
|
||||
static int renderer_colourMode(lua_State * l);
|
||||
static int renderer_decorations(lua_State * l);
|
||||
|
||||
//Elements
|
||||
static pim::VirtualMachine * updateVirtualMachines[PT_NUM];
|
||||
static int updateVM(UPDATE_FUNC_ARGS);
|
||||
//
|
||||
void initElementsAPI();
|
||||
static int elements_allocate(lua_State * l);
|
||||
static int elements_element(lua_State * l);
|
||||
static int elements_property(lua_State * l);
|
||||
static int elements_loadDefault(lua_State * l);
|
||||
static int elements_free(lua_State * l);
|
||||
|
||||
//Interface
|
||||
void initInterfaceAPI();
|
||||
static int interface_showWindow(lua_State * l);
|
||||
static int interface_closeWindow(lua_State * l);
|
||||
static int interface_addComponent(lua_State * l);
|
||||
|
||||
//VM
|
||||
void initVirtualMachineAPI();
|
||||
static int virtualMachine_loadProgram(lua_State * l);
|
||||
|
||||
void initGraphicsAPI();
|
||||
static int graphics_textSize(lua_State * l);
|
||||
static int graphics_drawText(lua_State * l);
|
||||
static int graphics_drawLine(lua_State * l);
|
||||
static int graphics_drawRect(lua_State * l);
|
||||
static int graphics_fillRect(lua_State * l);
|
||||
|
||||
void initFileSystemAPI();
|
||||
static int fileSystem_list(lua_State * l);
|
||||
static int fileSystem_exists(lua_State * l);
|
||||
static int fileSystem_isFile(lua_State * l);
|
||||
static int fileSystem_isDirectory(lua_State * l);
|
||||
static int fileSystem_makeDirectory(lua_State * l);
|
||||
static int fileSystem_removeDirectory(lua_State * l);
|
||||
static int fileSystem_removeFile(lua_State * l);
|
||||
static int fileSystem_move(lua_State * l);
|
||||
static int fileSystem_copy(lua_State * l);
|
||||
|
||||
public:
|
||||
ui::Window * Window;
|
||||
lua_State *l;
|
||||
LuaScriptInterface(GameController * c, GameModel * m);
|
||||
virtual bool OnBrushChanged(int brushType, int rx, int ry);
|
||||
virtual bool OnMouseMove(int x, int y, int dx, int dy);
|
||||
virtual bool OnMouseDown(int x, int y, unsigned button);
|
||||
virtual bool OnMouseUp(int x, int y, unsigned button);
|
||||
virtual bool OnMouseWheel(int x, int y, int d);
|
||||
virtual bool OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt);
|
||||
virtual bool OnKeyRelease(int key, Uint16 character, bool shift, bool ctrl, bool alt);
|
||||
virtual void OnTick();
|
||||
virtual void Init();
|
||||
virtual void SetWindow(ui::Window * window);
|
||||
virtual int Command(std::string command);
|
||||
virtual std::string FormatCommand(std::string command);
|
||||
virtual ~LuaScriptInterface();
|
||||
};
|
||||
|
||||
|
||||
#endif /* LUASCRIPTINTERFACE_H_ */
|
112
src/cat/LuaSlider.cpp
Normal file
112
src/cat/LuaSlider.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
extern "C"
|
||||
{
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
#include "LuaSlider.h"
|
||||
#include "LuaScriptInterface.h"
|
||||
#include "interface/Slider.h"
|
||||
|
||||
const char LuaSlider::className[] = "Slider";
|
||||
|
||||
#define method(class, name) {#name, &class::name}
|
||||
Luna<LuaSlider>::RegType LuaSlider::methods[] = {
|
||||
method(LuaSlider, onValueChanged),
|
||||
method(LuaSlider, position),
|
||||
method(LuaSlider, size),
|
||||
method(LuaSlider, visible),
|
||||
method(LuaSlider, value),
|
||||
method(LuaSlider, steps),
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
LuaSlider::LuaSlider(lua_State * l) :
|
||||
LuaComponent(l),
|
||||
onValueChangedFunction(0)
|
||||
{
|
||||
int posX = luaL_optinteger(l, 1, 0);
|
||||
int posY = luaL_optinteger(l, 2, 0);
|
||||
int sizeX = luaL_optinteger(l, 3, 10);
|
||||
int sizeY = luaL_optinteger(l, 4, 10);
|
||||
int steps = luaL_optinteger(l, 5, 10);
|
||||
|
||||
slider = new ui::Slider(ui::Point(posX, posY), ui::Point(sizeX, sizeY), steps);
|
||||
component = slider;
|
||||
class ValueAction : public ui::SliderAction
|
||||
{
|
||||
LuaSlider * luaSlider;
|
||||
public:
|
||||
ValueAction(LuaSlider * luaSlider) : luaSlider(luaSlider) {}
|
||||
void ValueChangedCallback(ui::Slider * sender)
|
||||
{
|
||||
luaSlider->triggerOnValueChanged();
|
||||
}
|
||||
};
|
||||
slider->SetActionCallback(new ValueAction(this));
|
||||
}
|
||||
|
||||
int LuaSlider::steps(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
slider->SetSteps(lua_tointeger(l, 1));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushinteger(l, slider->GetSteps());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int LuaSlider::onValueChanged(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onValueChangedFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onValueChangedFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaSlider::value(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
slider->SetValue(lua_tointeger(l, 1));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushinteger(l, slider->GetValue());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void LuaSlider::triggerOnValueChanged()
|
||||
{
|
||||
if(onValueChangedFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onValueChangedFunction);
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, UserData);
|
||||
lua_pushinteger(l, slider->GetValue());
|
||||
if (lua_pcall(l, 2, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LuaSlider::~LuaSlider()
|
||||
{
|
||||
}
|
33
src/cat/LuaSlider.h
Normal file
33
src/cat/LuaSlider.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include "LuaLuna.h"
|
||||
#include "LuaComponent.h"
|
||||
|
||||
namespace ui
|
||||
{
|
||||
class Slider;
|
||||
}
|
||||
|
||||
class LuaScriptInterface;
|
||||
|
||||
class LuaSlider: public LuaComponent
|
||||
{
|
||||
ui::Slider * slider;
|
||||
int onValueChangedFunction;
|
||||
void triggerOnValueChanged();
|
||||
int onValueChanged(lua_State * l);
|
||||
int steps(lua_State * l);
|
||||
int value(lua_State * l);
|
||||
public:
|
||||
static const char className[];
|
||||
static Luna<LuaSlider>::RegType methods[];
|
||||
|
||||
LuaSlider(lua_State * l);
|
||||
~LuaSlider();
|
||||
};
|
116
src/cat/LuaTextbox.cpp
Normal file
116
src/cat/LuaTextbox.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
extern "C"
|
||||
{
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
#include "LuaScriptInterface.h"
|
||||
#include "LuaTextbox.h"
|
||||
#include "interface/Textbox.h"
|
||||
|
||||
const char LuaTextbox::className[] = "Textbox";
|
||||
|
||||
#define method(class, name) {#name, &class::name}
|
||||
Luna<LuaTextbox>::RegType LuaTextbox::methods[] = {
|
||||
method(LuaTextbox, text),
|
||||
method(LuaTextbox, readonly),
|
||||
method(LuaTextbox, onTextChanged),
|
||||
method(LuaTextbox, position),
|
||||
method(LuaTextbox, size),
|
||||
method(LuaTextbox, visible),
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
LuaTextbox::LuaTextbox(lua_State * l) :
|
||||
LuaComponent(l),
|
||||
onTextChangedFunction(0)
|
||||
{
|
||||
this->l = l;
|
||||
int posX = luaL_optinteger(l, 1, 0);
|
||||
int posY = luaL_optinteger(l, 2, 0);
|
||||
int sizeX = luaL_optinteger(l, 3, 10);
|
||||
int sizeY = luaL_optinteger(l, 4, 10);
|
||||
std::string text = luaL_optstring(l, 5, "");
|
||||
std::string placeholder = luaL_optstring(l, 6, "");
|
||||
|
||||
textbox = new ui::Textbox(ui::Point(posX, posY), ui::Point(sizeX, sizeY), text, placeholder);
|
||||
textbox->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||
class TextChangedAction : public ui::TextboxAction
|
||||
{
|
||||
LuaTextbox * t;
|
||||
public:
|
||||
TextChangedAction(LuaTextbox * t) : t(t) {}
|
||||
void TextChangedCallback(ui::Textbox * sender)
|
||||
{
|
||||
t->triggerOnTextChanged();
|
||||
}
|
||||
};
|
||||
textbox->SetActionCallback(new TextChangedAction(this));
|
||||
component = textbox;
|
||||
}
|
||||
|
||||
int LuaTextbox::readonly(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TBOOLEAN);
|
||||
textbox->ReadOnly = lua_toboolean(l, 1);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushboolean(l, textbox->ReadOnly);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int LuaTextbox::onTextChanged(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onTextChangedFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onTextChangedFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LuaTextbox::triggerOnTextChanged()
|
||||
{
|
||||
if(onTextChangedFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onTextChangedFunction);
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, UserData);
|
||||
if (lua_pcall(l, 1, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int LuaTextbox::text(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TSTRING);
|
||||
textbox->SetText(lua_tostring(l, 1));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(l, textbox->GetText().c_str());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
LuaTextbox::~LuaTextbox()
|
||||
{
|
||||
}
|
33
src/cat/LuaTextbox.h
Normal file
33
src/cat/LuaTextbox.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include "LuaLuna.h"
|
||||
#include "LuaComponent.h"
|
||||
|
||||
namespace ui
|
||||
{
|
||||
class Textbox;
|
||||
}
|
||||
|
||||
class LuaScriptInterface;
|
||||
|
||||
class LuaTextbox: public LuaComponent
|
||||
{
|
||||
int onTextChangedFunction;
|
||||
ui::Textbox * textbox;
|
||||
int text(lua_State * l);
|
||||
int readonly(lua_State * l);
|
||||
int onTextChanged(lua_State * l);
|
||||
void triggerOnTextChanged();
|
||||
public:
|
||||
static const char className[];
|
||||
static Luna<LuaTextbox>::RegType methods[];
|
||||
|
||||
LuaTextbox(lua_State * l);
|
||||
~LuaTextbox();
|
||||
};
|
569
src/cat/LuaWindow.cpp
Normal file
569
src/cat/LuaWindow.cpp
Normal file
@ -0,0 +1,569 @@
|
||||
extern "C"
|
||||
{
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
#include "LuaScriptInterface.h"
|
||||
#include "LuaWindow.h"
|
||||
#include "LuaButton.h"
|
||||
#include "LuaLabel.h"
|
||||
#include "LuaTextbox.h"
|
||||
#include "LuaCheckbox.h"
|
||||
#include "LuaSlider.h"
|
||||
#include "LuaProgressBar.h"
|
||||
#include "interface/Button.h"
|
||||
#include "interface/Label.h"
|
||||
#include "interface/Window.h"
|
||||
|
||||
const char LuaWindow::className[] = "Window";
|
||||
|
||||
#define method(class, name) {#name, &class::name}
|
||||
Luna<LuaWindow>::RegType LuaWindow::methods[] = {
|
||||
method(LuaWindow, position),
|
||||
method(LuaWindow, size),
|
||||
method(LuaWindow, addComponent),
|
||||
method(LuaWindow, onInitialized),
|
||||
method(LuaWindow, onExit),
|
||||
method(LuaWindow, onTick),
|
||||
method(LuaWindow, onDraw),
|
||||
method(LuaWindow, onFocus),
|
||||
method(LuaWindow, onBlur),
|
||||
method(LuaWindow, onTryExit),
|
||||
method(LuaWindow, onTryOkay),
|
||||
method(LuaWindow, onMouseMove),
|
||||
method(LuaWindow, onMouseDown),
|
||||
method(LuaWindow, onMouseUp),
|
||||
method(LuaWindow, onMouseWheel),
|
||||
method(LuaWindow, onKeyPress),
|
||||
method(LuaWindow, onKeyRelease),
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
LuaWindow::LuaWindow(lua_State * l) :
|
||||
onInitializedFunction(0),
|
||||
onExitFunction(0),
|
||||
onTickFunction(0),
|
||||
onDrawFunction(0),
|
||||
onFocusFunction(0),
|
||||
onBlurFunction(0),
|
||||
onTryExitFunction(0),
|
||||
onTryOkayFunction(0),
|
||||
onMouseMoveFunction(0),
|
||||
onMouseDownFunction(0),
|
||||
onMouseUpFunction(0),
|
||||
onMouseWheelFunction(0),
|
||||
onKeyPressFunction(0),
|
||||
onKeyReleaseFunction(0)
|
||||
{
|
||||
this->l = l;
|
||||
int posX = luaL_optinteger(l, 1, 0);
|
||||
int posY = luaL_optinteger(l, 2, 0);
|
||||
int sizeX = luaL_optinteger(l, 3, 10);
|
||||
int sizeY = luaL_optinteger(l, 4, 10);
|
||||
|
||||
lua_pushstring(l, "Luacon_ci");
|
||||
lua_gettable(l, LUA_REGISTRYINDEX);
|
||||
ci = (LuaScriptInterface*)lua_touserdata(l, -1);
|
||||
lua_pop(l, 1);
|
||||
|
||||
class DrawnWindow : public ui::Window
|
||||
{
|
||||
LuaWindow * luaWindow;
|
||||
public:
|
||||
DrawnWindow(ui::Point position, ui::Point size, LuaWindow * luaWindow) : ui::Window(position, size), luaWindow(luaWindow) {}
|
||||
virtual void OnDraw()
|
||||
{
|
||||
Graphics * g = ui::Engine::Ref().g;
|
||||
g->clearrect(Position.X-2, Position.Y-2, Size.X+4, Size.Y+4);
|
||||
g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 255, 255, 255, 255);
|
||||
luaWindow->triggerOnDraw();
|
||||
}
|
||||
virtual void OnInitialized() { luaWindow->triggerOnInitialized(); }
|
||||
virtual void OnExit() { luaWindow->triggerOnExit(); }
|
||||
virtual void OnTick(float dt) { luaWindow->triggerOnTick( dt); }
|
||||
virtual void OnFocus() { luaWindow->triggerOnFocus(); }
|
||||
virtual void OnBlur() { luaWindow->triggerOnBlur(); }
|
||||
virtual void OnTryExit(ExitMethod) { luaWindow->triggerOnTryExit(); }
|
||||
virtual void OnTryOkay(OkayMethod) { luaWindow->triggerOnTryOkay(); }
|
||||
virtual void OnMouseMove(int x, int y, int dx, int dy) { luaWindow->triggerOnMouseMove(x, y, dx, dy); }
|
||||
virtual void OnMouseDown(int x, int y, unsigned button) { luaWindow->triggerOnMouseDown(x, y, button); }
|
||||
virtual void OnMouseUp(int x, int y, unsigned button) { luaWindow->triggerOnMouseUp(x, y, button); }
|
||||
virtual void OnMouseWheel(int x, int y, int d) { luaWindow->triggerOnMouseWheel(x, y, d); }
|
||||
virtual void OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt) { luaWindow->triggerOnKeyPress(key, character, shift, ctrl, alt); }
|
||||
virtual void OnKeyRelease(int key, Uint16 character, bool shift, bool ctrl, bool alt) { luaWindow->triggerOnKeyRelease(key, character, shift, ctrl, alt); }
|
||||
};
|
||||
|
||||
window = new DrawnWindow(ui::Point(posX, posY), ui::Point(sizeX, sizeY), this);
|
||||
}
|
||||
|
||||
int LuaWindow::addComponent(lua_State * l)
|
||||
{
|
||||
void * luaComponent = NULL;
|
||||
ui::Component * component = NULL;
|
||||
if(luaComponent = Luna<LuaButton>::tryGet(l, 1))
|
||||
component = Luna<LuaButton>::get(luaComponent)->GetComponent();
|
||||
else if(luaComponent = Luna<LuaLabel>::tryGet(l, 1))
|
||||
component = Luna<LuaLabel>::get(luaComponent)->GetComponent();
|
||||
else if(luaComponent = Luna<LuaTextbox>::tryGet(l, 1))
|
||||
component = Luna<LuaTextbox>::get(luaComponent)->GetComponent();
|
||||
else if(luaComponent = Luna<LuaCheckbox>::tryGet(l, 1))
|
||||
component = Luna<LuaCheckbox>::get(luaComponent)->GetComponent();
|
||||
else if(luaComponent = Luna<LuaSlider>::tryGet(l, 1))
|
||||
component = Luna<LuaSlider>::get(luaComponent)->GetComponent();
|
||||
else if(luaComponent = Luna<LuaProgressBar>::tryGet(l, 1))
|
||||
component = Luna<LuaProgressBar>::get(luaComponent)->GetComponent();
|
||||
else
|
||||
luaL_typerror(l, 1, "Component");
|
||||
if(component)
|
||||
window->AddComponent(component);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaWindow::position(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TNUMBER);
|
||||
luaL_checktype(l, 2, LUA_TNUMBER);
|
||||
window->Position = ui::Point(lua_tointeger(l, 1), lua_tointeger(l, 2));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushinteger(l, window->Position.X);
|
||||
lua_pushinteger(l, window->Position.Y);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
int LuaWindow::size(lua_State * l)
|
||||
{
|
||||
int args = lua_gettop(l);
|
||||
if(args)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TNUMBER);
|
||||
luaL_checktype(l, 2, LUA_TNUMBER);
|
||||
window->Size = ui::Point(lua_tointeger(l, 1), lua_tointeger(l, 2));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushinteger(l, window->Size.X);
|
||||
lua_pushinteger(l, window->Size.Y);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
void LuaWindow::triggerOnInitialized()
|
||||
{
|
||||
if(onInitializedFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onInitializedFunction);
|
||||
if(lua_pcall(l, 0, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LuaWindow::triggerOnExit()
|
||||
{
|
||||
if(onExitFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onExitFunction);
|
||||
if(lua_pcall(l, 0, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LuaWindow::triggerOnTick(float dt)
|
||||
{
|
||||
if(onTickFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onTickFunction);
|
||||
lua_pushnumber(l, dt);
|
||||
if(lua_pcall(l, 1, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LuaWindow::triggerOnDraw()
|
||||
{
|
||||
if(onDrawFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onDrawFunction);
|
||||
if(lua_pcall(l, 0, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LuaWindow::triggerOnFocus()
|
||||
{
|
||||
if(onFocusFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onFocusFunction);
|
||||
if(lua_pcall(l, 0, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LuaWindow::triggerOnBlur()
|
||||
{
|
||||
if(onBlurFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onBlurFunction);
|
||||
if(lua_pcall(l, 0, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LuaWindow::triggerOnTryExit()
|
||||
{
|
||||
if(onTryExitFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onTryExitFunction);
|
||||
if(lua_pcall(l, 0, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LuaWindow::triggerOnTryOkay()
|
||||
{
|
||||
if(onTryOkayFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onTryOkayFunction);
|
||||
if(lua_pcall(l, 0, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LuaWindow::triggerOnMouseMove(int x, int y, int dx, int dy)
|
||||
{
|
||||
if(onMouseMoveFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onMouseMoveFunction);
|
||||
lua_pushinteger(l, x);
|
||||
lua_pushinteger(l, y);
|
||||
lua_pushinteger(l, dx);
|
||||
lua_pushinteger(l, dy);
|
||||
if(lua_pcall(l, 4, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LuaWindow::triggerOnMouseDown(int x, int y, unsigned button)
|
||||
{
|
||||
if(onMouseDownFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onMouseDownFunction);
|
||||
lua_pushinteger(l, x);
|
||||
lua_pushinteger(l, y);
|
||||
lua_pushinteger(l, button);
|
||||
if(lua_pcall(l, 3, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LuaWindow::triggerOnMouseUp(int x, int y, unsigned button)
|
||||
{
|
||||
if(onMouseUpFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onMouseUpFunction);
|
||||
lua_pushinteger(l, x);
|
||||
lua_pushinteger(l, y);
|
||||
lua_pushinteger(l, button);
|
||||
if(lua_pcall(l, 3, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LuaWindow::triggerOnMouseWheel(int x, int y, int d)
|
||||
{
|
||||
if(onMouseWheelFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onMouseWheelFunction);
|
||||
lua_pushinteger(l, x);
|
||||
lua_pushinteger(l, y);
|
||||
lua_pushinteger(l, d);
|
||||
if(lua_pcall(l, 3, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LuaWindow::triggerOnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt)
|
||||
{
|
||||
if(onKeyPressFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onKeyPressFunction);
|
||||
lua_pushinteger(l, key);
|
||||
lua_pushinteger(l, character);
|
||||
lua_pushboolean(l, shift);
|
||||
lua_pushboolean(l, ctrl);
|
||||
lua_pushboolean(l, alt);
|
||||
if(lua_pcall(l, 5, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LuaWindow::triggerOnKeyRelease(int key, Uint16 character, bool shift, bool ctrl, bool alt)
|
||||
{
|
||||
if(onKeyReleaseFunction)
|
||||
{
|
||||
lua_rawgeti(l, LUA_REGISTRYINDEX, onKeyReleaseFunction);
|
||||
lua_pushinteger(l, key);
|
||||
lua_pushinteger(l, character);
|
||||
lua_pushboolean(l, shift);
|
||||
lua_pushboolean(l, ctrl);
|
||||
lua_pushboolean(l, alt);
|
||||
if(lua_pcall(l, 5, 0, 0))
|
||||
{
|
||||
ci->Log(CommandInterface::LogError, lua_tostring(l, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int LuaWindow::onInitialized(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onInitializedFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onInitializedFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaWindow::onExit(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onExitFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onExitFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaWindow::onTick(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onTickFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onTickFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaWindow::onDraw(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onDrawFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onDrawFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaWindow::onFocus(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onFocusFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onFocusFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaWindow::onBlur(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onBlurFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onBlurFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaWindow::onTryExit(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onTryExitFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onTryExitFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaWindow::onTryOkay(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onTryOkayFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onTryOkayFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaWindow::onMouseMove(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onMouseMoveFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onMouseMoveFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaWindow::onMouseDown(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onMouseDownFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onMouseDownFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaWindow::onMouseUp(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onMouseUpFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onMouseUpFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaWindow::onMouseWheel(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onMouseWheelFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onMouseWheelFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaWindow::onKeyPress(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onKeyPressFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onKeyPressFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaWindow::onKeyRelease(lua_State * l)
|
||||
{
|
||||
if(lua_type(l, 1) != LUA_TNIL)
|
||||
{
|
||||
luaL_checktype(l, 1, LUA_TFUNCTION);
|
||||
lua_pushvalue(l, 1);
|
||||
onKeyReleaseFunction = luaL_ref(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
onKeyReleaseFunction = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
LuaWindow::~LuaWindow()
|
||||
{
|
||||
if(ui::Engine::Ref().GetWindow() == window)
|
||||
ui::Engine::Ref().CloseWindow();
|
||||
delete window;
|
||||
}
|
81
src/cat/LuaWindow.h
Normal file
81
src/cat/LuaWindow.h
Normal file
@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include "LuaLuna.h"
|
||||
|
||||
#include "interface/Platform.h"
|
||||
namespace ui
|
||||
{
|
||||
class Window;
|
||||
}
|
||||
|
||||
class LuaScriptInterface;
|
||||
class LuaWindow
|
||||
{
|
||||
int onInitializedFunction;
|
||||
int onExitFunction;
|
||||
int onTickFunction;
|
||||
int onDrawFunction;
|
||||
int onFocusFunction;
|
||||
int onBlurFunction;
|
||||
int onTryExitFunction;
|
||||
int onTryOkayFunction;
|
||||
int onMouseMoveFunction;
|
||||
int onMouseDownFunction;
|
||||
int onMouseUpFunction;
|
||||
int onMouseWheelFunction;
|
||||
int onKeyPressFunction;
|
||||
int onKeyReleaseFunction;
|
||||
|
||||
ui::Window * window;
|
||||
lua_State * l;
|
||||
int position(lua_State * l);
|
||||
int size(lua_State * l);
|
||||
int addComponent(lua_State * l);
|
||||
|
||||
//Set event handlers
|
||||
int onInitialized(lua_State * l);
|
||||
int onExit(lua_State * l);
|
||||
int onTick(lua_State * l);
|
||||
int onDraw(lua_State * l);
|
||||
int onFocus(lua_State * l);
|
||||
int onBlur(lua_State * l);
|
||||
int onTryExit(lua_State * l);
|
||||
int onTryOkay(lua_State * l);
|
||||
int onMouseMove(lua_State * l);
|
||||
int onMouseDown(lua_State * l);
|
||||
int onMouseUp(lua_State * l);
|
||||
int onMouseWheel(lua_State * l);
|
||||
int onKeyPress(lua_State * l);
|
||||
int onKeyRelease(lua_State * l);
|
||||
|
||||
void triggerOnInitialized();
|
||||
void triggerOnExit();
|
||||
void triggerOnTick(float deltaTime);
|
||||
void triggerOnDraw();
|
||||
void triggerOnFocus();
|
||||
void triggerOnBlur();
|
||||
void triggerOnTryExit();
|
||||
void triggerOnTryOkay();
|
||||
void triggerOnMouseMove(int x, int y, int dx, int dy);
|
||||
void triggerOnMouseDown(int x, int y, unsigned button);
|
||||
void triggerOnMouseUp(int x, int y, unsigned button);
|
||||
void triggerOnMouseWheel(int x, int y, int d);
|
||||
void triggerOnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt);
|
||||
void triggerOnKeyRelease(int key, Uint16 character, bool shift, bool ctrl, bool alt);
|
||||
|
||||
public:
|
||||
LuaScriptInterface * ci;
|
||||
int UserData;
|
||||
static const char className[];
|
||||
static Luna<LuaWindow>::RegType methods[];
|
||||
|
||||
ui::Window * GetWindow() { return window; }
|
||||
LuaWindow(lua_State * l);
|
||||
~LuaWindow();
|
||||
};
|
113
src/cat/TPTSTypes.cpp
Normal file
113
src/cat/TPTSTypes.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* TPTSTypes.cpp
|
||||
*
|
||||
* Created on: Feb 4, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdint.h>
|
||||
#include "TPTSTypes.h"
|
||||
|
||||
AnyType::AnyType(ValueType type_, void * value_):
|
||||
type(type_),
|
||||
value(value_)
|
||||
{
|
||||
}
|
||||
|
||||
ValueType AnyType::GetType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
AnyType::AnyType(const AnyType & v):
|
||||
type(v.type),
|
||||
value(v.value)
|
||||
{
|
||||
if(type == TypeString)
|
||||
{
|
||||
value = new std::string(*((std::string*)value));
|
||||
}
|
||||
else if(type == TypePoint)
|
||||
{
|
||||
value = new ui::Point(*((ui::Point*)value));
|
||||
}
|
||||
}
|
||||
|
||||
AnyType::operator NumberType()
|
||||
{
|
||||
if(type != TypeNumber)
|
||||
throw InvalidConversionException(type, TypeNumber);
|
||||
else
|
||||
return NumberType((intptr_t)value);
|
||||
}
|
||||
|
||||
AnyType::operator StringType()
|
||||
{
|
||||
if(type == TypeNumber)
|
||||
{
|
||||
std::stringstream numberStream;
|
||||
numberStream << ((NumberType*)this)->Value();
|
||||
return StringType(numberStream.str());
|
||||
}
|
||||
else if(type == TypeString && value)
|
||||
{
|
||||
return StringType(*((std::string*)value));
|
||||
}
|
||||
else
|
||||
throw InvalidConversionException(type, TypeString);
|
||||
|
||||
}
|
||||
|
||||
AnyType::operator PointType()
|
||||
{
|
||||
if(type == TypePoint)
|
||||
{
|
||||
return PointType(*((ui::Point*)value));
|
||||
}
|
||||
else if(type == TypeString)
|
||||
{
|
||||
ui::Point thisPoint = *((ui::Point*)value);
|
||||
std::stringstream pointStream;
|
||||
pointStream << thisPoint.X << "," << thisPoint.Y;
|
||||
return StringType(pointStream.str());
|
||||
}
|
||||
else
|
||||
throw InvalidConversionException(type, TypePoint);
|
||||
}
|
||||
|
||||
AnyType::~AnyType()
|
||||
{
|
||||
if(type == TypeString || type == TypePoint)
|
||||
delete value;
|
||||
}
|
||||
|
||||
//Number Type
|
||||
|
||||
NumberType::NumberType(int number): AnyType(TypeNumber, (void*)number) { }
|
||||
|
||||
int NumberType::Value()
|
||||
{
|
||||
return (intptr_t)value;
|
||||
}
|
||||
|
||||
//String type
|
||||
|
||||
StringType::StringType(std::string string): AnyType(TypeString, new std::string(string)) { }
|
||||
|
||||
std::string StringType::Value()
|
||||
{
|
||||
return std::string(*((std::string*)value));
|
||||
}
|
||||
|
||||
//Point type
|
||||
|
||||
PointType::PointType(ui::Point point): AnyType(TypePoint, new ui::Point(point)) { }
|
||||
|
||||
PointType::PointType(int pointX, int pointY): AnyType(TypePoint, new ui::Point(pointX, pointY)) { }
|
||||
|
||||
ui::Point PointType::Value()
|
||||
{
|
||||
return ui::Point(*((ui::Point*)value));
|
||||
}
|
119
src/cat/TPTSTypes.h
Normal file
119
src/cat/TPTSTypes.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* TPTSTypes.h
|
||||
*
|
||||
* Created on: Feb 4, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#ifndef TPTSTYPES_H_
|
||||
#define TPTSTYPES_H_
|
||||
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include "interface/Point.h"
|
||||
|
||||
enum ValueType { TypeNumber, TypePoint, TypeString, TypeNull, TypeFunction };
|
||||
|
||||
class GeneralException
|
||||
{
|
||||
protected:
|
||||
std::string exception;
|
||||
public:
|
||||
GeneralException(std::string message){
|
||||
exception = message;
|
||||
}
|
||||
std::string GetExceptionMessage() {
|
||||
return exception;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class NumberType;
|
||||
class StringType;
|
||||
class PointType;
|
||||
|
||||
class AnyType
|
||||
{
|
||||
protected:
|
||||
ValueType type;
|
||||
void * value;
|
||||
public:
|
||||
AnyType(ValueType type_, void * value_);
|
||||
AnyType(const AnyType & v);
|
||||
operator NumberType();
|
||||
operator StringType();
|
||||
operator PointType();
|
||||
ValueType GetType();
|
||||
std::string TypeName()
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case TypeNumber:
|
||||
return "Number";
|
||||
case TypePoint:
|
||||
return "Point";
|
||||
case TypeString:
|
||||
return "String";
|
||||
case TypeNull:
|
||||
return "Null";
|
||||
case TypeFunction:
|
||||
return "Function";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
static std::string TypeName(ValueType type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case TypeNumber:
|
||||
return "Number";
|
||||
case TypePoint:
|
||||
return "Point";
|
||||
case TypeString:
|
||||
return "String";
|
||||
case TypeNull:
|
||||
return "Null";
|
||||
case TypeFunction:
|
||||
return "Function";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
~AnyType();
|
||||
};
|
||||
|
||||
class InvalidConversionException: public GeneralException
|
||||
{
|
||||
private:
|
||||
ValueType from;
|
||||
ValueType to;
|
||||
public:
|
||||
InvalidConversionException(ValueType from_, ValueType to_):
|
||||
GeneralException("Invalid conversion from " + AnyType::TypeName(from_) + " to " + AnyType::TypeName(to_)), from(from_), to(to_) {
|
||||
}
|
||||
};
|
||||
|
||||
class NumberType: public AnyType
|
||||
{
|
||||
public:
|
||||
NumberType(int number);
|
||||
int Value();
|
||||
};
|
||||
|
||||
class StringType: public AnyType
|
||||
{
|
||||
public:
|
||||
StringType(std::string string);
|
||||
std::string Value();
|
||||
};
|
||||
|
||||
class PointType: public AnyType
|
||||
{
|
||||
public:
|
||||
PointType(ui::Point point);
|
||||
PointType(int pointX, int pointY);
|
||||
ui::Point Value();
|
||||
};
|
||||
|
||||
#endif /* TPTSTYPES_H_ */
|
488
src/cat/TPTScriptInterface.cpp
Normal file
488
src/cat/TPTScriptInterface.cpp
Normal file
@ -0,0 +1,488 @@
|
||||
/*
|
||||
* TPTScriptInterface.cpp
|
||||
*
|
||||
* Created on: Feb 5, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#include <stack>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <deque>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "TPTScriptInterface.h"
|
||||
#include "game/GameModel.h"
|
||||
#include "simulation/Air.h"
|
||||
|
||||
TPTScriptInterface::TPTScriptInterface(GameController * c, GameModel * m): CommandInterface(c, m)
|
||||
{
|
||||
}
|
||||
|
||||
int TPTScriptInterface::Command(std::string command)
|
||||
{
|
||||
lastError = "";
|
||||
std::deque<std::string> words;
|
||||
std::deque<AnyType> commandWords;
|
||||
int retCode;
|
||||
|
||||
//Split command into words, put them on the stack
|
||||
char * rawCommand;
|
||||
rawCommand = (char*)calloc(command.length()+1, 1);
|
||||
memcpy(rawCommand, (char*)command.c_str(), command.length());
|
||||
char * currentWord = rawCommand;
|
||||
char * currentCommand = rawCommand;
|
||||
while((currentCommand = strchr(currentCommand, ' ')))
|
||||
{
|
||||
currentCommand[0] = 0;
|
||||
words.push_back(std::string(currentWord));
|
||||
currentWord = ++currentCommand;
|
||||
}
|
||||
words.push_back(std::string(currentWord));
|
||||
while(!words.empty())
|
||||
{
|
||||
try
|
||||
{
|
||||
commandWords.push_back(eval(&words));
|
||||
}
|
||||
catch (GeneralException & e)
|
||||
{
|
||||
retCode = -1;
|
||||
lastError = e.GetExceptionMessage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(rawCommand);
|
||||
if(commandWords.size())
|
||||
{
|
||||
retCode = 0;
|
||||
lastError = ((StringType)commandWords.front()).Value();
|
||||
}
|
||||
|
||||
//Evaluate
|
||||
return 0;
|
||||
}
|
||||
|
||||
ValueType TPTScriptInterface::testType(std::string word)
|
||||
{
|
||||
int i = 0;
|
||||
char * rawWord = (char *)word.c_str();
|
||||
//Function
|
||||
if(word == "set")
|
||||
return TypeFunction;
|
||||
else if(word == "create")
|
||||
return TypeFunction;
|
||||
else if(word == "delete")
|
||||
return TypeFunction;
|
||||
else if(word == "kill")
|
||||
return TypeFunction;
|
||||
else if(word == "load")
|
||||
return TypeFunction;
|
||||
else if(word == "reset")
|
||||
return TypeFunction;
|
||||
else if(word == "bubble")
|
||||
return TypeFunction;
|
||||
else if(word == "quit")
|
||||
return TypeFunction;
|
||||
//Basic type
|
||||
parseNumber:
|
||||
for(i = 0; i < word.length(); i++)
|
||||
{
|
||||
if(!(rawWord[i] >= '0' && rawWord[i] <= '9') && rawWord[i] != '.' && !(rawWord[i] == '-' && !i))
|
||||
{
|
||||
if(rawWord[i] == ',' && rawWord[i+1] >= '0' && rawWord[i+1] <= '9')
|
||||
goto parsePoint;
|
||||
else
|
||||
goto parseString;
|
||||
}
|
||||
}
|
||||
return TypeNumber;
|
||||
parsePoint:
|
||||
i++;
|
||||
for(; i < word.length(); i++)
|
||||
if(!(rawWord[i] >= '0' && rawWord[i] <= '9'))
|
||||
{
|
||||
goto parseString;
|
||||
}
|
||||
return TypePoint;
|
||||
parseString:
|
||||
return TypeString;
|
||||
}
|
||||
|
||||
AnyType TPTScriptInterface::eval(std::deque<std::string> * words)
|
||||
{
|
||||
if(words->size() < 1)
|
||||
return AnyType(TypeNull, NULL);
|
||||
std::string word = words->front(); words->pop_front();
|
||||
char * rawWord = (char *)word.c_str();
|
||||
ValueType wordType = testType(word);
|
||||
switch(wordType)
|
||||
{
|
||||
case TypeFunction:
|
||||
if(word == "set")
|
||||
return tptS_set(words);
|
||||
else if(word == "create")
|
||||
return tptS_create(words);
|
||||
else if(word == "delete" || word == "kill")
|
||||
return tptS_delete(words);
|
||||
else if(word == "load")
|
||||
return tptS_load(words);
|
||||
else if(word == "reset")
|
||||
return tptS_reset(words);
|
||||
else if(word == "bubble")
|
||||
return tptS_bubble(words);
|
||||
else if(word == "quit")
|
||||
return tptS_quit(words);
|
||||
break;
|
||||
case TypeNumber:
|
||||
return NumberType(atoi(rawWord));
|
||||
case TypePoint:
|
||||
{
|
||||
int pointX, pointY;
|
||||
sscanf(rawWord, "%d,%d", &pointX, &pointY);
|
||||
return PointType(pointX, pointY);
|
||||
}
|
||||
case TypeString:
|
||||
return StringType(word);
|
||||
}
|
||||
}
|
||||
|
||||
std::string TPTScriptInterface::FormatCommand(std::string command)
|
||||
{
|
||||
std::deque<std::string> words;
|
||||
std::deque<AnyType> commandWords;
|
||||
std::string outputData;
|
||||
|
||||
//Split command into words, put them on the stack
|
||||
char * rawCommand;
|
||||
rawCommand = (char*)calloc(command.length()+1, 1);
|
||||
memcpy(rawCommand, (char*)command.c_str(), command.length());
|
||||
char * currentWord = rawCommand;
|
||||
char * currentCommand = rawCommand;
|
||||
while((currentCommand = strchr(currentCommand, ' ')))
|
||||
{
|
||||
currentCommand[0] = 0;
|
||||
words.push_back(std::string(currentWord));
|
||||
currentWord = ++currentCommand;
|
||||
}
|
||||
words.push_back(std::string(currentWord));
|
||||
free(rawCommand);
|
||||
while(!words.empty())
|
||||
{
|
||||
ValueType cType = testType(words.front());
|
||||
switch(cType)
|
||||
{
|
||||
case TypeFunction:
|
||||
outputData += "\bt";
|
||||
break;
|
||||
case TypeNumber:
|
||||
case TypePoint:
|
||||
outputData += "\bo";
|
||||
break;
|
||||
case TypeString:
|
||||
outputData += "\bg";
|
||||
break;
|
||||
default:
|
||||
outputData += "\bw";
|
||||
break;
|
||||
}
|
||||
outputData += words.front() + " ";
|
||||
words.pop_front();
|
||||
}
|
||||
return outputData;
|
||||
}
|
||||
|
||||
AnyType TPTScriptInterface::tptS_set(std::deque<std::string> * words)
|
||||
{
|
||||
//Arguments from stack
|
||||
StringType property = eval(words);
|
||||
AnyType selector = eval(words);
|
||||
AnyType value = eval(words);
|
||||
|
||||
Simulation * sim = m->GetSimulation();
|
||||
unsigned char * partsBlock = (unsigned char*)&sim->parts[0];
|
||||
|
||||
int returnValue = 0;
|
||||
|
||||
FormatType propertyFormat;
|
||||
int propertyOffset = GetPropertyOffset(property.Value(), propertyFormat);
|
||||
|
||||
if(propertyOffset==-1)
|
||||
throw GeneralException("Invalid property");
|
||||
|
||||
//Selector
|
||||
int newValue;
|
||||
if(value.GetType() == TypeNumber)
|
||||
newValue = ((NumberType)value).Value();
|
||||
else if(value.GetType() == TypeString)
|
||||
{
|
||||
newValue = GetParticleType(((StringType)value).Value());
|
||||
if (newValue < 0 || newValue >= PT_NUM)
|
||||
{
|
||||
if (((StringType)value).Value() == "GOLD" || ((StringType)value).Value() == "gold")
|
||||
throw GeneralException("No, GOLD will not be an element");
|
||||
else
|
||||
throw GeneralException("Invalid element");
|
||||
}
|
||||
}
|
||||
else
|
||||
throw GeneralException("Invalid value for assignment");
|
||||
if (property.Value() == "type" && (newValue < 0 || newValue >= PT_NUM))
|
||||
throw GeneralException("Invalid element");
|
||||
|
||||
if(selector.GetType() == TypePoint || selector.GetType() == TypeNumber)
|
||||
{
|
||||
int partIndex = -1;
|
||||
if(selector.GetType() == TypePoint)
|
||||
{
|
||||
ui::Point tempPoint = ((PointType)selector).Value();
|
||||
if(tempPoint.X<0 || tempPoint.Y<0 || tempPoint.Y >= YRES || tempPoint.X >= XRES)
|
||||
throw GeneralException("Invalid position");
|
||||
|
||||
}
|
||||
else
|
||||
partIndex = ((NumberType)selector).Value();
|
||||
if(partIndex<0 || partIndex>NPART || sim->parts[partIndex].type==0)
|
||||
throw GeneralException("Invalid particle");
|
||||
|
||||
switch(propertyFormat)
|
||||
{
|
||||
case FormatInt:
|
||||
*((int*)(partsBlock+(partIndex*sizeof(Particle))+propertyOffset)) = newValue;
|
||||
break;
|
||||
case FormatFloat:
|
||||
*((float*)(partsBlock+(partIndex*sizeof(Particle))+propertyOffset)) = newValue;
|
||||
break;
|
||||
}
|
||||
returnValue = 1;
|
||||
}
|
||||
else if(selector.GetType() == TypeString && ((StringType)selector).Value() == "all")
|
||||
{
|
||||
switch(propertyFormat)
|
||||
{
|
||||
case FormatInt:
|
||||
{
|
||||
for(int j = 0; j < NPART; j++)
|
||||
if(sim->parts[j].type)
|
||||
{
|
||||
returnValue++;
|
||||
*((int*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FormatFloat:
|
||||
{
|
||||
for(int j = 0; j < NPART; j++)
|
||||
if(sim->parts[j].type)
|
||||
{
|
||||
returnValue++;
|
||||
*((float*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(selector.GetType() == TypeString || selector.GetType() == TypeNumber)
|
||||
{
|
||||
int type;
|
||||
if(selector.GetType() == TypeNumber)
|
||||
type = ((NumberType)selector).Value();
|
||||
else if(selector.GetType() == TypeString)
|
||||
type = GetParticleType(((StringType)selector).Value());
|
||||
|
||||
if(type<0 || type>=PT_NUM)
|
||||
throw GeneralException("Invalid particle type");
|
||||
std::cout << propertyOffset << std::endl;
|
||||
switch(propertyFormat)
|
||||
{
|
||||
case FormatInt:
|
||||
{
|
||||
for(int j = 0; j < NPART; j++)
|
||||
if(sim->parts[j].type == type)
|
||||
{
|
||||
returnValue++;
|
||||
*((int*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FormatFloat:
|
||||
{
|
||||
for(int j = 0; j < NPART; j++)
|
||||
if(sim->parts[j].type == type)
|
||||
{
|
||||
returnValue++;
|
||||
*((float*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
throw GeneralException("Invalid selector");
|
||||
return NumberType(returnValue);
|
||||
}
|
||||
|
||||
AnyType TPTScriptInterface::tptS_create(std::deque<std::string> * words)
|
||||
{
|
||||
//Arguments from stack
|
||||
AnyType createType = eval(words);
|
||||
PointType position = eval(words);
|
||||
|
||||
Simulation * sim = m->GetSimulation();
|
||||
|
||||
int type;
|
||||
if(createType.GetType() == TypeNumber)
|
||||
type = ((NumberType)createType).Value();
|
||||
else if(createType.GetType() == TypeString)
|
||||
type = GetParticleType(((StringType)createType).Value());
|
||||
else
|
||||
throw GeneralException("Invalid type");
|
||||
|
||||
if(type == -1)
|
||||
throw GeneralException("Invalid particle type");
|
||||
|
||||
ui::Point tempPoint = position.Value();
|
||||
if(tempPoint.X<0 || tempPoint.Y<0 || tempPoint.Y >= YRES || tempPoint.X >= XRES)
|
||||
throw GeneralException("Invalid position");
|
||||
|
||||
int returnValue = sim->create_part(-1, tempPoint.X, tempPoint.Y, type);
|
||||
|
||||
return NumberType(returnValue);
|
||||
}
|
||||
|
||||
AnyType TPTScriptInterface::tptS_delete(std::deque<std::string> * words)
|
||||
{
|
||||
//Arguments from stack
|
||||
AnyType partRef = eval(words);
|
||||
|
||||
Simulation * sim = m->GetSimulation();
|
||||
|
||||
if(partRef.GetType() == TypePoint)
|
||||
{
|
||||
ui::Point deletePoint = ((PointType)partRef).Value();
|
||||
if(deletePoint.X<0 || deletePoint.Y<0 || deletePoint.Y >= YRES || deletePoint.X >= XRES)
|
||||
throw GeneralException("Invalid position");
|
||||
sim->delete_part(deletePoint.X, deletePoint.Y, 0);
|
||||
}
|
||||
else if(partRef.GetType() == TypeNumber)
|
||||
{
|
||||
int partIndex = ((NumberType)partRef).Value();
|
||||
if(partIndex < 0 || partIndex >= NPART)
|
||||
throw GeneralException("Invalid particle index");
|
||||
sim->kill_part(partIndex);
|
||||
}
|
||||
else
|
||||
throw GeneralException("Invalid particle reference");
|
||||
|
||||
return NumberType(0);
|
||||
}
|
||||
|
||||
AnyType TPTScriptInterface::tptS_load(std::deque<std::string> * words)
|
||||
{
|
||||
//Arguments from stack
|
||||
NumberType saveID = eval(words);
|
||||
|
||||
c->OpenSavePreview(saveID.Value(), 0);
|
||||
|
||||
return NumberType(0);
|
||||
}
|
||||
|
||||
AnyType TPTScriptInterface::tptS_bubble(std::deque<std::string> * words)
|
||||
{
|
||||
//Arguments from stack
|
||||
PointType bubblePosA = eval(words);
|
||||
ui::Point bubblePos = bubblePosA.Value();
|
||||
|
||||
if(bubblePos.X<0 || bubblePos.Y<0 || bubblePos.Y >= YRES || bubblePos.X >= XRES)
|
||||
throw GeneralException("Invalid position");
|
||||
|
||||
Simulation * sim = m->GetSimulation();
|
||||
|
||||
int first, rem1, rem2;
|
||||
|
||||
first = sim->create_part(-1, bubblePos.X+18, bubblePos.Y, PT_SOAP);
|
||||
rem1 = first;
|
||||
|
||||
for (int i = 1; i<=30; i++)
|
||||
{
|
||||
rem2 = sim->create_part(-1, bubblePos.X+18*cosf(i/5.0), bubblePos.Y+18*sinf(i/5.0), PT_SOAP);
|
||||
|
||||
sim->parts[rem1].ctype = 7;
|
||||
sim->parts[rem1].tmp = rem2;
|
||||
sim->parts[rem2].tmp2 = rem1;
|
||||
|
||||
rem1 = rem2;
|
||||
}
|
||||
|
||||
sim->parts[rem1].ctype = 7;
|
||||
sim->parts[rem1].tmp = first;
|
||||
sim->parts[first].tmp2 = rem1;
|
||||
sim->parts[first].ctype = 7;
|
||||
|
||||
return NumberType(0);
|
||||
}
|
||||
|
||||
AnyType TPTScriptInterface::tptS_reset(std::deque<std::string> * words)
|
||||
{
|
||||
//Arguments from stack
|
||||
StringType reset = eval(words);
|
||||
std::string resetStr = reset.Value();
|
||||
|
||||
Simulation * sim = m->GetSimulation();
|
||||
|
||||
if (resetStr == "pressure")
|
||||
{
|
||||
for (int nx = 0; nx < XRES/CELL; nx++)
|
||||
for (int ny = 0; ny < YRES/CELL; ny++)
|
||||
{
|
||||
sim->air->pv[ny][nx] = 0;
|
||||
}
|
||||
}
|
||||
else if (resetStr == "velocity")
|
||||
{
|
||||
for (int nx = 0; nx < XRES/CELL; nx++)
|
||||
for (int ny = 0; ny < YRES/CELL; ny++)
|
||||
{
|
||||
sim->air->vx[ny][nx] = 0;
|
||||
sim->air->vy[ny][nx] = 0;
|
||||
}
|
||||
}
|
||||
else if (resetStr == "sparks")
|
||||
{
|
||||
for (int i = 0; i < NPART; i++)
|
||||
{
|
||||
if (sim->parts[i].type == PT_SPRK)
|
||||
{
|
||||
sim->parts[i].type = sim->parts[i].ctype;
|
||||
sim->parts[i].life = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (resetStr == "temp")
|
||||
{
|
||||
for (int i = 0; i < NPART; i++)
|
||||
{
|
||||
if (sim->parts[i].type)
|
||||
{
|
||||
sim->parts[i].temp = sim->elements[sim->parts[i].type].Temperature;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw GeneralException("Unknown reset command");
|
||||
}
|
||||
|
||||
return NumberType(0);
|
||||
}
|
||||
|
||||
AnyType TPTScriptInterface::tptS_quit(std::deque<std::string> * words)
|
||||
{
|
||||
ui::Engine::Ref().Exit();
|
||||
|
||||
return NumberType(0);
|
||||
}
|
||||
|
||||
TPTScriptInterface::~TPTScriptInterface() {
|
||||
}
|
||||
|
33
src/cat/TPTScriptInterface.h
Normal file
33
src/cat/TPTScriptInterface.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* TPTScriptInterface.h
|
||||
*
|
||||
* Created on: Feb 5, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#ifndef TPTSCRIPTINTERFACE_H_
|
||||
#define TPTSCRIPTINTERFACE_H_
|
||||
|
||||
#include "CommandInterface.h"
|
||||
#include "TPTSTypes.h"
|
||||
|
||||
class TPTScriptInterface: public CommandInterface {
|
||||
protected:
|
||||
AnyType eval(std::deque<std::string> * words);
|
||||
AnyType tptS_set(std::deque<std::string> * words);
|
||||
AnyType tptS_create(std::deque<std::string> * words);
|
||||
AnyType tptS_delete(std::deque<std::string> * words);
|
||||
AnyType tptS_load(std::deque<std::string> * words);
|
||||
AnyType tptS_reset(std::deque<std::string> * words);
|
||||
AnyType tptS_bubble(std::deque<std::string> * words);
|
||||
AnyType tptS_quit(std::deque<std::string> * words);
|
||||
ValueType testType(std::string word);
|
||||
public:
|
||||
TPTScriptInterface(GameController * c, GameModel * m);
|
||||
virtual void Tick() {}
|
||||
virtual int Command(std::string command);
|
||||
virtual std::string FormatCommand(std::string command);
|
||||
virtual ~TPTScriptInterface();
|
||||
};
|
||||
|
||||
#endif /* TPTSCRIPTINTERFACE_H_ */
|
2351
src/client/Client.cpp
Normal file
2351
src/client/Client.cpp
Normal file
File diff suppressed because it is too large
Load Diff
176
src/client/Client.h
Normal file
176
src/client/Client.h
Normal file
@ -0,0 +1,176 @@
|
||||
#ifndef CLIENT_H
|
||||
#define CLIENT_H
|
||||
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#include "Config.h"
|
||||
#include "Singleton.h"
|
||||
|
||||
#include "User.h"
|
||||
|
||||
#include "cajun/elements.h"
|
||||
|
||||
class Thumbnail;
|
||||
class SaveInfo;
|
||||
class SaveFile;
|
||||
class SaveComment;
|
||||
class GameSave;
|
||||
|
||||
enum LoginStatus {
|
||||
LoginOkay, LoginError
|
||||
};
|
||||
|
||||
enum RequestStatus {
|
||||
RequestOkay, RequestFailure
|
||||
};
|
||||
|
||||
class UpdateInfo
|
||||
{
|
||||
public:
|
||||
enum BuildType { Stable, Beta, Snapshot };
|
||||
std::string File;
|
||||
int Major;
|
||||
int Minor;
|
||||
int Build;
|
||||
int Time;
|
||||
BuildType Type;
|
||||
UpdateInfo() : Major(0), Minor(0), Build(0), Time(0), File(""), Type(Stable) {}
|
||||
UpdateInfo(int major, int minor, int build, std::string file, BuildType type) : Major(major), Minor(minor), Build(build), Time(0), File(file), Type(type) {}
|
||||
UpdateInfo(int time, std::string file, BuildType type) : Major(0), Minor(0), Build(0), Time(time), File(file), Type(type) {}
|
||||
};
|
||||
|
||||
class ThumbnailListener;
|
||||
class ClientListener;
|
||||
class Client: public Singleton<Client> {
|
||||
private:
|
||||
std::string messageOfTheDay;
|
||||
|
||||
void * versionCheckRequest;
|
||||
bool updateAvailable;
|
||||
UpdateInfo updateInfo;
|
||||
|
||||
|
||||
std::string lastError;
|
||||
|
||||
std::list<std::string> stampIDs;
|
||||
int lastStampTime;
|
||||
int lastStampName;
|
||||
|
||||
//Auth session
|
||||
User authUser;
|
||||
|
||||
//Thumbnail retreival
|
||||
int thumbnailCacheNextID;
|
||||
Thumbnail * thumbnailCache[THUMB_CACHE_SIZE];
|
||||
void * activeThumbRequests[IMGCONNS];
|
||||
int activeThumbRequestTimes[IMGCONNS];
|
||||
int activeThumbRequestCompleteTimes[IMGCONNS];
|
||||
std::string activeThumbRequestIDs[IMGCONNS];
|
||||
void updateStamps();
|
||||
static std::vector<std::string> explodePropertyString(std::string property);
|
||||
void notifyUpdateAvailable();
|
||||
void notifyAuthUserChanged();
|
||||
void notifyMessageOfTheDay();
|
||||
|
||||
//Config file handle
|
||||
json::Object configDocument;
|
||||
public:
|
||||
|
||||
std::vector<ClientListener*> listeners;
|
||||
|
||||
UpdateInfo GetUpdateInfo();
|
||||
|
||||
Client();
|
||||
~Client();
|
||||
|
||||
std::vector<std::string> DirectorySearch(std::string directory, std::string search, std::vector<std::string> extensions);
|
||||
std::vector<std::string> DirectorySearch(std::string directory, std::string search, std::string extension);
|
||||
|
||||
bool DoInstallation();
|
||||
|
||||
std::vector<unsigned char> ReadFile(std::string filename);
|
||||
|
||||
void SetMessageOfTheDay(std::string message);
|
||||
std::string GetMessageOfTheDay();
|
||||
|
||||
void Initialise(std::string proxyString);
|
||||
void SetProxy(std::string proxy);
|
||||
|
||||
int MakeDirectory(const char * dirname);
|
||||
void WriteFile(std::vector<unsigned char> fileData, std::string filename);
|
||||
void WriteFile(std::vector<char> fileData, std::string filename);
|
||||
bool FileExists(std::string filename);
|
||||
|
||||
void AddListener(ClientListener * listener);
|
||||
void RemoveListener(ClientListener * listener);
|
||||
|
||||
RequestStatus ExecVote(int saveID, int direction);
|
||||
RequestStatus UploadSave(SaveInfo & save);
|
||||
|
||||
SaveFile * GetStamp(std::string stampID);
|
||||
void DeleteStamp(std::string stampID);
|
||||
std::string AddStamp(GameSave * saveData);
|
||||
std::vector<std::string> GetStamps(int start, int count);
|
||||
void RescanStamps();
|
||||
int GetStampsCount();
|
||||
SaveFile * GetFirstStamp();
|
||||
|
||||
RequestStatus AddComment(int saveID, std::string comment);
|
||||
|
||||
unsigned char * GetSaveData(int saveID, int saveDate, int & dataLength);
|
||||
std::vector<unsigned char> GetSaveData(int saveID, int saveDate);
|
||||
LoginStatus Login(std::string username, std::string password, User & user);
|
||||
void ClearThumbnailRequests();
|
||||
std::vector<SaveInfo*> * SearchSaves(int start, int count, std::string query, std::string sort, std::string category, int & resultCount);
|
||||
std::vector<std::pair<std::string, int> > * GetTags(int start, int count, std::string query, int & resultCount);
|
||||
std::vector<SaveComment*> * GetComments(int saveID, int start, int count);
|
||||
Thumbnail * GetPreview(int saveID, int saveDate);
|
||||
Thumbnail * GetThumbnail(int saveID, int saveDate);
|
||||
SaveInfo * GetSave(int saveID, int saveDate);
|
||||
RequestStatus DeleteSave(int saveID);
|
||||
RequestStatus ReportSave(int saveID, std::string message);
|
||||
RequestStatus UnpublishSave(int saveID);
|
||||
RequestStatus FavouriteSave(int saveID, bool favourite);
|
||||
void SetAuthUser(User user);
|
||||
User GetAuthUser();
|
||||
std::vector<std::string> * RemoveTag(int saveID, std::string tag); //TODO RequestStatus
|
||||
std::vector<std::string> * AddTag(int saveID, std::string tag);
|
||||
std::string GetLastError() {
|
||||
return lastError;
|
||||
}
|
||||
void Tick();
|
||||
void Shutdown();
|
||||
|
||||
//Force flushing preferences to file on disk.
|
||||
void WritePrefs();
|
||||
|
||||
std::string GetPrefString(std::string property, std::string defaultValue);
|
||||
double GetPrefNumber(std::string property, double defaultValue);
|
||||
int GetPrefInteger(std::string property, int defaultValue);
|
||||
unsigned int GetPrefUInteger(std::string property, unsigned int defaultValue);
|
||||
std::vector<std::string> GetPrefStringArray(std::string property);
|
||||
std::vector<double> GetPrefNumberArray(std::string property);
|
||||
std::vector<int> GetPrefIntegerArray(std::string property);
|
||||
std::vector<unsigned int> GetPrefUIntegerArray(std::string property);
|
||||
std::vector<bool> GetPrefBoolArray(std::string property);
|
||||
bool GetPrefBool(std::string property, bool defaultValue);
|
||||
|
||||
void SetPref(std::string property, std::string value);
|
||||
void SetPref(std::string property, double value);
|
||||
void SetPref(std::string property, int value);
|
||||
void SetPref(std::string property, unsigned int value);
|
||||
void SetPref(std::string property, std::vector<std::string> value);
|
||||
void SetPref(std::string property, std::vector<double> value);
|
||||
void SetPref(std::string property, std::vector<int> value);
|
||||
void SetPref(std::string property, std::vector<unsigned int> value);
|
||||
void SetPref(std::string property, std::vector<bool> value);
|
||||
void SetPref(std::string property, bool value);
|
||||
|
||||
json::UnknownElement GetPref(std::string property);
|
||||
void setPrefR(std::deque<std::string> tokens, json::UnknownElement & element, json::UnknownElement & value);
|
||||
void SetPref(std::string property, json::UnknownElement & value);
|
||||
};
|
||||
|
||||
#endif // CLIENT_H
|
24
src/client/ClientListener.h
Normal file
24
src/client/ClientListener.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* ClientListener.h
|
||||
*
|
||||
* Created on: Jun 19, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#ifndef CLIENTLISTENER_H_
|
||||
#define CLIENTLISTENER_H_
|
||||
|
||||
class Client;
|
||||
class ClientListener
|
||||
{
|
||||
public:
|
||||
ClientListener() {}
|
||||
virtual ~ClientListener() {}
|
||||
|
||||
virtual void NotifyUpdateAvailable(Client * sender) {}
|
||||
virtual void NotifyAuthUserChanged(Client * sender) {}
|
||||
virtual void NotifyMessageOfTheDay(Client * sender) {}
|
||||
};
|
||||
|
||||
|
||||
#endif /* CLIENTLISTENER_H_ */
|
2092
src/client/GameSave.cpp
Normal file
2092
src/client/GameSave.cpp
Normal file
File diff suppressed because it is too large
Load Diff
112
src/client/GameSave.h
Normal file
112
src/client/GameSave.h
Normal file
@ -0,0 +1,112 @@
|
||||
//
|
||||
// GameSave.h
|
||||
// The Powder Toy
|
||||
//
|
||||
// Created by Simon Robertshaw on 04/06/2012.
|
||||
//
|
||||
|
||||
#ifndef The_Powder_Toy_GameSave_h
|
||||
#define The_Powder_Toy_GameSave_h
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "Config.h"
|
||||
#include "Misc.h"
|
||||
|
||||
#include "simulation/Sign.h"
|
||||
#include "simulation/Particle.h"
|
||||
|
||||
//using namespace std;
|
||||
|
||||
struct ParseException: public std::exception {
|
||||
enum ParseResult { OK = 0, Corrupt, WrongVersion, InvalidDimensions, InternalError, MissingElement };
|
||||
std::string message;
|
||||
ParseResult result;
|
||||
public:
|
||||
ParseException(ParseResult result, std::string message_): message(message_), result(result) {}
|
||||
const char * what() const throw()
|
||||
{
|
||||
return message.c_str();
|
||||
}
|
||||
~ParseException() throw() {};
|
||||
};
|
||||
|
||||
class GameSave
|
||||
{
|
||||
public:
|
||||
|
||||
int blockWidth, blockHeight;
|
||||
|
||||
//Simulation data
|
||||
//int ** particleMap;
|
||||
int particlesCount;
|
||||
Particle * particles;
|
||||
unsigned char ** blockMap;
|
||||
float ** fanVelX;
|
||||
float ** fanVelY;
|
||||
|
||||
//Simulation Options
|
||||
bool waterEEnabled;
|
||||
bool legacyEnable;
|
||||
bool gravityEnable;
|
||||
bool paused;
|
||||
int gravityMode;
|
||||
int airMode;
|
||||
|
||||
//Signs
|
||||
std::vector<sign> signs;
|
||||
|
||||
//Element palette
|
||||
typedef std::pair<std::string, int> PaletteItem;
|
||||
std::vector<PaletteItem> palette;
|
||||
|
||||
GameSave();
|
||||
GameSave(GameSave & save);
|
||||
GameSave(int width, int height);
|
||||
GameSave(char * data, int dataSize);
|
||||
GameSave(std::vector<char> data);
|
||||
GameSave(std::vector<unsigned char> data);
|
||||
~GameSave();
|
||||
void setSize(int width, int height);
|
||||
char * Serialise(int & dataSize);
|
||||
std::vector<char> Serialise();
|
||||
void Transform(matrix2d transform, vector2d translate);
|
||||
|
||||
void Expand();
|
||||
void Collapse();
|
||||
bool Collapsed();
|
||||
|
||||
inline GameSave& operator << (Particle v)
|
||||
{
|
||||
if(particlesCount<NPART && v.type)
|
||||
{
|
||||
particles[particlesCount++] = v;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline GameSave& operator << (sign v)
|
||||
{
|
||||
if(signs.size()<MAXSIGNS && v.text.length())
|
||||
signs.push_back(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
bool expanded;
|
||||
bool hasOriginalData;
|
||||
float * fanVelXPtr;
|
||||
float * fanVelYPtr;
|
||||
unsigned char * blockMapPtr;
|
||||
|
||||
std::vector<char> originalData;
|
||||
|
||||
void dealloc();
|
||||
void read(char * data, int dataSize);
|
||||
void readOPS(char * data, int dataLength);
|
||||
void readPSv(char * data, int dataLength);
|
||||
char * serialiseOPS(int & dataSize);
|
||||
//serialisePSv();
|
||||
};
|
||||
|
||||
#endif
|
1104
src/client/HTTP.cpp
Normal file
1104
src/client/HTTP.cpp
Normal file
File diff suppressed because it is too large
Load Diff
45
src/client/HTTP.h
Normal file
45
src/client/HTTP.h
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Powder Toy - HTTP Library (Header)
|
||||
*
|
||||
* Copyright (c) 2008 - 2010 Stanislaw Skowronek.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
#ifndef HTTP_H
|
||||
#define HTTP_H
|
||||
|
||||
static char hexChars[] = "0123456789abcdef";
|
||||
|
||||
void http_init(char *proxy);
|
||||
void http_done(void);
|
||||
|
||||
char *http_simple_get(char *uri, int *ret, int *len);
|
||||
char *http_auth_get(char *uri, char *user, char *pass, char * session_id, int *ret, int *len);
|
||||
char *http_simple_post(char *uri, char *data, int dlen, int *ret, int *len);
|
||||
|
||||
void http_auth_headers(void *ctx, char *user, char *pass, char * session_id);
|
||||
|
||||
void *http_async_req_start(void *ctx, char *uri, char *data, int dlen, int keep);
|
||||
void http_async_add_header(void *ctx, char *name, char *data);
|
||||
int http_async_req_status(void *ctx);
|
||||
void http_async_get_length(void *ctx, int *total, int *done);
|
||||
char *http_async_req_stop(void *ctx, int *ret, int *len);
|
||||
void http_async_req_close(void *ctx);
|
||||
|
||||
char *http_multipart_post(char *uri, char **names, char **parts, int *plens, char *user, char *pass, char * session_id, int *ret, int *len);
|
||||
|
||||
char *http_ret_text(int ret);
|
||||
|
||||
#endif
|
231
src/client/MD5.cpp
Normal file
231
src/client/MD5.cpp
Normal file
@ -0,0 +1,231 @@
|
||||
// based on public-domain code from Colin Plumb (1993)
|
||||
#include <string.h>
|
||||
#include "MD5.h"
|
||||
|
||||
static unsigned getu32(const unsigned char *addr)
|
||||
{
|
||||
return (((((unsigned long)addr[3] << 8) | addr[2]) << 8) | addr[1]) << 8 | addr[0];
|
||||
}
|
||||
|
||||
static void putu32(unsigned data, unsigned char *addr)
|
||||
{
|
||||
addr[0] = (unsigned char)data;
|
||||
addr[1] = (unsigned char)(data >> 8);
|
||||
addr[2] = (unsigned char)(data >> 16);
|
||||
addr[3] = (unsigned char)(data >> 24);
|
||||
}
|
||||
|
||||
void md5_init(struct md5_context *ctx)
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
ctx->bits[0] = 0;
|
||||
ctx->bits[1] = 0;
|
||||
}
|
||||
|
||||
void md5_update(struct md5_context *ctx, unsigned char const *buf, unsigned len)
|
||||
{
|
||||
unsigned t;
|
||||
|
||||
// update bit count
|
||||
t = ctx->bits[0];
|
||||
if ((ctx->bits[0] = (t + ((unsigned)len << 3)) & 0xffffffff) < t)
|
||||
ctx->bits[1]++; // carry
|
||||
ctx->bits[1] += len >> 29;
|
||||
|
||||
t = (t >> 3) & 0x3f;
|
||||
|
||||
// use leading data to top up the buffer
|
||||
|
||||
if (t)
|
||||
{
|
||||
unsigned char *p = ctx->in + t;
|
||||
|
||||
t = 64-t;
|
||||
if (len < t)
|
||||
{
|
||||
memcpy(p, buf, len);
|
||||
return;
|
||||
}
|
||||
memcpy(p, buf, t);
|
||||
md5_transform(ctx->buf, ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
}
|
||||
|
||||
// following 64-byte chunks
|
||||
|
||||
while (len >= 64)
|
||||
{
|
||||
memcpy(ctx->in, buf, 64);
|
||||
md5_transform(ctx->buf, ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
// save rest of bytes for later
|
||||
|
||||
memcpy(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
void md5_final(unsigned char digest[16], struct md5_context *ctx)
|
||||
{
|
||||
unsigned count;
|
||||
unsigned char *p;
|
||||
|
||||
// #bytes mod64
|
||||
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||
|
||||
// first char of padding = 0x80
|
||||
p = ctx->in + count;
|
||||
*p++ = 0x80;
|
||||
|
||||
// calculate # of bytes to pad
|
||||
count = 64 - 1 - count;
|
||||
|
||||
// Pad out to 56 mod 64
|
||||
if (count < 8)
|
||||
{
|
||||
// we need to finish a whole block before padding
|
||||
memset(p, 0, count);
|
||||
md5_transform(ctx->buf, ctx->in);
|
||||
memset(ctx->in, 0, 56);
|
||||
}
|
||||
else
|
||||
{
|
||||
// just pad to 56 bytes
|
||||
memset(p, 0, count-8);
|
||||
}
|
||||
|
||||
// append length & final transform
|
||||
putu32(ctx->bits[0], ctx->in + 56);
|
||||
putu32(ctx->bits[1], ctx->in + 60);
|
||||
|
||||
md5_transform(ctx->buf, ctx->in);
|
||||
putu32(ctx->buf[0], digest);
|
||||
putu32(ctx->buf[1], digest + 4);
|
||||
putu32(ctx->buf[2], digest + 8);
|
||||
putu32(ctx->buf[3], digest + 12);
|
||||
memset(ctx, 0, sizeof(ctx));
|
||||
}
|
||||
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x )
|
||||
|
||||
void md5_transform(unsigned buf[4], const unsigned char inraw[64])
|
||||
{
|
||||
unsigned a, b, c, d;
|
||||
unsigned in[16];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
in[i] = getu32 (inraw + 4 * i);
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
static char hexChars[] = "0123456789abcdef";
|
||||
void md5_ascii(char *result, unsigned char const *buf, unsigned len)
|
||||
{
|
||||
struct md5_context md5;
|
||||
unsigned char hash[16];
|
||||
int i;
|
||||
|
||||
if (len==0)
|
||||
len = strlen((char *)buf);
|
||||
|
||||
md5_init(&md5);
|
||||
md5_update(&md5, buf, len);
|
||||
md5_final(hash, &md5);
|
||||
|
||||
for (i=0; i<16; i++)
|
||||
{
|
||||
result[i*2] = hexChars[(hash[i]>>4)&0xF];
|
||||
result[i*2+1] = hexChars[hash[i]&0x0F];
|
||||
}
|
||||
result[32] = 0;
|
||||
}
|
18
src/client/MD5.h
Normal file
18
src/client/MD5.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef MD5_H
|
||||
#define MD5_H
|
||||
|
||||
struct md5_context
|
||||
{
|
||||
unsigned buf[4];
|
||||
unsigned bits[2];
|
||||
unsigned char in[64];
|
||||
};
|
||||
|
||||
void md5_init(struct md5_context *context);
|
||||
void md5_update(struct md5_context *context, unsigned char const *buf, unsigned len);
|
||||
void md5_final(unsigned char digest[16], struct md5_context *context);
|
||||
void md5_transform(unsigned buf[4], const unsigned char in[64]);
|
||||
|
||||
void md5_ascii(char *result, unsigned char const *buf, unsigned len);
|
||||
|
||||
#endif
|
80
src/client/SaveFile.cpp
Normal file
80
src/client/SaveFile.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* SaveFile.cpp
|
||||
*
|
||||
* Created on: Jun 6, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#include "SaveFile.h"
|
||||
#include "GameSave.h"
|
||||
#include "Client.h"
|
||||
#include "search/Thumbnail.h"
|
||||
|
||||
SaveFile::SaveFile(SaveFile & save):
|
||||
gameSave(NULL),
|
||||
thumbnail(NULL),
|
||||
filename(save.filename),
|
||||
displayName(save.displayName)
|
||||
{
|
||||
if(save.gameSave)
|
||||
gameSave = new GameSave(*save.gameSave);
|
||||
if(save.thumbnail)
|
||||
thumbnail = new Thumbnail(*save.thumbnail);
|
||||
}
|
||||
|
||||
Thumbnail * SaveFile::GetThumbnail()
|
||||
{
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
void SaveFile::SetThumbnail(Thumbnail * thumb)
|
||||
{
|
||||
thumbnail = thumb;
|
||||
}
|
||||
|
||||
SaveFile::SaveFile(std::string filename):
|
||||
filename(filename),
|
||||
displayName(filename),
|
||||
gameSave(NULL),
|
||||
thumbnail(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
GameSave * SaveFile::GetGameSave()
|
||||
{
|
||||
return gameSave;
|
||||
}
|
||||
|
||||
void SaveFile::SetGameSave(GameSave * save)
|
||||
{
|
||||
gameSave = save;
|
||||
}
|
||||
|
||||
std::string SaveFile::GetName()
|
||||
{
|
||||
return filename;
|
||||
}
|
||||
|
||||
void SaveFile::SetFileName(std::string fileName)
|
||||
{
|
||||
this->filename = fileName;
|
||||
}
|
||||
|
||||
std::string SaveFile::GetDisplayName()
|
||||
{
|
||||
return displayName;
|
||||
}
|
||||
|
||||
void SaveFile::SetDisplayName(std::string displayName)
|
||||
{
|
||||
this->displayName = displayName;
|
||||
}
|
||||
|
||||
SaveFile::~SaveFile() {
|
||||
if(gameSave)
|
||||
delete gameSave;
|
||||
if(thumbnail)
|
||||
delete thumbnail;
|
||||
}
|
||||
|
38
src/client/SaveFile.h
Normal file
38
src/client/SaveFile.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* SaveFile.h
|
||||
*
|
||||
* Created on: Jun 6, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#ifndef SAVEFILE_H_
|
||||
#define SAVEFILE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
class GameSave;
|
||||
class Thumbnail;
|
||||
|
||||
class SaveFile {
|
||||
public:
|
||||
SaveFile(SaveFile & save);
|
||||
SaveFile(std::string filename);
|
||||
|
||||
Thumbnail * GetThumbnail();
|
||||
GameSave * GetGameSave();
|
||||
void SetThumbnail(Thumbnail * thumb);
|
||||
void SetGameSave(GameSave * save);
|
||||
std::string GetDisplayName();
|
||||
void SetDisplayName(std::string displayName);
|
||||
std::string GetName();
|
||||
void SetFileName(std::string fileName);
|
||||
|
||||
virtual ~SaveFile();
|
||||
private:
|
||||
Thumbnail * thumbnail;
|
||||
GameSave * gameSave;
|
||||
std::string filename;
|
||||
std::string displayName;
|
||||
};
|
||||
|
||||
#endif /* SAVEFILE_H_ */
|
128
src/client/SaveInfo.cpp
Normal file
128
src/client/SaveInfo.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Save.cpp
|
||||
*
|
||||
* Created on: Jan 26, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#include "SaveInfo.h"
|
||||
#include "GameSave.h"
|
||||
#include "Client.h"
|
||||
|
||||
SaveInfo::SaveInfo(SaveInfo & save) :
|
||||
userName(save.userName), name(save.name), Description(save.Description), date(
|
||||
save.date), Published(save.Published), id(save.id), votesUp(
|
||||
save.votesUp), votesDown(save.votesDown), gameSave(NULL), vote(save.vote), tags(save.tags), Comments(save.Comments), Views(save.Views), Version(save.Version) {
|
||||
if(save.gameSave)
|
||||
gameSave = new GameSave(*save.gameSave);
|
||||
}
|
||||
|
||||
SaveInfo::SaveInfo(int _id, int _date, int _votesUp, int _votesDown, std::string _userName,
|
||||
std::string _name) :
|
||||
id(_id), votesUp(_votesUp), votesDown(_votesDown), userName(_userName), name(
|
||||
_name), Description(""), date(_date), Published(
|
||||
true), gameSave(NULL), vote(0), tags(), Comments(0), Views(0), Version(0) {
|
||||
}
|
||||
|
||||
SaveInfo::SaveInfo(int _id, int date_, int _votesUp, int _votesDown, int _vote, std::string _userName,
|
||||
std::string _name, std::string description_, bool published_, std::vector<std::string> tags_) :
|
||||
id(_id), votesUp(_votesUp), votesDown(_votesDown), userName(_userName), name(
|
||||
_name), Description(description_), date(date_), Published(
|
||||
published_), gameSave(NULL), vote(_vote), tags(tags_), Views(0), Comments(0), Version(0) {
|
||||
}
|
||||
|
||||
SaveInfo::~SaveInfo()
|
||||
{
|
||||
if(gameSave)
|
||||
{
|
||||
delete gameSave;
|
||||
}
|
||||
}
|
||||
|
||||
void SaveInfo::SetName(std::string name) {
|
||||
this->name = name;
|
||||
}
|
||||
std::string SaveInfo::GetName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
void SaveInfo::SetDescription(std::string description) {
|
||||
Description = description;
|
||||
}
|
||||
std::string SaveInfo::GetDescription() {
|
||||
return Description;
|
||||
}
|
||||
|
||||
void SaveInfo::SetPublished(bool published) {
|
||||
Published = published;
|
||||
}
|
||||
|
||||
bool SaveInfo::GetPublished() {
|
||||
return Published;
|
||||
}
|
||||
|
||||
void SaveInfo::SetVote(int vote)
|
||||
{
|
||||
this->vote = vote;
|
||||
}
|
||||
int SaveInfo::GetVote()
|
||||
{
|
||||
return vote;
|
||||
}
|
||||
|
||||
void SaveInfo::SetUserName(std::string userName) {
|
||||
this->userName = userName;
|
||||
}
|
||||
|
||||
std::string SaveInfo::GetUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
void SaveInfo::SetID(int id) {
|
||||
this->id = id;
|
||||
}
|
||||
int SaveInfo::GetID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
void SaveInfo::SetVotesUp(int votesUp) {
|
||||
this->votesUp = votesUp;
|
||||
}
|
||||
int SaveInfo::GetVotesUp() {
|
||||
return votesUp;
|
||||
}
|
||||
|
||||
void SaveInfo::SetVotesDown(int votesDown) {
|
||||
this->votesDown = votesDown;
|
||||
}
|
||||
int SaveInfo::GetVotesDown() {
|
||||
return votesDown;
|
||||
}
|
||||
|
||||
void SaveInfo::SetVersion(int version) {
|
||||
this->Version = version;
|
||||
}
|
||||
int SaveInfo::GetVersion() {
|
||||
return Version;
|
||||
}
|
||||
|
||||
void SaveInfo::SetTags(std::vector<std::string> tags)
|
||||
{
|
||||
this->tags = tags;
|
||||
}
|
||||
std::vector<std::string> SaveInfo::GetTags()
|
||||
{
|
||||
return tags;
|
||||
}
|
||||
|
||||
GameSave * SaveInfo::GetGameSave()
|
||||
{
|
||||
return gameSave;
|
||||
}
|
||||
|
||||
void SaveInfo::SetGameSave(GameSave * saveGame)
|
||||
{
|
||||
if(gameSave)
|
||||
delete gameSave;
|
||||
gameSave = saveGame;
|
||||
}
|
78
src/client/SaveInfo.h
Normal file
78
src/client/SaveInfo.h
Normal file
@ -0,0 +1,78 @@
|
||||
#ifndef SAVE_H
|
||||
#define SAVE_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
|
||||
class GameSave;
|
||||
|
||||
class SaveInfo
|
||||
{
|
||||
private:
|
||||
public:
|
||||
int id;
|
||||
int date;
|
||||
int votesUp, votesDown;
|
||||
bool Favourite;
|
||||
int Comments;
|
||||
int Views;
|
||||
int Version;
|
||||
|
||||
GameSave * gameSave;
|
||||
|
||||
SaveInfo(SaveInfo & save);
|
||||
|
||||
SaveInfo(int _id, int _date, int _votesUp, int _votesDown, std::string _userName, std::string _name);
|
||||
|
||||
SaveInfo(int _id, int date_, int _votesUp, int _votesDown, int _vote, std::string _userName, std::string _name, std::string description_, bool published_, std::vector<std::string> tags);
|
||||
|
||||
~SaveInfo();
|
||||
|
||||
std::string userName;
|
||||
std::string name;
|
||||
|
||||
std::string Description;
|
||||
|
||||
std::vector<std::string> tags;
|
||||
|
||||
int vote;
|
||||
|
||||
bool Published;
|
||||
|
||||
void SetName(std::string name);
|
||||
std::string GetName();
|
||||
|
||||
void SetDescription(std::string description);
|
||||
std::string GetDescription();
|
||||
|
||||
void SetPublished(bool published);
|
||||
bool GetPublished();
|
||||
|
||||
void SetUserName(std::string userName);
|
||||
std::string GetUserName();
|
||||
|
||||
void SetID(int id);
|
||||
int GetID();
|
||||
|
||||
void SetVote(int vote);
|
||||
int GetVote();
|
||||
|
||||
void SetVotesUp(int votesUp);
|
||||
int GetVotesUp();
|
||||
|
||||
void SetVotesDown(int votesDown);
|
||||
int GetVotesDown();
|
||||
|
||||
void SetVersion(int version);
|
||||
int GetVersion();
|
||||
|
||||
void SetTags(std::vector<std::string> tags);
|
||||
std::vector<std::string> GetTags();
|
||||
|
||||
GameSave * GetGameSave();
|
||||
void SetGameSave(GameSave * gameSave);
|
||||
};
|
||||
|
||||
#endif // SAVE_H
|
347
src/client/ThumbnailBroker.cpp
Normal file
347
src/client/ThumbnailBroker.cpp
Normal file
@ -0,0 +1,347 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
#include "ThumbnailBroker.h"
|
||||
#include "ThumbnailListener.h"
|
||||
#include "Client.h"
|
||||
#include "HTTP.h"
|
||||
#include "GameSave.h"
|
||||
#include "search/Thumbnail.h"
|
||||
#include "simulation/SaveRenderer.h"
|
||||
|
||||
//Asynchronous Thumbnail render & request processing
|
||||
|
||||
ThumbnailBroker::ThumbnailBroker()
|
||||
{
|
||||
thumbnailQueueRunning = false;
|
||||
//thumbnailQueueMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_mutex_init (&thumbnailQueueMutex, NULL);
|
||||
|
||||
//listenersMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_mutex_init (&listenersMutex, NULL);
|
||||
}
|
||||
|
||||
ThumbnailBroker::~ThumbnailBroker()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ThumbnailBroker::RenderThumbnail(GameSave * gameSave, int width, int height, ThumbnailListener * tListener)
|
||||
{
|
||||
RenderThumbnail(gameSave, true, true, width, height, tListener);
|
||||
}
|
||||
|
||||
void ThumbnailBroker::RenderThumbnail(GameSave * gameSave, bool decorations, bool fire, int width, int height, ThumbnailListener * tListener)
|
||||
{
|
||||
AttachThumbnailListener(tListener);
|
||||
pthread_mutex_lock(&thumbnailQueueMutex);
|
||||
bool running = thumbnailQueueRunning;
|
||||
thumbnailQueueRunning = true;
|
||||
renderRequests.push_back(ThumbRenderRequest(new GameSave(*gameSave), decorations, fire, width, height, ListenerHandle(tListener->ListenerRand, tListener)));
|
||||
pthread_mutex_unlock(&thumbnailQueueMutex);
|
||||
|
||||
if(!running)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cout << typeid(*this).name() << " Starting background thread for new " << __FUNCTION__ << " request" << std::endl;
|
||||
#endif
|
||||
pthread_create(&thumbnailQueueThread, 0, &ThumbnailBroker::thumbnailQueueProcessHelper, this);
|
||||
}
|
||||
}
|
||||
|
||||
void ThumbnailBroker::RetrieveThumbnail(int saveID, int saveDate, int width, int height, ThumbnailListener * tListener)
|
||||
{
|
||||
AttachThumbnailListener(tListener);
|
||||
pthread_mutex_lock(&thumbnailQueueMutex);
|
||||
bool running = thumbnailQueueRunning;
|
||||
thumbnailQueueRunning = true;
|
||||
thumbnailRequests.push_back(ThumbnailRequest(saveID, saveDate, width, height, ListenerHandle(tListener->ListenerRand, tListener)));
|
||||
pthread_mutex_unlock(&thumbnailQueueMutex);
|
||||
|
||||
if(!running)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cout << typeid(*this).name() << " Starting background thread for new " << __FUNCTION__ << " request" << std::endl;
|
||||
#endif
|
||||
pthread_create(&thumbnailQueueThread, 0, &ThumbnailBroker::thumbnailQueueProcessHelper, this);
|
||||
}
|
||||
}
|
||||
|
||||
void * ThumbnailBroker::thumbnailQueueProcessHelper(void * ref)
|
||||
{
|
||||
((ThumbnailBroker*)ref)->thumbnailQueueProcessTH();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ThumbnailBroker::FlushThumbQueue()
|
||||
{
|
||||
pthread_mutex_lock(&thumbnailQueueMutex);
|
||||
while(thumbnailComplete.size())
|
||||
{
|
||||
if(CheckThumbnailListener(thumbnailComplete.front().first))
|
||||
{
|
||||
thumbnailComplete.front().first.second->OnThumbnailReady(thumbnailComplete.front().second);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cout << typeid(*this).name() << " Listener lost, discarding request" << std::endl;
|
||||
#endif
|
||||
delete thumbnailComplete.front().second;
|
||||
}
|
||||
thumbnailComplete.pop_front();
|
||||
}
|
||||
pthread_mutex_unlock(&thumbnailQueueMutex);
|
||||
}
|
||||
|
||||
void ThumbnailBroker::thumbnailQueueProcessTH()
|
||||
{
|
||||
time_t lastAction = time(NULL);
|
||||
while(true)
|
||||
{
|
||||
//Shutdown after 2 seconds of idle
|
||||
if(time(NULL) - lastAction > 2)
|
||||
{
|
||||
pthread_mutex_lock(&thumbnailQueueMutex);
|
||||
thumbnailQueueRunning = false;
|
||||
pthread_mutex_unlock(&thumbnailQueueMutex);
|
||||
break;
|
||||
}
|
||||
|
||||
//Renderer
|
||||
pthread_mutex_lock(&thumbnailQueueMutex);
|
||||
if(renderRequests.size())
|
||||
{
|
||||
lastAction = time(NULL);
|
||||
ThumbRenderRequest req;
|
||||
req = renderRequests.front();
|
||||
renderRequests.pop_front();
|
||||
pthread_mutex_unlock(&thumbnailQueueMutex);
|
||||
|
||||
#ifdef DEBUG
|
||||
std::cout << typeid(*this).name() << " Processing render request" << std::endl;
|
||||
#endif
|
||||
|
||||
Thumbnail * thumbnail = SaveRenderer::Ref().Render(req.Save, req.Decorations, req.Fire);
|
||||
delete req.Save;
|
||||
|
||||
if(thumbnail)
|
||||
{
|
||||
thumbnail->Resize(req.Width, req.Height);
|
||||
|
||||
pthread_mutex_lock(&thumbnailQueueMutex);
|
||||
thumbnailComplete.push_back(std::pair<ListenerHandle, Thumbnail*>(req.CompletedListener, thumbnail));
|
||||
pthread_mutex_unlock(&thumbnailQueueMutex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_mutex_unlock(&thumbnailQueueMutex);
|
||||
}
|
||||
|
||||
//Renderer
|
||||
pthread_mutex_lock(&thumbnailQueueMutex);
|
||||
if(thumbnailRequests.size())
|
||||
{
|
||||
lastAction = time(NULL);
|
||||
Thumbnail * thumbnail = NULL;
|
||||
|
||||
ThumbnailRequest req;
|
||||
req = thumbnailRequests.front();
|
||||
|
||||
//Check the cache
|
||||
for(std::deque<std::pair<ThumbnailID, Thumbnail*> >::iterator iter = thumbnailCache.begin(), end = thumbnailCache.end(); iter != end; ++iter)
|
||||
{
|
||||
if((*iter).first == req.ID)
|
||||
{
|
||||
thumbnail = (*iter).second;
|
||||
#ifdef DEBUG
|
||||
std::cout << typeid(*this).name() << " " << req.ID.SaveID << ":" << req.ID.SaveDate << " found in cache" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(thumbnail)
|
||||
{
|
||||
//Got thumbnail from cache
|
||||
thumbnailRequests.pop_front();
|
||||
pthread_mutex_unlock(&thumbnailQueueMutex);
|
||||
|
||||
for(std::vector<ThumbnailSpec>::iterator specIter = req.SubRequests.begin(), specEnd = req.SubRequests.end(); specIter != specEnd; ++specIter)
|
||||
{
|
||||
Thumbnail * tempThumbnail = new Thumbnail(*thumbnail);
|
||||
tempThumbnail->Resize((*specIter).Width, (*specIter).Height);
|
||||
|
||||
pthread_mutex_lock(&thumbnailQueueMutex);
|
||||
thumbnailComplete.push_back(std::pair<ListenerHandle, Thumbnail*>((*specIter).CompletedListener, tempThumbnail));
|
||||
pthread_mutex_unlock(&thumbnailQueueMutex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Check for ongoing requests
|
||||
bool requested = false;
|
||||
for(std::list<ThumbnailRequest>::iterator iter = currentRequests.begin(), end = currentRequests.end(); iter != end; ++iter)
|
||||
{
|
||||
if((*iter).ID == req.ID)
|
||||
{
|
||||
requested = true;
|
||||
|
||||
#ifdef DEBUG
|
||||
std::cout << typeid(*this).name() << " Request for " << req.ID.SaveID << ":" << req.ID.SaveDate << " found, appending." << std::endl;
|
||||
#endif
|
||||
|
||||
//Add the current listener to the item already being requested
|
||||
(*iter).SubRequests.push_back(req.SubRequests.front());
|
||||
}
|
||||
}
|
||||
|
||||
if(requested)
|
||||
{
|
||||
//Already requested
|
||||
thumbnailRequests.pop_front();
|
||||
pthread_mutex_unlock(&thumbnailQueueMutex);
|
||||
}
|
||||
else if(currentRequests.size() < IMGCONNS) //If it's not already being requested and we still have more space for a new connection, request it
|
||||
{
|
||||
thumbnailRequests.pop_front();
|
||||
pthread_mutex_unlock(&thumbnailQueueMutex);
|
||||
|
||||
//If it's not already being requested, request it
|
||||
std::stringstream urlStream;
|
||||
urlStream << "http://" << STATICSERVER << "/" << req.ID.SaveID;
|
||||
if(req.ID.SaveDate)
|
||||
{
|
||||
urlStream << "_" << req.ID.SaveDate;
|
||||
}
|
||||
urlStream << "_small.pti";
|
||||
|
||||
#ifdef DEBUG
|
||||
std::cout << typeid(*this).name() << " Creating new request for " << req.ID.SaveID << ":" << req.ID.SaveDate << std::endl;
|
||||
#endif
|
||||
|
||||
req.HTTPContext = http_async_req_start(NULL, (char *)urlStream.str().c_str(), NULL, 0, 1);
|
||||
req.RequestTime = time(NULL);
|
||||
currentRequests.push_back(req);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Already full of requests
|
||||
pthread_mutex_unlock(&thumbnailQueueMutex);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_mutex_unlock(&thumbnailQueueMutex);
|
||||
}
|
||||
|
||||
std::list<ThumbnailRequest>::iterator iter = currentRequests.begin();
|
||||
while (iter != currentRequests.end())
|
||||
{
|
||||
lastAction = time(NULL);
|
||||
|
||||
ThumbnailRequest req = *iter;
|
||||
Thumbnail * thumbnail = NULL;
|
||||
|
||||
if(http_async_req_status(req.HTTPContext))
|
||||
{
|
||||
|
||||
pixel * thumbData;
|
||||
char * data;
|
||||
int status, data_size, imgw, imgh;
|
||||
data = http_async_req_stop(req.HTTPContext, &status, &data_size);
|
||||
free(req.HTTPContext);
|
||||
|
||||
if (status == 200 && data)
|
||||
{
|
||||
thumbData = Graphics::ptif_unpack(data, data_size, &imgw, &imgh);
|
||||
free(data);
|
||||
|
||||
if(thumbData)
|
||||
{
|
||||
thumbnail = new Thumbnail(req.ID.SaveID, req.ID.SaveID, thumbData, ui::Point(imgw, imgh));
|
||||
free(thumbData);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Error thumbnail
|
||||
VideoBuffer errorThumb(128, 128);
|
||||
errorThumb.SetCharacter(64, 64, 'x', 255, 255, 255, 255);
|
||||
|
||||
thumbnail = new Thumbnail(req.ID.SaveID, req.ID.SaveID, errorThumb.Buffer, ui::Point(errorThumb.Width, errorThumb.Height));
|
||||
}
|
||||
|
||||
if(thumbnailCache.size() >= THUMB_CACHE_SIZE)
|
||||
{
|
||||
delete thumbnailCache.front().second;
|
||||
thumbnailCache.pop_front();
|
||||
}
|
||||
thumbnailCache.push_back(std::pair<ThumbnailID, Thumbnail*>(req.ID, thumbnail));
|
||||
|
||||
for(std::vector<ThumbnailSpec>::iterator specIter = req.SubRequests.begin(), specEnd = req.SubRequests.end(); specIter != specEnd; ++specIter)
|
||||
{
|
||||
Thumbnail * tempThumbnail = new Thumbnail(*thumbnail);
|
||||
tempThumbnail->Resize((*specIter).Width, (*specIter).Height);
|
||||
|
||||
pthread_mutex_lock(&thumbnailQueueMutex);
|
||||
thumbnailComplete.push_back(std::pair<ListenerHandle, Thumbnail*>((*specIter).CompletedListener, tempThumbnail));
|
||||
pthread_mutex_unlock(&thumbnailQueueMutex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cout << typeid(*this).name() << " Request for " << req.ID.SaveID << ":" << req.ID.SaveDate << " failed with status " << status << std::endl;
|
||||
#endif
|
||||
if(data)
|
||||
free(data);
|
||||
}
|
||||
iter = currentRequests.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ThumbnailBroker::RetrieveThumbnail(int saveID, int width, int height, ThumbnailListener * tListener)
|
||||
{
|
||||
RetrieveThumbnail(saveID, 0, width, height, tListener);
|
||||
}
|
||||
|
||||
bool ThumbnailBroker::CheckThumbnailListener(ListenerHandle handle)
|
||||
{
|
||||
pthread_mutex_lock(&listenersMutex);
|
||||
int count = std::count(validListeners.begin(), validListeners.end(), handle);
|
||||
pthread_mutex_unlock(&listenersMutex);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void ThumbnailBroker::AttachThumbnailListener(ThumbnailListener * tListener)
|
||||
{
|
||||
pthread_mutex_lock(&listenersMutex);
|
||||
validListeners.push_back(ListenerHandle(tListener->ListenerRand, tListener));
|
||||
pthread_mutex_unlock(&listenersMutex);
|
||||
}
|
||||
|
||||
void ThumbnailBroker::DetachThumbnailListener(ThumbnailListener * tListener)
|
||||
{
|
||||
pthread_mutex_lock(&listenersMutex);
|
||||
|
||||
std::vector<ListenerHandle>::iterator iter = validListeners.begin();
|
||||
while (iter != validListeners.end())
|
||||
{
|
||||
if(*iter == ListenerHandle(tListener->ListenerRand, tListener))
|
||||
iter = validListeners.erase(iter);
|
||||
else
|
||||
++iter;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&listenersMutex);
|
||||
}
|
108
src/client/ThumbnailBroker.h
Normal file
108
src/client/ThumbnailBroker.h
Normal file
@ -0,0 +1,108 @@
|
||||
#pragma once
|
||||
#include <queue>
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include <deque>
|
||||
#include <pthread.h>
|
||||
#undef GetUserName //God dammit microsoft!
|
||||
|
||||
#include "Singleton.h"
|
||||
|
||||
class GameSave;
|
||||
class Thumbnail;
|
||||
class ThumbnailListener;
|
||||
typedef std::pair<int, ThumbnailListener*> ListenerHandle;
|
||||
class ThumbnailBroker: public Singleton<ThumbnailBroker>
|
||||
{
|
||||
private:
|
||||
class ThumbnailSpec
|
||||
{
|
||||
public:
|
||||
int Width, Height;
|
||||
ListenerHandle CompletedListener;
|
||||
ThumbnailSpec(int width, int height, ListenerHandle completedListener) :
|
||||
Width(width), Height(height), CompletedListener(completedListener) {}
|
||||
};
|
||||
|
||||
class ThumbnailID
|
||||
{
|
||||
public:
|
||||
int SaveID, SaveDate;
|
||||
bool operator ==(const ThumbnailID & second)
|
||||
{
|
||||
return SaveID == second.SaveID && SaveDate == second.SaveDate;
|
||||
}
|
||||
ThumbnailID(int saveID, int saveDate) : SaveID(saveID), SaveDate(saveDate) {}
|
||||
ThumbnailID() : SaveID(0), SaveDate(0) {}
|
||||
};
|
||||
|
||||
class ThumbnailRequest
|
||||
{
|
||||
public:
|
||||
bool Complete;
|
||||
void * HTTPContext;
|
||||
int RequestTime;
|
||||
|
||||
ThumbnailID ID;
|
||||
std::vector<ThumbnailSpec> SubRequests;
|
||||
|
||||
ThumbnailRequest(int saveID, int saveDate, int width, int height, ListenerHandle completedListener) :
|
||||
ID(saveID, saveDate), Complete(false), HTTPContext(NULL), RequestTime(0)
|
||||
{
|
||||
SubRequests.push_back(ThumbnailSpec(width, height, completedListener));
|
||||
}
|
||||
ThumbnailRequest() : Complete(false), HTTPContext(NULL), RequestTime(0) {}
|
||||
};
|
||||
|
||||
class ThumbRenderRequest
|
||||
{
|
||||
public:
|
||||
int Width, Height;
|
||||
bool Decorations;
|
||||
bool Fire;
|
||||
GameSave * Save;
|
||||
ListenerHandle CompletedListener;
|
||||
ThumbRenderRequest(GameSave * save, bool decorations, bool fire, int width, int height, ListenerHandle completedListener) :
|
||||
Save(save), Width(width), Height(height), CompletedListener(completedListener), Decorations(decorations), Fire(fire) {}
|
||||
ThumbRenderRequest() : Save(0), Decorations(true), Fire(true), Width(0), Height(0), CompletedListener(ListenerHandle(0, (ThumbnailListener*)NULL)) {}
|
||||
};
|
||||
|
||||
//Thumbnail retreival
|
||||
/*int thumbnailCacheNextID;
|
||||
Thumbnail * thumbnailCache[THUMB_CACHE_SIZE];
|
||||
void * activeThumbRequests[IMGCONNS];
|
||||
int activeThumbRequestTimes[IMGCONNS];
|
||||
int activeThumbRequestCompleteTimes[IMGCONNS];
|
||||
std::string activeThumbRequestIDs[IMGCONNS];*/
|
||||
|
||||
pthread_mutex_t thumbnailQueueMutex;
|
||||
pthread_mutex_t listenersMutex;
|
||||
pthread_t thumbnailQueueThread;
|
||||
bool thumbnailQueueRunning;
|
||||
std::deque<ThumbnailRequest> thumbnailRequests;
|
||||
std::deque<ThumbRenderRequest> renderRequests;
|
||||
|
||||
std::deque<std::pair<ListenerHandle, Thumbnail*> > thumbnailComplete;
|
||||
std::list<ThumbnailRequest> currentRequests;
|
||||
std::deque<std::pair<ThumbnailID, Thumbnail*> > thumbnailCache;
|
||||
|
||||
|
||||
std::vector<ListenerHandle> validListeners;
|
||||
|
||||
static void * thumbnailQueueProcessHelper(void * ref);
|
||||
void thumbnailQueueProcessTH();
|
||||
|
||||
public:
|
||||
ThumbnailBroker();
|
||||
virtual ~ThumbnailBroker();
|
||||
|
||||
void FlushThumbQueue();
|
||||
void RenderThumbnail(GameSave * gameSave, bool decorations, bool fire, int width, int height, ThumbnailListener * tListener);
|
||||
void RenderThumbnail(GameSave * gameSave, int width, int height, ThumbnailListener * tListener);
|
||||
void RetrieveThumbnail(int saveID, int saveDate, int width, int height, ThumbnailListener * tListener);
|
||||
void RetrieveThumbnail(int saveID, int width, int height, ThumbnailListener * tListener);
|
||||
|
||||
bool CheckThumbnailListener(ListenerHandle handle);
|
||||
void AttachThumbnailListener(ThumbnailListener * tListener);
|
||||
void DetachThumbnailListener(ThumbnailListener * tListener);
|
||||
};
|
12
src/client/ThumbnailListener.h
Normal file
12
src/client/ThumbnailListener.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
class Thumbnail;
|
||||
class ThumbnailListener
|
||||
{
|
||||
public:
|
||||
int ListenerRand;
|
||||
ThumbnailListener() { ListenerRand = rand(); }
|
||||
virtual ~ThumbnailListener() {}
|
||||
|
||||
virtual void OnThumbnailReady(Thumbnail * thumb) {}
|
||||
};
|
38
src/client/User.h
Normal file
38
src/client/User.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* User.h
|
||||
*
|
||||
* Created on: Jan 25, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#ifndef USER_H_
|
||||
#define USER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
class User
|
||||
{
|
||||
public:
|
||||
enum Elevation
|
||||
{
|
||||
ElevationAdmin, ElevationModerator, ElevationNone
|
||||
};
|
||||
int ID;
|
||||
std::string Username;
|
||||
std::string SessionID;
|
||||
std::string SessionKey;
|
||||
Elevation UserElevation;
|
||||
User(int id, std::string username):
|
||||
ID(id),
|
||||
Username(username),
|
||||
SessionID(""),
|
||||
SessionKey(""),
|
||||
UserElevation(ElevationNone)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif /* USER_H_ */
|
311
src/colourpicker/ColourPickerActivity.cpp
Normal file
311
src/colourpicker/ColourPickerActivity.cpp
Normal file
@ -0,0 +1,311 @@
|
||||
/*
|
||||
* ElementSearchActivity.cpp
|
||||
*
|
||||
* Created on: Jun 24, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include "ColourPickerActivity.h"
|
||||
#include "interface/Textbox.h"
|
||||
#include "interface/Label.h"
|
||||
#include "interface/Keys.h"
|
||||
#include "game/Tool.h"
|
||||
#include "Style.h"
|
||||
#include "Format.h"
|
||||
#include "game/GameModel.h"
|
||||
|
||||
ColourPickerActivity::ColourPickerActivity(ui::Colour initialColour, ColourPickedCallback * callback) :
|
||||
WindowActivity(ui::Point(-1, -1), ui::Point(266, 175)),
|
||||
currentHue(0),
|
||||
currentSaturation(0),
|
||||
currentValue(0),
|
||||
mouseDown(false),
|
||||
valueMouseDown(false),
|
||||
callback(callback)
|
||||
{
|
||||
|
||||
class ColourChange : public ui::TextboxAction
|
||||
{
|
||||
ColourPickerActivity * a;
|
||||
public:
|
||||
ColourChange(ColourPickerActivity * a) : a(a) {}
|
||||
|
||||
void TextChangedCallback(ui::Textbox * sender)
|
||||
{
|
||||
int r, g, b, alpha;
|
||||
r = format::StringToNumber<int>(a->rValue->GetText());
|
||||
g = format::StringToNumber<int>(a->gValue->GetText());
|
||||
b = format::StringToNumber<int>(a->bValue->GetText());
|
||||
alpha = format::StringToNumber<int>(a->aValue->GetText());
|
||||
if (r > 255)
|
||||
r = 255;
|
||||
if (g > 255)
|
||||
g = 255;
|
||||
if (b > 255)
|
||||
b = 255;
|
||||
if (alpha > 255)
|
||||
alpha = 255;
|
||||
|
||||
RGB_to_HSV(r, g, b, &a->currentHue, &a->currentSaturation, &a->currentValue);
|
||||
a->currentAlpha = alpha;
|
||||
a->UpdateTextboxes(r, g, b, alpha);
|
||||
}
|
||||
};
|
||||
|
||||
rValue = new ui::Textbox(ui::Point(5, Size.Y-23), ui::Point(30, 17), "255");
|
||||
rValue->SetActionCallback(new ColourChange(this));
|
||||
rValue->SetLimit(3);
|
||||
rValue->SetInputType(ui::Textbox::Number);
|
||||
AddComponent(rValue);
|
||||
|
||||
gValue = new ui::Textbox(ui::Point(40, Size.Y-23), ui::Point(30, 17), "255");
|
||||
gValue->SetActionCallback(new ColourChange(this));
|
||||
gValue->SetLimit(3);
|
||||
gValue->SetInputType(ui::Textbox::Number);
|
||||
AddComponent(gValue);
|
||||
|
||||
bValue = new ui::Textbox(ui::Point(75, Size.Y-23), ui::Point(30, 17), "255");
|
||||
bValue->SetActionCallback(new ColourChange(this));
|
||||
bValue->SetLimit(3);
|
||||
bValue->SetInputType(ui::Textbox::Number);
|
||||
AddComponent(bValue);
|
||||
|
||||
aValue = new ui::Textbox(ui::Point(110, Size.Y-23), ui::Point(30, 17), "255");
|
||||
aValue->SetActionCallback(new ColourChange(this));
|
||||
aValue->SetLimit(3);
|
||||
aValue->SetInputType(ui::Textbox::Number);
|
||||
AddComponent(aValue);
|
||||
|
||||
hexValue = new::ui::Label(ui::Point(150, Size.Y-23), ui::Point(53, 17), "0xFFFFFFFF");
|
||||
AddComponent(hexValue);
|
||||
|
||||
class OkayAction: public ui::ButtonAction
|
||||
{
|
||||
ColourPickerActivity * a;
|
||||
public:
|
||||
OkayAction(ColourPickerActivity * a) : a(a) { }
|
||||
void ActionCallback(ui::Button * sender)
|
||||
{
|
||||
int Red, Green, Blue;
|
||||
Red = format::StringToNumber<int>(a->rValue->GetText());
|
||||
Green = format::StringToNumber<int>(a->gValue->GetText());
|
||||
Blue = format::StringToNumber<int>(a->bValue->GetText());
|
||||
ui::Colour col(Red, Green, Blue, a->currentAlpha);
|
||||
if(a->callback)
|
||||
a->callback->ColourPicked(col);
|
||||
a->Exit();
|
||||
}
|
||||
};
|
||||
|
||||
ui::Button * doneButton = new ui::Button(ui::Point(Size.X-45, Size.Y-23), ui::Point(40, 17), "Done");
|
||||
doneButton->SetActionCallback(new OkayAction(this));
|
||||
AddComponent(doneButton);
|
||||
SetOkayButton(doneButton);
|
||||
|
||||
RGB_to_HSV(initialColour.Red, initialColour.Green, initialColour.Blue, ¤tHue, ¤tSaturation, ¤tValue);
|
||||
currentAlpha = initialColour.Alpha;
|
||||
UpdateTextboxes(initialColour.Red, initialColour.Green, initialColour.Blue, initialColour.Alpha);
|
||||
}
|
||||
|
||||
void ColourPickerActivity::UpdateTextboxes(int r, int g, int b, int a)
|
||||
{
|
||||
rValue->SetText(format::NumberToString<int>(r));
|
||||
gValue->SetText(format::NumberToString<int>(g));
|
||||
bValue->SetText(format::NumberToString<int>(b));
|
||||
aValue->SetText(format::NumberToString<int>(a));
|
||||
std::stringstream hex;
|
||||
hex << std::hex << "0x" << std::setfill('0') << std::setw(2) << std::uppercase << a << std::setw(2) << r << std::setw(2) << g << std::setw(2) << b;
|
||||
hexValue->SetText(hex.str());
|
||||
}
|
||||
void ColourPickerActivity::OnTryExit(ExitMethod method)
|
||||
{
|
||||
Exit();
|
||||
}
|
||||
|
||||
void ColourPickerActivity::OnMouseMove(int x, int y, int dx, int dy)
|
||||
{
|
||||
if(mouseDown)
|
||||
{
|
||||
x -= Position.X+5;
|
||||
y -= Position.Y+5;
|
||||
|
||||
currentHue = (float(x)/float(255))*359.0f;
|
||||
currentSaturation = 255-(y*2);
|
||||
|
||||
if(currentSaturation > 255)
|
||||
currentSaturation = 255;
|
||||
if(currentSaturation < 0)
|
||||
currentSaturation = 0;
|
||||
if(currentHue > 359)
|
||||
currentHue = 359;
|
||||
if(currentHue < 0)
|
||||
currentHue = 0;
|
||||
}
|
||||
|
||||
if(valueMouseDown)
|
||||
{
|
||||
x -= Position.X+5;
|
||||
y -= Position.Y+5;
|
||||
|
||||
currentValue = x;
|
||||
|
||||
if(currentValue > 255)
|
||||
currentValue = 255;
|
||||
if(currentValue < 0)
|
||||
currentValue = 0;
|
||||
}
|
||||
|
||||
if(mouseDown || valueMouseDown)
|
||||
{
|
||||
int cr, cg, cb;
|
||||
HSV_to_RGB(currentHue, currentSaturation, currentValue, &cr, &cg, &cb);
|
||||
UpdateTextboxes(cr, cg, cb, currentAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
void ColourPickerActivity::OnMouseDown(int x, int y, unsigned button)
|
||||
{
|
||||
x -= Position.X+5;
|
||||
y -= Position.Y+5;
|
||||
if(x >= 0 && x <= 256 && y >= 0 && y < 127)
|
||||
{
|
||||
mouseDown = true;
|
||||
currentHue = (float(x)/float(255))*359.0f;
|
||||
currentSaturation = 255-(y*2);
|
||||
|
||||
if(currentSaturation > 255)
|
||||
currentSaturation = 255;
|
||||
if(currentSaturation < 0)
|
||||
currentSaturation = 0;
|
||||
if(currentHue > 359)
|
||||
currentHue = 359;
|
||||
if(currentHue < 0)
|
||||
currentHue = 0;
|
||||
}
|
||||
|
||||
if(x >= 0 && x <= 256 && y >= 131 && y < 142)
|
||||
{
|
||||
valueMouseDown = true;
|
||||
currentValue = x;
|
||||
|
||||
if(currentValue > 255)
|
||||
currentValue = 255;
|
||||
if(currentValue < 0)
|
||||
currentValue = 0;
|
||||
}
|
||||
|
||||
if(mouseDown || valueMouseDown)
|
||||
{
|
||||
int cr, cg, cb;
|
||||
HSV_to_RGB(currentHue, currentSaturation, currentValue, &cr, &cg, &cb);
|
||||
UpdateTextboxes(cr, cg, cb, currentAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
void ColourPickerActivity::OnMouseUp(int x, int y, unsigned button)
|
||||
{
|
||||
if(mouseDown || valueMouseDown)
|
||||
{
|
||||
int cr, cg, cb;
|
||||
HSV_to_RGB(currentHue, currentSaturation, currentValue, &cr, &cg, &cb);
|
||||
UpdateTextboxes(cr, cg, cb, currentAlpha);
|
||||
}
|
||||
|
||||
if(mouseDown)
|
||||
{
|
||||
mouseDown = false;
|
||||
x -= Position.X+5;
|
||||
y -= Position.Y+5;
|
||||
|
||||
currentHue = (float(x)/float(255))*359.0f;
|
||||
currentSaturation = 255-(y*2);
|
||||
|
||||
if(currentSaturation > 255)
|
||||
currentSaturation = 255;
|
||||
if(currentSaturation < 0)
|
||||
currentSaturation = 0;
|
||||
if(currentHue > 359)
|
||||
currentHue = 359;
|
||||
if(currentHue < 0)
|
||||
currentHue = 0;
|
||||
}
|
||||
|
||||
if(valueMouseDown)
|
||||
{
|
||||
valueMouseDown = false;
|
||||
|
||||
x -= Position.X+5;
|
||||
y -= Position.Y+5;
|
||||
|
||||
currentValue = x;
|
||||
|
||||
if(currentValue > 255)
|
||||
currentValue = 255;
|
||||
if(currentValue < 0)
|
||||
currentValue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ColourPickerActivity::OnDraw()
|
||||
{
|
||||
Graphics * g = ui::Engine::Ref().g;
|
||||
//g->clearrect(Position.X-2, Position.Y-2, Size.X+3, Size.Y+3);
|
||||
g->fillrect(Position.X-2, Position.Y-2, Size.X+3, Size.Y+3, 0, 0, 0, currentAlpha);
|
||||
g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 255, 255, 255, 255);
|
||||
|
||||
g->drawrect(Position.X+4, Position.Y+4, 258, 130, 180, 180, 180, 255);
|
||||
|
||||
g->drawrect(Position.X+4, Position.Y+4+4+128, 258, 12, 180, 180, 180, 255);
|
||||
|
||||
|
||||
int offsetX = Position.X+5;
|
||||
int offsetY = Position.Y+5;
|
||||
|
||||
|
||||
//draw color square
|
||||
int lastx = -1, currx = 0;
|
||||
for(int saturation = 0; saturation <= 255; saturation+=2)
|
||||
{
|
||||
for(int hue = 0; hue <= 359; hue++)
|
||||
{
|
||||
currx = clamp_flt(hue, 0, 359)+offsetX;
|
||||
if (currx == lastx)
|
||||
continue;
|
||||
lastx = currx;
|
||||
int cr = 0;
|
||||
int cg = 0;
|
||||
int cb = 0;
|
||||
HSV_to_RGB(hue, 255-saturation, currentValue, &cr, &cg, &cb);
|
||||
g->blendpixel(currx, (saturation/2)+offsetY, cr, cg, cb, currentAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
//draw brightness bar
|
||||
for(int value = 0; value <= 255; value++)
|
||||
for(int i = 0; i < 10; i++)
|
||||
{
|
||||
int cr = 0;
|
||||
int cg = 0;
|
||||
int cb = 0;
|
||||
HSV_to_RGB(currentHue, currentSaturation, value, &cr, &cg, &cb);
|
||||
|
||||
g->blendpixel(value+offsetX, i+offsetY+127+5, cr, cg, cb, currentAlpha);
|
||||
}
|
||||
|
||||
int currentHueX = clamp_flt(currentHue, 0, 359);
|
||||
int currentSaturationY = ((255-currentSaturation)/2);
|
||||
g->xor_line(offsetX+currentHueX, offsetY+currentSaturationY-5, offsetX+currentHueX, offsetY+currentSaturationY+5);
|
||||
g->xor_line(offsetX+currentHueX-5, offsetY+currentSaturationY, offsetX+currentHueX+5, offsetY+currentSaturationY);
|
||||
|
||||
g->xor_line(offsetX+currentValue, offsetY+4+128, offsetX+currentValue, offsetY+13+128);
|
||||
g->xor_line(offsetX+currentValue+1, offsetY+4+128, offsetX+currentValue+1, offsetY+13+128);
|
||||
}
|
||||
|
||||
ColourPickerActivity::~ColourPickerActivity() {
|
||||
if(callback)
|
||||
delete callback;
|
||||
}
|
||||
|
43
src/colourpicker/ColourPickerActivity.h
Normal file
43
src/colourpicker/ColourPickerActivity.h
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "Activity.h"
|
||||
#include "interface/Window.h"
|
||||
#include "interface/Textbox.h"
|
||||
|
||||
class ColourPickedCallback
|
||||
{
|
||||
public:
|
||||
ColourPickedCallback() {}
|
||||
virtual ~ColourPickedCallback() {}
|
||||
virtual void ColourPicked(ui::Colour colour) {}
|
||||
};
|
||||
|
||||
class ColourPickerActivity: public WindowActivity {
|
||||
int currentHue;
|
||||
int currentSaturation;
|
||||
int currentValue;
|
||||
int currentAlpha;
|
||||
|
||||
bool mouseDown;
|
||||
bool valueMouseDown;
|
||||
|
||||
ui::Textbox * rValue;
|
||||
ui::Textbox * gValue;
|
||||
ui::Textbox * bValue;
|
||||
ui::Textbox * aValue;
|
||||
ui::Label * hexValue;
|
||||
|
||||
ColourPickedCallback * callback;
|
||||
|
||||
void UpdateTextboxes(int r, int g, int b, int a);
|
||||
public:
|
||||
virtual void OnMouseMove(int x, int y, int dx, int dy);
|
||||
virtual void OnMouseDown(int x, int y, unsigned button);
|
||||
virtual void OnMouseUp(int x, int y, unsigned button);
|
||||
virtual void OnTryExit(ExitMethod method);
|
||||
ColourPickerActivity(ui::Colour initialColour, ColourPickedCallback * callback = NULL);
|
||||
virtual ~ColourPickerActivity();
|
||||
virtual void OnDraw();
|
||||
};
|
30
src/console/ConsoleCommand.h
Normal file
30
src/console/ConsoleCommand.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* ConsoleCommand.h
|
||||
*
|
||||
* Created on: Feb 1, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#ifndef CONSOLECOMMAND_H_
|
||||
#define CONSOLECOMMAND_H_
|
||||
|
||||
class ConsoleCommand
|
||||
{
|
||||
public:
|
||||
ConsoleCommand(std::string command, int returnStatus, std::string returnValue):
|
||||
Command(command), ReturnStatus(returnStatus), ReturnValue(returnValue)
|
||||
{
|
||||
|
||||
}
|
||||
std::string Command;
|
||||
int ReturnStatus;
|
||||
std::string ReturnValue;
|
||||
|
||||
operator std::string() const
|
||||
{
|
||||
return Command;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif /* CONSOLECOMMAND_H_ */
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user