From 8b5037a6470762c73ca6f5e1e9bb5566f805e948 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Fri, 11 Oct 2013 15:02:53 +0200 Subject: [PATCH] Launcher, based on PickleLauncher --- source/mupen64launcher/Makefile | 125 + source/mupen64launcher/docs/COPYING.TXT | 675 +++++ .../docs/DejaVu Fonts License.txt | 97 + .../mupen64launcher/docs/MiniZip64_info.txt | 74 + .../docs/PickleLauncher_README.txt | 33 + source/mupen64launcher/src/cbase.cpp | 359 +++ source/mupen64launcher/src/cbase.h | 184 ++ source/mupen64launcher/src/cconfig.cpp | 510 ++++ source/mupen64launcher/src/cconfig.h | 449 +++ source/mupen64launcher/src/cprofile.cpp | 1353 +++++++++ source/mupen64launcher/src/cprofile.h | 313 ++ source/mupen64launcher/src/cselector.cpp | 2678 +++++++++++++++++ source/mupen64launcher/src/cselector.h | 350 +++ source/mupen64launcher/src/csystem.cpp | 104 + source/mupen64launcher/src/csystem.h | 81 + source/mupen64launcher/src/czip.cpp | 456 +++ source/mupen64launcher/src/czip.h | 99 + source/mupen64launcher/src/main.cpp | 35 + source/mupen64launcher/src/main.h | 48 + source/mupen64launcher/src/unzip/ioapi.c | 235 ++ source/mupen64launcher/src/unzip/ioapi.h | 200 ++ source/mupen64launcher/src/unzip/unzip.c | 2125 +++++++++++++ source/mupen64launcher/src/unzip/unzip.h | 437 +++ source/mupen64launcher/src/version.h | 31 + 24 files changed, 11051 insertions(+) create mode 100755 source/mupen64launcher/Makefile create mode 100755 source/mupen64launcher/docs/COPYING.TXT create mode 100755 source/mupen64launcher/docs/DejaVu Fonts License.txt create mode 100755 source/mupen64launcher/docs/MiniZip64_info.txt create mode 100755 source/mupen64launcher/docs/PickleLauncher_README.txt create mode 100755 source/mupen64launcher/src/cbase.cpp create mode 100755 source/mupen64launcher/src/cbase.h create mode 100755 source/mupen64launcher/src/cconfig.cpp create mode 100755 source/mupen64launcher/src/cconfig.h create mode 100755 source/mupen64launcher/src/cprofile.cpp create mode 100755 source/mupen64launcher/src/cprofile.h create mode 100755 source/mupen64launcher/src/cselector.cpp create mode 100755 source/mupen64launcher/src/cselector.h create mode 100644 source/mupen64launcher/src/csystem.cpp create mode 100644 source/mupen64launcher/src/csystem.h create mode 100755 source/mupen64launcher/src/czip.cpp create mode 100755 source/mupen64launcher/src/czip.h create mode 100755 source/mupen64launcher/src/main.cpp create mode 100755 source/mupen64launcher/src/main.h create mode 100755 source/mupen64launcher/src/unzip/ioapi.c create mode 100755 source/mupen64launcher/src/unzip/ioapi.h create mode 100755 source/mupen64launcher/src/unzip/unzip.c create mode 100755 source/mupen64launcher/src/unzip/unzip.h create mode 100755 source/mupen64launcher/src/version.h diff --git a/source/mupen64launcher/Makefile b/source/mupen64launcher/Makefile new file mode 100755 index 0000000..50a8a4c --- /dev/null +++ b/source/mupen64launcher/Makefile @@ -0,0 +1,125 @@ +# Picklelauncher makefile + +PROGRAM = mupen64launcher +LIB_ZIP = libunzip.a + +# Build type +#BUILDTYPE = debug +BUILDTYPE = release +BUILDTARGET = PANDORA + +# Compiler flags +CXXFLAGS ?= -g -Wall -Wextra -O3 +ZIP_CFLAGS = $(CXXFLAGS) +# Linker flags +BASE_LDFLAGS = -L$(LIBRARY) -lSDL_ttf -lSDL_image -lSDL +ZIP_LDFLAGS = -L$(LIBRARY) -lz + +# Target compiler options +ifeq ($(BUILDTARGET),PANDORA) +PREFIX = /mnt/utmp/codeblocks +TOOLS = usr/bin +TARGET = +INCLUDE = $(PREFIX)/usr/include +LIBRARY = $(PREFIX)/usr/lib +CXXFLAGS += -DPANDORA +LDFLAGS = $(BASE_LDFLAGS) -lfreetype -ltiff -lpng12 -lz -ljpeg -lts +else +ifeq ($(BUILDTARGET),CAANOO) +PREFIX = /data/devel/toolchains/caanoo/GPH_SDK +TOOLS = tools/gcc-4.2.4-glibc-2.7-eabi/bin +TARGET = arm-gph-linux-gnueabi- +INCLUDE = $(PREFIX)/DGE/include +LIBRARY = $(PREFIX)/DGE/lib/target +CXXFLAGS += -DCAANOO +LDFLAGS = $(BASE_LDFLAGS) +else +ifeq ($(BUILDTARGET),WIZ) +PREFIX = /data/devel/toolchains/openwiz/arm-openwiz-linux-gnu +TOOLS = bin +TARGET = arm-openwiz-linux-gnu- +INCLUDE = $(PREFIX)/include +LIBRARY = $(PREFIX)/lib +CXXFLAGS += -DWIZ +LDFLAGS = $(BASE_LDFLAGS) -lfreetype -lz +else +ifeq ($(BUILDTARGET),GP2X) +PREFIX = /data/devel/toolchains/open2x/gcc-4.1.1-glibc-2.3.6 +TOOLS = bin +TARGET = arm-open2x-linux- +INCLUDE = $(PREFIX)/include +LIBRARY = $(PREFIX)/lib +CXXFLAGS += -DGP2X +LDFLAGS = -static $(BASE_LDFLAGS) -lfreetype -lz -lpng12 -lpthread -ldl +else +ifeq ($(BUILDTARGET),GCW) +PREFIX = /data/devel/toolchains/gcw_mips/buildroot/output/host/usr +TOOLS = bin +TARGET = mipsel-gcw0-linux-uclibc- +INCLUDE = $(PREFIX)/mipsel-gcw0-linux-uclibc/sysroot/usr/include +LIBRARY = $(PREFIX)/mipsel-gcw0-linux-uclibc/sysroot/usr/lib +CXXFLAGS += -DGCW +LDFLAGS = $(BASE_LDFLAGS) -lz -lpthread +else # default linux +PREFIX = /usr +TOOLS = bin +TARGET = +INCLUDE = $(PREFIX)/include +LIBRARY = $(PREFIX)/lib +LDFLAGS = $(BASE_LDFLAGS) +endif +endif +endif +endif +endif + +# Assign includes +CXXFLAGS += -I$(INCLUDE) -I$(INCLUDE)/SDL + +ifeq ($(BUILDTYPE),debug) +CXXFLAGS += -DDEBUG +endif + +# Source files +SRCS = main.cpp cselector.cpp cprofile.cpp cconfig.cpp csystem.cpp czip.cpp cbase.cpp +SRCS_ZIP = ioapi.c unzip.c + +# Assign paths to binaries/sources/objects +BUILD = build +SRCDIR = src +SRCDIR_ZIP = $(SRCDIR)/unzip +OBJDIR = $(BUILD)/objs/$(BUILDTYPE) + +SRCS := $(addprefix $(SRCDIR)/,$(SRCS)) +OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) +SRCS_ZIP := $(addprefix $(SRCDIR_ZIP)/,$(SRCS_ZIP)) +OBJS_ZIP := $(addprefix $(OBJDIR)/,$(SRCS_ZIP:.c=.o)) + +LIB_ZIP := $(addprefix $(OBJDIR)/,$(LIB_ZIP)) +PROGRAM := $(addprefix $(BUILD)/,$(PROGRAM)) + +# Assign Tools +CC = $(PREFIX)/$(TOOLS)/$(TARGET)gcc +CXX = $(PREFIX)/$(TOOLS)/$(TARGET)g++ +AR = $(PREFIX)/$(TOOLS)/$(TARGET)ar + +# Build rules +all : setup $(LIB_ZIP) $(PROGRAM) + +setup: + mkdir -p $(OBJDIR)/$(SRCDIR_ZIP) + +$(LIB_ZIP): $(OBJS_ZIP) + $(AR) rcs $(LIB_ZIP) $(OBJS_ZIP) + +$(PROGRAM): $(OBJS) + $(CXX) $(CXXFLAGS) -o $(PROGRAM) $(OBJS) $(LIB_ZIP) $(LDFLAGS) + +$(OBJDIR)/$(SRCDIR_ZIP)/%.o: $(SRCDIR_ZIP)/%.c + $(CC) $(ZIP_CFLAGS) -c $< -o $@ + +$(OBJDIR)/$(SRCDIR)/%.o: $(SRCDIR)/%.cpp + $(CXX) $(CXXFLAGS) -c $< -o $@ + +clean: + rm -f $(PROGRAM) $(OBJS) $(LIB_ZIP) $(OBJS_ZIP) diff --git a/source/mupen64launcher/docs/COPYING.TXT b/source/mupen64launcher/docs/COPYING.TXT new file mode 100755 index 0000000..36c78ad --- /dev/null +++ b/source/mupen64launcher/docs/COPYING.TXT @@ -0,0 +1,675 @@ + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + 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. + + + Copyright (C) + + 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 . + +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: + + Copyright (C) + 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 +. + + 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 +. diff --git a/source/mupen64launcher/docs/DejaVu Fonts License.txt b/source/mupen64launcher/docs/DejaVu Fonts License.txt new file mode 100755 index 0000000..6939980 --- /dev/null +++ b/source/mupen64launcher/docs/DejaVu Fonts License.txt @@ -0,0 +1,97 @@ +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. +Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) + +Bitstream Vera Fonts Copyright +------------------------------ + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is +a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license ("Fonts") and associated +documentation files (the "Font Software"), to reproduce and distribute the +Font Software, including without limitation the rights to use, copy, merge, +publish, distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to the +following conditions: + +The above copyright and trademark notices and this permission notice shall +be included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional glyphs or characters may be added to the Fonts, only if the fonts +are renamed to names not containing either the words "Bitstream" or the word +"Vera". + +This License becomes null and void to the extent applicable to Fonts or Font +Software that has been modified and is distributed under the "Bitstream +Vera" names. + +The Font Software may be sold as part of a larger software package but no +copy of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING +ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE +FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font Software +without prior written authorization from the Gnome Foundation or Bitstream +Inc., respectively. For further information, contact: fonts at gnome dot +org. + +Arev Fonts Copyright +------------------------------ + +Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license ("Fonts") and +associated documentation files (the "Font Software"), to reproduce +and distribute the modifications to the Bitstream Vera Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to +the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words "Tavmjong Bah" or the word "Arev". + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +"Tavmjong Bah Arev" names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the name of Tavmjong Bah shall not +be used in advertising or otherwise to promote the sale, use or other +dealings in this Font Software without prior written authorization +from Tavmjong Bah. For further information, contact: tavmjong @ free +. fr. \ No newline at end of file diff --git a/source/mupen64launcher/docs/MiniZip64_info.txt b/source/mupen64launcher/docs/MiniZip64_info.txt new file mode 100755 index 0000000..57d7152 --- /dev/null +++ b/source/mupen64launcher/docs/MiniZip64_info.txt @@ -0,0 +1,74 @@ +MiniZip - Copyright (c) 1998-2010 - by Gilles Vollant - version 1.1 64 bits from Mathias Svensson + +Introduction +--------------------- +MiniZip 1.1 is built from MiniZip 1.0 by Gilles Vollant ( http://www.winimage.com/zLibDll/minizip.html ) + +When adding ZIP64 support into minizip it would result into risk of breaking compatibility with minizip 1.0. +All possible work was done for compatibility. + + +Background +--------------------- +When adding ZIP64 support Mathias Svensson found that Even Rouault have added ZIP64 +support for unzip.c into minizip for a open source project called gdal ( http://www.gdal.org/ ) + +That was used as a starting point. And after that ZIP64 support was added to zip.c +some refactoring and code cleanup was also done. + + +Changed from MiniZip 1.0 to MiniZip 1.1 +--------------------------------------- +* Added ZIP64 support for unzip ( by Even Rouault ) +* Added ZIP64 support for zip ( by Mathias Svensson ) +* Reverted some changed that Even Rouault did. +* Bunch of patches received from Gulles Vollant that he received for MiniZip from various users. +* Added unzip patch for BZIP Compression method (patch create by Daniel Borca) +* Added BZIP Compress method for zip +* Did some refactoring and code cleanup + + +Credits + + Gilles Vollant - Original MiniZip author + Even Rouault - ZIP64 unzip Support + Daniel Borca - BZip Compression method support in unzip + Mathias Svensson - ZIP64 zip support + Mathias Svensson - BZip Compression method support in zip + + Resources + + ZipLayout http://result42.com/projects/ZipFileLayout + Command line tool for Windows that shows the layout and information of the headers in a zip archive. + Used when debugging and validating the creation of zip files using MiniZip64 + + + ZIP App Note http://www.pkware.com/documents/casestudies/APPNOTE.TXT + Zip File specification + + +Notes. + * To be able to use BZip compression method in zip64.c or unzip64.c the BZIP2 lib is needed and HAVE_BZIP2 need to be defined. + +License +---------------------------------------------------------- + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +---------------------------------------------------------- + diff --git a/source/mupen64launcher/docs/PickleLauncher_README.txt b/source/mupen64launcher/docs/PickleLauncher_README.txt new file mode 100755 index 0000000..d396c68 --- /dev/null +++ b/source/mupen64launcher/docs/PickleLauncher_README.txt @@ -0,0 +1,33 @@ +PickleLauncher + by Scott Smith (Pickle) Copyright (C) 2010-2011 + +Summary: + PickleLauncher is meant to a simple frontend for auto-detecting and configuring + command line based applications that might have different input files, like emulators. + +How it works: + PickleLauncher looks for its configuration from the config.txt and profile.txt. + profile.txt specifies location, file types, commands, arguments, and entries. + config.txt contains options for the application gui and input. + +License and Redistribution: + PickleLauncher source code is released under gplv3 see COPYING.txt for license details. + If you do redistribute I humbly request that all documentation is included. + +Contributions: + Patches and suggestions for improvements are welcome. + +References: + DejaVu font is Copyright (C) by Bitstream Vera Fonts (if included) see "DejaVu Fonts License.txt" for license details + Zip support uses minizip by Gilles Vollant and Mathias Svensson see "MiniZip64_info.txt" for license details + Portions of the exec support was based on Gmenu2x by Massimiliano Torromeo which is released under gplv2 see + http://github.com/mtorromeo/gmenu2x/blob/master/COPYING for license details + +Library Dependencies: + zlib + SDL + SDL_ttf + SDL_image + +For More Detailed Information and Instructions for Setup: +http://pandorawiki.org/PickleLauncher \ No newline at end of file diff --git a/source/mupen64launcher/src/cbase.cpp b/source/mupen64launcher/src/cbase.cpp new file mode 100755 index 0000000..85d5d69 --- /dev/null +++ b/source/mupen64launcher/src/cbase.cpp @@ -0,0 +1,359 @@ +/** + * @section LICENSE + * + * PickleLauncher + * Copyright (C) 2010-2011 Scott Smith + * + * 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 . + * + * @section LOCATION + */ + +#include "cbase.h" + +CBase::CBase() +{ +} + +CBase::~CBase() +{ +} + +void CBase::Log( const char* output, ... ) +{ + va_list fmtargs; + char buffer[1024]; + + va_start( fmtargs, output ); + vsnprintf( buffer, sizeof(buffer)-1, output, fmtargs ); + va_end( fmtargs ); + + fprintf( stdout, "%s", buffer ); + +#if defined(DEBUG) + FILE* fout = fopen( "log.txt", "a" ); + if (!fout) + { + printf( "Failed to open logfile\n" ); + return; + } + fputs(buffer, fout); + fclose(fout); +#endif +} + +uint32_t CBase::CheckRange( int32_t value, int32_t size ) +{ + if (value >= 0 && value < size) + { + return 1; + } + else + { + return 0; + } +} + +uint32_t CBase::rgb_to_int( SDL_Color color ) +{ + return SDL_MapRGB(SDL_GetVideoSurface()->format, color.r, color.g, color.b); +} + +int32_t CBase::a_to_i( const string& line ) +{ + int32_t number; + + stringstream ss( line.c_str() ); + ss >> number; // Convert string to integer + return number; +} + +string CBase::i_to_a( const int16_t num ) +{ + string str; + stringstream ss; + + ss << num; + ss >> str; // Convert string to integer + return str; +} + +string CBase::lowercase( string text ) +{ + transform( text.begin(), text.end(), text.begin(), (int (*)(int))tolower ); + return text; +} + +SDL_Surface* CBase::LoadImage( const string& filename ) +{ + SDL_Surface* loaded_image = NULL; // The mpImage that's loaded + SDL_Surface* optimized_image = NULL; // The optimized surface that will be used + + loaded_image = IMG_Load( filename.c_str() ); //Load the mpImage + + // If the mpImage loaded + if (NULL != loaded_image) + { + optimized_image = SDL_DisplayFormatAlpha( loaded_image ); // Create an optimized surface + SDL_FreeSurface(loaded_image); // Free the old surface + loaded_image = NULL; + + // If the surface was optimized + if (NULL != optimized_image) + { + // Color key surface + SDL_SetColorKey( optimized_image, SDL_RLEACCEL | SDL_SRCCOLORKEY, SDL_MapRGB( optimized_image->format, 0xFF, 0, 0xFF ) ); + } + } + else + { + //Log( "LoadImage -> Could not load image: %s at path='%s'\n", IMG_GetError(), filename.c_str() ); + return NULL; + } + + //Return the optimized surface + return optimized_image; +} + +void CBase::ApplyImage( int16_t x, int16_t y, SDL_Surface* src, SDL_Surface* dst, SDL_Rect* clip ) +{ + // Holds offsets + SDL_Rect offset; + + // Get offsets + offset.x = x; + offset.y = y; + + // Blit + SDL_BlitSurface( src, clip, dst, &offset ); +} + +bool CBase::CheckRectCollision( SDL_Rect* boxA, SDL_Rect* boxB ) +{ + // The sides of the SDL_Rects + int16_t leftA, leftB; + int16_t rightA, rightB; + int16_t topA, topB; + int16_t bottomA, bottomB; + + // Calculate the sides of rec mCollisionbox + leftA = boxB->x; + rightA = boxB->x + boxB->w; + topA = boxB->y; + bottomA = boxB->y + boxB->h; + + // Calculate the sides of rec box + leftB = boxA->x; + rightB = boxA->x + boxA->w; + topB = boxA->y; + bottomB = boxA->y + boxA->h; + + // If any of the sides from mCollisionbox are outside of box + if (bottomA <= topB) return false; + if (topA >= bottomB) return false; + if (rightA <= leftB) return false; + if (leftA >= rightB) return false; + // If none of the sides from mCollisionbox are outside box + return true; // Collision has occured +} + +void CBase::SplitString( const std::string& delimiter, const std::string& text, vector& array ) +{ + string::size_type pos1, pos2; + string value; + + array.clear(); + + pos1 = text.find( delimiter, 0 ); + if (pos1 == string::npos) + { + pos1 = text.length(); + } + value = text.substr( 0, pos1 ); + array.push_back(value); + + pos2 = pos1; + + do { + pos1 = text.find( delimiter, pos2 ); + + if (pos1 != string::npos) + { + pos2 = text.find( delimiter, pos1+1 ); + if (pos2 == string::npos) + { + pos2 = text.length(); + } + + value = text.substr( pos1+1, pos2-pos1-1 ); + array.push_back(value); + } + } while (pos1 != string::npos); +} + +bool CBase::UnprefixString( string& result, const string& line, const string& prefix ) +{ + string::size_type pos; + + pos = line.find(prefix, 0); + if (pos == 0) + { + // Remove the prefix + pos = line.find("=", 0) + 1; + result = line.substr(pos, line.length()-pos); + // Remove any comments + pos = result.find("#", 0); + result = result.substr(0, pos); + // Trim left and right white spaces + result.erase( result.begin(), std::find_if(result.begin(), result.end(), std::not1(std::ptr_fun(std::isspace))) ); + result.erase( std::find_if(result.rbegin(), result.rend(), std::not1(std::ptr_fun(std::isspace))).base(), result.end() ); + + return true; + } + return false; +} + +int16_t CBase::CheckExtension( const string& filename, const string& ext ) +{ + int16_t result; + string::size_type pos; + + pos = filename.length() - ext.length(); + result = lowercase(filename).find( lowercase(ext), pos); + + return result; +} + +void CBase::CheckPath( string& path ) +{ + if (path.length()>1) + { + if (path.at(path.length()-1) != '/') + { + path += '/'; + } + } + else + { + Log( "Warning: CheckPath path too short\n" ); + } +} + +string CBase::cmdclean( string& cmdline ) +{ + string spchars = "\\`$();|{}&'\"*?<>[]!^~-#\n\r "; + for (uint i=0; iflags, width, height, surface->format->BitsPerPixel, + surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask); + + double _stretch_factor_x = ( static_cast(width) / static_cast(surface->w) ), + _stretch_factor_y = ( static_cast(height) / static_cast(surface->h) ); + + for (int32_t y = 0; y < surface->h; y++) + for (int32_t x = 0; x < surface->w; x++) + for (int32_t o_y = 0; o_y < _stretch_factor_y; ++o_y) + for (int32_t o_x = 0; o_x < _stretch_factor_x; ++o_x) + putpixel( _ret, static_cast(_stretch_factor_x * x) + o_x, + static_cast(_stretch_factor_y * y) + o_y, getpixel(surface, x, y) ); + + return _ret; +} + +uint32_t CBase::getpixel( SDL_Surface *surface, int16_t x, int16_t y ) +{ + int16_t bpp = surface->format->BytesPerPixel; + /* Here p is the address to the pixel we want to retrieve */ + uint8_t *p = (uint8_t *)surface->pixels + y * surface->pitch + x * bpp; + + switch (bpp) { + case 1: + return *p; + break; + + case 2: + return *(uint16_t *)p; + break; + + case 3: + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) + return p[0] << 16 | p[1] << 8 | p[2]; + else + return p[0] | p[1] << 8 | p[2] << 16; + break; + + case 4: + return *(uint32_t *)p; + break; + + default: + return 0; /* shouldn't happen, but avoids warnings */ + } +} + +void CBase::putpixel( SDL_Surface *surface, int16_t x, int16_t y, uint32_t pixel ) +{ + int16_t bpp = surface->format->BytesPerPixel; + /* Here p is the address to the pixel we want to set */ + uint8_t *p = (uint8_t *)surface->pixels + y * surface->pitch + x * bpp; + + switch (bpp) { + case 1: + *p = pixel; + break; + + case 2: + *(uint16_t *)p = pixel; + break; + + case 3: + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { + p[0] = (pixel >> 16) & 0xff; + p[1] = (pixel >> 8) & 0xff; + p[2] = pixel & 0xff; + } else { + p[0] = pixel & 0xff; + p[1] = (pixel >> 8) & 0xff; + p[2] = (pixel >> 16) & 0xff; + } + break; + + case 4: + default: + *(uint32_t *)p = pixel; + break; + } +} diff --git a/source/mupen64launcher/src/cbase.h b/source/mupen64launcher/src/cbase.h new file mode 100755 index 0000000..8ef2642 --- /dev/null +++ b/source/mupen64launcher/src/cbase.h @@ -0,0 +1,184 @@ +/** + * @section LICENSE + * + * PickleLauncher + * Copyright (C) 2010-2011 Scott Smith + * + * 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 . + * + * @section LOCATION + */ + +#ifndef CBASE_H +#define CBASE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include //*SEB* for execlp + +#include "SDL.h" +#include "SDL_ttf.h" +#include "SDL_image.h" + +using namespace std; + +#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) /**< Return minimum of two numbers. */ +#define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) /**< Return maximum of two numbers. */ + +/** @brief Generic class to hold any common methods usable by any other class + */ +class CBase +{ + public: + /** Constructor. */ + CBase(); + /** Destructor. */ + virtual ~CBase(); + + /** @brief Logging function + * @param output : formating string to write to the log + */ + void Log ( const char* output, ... ); + + /** @brief Checks a value is between 0 and size + * @param value : value for the range check + * @param size : max that the value should be less than + */ + uint32_t CheckRange ( int32_t value, int32_t size ); + + /** @brief Convert color componets to a single integer + * @param color : SDL color struct with color components + * @return color in integer form + */ + uint32_t rgb_to_int ( SDL_Color color ); + + /** @brief Convert string to integer form + * @param line : string to convert (typically one character) + * @return string in integer form + */ + int32_t a_to_i ( const string& line ); + + /** @brief Convert integer to string form + * @param num : integer to convert + * @return integer in string form + */ + string i_to_a ( const int16_t num ); + + /** @brief Convert string to all lowercase characters + * @param text : string to convert + * @return copy fo string in all lowercase characters + */ + string lowercase ( string text ); + + /** @brief Load graphics from file + * @param filename : file location to the graphic + * @return pointer to the optimized graphic + */ + SDL_Surface* LoadImage ( const string& filename ); + + /** @brief Blit a surface to another surface(screen) + * @param x : x coordinate location for the blit + * @param y : y coordinate location for the blit + * @param src : source graphic to blit to destination + * @param dst : destination graphic to blit to source + * @param clip : dimensions to clip the source graphic + */ + void ApplyImage ( int16_t x, int16_t y, SDL_Surface* src, SDL_Surface* dst, SDL_Rect* clip ); + + /** @brief Detect collision by determining if two rects overlap + * @param boxA : first rect + * @param boxB : second rect + * @return true if collision occured, false if it has not + */ + bool CheckRectCollision ( SDL_Rect* boxA, SDL_Rect* boxB ); + + /** @brief Separate string into different substring based on a delimter string + * @param delimiter : string value to separate text string + * @param text : string to separate + * @param array : contains all of the separate string parts + */ + void SplitString ( const std::string& delimiter, const std::string& text, vector& array ); + + /** @brief Removes a prefix from the beginning of the line and returns the result + * @param result : resulting string + * @param line : string to separate + * @param prefix : string to remove + * @return true if prefix was found and removed, false if it has not + */ + bool UnprefixString ( string& result, const string& line, const string& prefix ); + + /** @brief Checks a string filename to be ended by a extension string + * @param filename : string filename to scan + * @param ext : string extension to find + * @return position of ext if found + */ + int16_t CheckExtension ( const string& filename, const string& ext ); + + /** @brief Checks a string path if ended with a backslash + * @param path : string path to scan + */ + void CheckPath ( string& path ); + + /** @brief Removes a list of characters from the string command line + * @param cmdline : string command line to filter + * @return the filtered string + */ + string cmdclean ( string& cmdline ); + + /** @brief Replaces one string for another string + * @param orig : original string to search + * @param search : string to search + * @param replace : string to replace any instances of string search + * @return the modified result + */ + string strreplace ( string& orig, const string& search, const string& replace ); + + /** @brief Scales the input surface to a new surface with the dimensions provided + * @param surface : input image to be scaled + * @param width : width of the new scaled image + * @param height : height of the new scaled image + * @return the new scaled image + */ + SDL_Surface* ScaleSurface ( SDL_Surface *surface, uint16_t width, uint16_t height ); + + /** @brief Gets the pixel data at the provided coordinates + * @param surface : input image to be read + * @param x : x position of the pixel + * @param y : y position of the pixel + * @return pixel data + */ + uint32_t getpixel ( SDL_Surface *surface, int16_t x, int16_t y ); + + /** @brief Writes the pixel data at the provided coordinates + * @param surface : input image to be modified + * @param x : x position of the pixel + * @param y : y position of the pixel + */ + void putpixel ( SDL_Surface *surface, int16_t x, int16_t y, uint32_t pixel ); +}; + +#endif // CBASE_H diff --git a/source/mupen64launcher/src/cconfig.cpp b/source/mupen64launcher/src/cconfig.cpp new file mode 100755 index 0000000..af5587c --- /dev/null +++ b/source/mupen64launcher/src/cconfig.cpp @@ -0,0 +1,510 @@ +/** + * @section LICENSE + * + * PickleLauncher + * Copyright (C) 2010-2011 Scott Smith + * + * 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 . + * + * @section LOCATION + */ + +#include "cconfig.h" + +CConfig::CConfig() : CBase(), + ResetGUI (false), +#if defined(DEBUG) + Fullscreen (false), +#else + Fullscreen (true), +#endif + ScreenFlip (false), + UseZipSupport (true), + ShowExts (true), + ShowHidden (false), +#if defined(X86) + ShowPointer (true), +#else + ShowPointer (false), +#endif + ShowLabels (true), + UnusedKeysLaunch (false), + UnusedJoysLaunch (false), + ReloadLauncher (true), + TextScrollOption (true), + AutoLayout (true), + FilenameArgNoExt (false), + FilenameAbsPath (true), + EntryFastMode (ENTRY_FAST_MODE_FILTER), + MaxEntries (MAX_ENTRIES), + ColorButton (COLOR_BLUE), + ColorFontButton (COLOR_WHITE), + ColorBackground (COLOR_WHITE), + ColorFontFiles (COLOR_BLACK), + ColorFontFolders (COLOR_RED), + AnalogDeadZone (DEAD_ZONE), + ScreenWidth (SCREEN_WIDTH), + ScreenHeight (SCREEN_HEIGHT), + ScreenDepth (SCREEN_DEPTH), + CPUClock (CPU_CLOCK_DEF), + ScrollSpeed (SCROLL_SPEED), + ScrollPauseSpeed (SCROLL_PAUSE_SPEED), + EntryYDelta (0), + EntryXOffset (0), + EntryYOffset (0), + ButtonWidthLeft (0), + ButtonHeightLeft (0), + ButtonWidthRight (0), + ButtonHeightRight (0), + PreviewWidth (0), + PreviewHeight (0), + DisplayListMaxWidth (0), + FilePathMaxWidth (0), + PosX_Title (0), + PosY_Title (0), + PosX_ButtonLeft (0), + PosY_ButtonLeft (0), + PosX_ButtonRight (0), + PosY_ButtonRight (0), + PosX_ListNames (0), + PosY_ListNames (0), + ScreenRatioW ((float)ScreenWidth/(float)BASE_WIDTH), + ScreenRatioH ((float)ScreenHeight/(float)BASE_HEIGHT), + ZipPath ("ziptemp"), + PreviewsPath ("previews"), + PathFont ("DejaVuSansMono-Bold.ttf"), + PathBackground ("images/background.png"), + PathPointer ("images/pointer.png"), + PathSelectPointer ("images/selectpointer.png"), + Delimiter (DELIMITER), + ButtonModesLeftEnable (), + ButtonModesRightEnable (), + PathButtons (), + KeyMaps (), + JoyMaps (), + FontSizes (), + Colors (), + ColorNames () +{ + SetDefaults(); +} + +CConfig::~CConfig() +{ +} + +void CConfig::SetDefaults( void ) +{ + ButtonModesLeftEnable.resize( BUTTONS_MAX_LEFT, true ); + ButtonModesRightEnable.resize( BUTTONS_MAX_RIGHT, true ); + + KeyMaps.resize(EVENT_TOTAL); + KeyMaps.at(EVENT_ONE_UP) = SDLK_UP; + KeyMaps.at(EVENT_ONE_DOWN) = SDLK_DOWN; + KeyMaps.at(EVENT_PAGE_UP) = SDLK_LEFT; + KeyMaps.at(EVENT_PAGE_DOWN) = SDLK_RIGHT; + KeyMaps.at(EVENT_DIR_UP) = SDLK_LCTRL; + KeyMaps.at(EVENT_DIR_DOWN) = SDLK_RSHIFT; + KeyMaps.at(EVENT_CFG_APP) = SDLK_1; + KeyMaps.at(EVENT_CFG_ITEM) = SDLK_2; + KeyMaps.at(EVENT_SET_ONE) = SDLK_3; + KeyMaps.at(EVENT_SET_ALL) = SDLK_4; + KeyMaps.at(EVENT_SELECT) = SDLK_RETURN; + KeyMaps.at(EVENT_BACK) = SDLK_LCTRL; + KeyMaps.at(EVENT_QUIT) = SDLK_ESCAPE; + + JoyMaps.resize(EVENT_TOTAL); + JoyMaps.at(EVENT_ONE_UP) = 0; + JoyMaps.at(EVENT_ONE_DOWN) = 1; + JoyMaps.at(EVENT_PAGE_UP) = 2; + JoyMaps.at(EVENT_PAGE_DOWN) = 3; + JoyMaps.at(EVENT_DIR_UP) = 4; + JoyMaps.at(EVENT_DIR_DOWN) = 5; + JoyMaps.at(EVENT_CFG_APP) = 6; + JoyMaps.at(EVENT_CFG_ITEM) = 7; + JoyMaps.at(EVENT_SET_ONE) = 8; + JoyMaps.at(EVENT_SET_ALL) = 9; + JoyMaps.at(EVENT_SELECT) = 10; + JoyMaps.at(EVENT_BACK) = 11; + JoyMaps.at(EVENT_QUIT) = 12; + + PathButtons.resize(EVENT_TOTAL); + PathButtons.at(EVENT_ONE_UP) = "images/button_oneup.png"; + PathButtons.at(EVENT_ONE_DOWN) = "images/button_onedn.png"; + PathButtons.at(EVENT_PAGE_UP) = "images/button_pageup.png"; + PathButtons.at(EVENT_PAGE_DOWN) = "images/button_pagedn.png"; + PathButtons.at(EVENT_DIR_UP) = "images/button_dirup.png"; + PathButtons.at(EVENT_DIR_DOWN) = "images/button_dirdn.png"; + PathButtons.at(EVENT_ZIP_MODE) = "images/button_zipmode.png"; + PathButtons.at(EVENT_CFG_APP) = "images/button_cfg_app.png"; + PathButtons.at(EVENT_CFG_ITEM) = "images/button_cfg_item.png"; + PathButtons.at(EVENT_SET_ONE) = "images/button_set_one.png"; + PathButtons.at(EVENT_SET_ALL) = "images/button_set_all.png"; + PathButtons.at(EVENT_BACK) = "images/button_back.png"; + PathButtons.at(EVENT_SELECT) = "images/button_select.png"; + PathButtons.at(EVENT_QUIT) = "images/button_quit.png"; + + Colors.resize(COLOR_TOTAL); + ColorNames.resize(COLOR_TOTAL); + ColorNames.at(COLOR_WHITE) = "white"; Colors.at(COLOR_WHITE).r = 255; Colors.at(COLOR_WHITE).g = 255; Colors.at(COLOR_WHITE).b = 255; + ColorNames.at(COLOR_YELLOW) = "yellow"; Colors.at(COLOR_YELLOW).r = 255; Colors.at(COLOR_YELLOW).g = 255; Colors.at(COLOR_YELLOW).b = 0; + ColorNames.at(COLOR_FUCHSIA) = "fushsia"; Colors.at(COLOR_FUCHSIA).r = 255; Colors.at(COLOR_FUCHSIA).g = 0; Colors.at(COLOR_FUCHSIA).b = 255; + ColorNames.at(COLOR_RED) = "red"; Colors.at(COLOR_RED).r = 255; Colors.at(COLOR_RED).g = 0; Colors.at(COLOR_RED).b = 0; + ColorNames.at(COLOR_SILVER) = "silver"; Colors.at(COLOR_SILVER).r = 192; Colors.at(COLOR_SILVER).g = 192; Colors.at(COLOR_SILVER).b = 192; + ColorNames.at(COLOR_GRAY) = "gray"; Colors.at(COLOR_GRAY).r = 128; Colors.at(COLOR_GRAY).g = 128; Colors.at(COLOR_GRAY).b = 128; + ColorNames.at(COLOR_OLIVE) = "olive"; Colors.at(COLOR_OLIVE).r = 128; Colors.at(COLOR_OLIVE).g = 128; Colors.at(COLOR_OLIVE).b = 0; + ColorNames.at(COLOR_PURPLE) = "purple"; Colors.at(COLOR_PURPLE).r = 128; Colors.at(COLOR_PURPLE).g = 0; Colors.at(COLOR_PURPLE).b = 128; + ColorNames.at(COLOR_MAROON) = "maroon"; Colors.at(COLOR_MAROON).r = 128; Colors.at(COLOR_MAROON).g = 0; Colors.at(COLOR_MAROON).b = 0; + ColorNames.at(COLOR_AQUA) = "aqua"; Colors.at(COLOR_AQUA).r = 0; Colors.at(COLOR_AQUA).g = 255; Colors.at(COLOR_AQUA).b = 255; + ColorNames.at(COLOR_LIME) = "lime"; Colors.at(COLOR_LIME).r = 0; Colors.at(COLOR_LIME).g = 255; Colors.at(COLOR_LIME).b = 0; + ColorNames.at(COLOR_TEAL) = "teal"; Colors.at(COLOR_TEAL).r = 0; Colors.at(COLOR_TEAL).g = 128; Colors.at(COLOR_TEAL).b = 128; + ColorNames.at(COLOR_GREEN) = "green"; Colors.at(COLOR_GREEN).r = 0; Colors.at(COLOR_GREEN).g = 128; Colors.at(COLOR_GREEN).b = 0; + ColorNames.at(COLOR_BLUE) = "blue"; Colors.at(COLOR_BLUE).r = 0; Colors.at(COLOR_BLUE).g = 0; Colors.at(COLOR_BLUE).b = 255; + ColorNames.at(COLOR_NAVY) = "navy"; Colors.at(COLOR_NAVY).r = 0; Colors.at(COLOR_NAVY).g = 0; Colors.at(COLOR_NAVY).b = 128; + ColorNames.at(COLOR_BLACK) = "black"; Colors.at(COLOR_BLACK).r = 0; Colors.at(COLOR_BLACK).g = 0; Colors.at(COLOR_BLACK).b = 0; + + FontSizes.resize(FONT_SIZE_TOTAL, 0); + FontSizes.at(FONT_SIZE_SMALL) = (int16_t)( 8*ScreenRatioH); + FontSizes.at(FONT_SIZE_MEDIUM) = (int16_t)(12*ScreenRatioH); + FontSizes.at(FONT_SIZE_LARGE) = (int16_t)(14*ScreenRatioH); + + EntryYDelta = ENTRY_Y_DELTA; + EntryXOffset = ENTRY_X_OFFSET; + EntryYOffset = ENTRY_Y_OFFSET; + ButtonWidthLeft = BUTTON_W_LEFT; + ButtonHeightLeft = BUTTON_H_LEFT; + ButtonWidthRight = BUTTON_W_RIGHT; + ButtonHeightRight = BUTTON_H_RIGHT; + PreviewWidth = PREVIEW_W; + PreviewHeight = PREVIEW_H; + DisplayListMaxWidth = ENTRY_MAX_W; + FilePathMaxWidth = FILEPATH_MAX_W; +} + +#define LOAD_INT(X,Y) if (UnprefixString( line, line, X ) == true) { Y = a_to_i(line); } +#define LOAD_KEY(X,Y) if (UnprefixString( line, line, X ) == true) { Y = (SDLKey)a_to_i(line); } +#define LOAD_STR(X,Y) if (UnprefixString( Y, line, X ) == true) {} + +int8_t CConfig::Load( const string& location ) +{ + uint16_t i; + string line; + string label; + ifstream fin; + + fin.open(location.c_str(), ios_base::in); + + if (!fin) + { + Log( "Failed to open config\n" ); + return 0; // Dont stop the app if it cant be opened, default values will be used and then save to file. + } + + // Read in the profile + if (fin.is_open()) + { + while (!fin.eof()) + { + getline(fin,line); + +#if defined(DEBUG) + Log( "%s\n", line.c_str() ); +#endif + + if (line.length() > 0) + { + LOAD_INT( OPT_SCREEN_WIDTH, ScreenWidth ); + LOAD_INT( OPT_SCREEN_HEIGHT, ScreenHeight ); + LOAD_INT( OPT_SCREEN_DEPTH, ScreenDepth ); + LOAD_INT( OPT_FULLSCREEN, Fullscreen ); + LOAD_INT( OPT_CPU_CLOCK, CPUClock ); + LOAD_INT( OPT_USEZIPSUPPORT, UseZipSupport ); + LOAD_INT( OPT_SHOWEXTS, ShowExts ); + LOAD_INT( OPT_SHOWHIDDEN, ShowHidden ); + LOAD_INT( OPT_SHOWPOINTER, ShowPointer ); + LOAD_INT( OPT_SHOWLABELS, ShowLabels ); + LOAD_INT( OPT_UNUSED_KEYS_SELECT, UnusedKeysLaunch ); + LOAD_INT( OPT_UNUSED_JOYS_SELECT, UnusedJoysLaunch ); + LOAD_INT( OPT_RELOAD_LAUNCHER, ReloadLauncher ); + LOAD_INT( OPT_TEXT_SCROLL_OPTION, TextScrollOption ); + LOAD_INT( OPT_FILENAMEARGNOEXT, FilenameArgNoExt ); + LOAD_INT( OPT_FILEABSPATH, FilenameAbsPath ); + LOAD_INT( OPT_FONT_SIZE_SMALL, FontSizes.at(FONT_SIZE_SMALL) ); + LOAD_INT( OPT_FONT_SIZE_MEDIUM, FontSizes.at(FONT_SIZE_MEDIUM) ); + LOAD_INT( OPT_FONT_SIZE_LARGE, FontSizes.at(FONT_SIZE_LARGE) ); + LOAD_INT( OPT_ENTRY_FAST_MODE, EntryFastMode ); + LOAD_INT( OPT_MAX_ENTRIES, MaxEntries ); + LOAD_INT( OPT_SCROLL_SPEED, ScrollSpeed ); + LOAD_INT( OPT_SCROLL_PAUSE_SPEED, ScrollPauseSpeed ); + LOAD_STR( OPT_PROFILE_DELIMITER, Delimiter ); + // GUI Positions + LOAD_INT( OPT_AUTOLAYOUT, AutoLayout ); + LOAD_INT( OPT_POSX_TITLE, PosX_Title ); + LOAD_INT( OPT_POSY_TITLE, PosY_Title ); + LOAD_INT( OPT_POSX_BTNLEFT, PosX_ButtonLeft ); + LOAD_INT( OPT_POSY_BTNLEFT, PosY_ButtonLeft ); + LOAD_INT( OPT_POSX_BTNRIGHT, PosX_ButtonRight ); + LOAD_INT( OPT_POSY_BTNRIGHT, PosY_ButtonRight ); + LOAD_INT( OPT_POSX_LISTNAMES, PosX_ListNames ); + LOAD_INT( OPT_POSY_LISTNAMES, PosY_ListNames ); + // GUI Options + LOAD_INT( OPT_ENTRY_Y_DELTA, EntryYDelta ); + LOAD_INT( OPT_ENTRY_X_OFFSET, EntryXOffset ); + LOAD_INT( OPT_ENTRY_Y_OFFSET, EntryYOffset ); + LOAD_INT( OPT_BUTTON_W_LEFT, ButtonWidthLeft ); + LOAD_INT( OPT_BUTTON_H_LEFT, ButtonHeightLeft ); + LOAD_INT( OPT_BUTTON_W_RIGHT, ButtonWidthRight ); + LOAD_INT( OPT_BUTTON_H_RIGHT, ButtonHeightRight ); + LOAD_INT( OPT_PREVIEW_W, PreviewWidth ); + LOAD_INT( OPT_PREVIEW_H, PreviewHeight ); + LOAD_INT( OPT_ENTRY_MAX_W, DisplayListMaxWidth ); + LOAD_INT( OPT_FILEPATH_MAX_W, FilePathMaxWidth ); + // GUI Buttons + for (i=0; i. + * + * @section LOCATION + */ + +#ifndef CCONFIG_H +#define CCONFIG_H + +#include "cbase.h" +#include "csystem.h" + +using namespace std; + +#define SCREEN_FLAGS SDL_SWSURFACE /**< Basic SDL screen flags. */ +#define BASE_WIDTH 320 /**< Minimum screen width size (pixels). */ +#define BASE_HEIGHT 240 /**< Maximum screen height size (pixels). */ +#if defined(PANDORA) || defined(X86) +#define SCREEN_WIDTH 800 /**< Default screen width for Pandora and PC (pixels). */ +#define SCREEN_HEIGHT 480 /**< Default screen height for Pandora and PC (pixels). */ +#else +#define SCREEN_WIDTH BASE_WIDTH /**< Default screen width for any other device (pixels). */ +#define SCREEN_HEIGHT BASE_HEIGHT /**< Default screen height for any other device (pixels). */ +#endif +#define SCREEN_DEPTH 16 /**< Default screen depth for any device (bits per pixel). */ +#define REFRESH_DELAY 10 /**< Default screen depth for any device (millseconds). */ +#define MAX_ENTRIES 10 /**< Default maximum entries in the display list. */ +#define SCROLL_SPEED 2 /**< Default speed for scrolling text. */ +#define SCROLL_PAUSE_SPEED 100 /**< Default speed for pausing scrolling text when left or right ends are reached. */ +#define DEAD_ZONE 10000 /**< Default analog joystick deadzone. */ +#define DELIMITER ";" /**< Default profile delimiter. */ +#define CFG_LBL_W 30 /**< Mininum character width for the profile label. */ +#define CFG_VAL_W 30 /**< Mininum character width for the profile value. */ + +// GUI Options Defaults +#define ENTRY_Y_DELTA (2*ScreenRatioH) /** Scaled pixel amount used between entries. */ +#define ENTRY_X_OFFSET (8*ScreenRatioW) /** Scaled pixel amount used to separate gui elements along the X axis. */ +#define ENTRY_Y_OFFSET (8*ScreenRatioH) /** Scaled pixel amount used to separate gui elements along the Y axis. */ + +#define BUTTONS_MAX_LEFT 7 /** Number of buttons on the left side of the GUI. */ +#define BUTTONS_MAX_RIGHT 4 /** Number of buttons on the right side of the GUI. */ + +#define BUTTON_W_LEFT (25*ScreenRatioW) /** Scaled pixel width for buttons on the left side. */ +#define BUTTON_H_LEFT (15*ScreenRatioH) /** Scaled pixel hieght for buttons on the left side. */ +#define BUTTON_W_RIGHT (80*ScreenRatioW) /** Scaled pixel width for buttons on the right side. */ +#define BUTTON_H_RIGHT (30*ScreenRatioH) /** Scaled pixel hieght for buttons on the right side. */ + +#define PREVIEW_W (80*ScreenRatioW) /** Scaled pixel width for the preview image. */ +#define PREVIEW_H (60*ScreenRatioH) /** Scaled pixel height for the preview image. */ + +#define ENTRY_MAX_W (ScreenWidth-(BUTTON_W_RIGHT)-(ENTRY_X_OFFSET*2)) /** Max scaled pixel width for an entry. */ +#define FILEPATH_MAX_W (ScreenWidth-(ENTRY_X_OFFSET*2)) /** Max scaled pixel width for an the current path. */ + +#define HELP_DEFAULT "" + +// Screen options +#define OPT_SCREEN_WIDTH "screen_width" +#define HELP_SCREEN_WIDTH "Screen width in pixels." + +#define OPT_SCREEN_HEIGHT "screen_height" +#define HELP_SCREEN_HEIGHT "Screen height in pixels." + +#define OPT_SCREEN_DEPTH "screen_depth" +#define HELP_SCREEN_DEPTH "Screen depth in bits per pixel." + +#define OPT_REFRESH_DELAY "refresh_delay" +#define HELP_REFRESH_DELAY "Delay in milliseconds after a screen flip." + +#define OPT_FULLSCREEN "fullscreen" +#define HELP_FULLSCREEN "True if screen is set to fullscreen mode, otherwise false." + +// Selector options +#define OPT_CPU_CLOCK "cpu_clock" +#define HELP_CPU_CLOCK "If supported, will set the CPU to clock value in Mhz." + +#define OPT_USEZIPSUPPORT "use_zip_support" +#define HELP_USEZIPSUPPORT "True if launcher uses internal zip support." + +#define OPT_SHOWEXTS "show_exts" +#define HELP_SHOWEXTS "True if the selector should show file extensions in the filenames, otherwise false." + +#define OPT_SHOWHIDDEN "show_hidden" +#define HELP_SHOWHIDDEN "True if the selector should show hidden files and folders in the display list, otherwise false." + +#define OPT_SHOWPOINTER "show_pointer" +#define HELP_SHOWPOINTER "True if the selector should show the SDL pointer, otherwise false." + +#define OPT_SHOWLABELS "show_labels" +#define HELP_SHOWLABELS "True if the selector should show the button text ttf labels, otherwise false." + +#define OPT_UNUSED_KEYS_SELECT "unused_keys_select" +#define HELP_UNUSED_KEYS_SELECT "True if any unmapped key events should cause the application launch, otherwise false." + +#define OPT_UNUSED_JOYS_SELECT "unused_buttons_select" +#define HELP_UNUSED_JOYS_SELECT "True if any unmapped button events should cause the application launch, otherwise false." + +#define OPT_RELOAD_LAUNCHER "reload_launcher" +#define HELP_RELOAD_LAUNCHER "True if the launcher should reload following the shutdown of the target application, otherwise false." + +#define OPT_TEXT_SCROLL_OPTION "text_scroll_option" +#define HELP_TEXT_SCROLL_OPTION "True if horizontal the text scroll option should enabled, otherwise false." + +#define OPT_FILENAMEARGNOEXT "filename_arg_no_ext" +#define HELP_FILENAMEARGNOEXT "True if the extension for file to be loaded is removed, else the extension is not removed from the filename." + +#define OPT_FILEABSPATH "file_abs_path" +#define HELP_FILEABSPATH "True if the absolute path for the file location should be used to calling the filname, else the path is omitted." + +#define OPT_ENTRY_FAST_MODE "entry_fast_mode" +#define HELP_ENTRY_FAST_MODE "Fast entry navagation mode, where 0 for alphabetic mode 1 for search filter" + +#define OPT_MAX_ENTRIES "max_entries" +#define HELP_MAX_ENTRIES "Maximum number of entries to be in the display list." + +#define OPT_SCROLL_SPEED "scroll_speed" +#define HELP_SCROLL_SPEED "The speed of the horizontal the text scroll speed, lower faster, higher slower.." + +#define OPT_SCROLL_PAUSE_SPEED "scroll_pause_speed" +#define HELP_SCROLL_PAUSE_SPEED "The time delay of the horizontal the text scroll when the left/right ends are reached, lower shorter, higher longer." + +#define OPT_PROFILE_DELIMITER "profile_delimiter" +#define HELP_PROFILE_DELIMITER "Delimiter character" + +// GUI Positions +#define OPT_AUTOLAYOUT "autolayout" +#define HELP_AUTOLAYOUT "True if the launcher should auto position gui elements, if false manual positions are used." + +#define OPT_POSX_TITLE "posx_title" +#define OPT_POSY_TITLE "posy_title" +#define OPT_POSX_BTNLEFT "posx_btnleft" +#define OPT_POSY_BTNLEFT "posy_btnleft" +#define OPT_POSX_BTNRIGHT "posx_btnright" +#define OPT_POSY_BTNRIGHT "posy_btnright" +#define OPT_POSX_LISTNAMES "posx_listnames" +#define OPT_POSY_LISTNAMES "posy_listnames" + +#define HELP_POSX_TITLE "X coordinate in the upper left corner" +#define HELP_POSY_TITLE "Y coordinate in the upper left corner" +#define HELP_POSX_BTNLEFT "X coordinate in the upper left corner" +#define HELP_POSY_BTNLEFT "Y coordinate in the upper left corner" +#define HELP_POSX_BTNRIGHT "X coordinate in the bottom left corner" +#define HELP_POSY_BTNRIGHT "Y coordinate in the bottom left corner" +#define HELP_POSX_LISTNAMES "X coordinate in the upper left corner" +#define HELP_POSY_LISTNAMES "Y coordinate in the upper left corner" + +// GUI Options +#define OPT_ENTRY_Y_DELTA "entry_y_delta" +#define OPT_ENTRY_X_OFFSET "entry_x_offset" +#define OPT_ENTRY_Y_OFFSET "entry_y_offset" +#define OPT_BUTTON_W_LEFT "button_w_left" +#define OPT_BUTTON_H_LEFT "button_h_left" +#define OPT_BUTTON_W_RIGHT "button_w_right" +#define OPT_BUTTON_H_RIGHT "button_h_right" +#define OPT_PREVIEW_W "preview_w" +#define OPT_PREVIEW_H "preview_h" +#define OPT_ENTRY_MAX_W "entry_max_w" +#define OPT_FILEPATH_MAX_W "filepath_max_w" + +#define OPT_BUTTONLEFT_ENABLED "buttonleft_enable" +#define OPT_BUTTONRIGHT_ENABLED "buttonright_enable" + +#define HELP_ENTRY_Y_DELTA "todo" +#define HELP_ENTRY_X_OFFSET "todo" +#define HELP_ENTRY_Y_OFFSET "todo" +#define HELP_BUTTON_W_LEFT "todo" +#define HELP_BUTTON_H_LEFT "todo" +#define HELP_BUTTON_W_RIGHT "todo" +#define HELP_BUTTON_H_RIGHT "todo" +#define HELP_PREVIEW_W "todo" +#define HELP_PREVIEW_H "todo" +#define HELP_ENTRY_MAX_W "todo" +#define HELP_FILEPATH_MAX_W "todo" + +// Paths +#define OPT_PATH_ZIPTEMP "zip_temp_path" +#define HELP_PATH_ZIPTEMP "Path to store extracted files from zip." + +#define OPT_PATH_PREVIEWS "previews_path" +#define HELP_PATH_PREVIEWS "Path to read preview graphics." + +#define OPT_PATH_FONT "font_path" +#define HELP_PATH_FONT "Path to ttf font file." + +#define OPT_FONT_SIZE_SMALL "font_size_small" +#define HELP_FONT_SIZE_SMALL "Font size identified as small." + +#define OPT_FONT_SIZE_MEDIUM "font_size_medium" +#define HELP_FONT_SIZE_MEDIUM "Font size identified as medium." + +#define OPT_FONT_SIZE_LARGE "font_size_large" +#define HELP_FONT_SIZE_LARGE "Font size identified as large." + +#define OPT_PATH_BACKGND "image_background" +#define HELP_PATH_BACKGND "Path to background graphic." + +#define OPT_PATH_POINTER "image_pointer" +#define HELP_PATH_POINTER "Path to pointer graphic" + +#define OPT_PATH_SELECTPOINTER "image_selectpointer" +#define HELP_PATH_SELECTPOINTER "Path to selector pointer graphic" + +#define OPT_PATH_ONEUP "image_upone" +#define HELP_PATH_ONEUP "Path to button graphic for one up." + +#define OPT_PATH_ONEDN "image_downone" +#define HELP_PATH_ONEDN "Path to button graphic for one down." + +#define OPT_PATH_PGUP "image_pageup" +#define HELP_PATH_PGUP "Path to button graphic for page up." + +#define OPT_PATH_PGDN "image_pagedown" +#define HELP_PATH_PGDN "Path to button graphic for page down." + +#define OPT_PATH_DIRUP "image_dirup" +#define HELP_PATH_DIRUP "Path to button graphic for dir up." + +#define OPT_PATH_DIRDN "image_dirdown" +#define HELP_PATH_DIRDN "Path to button graphic for dir down." + +#define OPT_PATH_CFG_APP "image_cfgapp" +#define HELP_PATH_CFG_APP "Path to button graphic for cfg app." + +#define OPT_PATH_CFG_ITEM "image_cfgitem" +#define HELP_PATH_CFG_ITEM "Path to button graphic for cfg item." + +#define OPT_PATH_SELECT "image_select" +#define HELP_PATH_SELECT "Path to button graphic for cfg select." + +#define OPT_PATH_QUIT "image_quit" +#define HELP_PATH_QUIT "Path to button graphic for quit." + +// Color GUI options +#define OPT_COLOR_BUTTON "color_buttons" +#define HELP_COLOR_BUTTON "Color index used for the coloring the fallback button." + +#define OPT_COLOR_FONTBUTTON "color_fontbuttons" +#define HELP_COLOR_FONTBUTTON "Color index used for the coloring the font used in the fallback button." + +#define OPT_COLOR_BACKGND "color_background" +#define HELP_COLOR_BACKGND "Color index used for the coloring the screen background. " + +#define OPT_COLOR_FONTFILES "color_fontfiles" +#define HELP_COLOR_FONTFILES "Color index used for the coloring the entries that are files." + +#define OPT_COLOR_FONTFOLDERS "color_fontfolders" +#define HELP_COLOR_FONTFOLDERS "Color index used for the coloring the entries that are folders." + +// Keyboard +#define OPT_KEYUP "key_up" +#define OPT_KEYDOWN "key_down" +#define OPT_KEYLEFT "key_left" +#define OPT_KEYRIGHT "key_right" +#define OPT_KEYDIRUP "key_dirup" +#define OPT_KEYDIRDOWN "key_dirdown" +#define OPT_KEYCFGENTRY "key_cfgentry" +#define OPT_KEYCFGAPP "key_cfgapp" +#define OPT_KEYSETONE "key_setone" +#define OPT_KEYSETALL "key_setall" +#define OPT_KEYSELECT "key_select" +#define OPT_KEYBACK "key_back" +#define OPT_KEYQUIT "key_quit" + +// Joystick +#define OPT_JOYUP "button_up" +#define OPT_JOYDOWN "button_down" +#define OPT_JOYLEFT "button_left" +#define OPT_JOYRIGHT "button_right" +#define OPT_JOYDIRUP "button_dirup" +#define OPT_JOYDIRDOWN "button_dirdown" +#define OPT_JOYCFGENTRY "button_cfgentry" +#define OPT_JOYCFGAPP "button_cfgapp" +#define OPT_JOYSETONE "button_setone" +#define OPT_JOYSETALL "button_setall" +#define OPT_JOYSELECT "button_select" +#define OPT_JOYBACK "button_back" +#define OPT_JOYQUIT "button_quit" + +#define OPT_DEADZONE "deadzone" +#define HELP_DEADZONE "Deadzone for analog joysticks." + +/** @brief Internal user events + */ +enum EVENT_T { + EVENT_ONE_UP=0, /**< 0 Move selection one item up. */ + EVENT_ONE_DOWN, /**< 1 Move selection one item down. */ + EVENT_PAGE_UP, /**< 2 Move selection one page up. */ + EVENT_PAGE_DOWN, /**< 3 Move selection one page down. */ + EVENT_DIR_UP, /**< 4 Move current path one directory up. */ + EVENT_DIR_DOWN, /**< 5 Move current path one directory down. */ + EVENT_ZIP_MODE, /**< 6 Mode to use when extracing files from a zip. */ + EVENT_CFG_APP, /**< 7 Enter mode to configure the launcher. */ + EVENT_CFG_ITEM, /**< 8 Enter mode to configure an entry. */ + EVENT_SET_ONE, /**< 9 For an argument set selected value for the current entry. */ + EVENT_SET_ALL, /**< 10 For an argument set selected value for the all entry. */ + EVENT_SELECT, /**< 11 Select the current item. */ + EVENT_BACK, /**< 12 Go back from the current mode and return to the previous mode. */ + EVENT_QUIT, /**< 13 Quit the launcher. */ + EVENT_TOTAL, /**< 14 Total number of events. */ + EVENT_NONE /**< 15 No event. */ +}; + +/** @brief Mode for navagating to an entry quickly. + */ +enum ENTRY_FAST_MODE_T { + ENTRY_FAST_MODE_ALPHA=0, + ENTRY_FAST_MODE_FILTER +}; + +/** @brief Basic colors + */ +enum COLORS_T { + COLOR_WHITE=0, + COLOR_YELLOW, + COLOR_FUCHSIA, + COLOR_RED, + COLOR_SILVER, + COLOR_GRAY, + COLOR_OLIVE, + COLOR_PURPLE, + COLOR_MAROON, + COLOR_AQUA, + COLOR_LIME, + COLOR_TEAL, + COLOR_GREEN, + COLOR_BLUE, + COLOR_NAVY, + COLOR_BLACK, + COLOR_TOTAL +}; + +/** @brief Font sizes + */ +enum FONT_SIZE_T { + FONT_SIZE_SMALL=0, + FONT_SIZE_MEDIUM, + FONT_SIZE_LARGE, + FONT_SIZE_TOTAL +}; + +/** @brief Class that handles loading and saving of all configurable options + */ +class CConfig : public CBase +{ + public: + /** Constructor. */ + CConfig(); + /** Destructor. */ + virtual ~CConfig(); + + /** @brief Set configuration options to calculated defaults + */ + void SetDefaults ( void ); + + /** @brief Load the configuration option from file + * @param location : path and filename to config file + * @return 0 no errors or 1 if an error is detected + */ + int8_t Load ( const string& location ); + + /** @brief Save the configuration option from file + * @param location : path and filename to config file + * @return 0 no errors or 1 if an error is detected + */ + int8_t Save ( const string& location ); + + bool ResetGUI; /**< NOT CONFIGURABLE Set via argument and uses scaled defaults and not config file */ + bool Fullscreen; /**< CONFIGURABLE Refer to HELP_FULLSCREEN */ + bool ScreenFlip; /**< CONFIGURABLE Refer to HELP_SCREENFLIP */ + bool UseZipSupport; /**< CONFIGURABLE Refer to HELP_USEZIPSUPPORT */ + bool ShowExts; /**< CONFIGURABLE Refer to HELP_SHOWEXTS */ + bool ShowHidden; /**< CONFIGURABLE Refer to HELP_SHOWHIDDEN */ + bool ShowPointer; /**< CONFIGURABLE Refer to HELP_SHOWPOINTER */ + bool ShowLabels; /**< CONFIGURABLE Refer to HELP_SHOWLABELS */ + bool UnusedKeysLaunch; /**< CONFIGURABLE Refer to HELP_UNUSED_KEYS_SELECT */ + bool UnusedJoysLaunch; /**< CONFIGURABLE Refer to HELP_UNUSED_JOYS_SELECT */ + bool ReloadLauncher; /**< CONFIGURABLE Refer to HELP_RELOAD_LAUNCHER */ + bool TextScrollOption; /**< CONFIGURABLE Refer to HELP_TEXT_SCROLL_OPTION */ + bool AutoLayout; /**< CONFIGURABLE Refer to HELP_AUTOLAYOUT */ + bool FilenameArgNoExt; /**< CONFIGURABLE Refer to HELP_FILENAMEARGNOEXT */ + bool FilenameAbsPath; /**< CONFIGURABLE Refer to HELP_FILEABSPATH */ + uint8_t EntryFastMode; /**< CONFIGURABLE Refer to HELP_ENTRY_FAST_MODE */ + uint8_t MaxEntries; /**< CONFIGURABLE Refer to HELP_MAX_ENTRIES */ + uint8_t ColorButton; /**< CONFIGURABLE Refer to HELP_COLOR_BUTTON */ + uint8_t ColorFontButton; /**< CONFIGURABLE Refer to HELP_COLOR_FONTBUTTON */ + uint8_t ColorBackground; /**< CONFIGURABLE Refer to HELP_COLOR_BACKGND */ + uint8_t ColorFontFiles; /**< CONFIGURABLE Refer to HELP_COLOR_FONTFILES */ + uint8_t ColorFontFolders; /**< CONFIGURABLE Refer to HELP_COLOR_FONTFOLDERS */ + int16_t AnalogDeadZone; /**< CONFIGURABLE Refer to HELP_DEADZONE */ + int16_t ScreenWidth; /**< CONFIGURABLE Refer to HELP_SCREEN_WIDTH */ + int16_t ScreenHeight; /**< CONFIGURABLE Refer to HELP_SCREEN_HEIGHT */ + int16_t ScreenDepth; /**< CONFIGURABLE Refer to HELP_SCREEN_DEPTH */ + uint16_t CPUClock; /**< CONFIGURABLE Refer to HELP_CPU_CLOCK */ + uint16_t ScrollSpeed; /**< CONFIGURABLE Refer to HELP_SCROLL_PAUSE_SPEED */ + uint16_t ScrollPauseSpeed; /**< CONFIGURABLE Refer to HELP_SCROLL_PAUSE_SPEED */ + uint16_t EntryYDelta; /**< CONFIGURABLE Refer to HELP_SCROLL_PAUSE_SPEED */ + uint16_t EntryXOffset; /**< CONFIGURABLE Refer to HELP_SCROLL_PAUSE_SPEED */ + uint16_t EntryYOffset; /**< CONFIGURABLE Refer to HELP_SCROLL_PAUSE_SPEED */ + uint16_t ButtonWidthLeft; /**< CONFIGURABLE Refer to HELP_SCROLL_PAUSE_SPEED */ + uint16_t ButtonHeightLeft; /**< CONFIGURABLE Refer to HELP_SCROLL_PAUSE_SPEED */ + uint16_t ButtonWidthRight; /**< CONFIGURABLE Refer to HELP_SCROLL_PAUSE_SPEED */ + uint16_t ButtonHeightRight; /**< CONFIGURABLE Refer to HELP_SCROLL_PAUSE_SPEED */ + uint16_t PreviewWidth; /**< CONFIGURABLE Refer to HELP_SCROLL_PAUSE_SPEED */ + uint16_t PreviewHeight; /**< CONFIGURABLE Refer to HELP_SCROLL_PAUSE_SPEED */ + uint16_t DisplayListMaxWidth; /**< CONFIGURABLE Refer to HELP_DISPLAY_LIST_MAX_WIDTH */ + uint16_t FilePathMaxWidth; /**< CONFIGURABLE Refer to HELP_SCROLL_PAUSE_SPEED */ + uint16_t PosX_Title; /**< CONFIGURABLE */ + uint16_t PosY_Title; /**< CONFIGURABLE */ + uint16_t PosX_ButtonLeft; /**< CONFIGURABLE */ + uint16_t PosY_ButtonLeft; /**< CONFIGURABLE */ + uint16_t PosX_ButtonRight; /**< CONFIGURABLE */ + uint16_t PosY_ButtonRight; /**< CONFIGURABLE */ + uint16_t PosX_ListNames; /**< CONFIGURABLE */ + uint16_t PosY_ListNames; /**< CONFIGURABLE */ + float ScreenRatioW; /**< NOT CONFIGURABLE The ratio of the current resolution to the base resolution, used for scaling. */ + float ScreenRatioH; /**< NOT CONFIGURABLE The ratio of the current resolution to the base resolution, used for scaling. */ + string ZipPath; /**< CONFIGURABLE Refer to HELP_PATH_ZIPTEMP */ + string PreviewsPath; /**< CONFIGURABLE Refer to HELP_PATH_PREVIEWS */ + string PathFont; /**< CONFIGURABLE Refer to HELP_PATH_FONT */ + string PathBackground; /**< CONFIGURABLE Refer to HELP_PATH_BACKGND */ + string PathPointer; /**< CONFIGURABLE Refer to HELP_PATH_POINTER */ + string PathSelectPointer; /**< CONFIGURABLE Refer to HELP_PATH_SELECTPOINTER */ + string Delimiter; /**< CONFIGURABLE Refer to HELP_PROFILE_DELIMITER */ + vector ButtonModesLeftEnable; /**< CONFIGURABLE force buttons to be disabled */ + vector ButtonModesRightEnable; /**< CONFIGURABLE force buttons to be disabled */ + vector PathButtons; /**< CONFIGURABLE Paths for the button graphics */ + vector KeyMaps; /**< CONFIGURABLE Key mappings to user actions */ + vector JoyMaps; /**< CONFIGURABLE Button mappings to user actions */ + vector FontSizes; /**< CONFIGURABLE Point size of the font sizes */ + vector Colors; /**< NOT CONFIGURABLE Basic color types */ + vector ColorNames; /**< NOT CONFIGURABLE Basic color names */ +}; + +#endif // CCONFIG_H diff --git a/source/mupen64launcher/src/cprofile.cpp b/source/mupen64launcher/src/cprofile.cpp new file mode 100755 index 0000000..251bfa7 --- /dev/null +++ b/source/mupen64launcher/src/cprofile.cpp @@ -0,0 +1,1353 @@ +/** + * @section LICENSE + * + * PickleLauncher + * Copyright (C) 2010-2011 Scott Smith + * + * 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 . + * + * @section LOCATION + */ + +#include "cprofile.h" + +CProfile::CProfile() : CBase(), + LaunchableDirs (false), + LauncherPath (""), + LauncherName (""), + FilePath (""), + TargetApp (""), + ZipFile (""), + EntryFilter (""), + Commands (), + Extensions (), + Entries (), + AlphabeticIndices (), + Minizip (), + Plugins (), + Rom ("") +{ + AlphabeticIndices.resize(TOTAL_LETTERS, 0); +} + +CProfile::~CProfile() +{ +} + +int8_t CProfile::Load( const string& location, const string& delimiter ) +{ + bool readline; + string line; + ifstream fin; + + fin.open(location.c_str(), ios_base::in); + + if (!fin) + { + Log( "Error: Failed to open profile\n" ); + return 1; + } + + // Read in the profile + if (fin.is_open()) + { + readline = true; + while (!fin.eof()) + { + if (readline == true) + { + getline(fin,line); + } + + if (line.length() > 0) + { + // Common options + if (UnprefixString( TargetApp, line, PROFILE_TARGETAPP ) == true) + { + readline = true; + } + else + if (UnprefixString( FilePath, line, PROFILE_FILEPATH ) == true) + { + CheckPath(FilePath); + readline = true; + } + else // Commands + if (line.at(0) == '<' && line.at(line.length()-1) == '>') + { + if (LoadCmd(fin, line, delimiter)) + { + Log( "Error: Loading command from %s\n", location.c_str() ); + return 1; + } + readline = false; + } + else // Extensions + if (line.at(0) == '[' && line.at(line.length()-1) == ']') + { + if (LoadExt(fin, line, delimiter)) + { + Log( "Error: Loading extension from %s\n", location.c_str() ); + return 1; + } + readline = false; + } + else // Entries + if (line.at(0) == '{' && line.at(line.length()-1) == '}') + { + if (LoadEntry(fin, line, delimiter)) + { + Log( "Error: Loading entry from %s\n", location.c_str() ); + return 1; + } + readline = false; + } + else + { + readline = true; + } + } + else + { + readline = true; + } + } + fin.close(); + } + else + { + Log( "Error: Failed to open profile\n" ); + return 1; + } + + // Load plugins + if (LoadPlugins()) + { + Log( "Error: Loading plugin from %s\n", location.c_str() ); + return 1; + } + + // Sanity checks + if (FilePath.length()<=0) + { + Log( "Error: file path was not read from profile\n" ); + return 1; + } + if (Extensions.size()<=0) + { + Log( "Error: no extensions were read from profile\n" ); + return 1; + } + + return 0; +} + +int8_t CProfile::LoadCmd( ifstream& fin, string& line, const string& delimiter ) +{ + uint8_t i; + uint8_t count; + command_t cmd; + argument_t arg; + vector parts; + + // Command name + cmd.Name = line.substr( 1, line.length()-2 ); + + // Command location and script + getline(fin,line); + if (UnprefixString( line, line, PROFILE_CMDPATH ) == true) + { + cmd.Command = line.substr( line.find_last_of('/')+1 ); + cmd.Path = line.substr( 0, line.find_last_of('/')+1 ); + + if (cmd.Command.compare("./") == 0) + { + cmd.Command = string(getenv("PWD"))+"/"; + } + CheckPath(cmd.Path); + + getline(fin,line); + } + else + { + Log( "Error: %s not found\n", PROFILE_CMDPATH ); + return 1; + } + + // Command arguments and values + count = 0; + while (UnprefixString( line, line, PROFILE_CMDARG ) == true) + { + SplitString( delimiter, line, parts ); + + if (parts.size() >= ARG_MIN_COUNT) + { + arg.Flag = parts.at(0); + arg.Default = a_to_i( parts.at(1) ); + + arg.Names.clear(); + arg.Values.clear(); + for (i=2; i= arg.Values.size()) + { + arg.Default = arg.Values.size()-1; + } + + cmd.Arguments.push_back( arg ); + + count++; + getline( fin, line ); + } + else + { + Log( "Error: Not enough argument parts detected\n" ); + return 1; + } + } + + if (count<1) + { + Log( "Error: %s not found at least once\n", PROFILE_CMDARG ); + return 1; + } + + Commands.push_back(cmd); + return 0; +} + +int8_t CProfile::LoadPlugins() +{ + plugin_t plugin; + oneplugin_t one; + string line; + + Plugins.clear(); + // all hardcoded for now! + // init video plugins + plugin.Name=string("Video Plugin"); + plugin.TextFile=string("videodriver"); +// plugin.TextFile+=string(".txt"); + // videos plugins + one.Name="Glide GLES2"; + one.So="mupen64plus-video-glide64mk2"; + plugin.Plugins.push_back(one); + one.Name="Rice GLES2"; + one.So="mupen64plus-video-rice"; + plugin.Plugins.push_back(one); + one.Name="Rice GLES1.1"; + one.So="mupen64plus-video-ricees1"; + plugin.Plugins.push_back(one); + one.Name="GLES2N64"; + one.So="mupen64plus-video-gles2n64"; + plugin.Plugins.push_back(one); + one.Name="Arachnoid GLES1.1"; + one.So="mupen64plus-video-arachnoid"; + plugin.Plugins.push_back(one); + + Plugins.push_back(plugin); + + plugin.Plugins.clear(); + // init audio plugins + plugin.Name="Audio Plugin"; + plugin.TextFile="audiodriver"; +// plugin.TextFile+=".txt"; + // audios plugins + one.Name="Notaz Audio"; + one.So="notaz-audio"; + plugin.Plugins.push_back(one); + one.Name="SDL Audio"; + one.So="mupen64plus-audio-sdl"; + plugin.Plugins.push_back(one); + + Plugins.push_back(plugin); + + plugin.Plugins.clear(); + // init rsp plugins + plugin.Name="RSP Plugin"; + plugin.TextFile="rspdriver"; +// plugin.TextFile+=".txt"; + // audios plugins + one.Name="Default HLE RSP"; + one.So="mupen64plus-rsp-hle"; + plugin.Plugins.push_back(one); + one.Name="Z64 LLE RSP with HLE Video"; + one.So="mupen64plus-rsp-z64-hlevideo"; + plugin.Plugins.push_back(one); + one.Name="Z64 LLE RSP"; + one.So="mupen64plus-rsp-z64"; + plugin.Plugins.push_back(one); + + Plugins.push_back(plugin); + //Get default values + ifstream fplug; + int index, i; + for (index=0; index 0) + { + //search for a match + for (i=0; i parts; + extension_t ext; + argument_t arg; + argforce_t argforce; + exeforce_t exeforce; + string extensions; + + // Extension names + extensions = line.substr(1, line.length()-2); + SplitString( delimiter, extensions, parts ); + ext.extName.clear(); + for (i=0; i= ARG_MIN_COUNT) + { + arg.Flag = parts.at(0); + arg.Default = a_to_i( parts.at(1) ); + + arg.Names.clear(); + arg.Values.clear(); + for (i=2; i= arg.Values.size()) + { + arg.Default = arg.Values.size()-1; + } + + ext.Arguments.push_back(arg); + + count++; + getline(fin,line); + } + else + { + Log( "Error: Not enough argument parts detected\n" ); + return 1; + } + } + + if (count<1) + { + Log( "Error: %s not found at least once\n", PROFILE_EXTARG ); + return 1; + } + + // Extension argforces + while (UnprefixString( line, line, PROFILE_ARGFORCE ) == true) + { + SplitString( delimiter, line, parts ); + + if (parts.size() == ARGFORCE_COUNT) + { + argforce.Path = parts.at(0); + CheckPath(argforce.Path); + + argforce.Argument = a_to_i( parts.at(1) ); + argforce.Value = parts.at(2); + ext.ArgForces.push_back( argforce ); + } + else + { + Log( "Error: %s wrong number of parts actual: %d expected: %s\n", PROFILE_ARGFORCE, parts.size(), ARGFORCE_COUNT ); + return 1; + } + getline( fin, line ); + } + + // Exe path forces + while (UnprefixString( line, line, PROFILE_EXEFORCE ) == true) + { + SplitString( delimiter, line, parts ); + + if (parts.size()>=EXEFORCE_COUNT) + { + exeforce.exeName = parts.at(0).substr( line.find_last_of('/')+1 ); + exeforce.exePath = parts.at(0).substr( 0, line.find_last_of('/')+1 ); + + if (exeforce.exePath.compare("./") == 0) + { + exeforce.exePath = string(getenv("PWD"))+"/"; + } + + exeforce.Files.clear(); + for (i=1; i 0) + { + for (i=0; i= 0) + { + LaunchableDirs = true; + } + } + } + + return 0; +} + +int8_t CProfile::LoadEntry( ifstream& fin, string& line, const string& delimiter ) +{ + uint16_t i; + string::size_type pos1,pos2; + entry_t entry; + vector parts; + + // Extension name + pos1 = line.find_last_of('/'); + pos2 = line.find_last_of(delimiter); + entry.Path = line.substr( 1, pos1 ); + entry.Name = line.substr( pos1+1, pos2-pos1-1 ); + entry.Alias = line.substr( pos2+1, line.length()-pos2-2 ); + entry.Custom = true; + + // Extension executable + getline(fin,line); + if (UnprefixString( line, line, PROFILE_ENTRY_CMDS ) == true) + { + SplitString( delimiter, line, parts ); + for (i=0; i" << endl; + fout << PROFILE_CMDPATH << Commands.at(index).Path << Commands.at(index).Command << endl; + // Arguments + for (i=0; i0) + { + fout << delimiter; + } + fout << Extensions.at(index).extName.at(i); + } + fout << "]" << endl; + + // Executables + fout << PROFILE_EXEPATH + Extensions.at(index).exePath + Extensions.at(index).exeName << endl; + + // Blacklist + if (Extensions.at(index).Blacklist.size()>0) + { + fout << PROFILE_BLACKLIST; + for (i=0; i0) + { + fout << delimiter; + } + fout << Extensions.at(index).Blacklist.at(i); + } + fout << endl; + } + // Arguments + for (i=0; i0) + { + fout << delimiter; + } + fout << Entries.at(index).CmdValues.at(i); + } + fout << endl; + // Entry argument values + fout << PROFILE_ENTRY_ARGS; + for (i=0; i0) + { + fout << delimiter; + } + fout << Entries.at(index).ArgValues.at(i); + } + fout << endl; + } + } + + fout.close(); + } + else + { + Log( "Failed to open profile\n" ); + return 1; + } + return 0; +} + +int8_t CProfile::ScanEntry( listitem_t& item, vector& items ) +{ + int16_t ext_index; + uint16_t i, j; + listoption_t option; + + items.clear(); + + // Find the extension + if (item.Type == TYPE_DIR && LaunchableDirs == true) + { + ext_index = FindExtension(EXT_DIRS); + } + else + { + ext_index = FindExtension(item.Name); + } + + if (CheckRange( ext_index, Extensions.size())) + { + option.Extension = ext_index; + + // Scan for command arguments + for (i=0; i& values ) +{ + uint16_t index; + + values.clear(); + + if (CheckRange( item.Command, Commands.size() )) + { + if (CheckRange(item.Argument, Commands.at(item.Command).Arguments.size() )) + { + for (index=0; index& items ) +{ + DIR *dp; + struct dirent *dirp; + string filename; + bool found; + int16_t alpha_index; + int16_t ext_index; + uint16_t file, i; + listitem_t item; + entry_t entry; + vector dirs; + vector files; + vector::iterator sort_index; + + dirs.clear(); + files.clear(); + items.clear(); + + if (ZipFile.length() == 0) + { + if((dp = opendir(location.c_str())) == NULL) + { + Log( "Failed to open dir path %s\n", location.c_str() ); + return 1; + } + + while ((dirp = readdir(dp)) != NULL) + { + filename = string(dirp->d_name); + + if (filename.length() > 0) + { + // Skip . and .. + if (filename.compare(".") == 0 || filename.compare("..") == 0) + continue; + + // Skip hidden files and folders + if (showhidden == false && filename.at(0) == '.') + continue; + + item.Entry = -1; + item.Name = filename; + if (dirp->d_type == DT_DIR) // Directories + { + // Filter out by blacklist + ext_index = FindExtension( EXT_DIRS ); + found = false; + if (CheckRange( ext_index, Extensions.size() )) + { + for (i=0; i= 0 && showzip == false)) // only filter zip if internal support is off + { + // Filter out files by extension + ext_index = FindExtension( files.at(file) ); + + // Filter out by blacklist + found = false; + if (CheckRange( ext_index, Extensions.size() )) + { + for (i=0; i 0) + { + if (lowercase(files.at(file)).find( lowercase(EntryFilter), 0) != string::npos) + { + found = false; + } + else + { + found = true; + } + } + + // If here then item is valid and determine if an entry exists + if (found == false) + { + // Add to display list + item.Name = files.at(file); + // Check for zip file + if (CheckExtension( files.at(file), ZIP_EXT) >= 0) + { + item.Type = TYPE_ZIP; + } + else + { + item.Type = TYPE_FILE; + } + + // Find if an entry has been defined + item.Entry = -1; + for (i=0; i 0 ) + { + alpha_index = tolower(items.at(i).Name.at(0))-'a'; + if (alpha_index < 'a' || alpha_index > 'z') + { + alpha_index = TOTAL_LETTERS-1; + } + + if (CheckRange( alpha_index, AlphabeticIndices.size() )) + { + if (AlphabeticIndices.at(alpha_index) == 0) + { + AlphabeticIndices.at(alpha_index) = i; + } + } + else + { + Log( "Error: Scandir alpha_index out of range\n" ); + return 1; + } + } + } + } + alpha_index = 0; + for (i=0; i= 0) + { + return i; + } + } + } + + return -1; +} + +void CProfile::ScanDefPlugins( vector& items ) +{ + items.clear(); + listoption_t itm; + for (int i=0; i& items ) +{ + items.clear(); + listitem_t itm; + for (int i=0; i b +bool CompareItems( listitem_t a, listitem_t b ) +{ + // Folders should be above files + if (a.Type == TYPE_DIR && b.Type >= TYPE_FILE) + { + return true; + } + else if (a.Type >= TYPE_FILE && b.Type == TYPE_DIR) + { + return false; + } + else + { + // Convert to lower cases, so that upper case files are sorted with lower case files + transform( a.Name.begin(), a.Name.end(), a.Name.begin(), (int (*)(int))tolower ); + transform( b.Name.begin(), b.Name.end(), b.Name.begin(), (int (*)(int))tolower ); + + if (a.Name.compare(b.Name) >= 0) + { + return false; + } + else + { + return true; + } + } +} + +void CProfile::SaveDef1Plugin( int8_t which, int8_t index ) +{ + ofstream fout; + + fout.open( (Plugins.at(which).TextFile+".txt").c_str(), ios_base::trunc ); + if (!fout) + { + Log( "Failed to open profile\n" ); + return; + } + + // Write out the profile + if (fout.is_open()) + { + fout << Plugins.at(which).Plugins.at(index).So << endl; + fout.close(); + } + // Change the default + Plugins[which].Which = index; + return; +} + +void CProfile::ScanRomPlugins( const string& name, vector& items ) +{ + string line; + vector parts; + + Rom = RomCRC(name); + + items.clear(); + listoption_t itm; + for (int i=0; i Names; /** @brief Names for the possible values */ + vector Values; /** @brief Values for the argument */ +}; + +/** @brief Data structure for overriding argument values that reside in the path + */ +struct argforce_t { + argforce_t() : Argument(0), Path(""), Value("") {}; + uint8_t Argument; /** @brief The index of the agrument to override */ + string Path; /** @brief The location of target files to override */ + string Value; /** @brief Value to overide the argument with */ +}; + +/** @brief Data structure for overriding the exe path for listed files. + */ +struct exeforce_t { + exeforce_t() : exeName(""), exePath(""), Files() {}; + string exeName; /** @brief The executable name to pass the detected files to. */ + string exePath; /** @brief The path to the executable. */ + vector Files; /** @brief Value to overide the argument with */ +}; + +/** @brief Data structure for an command that is run before the application + */ +struct command_t { + command_t() : Name(""), Command(""), Path(""), Arguments() {}; + string Name; /** @brief Display name for the command. */ + string Command; /** @brief Executable name for the command. */ + string Path; /** @brief Path to the executable. */ + vector Arguments; /** @brief Arguments to apply to the command. */ +}; + +/** @brief Data structure for an file extension type + */ +struct extension_t { + extension_t() : exeName(""), exePath(""), extName(), Blacklist(), Arguments(), ArgForces(), ExeForces() {}; + string exeName; /** @brief The executable name to pass the detected files to. */ + string exePath; /** @brief The path to the executable. */ + vector extName; /** @brief The extenion (usually 3 letters). */ + vector Blacklist; /** @brief List of filenames that will be filtered from the selection output. */ + vector Arguments; /** @brief Arguments to apply to the appliction. */ + vector ArgForces; /** @brief Overide arguments based on path. */ + vector ExeForces; /** @brief Overide the exe path based on file names. */ +}; + +/** @brief Data structure for a detected entry that has been set with custom arg/cmd values + */ +struct entry_t { + entry_t() : Custom(false), Name(""), Path(""), Alias(""), CmdValues(), ArgValues() {}; + bool Custom; /** @brief Does the entry have values that are different than the defaults */ + string Name; /** @brief Name of the entry */ + string Path; /** @brief Path to the file */ + string Alias; /** @brief Overides the actual filename for display */ + vector CmdValues; /** @brief The current selected values for the commands */ + vector ArgValues; /** @brief The current selected values for the arguments */ +}; + +//SEB +/** @brief Data structure for a plugin that has been set in profile + */ +struct oneplugin_t { + oneplugin_t() : So(""), Name(""), Desc("") {}; + string So; /** @brief So Name of the entry */ + string Name; /** @brief Clear Name to the file */ + string Desc; /** @brief Description of plugin */ +}; + +/** @brief Data structure for a plugin that has been set in profile + */ +struct plugin_t { + plugin_t() : Name(""), TextFile(""), Alias(""), Which(0), Rom(-1), Plugins() {}; + string Name; /** @brief Name of the entry */ + string TextFile; /** @brief Path to the file */ + string Alias; /** @brief Overides the actual filename for display */ + uint16_t Which; /** @brief Current selected plugin */ + int16_t Rom; /** @brief Current plugin for selected Rom */ + vector Plugins; /** @brief The current plugins */ +}; + +/** @brief This class controls loading, processing, and saving of profile data + */ +class CProfile : public CBase +{ + public: + /** Constructor. */ + CProfile(); + /** Destructor. */ + virtual ~CProfile(); + + /** @brief Load the profile data from file and store in memory. + * @param location : path to the profile file. + * @param delimiter : the delimiter used between options. + * @return 0 if passed 1 if failed. + */ + int8_t Load ( const string& location, const string& delimiter ); + + /** @brief Save the profile data to file from memory. + * @param location : path to the profile file. + * @param delimiter : the delimiter used between options. + * @return 0 if passed 1 if failed. + */ + int8_t Save ( const string& location, const string& delimiter ); + + /** @brief Load a command from a line from the profile. + * @param fin : file input. + * @param line : current read line. + * @param delimiter : the delimiter used between options. + * @return 0 if passed 1 if failed. + */ + int8_t LoadCmd ( ifstream& fin, string& line, const string& delimiter ); + + /** @brief Load plugins from the profile. + * @return 0 if passed 1 if failed. + */ + int8_t LoadPlugins ( ); + + /** @brief Load a extension from a line from the profile. + * @param fin : file input. + * @param line : current read line. + * @param delimiter : the delimiter used between options. + * @return 0 if passed 1 if failed. + */ + int8_t LoadExt ( ifstream& fin, string& line, const string& delimiter ); + + /** @brief Load a entry from a line from the profile. + * @param fin : file input. + * @param line : current read line. + * @param delimiter : the delimiter used between options. + * @return 0 if passed 1 if failed. + */ + int8_t LoadEntry ( ifstream& fin, string& line, const string& delimiter ); + + /** @brief Scan an entry for command and arguments and load them into a list. + * @param item : the selected item from the list. + * @param items : list to load into. + * @return 0 if passed 1 if failed. + */ + int8_t ScanEntry ( listitem_t& item, vector& items ); + + /** @brief Add an entry that will contain custom values. + * @param argument : argument with the custom value. + * @param name : name for the new entry. + * @return -1 if failed, else the new size of the entry list. + */ + int16_t AddEntry ( listoption_t& argument, const string& name ); + + /** @brief Scan an entry for values and load them into a list. + * @param item : argument with the custom value. + * @param values : values for the argument. + */ + void ScanArgument ( listoption_t& item, vector& values ); + + /** @brief Scan an the current path for dirs and runable files. + * @param location : path the scan. + * @param showhidden : if true include hidden items in output list, else ignore. + * @param showzip : if true include zip items in output list, else put through filters. + * @param items : entries det. + * @return 0 if passed 1 if failed. + */ + int8_t ScanDir ( string location, bool showhidden, bool showzip, vector& items ); + + /** @brief Find the extension a file belongs to. + * @param ext : extension to search for. + * @return -1 if failed, else the index of the ext structure. + */ + int16_t FindExtension ( const string& ext ); + + /** @brief Scan def. plugins and load them into a list. + * @param values : values for the argument. + */ + void ScanDefPlugins ( vector& items ); + + /** @brief Scan rom plugins and load them into a list. + * @param values : values for the argument. + */ + void ScanRomPlugins ( const string& name, vector& items ); + + /** @brief Scan def. one plugin type and load them into a list. + * @param which : which of the default plugins + * @param values : values for the argument. + */ + void ScanDef1Plugins ( int8_t which, vector& items ); + + void ScanRom1Plugins ( int8_t which, vector& items ); + + /** @brief Save 1 type of default plugin + */ + void SaveDef1Plugin ( int8_t which, int8_t index ); + + /** @brief Save plugin for curent Rom + */ + void SaveRom1Plugin ( int8_t which, int8_t index ); + + /** @brief Get CRC of Rom file + */ + string RomCRC (const string& name); + + int8_t FindPlugin(const string& name); + int8_t Find1Plugin(int8_t which, const string& name); + + bool LaunchableDirs; /**< If true directories are considered as launchable, if false browsing is on. */ + string LauncherPath; /**< Path where the launcher was executed from. */ + string LauncherName; /**< Name of the launcher when executed. */ + string FilePath; /**< Current path for searching for runable files. */ + string TargetApp; /**< Label for the target appliction the launcher is executing. */ + string ZipFile; /**< If not empty then the currently loaded zip file. */ + string EntryFilter; + vector Commands; /**< Commands to be run before executing the target application. */ + vector Extensions; /**< File extensions runable by the target application. */ + vector Entries; /**< Entries with custom values. */ + vector AlphabeticIndices; /**< Set to cause the current directory to be rescaned. */ + string Rom; /**< CRC of the current rom */ + //SEB + vector Plugins; /**< All plugins */ + CZip Minizip; /**< Handles examing and extracting zip files. */ +}; + +bool CompareItems( listitem_t a, listitem_t b ); /**< Compare two listitems, which sort by type and then by name. */ + +#endif // CPROFILE_H diff --git a/source/mupen64launcher/src/cselector.cpp b/source/mupen64launcher/src/cselector.cpp new file mode 100755 index 0000000..cd55971 --- /dev/null +++ b/source/mupen64launcher/src/cselector.cpp @@ -0,0 +1,2678 @@ +/** + * @section LICENSE + * + * PickleLauncher + * Copyright (C) 2010-2011 Scott Smith + * + * 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 . + * + * @section LOCATION + */ + +#include "cselector.h" + +CSelector::CSelector() : CBase(), + Redraw (true), + SkipFrame (false), + Rescan (true), + RefreshList (true), + SetOneEntryValue (false), + SetAllEntryValue (false), + TextScrollDir (true), + ExtractAllFiles (false), + DrawState_Title (true), + DrawState_About (true), + DrawState_Filter (true), + DrawState_FilePath (true), + DrawState_Index (true), + DrawState_ZipMode (true), + DrawState_Preview (true), + DrawState_ButtonL (true), + DrawState_ButtonR (true), + Mode (MODE_SELECT_ENTRY), + LastSelectedEntry (0), + TextScrollOffset (0), + CurScrollSpeed (0), + CurScrollPause (0), + ListNameHeight (0), + FramesDrawn (0), + FramesSkipped (0), + FramesSleep (0), +#if defined(DEBUG) + FPSDrawn (0), + FPSSkip (0), + FPSSleep (0), + FrameCountTime (0), + LoopTimeAverage (0), +#endif + FrameEndTime (0), + FrameStartTime (0), + FrameDelay (0), + Mouse (), + Joystick (NULL), + Screen (NULL), + ImageBackground (NULL), + ImagePointer (NULL), + ImageSelectPointer (NULL), + ImagePreview (NULL), + ImageTitle (NULL), + ImageAbout (NULL), + ImageFilePath (NULL), + ImageFilter (NULL), + ImageIndex (NULL), + ImageZipMode (NULL), +#if defined(DEBUG) + ImageDebug (NULL), +#endif + ImageButtons (), + Fonts (), + Config (), + Profile (), + System (), + ConfigPath (DEF_CONFIG), + ProfilePath (DEF_PROFILE), + ZipListPath (DEF_ZIPLIST), + EventReleased (), + EventPressCount (), + ButtonModesLeft (), + ButtonModesRight (), + DisplayList (), + LabelButtons (), + ListNames (), + ItemsEntry (), + ItemsArgument (), + ItemsValue (), + ItemsDefPlugin (), + WhichPlugin (0), + ItemsRomOption (), + ItemsRomPlugin (), + WhichRomPlugin (0), + RectEntries (), + RectButtonsLeft (), + RectButtonsRight (), + ScreenRectsDirty () +{ + Fonts.resize( FONT_SIZE_TOTAL, NULL ); + + ButtonModesLeft.resize( BUTTONS_MAX_LEFT ); + ButtonModesRight.resize( BUTTONS_MAX_RIGHT ); + RectButtonsLeft.resize( BUTTONS_MAX_LEFT ); + RectButtonsRight.resize( BUTTONS_MAX_RIGHT ); + ImageButtons.resize( EVENT_TOTAL, NULL ); + LabelButtons.resize( EVENT_TOTAL, "" ); + + LabelButtons.at(EVENT_ONE_UP) = BUTTON_LABEL_ONE_UP; + LabelButtons.at(EVENT_ONE_DOWN) = BUTTON_LABEL_ONE_DOWN; + LabelButtons.at(EVENT_PAGE_UP) = BUTTON_LABEL_PAGE_UP; + LabelButtons.at(EVENT_PAGE_DOWN) = BUTTON_LABEL_PAGE_DOWN; + LabelButtons.at(EVENT_DIR_UP) = BUTTON_LABEL_DIR_UP; + LabelButtons.at(EVENT_DIR_DOWN) = BUTTON_LABEL_DIR_DOWN; + LabelButtons.at(EVENT_ZIP_MODE) = BUTTON_LABEL_ZIP_MODE; + LabelButtons.at(EVENT_CFG_APP) = BUTTON_LABEL_CONFIG; + LabelButtons.at(EVENT_CFG_ITEM) = BUTTON_LABEL_EDIT; + LabelButtons.at(EVENT_SET_ONE) = BUTTON_LABEL_SET_ONE; + LabelButtons.at(EVENT_SET_ALL) = BUTTON_LABEL_SET_ALL; + LabelButtons.at(EVENT_BACK) = BUTTON_LABEL_BACK; + LabelButtons.at(EVENT_SELECT) = BUTTON_LABEL_SELECT; + LabelButtons.at(EVENT_QUIT) = BUTTON_LABEL_QUIT; + + DisplayList.resize( MODE_TOTAL ); + + EventPressCount.resize( EVENT_TOTAL, EVENT_LOOPS_OFF ); + EventReleased.resize( EVENT_TOTAL, false ); +} + +CSelector::~CSelector() +{ +} + +int8_t CSelector::Run( int32_t argc, char** argv ) +{ + int8_t result; + int16_t selection; + + result = 0; + + ProcessArguments( argc, argv ); + + System.SetCPUClock( Config.CPUClock ); + + // Load video,input,profile resources + if (OpenResources()) + { + result = 1; + } + + // Display and poll the user for a selection + if (result == 0) + { + selection = DisplayScreen(); + + // Setup a exec script for execution following termination of this application + if (selection >= 0) + { + if (RunExec( selection )) + { + result = 1; + } + } + else if (selection < -1) + { + result = 1; + } + else + { + result = 0; + } + } + + // Release resources + CloseResources( result ); + + return result; +} + +void CSelector::ProcessArguments( int argc, char** argv ) +{ + uint8_t arg_index; + string launcher; + string argument; + + launcher = string(argv[0]); + Profile.LauncherName = launcher.substr( launcher.find_last_of('/')+1 ); + Profile.LauncherPath = launcher.substr( 0, launcher.find_last_of('/')+1 ); + if (Profile.LauncherPath.compare("./") == 0 || Profile.LauncherPath.length() == 0) + { + Profile.LauncherPath = string(getenv("PWD"))+"/"; + } + +#if defined(DEBUG) + Log( "Running from '%s'\n", launcher.c_str() ); +#endif + Log( "Running from '%s' as '%s'\n", Profile.LauncherPath.c_str(), Profile.LauncherName.c_str() ); + + for (arg_index=0; arg_index 0) + { + text += " for " + Profile.TargetApp; + } + ImageTitle = TTF_RenderText_Solid( Fonts.at(FONT_SIZE_LARGE), text.c_str(), Config.Colors.at(Config.ColorFontFiles) ); + if (ImageTitle == NULL) + { + Log( "Failed to create TTF surface with TTF_RenderText_Solid: %s\n", TTF_GetError() ); + return 1; + } + + // About text + text = "Written by " + string(APPAUTHOR) + " " + string(APPCOPYRIGHT); + ImageAbout = TTF_RenderText_Solid( Fonts.at(FONT_SIZE_SMALL), text.c_str(), Config.Colors.at(Config.ColorFontFiles) ); + if (ImageAbout == NULL) + { + Log( "Failed to create TTF surface with TTF_RenderText_Solid: %s\n", TTF_GetError() ); + return 1; + } + + + return 0; +} + +void CSelector::CloseResources( int8_t result ) +{ + uint8_t button_index; + + if (result == 0) + { + Config.Save( ConfigPath ); + Profile.Save( ProfilePath, Config.Delimiter ); + } + + if (Config.UseZipSupport == true) + { + Profile.Minizip.SaveUnzipList( ZipListPath ); + } + + // Close joystick + if (Joystick != NULL) + { + Log( "Closing SDL Joystick.\n" ); + SDL_JoystickClose( Joystick ); + Joystick = NULL; + } + + // Close fonts + Log( "Closing TTF fonts.\n" ); + if (Fonts.at(FONT_SIZE_SMALL) != NULL) + { + TTF_CloseFont( Fonts.at(FONT_SIZE_SMALL) ); + Fonts.at(FONT_SIZE_SMALL) = NULL; + } + if (Fonts.at(FONT_SIZE_MEDIUM) != NULL) + { + TTF_CloseFont( Fonts.at(FONT_SIZE_MEDIUM) ); + Fonts.at(FONT_SIZE_MEDIUM) = NULL; + } + if (Fonts.at(FONT_SIZE_LARGE) != NULL) + { + TTF_CloseFont( Fonts.at(FONT_SIZE_LARGE) ); + Fonts.at(FONT_SIZE_LARGE) = NULL; + } + + // Free images + FREE_IMAGE( ImageBackground ); + FREE_IMAGE( ImagePointer ); + FREE_IMAGE( ImageSelectPointer ); + FREE_IMAGE( ImagePreview ); + FREE_IMAGE( ImageTitle ); + FREE_IMAGE( ImageAbout ); + FREE_IMAGE( ImageFilePath ); + FREE_IMAGE( ImageFilter ); + FREE_IMAGE( ImageIndex ); + FREE_IMAGE( ImageZipMode ); +#if defined(DEBUG) + FREE_IMAGE( ImageDebug ); +#endif + for (button_index=0; button_index Config.ScreenWidth ) + { + x = Config.ScreenWidth-1; + Log( "ERROR: UpdateRect X was out of bounds\n" ); + } + + if( y > Config.ScreenHeight ) + { + y = Config.ScreenHeight-1; + Log( "ERROR: UpdateRect Y was out of bounds\n" ); + } + + if( x + w > Config.ScreenWidth ) + { + w = Config.ScreenWidth-x; + Log( "ERROR: UpdateRect W was out of bounds\n" ); + } + + if( y + h > Config.ScreenHeight ) + { + h = Config.ScreenHeight-y; + Log( "ERROR: UpdateRect H was out of bounds\n" ); + } + + rect.x = x; + rect.y = y; + rect.w = w; + rect.h = h; + + ScreenRectsDirty.push_back( rect ); + } +} + +void CSelector::UpdateScreen( void ) +{ +#if defined(DEBUG_FORCE_REDRAW) + Redraw = true; +#endif + + if (SkipFrame == false && Redraw == true) + { + if (Config.ScreenFlip == true) + { + if (SDL_Flip( Screen ) != 0) + { + Log( "Failed to swap the buffers: %s\n", SDL_GetError() ); + } + } + else + { + SDL_UpdateRects( Screen, ScreenRectsDirty.size(), &ScreenRectsDirty[0] ); + } + + Redraw = false; + FramesDrawn++; + } + else + { + if (SkipFrame == true) + { + FramesSkipped++; + } + else + { + FramesSleep++; + } + } + ScreenRectsDirty.clear(); + + FrameEndTime = SDL_GetTicks(); + FrameDelay = (MS_PER_SEC/FRAMES_PER_SEC) - (FrameEndTime - FrameStartTime); + +#if defined(DEBUG_FPS) + LoopTimeAverage = (LoopTimeAverage + (FrameEndTime - FrameStartTime))/2; +#endif + + if (FrameDelay < 0) + { + if (FramesSkipped/FramesDrawn < FRAME_SKIP_RATIO) + { + SkipFrame = true; + } + else // Force a frame to be drawn + { + SkipFrame = false; + } + } + else + { + SkipFrame = false; + SDL_Delay( MIN(FrameDelay, MS_PER_SEC) ); + } + FrameStartTime = SDL_GetTicks(); + +#if defined(DEBUG_FPS) + if (FrameStartTime - FrameCountTime >= MS_PER_SEC) + { + FrameCountTime = FrameStartTime; + FPSDrawn = FramesDrawn; + FPSSkip = FramesSkipped; + FPSSleep = FramesSleep; + FramesDrawn = 1; + FramesSkipped = 0; + FramesSleep = 0; + + cout << "DEBUG total " << i_to_a(FPSDrawn+FPSSkip+FPSSleep) + << " fps " << i_to_a(FPSDrawn) << " skip " << i_to_a(FPSSkip) << " slp " << i_to_a(FPSSleep) + << " loop " << i_to_a(LoopTimeAverage) << endl; + } +#endif +} + +void CSelector::SelectMode( void ) +{ + uint8_t old_mode; + + old_mode = Mode; + + switch (Mode) + { + case MODE_SELECT_ENTRY: + if (IsEventOn( EVENT_CFG_ITEM ) == true) + { + if (ItemsEntry.size()>0) + { + if (ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Type == TYPE_FILE ) +// || (ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Type == TYPE_DIR && Profile.LaunchableDirs == true)) + { +// Profile.ScanRomPlugins(Profile.FilePath+ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Name, ItemsRomOption); + // Per Rom Plugin selection. Find ROMCRC and Load Plugins for this rom + Mode = MODE_ROM_OPTION; + } + } + } + else if (IsEventOn( EVENT_CFG_APP ) == true) + { + Mode = MODE_SELECT_OPTION; + } + break; + case MODE_SELECT_ARGUMENT: + if (IsEventOn( EVENT_BACK ) == true) + { + Mode = MODE_SELECT_ENTRY; + } + if (IsEventOn( EVENT_SELECT ) == true) + { + Mode = MODE_SELECT_VALUE; + } + break; + case MODE_SELECT_VALUE: + if (IsEventOn( EVENT_BACK ) == true) + { + Mode = MODE_SELECT_ARGUMENT; + } + break; + case MODE_SELECT_OPTION: + if (IsEventOn( EVENT_BACK ) == true) + { + Mode = MODE_SELECT_ENTRY; + } + if (IsEventOn( EVENT_SELECT ) == true) + { + WhichPlugin = DisplayList.at(MODE_SELECT_OPTION).absolute; + Mode = MODE_SELECT_PLUGIN; + } + break; + case MODE_ROM_OPTION: + if (IsEventOn( EVENT_BACK ) == true) + { + Mode = MODE_SELECT_ENTRY; + } + if (IsEventOn( EVENT_SELECT ) == true) + { + WhichPlugin = DisplayList.at(MODE_ROM_OPTION).absolute; + Mode = MODE_ROM_PLUGIN; + } + break; + case MODE_SELECT_PLUGIN: + if (IsEventOn( EVENT_BACK ) == true) + { + Mode = MODE_SELECT_OPTION; + } + if (IsEventOn( EVENT_SELECT ) == true) + { + Profile.SaveDef1Plugin(WhichPlugin, DisplayList.at(MODE_SELECT_PLUGIN).absolute); + Mode = MODE_SELECT_OPTION; + } + break; + case MODE_ROM_PLUGIN: + if (IsEventOn( EVENT_BACK ) == true) + { + Mode = MODE_ROM_OPTION; + } + if (IsEventOn( EVENT_SELECT ) == true) + { + Profile.SaveRom1Plugin(WhichPlugin, ItemsRomPlugin[DisplayList.at(MODE_ROM_PLUGIN).absolute].Entry); + Mode = MODE_ROM_OPTION; + } + break; + default: + Mode = MODE_SELECT_ENTRY; + Log( "Error: Unknown Mode\n" ); + break; + } + + if (Mode != old_mode) + { + DrawState_ButtonL = true; + DrawState_ButtonR = true; + Rescan = true; + } +} + +int8_t CSelector::DisplaySelector( void ) +{ + SDL_Rect rect_pos = { Config.EntryXOffset, Config.EntryYOffset, 0 ,0 }; + + if (Rescan) + { + RescanItems(); + RefreshList = true; + Rescan = false; + } + + if (RefreshList) + { + PopulateList(); + DrawState_Index = true; + Redraw = true; + RefreshList = false; + } + + if (Redraw == true || CurScrollPause != 0 || CurScrollSpeed != 0 || TextScrollOffset != 0) + { + if (Config.ScreenFlip == true) + { + DrawState_Title = true; + DrawState_About = true; + DrawState_Filter = true; + DrawState_FilePath = true; + DrawState_Index = true; + DrawState_ZipMode = true; + DrawState_Preview = true; + DrawState_ButtonL = true; + DrawState_ButtonR = true; + } +#if defined(DEBUG_DRAW_STATES) + else + { + cout << "DEBUG " + << " " << i_to_a(DrawState_Title) + << " " << i_to_a(DrawState_About) + << " " << i_to_a(DrawState_Filter) + << " " << i_to_a(DrawState_FilePath) + << " " << i_to_a(DrawState_Index) + << " " << i_to_a(DrawState_ZipMode) + << " " << i_to_a(DrawState_Preview) + << " " << i_to_a(DrawState_ButtonL) + << " " << i_to_a(DrawState_ButtonR) << endl; + } +#endif + + // Draw background or clear screen + DrawBackground(); + + // Draw text titles to the screen + if (DrawText( rect_pos )) + { + return 1; + } + + // Draw the buttons for touchscreen + if (DrawButtons( rect_pos )) + { + return 1; + } + + // Draw the names for the items for display + if (DrawNames( rect_pos )) + { + return 1; + } + + // Custom mouse pointer + if (Config.ShowPointer == true && ImagePointer != NULL) + { + ApplyImage( Mouse.x, Mouse.y, ImagePointer, Screen, NULL ); + } + } + + return 0; +} + +void CSelector::DirectoryUp( void ) +{ + if (Profile.FilePath.length() > 0) + { + if (Profile.FilePath.at( Profile.FilePath.length()-1) == '/') + { + Profile.FilePath.erase( Profile.FilePath.length()-1 ); + } + Profile.FilePath = Profile.FilePath.substr( 0, Profile.FilePath.find_last_of('/', Profile.FilePath.length()-1) ) + '/'; + DrawState_FilePath = true; + Rescan = true; + } + else + { + Log( "Error: Filepath is empty\n" ); + } +} + +void CSelector::DirectoryDown( void ) +{ + if (DisplayList.at(MODE_SELECT_ENTRY).absolute < (int16_t)ItemsEntry.size() ) + { + if (ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Type == TYPE_DIR ) + { + Profile.FilePath += ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Name + '/'; + DrawState_FilePath = true; + Rescan = true; + + EventPressCount.at(EVENT_SELECT) = EVENT_LOOPS_OFF; + } + } + else + { + Log( "Error: Item index of %d too large for size of scanitems %d\n", DisplayList.at(MODE_SELECT_ENTRY).absolute, ItemsEntry.size() ); + } +} + +void CSelector::ZipUp( void ) +{ + DrawState_FilePath = true; + DrawState_ZipMode = true; + DrawState_ButtonL = true; + Rescan = true; + Profile.ZipFile = ""; +} + +void CSelector::ZipDown( void ) +{ + DrawState_FilePath = true; + DrawState_ZipMode = true; + DrawState_ButtonL = true; + Rescan = true; + Profile.ZipFile = ItemsEntry.at(DisplayList.at(Mode).absolute).Name; + EventPressCount.at( EVENT_SELECT ) = EVENT_LOOPS_OFF; +} + +void CSelector::RescanItems( void ) +{ + uint16_t total; + + switch (Mode) + { + case MODE_SELECT_ENTRY: + Profile.ScanDir( Profile.FilePath, Config.ShowHidden, Config.UseZipSupport, ItemsEntry ); + total = ItemsEntry.size(); + break; + case MODE_SELECT_ARGUMENT: + Profile.ScanEntry( ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute), ItemsArgument ); + total = ItemsArgument.size(); + break; + case MODE_SELECT_VALUE: + Profile.ScanArgument( ItemsArgument.at(DisplayList.at(MODE_SELECT_ARGUMENT).absolute), ItemsValue ); + total = ItemsValue.size(); + break; + case MODE_SELECT_OPTION: + //Profile.ScanOptions( ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute), ItemsArgument ); + Profile.ScanDefPlugins( ItemsArgument ); + total = ItemsArgument.size(); + break; + case MODE_ROM_OPTION: + //Profile.ScanOptions( ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute), ItemsArgument ); + Profile.ScanRomPlugins(Profile.FilePath+ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Name, ItemsRomOption); + total = ItemsRomOption.size(); + break; + case MODE_SELECT_PLUGIN: + //Profile.ScanOptions( ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute), ItemsArgument ); + Profile.ScanDef1Plugins( WhichPlugin, ItemsDefPlugin ); + total = ItemsDefPlugin.size(); + break; + case MODE_ROM_PLUGIN: + //Profile.ScanOptions( ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute), ItemsArgument ); + Profile.ScanRom1Plugins( WhichPlugin, ItemsRomPlugin ); + total = ItemsRomPlugin.size(); + break; + default: + total = 0; + Log( "Error: Unknown Mode\n" ); + break; + } + + if (total > Config.MaxEntries) + { + RectEntries.resize( Config.MaxEntries ); + } + else + { + RectEntries.resize( total ); + } + ListNames.resize( RectEntries.size() ); + + DisplayList.at(Mode).absolute = 0; + DisplayList.at(Mode).relative = 0; + DisplayList.at(Mode).first = 0; + DisplayList.at(Mode).last = 0; + DisplayList.at(Mode).total = total; +} + +void CSelector::PopulateList( void ) +{ + // Set limits + SelectionLimits( DisplayList.at( Mode ) ); + + switch (Mode) + { + case MODE_SELECT_ENTRY: + PopModeEntry(); + break; + case MODE_SELECT_ARGUMENT: + PopModeArgument(); + break; + case MODE_SELECT_VALUE: + PopModeValue(); + break; + case MODE_SELECT_OPTION: + PopModeOption(); + break; + case MODE_ROM_OPTION: + PopModeRomOption(); + break; + case MODE_SELECT_PLUGIN: + PopModePlugin(); + break; + case MODE_ROM_PLUGIN: + PopModeRomPlugin(); + break; + default: + Log( "Error: CSelector::PopulateList Unknown Mode\n" ); + break; + } +} + +void CSelector::PopModeEntry( void ) +{ + uint16_t i; + uint16_t index; + + for (i=0; i= 0) + { + ListNames.at(i).text = Profile.Entries.at(ItemsEntry.at(index).Entry).Alias; + } + if (ListNames.at(i).text.length() == 0) + { + ListNames.at(i).text = ItemsEntry.at(index).Name; + } + + if (Config.ShowExts == false) + { + ListNames.at(i).text = ListNames.at(i).text.substr( 0, ListNames.at(i).text.find_last_of(".") ); + } + ListNames.at(i).text = ListNames.at(i).text; + + if (index == DisplayList.at(Mode).absolute) + { + ListNames.at(i).font = FONT_SIZE_LARGE; + LoadPreview( ListNames.at(i).text ); // Load preview + } + else + { + ListNames.at(i).font = FONT_SIZE_MEDIUM; + } + + ListNames.at(i).color = Config.ColorFontFiles; + if (ItemsEntry.at(index).Type == TYPE_DIR) + { + ListNames.at(i).color = Config.ColorFontFolders; + } + } + else + { + Log( "Error: CSelector::PopulateModeSelectEntry Index Error\n" ); + } + } +} + +void CSelector::PopModeArgument( void ) +{ + uint16_t i; + uint16_t index; + + for (i=0; i= 0) + { + if (SetAllEntryValue == true) + { + Profile.Commands.at(argument.Command).Arguments.at(argument.Argument).Default = DisplayList.at(MODE_SELECT_VALUE).absolute; + } + defvalue = Profile.Commands.at(argument.Command).Arguments.at(argument.Argument).Default; + } + else + { + if (SetAllEntryValue == true) + { + Profile.Extensions.at(argument.Extension).Arguments.at(argument.Argument).Default = DisplayList.at(MODE_SELECT_VALUE).absolute; + } + defvalue = Profile.Extensions.at(argument.Extension).Arguments.at(argument.Argument).Default; + } + if (index==defvalue) + { + ListNames.at(i).text += '*'; + } + + // Set the color for the selected item for the entry + ListNames.at(i).color = Config.ColorFontFiles; + if (ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Entry<0) + { + // A custom value has been selected, so create a new entry + if (SetOneEntryValue == true) + { + entry = Profile.AddEntry( argument, ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Name ); + if (entry>0) + { + ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Entry = entry; + } + else + { + Log( "Error: Could not create new entry\n" ); + } + } + else if (index==defvalue) + { + ListNames.at(i).color = COLOR_RED; + } + } + + if (ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Entry>=0) + { + if (ItemsArgument.at(DisplayList.at(MODE_SELECT_ARGUMENT).absolute).Command >= 0) + { + if (SetOneEntryValue == true || SetAllEntryValue == true) + { + Profile.Entries.at(ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Entry).CmdValues.at(argument.Command+argument.Argument) = DisplayList.at(MODE_SELECT_VALUE).absolute; + } + if (index == Profile.Entries.at(ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Entry).CmdValues.at(argument.Command+argument.Argument)) + { + ListNames.at(i).color = COLOR_RED; + } + } + else + { + if (SetOneEntryValue == true || SetAllEntryValue == true) + { + Profile.Entries.at(ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Entry).ArgValues.at(argument.Argument) = DisplayList.at(MODE_SELECT_VALUE).absolute; + } + if (index == Profile.Entries.at(ItemsEntry.at(DisplayList.at(MODE_SELECT_ENTRY).absolute).Entry).ArgValues.at(argument.Argument)) + { + ListNames.at(i).color = COLOR_RED; + } + } + } + } + else + { + Log( "Error: PopModeValue index is out of range\n" ); + } + } + } + else + { + Log( "Error: PopModeValue argument index out of range\n" ); + } +} + +void CSelector::PopModeOption( void ) +{ + uint16_t i; + uint16_t index; + + for (i=0; i 0) + { + text_surface = TTF_RenderText_Solid( Fonts.at(FONT_SIZE_MEDIUM), EMPTY_ZIP_LABEL, Config.Colors.at(COLOR_BLACK) ); + } + else + { + text_surface = TTF_RenderText_Solid( Fonts.at(FONT_SIZE_MEDIUM), EMPTY_DIR_LABEL, Config.Colors.at(COLOR_BLACK) ); + } + + if (text_surface != NULL) + { + location.x += ImageSelectPointer->w; + + rect_clip.x = 0; + rect_clip.y = 0; + rect_clip.w = Config.DisplayListMaxWidth-location.x; + rect_clip.h = text_surface->h; + + ApplyImage( location.x, location.y, text_surface, Screen, &rect_clip ); + + ListNameHeight = MAX(ListNameHeight, location.y+text_surface->h ); + location.x -= ImageSelectPointer->w; + location.y += text_surface->h + Config.EntryYDelta; + + FREE_IMAGE( text_surface ); + } + else + { + Log( "Failed to create TTF surface with TTF_RenderText_Solid: %s\n", TTF_GetError() ); + return 1; + } + } + else + { + for (entry_index=0; entry_indexw; + RectEntries.at(entry_index).x = location.x; + RectEntries.at(entry_index).y = location.y; + RectEntries.at(entry_index).w = text_surface->w; + RectEntries.at(entry_index).h = text_surface->h; + + if (text_surface->w > (Config.DisplayListMaxWidth-location.x) ) + { + RectEntries.at(entry_index).w = Config.DisplayListMaxWidth-location.x; + + if (Config.TextScrollOption == true && DisplayList.at(Mode).relative == entry_index) + { + offset = TextScrollOffset; + + if (CurScrollPause > 1) + { + CurScrollPause++; + if (CurScrollPause >= Config.ScrollPauseSpeed) + { + CurScrollPause = 1; + } + } + else + { + CurScrollSpeed++; + if (CurScrollSpeed >= Config.ScrollSpeed) + { + CurScrollSpeed = 1; + if (TextScrollDir == true) + { + TextScrollOffset += Config.ScreenRatioW; + } + else + { + TextScrollOffset -= Config.ScreenRatioW; + } + Redraw = true; + } + + if (RectEntries.at(entry_index).w+TextScrollOffset >= text_surface->w) + { + TextScrollDir = false; + CurScrollPause = 2; + } + else if (TextScrollOffset <= 0) + { + TextScrollDir = true; + CurScrollPause = 2; + } + } + } + } + + rect_clip.w = Config.DisplayListMaxWidth-location.x; + rect_clip.h = text_surface->h; + rect_clip.x = offset; + rect_clip.y = 0; + + ApplyImage( location.x, location.y, text_surface, Screen, &rect_clip ); + + ListNameHeight = MAX(ListNameHeight, location.y+text_surface->h ); + location.x -= ImageSelectPointer->w; + location.y += text_surface->h + Config.EntryYDelta; + + FREE_IMAGE( text_surface ); + } + else + { + Log( "Failed to create TTF surface with TTF_RenderText_Solid: %s\n", TTF_GetError() ); + return 1; + } + } + } + + UpdateRect( startx, starty, Config.DisplayListMaxWidth-startx, ListNameHeight-starty ); + + return 0; +} + +void CSelector::SelectionLimits( item_pos_t& pos ) +{ + if (pos.absolute <= pos.first) + { + pos.relative = 0; + if (pos.absolute < 0) + { + pos.absolute = 0; + } + + pos.first = pos.absolute; + if (pos.total < Config.MaxEntries) + { + pos.last = (pos.total-1); + } + else + { + pos.last = pos.absolute+(Config.MaxEntries-1); + } + } + else if (pos.absolute >= pos.last) + { + if (pos.absolute > (int16_t)(pos.total-1)) + { + pos.absolute = (pos.total-1); + } + + pos.first = pos.absolute-(Config.MaxEntries-1); + pos.last = pos.absolute; + if (pos.total < Config.MaxEntries) + { + pos.relative = (pos.total-1); + } + else + { + pos.relative = Config.MaxEntries-1; + } + + if (pos.first < 0) + { + pos.first = 0; + } + } +} + +void CSelector::DrawBackground( void ) +{ + if (ImageBackground != NULL) + { + ApplyImage( 0, 0, ImageBackground, Screen, NULL ); + } + else + { + SDL_FillRect( Screen, NULL, rgb_to_int(Config.Colors.at(Config.ColorBackground)) ); + } +} + +int8_t CSelector::ConfigureButtons( void ) +{ + uint16_t i; + + // Common button mappings + ButtonModesLeft.at(0) = EVENT_ONE_UP; + ButtonModesLeft.at(1) = EVENT_PAGE_UP; + ButtonModesLeft.at(2) = EVENT_PAGE_DOWN; + ButtonModesLeft.at(3) = EVENT_ONE_DOWN; + + ButtonModesRight.at(0) = EVENT_QUIT; + + // Specific button mappings + switch (Mode) + { + case MODE_SELECT_ENTRY: + ButtonModesLeft.at(4) = EVENT_DIR_UP; + ButtonModesLeft.at(5) = EVENT_DIR_DOWN; + if (Config.UseZipSupport == true && Profile.ZipFile.length() > 0) + { + ButtonModesLeft.at(6) = EVENT_ZIP_MODE; + } + else + { + ButtonModesLeft.at(6) = EVENT_NONE; + } + + ButtonModesRight.at(1) = EVENT_SELECT; + ButtonModesRight.at(2) = EVENT_CFG_ITEM; + ButtonModesRight.at(3) = EVENT_NONE; + ButtonModesRight.at(3) = EVENT_CFG_APP; // TODO + break; + case MODE_SELECT_ARGUMENT: + ButtonModesLeft.at(4) = EVENT_NONE; + ButtonModesLeft.at(5) = EVENT_NONE; + ButtonModesLeft.at(6) = EVENT_NONE; + + ButtonModesRight.at(1) = EVENT_BACK; + ButtonModesRight.at(2) = EVENT_SELECT; + ButtonModesRight.at(3) = EVENT_NONE; + break; + case MODE_SELECT_VALUE: + ButtonModesLeft.at(4) = EVENT_NONE; + ButtonModesLeft.at(5) = EVENT_NONE; + ButtonModesLeft.at(6) = EVENT_NONE; + + ButtonModesRight.at(1) = EVENT_BACK; + ButtonModesRight.at(2) = EVENT_SET_ALL; + ButtonModesRight.at(3) = EVENT_SET_ONE; + break; + case MODE_SELECT_OPTION: + ButtonModesLeft.at(4) = EVENT_NONE; + ButtonModesLeft.at(5) = EVENT_NONE; + ButtonModesLeft.at(6) = EVENT_NONE; + + ButtonModesRight.at(1) = EVENT_BACK; + ButtonModesRight.at(2) = EVENT_SELECT; + ButtonModesRight.at(3) = EVENT_NONE; + break; + case MODE_SELECT_PLUGIN: + ButtonModesLeft.at(4) = EVENT_NONE; + ButtonModesLeft.at(5) = EVENT_NONE; + ButtonModesLeft.at(6) = EVENT_NONE; + + ButtonModesRight.at(1) = EVENT_BACK; + ButtonModesRight.at(2) = EVENT_SELECT; + ButtonModesRight.at(3) = EVENT_NONE; + break; + case MODE_ROM_OPTION: + ButtonModesLeft.at(4) = EVENT_NONE; + ButtonModesLeft.at(5) = EVENT_NONE; + ButtonModesLeft.at(6) = EVENT_NONE; + + ButtonModesRight.at(1) = EVENT_BACK; + ButtonModesRight.at(2) = EVENT_SELECT; + ButtonModesRight.at(3) = EVENT_NONE; + break; + case MODE_ROM_PLUGIN: + ButtonModesLeft.at(4) = EVENT_NONE; + ButtonModesLeft.at(5) = EVENT_NONE; + ButtonModesLeft.at(6) = EVENT_NONE; + + ButtonModesRight.at(1) = EVENT_BACK; + ButtonModesRight.at(2) = EVENT_SELECT; + ButtonModesRight.at(3) = EVENT_NONE; + break; + default: + Log( "Error: Unknown Mode\n" ); + return 1; + break; + } + + // Overides for button driven by config options + for (i=0; iw)/2); + rect_text.y = location.y + ((location.h-text_surface->h)/2); + + if (text_surface != NULL) + { + ApplyImage( rect_text.x, rect_text.y, text_surface, Screen, NULL ); + + FREE_IMAGE( text_surface ); + } + else + { + Log( "Failed to create TTF surface with TTF_RenderText_Solid: %s\n", TTF_GetError() ); + return 1; + } + } + return 0; +} + +int8_t CSelector::DrawText( SDL_Rect& location ) +{ + int16_t total; + int16_t prev_width; + int16_t prev_height; + int16_t max_height; + string text; + SDL_Rect box, clip; + + prev_width = 0; + prev_height = 0; + + if (Config.AutoLayout == false) + { + location.x = Config.PosX_Title; + location.y = Config.PosY_Title; + } + + // Title text + if (ImageTitle != NULL) + { + if (DrawState_Title == true) + { + ApplyImage( location.x, location.y, ImageTitle, Screen, NULL ); + UpdateRect( location.x, location.y, ImageTitle->w, ImageTitle->h ); + DrawState_Title = false; + } + location.y += ImageTitle->h + Config.EntryYDelta; + } + + // Entry Filter and Filepath (they can overlap so both are drawn when either change) + if (Mode == MODE_SELECT_ENTRY) + { + if (DrawState_FilePath == true || DrawState_Filter == true ) + { + // Entry Filter + if (ImageFilter != NULL) + { + prev_width = ImageFilter->w; + prev_height = ImageFilter->h; + } + else + { + prev_width = 0; + prev_height = 0; + } + max_height = prev_height; + + FREE_IMAGE( ImageFilter ); + + if (Profile.EntryFilter.length() > 0) + { + ImageFilter = TTF_RenderText_Solid( Fonts.at(FONT_SIZE_MEDIUM), Profile.EntryFilter.c_str(), Config.Colors.at(Config.ColorFontFiles) ); + if (ImageFilter != NULL) + { + clip.x = 0; + clip.y = 0; + clip.w = Config.FilePathMaxWidth; + clip.h = ImageFilter->h; + if (ImageFilter->w > Config.FilePathMaxWidth) + { + clip.x = ImageFilter->w-Config.FilePathMaxWidth; + } + + location.x = Config.ScreenWidth - ImageFilter->w - Config.EntryXOffset; + + ApplyImage( location.x, location.y, ImageFilter, Screen, &clip ); + + max_height = MAX( max_height, ImageFilePath->h ); + } + else + { + Log( "Failed to create TTF surface with TTF_RenderText_Solid: %s\n", TTF_GetError() ); + return 1; + } + } + location.x = Config.EntryXOffset; + + // File path + if (ImageFilePath != NULL) + { + prev_width = ImageFilePath->w; + prev_height = ImageFilePath->h; + } + else + { + prev_width = 0; + prev_height = 0; + } + max_height = MAX( max_height, prev_height ); + + FREE_IMAGE(ImageFilePath); + + text = Profile.FilePath; + if (Profile.ZipFile.length()) + { + text += "->" + Profile.ZipFile; + } + + ImageFilePath = TTF_RenderText_Solid( Fonts.at(FONT_SIZE_MEDIUM), text.c_str(), Config.Colors.at(Config.ColorFontFiles) ); + if (ImageFilePath != NULL) + { + clip.x = 0; + clip.y = 0; + clip.w = Config.FilePathMaxWidth; + clip.h = ImageFilePath->h; + + if (ImageFilePath->w > Config.FilePathMaxWidth) + { + clip.x = ImageFilePath->w-Config.FilePathMaxWidth; + } + + ApplyImage( location.x, location.y, ImageFilePath, Screen, &clip ); + + max_height = MAX( max_height, ImageFilePath->h ); + } + else + { + Log( "Failed to create TTF surface with TTF_RenderText_Solid: %s\n", TTF_GetError() ); + return 1; + } + + UpdateRect( 0, location.y, Config.ScreenWidth, max_height ); + + DrawState_FilePath = false; + DrawState_Filter = false; + } + } + + if (ImageFilePath != NULL) + { + location.y += ImageFilePath->h + Config.EntryYOffset; + } + + // About text + if (ImageAbout != NULL) + { + if (DrawState_About == true) + { + box.x = Config.ScreenWidth - ImageAbout->w - Config.EntryXOffset; + box.y = Config.ScreenHeight - ImageAbout->h - Config.EntryYOffset; + ApplyImage( box.x, box.y, ImageAbout, Screen, NULL ); + UpdateRect( box.x, box.y, ImageAbout->w, ImageAbout->h ); + DrawState_About = false; + } + } + + // Item count + switch (Mode) + { + case MODE_SELECT_ENTRY: + total = ItemsEntry.size(); + break; + case MODE_SELECT_ARGUMENT: // fall through + case MODE_SELECT_OPTION: + total = ItemsArgument.size(); + break; + case MODE_SELECT_VALUE: + total = ItemsValue.size(); + break; + case MODE_SELECT_PLUGIN: + total = ItemsDefPlugin.size(); + break; + default: + total = 0; + text = "Error: Unknown mode"; + break; + } + + // Draw index + if (DrawState_Index == true) + { + if (ImageIndex != NULL) + { + prev_width = ImageIndex->w; + prev_height = ImageIndex->h; + } + else + { + prev_width = 0; + prev_height = 0; + } + + FREE_IMAGE( ImageIndex ); + + text = "0 of 0"; + if (total > 0) + { + text = i_to_a(DisplayList.at(Mode).absolute+1) + " of " + i_to_a(total); + } + ImageIndex = TTF_RenderText_Solid(Fonts.at(FONT_SIZE_SMALL), text.c_str(), Config.Colors.at(Config.ColorFontFiles)); + + if (ImageIndex != NULL) + { + box.x = Config.EntryXOffset; + box.y = Config.ScreenHeight - ImageIndex->h - Config.EntryYOffset; + + ApplyImage( box.x, box.y, ImageIndex, Screen, NULL ); + UpdateRect( box.x, box.y, MAX(ImageIndex->w, prev_width), MAX(ImageIndex->h, prev_height) ); + } + else + { + Log( "Failed to create TTF surface with TTF_RenderText_Solid: %s\n", TTF_GetError()); + return 1; + } + DrawState_Index = false; + } + + // Zip extract option + if (DrawState_ZipMode == true) + { + if (Config.UseZipSupport == true && Profile.ZipFile.length() > 0) + { + if (ImageZipMode != NULL) + { + prev_width = ImageZipMode->w; + prev_height = ImageZipMode->h; + } + else + { + prev_width = 0; + prev_height = 0; + } + + FREE_IMAGE( ImageZipMode ); + + if (ExtractAllFiles == true) + { + text = "Extract All"; + } + else + { + text = "Extract Selection"; + } + + ImageZipMode = TTF_RenderText_Solid(Fonts.at(FONT_SIZE_SMALL), text.c_str(), Config.Colors.at(Config.ColorFontFiles)); + if (ImageZipMode == NULL) + { + Log( "Failed to create TTF surface with TTF_RenderText_Solid: %s\n", TTF_GetError()); + return 1; + } + } + + if (ImageZipMode != NULL) + { + box.x = 5*Config.EntryXOffset; + box.y = Config.ScreenHeight - ImageZipMode->h - Config.EntryYOffset; + + if (Config.UseZipSupport == true && Profile.ZipFile.length() > 0) + { + ApplyImage( box.x, box.y, ImageZipMode, Screen, NULL ); + } + UpdateRect( box.x, box.y, MAX(ImageZipMode->w, prev_width), MAX(ImageZipMode->h, prev_height) ); + } + DrawState_ZipMode = false; + } + +#if defined(DEBUG) + if (ImageDebug != NULL) + { + prev_width = ImageDebug->w; + prev_height = ImageDebug->h; + } + else + { + prev_width = 0; + prev_height = 0; + } + + FREE_IMAGE( ImageDebug ); + + text = "DEBUG abs " + i_to_a(DisplayList.at(Mode).absolute) + " rel " + i_to_a(DisplayList.at(Mode).relative) + + " F " + i_to_a(DisplayList.at(Mode).first) + " L " + i_to_a(DisplayList.at(Mode).last) + + " T " + i_to_a(DisplayList.at(Mode).total) + + " fps " + i_to_a(FPSDrawn) + " skp " + i_to_a(FPSSkip) + " slp " + i_to_a(FPSSleep) + + " lp " + i_to_a(LoopTimeAverage); + + ImageDebug = TTF_RenderText_Solid( Fonts.at(FONT_SIZE_SMALL), text.c_str(), Config.Colors.at(Config.ColorFontFiles) ); + + if (ImageDebug != NULL) + { + box.x = Config.EntryXOffset; + box.y = Config.ScreenHeight - ImageDebug->h; + + ApplyImage( box.x, box.y, ImageDebug, Screen, NULL ); + UpdateRect( box.x, box.y, MAX(ImageDebug->w, prev_width), MAX(ImageDebug->h, prev_height) ); + } + else + { + Log( "Failed to create TTF surface with TTF_RenderText_Solid: %s\n", TTF_GetError() ); + return 1; + } +#endif + + return 0; +} + +int8_t CSelector::RunExec( uint16_t selection ) +{ + bool entry_found; + uint16_t i, j, k; + int16_t ext_index; + string filename; + string filepath; + string command; + string extension; + string value; + string cmdpath, cmdname; + entry_t* entry = NULL; + argforce_t* argforce = NULL; + exeforce_t* exeforce = NULL; + argument_t* argument = NULL; + + // Find a entry for argument values + entry_found = false; + + if (!CheckRange( selection, ItemsEntry.size() )) + { + Log( "Error: RunExec selection is out of range\n" ); + return 1; + } + + if (ItemsEntry.at(selection).Entry >= 0) + { + entry = &Profile.Entries.at(ItemsEntry.at(selection).Entry); + entry_found = true; + } + + // Find a executable for file extension + filename = ItemsEntry.at(selection).Name; + if (ItemsEntry.at(selection).Type == TYPE_DIR) + { + extension = EXT_DIRS; + } + else + { + extension = filename.substr( filename.find_last_of(".")+1 ); + } + + ext_index = Profile.FindExtension( extension ); + + if (CheckRange( ext_index, Profile.Extensions.size() )) + { + command.clear(); + + // Unzip if needed + if (Config.UseZipSupport == true && Profile.ZipFile.length() > 0) + { + mkdir( Config.ZipPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH ); + if (ExtractAllFiles == true) // Extract all + { + Profile.Minizip.ExtractFiles( Profile.FilePath + Profile.ZipFile, Config.ZipPath ); + } + else // Extract one + { + Profile.Minizip.ExtractFile( Profile.FilePath + Profile.ZipFile, Config.ZipPath, filename ); + } + + filepath = Config.ZipPath + "/"; + } + else + { + filepath = Profile.FilePath; + } + + + // Setup commands + for (i=0; iCmdValues.at(j)); + } + else + { + command += " " + Profile.Commands.at(i).Arguments.at(j).Values.at(Profile.Commands.at(i).Arguments.at(j).Default); + } + } + } + command += "; "; + } + + // Check exe forces + cmdpath = Profile.Extensions.at(ext_index).exePath; + cmdname = Profile.Extensions.at(ext_index).exeName; + for (j=0; jFiles.size(); k++) + { + if (exeforce->Files.at(k).compare( lowercase(filename) ) == 0) + { + cmdpath = exeforce->exePath; + cmdname = exeforce->exeName; + break; + } + } + } + + // Add Executable to command + command += "cd " + cmdpath + "; "; + command += "LD_LIBRARY_PATH=./; export LD_LIBRARY_PATH; "; + command += "./" + cmdname; + + // Setup arguments + for (i=0; iPath.compare( Profile.FilePath ) == 0) + { + if (i == argforce->Argument) + { + Log( "Setting argforce on arg %d\n", i ); + value = argforce->Value; + break; + } + } + } + // Check arguments for default value or custom entry value + if (value.length() <= 0 ) + { + if (entry_found==true) + { + if (CheckRange( i, entry->ArgValues.size() )) + { + value = argument->Values.at( entry->ArgValues.at(i) ); + } + else + { + Log( "Error: RunExec i is out of range\n" ); + return 1; + } + } + else + { + if (CheckRange( argument->Default, argument->Values.size() )) + { + value = argument->Values.at( argument->Default ); + } + else + { + Log( "Error: RunExec argument->Default is out of range\n" ); + return 1; + } + } + } + // Add the argument if used + if (value.length() > 0) + { + if (value.compare( VALUE_NOVALUE ) != 0 ) + { + command += " " + argument->Flag + " "; + + if (value.compare( VALUE_FLAGONLY ) !=0 ) + { + if (value.compare( VALUE_FILENAME ) == 0) + { + if (Config.FilenameArgNoExt == true) + { + filename = filename.substr( 0, filename.find_last_of(".") ); + } + + if (entry_found==true) + { + command += '\"'; + if (Config.FilenameAbsPath == true) + { + command += entry->Path; + } + command += entry->Name + '\"'; + } + else + { + command += '\"'; + if (Config.FilenameAbsPath == true) + { + command += filepath; + } + command += filename + '\"'; + } + } + else + { + command += value; + } + } + } + } + } + } + else + { + Log( "Warning no extension was found for this file type\n" ); + return 1; + } + + command += "; sync;"; + if (Config.ReloadLauncher == true) + { + command += " cd " + Profile.LauncherPath + ";"; + command += " exec ./" + Profile.LauncherName ; + // Arguments + command += " " + string(ARG_PROFILE) + " " + ProfilePath; + command += " " + string(ARG_CONFIG) + " " + ConfigPath; + command += " " + string(ARG_ZIPLIST) + " " + ZipListPath; + } + + Log( "Running command: '%s'\n", command.c_str()); + + CloseResources(0); + + execlp( "/bin/sh", "/bin/sh", "-c", command.c_str(), NULL ); + + //if execution continues then something went wrong and as we already called SDL_Quit we cannot continue, try reloading + Log( "Error executing selected application, re-launching %s\n", APPNAME); + + chdir( Profile.LauncherPath.c_str() ); + execlp( Profile.LauncherName.c_str(), Profile.LauncherName.c_str(), NULL ); + + return 0; +} + +int8_t CSelector::PollInputs( void ) +{ + int16_t newsel; + uint16_t index; + string keyname; + SDL_Event event; + + for (index=0; index 0) + { + Profile.EntryFilter.erase( Profile.EntryFilter.length()-1 ); + } + } + else + { + Profile.EntryFilter += keyname; + } + DrawState_Filter = true; + Rescan = true; + } + } + else + { + bool used=false; + for (index=0; index Config.AnalogDeadZone) + { + if (event.jaxis.axis == 0) + { + if (IsEventOff(EVENT_PAGE_DOWN)) + { + EventPressCount.at(EVENT_PAGE_DOWN) = EVENT_LOOPS_ON; + } + EventReleased.at(EVENT_PAGE_UP) = true; + } + + if (event.jaxis.axis == 1) + { + if (IsEventOff(EVENT_ONE_DOWN)) + { + EventPressCount.at(EVENT_ONE_DOWN) = EVENT_LOOPS_ON; + } + EventReleased.at(EVENT_ONE_UP) = true; + } + } + else + { + EventReleased.at(EVENT_ONE_UP) = true; + EventReleased.at(EVENT_ONE_DOWN) = true; + EventReleased.at(EVENT_PAGE_UP) = true; + EventReleased.at(EVENT_PAGE_DOWN) = true; + } + break; + + case SDL_MOUSEMOTION: + Mouse.x = event.motion.x; + Mouse.y = event.motion.y; + + for (index=0; index 0) + { + ZipUp(); + } + else + { + if (Profile.LaunchableDirs == false) + { + DirectoryUp(); + } + } + } + + // Go down into a dir + if (Rescan == false && ((IsEventOn(EVENT_DIR_DOWN) == true) || (IsEventOn(EVENT_SELECT) == true))) + { + if (ItemsEntry.size()>0) + { + if (ItemsEntry.at(DisplayList.at(Mode).absolute).Type == TYPE_DIR) + { + if (Profile.LaunchableDirs == false) + { + DirectoryDown(); + } + } + else if (Config.UseZipSupport == 1 && ItemsEntry.at(DisplayList.at(Mode).absolute).Type == TYPE_ZIP) + { + ZipDown(); + } + } + else + { + EventPressCount.at( EVENT_SELECT ) = EVENT_LOOPS_OFF; + } + } + } + + // Value configuration + if (Mode == MODE_SELECT_VALUE) + { + SetOneEntryValue = false; + SetAllEntryValue = false; + if (IsEventOn(EVENT_SET_ONE) == true) + { + RefreshList = true; + SetOneEntryValue = true; + } + if (IsEventOn(EVENT_SET_ALL) == true) + { + RefreshList = true; + SetAllEntryValue = true; + } + } + + if (IsEventOn(EVENT_ZIP_MODE) == true) + { + Redraw = true; + DrawState_ZipMode = true; + ExtractAllFiles = !ExtractAllFiles; + } + + return 0; +} + diff --git a/source/mupen64launcher/src/cselector.h b/source/mupen64launcher/src/cselector.h new file mode 100755 index 0000000..6426b8b --- /dev/null +++ b/source/mupen64launcher/src/cselector.h @@ -0,0 +1,350 @@ +/** + * @section LICENSE + * + * PickleLauncher + * Copyright (C) 2010-2011 Scott Smith + * + * 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 . + * + * @section LOCATION + */ + +#ifndef CSELECTOR_H +#define CSELECTOR_H + +#include "version.h" +#include "cbase.h" +#include "cconfig.h" +#include "cprofile.h" +#include "csystem.h" + +using namespace std; + +#define ARG_RESETGUI "--resetgui" /** Flag to reset GUI settings based on the current resolution. */ +#define ARG_CONFIG "--config" /** Flag to override the config file. */ +#define DEF_CONFIG "config.txt" /** Default config filename. */ +#define ARG_PROFILE "--profile" /** Flag to override the profile file. */ +#define DEF_PROFILE "profile.txt" /** Default profile filename. */ +#define ARG_ZIPLIST "--ziplist" /** Flag to override the ziplist file. */ +#define DEF_ZIPLIST "ziplist.txt" /** Default ziplist filename. */ + +#define ENTRY_ARROW "-> " /** Ascii fallback for the entry arrow selector. */ +#define BUTTON_LABEL_ONE_UP "<" /** Ascii text fallback for the one up button label. */ +#define BUTTON_LABEL_ONE_DOWN ">" /** Ascii text fallback for the one down button label. */ +#define BUTTON_LABEL_PAGE_UP "<<" /** Ascii text fallback for the page up button label. */ +#define BUTTON_LABEL_PAGE_DOWN ">>" /** Ascii text fallback for the page down button label. */ +#define BUTTON_LABEL_DIR_UP "U" /** Ascii text fallback for the directory up button label. */ +#define BUTTON_LABEL_DIR_DOWN "D" /** Ascii text fallback for the directory down button label. */ +#define BUTTON_LABEL_ZIP_MODE "Z" /** Ascii text fallback for the zip mode label. */ +#define BUTTON_LABEL_CONFIG "Def. Plugins" /** Ascii text fallback for the options button label. */ +#define BUTTON_LABEL_EDIT "ROM Plugins" /** Ascii text fallback for the edit item button label. */ +#define BUTTON_LABEL_SET_ONE "Set" /** Ascii text fallback for the set button label. */ +#define BUTTON_LABEL_SET_ALL "Default" /** Ascii text fallback for the default button label. */ +#define BUTTON_LABEL_BACK "Back" /** Ascii text fallback for the back button label. */ +#define BUTTON_LABEL_SELECT "Select" /** Ascii text fallback for the select button label. */ +#define BUTTON_LABEL_QUIT "Quit" /** Ascii text fallback for the quit button label. */ + +#define EMPTY_DIR_LABEL "" /** Ascii text for display if no files or dirs are detected. */ +#define EMPTY_ZIP_LABEL "" /** Ascii text for display if no files in a zip are detected. */ + +#define EVENT_LOOPS_ON 0 /** Value set to loops to indentify an active event. */ +#define EVENT_LOOPS_OFF 0x7F /** Value set to loops to indentify an inactive event. */ +#define EVENT_LOOPS 10 /** Number of loops an event must be active to be detected to be on. */ +#define IsEventOn(x) ((EventPressCount.at(x) <= EVENT_LOOPS_ON) ? true : false) /** Determines if an event is active. */ +#define IsEventOff(x) ((EventPressCount.at(x) == EVENT_LOOPS_OFF) ? true : false) /** Determines if an event is inactive. */ + +#define MS_PER_SEC 1000 /** Milliseconds in 1 Second. */ +#define FRAMES_PER_SEC 60 /** Frames in 1 Second. */ +#define FRAME_SKIP_RATIO 4 /** Maximum frames skip ratio, draw 1 frame for every X number of skipped frames. */ + +#define FREE_IMAGE(X) if (X != NULL) { SDL_FreeSurface(X); X = NULL; } /** Macro for checking and releasing pointers to pixel data. */ + +/** @brief Modes of the launcher. + */ +enum MODES_T { + MODE_SELECT_ENTRY=0, /** Main mode for selecting an file to run. */ + MODE_SELECT_ARGUMENT, /** Select an argument or command belonging to an entry. */ + MODE_SELECT_VALUE, /** Select an value belonging to an argument. */ + MODE_SELECT_OPTION, /** Select a Def. Plugin type */ + MODE_SELECT_PLUGIN, /** Selct one Def. Plugin */ + MODE_ROM_OPTION, + MODE_ROM_PLUGIN, + MODE_TOTAL /** Number of modes. */ +}; + +/** @brief List positions for the current item and first and last items. + */ +struct item_pos_t { + item_pos_t() : first(0), last(0), absolute(0), relative(0), total(0) {}; + int16_t first; /** Index of the first item on the display list. */ + int16_t last; /** Index of the last item on the display list. */ + int16_t absolute; /** Absolute index of the currently selected item in the display list. */ + int16_t relative; /** Relative index of the currently selected item in the display list. */ + int16_t total; /** Total number of items. */ +}; + +/** @brief The font, color, text for a item in the display list + */ +struct listtext_t { + listtext_t() : font(0), color(0), text("") {}; + int8_t font; /** Index of the selected font size for the text. */ + int8_t color; /** Index of the color for the text. */ + string text; /** Text for an item for the display list. */ +}; + +/** @brief This class controls resources, logic for gui, interaction with the user. + */ +class CSelector : public CBase +{ + public: + /** Constructor. */ + CSelector(); + /** Destructor. */ + virtual ~CSelector(); + + /** @brief Run the main loop of the application. + * @param argc : number of arguments. + * @param argv : arguments passed to the application. + * @return 0 if passed 1 if failed. + */ + int8_t Run( int argc, char** argv ); + + private: + /** @brief Parse and handle arguments sent to the application. + * @param argc : number of arguments. + * @param argv : arguments passed to the application. + */ + void ProcessArguments ( int32_t argc, char** argv ); + + /** @brief Open system interfaces and load configuration information. + * @return 0 if passed 1 if failed. + */ + int8_t OpenResources ( void ); + + /** @brief Close system interfaces and save configuration information. + * @param result : result of the application, do not save config files if an error occurs. + * @return 0 if passed 1 if failed. + */ + void CloseResources ( int8_t result ); + + /** @brief Main loop of the application, polls input, runs current mode, and freshes the screen. + * @return -1 for no selection otherwise the entry selection number. + */ + int16_t DisplayScreen ( void ); + + /** @brief Check which screen rects a rect overlaps. The marked screen rects will only be updated for the screen. + */ + void UpdateRect ( int16_t x, int16_t y, int16_t w, int16_t h ); + + /** @brief Handles logic for measuring and counting frame drawing to the screen. + */ + void UpdateScreen ( void ); + + /** @brief Determines the mode to run based on user input events. + */ + void SelectMode ( void ); + + /** @brief Mode to display list of input files. + * @return 0 if passed 1 if failed. + */ + int8_t DisplaySelector ( void ); + + /** @brief Loads the preview image if any exists. + */ + void LoadPreview ( const string& name ); + + /** @brief Moves the current path one directory level up. + */ + void DirectoryUp ( void ); + + /** @brief Moves the current path one directory level down. + */ + void DirectoryDown ( void ); + + /** @brief Moves the current path out of a zip file. + */ + void ZipUp ( void ); + + /** @brief Moves the current path into a zip file. + */ + void ZipDown ( void ); + + /** @brief Load the display list with text labels and font info. + */ + void PopulateList ( void ); + + /** @brief Load the display with items with entries. + */ + void PopModeEntry ( void ); + + /** @brief Load the display with items with entry arguments. + */ + void PopModeArgument ( void ); + + /** @brief Load the display list with items with argument values. + */ + void PopModeValue ( void ); + + /** @brief Load the display list with items with type of plugin. + */ + void PopModeOption ( void ); + + void PopModeRomOption ( void ); + + /** @brief Load the display list with items with Plugin detail for 1 type. + */ + void PopModePlugin ( void ); + + void PopModeRomPlugin ( void ); + + /** @brief Will redetect items for the current mode. + */ + void RescanItems ( void ); + + /** @brief Draws the names for the items in the display list for the current mode. + * @return 0 if passed 1 if failed. + */ + int8_t DrawNames ( SDL_Rect& location ); + + /** @brief Calculates the indices of the entries that should be displayed based on the current selection + * @param pos : reference to the position selections in the current list of entries + */ + void SelectionLimits ( item_pos_t& pos ); + + /** @brief Will either fill the screen with a color or blit a specified image to the screen + */ + void DrawBackground ( void ); + + /** @brief Configures the buttons to be displayed on the screen for the current mode + * @return 0 if passed 1 if failed + */ + int8_t ConfigureButtons ( void ); + + /** @brief Draws the buttons to the screen, in either fill color mode or bitmap's + * @param location : rect contains the starting coordinates for the buttons + */ + int8_t DrawButtons ( SDL_Rect& location ); + + /** @brief Draw a button to the screen + * @param button : the button to draw (index is defined in EVENT_T) + * @param font : the font used for render + * @param location : the coordinates and dimensions of the button + * @return 0 if passed 1 if failed + */ + int8_t DrawButton ( uint8_t button, TTF_Font* font, SDL_Rect& location ); + + /** @brief Draws text labels to the screen, like title and author info + * @param location : contains the starting coordinates for the text + * @return 0 if passed 1 if failed + */ + int8_t DrawText ( SDL_Rect& location ); + + /** @brief Creates a command script to run the target application + * @param selection : the entry selection to use for input to the target application + * @return 0 if passed 1 if failed + */ + int8_t RunExec ( uint16_t selection ); + + /** @brief Collect all input events from the user + * @return 0 if passed 1 if failed + */ + int8_t PollInputs ( void ); + + CSelector(const CSelector &); + CSelector & operator=(const CSelector&); + + bool Redraw; + bool SkipFrame; + bool Rescan; /**< Set to cause the current directory to be rescaned. */ + bool RefreshList; /**< Set to cause the current display list to be populated. */ + bool SetOneEntryValue; /**< Set value for the current entry to the selected value. */ + bool SetAllEntryValue; /**< Set default for all entries to the selected value. */ + bool TextScrollDir; /**< Determines the direction of the horizontal scroll, left or right. */ + bool ExtractAllFiles; /**< True if all files should be extracted from a zip, if false only the selected file is. */ + + bool DrawState_Title; + bool DrawState_About; + bool DrawState_Filter; + bool DrawState_FilePath; + bool DrawState_Index; + bool DrawState_ZipMode; + bool DrawState_Preview; + bool DrawState_ButtonL; + bool DrawState_ButtonR; + + uint8_t Mode; /**< The current mode of the application. */ + uint8_t LastSelectedEntry; /**< Stores the index of the last seclected entry so scrolling can be restarted. */ + uint16_t TextScrollOffset; /**< Number of pixels to offset the entry text surface when it will blit to the screen. */ + uint16_t CurScrollSpeed; /**< Current number of loops used to decide when to offset the entry text scroll effect. */ + uint16_t CurScrollPause; /**< Current number of loops used to decide when to pause the entry text scroll effect. */ + uint16_t ListNameHeight; + int16_t FramesDrawn; /**< Counter for the number frames drawn to the screen. */ + int16_t FramesSkipped; /**< Counter for the number frames not drawn to the screen. */ + int16_t FramesSleep; +#if defined(DEBUG) + int16_t FPSDrawn; /**< Number frames drawn to the screen per second. */ + int16_t FPSSkip; /**< Number frames not drawn to the screen per second. */ + int16_t FPSSleep; + int32_t FrameCountTime; /**< Tick count from measureing FPS. */ + int16_t LoopTimeAverage; /**< Average loop time. */ +#endif + int32_t FrameEndTime; /**< Tick count at the end of the frame. */ + int32_t FrameStartTime; /**< Tick count at the start of the frame. */ + int16_t FrameDelay; /**< Tick duration of the frame. */ + SDL_Rect Mouse; /**< Stores the absolute position of the mouse pointer. */ + SDL_Joystick* Joystick; /**< SDL surface reference to the first joystick device. */ + SDL_Surface* Screen; /**< SDL surface reference to the screen. */ + SDL_Surface* ImageBackground; /**< SDL surface reference to the background pixel data (optional). */ + SDL_Surface* ImagePointer; /**< SDL surface reference to the pointer pixel data (optional). */ + SDL_Surface* ImageSelectPointer; /**< SDL surface reference to the list select pointer pixel data (optional). */ + SDL_Surface* ImagePreview; /**< SDL surface reference to the preview pixel data. */ + SDL_Surface* ImageTitle; /**< SDL surface reference to the title text pixel data. */ + SDL_Surface* ImageAbout; /**< SDL surface reference to the about text pixel data. */ + SDL_Surface* ImageFilePath; /**< SDL surface reference to the about text pixel data. */ + SDL_Surface* ImageFilter; /**< SDL surface reference to the about text pixel data. */ + SDL_Surface* ImageIndex; /**< SDL surface reference to the about text pixel data. */ + SDL_Surface* ImageZipMode; /**< SDL surface reference to the about text pixel data. */ +#if defined(DEBUG) + SDL_Surface* ImageDebug; /**< SDL surface reference to the about text pixel data. */ +#endif + vector ImageButtons; /**< SDL surface references to the button's pixel data (optional). */ + vector Fonts; /**< SDL-TTF references to the rendered font in different size. */ + CConfig Config; /**< The configuration data. */ + CProfile Profile; /**< The extension and entries data. */ + CSystem System; /**< System specific controls and methods. */ + string ConfigPath; /**< Contains the file path to the config.txt. */ + string ProfilePath; /**< Contains the file path to the profile.txt. */ + string ZipListPath; /**< Contains the path and name of the files that have been unzipped. */ + vector EventReleased; /**< Collection of the states if a release event was detected. */ + vector EventPressCount; /**< Collection of the loop counts for when an event can act again. */ + vector ButtonModesLeft; /**< Collection of the state of the buttons on the left side. */ + vector ButtonModesRight; /**< Collection of the state of the buttons on the right side. */ + vector DisplayList; /**< Collection of the positions and limits of list selection for each mode. */ + vector LabelButtons; /**< Collection of text labels for the buttons. */ + vector ListNames; /**< Collection of text and font information for the entry currently displayed. */ + vector ItemsEntry; /**< Collection of directories and filenames detected in the current path. */ + vector ItemsArgument; /**< Collection of options for an entry or config. */ + vector ItemsDefPlugin; /**< Collection of Plugin for selected plugin type. */ + uint8_t WhichPlugin; /**< Wich Plugin is selected */ + vector ItemsRomOption; /**< Collection of options for an entry or config. */ + vector ItemsRomPlugin; /**< Collection of Plugin for selected plugin type. */ + uint8_t WhichRomPlugin; /**< Wich Plugin is selected */ + vector ItemsValue; /**< Collection of values for an option. */ + vector RectEntries; /**< Collection of position rects for the displayed entries. */ + vector RectButtonsLeft; /**< Collection of position rects for the displayed buttons on left. */ + vector RectButtonsRight; /**< Collection of position rects for the displayed buttons on right. */ + vector ScreenRectsDirty; /**< Collection of rects for the areas of the screen that will be updated. */ +}; + +#endif // CSELECTOR_H diff --git a/source/mupen64launcher/src/csystem.cpp b/source/mupen64launcher/src/csystem.cpp new file mode 100644 index 0000000..73c1bea --- /dev/null +++ b/source/mupen64launcher/src/csystem.cpp @@ -0,0 +1,104 @@ +/** + * @section LICENSE + * + * PickleLauncher + * Copyright (C) 2010-2011 Scott Smith + * + * 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 . + * + * @section LOCATION + */ + +#include "csystem.h" + +CSystem::CSystem() : CBase() +{ +#if defined(GP2X) || defined(WIZ) || defined(CAANOO) + memdev = open( "/dev/mem", O_RDWR ); + if (memdev == 0) + { + Log( "Could not open /dev/mem\n" ); + } + else + { + memregs = (uint32_t*)mmap( 0, MMAP_ADDRESS, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0xc0000000 ); + + if (memregs == MAP_FAILED) + { + Log( "Could not mmap hardware registers!\n" ); + close(memdev); + } + } +#endif +} + +CSystem::~CSystem() +{ +#if defined(GP2X) || defined(WIZ) || defined(CAANOO) + if (memdev != 0) + { + memregs = NULL; + } + close(memdev); +#endif +} + +void CSystem::SetCPUClock( uint16_t& mhz ) +{ + // Range check + if (mhz == 0 || mhz > CPU_CLOCK_MAX) + { + Log( "CPU mhz out of range, resetting to default. Value is now %d and allowed values should be between 0 and %d Mhz.\n", mhz, CPU_CLOCK_MAX ); + mhz = CPU_CLOCK_DEF; + } + +#if defined(PANDORA) + string command = "/usr/bin/sudo cpuset " + i_to_a(mhz); + execlp( command.c_str(), command.c_str(), NULL, NULL, NULL ); + +#elif defined(WIZ) || defined(CAANOO) + if (memdev != 0 && memregs != 0) + { + volatile uint32_t *memregl = static_cast((volatile void*)memregs); + uint32_t mdiv, pdiv = 9, sdiv = 0; + uint32_t v; + + mdiv = (mhz * pdiv) / SYS_CLK_FREQ; + if (mdiv & ~0x3ff) return; + v = pdiv<<18 | mdiv<<8 | sdiv; + + PLLSETREG0 = v; + PWRMODE |= 0x8000; + for (int i = 0; (PWRMODE & 0x8000) && i < 0x100000; i++); + } + +#elif defined(GP2X) + if (memdev != 0 && memregs != 0) + { + uint32_t v; + uint32_t mdiv, pdiv=3, scale=0; + + mhz *= 1000000; + mdiv = (mhz * pdiv) / SYS_CLK_FREQ; + mdiv = ((mdiv-8)<<8) & 0xff00; + pdiv = ((pdiv-2)<<2) & 0xfc; + scale &= 3; + v = mdiv | pdiv | scale; + MEM_REG[0x910>>1] = v; + } + +#else + Log( "Setting CPU Clock not supported on this machine.\n" ); +#endif +} diff --git a/source/mupen64launcher/src/csystem.h b/source/mupen64launcher/src/csystem.h new file mode 100644 index 0000000..f33dd93 --- /dev/null +++ b/source/mupen64launcher/src/csystem.h @@ -0,0 +1,81 @@ +/** + * @section LICENSE + * + * PickleLauncher + * Copyright (C) 2010-2011 Scott Smith + * + * 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 . + * + * @section LOCATION + */ + +#ifndef CSYSTEM_H +#define CSYSTEM_H + +#include "cbase.h" + +using namespace std; + +#if defined(PANDORA) +#define CPU_CLOCK_DEF 600 +#define CPU_CLOCK_MAX 1200 + +#elif defined(WIZ) || defined(CAANOO) +#define CPU_CLOCK_DEF 300 +#define CPU_CLOCK_MAX 600 +#define MMAP_ADDRESS 0x10000 +#define SYS_CLK_FREQ 27 +#define PLLSETREG0 (memregl[0xF004>>2]) +#define PWRMODE (memregl[0xF07C>>2]) + +#elif defined(GP2X) +#define CPU_CLOCK_DEF 150 +#define CPU_CLOCK_MAX 300 +#define MMAP_ADDRESS 0x20000 +#define SYS_CLK_FREQ 7372800 + +#elif defined(GP2X) +#define CPU_CLOCK_DEF 1000 +#define CPU_CLOCK_MAX 2000 + +#else +#define CPU_CLOCK_DEF 1 +#define CPU_CLOCK_MAX 1 +#endif + +/** @brief This class controls resources, logic for gui, interaction with the user. + */ +class CSystem : public CBase +{ + public: + /** Constructor. */ + CSystem(); + /** Destructor. */ + virtual ~CSystem(); + + /** @brief Set the CPU clock of the system. + * @param clock : number of arguments. + * @return 0 if passed 1 if failed. + */ + void SetCPUClock( uint16_t& mhz ); + + private: + +#if defined(GP2X) || defined(WIZ) || defined(CAANOO) + uint32_t memdev; + volatile uint32_t *memregs; +#endif +}; + +#endif // CSYSTEM_H diff --git a/source/mupen64launcher/src/czip.cpp b/source/mupen64launcher/src/czip.cpp new file mode 100755 index 0000000..a9f41bb --- /dev/null +++ b/source/mupen64launcher/src/czip.cpp @@ -0,0 +1,456 @@ +/** + * @section LICENSE + * + * PickleLauncher + * Copyright (C) 2010-2011 Scott Smith + * + * 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 . + * + * @section LOCATION + */ + + /* + czip.cpp is based on miniunz.c + + miniunz.c + Version 1.1, February 14h, 2010 + sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) +*/ + +#include "czip.h" + +CZip::CZip() : CBase(), + UnzipFiles () +{ +} + +CZip::~CZip() +{ +} + +void CZip::ListFiles( const string& zipfile, vector& list ) +{ + uint32_t i; + int32_t err; + unzFile uf=NULL; + unz_global_info64 gi; + + // Open the zip file + uf = unzOpen64( zipfile.c_str() ); + + if (uf != NULL) + { + // Get file info for the zip file + err = unzGetGlobalInfo64( uf,&gi ); + if (err != UNZ_OK) + { + Log( "error %d with zipfile in unzGetGlobalInfo\n",err); + return; + } + } + else + { + Log( "error with zipfile %s in unzOpen64\n", zipfile.c_str() ); + return; + } + Log( "Reading zip file %s\n", zipfile.c_str() ); + + // Spit out some information about the files in the zip for debug + Log( " Length Method Size Ratio Date Time CRC-32 Name\n" ); + Log( " ------ ------ ---- ----- ---- ---- ------ ----\n" ); + for (i=0; i 0) + ratio = (uLong)((file_info.compressed_size*100)/file_info.uncompressed_size); + + /* display a '*' if the file is crypted */ + if ((file_info.flag & 1) != 0) + charCrypt='*'; + + if (file_info.compression_method == 0) + string_method="Stored"; + else + if (file_info.compression_method == Z_DEFLATED) + { + uInt iLevel=(uInt)((file_info.flag & 0x6)/2); + if (iLevel==0) + string_method="Defl:N"; + else if (iLevel==1) + string_method="Defl:X"; + else if ((iLevel==2) || (iLevel==3)) + string_method="Defl:F"; /* 2:fast , 3 : extra fast*/ + } + else + if (file_info.compression_method == Z_BZIP2ED) + { + string_method="BZip2 "; + } + else + string_method="Unkn. "; + + Display64BitsSize( file_info.uncompressed_size,7 ); + Log( " %6s%c",string_method,charCrypt); + Display64BitsSize( file_info.compressed_size,7 ); + Log( " %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n", + ratio, + (uLong)file_info.tmu_date.tm_mon + 1, + (uLong)file_info.tmu_date.tm_mday, + (uLong)file_info.tmu_date.tm_year % 100, + (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min, + (uLong)file_info.crc,filename_inzip); + if ((i+1) < gi.number_entry) + { + err = unzGoToNextFile( uf ); + if (err != UNZ_OK) + { + Log( "error %d with zipfile in unzGoToNextFile\n",err); + break; + } + } + + // Save the names of the files in the zip + list.push_back( filename_inzip ); + } + + // Close the zip file + unzClose( uf ); +} + +void CZip::ExtractFile( const string& zipfile, const string& location, const string& filename ) +{ + uint32_t i; + int32_t err; + unzFile uf = NULL; + unz_global_info64 gi; + + // Open the zip file + uf = unzOpen64( zipfile.c_str() ); + + if (uf != NULL) + { + // Get file info for the zip file + err = unzGetGlobalInfo64( uf,&gi ); + if (err != UNZ_OK) + { + Log( "error %d with zipfile in unzGetGlobalInfo\n",err); + return; + } + } + else + { + Log( "error with zipfile %s in unzOpen64\n", zipfile.c_str() ); + return; + } + + for (i=0; i 0) + { + if (fwrite( buf, err, 1, fout ) != 1) + { + Log( "error in writing extracted file\n" ); + err = UNZ_ERRNO; + break; + } + } + } + while (err > 0); + + if (fout) + { + fclose( fout ); + } + } + + if (err==UNZ_OK) + { + err = unzCloseCurrentFile( uf ); + if (err != UNZ_OK) + { + Log( "error %d with zipfile in unzCloseCurrentFile\n",err); + } + + AddUnzipFile( write_filename ); + } + else + { + unzCloseCurrentFile( uf ); /* don't lose the error */ + } + + free(buf); + return err; +} + +void CZip::Display64BitsSize(ZPOS64_T n, int size_char) +{ + /* to avoid compatibility problem , we do here the conversion */ + char number[21]; + int offset=19; + int pos_string = 19; + number[20]=0; + for (;;) { + number[offset]=(char)((n%10)+'0'); + if (number[offset] != '0') + pos_string=offset; + n/=10; + if (offset==0) + break; + offset--; + } + { + int size_display_string = 19-pos_string; + while (size_char > size_display_string) + { + size_char--; + Log( " " ); + } + } + + Log( "%s",&number[pos_string]); +} + +void CZip::AddUnzipFile( const string& filename ) +{ + uint16_t i; + + for (i=0; i0) + { +#if defined(DEBUG) + Log( "Saving file %s to ziplist\n", UnzipFiles.at(i).c_str()); +#endif + fout << UnzipFiles.at(i) << endl; + } + } + } + + return 0; +} + +int8_t CZip::LoadUnzipList( const string& location ) +{ + string line; + ifstream fin; + + fin.open(location.c_str(), ios_base::in); + + if (!fin) + { + Log( "Failed to open unziplist at %s\n", location.c_str() ); + return 0; // Dont stop the app if it cant be opened, default values will be used and then save to file. + } + + UnzipFiles.clear(); + + // Read in the profile + if (fin.is_open()) + { + while (!fin.eof()) + { + getline(fin,line); + + if (line.length() > 0) + { + UnzipFiles.push_back(line); + } + } + } + + return 0; +} + diff --git a/source/mupen64launcher/src/czip.h b/source/mupen64launcher/src/czip.h new file mode 100755 index 0000000..38526d5 --- /dev/null +++ b/source/mupen64launcher/src/czip.h @@ -0,0 +1,99 @@ +/** + * @section LICENSE + * + * PickleLauncher + * Copyright (C) 2010-2011 Scott Smith + * + * 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 . + * + * @section LOCATION + */ + +#ifndef CZIP_H +#define CZIP_H + +#include "cbase.h" +#include "unzip/unzip.h" + +using namespace std; + +/** @brief This class handles interfaces to read and extract files from zips. + */ +class CZip : public CBase +{ + public: + /** Constructor. */ + CZip(); + /** Destructor. */ + virtual ~CZip(); + + /** @brief Loads a list of names for files detected in the zip. + * @param zipfile : the zip file to read. + * @param list : the list of filenames. + */ + void ListFiles ( const string& zipfile, vector& list ); + + /** @brief Extracts file within a zip to the designated location. + * @param zipfile : the zip file to extract from. + * @param location : location to extract the file to. + * @param filename : the file to extract. + * @param list : the list of filenames. + */ + void ExtractFile ( const string& zipfile, const string& location, const string& filename ); + + /** @brief Extracts files within a zip to the designated location. + * @param zipfile : the zip file to extract from. + * @param location : location to extract the files to. + * @param list : the list of filenames. + */ + void ExtractFiles ( const string& zipfile, const string& location ); + + /** @brief Deletes files extracted at the designated location + */ + void DelUnzipFiles ( void ); + + /** @brief Save a list of extracted files. + * @param location : where to save the zip list. + * @return 0 if passed 1 if failed. + */ + int8_t SaveUnzipList ( const string& location ); + + /** @brief Load a list of extracted files. + * @param location : where to load the zip list. + * @return 0 if passed 1 if failed. + */ + int8_t LoadUnzipList ( const string& location ); + + private: + /** @brief Display the zip size. + * @param n : file size. + * @param size_char : number of digits to display. + */ + void Display64BitsSize ( ZPOS64_T n, int size_char); + + /** @brief Extracts a file within a zip to the designated location + * @param location : location to extract the file to. + * @return zip result. + */ + int32_t Extract ( unzFile uf, const string& location ); + + /** @brief Stores the name of an extracted file to a list in memory. + * @param filename : filename to record. + */ + void AddUnzipFile ( const string& filename ); + + vector UnzipFiles; /**< A list of filenames for files that have been extracted. */ +}; + +#endif // CZIP_H diff --git a/source/mupen64launcher/src/main.cpp b/source/mupen64launcher/src/main.cpp new file mode 100755 index 0000000..5c895d9 --- /dev/null +++ b/source/mupen64launcher/src/main.cpp @@ -0,0 +1,35 @@ +/** + * @section LICENSE + * + * PickleLauncher + * Copyright (C) 2010-2011 Scott Smith + * + * 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 . + * + * @section LOCATION + */ + +#include "main.h" + +int32_t main( int32_t argc, char** argv ) +{ + int32_t result; + CSelector selector; + + selector.Log( "Starting %s Version %s.\n", APPNAME, APPVERSION ); + result = selector.Run( argc, argv ); + selector.Log( "Quitting %s Version %s.\n", APPNAME, APPVERSION ); + + return result; +} diff --git a/source/mupen64launcher/src/main.h b/source/mupen64launcher/src/main.h new file mode 100755 index 0000000..301548e --- /dev/null +++ b/source/mupen64launcher/src/main.h @@ -0,0 +1,48 @@ +/** + * @section LICENSE + * + * PickleLauncher + * Copyright (C) 2010-2011 Scott Smith + * + * 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 . + * + * @section LOCATION + */ + +#ifndef MAIN_H +#define MAIN_H + +#include "version.h" +#include "cselector.h" + +/**< Defines. */ +/**< DEBUG : enables additional code and logging for debug purposes. */ +/**< DEBUG_FPS : prints frame count information to the console. */ +/**< DEBUG_FORCE_REDRAW : force the drawing routines to redraw to the screen every loop. */ +/**< DEBUG_DRAW_STATES : prints the draw states every loop to the console. */ +/**< Platforms : Select only one. */ +/**< PANDORA : enables specific settings for the pandora platform. */ +/**< CAANOO : enables specific settings for the caanoo platform. */ +/**< WIZ : enables specific settings for the wiz platform. */ +/**< GP2X : enables specific settings for the gp2x platform. */ +/**< X86 : enables specific settings for the pc platform. */ + +/** @brief Main entry into the application + * @param argc : number of arguments + * @param argv : arguments passed to the application + * @return 0 if passed 1 if failed + */ +int32_t main( int32_t argc, char** argv ); + +#endif // MAIN_H diff --git a/source/mupen64launcher/src/unzip/ioapi.c b/source/mupen64launcher/src/unzip/ioapi.c new file mode 100755 index 0000000..49958f6 --- /dev/null +++ b/source/mupen64launcher/src/unzip/ioapi.c @@ -0,0 +1,235 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#if (defined(_WIN32)) + #define _CRT_SECURE_NO_WARNINGS +#endif + +#include "ioapi.h" + +voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) +{ + if (pfilefunc->zfile_func64.zopen64_file != NULL) + return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); + else + { + return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); + } +} + +long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); + else + { + uLong offsetTruncated = (uLong)offset; + if (offsetTruncated != offset) + return -1; + else + return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); + } +} + +ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); + else + { + uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); + if ((tell_uLong) == ((uLong)-1)) + return (ZPOS64_T)-1; + else + return tell_uLong; + } +} + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) +{ + p_filefunc64_32->zfile_func64.zopen64_file = NULL; + p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; + p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; + p_filefunc64_32->zfile_func64.ztell64_file = NULL; + p_filefunc64_32->zfile_func64.zseek64_file = NULL; + p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; + p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; + p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; +} + + + +static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); +static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); +static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); +static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); +static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); + +static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + +static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen64((const char*)filename, mode_fopen); + return file; +} + + +static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + + +static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) +{ + ZPOS64_T ret; + ret = ftello64((FILE *)stream); + return ret; +} + +static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + if (fseek((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + return ret; +} + +static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + + if(fseeko64((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + + return ret; +} + + +static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = fopen64_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell64_file = ftell64_file_func; + pzlib_filefunc_def->zseek64_file = fseek64_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/source/mupen64launcher/src/unzip/ioapi.h b/source/mupen64launcher/src/unzip/ioapi.h new file mode 100755 index 0000000..8309c4c --- /dev/null +++ b/source/mupen64launcher/src/unzip/ioapi.h @@ -0,0 +1,200 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + + Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) + Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. + More if/def section may be needed to support other platforms + Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. + (but you should use iowin32.c for windows instead) + +*/ + +#ifndef _ZLIBIOAPI64_H +#define _ZLIBIOAPI64_H + +#if (!defined(_WIN32)) && (!defined(WIN32)) + + // Linux needs this to support file operation on files larger then 4+GB + // But might need better if/def to select just the platforms that needs them. + + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif +#endif + +#include +#include +#include "zlib.h" + +#if defined(USE_FILE32API) +#define fopen64 fopen +#define ftello64 ftell +#define fseeko64 fseek +#else +#ifdef _MSC_VER + #define fopen64 fopen + #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) + #define ftello64 _ftelli64 + #define fseeko64 _fseeki64 + #else // old MSC + #define ftello64 ftell + #define fseeko64 fseek + #endif +#endif +#endif + +/* +#ifndef ZPOS64_T + #ifdef _WIN32 + #define ZPOS64_T fpos_t + #else + #include + #define ZPOS64_T uint64_t + #endif +#endif +*/ + +#ifdef HAVE_MINIZIP64_CONF_H +#include "mz64conf.h" +#endif + +/* a type choosen by DEFINE */ +#ifdef HAVE_64BIT_INT_CUSTOM +typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; +#else +#ifdef HAS_STDINT_H +#include "stdint.h" +typedef uint64_t ZPOS64_T; +#else + + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef unsigned __int64 ZPOS64_T; +#else +typedef unsigned long long int ZPOS64_T; +#endif +#endif +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) + #define ZCALLBACK CALLBACK + #else + #define ZCALLBACK + #endif +#endif + + + + +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + + +/* here is the "old" 32 bits structure structure */ +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + +typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); + +typedef struct zlib_filefunc64_def_s +{ + open64_file_func zopen64_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell64_file_func ztell64_file; + seek64_file_func zseek64_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc64_def; + +void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +/* now internal definition, only for zip.c and unzip.h */ +typedef struct zlib_filefunc64_32_def_s +{ + zlib_filefunc64_def zfile_func64; + open_file_func zopen32_file; + tell_file_func ztell32_file; + seek_file_func zseek32_file; +} zlib_filefunc64_32_def; + + +#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) +//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) +#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) + +voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); +long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); +ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); + +#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) +#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) +#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/mupen64launcher/src/unzip/unzip.c b/source/mupen64launcher/src/unzip/unzip.c new file mode 100755 index 0000000..7617f41 --- /dev/null +++ b/source/mupen64launcher/src/unzip/unzip.c @@ -0,0 +1,2125 @@ +/* unzip.c -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + + ------------------------------------------------------------------------------------ + Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of + compatibility with older software. The following is from the original crypt.c. + Code woven in by Terry Thorsen 1/2003. + + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html + + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + ------------------------------------------------------------------------------------ + + Changes in unzip.c + + 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos + 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* + 2007-2008 - Even Rouault - Remove old C style function prototypes + 2007-2008 - Even Rouault - Add unzip support for ZIP64 + + Copyright (C) 2007-2008 Even Rouault + + + Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). + Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G + should only read the compressed/uncompressed size from the Zip64 format if + the size from normal header was 0xFFFFFFFF + Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant + Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) + Patch created by Daniel Borca + + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + + Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson + +*/ + + +#include +#include +#include + +#ifndef NOUNCRYPT + #define NOUNCRYPT +#endif + +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +# define CASESENSITIVITYDEFAULT_NO +# endif +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + +const char unz_copyright[] = + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info64_internal_s +{ + ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ +} unz_file_info64_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ + ZPOS64_T total_out_64; + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ + ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip64_read_info_s; + + +/* unz64_s contain internal information about the zipfile +*/ +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + int is64bitOpenFunction; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info64 gi; /* public global information */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + ZPOS64_T num_file; /* number of the current file in the zipfile*/ + ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ + ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ + ZPOS64_T central_pos; /* position of the beginning of the central dir*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info64 cur_file_info; /* public info about the current file in zip*/ + unz_file_info64_internal cur_file_info_internal; /* private info about it*/ + file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; + + int isZip64; + +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; +# endif +} unz64_s; + + +#ifndef NOUNCRYPT +#include "crypt.h" +#endif + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +local int unz64local_getByte OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unz64local_getShort OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX)); + + +local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX) +{ + ZPOS64_T x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<24; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<32; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<40; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<48; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<56; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, + const char* fileName2, + int iCaseSensitivity) + +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); +local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + + +/* + Locate the Central directory 64 of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream)); + +local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) + return 0; + + /* total number of disks */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + if (uL != 0x06064b50) + return 0; + + return relativeOffset; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +local unzFile unzOpenInternal (const void *path, + zlib_filefunc64_32_def* pzlib_filefunc64_32_def, + int is64bitOpenFunction) +{ + unz64_s us; + unz64_s *s; + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + us.z_filefunc.zseek32_file = NULL; + us.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); + else + us.z_filefunc = *pzlib_filefunc64_32_def; + us.is64bitOpenFunction = is64bitOpenFunction; + + + + us.filestream = ZOPEN64(us.z_filefunc, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream==NULL) + return NULL; + + central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); + if (central_pos) + { + uLong uS; + ZPOS64_T uL64; + + us.isZip64 = 1; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* size of zip64 end of central directory record */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version made by */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version needed to extract */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + us.gi.size_comment = 0; + } + else + { + central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); + if (central_pos==0) + err=UNZ_ERRNO; + + us.isZip64 = 0; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.gi.number_entry = uL; + + /* total number of entries in the central dir */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + number_entry_CD = uL; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.size_central_dir = uL; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.offset_central_dir = uL; + + /* zipfile comment length */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + } + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + ZCLOSE64(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + +extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + /* to do : check if number_entry is not truncated */ + pglobal_info32->number_entry = (uLong)s->gi.number_entry; + pglobal_info32->size_comment = s->gi.size_comment; + return UNZ_OK; +} +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) +{ + ZPOS64_T uDate; + uDate = (ZPOS64_T)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unz64local_GetCurrentFileInfoInternal (unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ + unz64_s* s; + unz_file_info64 file_info; + unz_file_info64_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + uLong uL; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pos_in_central_dir+s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.compressed_size = uL; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.uncompressed_size = uL; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + // relative offset of local header + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info_internal.offset_curfile = uL; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + // Read extrafield + if ((err==UNZ_OK) && (extraField!=NULL)) + { + ZPOS64_T uSizeRead ; + if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + + lSeek += file_info.size_file_extra - (uLong)uSizeRead; + } + else + lSeek += file_info.size_file_extra; + + + if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) + { + uLong acc = 0; + + // since lSeek now points to after the extra field we need to move back + lSeek -= file_info.size_file_extra; + + if (lSeek!=0) + { + if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + while(acc < file_info.size_file_extra) + { + uLong headerId; + uLong dataSize; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) + err=UNZ_ERRNO; + + /* ZIP64 extra fields */ + if (headerId == 0x0001) + { + uLong uL; + + if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1) + { + /* Relative Header offset */ + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.disk_num_start == (unsigned long)-1) + { + /* Disk Start Number */ + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + } + + } + else + { + if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) + err=UNZ_ERRNO; + } + + acc += 2 + 2 + dataSize; + } + } + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, + unz_file_info64 * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, + unz_file_info * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + int err; + unz_file_info64 file_info64; + err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); + if (err==UNZ_OK) + { + pfile_info->version = file_info64.version; + pfile_info->version_needed = file_info64.version_needed; + pfile_info->flag = file_info64.flag; + pfile_info->compression_method = file_info64.compression_method; + pfile_info->dosDate = file_info64.dosDate; + pfile_info->crc = file_info64.crc; + + pfile_info->size_filename = file_info64.size_filename; + pfile_info->size_file_extra = file_info64.size_file_extra; + pfile_info->size_file_comment = file_info64.size_file_comment; + + pfile_info->disk_num_start = file_info64.disk_num_start; + pfile_info->internal_fa = file_info64.internal_fa; + pfile_info->external_fa = file_info64.external_fa; + + pfile_info->tmu_date = file_info64.tmu_date, + + + pfile_info->compressed_size = (uLong)file_info64.compressed_size; + pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; + + } + return err; +} +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (unzFile file) +{ + int err=UNZ_OK; + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (unzFile file) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) +{ + unz64_s* s; + int err; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info64 cur_file_infoSaved; + unz_file_info64_internal cur_file_info_internalSaved; + ZPOS64_T num_fileSaved; + ZPOS64_T pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + err = unzGetCurrentFileInfo64(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + + +/* +/////////////////////////////////////////// +// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) +// I need random access +// +// Further optimization could be realized by adding an ability +// to cache the directory in memory. The goal being a single +// comprehensive file read to put the file I need in a memory. +*/ + +/* +typedef struct unz_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; // offset in file + ZPOS64_T num_of_file; // # of file +} unz_file_pos; +*/ + +extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) +{ + unz64_s* s; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + int err = unzGetFilePos64(file,&file_pos64); + if (err==UNZ_OK) + { + file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; + file_pos->num_of_file = (uLong)file_pos64.num_of_file; + } + return err; +} + +extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) +{ + unz64_s* s; + int err; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + if (file_pos == NULL) + return UNZ_PARAMERROR; + + file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; + file_pos64.num_of_file = file_pos->num_of_file; + return unzGoToFilePos64(file,&file_pos64); +} + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// +*/ + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, + ZPOS64_T * poffset_local_extrafield, + uInt * psize_local_extrafield) +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, + int* level, int raw, const char* password) +{ + int err=UNZ_OK; + uInt iSizeVar; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +# ifndef NOUNCRYPT + char source[12]; +# else + if (password != NULL) + return UNZ_PARAMERROR; +# endif + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + pfile_in_zip_read_info->raw=raw; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if (method!=NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level!=NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6 : *level = 1; break; + case 4 : *level = 2; break; + case 2 : *level = 9; break; + } + } + + if ((s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + + err=UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->total_out_64=0; + pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream=s->filestream; + pfile_in_zip_read_info->z_filefunc=s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) + { +#ifdef HAVE_BZIP2 + pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; + pfile_in_zip_read_info->bstream.bzfree = (free_func)0; + pfile_in_zip_read_info->bstream.opaque = (voidpf)0; + pfile_in_zip_read_info->bstream.state = (voidpf)0; + + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } +#else + pfile_in_zip_read_info->raw=1; +#endif + } + else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = 0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + s->encrypted = 0; + +# ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password,s->keys,s->pcrc_32_tab); + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET)!=0) + return UNZ_INTERNALERROR; + if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) + return UNZ_INTERNALERROR; + + for (i = 0; i<12; i++) + zdecode(s->keys,s->pcrc_32_tab,source[i]); + + s->pfile_in_zip_read->pos_in_zipfile+=12; + s->encrypted=1; + } +# endif + + + return UNZ_OK; +} + +extern int ZEXPORT unzOpenCurrentFile (unzFile file) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) +{ + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + s=(unz64_s*)file; + if (file==NULL) + return 0; //UNZ_PARAMERROR; + pfile_in_zip_read_info=s->pfile_in_zip_read; + if (pfile_in_zip_read_info==NULL) + return 0; //UNZ_PARAMERROR; + return pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile; +} + +/** Addition for GDAL : END */ + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) +{ + int err=UNZ_OK; + uInt iRead = 0; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis)!=uReadThis) + return UNZ_ERRNO; + + +# ifndef NOUNCRYPT + if(s->encrypted) + { + uInt i; + for(i=0;iread_buffer[i] = + zdecode(s->keys,s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } +# endif + + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy,i ; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead==0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + + pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; + pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; + pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; + pfile_in_zip_read_info->bstream.total_in_hi32 = 0; + pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; + pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; + pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; + pfile_in_zip_read_info->bstream.total_out_hi32 = 0; + + uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; + bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; + + err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); + + uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; + pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; + pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; + pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; + pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; + pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; + + if (err==BZ_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=BZ_OK) + break; +#endif + } // end Z_BZIP2ED + else + { + ZPOS64_T uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + ZPOS64_T uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + +extern ZPOS64_T ZEXPORT unztell64 (unzFile file) +{ + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return (ZPOS64_T)-1; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return (ZPOS64_T)-1; + + return pfile_in_zip_read_info->total_out_64; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* +Read extra field from the current file (opened by unzOpenCurrentFile) +This is the local-header version of the extra field (sometimes, there is +more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + uInt read_now; + ZPOS64_T size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf,read_now)!=read_now) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (unzFile file) +{ + int err=UNZ_OK; + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) + inflateEnd(&pfile_in_zip_read_info->stream); +#ifdef HAVE_BZIP2 + else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) + BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); +#endif + + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) +{ + unz64_s* s; + uLong uReadThis ; + if (file==NULL) + return (int)UNZ_PARAMERROR; + s=(unz64_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + +/* Additions by RX '2004 */ +extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) +{ + unz64_s* s; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file==s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern uLong ZEXPORT unzGetOffset (unzFile file) +{ + ZPOS64_T offset64; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + offset64 = unzGetOffset64(file); + return (uLong)offset64; +} + +extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) +{ + return unzSetOffset64(file,pos); +} diff --git a/source/mupen64launcher/src/unzip/unzip.h b/source/mupen64launcher/src/unzip/unzip.h new file mode 100755 index 0000000..3183968 --- /dev/null +++ b/source/mupen64launcher/src/unzip/unzip.h @@ -0,0 +1,437 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------------- + + Changes + + See header of unzip64.c + +*/ + +#ifndef _unz64_H +#define _unz64_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info64_s +{ + ZPOS64_T number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info64; + +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info64_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + ZPOS64_T compressed_size; /* compressed size 8 bytes */ + ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info64; + +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +extern unzFile ZEXPORT unzOpen64 OF((const void *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. + the "64" function take a const void* pointer, because the path is just the + value passed to the open64_file_func callback. + Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path + is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* + does not describe the reality +*/ + + +extern unzFile ZEXPORT unzOpen2 OF((const char *path, + zlib_filefunc_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, + zlib_filefunc64_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unz64Open, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); + +extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, + unz_global_info64 *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +/* ****************************************** */ +/* Ryan supplied functions */ +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ +} unz_file_pos; + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos); + +typedef struct unz64_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ + ZPOS64_T num_of_file; /* # of file */ +} unz64_file_pos; + +extern int ZEXPORT unzGetFilePos64( + unzFile file, + unz64_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos64( + unzFile file, + const unz64_file_pos* file_pos); + +/* ****************************************** */ + +extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, + unz_file_info64 *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); + +/** Addition for GDAL : END */ + + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, + const char* password)); +/* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, + int* method, + int* level, + int raw)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + +extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, + int* method, + int* level, + int raw, + const char* password)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); + +extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +/***************************************************************************/ + +/* Get the current file offset */ +extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _unz64_H */ diff --git a/source/mupen64launcher/src/version.h b/source/mupen64launcher/src/version.h new file mode 100755 index 0000000..89add71 --- /dev/null +++ b/source/mupen64launcher/src/version.h @@ -0,0 +1,31 @@ +/** + * @section LICENSE + * + * PickleLauncher + * Copyright (C) 2010-2011 Scott Smith + * + * 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 . + * + * @section LOCATION + */ + +#ifndef VERSION_H +#define VERSION_H + +#define APPVERSION "v0.21" /**< The current version. */ +#define APPNAME "Mupen64Launcher, based on PickleLauncher" /**< Application name. */ +#define APPAUTHOR "Scott Smith" /**< Application author. */ +#define APPCOPYRIGHT "(c) 2010-2011" /**< Copyright year. */ + +#endif // VERSION_H -- 2.39.2