Source release for DOOM Classic for iOS version 2.1

This commit is contained in:
Travis Bradshaw 2012-01-31 16:40:40 -06:00
parent 0cdbbdf96e
commit 3bf2af22f3
371 changed files with 167116 additions and 776 deletions

345
COPYING.txt Normal file
View file

@ -0,0 +1,345 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) 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
this service 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 make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. 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.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
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
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the 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 a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE 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.
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
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision 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, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This 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 Library General
Public License instead of this License.

View file

@ -0,0 +1,24 @@
DOOM Classic iOS v2.1 GPL source release
===============================================
This file contains the following sections:
GENERAL NOTES
LICENSE
GENERAL NOTES
=============
DOOM Classic iOS v2.1 is a free release, and can be downloaded from
http://http://www.idsoftware.com/idstuff/doom/doomclassic_ios_v21_src.zip
This source release does not contain any game data, the game data remains subject to the original EULA and applicable law.
LICENSE
=======
See COPYING.txt for the GNU GENERAL PUBLIC LICENSE. If COPYING.txt does not accompany, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

24
README.txt Normal file
View file

@ -0,0 +1,24 @@
DOOM Classic iOS v2.1 GPL source release
===============================================
This file contains the following sections:
GENERAL NOTES
LICENSE
GENERAL NOTES
=============
DOOM Classic iOS v2.1 is a free release, and can be downloaded from
http://http://www.idsoftware.com/idstuff/doom/doomclassic_ios_v21_src.zip
This source release does not contain any game data, the game data remains subject to the original EULA and applicable law.
LICENSE
=======
See COPYING.txt for the GNU GENERAL PUBLIC LICENSE. If COPYING.txt does not accompany, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

BIN
base/.DS_Store vendored Normal file

Binary file not shown.

133
base/.svn/entries Normal file
View file

@ -0,0 +1,133 @@
10
dir
126
svn://svn.eden.idsoftware.com/iphone/trunk/doom/base
svn://svn.eden.idsoftware.com/iphone
2009-07-10T19:42:59.113299Z
119
johnc
b138b6a2-c55d-40dd-9022-e27c2c4ed457
music
dir
base.iPack
file
2009-10-02T16:01:00.000000Z
6faa1d952e42454c38a637052aa9a533
2009-07-10T19:42:59.113299Z
119
johnc
has-props
6541360
doom.wad
file
2009-10-02T16:01:00.000000Z
c4fe9fd920207691a9f493668e0a2083
2009-05-04T22:48:10.686458Z
85
johnc
has-props
12408292
prboom.wad
file
2009-10-02T16:01:00.000000Z
20a751b0bd1bff212f2e320db1db82bb
2009-04-17T15:12:57.371339Z
55
johnc
has-props
281020

View file

@ -0,0 +1,5 @@
K 13
svn:mime-type
V 24
application/octet-stream
END

View file

@ -0,0 +1,9 @@
K 14
svn:executable
V 1
*
K 13
svn:mime-type
V 24
application/octet-stream
END

View file

@ -0,0 +1,5 @@
K 13
svn:mime-type
V 24
application/octet-stream
END

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
base/prboom.wad Normal file

Binary file not shown.

5
code/.svn/dir-prop-base Normal file
View file

@ -0,0 +1,5 @@
K 13
svn:mergeinfo
V 0
END

105
code/.svn/entries Normal file
View file

@ -0,0 +1,105 @@
9
dir
119
svn://svn.eden.idsoftware.com/iphone/trunk/doom/code
svn://svn.eden.idsoftware.com/iphone
2009-07-10T19:42:59.113299Z
119
johnc
has-props
svn:special svn:externals svn:needs-lock
b138b6a2-c55d-40dd-9022-e27c2c4ed457
doomiphone.h
file
2009-07-07T20:07:39.000000Z
228271d33cc005bbe9cc1f60acc11970
2009-07-07T21:22:16.723278Z
114
johnc
2410
iphone
dir
libtess
dir
prboom
dir
wolfiphone.h
file
2009-05-15T16:26:33.625000Z
d7f126798bae7ceaafc3b12d5277dcc1
2009-04-30T17:26:10.292183Z
75
johnc
2301

1
code/.svn/format Normal file
View file

@ -0,0 +1 @@
9

View file

@ -0,0 +1,106 @@
/*
* doomiphone.h
* doom
*
* Created by John Carmack on 3/13/09.
* Copyright 2009 idSoftware. All rights reserved.
*
*/
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <setjmp.h>
#include <math.h>
#include <unistd.h>
#include <stdio.h>
#include <dlfcn.h>
#include <dlfcn.h>
#include <time.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <dirent.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <ifaddrs.h>
#include <OpenGLES/ES1/gl.h>
#include <OpenGLES/ES1/glext.h>
#include "iphone/gles_glue.h"
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#include <OpenAL/oalStaticBufferExtension.h>
#undef ALCAPI
#define ALCAPI
#undef false
#undef true
#include "prboom/SDL_opengl.h"
// prBoom code
#include "prboom/m_fixed.h"
#include "prboom/doomdef.h"
#include "prboom/doomtype.h"
#include "prboom/doomstat.h"
#include "prboom/d_net.h"
#include "prboom/dstrings.h"
#include "prboom/sounds.h"
#include "prboom/z_zone.h"
#include "prboom/w_wad.h"
#include "prboom/s_sound.h"
#include "prboom/v_video.h"
#include "prboom/f_finale.h"
#include "prboom/f_wipe.h"
#include "prboom/m_argv.h"
#include "prboom/m_misc.h"
#include "prboom/m_menu.h"
#include "prboom/p_checksum.h"
#include "prboom/i_main.h"
#include "prboom/i_system.h"
#include "prboom/i_sound.h"
#include "prboom/i_video.h"
#include "prboom/g_game.h"
#include "prboom/hu_stuff.h"
#include "prboom/wi_stuff.h"
#include "prboom/st_stuff.h"
#include "prboom/am_map.h"
#include "prboom/p_setup.h"
#include "prboom/r_draw.h"
#include "prboom/r_main.h"
#include "prboom/r_fps.h"
#include "prboom/d_main.h"
#include "prboom/d_deh.h"
#include "prboom/lprintf.h"
#include "prboom/am_map.h"
#include "prboom/gl_intern.h"
#include "prboom/p_mobj.h"
#include "prboom/p_maputl.h"
#include "prboom/p_map.h"
// open / close name collision problem... #include "prboom/p_spec.h"
#include "prboom/p_inter.h"
#include "prboom/m_random.h"
#include "prboom/m_bbox.h"
#include "prboom/m_cheat.h"
// we will now define landscapeViewport / landscapeScissor to rotate the coords
#undef glViewport
#undef glScissor
// our vestigial system environment
#include "iphone/misc.h"
#include "iphone/cvar.h"
// new iphone code
#include "iphone/ipak.h"
#include "iphone/iphone_doom.h"

View file

@ -0,0 +1,100 @@
/*
* wolfiphone.h
* wolf3d
*
* Created by John Carmack on 3/13/09.
* Copyright 2009 idSoftware. All rights reserved.
*
*/
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <setjmp.h>
#include <math.h>
#include <unistd.h>
#include <stdio.h>
#include <dlfcn.h>
#include <dlfcn.h>
#include <time.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <dirent.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <OpenGLES/ES1/gl.h>
#include <OpenGLES/ES1/glext.h>
#include "iphone/gles_glue.h"
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#include <OpenAL/oalStaticBufferExtension.h>
#undef ALCAPI
#define ALCAPI
#undef false
#undef true
#include "prboom/SDL_opengl.h"
// prBoom code
#include "prboom/m_fixed.h"
#include "prboom/doomdef.h"
#include "prboom/doomtype.h"
#include "prboom/doomstat.h"
#include "prboom/d_net.h"
#include "prboom/dstrings.h"
#include "prboom/sounds.h"
#include "prboom/z_zone.h"
#include "prboom/w_wad.h"
#include "prboom/s_sound.h"
#include "prboom/v_video.h"
#include "prboom/f_finale.h"
#include "prboom/f_wipe.h"
#include "prboom/m_argv.h"
#include "prboom/m_misc.h"
#include "prboom/m_menu.h"
#include "prboom/p_checksum.h"
#include "prboom/i_main.h"
#include "prboom/i_system.h"
#include "prboom/i_sound.h"
#include "prboom/i_video.h"
#include "prboom/g_game.h"
#include "prboom/hu_stuff.h"
#include "prboom/wi_stuff.h"
#include "prboom/st_stuff.h"
#include "prboom/am_map.h"
#include "prboom/p_setup.h"
#include "prboom/r_draw.h"
#include "prboom/r_main.h"
#include "prboom/r_fps.h"
#include "prboom/d_main.h"
#include "prboom/d_deh.h"
#include "prboom/lprintf.h"
#include "prboom/am_map.h"
#include "prboom/gl_intern.h"
#include "prboom/p_mobj.h"
#include "prboom/p_maputl.h"
#include "prboom/p_map.h"
// open / close name collision problem... #include "prboom/p_spec.h"
#include "prboom/p_inter.h"
#include "prboom/m_random.h"
#include "prboom/m_bbox.h"
// we will now define landscapeViewport / landscapeScissor to rotate the coords
#undef glViewport
#undef glScissor
// our vestigial system environment
#include "iphone/misc.h"
#include "iphone/cvar.h"
// new iphone code
#include "iphone/ipak.h"
#include "iphone/iphone_wolf.h"
#include "iphone/iphone_sound.h"

View file

@ -1,13 +1,5 @@
/*
* doomiphone.h
* doom
*
* Created by John Carmack on 3/13/09.
* Copyright 2009 idSoftware. All rights reserved.
*
*/
/*
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
Copyright (C) 2009 Id Software, Inc.
This program is free software; you can redistribute it and/or
@ -26,6 +18,8 @@
*/
#ifndef _DOOM_IPHONE_H_
#define _DOOM_IPHONE_H_
#include <string.h>
#include <stdarg.h>
@ -121,7 +115,10 @@
#include "iphone/cvar.h"
// new iphone code
#include "iphone/IBGlue.h"
#include "iphone/ipak.h"
#include "iphone/iphone_doom.h"
#include "iphone/iphone_email.h" //gsh, adds support for emailing the console to id
#endif

View file

@ -0,0 +1,6 @@
K 10
svn:ignore
V 6
build
END

1391
code/iphone/.svn/entries Normal file

File diff suppressed because it is too large Load diff

1
code/iphone/.svn/format Normal file
View file

@ -0,0 +1 @@
9

View file

@ -0,0 +1,5 @@
K 14
svn:executable
V 1
*
END

View file

@ -0,0 +1,5 @@
K 14
svn:executable
V 1
*
END

View file

@ -0,0 +1,5 @@
K 14
svn:executable
V 1
*
END

View file

@ -0,0 +1,9 @@
K 13
svn:mime-type
V 24
application/octet-stream
K 14
svn:executable
V 1
*
END

View file

@ -0,0 +1,5 @@
K 13
svn:mergeinfo
V 0
END

View file

@ -0,0 +1,5 @@
K 13
svn:mergeinfo
V 0
END

View file

@ -0,0 +1,5 @@
K 13
svn:mergeinfo
V 0
END

View file

@ -0,0 +1,5 @@
K 13
svn:mime-type
V 24
application/octet-stream
END

View file

@ -0,0 +1,507 @@
/*
* BackgroundMusic.cpp
* doom
*
* Created by John Carmack on 5/15/09.
* Copyright 2009 Id Software. All rights reserved.
*
*/
//==================================================================================================
// Includes
//==================================================================================================
// System Includes
#include <AudioToolbox/AudioToolbox.h>
#include <CoreFoundation/CFURL.h>
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#include <map>
#include <vector>
#include <pthread.h>
#include <mach/mach.h>
#include <string>
extern "C" {
#include "doomiphone.h"
}
enum {
kSoundEngineErrUnitialized = 1,
kSoundEngineErrInvalidID = 2,
kSoundEngineErrFileNotFound = 3,
kSoundEngineErrInvalidFileFormat = 4,
kSoundEngineErrDeviceNotFound = 5
};
#define AssertNoError(inMessage, inHandler) \
if(result != noErr) \
{ \
printf("%s: %d\n", inMessage, (int)result); \
goto inHandler; \
}
#define kNumberBuffers 3
static Float32 gMasterVolumeGain = 0.5f;
//==================================================================================================
// Helper functions
//==================================================================================================
OSStatus LoadFileDataInfo(const char *inFilePath, AudioFileID &outAFID, AudioStreamBasicDescription &outFormat, UInt64 &outDataSize)
{
UInt32 thePropSize;
CFURLRef theURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8*)inFilePath, strlen(inFilePath), false);
if (theURL == NULL)
return kSoundEngineErrFileNotFound;
OSStatus result = AudioFileOpenURL(theURL, kAudioFileReadPermission, 0, &outAFID);
CFRelease(theURL);
AssertNoError("Error opening file", end);
thePropSize = sizeof(outFormat);
result = AudioFileGetProperty(outAFID, kAudioFilePropertyDataFormat, &thePropSize, &outFormat);
AssertNoError("Error getting file format", end);
thePropSize = sizeof(UInt64);
result = AudioFileGetProperty(outAFID, kAudioFilePropertyAudioDataByteCount, &thePropSize, &outDataSize);
AssertNoError("Error getting file data size", end);
end:
return result;
}
void CalculateBytesForTime (AudioStreamBasicDescription & inDesc, UInt32 inMaxPacketSize, Float64 inSeconds, UInt32 *outBufferSize, UInt32 *outNumPackets)
{
static const UInt32 maxBufferSize = 0x10000; // limit size to 64K
static const UInt32 minBufferSize = 0x4000; // limit size to 16K
if (inDesc.mFramesPerPacket) {
Float64 numPacketsForTime = inDesc.mSampleRate / inDesc.mFramesPerPacket * inSeconds;
*outBufferSize = (long unsigned int)numPacketsForTime * inMaxPacketSize;
} else {
// if frames per packet is zero, then the codec has no predictable packet == time
// so we can't tailor this (we don't know how many Packets represent a time period
// we'll just return a default buffer size
*outBufferSize = maxBufferSize > inMaxPacketSize ? maxBufferSize : inMaxPacketSize;
}
// we're going to limit our size to our default
if (*outBufferSize > maxBufferSize && *outBufferSize > inMaxPacketSize)
*outBufferSize = maxBufferSize;
else {
// also make sure we're not too small - we don't want to go the disk for too small chunks
if (*outBufferSize < minBufferSize)
*outBufferSize = minBufferSize;
}
*outNumPackets = *outBufferSize / inMaxPacketSize;
}
static Boolean MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
{
UInt32 xFlags = x.mFormatFlags;
UInt32 yFlags = y.mFormatFlags;
// match wildcards
if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0)
return true;
if (x.mFormatID == kAudioFormatLinearPCM)
{
// knock off the all clear flag
xFlags = xFlags & ~kAudioFormatFlagsAreAllClear;
yFlags = yFlags & ~kAudioFormatFlagsAreAllClear;
// if both kAudioFormatFlagIsPacked bits are set, then we don't care about the kAudioFormatFlagIsAlignedHigh bit.
if (xFlags & yFlags & kAudioFormatFlagIsPacked) {
xFlags = xFlags & ~kAudioFormatFlagIsAlignedHigh;
yFlags = yFlags & ~kAudioFormatFlagIsAlignedHigh;
}
// if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit.
if (xFlags & yFlags & kAudioFormatFlagIsFloat) {
xFlags = xFlags & ~kAudioFormatFlagIsSignedInteger;
yFlags = yFlags & ~kAudioFormatFlagIsSignedInteger;
}
// if the bit depth is 8 bits or less and the format is packed, we don't care about endianness
if((x.mBitsPerChannel <= 8) && ((xFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked))
{
xFlags = xFlags & ~kAudioFormatFlagIsBigEndian;
}
if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked))
{
yFlags = yFlags & ~kAudioFormatFlagIsBigEndian;
}
// if the number of channels is 0 or 1, we don't care about non-interleavedness
if (x.mChannelsPerFrame <= 1 && y.mChannelsPerFrame <= 1) {
xFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
yFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
}
}
return xFlags == yFlags;
}
Boolean FormatIsEqual(AudioStreamBasicDescription x, AudioStreamBasicDescription y)
{
// the semantics for equality are:
// 1) Values must match exactly
// 2) wildcard's are ignored in the comparison
#define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name))
return
((x.mSampleRate==0.) || (y.mSampleRate==0.) || (x.mSampleRate==y.mSampleRate))
&& MATCH(mFormatID)
&& MatchFormatFlags(x, y)
&& MATCH(mBytesPerPacket)
&& MATCH(mFramesPerPacket)
&& MATCH(mBytesPerFrame)
&& MATCH(mChannelsPerFrame)
&& MATCH(mBitsPerChannel) ;
}
#pragma mark ***** BackgroundTrackMgr *****
//==================================================================================================
// BackgroundTrackMgr class
//==================================================================================================
typedef struct BG_FileInfo {
std::string mFilePath;
AudioFileID mAFID;
AudioStreamBasicDescription mFileFormat;
UInt64 mFileDataSize;
//UInt64 mFileNumPackets; // this is only used if loading file to memory
Boolean mLoadAtOnce;
Boolean mFileDataInQueue;
} BackgroundMusicFileInfo;
class BackgroundTrackMgr
{
public:
BackgroundTrackMgr();
~BackgroundTrackMgr();
void Teardown();
static void QueueCallback( void * inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inCompleteAQBuffer);
OSStatus SetupQueue(BG_FileInfo *inFileInfo);
OSStatus SetupBuffers(BG_FileInfo *inFileInfo);
OSStatus LoadTrack(const char* inFilePath, Boolean inAddToQueue, Boolean inLoadAtOnce);
OSStatus SetVolume(Float32 inVolume);
Float32 GetVolume() const;
OSStatus Start();
OSStatus Stop(Boolean inStopAtEnd);
AudioQueueRef mQueue;
AudioQueueBufferRef mBuffers[kNumberBuffers];
UInt32 mBufferByteSize;
SInt64 mCurrentPacket;
UInt32 mNumPacketsToRead;
Float32 mVolume;
AudioStreamPacketDescription * mPacketDescs;
static BG_FileInfo * CurFileInfo;
Boolean mStopAtEnd;
};
BG_FileInfo *BackgroundTrackMgr::CurFileInfo;
BackgroundTrackMgr::BackgroundTrackMgr()
: mQueue(0),
mBufferByteSize(0),
mCurrentPacket(0),
mNumPacketsToRead(0),
mVolume(1.0f),
mPacketDescs(NULL),
mStopAtEnd(false)
{ }
BackgroundTrackMgr::~BackgroundTrackMgr() {
Teardown();
}
void BackgroundTrackMgr::Teardown() {
if (mQueue) {
AudioQueueDispose(mQueue, true);
mQueue = NULL;
}
if ( CurFileInfo ) {
AudioFileClose( CurFileInfo->mAFID);
delete CurFileInfo;
CurFileInfo = NULL;
}
if (mPacketDescs) {
delete[] mPacketDescs;
mPacketDescs = NULL;
}
}
void BackgroundTrackMgr::QueueCallback( void * inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inCompleteAQBuffer ) {
// dispose of the buffer if no longer in use
OSStatus result = noErr;
BackgroundTrackMgr *THIS = (BackgroundTrackMgr*)inUserData;
UInt32 nPackets = 0;
// loop the current buffer if the following:
// 1. file was loaded into the buffer previously
// 2. only one file in the queue
// 3. we have not been told to stop at playlist completion
if ((CurFileInfo->mFileDataInQueue) && (!THIS->mStopAtEnd)) {
nPackets = THIS->mNumPacketsToRead;
} else {
UInt32 numBytes;
while (nPackets == 0) {
// if loadAtOnce, get all packets in the file, otherwise ~.5 seconds of data
nPackets = THIS->mNumPacketsToRead;
result = AudioFileReadPackets(CurFileInfo->mAFID, false, &numBytes, THIS->mPacketDescs, THIS->mCurrentPacket, &nPackets,
inCompleteAQBuffer->mAudioData);
AssertNoError("Error reading file data", end);
inCompleteAQBuffer->mAudioDataByteSize = numBytes;
if (nPackets == 0) { // no packets were read, this file has ended.
if (CurFileInfo->mLoadAtOnce) {
CurFileInfo->mFileDataInQueue = true;
}
THIS->mCurrentPacket = 0;
// we have gone through the playlist. if mStopAtEnd, stop the queue here
if ( THIS->mStopAtEnd ) {
result = AudioQueueStop(inAQ, false);
AssertNoError("Error stopping queue", end);
return;
}
}
}
}
result = AudioQueueEnqueueBuffer(inAQ, inCompleteAQBuffer, (THIS->mPacketDescs ? nPackets : 0), THIS->mPacketDescs);
if(result != noErr) {
result = AudioQueueFreeBuffer(inAQ, inCompleteAQBuffer);
AssertNoError("Error freeing buffers that didn't enqueue", end);
}
AssertNoError("Error enqueuing new buffer", end);
if (CurFileInfo->mLoadAtOnce) {
CurFileInfo->mFileDataInQueue = true;
}
THIS->mCurrentPacket += nPackets;
end:
return;
}
OSStatus BackgroundTrackMgr::SetupQueue(BG_FileInfo *inFileInfo) {
UInt32 size = 0;
OSStatus result = AudioQueueNewOutput(&inFileInfo->mFileFormat, QueueCallback, this,
CFRunLoopGetMain() /* CFRunLoopGetCurrent() */, kCFRunLoopCommonModes, 0, &mQueue);
AssertNoError("Error creating queue", end);
#if 0
// (2) If the file has a cookie, we should get it and set it on the AQ
size = sizeof(UInt32);
result = AudioFileGetPropertyInfo (inFileInfo->mAFID, kAudioFilePropertyMagicCookieData, &size, NULL);
if (!result && size) {
char* cookie = new char [size];
result = AudioFileGetProperty (inFileInfo->mAFID, kAudioFilePropertyMagicCookieData, &size, cookie);
AssertNoError("Error getting magic cookie", end);
result = AudioQueueSetProperty(mQueue, kAudioQueueProperty_MagicCookie, cookie, size);
delete [] cookie;
AssertNoError("Error setting magic cookie", end);
}
#endif
// channel layout
OSStatus err = AudioFileGetPropertyInfo(inFileInfo->mAFID, kAudioFilePropertyChannelLayout, &size, NULL);
if (err == noErr && size > 0) {
AudioChannelLayout *acl = (AudioChannelLayout *)malloc(size);
result = AudioFileGetProperty(inFileInfo->mAFID, kAudioFilePropertyChannelLayout, &size, acl);
AssertNoError("Error getting channel layout from file", end);
result = AudioQueueSetProperty(mQueue, kAudioQueueProperty_ChannelLayout, acl, size);
free(acl);
AssertNoError("Error setting channel layout on queue", end);
}
// volume
result = SetVolume(mVolume);
end:
return result;
}
OSStatus BackgroundTrackMgr::SetupBuffers(BG_FileInfo *inFileInfo) {
int numBuffersToQueue = kNumberBuffers;
UInt32 maxPacketSize;
UInt32 size = sizeof(maxPacketSize);
// we need to calculate how many packets we read at a time, and how big a buffer we need
// we base this on the size of the packets in the file and an approximate duration for each buffer
// first check to see what the max size of a packet is - if it is bigger
// than our allocation default size, that needs to become larger
OSStatus result = AudioFileGetProperty(inFileInfo->mAFID, kAudioFilePropertyPacketSizeUpperBound, &size, &maxPacketSize);
AssertNoError("Error getting packet upper bound size", end);
bool isFormatVBR = (inFileInfo->mFileFormat.mBytesPerPacket == 0 || inFileInfo->mFileFormat.mFramesPerPacket == 0);
CalculateBytesForTime(inFileInfo->mFileFormat, maxPacketSize, 0.5/*seconds*/, &mBufferByteSize, &mNumPacketsToRead);
// if the file is smaller than the capacity of all the buffer queues, always load it at once
if ((mBufferByteSize * numBuffersToQueue) > inFileInfo->mFileDataSize) {
inFileInfo->mLoadAtOnce = true;
}
if (inFileInfo->mLoadAtOnce) {
UInt64 theFileNumPackets;
size = sizeof(UInt64);
result = AudioFileGetProperty(inFileInfo->mAFID, kAudioFilePropertyAudioDataPacketCount, &size, &theFileNumPackets);
AssertNoError("Error getting packet count for file", end);
mNumPacketsToRead = (UInt32)theFileNumPackets;
mBufferByteSize = (UInt32)inFileInfo->mFileDataSize;
numBuffersToQueue = 1;
} else {
mNumPacketsToRead = mBufferByteSize / maxPacketSize;
}
if (isFormatVBR) {
mPacketDescs = new AudioStreamPacketDescription [mNumPacketsToRead];
} else {
mPacketDescs = NULL; // we don't provide packet descriptions for constant bit rate formats (like linear PCM)
}
// allocate the queue's buffers
for (int i = 0; i < numBuffersToQueue; ++i) {
result = AudioQueueAllocateBuffer(mQueue, mBufferByteSize, &mBuffers[i]);
AssertNoError("Error allocating buffer for queue", end);
QueueCallback (this, mQueue, mBuffers[i]);
if (inFileInfo->mLoadAtOnce) {
inFileInfo->mFileDataInQueue = true;
}
}
end:
return result;
}
OSStatus BackgroundTrackMgr::LoadTrack(const char* inFilePath, Boolean inAddToQueue, Boolean inLoadAtOnce) {
// OSStatus result = LoadFileDataInfo(CurFileInfo->mFilePath.c_str(), CurFileInfo->mAFID, CurFileInfo->mFileFormat, CurFileInfo->mFileDataSize);
// AssertNoError("Error getting file data info", fail);
OSStatus result;
UInt32 thePropSize;
CFURLRef theURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8*)inFilePath, strlen(inFilePath), false);
if (theURL == NULL)
result = kSoundEngineErrFileNotFound;
else
result = 0;
AssertNoError("Error opening URL", fail);
CurFileInfo = new BG_FileInfo;
CurFileInfo->mFilePath = inFilePath;
result = AudioFileOpenURL(theURL, kAudioFileReadPermission, 0, &CurFileInfo->mAFID);
CFRelease(theURL);
AssertNoError("Error opening file", fail);
thePropSize = sizeof(CurFileInfo->mFileFormat);
result = AudioFileGetProperty(CurFileInfo->mAFID, kAudioFilePropertyDataFormat, &thePropSize, &CurFileInfo->mFileFormat);
AssertNoError("Error getting file format", fail);
thePropSize = sizeof(UInt64);
result = AudioFileGetProperty(CurFileInfo->mAFID, kAudioFilePropertyAudioDataByteCount, &thePropSize, &CurFileInfo->mFileDataSize);
AssertNoError("Error getting file data size", fail);
CurFileInfo->mLoadAtOnce = inLoadAtOnce;
CurFileInfo->mFileDataInQueue = false;
result = SetupQueue(CurFileInfo);
AssertNoError("Error setting up queue", fail);
result = SetupBuffers(CurFileInfo);
AssertNoError("Error setting up queue buffers", fail);
return result;
fail:
if (CurFileInfo) {
delete CurFileInfo;
CurFileInfo = NULL;
}
return result;
}
OSStatus BackgroundTrackMgr::SetVolume(Float32 inVolume) {
mVolume = inVolume;
return AudioQueueSetParameter(mQueue, kAudioQueueParam_Volume, mVolume * gMasterVolumeGain);
}
Float32 BackgroundTrackMgr::GetVolume() const {
return mVolume;
}
OSStatus BackgroundTrackMgr::Start() {
OSStatus result = AudioQueuePrime(mQueue, 1, NULL);
if (result) {
printf("BackgroundTrackMgr: Error priming queue: %d\n", (int)result);
return result;
}
return AudioQueueStart(mQueue, NULL);
}
OSStatus BackgroundTrackMgr::Stop(Boolean inStopAtEnd) {
if (inStopAtEnd) {
mStopAtEnd = true;
return noErr;
} else {
return AudioQueueStop(mQueue, true);
}
}
static BackgroundTrackMgr sBackgroundTrackMgr;
static char currentMusicName[1024];
void iphoneStopMusic() {
sBackgroundTrackMgr.Teardown();
}
void iphoneStartMusic() {
if ( music->value == 0 ) {
// music is disabled
return;
}
char fullName[1024];
sprintf( fullName, "%s/base/music/d_%s.mp3", SysIphoneGetAppDir(), currentMusicName );
printf( "Starting music '%s'\n", fullName );
iphoneStopMusic();
sBackgroundTrackMgr.LoadTrack( fullName, false, true);
sBackgroundTrackMgr.Start();
if ( !strcmp( currentMusicName, "intro" ) ) {
// stop the intro music at end, don't loop
sBackgroundTrackMgr.mStopAtEnd = true;
} else {
sBackgroundTrackMgr.mStopAtEnd = false;
}
}
void iphonePlayMusic( const char *name ) {
strcpy( currentMusicName, name );
iphoneStartMusic();
}

View file

@ -0,0 +1,48 @@
/*
Copyright (C) 2009 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
/*
This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass.
The view content is basically an EAGL surface you render your OpenGL scene into.
Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel.
*/
@interface EAGLView : UIView <UITextFieldDelegate> {
@public
UITextField *textField;
@private
/* The pixel dimensions of the backbuffer */
GLint backingWidth;
GLint backingHeight;
/* OpenGL names for the renderbuffer and framebuffers used to render to this view */
GLuint viewRenderbuffer, viewFramebuffer;
/* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
GLuint depthRenderbuffer;
}
@end

View file

@ -0,0 +1,334 @@
//
// EAGLView.m
// Doom
//
// Created by Cass Everitt on 2/20/09.
// Copyright Id Software 2009. All rights reserved.
//
#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGLDrawable.h>
#import "EAGLView.h"
#import "doomAppDelegate.h"
#include "doomiphone.h"
#include <pthread.h>
EAGLView *eaglview;
EAGLContext *context;
@implementation EAGLView
// You must implement this method
+ (Class)layerClass {
return [CAEAGLLayer class];
}
CAEAGLLayer *eaglLayer;
//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
- (id)initWithCoder:(NSCoder*)coder {
self = [super initWithCoder:coder];
eaglview = self;
// allow multiple touch events
self.multipleTouchEnabled = true;
// Get the layer
eaglLayer = (CAEAGLLayer *)self.layer;
// set opaque so UIKit doesn't try to blend it over other layers
eaglLayer.opaque = YES;
// set it to no-backing-retained so it can do ast pageflips instead
// of update copies, and go to 565 bit depth for higher performance.
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO],
kEAGLDrawablePropertyRetainedBacking,
kEAGLColorFormatRGB565,
/* kEAGLColorFormatRGBA8, */
kEAGLDrawablePropertyColorFormat,
nil];
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
assert( context );
if ( ![EAGLContext setCurrentContext:context]) {
[self release];
return nil;
}
glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
glGenRenderbuffersOES(1, &depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
}
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
return self;
}
- (void) handleTouches:(UIEvent*)event {
int touchCount = 0;
static int previousTouchCount;
static int touchRover;
int touchThisSequence[MAX_TOUCHES];
memset( touchThisSequence, 0, sizeof( touchThisSequence ) );
NSSet *touches = [event allTouches];
// printf( "count: %i\n", [touches count] );
// lock the game out temporarily
pthread_mutex_lock( &eventMutex );
for (UITouch *myTouch in touches)
{
CGPoint touchLocation = [myTouch locationInView:nil];
// handle landscape mode and flipping
int x, y;
if ( revLand->value ) {
x = touchLocation.y;
y = 319 - touchLocation.x;
} else {
x = 479 - touchLocation.y;
y = touchLocation.x;
}
// printf( "%i, %i\n", x, y );
touchCount++;
touch_t *t2;
// find which one it is closest to
int minDist = 64 * 64; // allow up to 64 unit moves to be drags
int minIndex = -1;
for ( int i = 0 ; i < MAX_TOUCHES ; i++ ) {
t2 = &sysTouches[i];
if ( !t2->down ) {
continue;
}
int dist = ( t2->x - x ) * ( t2->x - x ) + ( t2->y - y ) * ( t2->y - y );
if ( dist < minDist ) {
minDist = dist;
minIndex = i;
}
}
if ( minIndex != -1 ) {
// reuse a touch
sysTouches[minIndex].x = x;
sysTouches[minIndex].y = y;
if (myTouch.phase == UITouchPhaseEnded) {
// if this was released before the game got to see it,
// make it a special case
if ( sysTouches[minIndex].stateCount == 1 ) {
// leave it in the down state with a special count
sysTouches[minIndex].stateCount = -1;
// printf( "Tap release touch on a reuse\n" );
} else {
sysTouches[minIndex].down = false;
sysTouches[minIndex].stateCount = 1;
// printf( "Release touch on a reuse\n" );
}
} else {
if (myTouch.phase == UITouchPhaseBegan) {
sysTouches[minIndex].stateCount = 1;
sysTouches[minIndex].controlOwner = NULL;
// printf( "Begin touch on a reuse\n" );
} else {
// printf( "Drag touch on a reuse\n" );
}
sysTouches[minIndex].down = true;
}
touchThisSequence[minIndex] = true;
} else {
if ( myTouch.phase != UITouchPhaseBegan ) {
printf( "Non-local touch wasn't a begin\n" );
} else {
// allocate a new one
// grab the next rover spot
// don't just use first-not-down, because that might
// cause the release to be missed by the game code.
int i, j;
for ( j = 0 ; j < MAX_TOUCHES ; j++ ) {
i = touchRover;
t2 = &sysTouches[i];
touchRover = ( touchRover + 1 ) % MAX_TOUCHES;
if ( !t2->down ) {
break;
}
}
if ( j == MAX_TOUCHES ) {
printf( "MAX_TOUCHES, clearing everything!\n" );
memset( sysTouches, 0, sizeof( sysTouches ) );
continue;
}
// printf( "new touch down\n" );
t2->x = x;
t2->y = y;
t2->down = true;
t2->controlOwner = NULL;
t2->stateCount = 1;
touchThisSequence[i] = true;
}
}
}
// Change any active touches to released if they weren't
// in the touch set. This will happen if we forced a break because
// a "moved" event was so large that it was very likely a release and
// press of a different finger that happened to be in the same frame.
for ( int i = 0 ; i < MAX_TOUCHES ; i++ ) {
if ( sysTouches[i].down && !touchThisSequence[i] ) {
printf( "clearing touch %i\n", i );
sysTouches[i].down = false;
sysTouches[i].stateCount = 0;
touchCount--;
}
}
// toggle the console with four touches
if ( touchCount == 4 && previousTouchCount != 4 ) {
touchCount = 0; // won't get the releases, because the text field will eat them
if ( textField == nil ) {
// do this before starting the textField, which
// takes a long time
// iphoneActivateConsole();
textField = [UITextField alloc];
[textField initWithFrame:CGRectMake( 0, 0, 20, 20 ) ];
[self addSubview:textField];
[textField release];
textField.hidden = true;
textField.delegate = self;
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
textField.autocorrectionType = UITextAutocorrectionTypeNo;
[textField becomeFirstResponder];
} else {
}
}
// the game is free to copy the touches now
pthread_mutex_unlock( &eventMutex );
previousTouchCount = touchCount;
}
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
// printf( "touchesBegan\n" );
[self handleTouches:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
// printf( "touchesMoved\n" );
[self handleTouches:event];
}
- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
// printf( "touchesEnded\n" );
[self handleTouches:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
// printf( "touchesCancelled\n" );
[self handleTouches:event];
}
@end
@implementation EAGLView (UITextFieldDelegate)
char consoleCommand[1024];
- (BOOL)textFieldShouldReturn:(UITextField *)_textField
{
if ( eaglview->textField == nil ) {
return YES;
}
// we can't just execute this, because we are running in another
// thread, so fetch the line and the game will catch it next time
// around
// lock the game out temporarily
pthread_mutex_lock( &eventMutex );
const char *line = [ eaglview->textField.text UTF8String ];
strncpy( consoleCommand, line, sizeof(consoleCommand)-1 );
eaglview->textField.text = [ NSString stringWithUTF8String: "" ];
// put it away
[textField resignFirstResponder];
[textField removeFromSuperview];
textField = nil;
// lock the game out temporarily
pthread_mutex_unlock( &eventMutex );
return YES;
}
@end
const char * SysIPhoneGetConsoleTextField() {
if ( eaglview->textField == nil ) {
return "";
}
return [ eaglview->textField.text UTF8String ];
}
void SysIPhoneSetConsoleTextField( const char * str) {
assert( eaglview->textField != nil );
eaglview->textField.text = [ NSString stringWithUTF8String: str ];
}
void SysIPhoneSwapBuffers() {
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
void SysIPhoneOpenURL( const char *url ) {
Com_Printf( "OpenURL char *: %s\n", url );
NSString *nss = [NSString stringWithCString: url encoding: NSASCIIStringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: nss]];
}
void SysIPhoneSetUIKitOrientation( int isLandscapeRight ) {
if ( isLandscapeRight ) {
[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeRight;
} else {
[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeLeft;
}
}

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key></key>
<string></string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string>${PRODUCT_NAME}_icon.png</string>
<key>CFBundleIdentifier</key>
<string>${PROFILE_PREFIX}.${PRODUCT_NAME:identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSMainNibFile</key>
<string>MainWindow</string>
<key>UIInterfaceOrientation</key>
<string>UIInterfaceOrientationLandscapeLeft</string>
<key>UIRequiresPersistentWiFi</key>
<true/>
<key>UIStatusBarHidden</key>
<true/>
</dict>
</plist>

View file

@ -0,0 +1,233 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.03">
<data>
<int key="IBDocument.SystemTarget">528</int>
<string key="IBDocument.SystemVersion">9G55</string>
<string key="IBDocument.InterfaceBuilderVersion">677</string>
<string key="IBDocument.AppKitVersion">949.43</string>
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="8"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBProxyObject" id="841351856">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
</object>
<object class="IBProxyObject" id="191355593">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
</object>
<object class="IBUICustomObject" id="664661524"/>
<object class="IBUIWindow" id="380026005">
<reference key="NSNextResponder"/>
<int key="NSvFlags">1316</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUIView" id="773737154">
<reference key="NSNextResponder" ref="380026005"/>
<int key="NSvFlags">1298</int>
<string key="NSFrameSize">{320, 480}</string>
<reference key="NSSuperview" ref="380026005"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace">
<int key="NSID">2</int>
</object>
</object>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
</object>
</object>
<object class="NSPSMatrix" key="NSFrameMatrix"/>
<string key="NSFrameSize">{320, 480}</string>
<reference key="NSSuperview"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MSAxIDEAA</bytes>
</object>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<bool key="IBUIVisibleAtLaunch">YES</bool>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="664661524"/>
</object>
<int key="connectionID">4</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">window</string>
<reference key="source" ref="664661524"/>
<reference key="destination" ref="380026005"/>
</object>
<int key="connectionID">5</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">glView</string>
<reference key="source" ref="664661524"/>
<reference key="destination" ref="773737154"/>
</object>
<int key="connectionID">9</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
<object class="NSArray" key="object" id="957960031">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="380026005"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="773737154"/>
</object>
<reference key="parent" ref="957960031"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="841351856"/>
<reference key="parent" ref="957960031"/>
<string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="664661524"/>
<reference key="parent" ref="957960031"/>
<string key="objectName">Game App Delegate</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">8</int>
<reference key="object" ref="773737154"/>
<reference key="parent" ref="380026005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="191355593"/>
<reference key="parent" ref="957960031"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-1.CustomClassName</string>
<string>-2.CustomClassName</string>
<string>2.IBAttributePlaceholdersKey</string>
<string>2.IBEditorWindowLastContentRect</string>
<string>2.IBPluginDependency</string>
<string>3.CustomClassName</string>
<string>3.IBPluginDependency</string>
<string>8.CustomClassName</string>
<string>8.IBPluginDependency</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>UIApplication</string>
<string>UIResponder</string>
<object class="NSMutableDictionary">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<string>{{500, 343}, {320, 480}}</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>gameAppDelegate</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>EAGLView</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">10</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">EAGLView</string>
<string key="superclassName">UIView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">EAGLView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">gameAppDelegate</string>
<string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>glView</string>
<string>window</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>EAGLView</string>
<string>UIWindow</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">doomAppDelegate.h</string>
</object>
</object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.LastKnownRelativeProjectPath">doom.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
</data>
</archive>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,383 @@
/*
File: SoundEngine.h
Abstract: These functions play background music tracks, multiple sound effects,
and support stereo panning with a low-latency response.
Version: 1.7
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under
Apple's copyrights in this original Apple software (the "Apple Software"), to
use, reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions
of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Inc. may be used
to endorse or promote products derived from the Apple Software without specific
prior written permission from Apple. Except as expressly stated in this notice,
no other rights or licenses, express or implied, are granted by Apple herein,
including but not limited to any patent rights that may be infringed by your
derivative works or by other works in which the Apple Software may be
incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Copyright (C) 2008 Apple Inc. All Rights Reserved.
*/
/*==================================================================================================
SoundEngine.h
==================================================================================================*/
#if !defined(__SoundEngine_h__)
#define __SoundEngine_h__
//==================================================================================================
// Includes
//==================================================================================================
// System Includes
#ifndef WIN32
#include <CoreAudio/CoreAudioTypes.h>
#include <AudioToolbox/AudioToolbox.h>
#else
typedef int OSStatus;
typedef int SInt32;
typedef unsigned int UInt32;
typedef float Float32;
typedef unsigned char Boolean;
#endif
#if defined(__cplusplus)
extern "C"
{
#endif
//==================================================================================================
// Sound Engine
//==================================================================================================
/*!
@enum SoundEngine error codes
@abstract These are the error codes returned from the SoundEngine API.
@constant kSoundEngineErrUnitialized
The SoundEngine has not been initialized. Use SoundEngine_Initialize().
@constant kSoundEngineErrInvalidID
The specified EffectID was not found. This can occur if the effect has not been loaded, or
if an unloaded is trying to be accessed.
@constant kSoundEngineErrFileNotFound
The specified file was not found.
@constant kSoundEngineErrInvalidFileFormat
The format of the file is invalid. Effect data must be little-endian 8 or 16 bit LPCM.
@constant kSoundEngineErrDeviceNotFound
The output device was not found.
*/
enum {
kSoundEngineErrUnitialized = 1,
kSoundEngineErrInvalidID = 2,
kSoundEngineErrFileNotFound = 3,
kSoundEngineErrInvalidFileFormat = 4,
kSoundEngineErrDeviceNotFound = 5
};
/*!
@function SoundEngine_Initialize
@abstract Initializes and sets up the sound engine. Calling after a previous initialize will
reset the state of the SoundEngine, with all previous effects and music tracks
erased. Note: This is not required, loading an effect or background track will
initialize as necessary.
@param inMixerOutputRate
A Float32 that represents the output sample rate of the mixer unit. Setting this to
0 will use the default rate (the sample rate of the device)
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_Initialize(Float32 inMixerOutputRate);
OSStatus SoundEngine_Reactivate();
/*!
@function SoundEngine_Teardown
@abstract Tearsdown the sound engine.
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_Teardown();
/*!
@function SoundEngine_SetMasterVolume
@abstract Sets the overall volume of all sounds coming from the process
@param inValue
A Float32 that represents the level. The range is between 0.0 and 1.0 (inclusive).
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_SetMasterVolume(Float32 inValue);
/*!
@function SoundEngine_SetListenerPosition
@abstract Sets the position of the listener in the 3D space
@param inX
A Float32 that represents the listener's position along the X axis.
@param inY
A Float32 that represents the listener's position along the Y axis.
@param inZ
A Float32 that represents the listener's position along the Z axis.
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_SetListenerPosition(Float32 inX, Float32 inY, Float32 inZ);
OSStatus SoundEngine_SetListenerDirection(Float32 inX, Float32 inY, Float32 inZ);
/*!
@function SoundEngine_SetListenerGain
@abstract Sets the gain of the listener. Must be >= 0.0
@param inValue
A Float32 that represents the listener's gain
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_SetListenerGain(Float32 inValue);
/*!
@function SoundEngine_LoadBackgroundMusicTrack
@abstract Tells the background music player which file to play
@param inPath
The absolute path to the file to play.
@param inAddToQueue
If true, file will be added to the current background music queue. If
false, queue will be cleared and only loop the specified file.
@param inLoadAtOnce
If true, file will be loaded completely into memory. If false, data will be
streamed from the file as needed. For games without large memory pressure and/or
small background music files, this can save memory access and improve power efficiency
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_LoadBackgroundMusicTrack(const char* inPath, Boolean inAddToQueue, Boolean inLoadAtOnce);
/*!
@function SoundEngine_UnloadBackgroundMusicTrack
@abstract Tells the background music player to release all resources and stop playing.
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_UnloadBackgroundMusicTrack();
/*!
@function SoundEngine_StartBackgroundMusic
@abstract Tells the background music player to start playing.
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_StartBackgroundMusic();
/*!
@function SoundEngine_StopBackgroundMusic
@abstract Tells the background music player to stop playing.
@param inAddToQueue
If true, playback will stop when all tracks have completed. If false, playback
will stop immediately.
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_StopBackgroundMusic(Boolean inStopAtEnd);
/*!
@function SoundEngine_SetBackgroundMusicVolume
@abstract Sets the volume for the background music player
@param inValue
A Float32 that represents the level. The range is between 0.0 and 1.0 (inclusive).
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_SetBackgroundMusicVolume(Float32 inValue);
/*!
@function SoundEngine_GetBackgroundMusicVolume
@abstract Gets the volume for the background music player
@result A Float32 representing the background music player volume, or 0 if it's not enabled
*/
Float32 SoundEngine_GetBackgroundMusicVolume();
/*!
@function SoundEngine_LoadLoopingEffect
@abstract Loads a sound effect from a file and return an ID to refer to that effect. Note: The files
MUST all be in the same data format and sample rate
@param inLoopFilePath
The absolute path to the file to load. This is the file that will loop continually.
@param inAttackFilePath
The absolute path to the file to load. This will play once at the start of the effect.
Set to NULL if no attack is desired, looping file will play immediately.
@param inDecayFilePath
The absolute path to the file to load. This will play once after looping has been ended.
Triggered using SoundEngine_StopEffect with the inDoDecay set to true. Set to NULL if no
decay is desired, looping file will stop immediately.
@param outEffectID
A UInt32 ID that refers to the effect.
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_LoadLoopingEffect(const char* inLoopFilePath, const char* inAttackFilePath, const char* inDecayFilePath, UInt32* outEffectID);
/*!
@function SoundEngine_LoadEffect
@abstract Loads a sound effect from a file and return an ID to refer to that effect.
@param inPath
The absolute path to the file to load.
@param outEffectID
A UInt32 ID that refers to the effect.
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_LoadEffect(const char* inPath, UInt32* outEffectID);
/*!
@function SoundEngine_UnloadEffect
@abstract Releases all resources associated with the given effect ID
@param inEffectID
The ID of the effect to unload.
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_UnloadEffect(UInt32 inEffectID);
/*!
@function SoundEngine_StartEffect
@abstract Starts playback of an effect
@param inEffectID
The ID of the effect to start.
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_StartEffect(UInt32 inEffectID);
/*!
@function SoundEngine_StopEffect
@abstract Stops playback of an effect
@param inEffectID
The ID of the effect to stop.
@param inDoDecay
Whether to play the decay file or stop immmediately (this is ignored
for non-looping effects)
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_StopEffect(UInt32 inEffectID, Boolean inDoDecay);
/*!
@function SoundEngine_Vibrate
@abstract Tells the device to vibrate
*/
#if TARGET_OS_IPHONE
#define SoundEngine_Vibrate() AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
#endif
/*!
@function SoundEngine_SetEffectPitch
@abstract Applies pitch shifting to an effect
@param inEffectID
The ID of the effect to adjust
@param inValue
A Float32 that represents the pitch scalar, with 1.0 being unchanged. Must
be greater than 0.
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_SetEffectPitch(UInt32 inEffectID, Float32 inValue);
/*!
@function SoundEngine_SetEffectVolume
@abstract Sets the volume for an effect
@param inEffectID
The ID of the effect to adjust
@param inValue
A Float32 that represents the level. The range is between 0.0 and 1.0 (inclusive).
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_SetEffectLevel(UInt32 inEffectID, Float32 inValue);
/*!
@function SoundEngine_SetEffectPosition
@abstract Tells the engine whether a given effect should loop when played or if it should
play through just once and stop.
@param inEffectID
The ID of the effect to adjust
@param inX
A Float32 that represents the effect's position along the X axis. Maximum distance
is 100000.0 (absolute, not per axis), reference distance (distance from which gain
begins to attenuate) is 1.0
@param inY
A Float32 that represents the effect's position along the Y axis. Maximum distance
is 100000.0 (absolute, not per axis), reference distance (distance from which gain
begins to attenuate) is 1.0
@param inZ
A Float32 that represents the effect's position along the Z axis. Maximum distance
is 100000.0 by default (absolute, not per axis), reference distance (distance from
which gain begins to attenuate) is 1.0
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_SetEffectPosition(UInt32 inEffectID, Float32 inX, Float32 inY, Float32 inZ);
/*!
@function SoundEngine_SetEffectsVolume
@abstract Sets the overall volume for the effects
@param inValue
A Float32 that represents the level. The range is between 0.0 and 1.0 (inclusive).
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_SetEffectsVolume(Float32 inValue);
/*!
@function SoundEngine_GetEffectsVolume
@abstract Gets the overall volume for the effects
@result A Float32 representing the effects volume, or 0 if it's disabled
*/
Float32 SoundEngine_GetEffectsVolume();
/*!
@function SoundEngine_SetMaxDistance
@abstract Sets the maximum distance for effect attenuation. Gain will attenuate between the
reference distance and the maximum distance, after which gain will be 0.0
@param inValue
A Float32 that represents the level. Must be greater than 0.0.
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_SetMaxDistance(Float32 inValue);
/*!
@function SoundEngine_SetReferenceDistance
@abstract Sets the distance at which effect gain attenuation begins. It will attenuate between
the reference distance and the maximum distance. Sounds closer than the reference
distance will have no attenuation applied
@param inValue
A Float32 that represents the level. Must be greater than 0.0.
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_SetReferenceDistance(Float32 inValue);
/*!
@function SoundEngine_SetEffectReferenceDistance
@abstract Sets the distance at which effect gain attenuation begins. It will attenuate between
the reference distance and the maximum distance. Sounds closer than the reference
distance will have no attenuation applied
@param inEffectId
The sound engine effect Id
@param inValue
A Float32 that represents the level. Must be greater than 0.0.
@result A OSStatus indicating success or failure.
*/
OSStatus SoundEngine_SetEffectReferenceDistance(UInt32 inEffectID, Float32 inValue);
#if defined(__cplusplus)
}
#endif
#endif

View file

@ -0,0 +1,102 @@
// generated by fontimg
//
// struct GlyphRect { unsigned short x0, y0, x1, y1; float xoff, yoff, xadvance; };
GlyphRect glyphRects[] = {
/* ' ' */ { 2, 2, 2, 2, 0.000000, 0.000000, 7.958042 },
/* '!' */ { 6, 2, 9, 22, 2.250000, -20.750000, 7.958042 },
/* '"' */ { 14, 2, 21, 9, 1.250000, -20.750000, 10.167832 },
/* '#' */ { 26, 2, 41, 23, 0.250000, -21.000000, 15.930070 },
/* '$' */ { 46, 2, 59, 27, 1.000000, -22.500000, 15.930070 },
/* '%' */ { 64, 2, 86, 24, 1.500000, -21.000000, 25.468531 },
/* '&' */ { 92, 2, 109, 23, 1.000000, -21.000000, 19.104895 },
/* ''' */ { 114, 2, 117, 9, 1.250000, -20.750000, 5.468532 },
/* '(' */ { 122, 2, 129, 29, 1.500000, -21.000000, 9.538462 },
/* ')' */ { 134, 2, 141, 29, 1.500000, -21.000000, 9.538462 },
/* '*' */ { 146, 2, 155, 11, 0.750000, -21.000000, 11.146853 },
/* '+' */ { 160, 2, 173, 15, 1.500000, -17.000000, 16.727272 },
/* ',' */ { 178, 2, 181, 9, 2.250000, -3.000000, 7.958042 },
/* '-' */ { 186, 2, 194, 4, 0.750000, -8.750000, 9.538462 },
/* '.' */ { 198, 2, 201, 5, 2.500000, -3.000000, 7.958042 },
/* '/' */ { 206, 2, 214, 23, 0.000000, -21.000000, 7.958042 },
/* '0' */ { 218, 2, 231, 23, 1.000000, -20.750000, 15.930070 },
/* '1' */ { 236, 2, 243, 22, 3.000000, -20.750000, 15.930070 },
/* '2' */ { 2, 34, 15, 54, 0.750000, -20.750000, 15.930070 },
/* '3' */ { 20, 34, 33, 55, 1.000000, -20.750000, 15.930070 },
/* '4' */ { 38, 34, 52, 54, 0.250000, -20.750000, 15.930070 },
/* '5' */ { 58, 34, 72, 54, 1.000000, -20.250000, 15.930070 },
/* '6' */ { 76, 34, 89, 55, 1.000000, -20.750000, 15.930070 },
/* '7' */ { 94, 34, 107, 54, 1.250000, -20.250000, 15.930070 },
/* '8' */ { 112, 34, 125, 55, 1.000000, -20.750000, 15.930070 },
/* '9' */ { 130, 34, 143, 55, 1.000000, -20.750000, 15.930070 },
/* ':' */ { 148, 34, 151, 49, 2.500000, -15.000000, 7.958042 },
/* ';' */ { 156, 34, 159, 53, 2.250000, -15.000000, 7.958042 },
/* '<' */ { 164, 34, 177, 48, 1.500000, -17.250000, 16.727272 },
/* '=' */ { 182, 34, 195, 42, 1.500000, -14.500000, 16.727272 },
/* '>' */ { 200, 34, 213, 48, 1.500000, -17.250000, 16.727272 },
/* '?' */ { 218, 34, 231, 55, 1.250000, -21.000000, 15.930070 },
/* '@' */ { 2, 60, 28, 87, 1.500000, -21.000000, 29.076923 },
/* 'A' */ { 34, 60, 53, 80, -0.250000, -20.750000, 19.104895 },
/* 'B' */ { 58, 60, 73, 80, 2.000000, -20.750000, 19.104895 },
/* 'C' */ { 78, 60, 96, 81, 1.250000, -21.000000, 20.685314 },
/* 'D' */ { 102, 60, 119, 80, 2.000000, -20.750000, 20.685314 },
/* 'E' */ { 124, 60, 139, 80, 2.250000, -20.750000, 19.104895 },
/* 'F' */ { 144, 60, 158, 80, 2.250000, -20.750000, 17.496504 },
/* 'G' */ { 162, 60, 181, 81, 1.500000, -21.000000, 22.279720 },
/* 'H' */ { 186, 60, 202, 80, 2.250000, -20.750000, 20.685314 },
/* 'I' */ { 208, 60, 211, 80, 2.500000, -20.750000, 7.958042 },
/* 'J' */ { 216, 60, 227, 81, 0.750000, -20.750000, 14.321678 },
/* 'K' */ { 232, 60, 249, 80, 2.000000, -20.750000, 19.104895 },
/* 'L' */ { 2, 92, 15, 112, 2.000000, -20.750000, 15.930070 },
/* 'M' */ { 20, 92, 39, 112, 2.000000, -20.750000, 23.860140 },
/* 'N' */ { 44, 92, 60, 112, 2.000000, -20.750000, 20.685314 },
/* 'O' */ { 66, 92, 85, 113, 1.250000, -21.000000, 22.279720 },
/* 'P' */ { 90, 92, 106, 112, 2.000000, -20.750000, 19.104895 },
/* 'Q' */ { 110, 92, 130, 114, 1.000000, -21.000000, 22.279720 },
/* 'R' */ { 136, 92, 154, 112, 2.250000, -20.750000, 20.685314 },
/* 'S' */ { 160, 92, 176, 113, 1.250000, -21.000000, 19.104895 },
/* 'T' */ { 182, 92, 198, 112, 0.500000, -20.750000, 17.496504 },
/* 'U' */ { 204, 92, 220, 113, 2.250000, -20.750000, 20.685314 },
/* 'V' */ { 226, 92, 245, 112, 0.000000, -20.750000, 19.104895 },
/* 'W' */ { 2, 120, 28, 140, 0.250000, -20.750000, 27.034966 },
/* 'X' */ { 34, 120, 53, 140, 0.000000, -20.750000, 19.104895 },
/* 'Y' */ { 58, 120, 77, 140, 0.000000, -20.750000, 19.104895 },
/* 'Z' */ { 82, 120, 98, 140, 0.500000, -20.750000, 17.496504 },
/* '[' */ { 104, 120, 109, 146, 1.750000, -20.750000, 7.958042 },
/* '\' */ { 114, 120, 122, 141, 0.000000, -21.000000, 7.958042 },
/* ']' */ { 126, 120, 131, 146, 0.500000, -20.750000, 7.958042 },
/* '^' */ { 136, 120, 148, 131, 0.750000, -21.000000, 13.440559 },
/* '_' */ { 152, 120, 169, 122, -0.500000, 3.750000, 15.930070 },
/* '`' */ { 174, 120, 179, 124, 1.000000, -20.750000, 9.538462 },
/* 'a' */ { 184, 120, 197, 135, 1.000000, -15.250000, 15.930070 },
/* 'b' */ { 202, 120, 215, 141, 1.750000, -20.750000, 15.930070 },
/* 'c' */ { 220, 120, 233, 135, 1.000000, -15.250000, 14.321678 },
/* 'd' */ { 238, 120, 251, 141, 0.750000, -20.750000, 15.930070 },
/* 'e' */ { 2, 152, 15, 167, 1.000000, -15.250000, 15.930070 },
/* 'f' */ { 20, 152, 28, 173, 0.250000, -21.000000, 7.958042 },
/* 'g' */ { 34, 152, 47, 173, 0.750000, -15.250000, 15.930070 },
/* 'h' */ { 52, 152, 64, 172, 1.750000, -20.750000, 15.930070 },
/* 'i' */ { 70, 152, 72, 172, 1.750000, -20.750000, 6.363636 },
/* 'j' */ { 78, 152, 84, 179, -1.500000, -20.750000, 6.363636 },
/* 'k' */ { 88, 152, 100, 172, 1.750000, -20.750000, 14.321678 },
/* 'l' */ { 106, 152, 108, 172, 1.750000, -20.750000, 6.363636 },
/* 'm' */ { 114, 152, 134, 167, 1.750000, -15.250000, 23.860140 },
/* 'n' */ { 140, 152, 152, 167, 1.750000, -15.250000, 15.930070 },
/* 'o' */ { 158, 152, 172, 167, 0.750000, -15.250000, 15.930070 },
/* 'p' */ { 178, 152, 191, 173, 1.750000, -15.250000, 15.930070 },
/* 'q' */ { 196, 152, 209, 173, 1.000000, -15.250000, 15.930070 },
/* 'r' */ { 214, 152, 222, 167, 1.750000, -15.250000, 9.538462 },
/* 's' */ { 228, 152, 240, 167, 0.750000, -15.250000, 14.321678 },
/* 't' */ { 246, 152, 253, 172, 0.500000, -20.250000, 7.958042 },
/* 'u' */ { 2, 184, 14, 199, 1.750000, -15.000000, 15.930070 },
/* 'v' */ { 20, 184, 33, 199, 0.250000, -15.000000, 14.321678 },
/* 'w' */ { 38, 184, 58, 199, 0.000000, -15.000000, 20.685314 },
/* 'x' */ { 64, 184, 78, 199, 0.000000, -15.000000, 14.321678 },
/* 'y' */ { 84, 184, 98, 205, 0.250000, -15.000000, 14.321678 },
/* 'z' */ { 102, 184, 115, 199, 0.500000, -15.000000, 14.321678 },
/* '{' */ { 120, 184, 128, 211, 0.750000, -21.000000, 9.566434 },
/* '|' */ { 134, 184, 136, 211, 2.500000, -21.000000, 7.440559 },
/* '}' */ { 142, 184, 150, 211, 0.500000, -21.000000, 9.566434 },
/* '~' */ { 156, 184, 170, 188, 1.000000, -12.500000, 16.727272 },
/* '' */ { 176, 184, 190, 202, 3.500000, -18.000000, 21.482517 }
};

View file

@ -0,0 +1,149 @@
/*
* cmd.c
* doom
*
* Created by John Carmack on 4/14/09.
* Copyright 2009 id Software. All rights reserved.
*
*/
#include "../doomiphone.h"
typedef struct cmd_function_s {
struct cmd_function_s *next;
const char *name;
int hashid;
xcommand_t function;
} cmd_function_t;
#define MAX_STRING_TOKENS 16
#define MAX_STRING_CHARS 1024
int cmd_argc;
char *cmd_argv[ MAX_STRING_TOKENS ];
cmd_function_t *cmd_functions; // possible commands to execute
int Cmd_Argc( void ) {
return cmd_argc;
}
const char *Cmd_Argv( int arg ) {
if( arg >= cmd_argc ) {
return "";
}
return cmd_argv[ arg ];
}
void Cmd_TokenizeString( const char *text ) {
static char *stringCopy;
// clear the args from the last string
// This better not be called recursively...
if ( stringCopy ) {
free( stringCopy );
stringCopy = NULL;
}
cmd_argc = 0;
if( ! text ) {
return;
}
stringCopy = strdup( text );
char *strval = stringCopy;
while( 1 ) {
char *start = strsep( &strval," \t\r\n");
if ( !start ) {
break;
}
if ( start[0] != 0 ) {
cmd_argv[cmd_argc] = start;
if ( ++cmd_argc == MAX_STRING_TOKENS ) {
break;
}
}
}
}
void Cmd_ListCommands_f() {
for( cmd_function_t *cmd = cmd_functions ; cmd ; cmd = cmd->next ) {
Com_Printf( "%s\n", cmd->name );
}
}
void Cmd_AddCommand( const char *cmd_name, xcommand_t function ) {
cmd_function_t *cmd;
int hashid;
hashid = HashString( cmd_name );
// fail if the command already exists
for( cmd = cmd_functions ; cmd ; cmd = cmd->next ) {
if( hashid == cmd->hashid && !strcmp( cmd_name, cmd->name ) ) {
Com_Printf( "Cmd_AddCommand: \"%s\" already defined\n", cmd_name );
return;
}
}
cmd = malloc( sizeof( cmd_function_t ) );
cmd->name = cmd_name;
cmd->hashid = hashid;
cmd->function = function;
cmd->next = cmd_functions;
cmd_functions = cmd;
}
void Cmd_ExecuteString( const char *str ) {
int l = strlen( str );
if ( str[l-1] == '\n' ) {
char *stripped = alloca( l+1 );
strcpy( stripped, str );
str = stripped;
stripped[l-1] = 0;
}
Com_Printf( "%s\n", str );
Cmd_TokenizeString( str );
const char *arg0 = Cmd_Argv( 0 );
int hashid = HashString( arg0 );
// check commands first
for( cmd_function_t *cmd = cmd_functions ; cmd ; cmd = cmd->next ) {
if( hashid == cmd->hashid && !strcmp( arg0, cmd->name ) ) {
cmd->function();
return;
}
}
// then check cvars
cvar_t *cvar = Cvar_FindVar( arg0 );
if ( cvar ) {
Cvar_Set( arg0, Cmd_Argv( 1 ) );
return;
}
Com_Printf( "Unknown command: %s\n", arg0 );
}
// execute each line of the config file
void Cmd_ExecuteFile( const char *fullPathName ) {
Com_Printf( "Executing command file '%s'\n", fullPathName );
FILE *f = fopen( fullPathName, "rb" );
if ( !f ) {
Com_Printf( "Failed to open.\n" );
return;
}
char line[1024];
while( fgets( line, sizeof( line ), f ) ) {
Cmd_ExecuteString( line );
}
fclose( f );
}

View file

@ -0,0 +1,375 @@
/*
Copyright (C) 2004 Michael Liebscher
Copyright (C) 1997-2001 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General License for more details.
You should have received a copy of the GNU General License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../doomiphone.h"
cvar_t *cvar_vars;
/*
-----------------------------------------------------------------------------
Function: Cvar_FindVar -Return cvar;
Parameters: var_name -[in] Name of cvar to lookup.
Returns: NULL if cvar not found, otherwise returns the cvar.
Notes:
-----------------------------------------------------------------------------
*/
cvar_t *Cvar_FindVar( const char *var_name )
{
cvar_t *var;
int hashid;
hashid = HashString( var_name );
for( var = cvar_vars ; var ; var = var->next )
{
if( hashid == var->hashid && !strcasecmp( var_name, var->name ) )
{
return var;
}
}
return NULL;
}
/*
-----------------------------------------------------------------------------
Function: Cvar_VariableValue -Get value of cvar.
Parameters: var_name -[in] Name of cvar to get value.
Returns: 0 if not found, other the value of the cvar.
Notes:
-----------------------------------------------------------------------------
*/
float Cvar_VariableValue( const char *var_name )
{
cvar_t *var;
var = Cvar_FindVar( var_name );
if( ! var )
{
return 0;
}
return (float)atof( var->string );
}
/*
-----------------------------------------------------------------------------
Function: Cvar_VariableString -Get cvar variable as string.
Parameters: var_name -[in] Name of cvar to get value.
Returns: Blank string on error, otherwise value string.
Notes:
-----------------------------------------------------------------------------
*/
char *Cvar_VariableString( const char *var_name )
{
cvar_t *var;
var = Cvar_FindVar( var_name );
if( ! var )
{
return "";
}
return var->string;
}
/*
-----------------------------------------------------------------------------
Function: Cvar_CompleteVariable -Complete cvar string name.
Parameters: partial -[in] Partial name of string to look up.
Returns: NULL if partial string not found, otherwise the complete
string name.
Notes:
-----------------------------------------------------------------------------
*/
char *Cvar_CompleteVariable( const char *partial )
{
cvar_t *cvar;
size_t len;
len = strlen( partial );
if( ! len )
{
return NULL;
}
//
// Check partial match.
//
for( cvar = cvar_vars ; cvar ; cvar = cvar->next )
{
if( ! strncmp( partial, cvar->name, len ) )
{
return cvar->name;
}
}
return NULL;
}
/*
-----------------------------------------------------------------------------
Function: Cvar_Get -Get cvar structure.
Parameters:
var_name -[in] the name of the cvar variable.
var_value -[in] string value of the cvar variable.
flags -[in] see CVARFlags for more information.
Returns: NULL on error, otherwise valid pointer to cvar_t structure.
Notes:
If the variable already exists, the value will not be set and
the flags will be or'ed.
-----------------------------------------------------------------------------
*/
cvar_t *Cvar_Get( const char *var_name, const char *var_value, CVARFlags flags ) {
cvar_t *var;
var = Cvar_FindVar( var_name );
if( var ) {
var->flags |= flags;
return var;
}
if( ! var_value ) {
return NULL;
}
var = malloc( sizeof( *var ) );
var->name = strdup( var_name );
var->string = strdup( var_value );
var->defaultString = strdup( var_value );
var->hashid = HashString( var_name );
var->modified = true;
var->value = (float)atof( var->string );
// link the variable in
var->next = cvar_vars;
cvar_vars = var;
var->flags = flags;
return var;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
void Cvar_Set( const char *var_name, const char *value ) {
cvar_t *var;
var = Cvar_FindVar( var_name );
if( ! var ) {
Com_Printf( "Cvar '%s' doesn't exist\n", var_name );
return;
}
if( var->flags & CVAR_NOSET ) {
Com_Printf( "%s is write protected.\n", var_name );
return;
}
if( ! strcmp( value, var->string ) ) {
return; // not changed
}
var->modified = true;
free( var->string ); // free the old value string
var->string = strdup( value );
var->value = (float)atof( var->string );
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
void Cvar_SetValue( const char *var_name, float value )
{
char val[ 32 ];
if( value == (int)value )
{
snprintf( val, sizeof( val ), "%i", (int)value );
}
else
{
snprintf( val, sizeof( val ), "%f", value );
}
Cvar_Set( var_name, val );
}
/*
-----------------------------------------------------------------------------
Function: Cvar_Command -Handles variable inspection and changing from
the console.
Parameters: Nothing.
Returns: false if variable not found, otherwise true.
Notes:
-----------------------------------------------------------------------------
*/
boolean Cvar_Command( void )
{
cvar_t *v;
// check variables
v = Cvar_FindVar( Cmd_Argv( 0 ) );
if( ! v )
{
return false;
}
// perform a variable print or set
if( Cmd_Argc() == 1 )
{
Com_Printf( "\"%s\" is \"%s\"\n", v->name, v->string );
return true;
}
Cvar_Set( v->name, Cmd_Argv( 1 ) );
return true;
}
/*
-----------------------------------------------------------------------------
Function: Cvar_WriteVariables -Appends lines containing "set variable value"
for all variables with the archive flag set
to true.
Parameters:
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
void Cvar_WriteVariables( const char *path )
{
cvar_t *var;
char buffer[1024];
FILE *f;
f = fopen( path, "a" );
for( var = cvar_vars ; var ; var = var->next )
{
if( var->flags & CVAR_ARCHIVE )
{
snprintf( buffer, sizeof( buffer ), "set %s %s\n", var->name, var->string );
fprintf( f, "%s", buffer );
}
}
fclose( f );
}
/*
-----------------------------------------------------------------------------
Function: Cvar_List_f -Print all cvars to the console.
Parameters: Nothing.
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
void Cvar_List_f( void )
{
cvar_t *var;
int i;
i = 0;
for( var = cvar_vars ; var ; var = var->next, ++i )
{
if( var->flags & CVAR_ARCHIVE )
{
Com_Printf ("*");
}
else
{
Com_Printf (" ");
}
Com_Printf (" %s \"%s\"\n", var->name, var->string);
}
Com_Printf ("%i cvars\n", i);
}
void Cvar_Reset_f( void ) {
for( cvar_t *var = cvar_vars ; var ; var = var->next ) {
Cvar_Set( var->name, var->defaultString );
}
Cvar_List_f();
}

View file

@ -0,0 +1,145 @@
/*
Copyright (C) 2004 Michael Liebscher
Copyright (C) 1997-2001 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* cvar.h: Dynamic variable tracking.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
* Date: 2004
*
* Acknowledgement:
* This code was derived from Quake II, and was originally
* written by Id Software, Inc.
*
*/
/*
Notes:
Dynamic variable tracking.
cvar_t variables are used to hold scalar or string variables
that can be changed or displayed at the console or prog code
as well as accessed directly in C code.
The user can access cvars from the console in three ways:
r_draworder -prints the current value
r_draworder 0 -sets the current value to 0
set r_draworder 0 -as above, but creates the cvar if not present
Cvars are restricted from having the same names as commands to keep this
module from being ambiguous.
This module is implemented by cvar.c
*/
#ifndef __CVAR_H__
#define __CVAR_H__
#if 0
typedef enum _CVARType
{
CVAR_DEFAULT = BIT( 0 ), // Just create it with no flag value.
CVAR_BOOL = BIT( 0 ), // Set to cause it to be saved to vars.rc
CVAR_INT = BIT( 0 ), // Added to userinfo when changed.
CVAR_FLOAT = BIT( 0 ), // Added to serverinfo when changed.
CVAR_STRING = BIT( 0 ), // Don't allow change from console at all,
// but can be set from the command line.
CVAR_LATCH = BIT( 0 ), // Save changes until server restart.
} CVARType;
#endif
typedef enum _CVARFlags
{
CVAR_INIT = 0x0, // Just create it with no flag value.
CVAR_ARCHIVE = 0x1, // Set to cause it to be saved to the config file
CVAR_NOSET = 0x8, // Don't allow change from console at all,
// but can be set from the command line.
} CVARFlags;
// nothing outside the Cvar_*() functions should modify these fields!
typedef struct cvar_s {
// By putting the value first, cvars can be referenced in other code
// as just extern float *name, without having to include the cvar_t
// declaration. This is probably a bad idea that I will
// regret at some point.
float value;
char *name;
char *string;
char *defaultString;
int hashid;
int flags;
boolean modified; // set each time the cvar is changed
struct cvar_s *next;
} cvar_t;
extern cvar_t *cvar_vars;
void Cvar_List_f();
void Cvar_Reset_f();
extern cvar_t *Cvar_Get( const char *var_name, const char *value, CVARFlags flags );
// creates the variable if it doesn't exist, or returns the existing one
// if it exists, the value will not be changed, but flags will be ORed in
// that allows variables to be unarchived without needing bitflags
extern cvar_t *Cvar_FindVar( const char *var_name );
// returns NULL if it doesn't exist
extern void Cvar_Set( const char *var_name, const char *value );
// prints warning if it doesn't exist
extern void Cvar_SetValue( const char *var_name, float value );
// expands value to a string and calls Cvar_Set
extern float Cvar_VariableValue( const char *var_name );
// returns 0 if not defined or non numeric
extern char *Cvar_VariableString( const char *var_name );
// returns an empty string if not defined
extern char *Cvar_CompleteVariable( const char *partial );
// attempts to match a partial variable name for command line completion
// returns NULL if nothing fits
extern void Cvar_GetLatchedVars( void );
// any CVAR_LATCHED variables that have been set will now take effect
extern void Cvar_WriteVariables( const char *path );
// appends lines containing "set variable value" for all variables
// with the archive flag set to true.
extern void Cvar_Init( void );
extern char *Cvar_Userinfo( void );
// returns an info string containing all the CVAR_USERINFO cvars
extern char *Cvar_Serverinfo( void );
// returns an info string containing all the CVAR_SERVERINFO cvars
#endif /* __CVAR_H__ */

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>get-task-allow</key>
<false/>
</dict>
</plist>

View file

@ -0,0 +1,39 @@
/*
Copyright (C) 2009 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#import <UIKit/UIAccelerometer.h>
@class EAGLView;
@interface gameAppDelegate : NSObject <UIApplicationDelegate, UIAccelerometerDelegate> {
UIWindow *window;
EAGLView *glView;
int lastAccelUpdateMsec;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet EAGLView *glView;
- (void)restartAccelerometerIfNeeded;
@end

View file

@ -0,0 +1,234 @@
/*
Copyright (C) 2009 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import "doomAppDelegate.h"
#import "EAGLView.h"
#import <AudioToolbox/AudioServices.h>
#include "../doomiphone.h"
@interface UIApplication (Private)
- (void)setSystemVolumeHUDEnabled:(BOOL)enabled forAudioCategory:(NSString *)category;
- (void)setSystemVolumeHUDEnabled:(BOOL)enabled;
- (void)runFrame;
- (void)asyncTic;
@end
char iphoneDocDirectory[1024];
char iphoneAppDirectory[1024];
@implementation gameAppDelegate
@synthesize window;
@synthesize glView;
extern EAGLContext *context;
NSTimer *animationTimer;
touch_t sysTouches[MAX_TOUCHES];
touch_t gameTouches[MAX_TOUCHES];
pthread_mutex_t eventMutex; // used to sync between game and event threads
pthread_t gameThreadHandle;
volatile boolean startupCompleted;
void *GameThread( void *args ) {
if ( ![EAGLContext setCurrentContext:context]) {
printf( "Couldn't setCurrentContext for game thread\n" );
exit( 1 );
}
printf( "original game thread priority: %f\n", (float)[NSThread threadPriority] );
[NSThread setThreadPriority: 0.5];
printf( "new game thread priority: %f\n", (float)[NSThread threadPriority] );
iphoneStartup();
// make sure one frame has been run before setting
// startupCompleted, so we don't get one grey frame
iphoneFrame();
startupCompleted = TRUE; // OK to start touch / accel callbacks
while( 1 ) {
iphoneFrame();
}
}
- (void)asyncTic {
iphoneAsyncTic();
[ self restartAccelerometerIfNeeded];
}
- (void)runFrame {
iphoneFrame();
}
- (void)applicationDidFinishLaunching:(UIApplication *)application {
application.statusBarHidden = YES;
application.statusBarOrientation = UIInterfaceOrientationLandscapeLeft;
// get the documents directory, where we will write configs and save games
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
[documentsDirectory getCString: iphoneDocDirectory
maxLength: sizeof( iphoneDocDirectory ) - 1
encoding: NSASCIIStringEncoding ];
// get the app directory, where our data files live
// this gives something like:
// /var/mobile/Applications/71355F9F-6400-4267-B07D-E7980764F5A8/Applications
// when what we want is:
// /var/mobile/Applications/71355F9F-6400-4267-B07D-E7980764F5A8/doom.app
// so we get that in main() from argv[0]
#if 0
paths = NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSUserDomainMask, YES);
NSString *appDirectory = [paths objectAtIndex:0];
static char iphoneAppDirectoryFromAPI[1024];
[appDirectory getCString: iphoneAppDirectoryFromAPI
maxLength: sizeof( iphoneAppDirectoryFromAPI ) - 1
encoding: NSASCIIStringEncoding ];
#endif
// disable screen dimming
[UIApplication sharedApplication].idleTimerDisabled = YES;
// start the flow of accelerometer events
UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
accelerometer.delegate = self;
accelerometer.updateInterval = 0.01;
// use this mutex for coordinating touch handling between
// the run loop thread and the game thread
if ( pthread_mutex_init( &eventMutex, NULL ) == -1 ) {
perror( "pthread_mutex_init" );
}
// use this semaphore for signaling from the async cmd generation thread that
// the game / draw thread can wake up
// sem_init is unimplemented on iPhone
//if ( sem_init( &ticSemaphore, 0, 0 ) == -1 ) {
// perror( "sem_init" );
//}
ticSemaphore = sem_open( "ticSemaphore", O_CREAT, S_IRWXU, 0 );
if ( ticSemaphore == SEM_FAILED ) {
perror( "sem_open" );
}
// we want the main (event/async) thread to be as high a priority as possible
// so the game/render thread will be interrupted immediately.
// It looks like the default scheduling on iPhone is already what we want --
// the main thread is at 1.0, and new threads are at 0.5.
printf( "original event thread priority: %f\n", (float)[NSThread threadPriority] );
[NSThread setThreadPriority: 1.0];
printf( "new event thread priority: %f\n", (float)[NSThread threadPriority] );
#ifdef USE_GAME_THREAD
// the game thread will do the init and start running frames
pthread_create( &gameThreadHandle, NULL, GameThread, NULL );
while( !startupCompleted ) {
// pause until all startup is completed and the game is
// ready to receive accel and touch calls
usleep( 1000 );
}
// schedule the time for async command generation in network games
float interval = 1.0 / 30.0f;
[NSTimer scheduledTimerWithTimeInterval:interval
target:self
selector:@selector(asyncTic)
userInfo:nil repeats:YES];
#else
// do all the game startup work
iphoneStartup();
// schedule the time for frame updates
float interval = 1.0 / 30.0f;
// float interval = 1.0 / 5.0f; // a low framerate is useful for some timing tests
animationTimer = [NSTimer scheduledTimerWithTimeInterval:interval
target:self
selector:@selector(runFrame)
userInfo:nil repeats:YES];
// run one frame manually to avoid a grey view swap
[self runFrame];
#endif
}
- (void)applicationWillResignActive:(UIApplication *)application {
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
- (void)applicationWillTerminate:(UIApplication *)application {
iphoneShutdown();
}
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
Com_Printf( "applicationDidReceiveMemoryWarning\n" );
}
- (void)dealloc {
[window release];
[glView release];
[super dealloc];
}
- (void)restartAccelerometerIfNeeded {
// I have no idea why this seems to happen sometimes...
if ( SysIphoneMilliseconds() - lastAccelUpdateMsec > 1000 ) {
static int count;
if ( ++count < 100 ) {
printf( "Restarting accelerometer updates.\n" );
}
UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
accelerometer.delegate = self;
accelerometer.updateInterval = 0.01;
}
}
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
float acc[4];
acc[0] = acceleration.x;
acc[1] = acceleration.y;
acc[2] = acceleration.z;
acc[3] = acceleration.timestamp;
iphoneTiltEvent( acc );
lastAccelUpdateMsec = SysIphoneMilliseconds();
}
@end

View file

@ -0,0 +1,8 @@
//
// Prefix header for all source files of the 'doom' target in the 'doom' project
//
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View file

@ -0,0 +1,200 @@
/*
Copyright (C) 2009 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "doomiphone.h"
//int registration_sequence;
//#include "iphone_gl.h"
void GLCheckError(const char *message) {
GLint err = glGetError();
if ( err != GL_NO_ERROR ) {
printf( "GL ERROR %d from %s\n", err, message );
}
}
unsigned int QGLBeginStarted = 0;
struct Vertex {
float xyz[3];
float st[2];
#ifdef VERTEX_COLOR
GLubyte c[4];
#endif
};
#define MAX_VERTS 16384
typedef struct Vertex Vertex;
Vertex immediate[ MAX_VERTS ];
Vertex vab;
short quad_indexes[MAX_VERTS * 3 / 2 ];
int curr_vertex;
GLenum curr_prim;
void SetImmediateModeGLVertexArrays() {
glVertexPointer( 3, GL_FLOAT, sizeof( Vertex ), immediate[ 0 ].xyz );
glEnableClientState( GL_VERTEX_ARRAY );
glTexCoordPointer( 2, GL_FLOAT, sizeof( Vertex ), immediate[ 0 ].st );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
#ifdef VERTEX_COLOR
glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( Vertex ), immediate[ 0 ].c );
glEnableClientState( GL_COLOR_ARRAY );
#endif
}
void InitImmediateModeGL() {
for ( int i = 0; i < MAX_VERTS * 3 / 2; i+=6 ) {
int q = i / 6 * 4;
quad_indexes[ i + 0 ] = q + 0;
quad_indexes[ i + 1 ] = q + 1;
quad_indexes[ i + 2 ] = q + 2;
quad_indexes[ i + 3 ] = q + 0;
quad_indexes[ i + 4 ] = q + 2;
quad_indexes[ i + 5 ] = q + 3;
}
SetImmediateModeGLVertexArrays();
}
void glBegin( GLenum prim ) {
curr_vertex = 0;
curr_prim = prim;
}
void glVertex3f( GLfloat x, GLfloat y, GLfloat z ) {
assert( curr_vertex < MAX_VERTS );
vab.xyz[ 0 ] = x;
vab.xyz[ 1 ] = y;
vab.xyz[ 2 ] = z;
immediate[ curr_vertex ] = vab;
curr_vertex++;
}
void glVertex3fv( GLfloat *xyz ) {
assert( curr_vertex < MAX_VERTS );
vab.xyz[ 0 ] = xyz[0];
vab.xyz[ 1 ] = xyz[1];
vab.xyz[ 2 ] = xyz[2];
immediate[ curr_vertex ] = vab;
curr_vertex++;
}
void glVertex2f( GLfloat x, GLfloat y ) {
assert( curr_vertex < MAX_VERTS );
vab.xyz[ 0 ] = (float)x;
vab.xyz[ 1 ] = (float)y;
vab.xyz[ 2 ] = 0.0f;
immediate[ curr_vertex ] = vab;
curr_vertex++;
}
void glVertex2i( GLint x, GLint y ) {
assert( curr_vertex < MAX_VERTS );
vab.xyz[ 0 ] = (float)x;
vab.xyz[ 1 ] = (float)y;
vab.xyz[ 2 ] = 0.0f;
immediate[ curr_vertex ] = vab;
curr_vertex++;
}
#ifdef VERTEX_COLOR
void glColor4ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) {
vab.c[ 0 ] = r;
vab.c[ 1 ] = g;
vab.c[ 2 ] = b;
vab.c[ 3 ] = a;
}
void glColor4ubv( GLubyte *rgba ) {
vab.c[ 0 ] = rgba[0];
vab.c[ 1 ] = rgba[1];
vab.c[ 2 ] = rgba[2];
vab.c[ 3 ] = rgba[3];
}
void glColor4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) {
vab.c[ 0 ] = (GLubyte) ( r * 255 );
vab.c[ 1 ] = (GLubyte) ( g * 255 );
vab.c[ 2 ] = (GLubyte) ( b * 255 );
vab.c[ 3 ] = (GLubyte) ( a * 255 );
}
void glColor4fv( GLfloat *rgba ) {
vab.c[ 0 ] = (GLubyte) ( rgba[0] * 255 );
vab.c[ 1 ] = (GLubyte) ( rgba[1] * 255 );
vab.c[ 2 ] = (GLubyte) ( rgba[2] * 255 );
vab.c[ 3 ] = (GLubyte) ( rgba[3] * 255 );
}
void glColor3f( GLfloat r, GLfloat g, GLfloat b ) {
vab.c[ 0 ] = (GLubyte) ( r * 255 );
vab.c[ 1 ] = (GLubyte) ( g * 255 );
vab.c[ 2 ] = (GLubyte) ( b * 255 );
vab.c[ 3 ] = 255;
}
#endif
void glTexCoord2i( GLint s, GLint t ) {
vab.st[ 0 ] = (float)s;
vab.st[ 1 ] = (float)t;
}
void glTexCoord2f( GLfloat s, GLfloat t ) {
vab.st[ 0 ] = s;
vab.st[ 1 ] = t;
}
void glTexCoord2fv( GLfloat *st ) {
vab.st[ 0 ] = st[0];
vab.st[ 1 ] = st[1];
}
void glEnd() {
#if 0
glVertexPointer( 3, GL_FLOAT, sizeof( Vertex ), immediate[ 0 ].xyz );
glTexCoordPointer( 2, GL_FLOAT, sizeof( Vertex ), immediate[ 0 ].st );
glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( Vertex ), immediate[ 0 ].c );
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glEnableClientState( GL_COLOR_ARRAY );
#endif
if ( curr_prim == GL_QUADS ) {
glDrawElements( GL_TRIANGLES, curr_vertex / 4 * 6, GL_UNSIGNED_SHORT, quad_indexes );
} else {
glDrawArrays( curr_prim, 0, curr_vertex );
}
curr_vertex = 0;
curr_prim = 0;
}
void landscapeViewport( GLint x, GLint y, GLsizei width, GLsizei height ) {
y = 0; // !@#
if ( revLand->value ) {
glViewport( VID_HEIGHT - (y+height), x, height, width );
} else {
glViewport( y, x, height, width );
}
}
void landscapeScissor( GLint x, GLint y, GLsizei width, GLsizei height ) {
y = 0; // !@#
if ( revLand->value ) {
glScissor( VID_HEIGHT - (y+height), x, height, width );
} else {
glScissor( y, x, height, width );
}
}

View file

@ -0,0 +1,22 @@
#ifndef __GLES_GLUE_H__
#define __GLES_GLUE_H__
#define GL_QUADS 888
void GLCheckError( const char *message );
void glBegin( GLenum prim );
void glVertex3f( float x, float y, float z );
void glVertex2i( GLint x, GLint y );
void glColor4ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a );
void glColor4ubv( GLubyte *rgba );
void glColor3f( GLfloat r, GLfloat g, GLfloat b );
void glColor4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a );
void glColor4fv( GLfloat *rgba );
void glTexCoord2i( GLint s, GLint t );
void glTexCoord2f( GLfloat s, GLfloat t );
void glEnd();
#endif

View file

@ -0,0 +1,213 @@
/*
Copyright (C) 2009 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../doomiphone.h"
hud_t huds;
void HudDraw();
void HudWrite();
void HudRead();
ibutton_t *dragHud;
int dragX, dragY;
void SetHudPic( ibutton_t *hp, const char *image ) {
pkTexture_t *gl;
gl = PK_FindTexture( image );
assert( gl );
hp->texture = gl;
hp->touch = NULL; // in case one was down when it was saved
}
void SetHudSpot( ibutton_t *hp, int x, int y, int dw, int dh ) {
hp->touch = NULL; // in case one was down when it was saved
hp->x = x - dw/2;
hp->y = y - dh/2;
hp->drawWidth = dw;
hp->drawHeight = dh;
hp->buttonFlags = 0;
hp->scale = 1.0f;
}
void HudSetTexnums() {
SetHudPic( &huds.forwardStick, "iphone/up_down.tga" );
SetHudPic( &huds.sideStick, "iphone/side_2_side.tga" );
SetHudPic( &huds.turnStick, "iphone/directional_2.tga" );
SetHudPic( &huds.turnRotor, "iphone/rotate.tga" );
SetHudPic( &huds.fire, "iphone/fire.tga" );
SetHudPic( &huds.menu, "iphone/menu_button.tga" );
SetHudPic( &huds.map, "iphone/map_button.tga" );
SetHudSpot( &huds.weaponSelect, 240, 280, 40, 40 );
}
void HudSetForScheme( int schemeNum ) {
for ( ibutton_t *hud = (ibutton_t *)&huds ; hud != (ibutton_t *)(&huds+1) ; hud++ ) {
hud->buttonFlags = BF_IGNORE;
}
static const int STICK_SIZE = 128;
static const int HALF_STICK = 128/2;
static const int BOTTOM = 320 - 44; // above the status bar
SetHudSpot( &huds.weaponSelect, 240, 280, 40, 40 ); // the touch area is doubled
// don't process these in the update hud touch loop, because they will be
// handled with normal button calls
huds.menu.buttonFlags |= BF_HUDBUTTON;
huds.map.buttonFlags |= BF_HUDBUTTON;
static const int MID = 160; // BOTTOM-HALF_STICK;
// make the forward / back sticks touch taller than they draw
switch ( schemeNum ) {
default:
case 0: // turn stick
SetHudSpot( &huds.forwardStick, HALF_STICK, BOTTOM-HALF_STICK, STICK_SIZE, STICK_SIZE );
SetHudSpot( &huds.turnStick, HALF_STICK, BOTTOM-HALF_STICK, STICK_SIZE, STICK_SIZE );
SetHudSpot( &huds.fire, 480-40, BOTTOM-HALF_STICK, 80, 80 );
SetHudSpot( &huds.menu, 480-24, 24, 48, 48 );
SetHudSpot( &huds.map, 24, 24, 48, 48 );
break;
case 1: // dual stick
SetHudSpot( &huds.forwardStick, HALF_STICK, BOTTOM-HALF_STICK, STICK_SIZE, STICK_SIZE );
SetHudSpot( &huds.sideStick, HALF_STICK, BOTTOM-HALF_STICK, STICK_SIZE, STICK_SIZE );
SetHudSpot( &huds.turnStick, 480-HALF_STICK, BOTTOM-HALF_STICK, STICK_SIZE, STICK_SIZE );
SetHudSpot( &huds.fire, 480-40, 40, 80, 80 );
SetHudSpot( &huds.menu, 48+24, 24, 48, 48 );
SetHudSpot( &huds.map, 24, 24, 48, 48 );
break;
case 2: // rotor
SetHudSpot( &huds.forwardStick, HALF_STICK, BOTTOM-HALF_STICK, STICK_SIZE, STICK_SIZE );
SetHudSpot( &huds.sideStick, HALF_STICK, BOTTOM-HALF_STICK, STICK_SIZE, STICK_SIZE );
SetHudSpot( &huds.turnRotor, 480-HALF_STICK, BOTTOM-HALF_STICK, STICK_SIZE, STICK_SIZE );
SetHudSpot( &huds.fire, 480-40, 40, 80, 80 );
SetHudSpot( &huds.menu, 48+24, 24, 48, 48 );
SetHudSpot( &huds.map, 24, 24, 48, 48 );
break;
}
}
void SnapSticks( ibutton_t *test, const ibutton_t *to ) {
if ( abs( test->x - to->x ) < test->drawWidth && abs( test->y - to->y ) < test->drawHeight ) {
test->x = to->x;
test->y = to->y;
}
}
/*
==================
HudEditFrame
==================
*/
void HudEditFrame() {
color3_t gray = { 32, 32, 32 };
if ( numTouches == 0 && numPrevTouches == 1 && dragHud ) {
Sound_StartLocalSound( "iphone/baction_01.wav" );
dragHud = NULL;
}
if ( numTouches == 1 && numPrevTouches == 0 ) {
// identify the hud being touched for drag
int x = touches[0][0];
int y = touches[0][1];
dragHud = NULL;
for ( ibutton_t *hud = (ibutton_t *)&huds ; hud != (ibutton_t *)(&huds+1) ; hud++ ) {
if ( hud->buttonFlags & BF_IGNORE ) {
continue;
}
if ( x >= hud->x && x - hud->x < hud->drawWidth && y >= hud->y && y - hud->y < hud->drawHeight ) {
dragHud = hud;
dragX = dragHud->x - x;
dragY = dragHud->y - y;
Sound_StartLocalSound( "iphone/bdown_01.wav" );
break;
}
}
}
if ( numTouches == 1 && numPrevTouches == 1 && dragHud ) {
// adjust the position of the dragHud
dragHud->x = touches[0][0] + dragX;
dragHud->y = touches[0][1] + dragY;
if ( dragHud->x < 0 ) {
dragHud->x = 0;
}
if ( dragHud->x > 480 - dragHud->drawWidth ) {
dragHud->x = 480 - dragHud->drawWidth;
}
if ( dragHud->y < 0 ) {
dragHud->y = 0;
}
if ( dragHud->y > 320 - dragHud->drawHeight ) {
dragHud->y = 320 - dragHud->drawHeight;
}
// magnet pull a matchable axis
if ( dragHud == &huds.forwardStick ) {
SnapSticks( &huds.sideStick, dragHud );
SnapSticks( &huds.turnStick, dragHud );
}
if ( dragHud == &huds.sideStick ) {
SnapSticks( &huds.forwardStick, dragHud );
}
if ( dragHud == &huds.turnStick ) {
SnapSticks( &huds.forwardStick, dragHud );
}
}
// solid background color and some UI elements for context
R_Draw_Fill( 0, 0, 480, 320, gray );
glColor4f( 1, 1, 1, 1 );
iphoneCenterText( 240, 20, 0.75, "Drag the controls" );
// draw the status bar
extern patchnum_t stbarbg;
if ( statusBar->value ) {
// force doom to rebind, since we have changed the active GL_TEXTURE_2D
last_gltexture = NULL;
gld_DrawNumPatch(0, ST_Y, stbarbg.lumpnum, CR_DEFAULT, VPT_STRETCH);
}
// draw the active items at their current locations
for ( ibutton_t *hud = (ibutton_t *)&huds ; hud != (ibutton_t *)(&huds+1) ; hud++ ) {
if ( !hud->texture ) {
continue;
}
if ( hud->buttonFlags & BF_IGNORE ) {
continue;
}
PK_StretchTexture( hud->texture, hud->x, hud->y, hud->drawWidth, hud->drawHeight );
}
// draw the done button
static ibutton_t btnDone;
if ( !btnDone.texture ) {
// initial setup
SetButtonPicsAndSizes( &btnDone, "iphone/back_button.tga", "Done", 240 - 32, 160-32, 64, 64 );
}
if ( HandleButton( &btnDone ) ) {
menuState = IPM_CONTROLS;
}
}

View file

@ -0,0 +1,398 @@
/*
* ipak.c
* doom
*
* Created by John Carmack on 4/9/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include "../doomiphone.h"
pkHeader_t *pkHeader;
int pkSize;
// images and wavs have writable state, so they need separate
// structs that also point to the source in the pak file
pkTexture_t *pkTextures;
pkWav_t *pkWavs;
void PK_LoadTexture( pkTexture_t *image );
/*
==================
PK_Init
==================
*/
void PK_Init( const char *pakFileName ) {
printf( "PK_Init( %s )\n", pakFileName );
int fd = open( pakFileName, O_RDONLY );
if ( fd == -1 ) {
printf( "Couldn't open file\n" );
assert( 0 );
}
struct stat s;
fstat( fd, &s );
pkSize = s.st_size;
pkHeader = mmap( NULL, pkSize, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0 );
// mmap keeps the file internally, we can close our descriptor
close( fd );
if ( (int)pkHeader == -1 ) {
printf( "mmap failed: %s\n", strerror( errno ) );
assert( 0 );
}
if ( pkHeader->version != PKFILE_VERSION ) {
printf( "bad pak file version: 0x%x != 0x%x\n", pkHeader->version, PKFILE_VERSION );
assert( 0 );
}
// build the local image table
pkTextures = malloc( sizeof( pkTextures[0] ) * pkHeader->textures.count );
memset( pkTextures, 0, sizeof( pkTextures[0] ) * pkHeader->textures.count );
for ( int i = 0 ; i < pkHeader->textures.count ; i++ ) {
pkTextures[i].textureData = (pkTextureData_t *)( (byte *)pkHeader + pkHeader->textures.tableOfs + i * pkHeader->textures.structSize );
}
// build the local wav table
int startLoadingWavs = SysIphoneMicroseconds();
pkWavs = malloc( sizeof( pkWavs[0] ) * pkHeader->wavs.count );
memset( pkWavs, 0, sizeof( pkWavs[0] ) * pkHeader->wavs.count );
for ( int i = 0 ; i < pkHeader->wavs.count ; i++ ) {
pkWav_t *sfx = &pkWavs[i];
sfx->wavData = (pkWavData_t *)( (byte *)pkHeader + pkHeader->wavs.tableOfs + i * pkHeader->wavs.structSize );
// there is no harm in setting the OpenAl static buffer up for everything now
alGenBuffers( 1, &sfx->alBufferNum );
int alFormat;
if ( sfx->wavData->wavChannels == 1 ) {
if ( sfx->wavData->wavChannelBytes == 1 ) {
alFormat = AL_FORMAT_MONO8;
} else {
alFormat = AL_FORMAT_MONO16;
}
} else {
if ( sfx->wavData->wavChannelBytes == 1 ) {
alFormat = AL_FORMAT_STEREO8;
} else {
alFormat = AL_FORMAT_STEREO16;
}
}
#if 0
alBufferData( sfx->alBufferNum, alFormat, (byte *)pkHeader + sfx->wavData->wavDataOfs
, sfx->wavData->wavChannels*sfx->wavData->wavChannelBytes*sfx->wavData->wavNumSamples
, sfx->wavData->wavRate );
#else
// This should just store out a pointer, so the data won't get touched until it is actually
// used to play a sound.
extern void alBufferDataStatic(const ALint bid, ALenum format, ALvoid* data, ALsizei size, ALsizei freq);
alBufferDataStatic( sfx->alBufferNum, alFormat, (byte *)pkHeader + sfx->wavData->wavDataOfs
, sfx->wavData->wavChannels*sfx->wavData->wavChannelBytes*sfx->wavData->wavNumSamples
, sfx->wavData->wavRate );
#endif
}
int endLoadingWavs = SysIphoneMicroseconds();
printf( "%i usec to load wavs\n", endLoadingWavs - startLoadingWavs );
printf( "Mapped %i bytes of %s at 0x%p\n", pkSize, pakFileName, pkHeader );
printf( "%4i textures\n", pkHeader->textures.count );
printf( "%4i wavs\n", pkHeader->wavs.count );
printf( "%4i raws\n", pkHeader->raws.count );
#if 0
// testing
for ( int j = 0 ; j < 4 ; j++ ) {
int startTime = Sys_Microseconds();
int sum = 0;
for ( int i = 0 ; i < pkSize ; i+=16 ) {
sum += ((byte *)pkHeader)[i];
}
int endTime = Sys_Microseconds();
printf( "%5.1f mb/s page-in speed (%i)\n", (float)pkSize / (endTime - startTime ), endTime - startTime );
}
for ( int i = 0 ; i < pkHeader->numTextures ; i++ ) {
printf( "-------------------------\n" );
for ( int j = 0 ; j < 8 ; j++ ) {
pkTexture_t *tex = &pkTextures[i];
int start = Sys_Microseconds();
PK_LoadTexture( tex );
int middle = Sys_Microseconds();
PK_StretchTexture( tex, 0, 0, 0, 0 );
int middle2 = Sys_Microseconds();
PK_StretchTexture( tex, 0, 0, 0, 0 );
int end = Sys_Microseconds();
printf( "%i usec load, %i usec first draw, %i usec second draw\n",
middle - start, middle2 - middle, end - middle2 );
glDeleteTextures( 1, &tex->glTexNum );
tex->glTexNum = 0;
}
}
#endif
}
/*
==================
PK_LoadTexture
==================
*/
void PK_LoadTexture( pkTexture_t *tex ) {
int startTime = SysIphoneMicroseconds();
const pkTextureData_t *imd = tex->textureData;
glGenTextures( 1, &tex->glTexNum );
glBindTexture( GL_TEXTURE_2D, tex->glTexNum );
// load the image directly from the mapped file
typedef struct {
int internalFormat;
int externalFormat;
int type;
int bpp;
} formatInfo_t;
static formatInfo_t formatInfo[9] = {
{ GL_RGB , GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 16 },
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 16 },
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 16 },
{ GL_RGBA, GL_BGRA, GL_UNSIGNED_BYTE, 32 },
{ GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 16 },
{ GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, 0, 0, 4 },
{ GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, 0, 0, 4 },
{ GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, 0, 0, 2 },
{ GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, 0, 0, 2 },
};
assert( imd->format < 9 );
formatInfo_t *fi = &formatInfo[imd->format];
unsigned char *s = (byte *)pkHeader + imd->picDataOfs;
int w = imd->uploadWidth;
int h = imd->uploadHeight;
// upload each mip level
int l = 0;
int totalSize = 0;
while( 1 ) {
int size = (w*h*fi->bpp)/8;
if ( fi->type == 0 ) {
if ( size < 32 ) {
// minimum PVRTC size
size = 32;
}
glCompressedTexImage2D( GL_TEXTURE_2D, l, fi->internalFormat, w, h, 0,
size, s );
} else {
glTexImage2D( GL_TEXTURE_2D, l, fi->internalFormat, w, h, 0,
fi->externalFormat, fi->type, s );
}
GLCheckError( "texture upload" );
totalSize += size;
if ( ++l == imd->numLevels ) {
break;
}
if ( w == 1 && h == 1 ) {
break;
}
s += size;
w >>= 1;
if ( w == 0 ) {
w = 1;
}
h >>= 1;
if ( h == 0 ) {
h = 1;
}
}
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, imd->minFilter );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, imd->magFilter );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, imd->wrapS );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, imd->wrapT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0f );
int endTime = SysIphoneMicroseconds();
printf( "%5.1f mb/s TexImage for %s\n", (float)totalSize /
( endTime - startTime ), imd->name.name );
}
/*
==================
PK_FindTexture
Fully creates the gl texture before returning.
==================
*/
pkTexture_t *PK_FindTexture( const char *imageName ) {
int index;
pkTexture_t *texData = (pkTexture_t *)PK_FindType( imageName, &pkHeader->textures, &index );
if ( !texData ) {
return NULL;
}
pkTexture_t *tex = pkTextures + index;
if ( tex->glTexNum == 0 ) {
PK_LoadTexture( tex );
}
return tex;
}
/*
==================
PK_FindWav
==================
*/
pkWav_t *PK_FindWav( const char *soundName ) {
int index;
pkWavData_t *wavData = (pkWavData_t *)PK_FindType( soundName, &pkHeader->wavs, &index );
if ( !wavData ) {
return NULL;
}
pkWav_t *wav = pkWavs + index;
// create the OpenAL buffer
return wav;
}
/*
==================
PK_FindRaw
==================
*/
const byte *PK_FindRaw( const char *rawName, int *len ) {
pkRawData_t *raw = (pkRawData_t *)PK_FindType( rawName, &pkHeader->raws, NULL );
if ( !raw ) {
if ( len ) {
*len = -1;
}
return NULL;
}
if ( len ) {
*len = raw->rawDataLen;
}
return (byte *)pkHeader + raw->rawDataOfs;
}
/*
==================
PK_HashName
==================
*/
int PK_HashName( const char *name, char canonical[MAX_PK_NAME] ) {
int o = 0;
int hash = 0;
do {
int c = name[o];
if ( c == 0 ) {
break;
}
// backslashes to forward slashes
if ( c == '\\' ) {
c = '/';
}
// to lowercase
c = tolower( c );
canonical[o++] = c;
hash = (hash << 5) - hash + c;
} while ( o < MAX_PK_NAME-1 );
canonical[o] = 0;
return hash;
}
/*
==================
PK_FindType
==================
*/
const pkName_t *PK_FindType( const char *rawName, const pkType_t *type, int *indexOutput ) {
char canonicalName[MAX_PK_NAME];
int hash = PK_HashName( rawName, canonicalName );
int hashChain = hash & (PK_HASH_CHAINS-1);
int index = type->hashChains[hashChain];
while ( index != -1 ) {
assert( index >= 0 && index < type->count );
const pkName_t *name = (pkName_t *)((byte *)pkHeader + type->tableOfs + index * type->structSize );
if ( name->nameHash == hash && !strcmp( canonicalName, name->name ) ) {
// this is it
if ( indexOutput ) {
*indexOutput = index;
}
return name;
}
index = name->nextOnHashChain;
}
// not found
if ( indexOutput ) {
*indexOutput = -1;
}
return NULL;
}
/*
==================
PK_BindTexture
==================
*/
void PK_BindTexture( pkTexture_t *tex ) {
assert( tex->glTexNum );
glBindTexture( GL_TEXTURE_2D, tex->glTexNum );
}
/*
==================
PK_DrawTexture
==================
*/
void PK_DrawTexture( pkTexture_t *tex, int x, int y ) {
PK_BindTexture( tex );
int w = tex->textureData->srcWidth;
int h = tex->textureData->srcHeight;
glBegin( GL_QUADS );
glTexCoord2f( 0.0f, 0.0f ); glVertex2i( x, y );
glTexCoord2f( tex->textureData->maxS, 0.0f ); glVertex2i( x+w, y );
glTexCoord2f( tex->textureData->maxS, tex->textureData->maxT ); glVertex2i( x+w, y+h );
glTexCoord2f( 0.0f, tex->textureData->maxT ); glVertex2i( x, y+h );
glEnd();
}
void PK_StretchTexture( pkTexture_t *tex, float x, float y, float w, float h ) {
PK_BindTexture( tex );
glBegin( GL_QUADS );
glTexCoord2f( 0.0f, 0.0f ); glVertex2i( x, y );
glTexCoord2f( tex->textureData->maxS, 0.0f ); glVertex2i( x+w, y );
glTexCoord2f( tex->textureData->maxS, tex->textureData->maxT ); glVertex2i( x+w, y+h );
glTexCoord2f( 0.0f, tex->textureData->maxT ); glVertex2i( x, y+h );
glEnd();
}

View file

@ -0,0 +1,160 @@
/*
* ipak.h
* General purpose data file management intended to be used
* as a read-only memory mapped file to play nice with iPhone OS's
* non-swapping and variable memory management.
*
* Created by John Carmack on 4/9/09.
* Copyright 2009 id Software. All rights reserved.
*
*/
//============================================================
//
// In-file structures
//
// These stuctures are in the mapped data file, and shared
// between the app and utility.
//
// Type headers are stored separately from the bulk data to minimize the
// number of active pages.
//
// The full hash of the name is stored in nameHash, and nameHash&(PK_HASH_BUCKETS-1) is
// used to chain structures of a particular type together.
//
//============================================================
#define MAX_PK_NAME 64
typedef struct {
int nameHash; // PK_HashName( name )
int nextOnHashChain; // -1 = end of chain
char name[MAX_PK_NAME]; // in canonical form: backslashes to slashes and lowercase
} pkName_t;
#define PK_HASH_CHAINS 256
typedef struct {
int tableOfs; // // &firstStruct = (byte *)dfHeader + tableOfs
int count;
int structSize; // sizeof( pkWavData_t ), etc
int hashChains[PK_HASH_CHAINS]; // -1 = end of chain
} pkType_t;
// dfWavData holds everything necessary to fully create an OpenAL sample buffer
typedef struct {
pkName_t name;
int wavDataOfs;
int wavChannels; // 1 or 2
int wavChannelBytes; // 1 or 2
int wavRate; // 22050, etc
int wavNumSamples; // each sample holds all the channels
// we may want looping information here later
} pkWavData_t;
// iPhone does not natively support palettized textures, but we
// might conceivably want to support luminance and intensity textures
// in the future.
typedef enum {
TF_565,
TF_5551,
TF_4444,
TF_8888,
TF_LA,
TF_PVR4,
TF_PVR4A,
TF_PVR2,
TF_PVR2A,
} textureFormat_t;
// dfImageData_t holds everything necessary to fully create an OpenGL texture object
typedef struct {
pkName_t name;
int picDataOfs; // the raw bits to pass to gl, mipmaps appended
// for PVR formats, the minimum size of each level is 32 bytes
int format;
int uploadWidth;
int uploadHeight;
int numLevels; // 1 for non mipmapped, otherwise log2( largest dimension )
// glTexParameters
int wrapS;
int wrapT;
int minFilter;
int magFilter;
int aniso;
// The upload sizes can be larger than the source sizes for
// non power of two sources, or for non square sources in the
// case of PVR compression.
int srcWidth;
int srcHeight;
float maxS; // srcWidth / uploadWidth
float maxT;
// Track the outlines of up to two boxes of non-transparent pixels
// to allow optimized drawing of sprites with large empty areas.
// The reason for two boxes is that the common lights have something
// at the top and something at the bottom, with nothing inbetween.
// These are inclusive bounds of the rows / columns in
// uploadWidth / uploadHeight with non-0 alpha
int numBounds;
int bounds[2][2][2];
} pkTextureData_t;
typedef struct {
pkName_t name;
int rawDataOfs; // (byte *)pkHeader + dataOfs
int rawDataLen; // there will always be a 0 byte appended to terminate strings
// that is not counted in this length
} pkRawData_t;
#define PKFILE_VERSION 0x12340002
typedef struct {
int version;
pkType_t textures;
pkType_t wavs;
pkType_t raws;
} pkHeader_t;
//============================================================
//
// In-memory, writable structures
//
//============================================================
typedef struct {
unsigned glTexNum;
const pkTextureData_t *textureData;
// we will need to add LRU links if texture caching is needed
} pkTexture_t;
typedef struct {
unsigned alBufferNum; // created with the staticBuffer extension directly in the mapped memory
const pkWavData_t *wavData;
} pkWav_t;
void PK_Init( const char *pakFileName );
const pkName_t *PK_FindType( const char *rawName, const pkType_t *type, int *index );
const byte * PK_FindRaw( const char *rawName, int *len ); // len can be NULL if you don't need it
pkTexture_t * PK_FindTexture( const char *imageName );
pkWav_t * PK_FindWav( const char *soundName );
// The name will be converted to canonical name (backslashes converted to slashes and lowercase)
// before generating a hash.
int PK_HashName( const char *name, char canonical[MAX_PK_NAME] );
void PK_BindTexture( pkTexture_t *tex );
void PK_DrawTexture( pkTexture_t *tex, int x, int y );
void PK_StretchTexture( pkTexture_t *tex, float x, float y, float w, float h );
extern pkHeader_t * pkHeader;
extern int pkSize;
// images and wavs have writable state, so they need separate
// structs that also point to the source in the pak file
extern pkTexture_t *pkTextures;
extern pkWav_t * pkWavs;

View file

@ -0,0 +1,973 @@
/*
* iphone_async.c
* doom
*
* Created by John Carmack on 7/2/09.
* Copyright 2009 id Software. All rights reserved.
*
*/
#include "../doomiphone.h"
typedef struct {
int msecFromLast;
int msecToExecute;
int sent;
int received;
int latency;
} asyncStats_t;
#define MAX_ASYNC_LOGS 256
static asyncStats_t asyncStats[MAX_ASYNC_LOGS];
int asyncTicNum;
// we save this for the packet acknowledge, and also for debugging
static packetServer_t lastServerPacket;
/*
==================
ShowNet
Graph packet receives and transmits
==================
*/
void ShowNet() {
if ( !showNet->value ) {
return;
}
color4_t red = { 255, 0, 0, 255 };
color4_t green = { 0, 255, 0, 255 };
color4_t blue = { 0, 0, 255, 255 };
int now = asyncTicNum; // latch it in case it changes
for ( int i = 1 ; i < 30 ; i++ ) {
asyncStats_t *lt = &asyncStats[(now - i ) & (MAX_ASYNC_LOGS-1)];
R_Draw_Fill( 0, i * 4, lt->sent * 10, 2, red );
R_Draw_Fill( 100, i * 4, lt->received * 10, 2, green );
R_Draw_Fill( 200, i * 4, lt->latency * 10, 2, blue );
}
}
void ShowMiniNet() {
if ( !miniNet->value ) {
return;
}
color4_t red = { 255, 0, 0, 255 };
color4_t green = { 0, 255, 0, 255 };
color4_t blue = { 0, 0, 255, 255 };
int now = asyncTicNum; // latch it in case it changes
now--;
int x = huds.menu.x;
int y = huds.menu.y;
for ( int i = 0 ; i < 10 ; i++ ) {
asyncStats_t *lt = &asyncStats[(now - i ) & (MAX_ASYNC_LOGS-1)];
R_Draw_Fill( x, y+i * 4, lt->sent * 4, 2, red );
R_Draw_Fill( x+20, y+i * 4, lt->received * 4, 2, green );
R_Draw_Fill( x+40, y+i * 4, lt->latency * 4, 2, blue );
}
}
/*
==================
UpdatePeerTiming
Calculates one way latency based on local and remote times
==================
*/
void UpdatePeerTiming( netPeer_t *peer, int remoteMilliseconds ) {
peer->lastPacketAsyncTic == asyncTicNum;
peer->lastPacketTime = SysIphoneMilliseconds();
peer->lastTimeDelta = abs( remoteMilliseconds - peer->lastPacketTime );
if ( peer->lowestTimeDelta == 0 || peer->lastTimeDelta < peer->lowestTimeDelta ) {
peer->lowestTimeDelta = peer->lastTimeDelta;
}
peer->oneWayLatency = peer->lastTimeDelta - peer->lowestTimeDelta;
if ( peer->oneWayLatency < 0 ) {
// this can happen if we context switched at a bad time
peer->lowestTimeDelta = peer->lastTimeDelta;
peer->oneWayLatency = 0;
}
// printf( "OWL:%i timeDelta:%i lowest:%i\n", peer->oneWayLatency,
// peer->lastTimeDelta, peer->lowestTimeDelta );
}
/*
==================
iphoneProcessPacket
A packet has been received over WiFi or bluetooth
==================
*/
void iphoneProcessPacket( const struct sockaddr *from, const void *data, int len ) {
if ( len < 4 ) {
printf( "discarding packet because len = %i.\n", len );
return;
}
int packetID = *(int *)data;
if ( !netgame ) {
// setup and join are only processed while in the menu system
if ( packetID == PACKET_VERSION_SETUP ) {
if ( localGameID == setupPacket.gameID ) {
// if we are sending packets, always ignore other setup packets
printf( "discarding setup packet because we are the server\n" );
return;
}
setupPacketFrameNum = iphoneFrameNum;
// save this packet
// printf( "valid setup packet\n" );
setupPacket = *(packetSetup_t *)data;
return;
}
if ( packetID == PACKET_VERSION_JOIN ) {
// we should only process join packets if we are in the multiplayer
// menu and running the current game
if ( menuState != IPM_MULTIPLAYER ) {
printf( "discarding join packet because not in IPM_MULTIPLAYER\n" );
return;
}
if ( setupPacket.gameID != localGameID ) {
printf( "discarding join packet because we aren't the server\n" );
return;
}
packetJoin_t *pj = (packetJoin_t *)data;
if ( pj->playerID == 0 ) {
// should never happen
printf( "discarding join packet because playerID is 0\n" );
return;
}
// add this player
int i;
for ( i = 0 ; i < MAXPLAYERS ; i++ ) {
if ( setupPacket.playerID[i] == pj->playerID ) {
netPlayers[i].peer.lastPacketTime = SysIphoneMilliseconds();
break;
}
}
if ( i == MAXPLAYERS ) {
// not in yet, add if possible
for ( i = 0 ; i < MAXPLAYERS ; i++ ) {
if ( setupPacket.playerID[i] == 0 ) {
setupPacket.playerID[i] = pj->playerID;
netPlayers[i].peer.address = *from;
netPlayers[i].peer.lastPacketTime = SysIphoneMilliseconds();
break;
}
}
// if all players are active, the new join gets ignored
}
// printf( "valid join packet\n" );
return;
}
// no other packets are processed unless we are in the game
printf( "discarding packet with id 0x%x when not in netgame\n", packetID );
return;
}
// the following are only for running games
if ( consoleplayer == 0 ) {
// we are the server, and should only receive packetClient_t
if ( packetID != PACKET_VERSION_CLIENT ) {
static boolean typeErrorPrinted;
if ( !typeErrorPrinted ) {
typeErrorPrinted = true;
printf( "Packet received with type 0x%x instead of 0x%x\n", packetID, PACKET_VERSION_CLIENT );
}
return;
}
packetClient_t *pc = (packetClient_t *)data;
if ( len != sizeof( *pc ) ) {
// this should always be an exact length match
return;
}
if ( pc->gameID != gameID ) {
static boolean gameErrorPrinted;
if ( !gameErrorPrinted ) {
gameErrorPrinted = true;
printf( "Packet received with gameID 0x%x instead of 0x%x\n", pc->gameID, gameID );
}
return;
}
assert( pc->consoleplayer > 0 && pc->consoleplayer < MAXPLAYERS );
netPlayer_t *np = &netPlayers[pc->consoleplayer];
if ( np->pc.packetSequence >= pc->packetSequence ) {
printf( "Out of order or duplicated packet from player %i\n", pc->consoleplayer );
return;
}
np->peer.currentPingTics = packetSequence - pc->packetAcknowledge;
if ( np->pc.packetSequence != pc->packetSequence - 1 ) {
printf( "Dropped %i packets from player %i\n", pc->packetSequence - 1 - np->pc.packetSequence,
pc->consoleplayer );
}
// good packet from client
np->pc = *pc;
UpdatePeerTiming( &np->peer, np->pc.milliseconds );
} else {
// we are a client, and should only receive server packets
if ( packetID != PACKET_VERSION_SERVER ) {
static boolean typeErrorPrinted;
if ( !typeErrorPrinted ) {
typeErrorPrinted = true;
printf( "Packet received with type 0x%x instead of 0x%x\n", packetID, PACKET_VERSION_CLIENT );
}
return;
}
packetServer_t *ps = (packetServer_t *)data;
if ( len > sizeof( *ps ) ) {
// packets will usually have less ticcmd_t, but never more
return;
}
if ( ps->gameID != gameID ) {
static boolean gameErrorPrinted;
if ( !gameErrorPrinted ) {
gameErrorPrinted = true;
printf( "Packet received with gameID 0x%x instead of 0x%x\n", ps->gameID, gameID );
}
return;
}
if ( ps->packetSequence <= lastServerPacket.packetSequence ) {
printf( "Out of order or duplicated packet from server: %i <= %i\n",
ps->packetSequence , lastServerPacket.packetSequence );
return;
}
int drop = ps->packetSequence - (lastServerPacket.packetSequence + 1);
if ( drop > 0 ) {
printf( "Dropped %i packets from server\n", drop );
}
// good packet from server
memcpy( &lastServerPacket, ps, len );
UpdatePeerTiming( &netServer, ps->milliseconds );
netServer.currentPingTics = packetSequence - ps->packetAcknowledge;
// It is possible to have a client run a tic that hasn't been run yet on the game
// server, since the server can be generating cmds and sending packets while
// its game frame is hitched for an image load, so this is not an error condition.
// assert( ps->gametic >= gametic );
// this should never happen
assert( ps->maketic >= maketic );
// if a ticcmd_t that we need has permanently rolled off the end, we are hosed.
// This shouldn't happen, since we don't create commands if all the clients
// haven't processed most of the ones already sent.
if ( ps->maketic - gametic >= BACKUPTICS ) {
printf( "BACKUPTICS exceeded: ps->maketic %i, gametic %i\n",
ps->maketic, gametic );
netGameFailure = NF_INTERRUPTED;
}
// move over the new commands
// it is possible that some early frames of these are redundant, due
// to packets crossing in flight.
ticcmd_t *cmd_p = ps->netcmds;
for ( int i = ps->starttic ; i < ps->maketic ; i++ ) {
for ( int j = 0 ; j < MAXPLAYERS ; j++ ) {
if ( playeringame[j] ) {
netcmds[j][i&BACKUPTICMASK] = *cmd_p++;
}
}
}
// copy this after the cmds have been updated
maketic = ps->maketic;
// check consistancy for all in-game players on the most
// recent gametic that the server knew this client had run
int checkTic = ps->consistancyTic;
assert( checkTic > gametic - BACKUPTICS ); // if older than this, we have lost the data
checkTic &= BACKUPTICMASK;
for ( int i = 0 ; i < MAXPLAYERS ; i++ ) {
if ( playeringame[i] ) {
if ( ps->consistancy[i] != consistancy[i][checkTic] ) {
printf( "ConsistancyFailure for player %i on consistancyTic %i\n",
i, ps->consistancyTic );
netGameFailure = NF_CONSISTANCY;
}
}
}
}
}
/*
==================
SendSetupPacketIfNecessary
the server sends out a setup packet to each joined client so they
can see the game options needed to start the game.
==================
*/
void SendSetupPacketIfNecessary() {
if ( setupPacket.gameID != localGameID ) {
// we aren't the server
return;
}
if ( gametic >= 2 ) {
// everyone has already started, so they don't need more setup packets
return;
}
setupPacket.sendCount++;
// player 0 is always the server, no need to send to ourselves
for ( int i = 1 ; i < MAXPLAYERS ; i++ ) {
if ( setupPacket.playerID[i] == 0 ) {
continue;
}
int r = sendto( gameSocket, &setupPacket, sizeof( setupPacket ), 0,
&netPlayers[i].peer.address, sizeof( netPlayers[i].peer.address ) );
if ( r == -1 ) {
Com_Printf( "UDP sendTo failed: %s\n", strerror( errno ) );
close( gameSocket );
gameSocket = -1;
}
}
}
/*
==================
DeadBandAdjust
Compresses the 0.0 - 1.0 range into deadband - 1.0
==================
*/
float DeadBandAdjust( float f, float deadBand ) {
if ( f < 0 ) {
return -DeadBandAdjust( -f, deadBand );
}
if ( f > 1.0 ) {
return 1.0;
}
if ( f < deadBand ) {
return 0;
}
return (f-deadBand) / (1.0 - deadBand);
}
/*
==================
AxisHit
Returns a -1 to 1 range
If activeFraction is less than 1.0, the range will clamp
to the limits before the edge of the box is hit.
==================
*/
float AxisHit( ibutton_t *hud ) {
// will be set true if -1 or 1
hud->drawAsLimit = false;
if ( hud->buttonFlags & BF_IGNORE ) {
return 0;
}
touch_t *t = hud->touch;
if ( !t ) {
return 0;
}
int centerX, centerY;
if ( centerSticks->value ) {
// center on each touch
centerX = hud->downX;
centerY = hud->downY;
} else {
centerX = hud->x + hud->drawWidth / 2;
centerY = hud->y + hud->drawHeight / 2;
}
float w = hud->drawWidth * 0.5 * hud->scale;
float h = hud->drawHeight * 0.5 * hud->scale;
int x = t->x - centerX;
int y = t->y - centerY;
float f;
int isXaxis = ( hud != &huds.forwardStick );
if ( isXaxis ) {
f = (float)x / w;
} else {
f = (float)y / h;
}
float deadBand = stickDeadBand->value;
if ( hud == &huds.turnStick ) {
deadBand = 0;
}
if ( f > deadBand ) {
f -= deadBand;
} else if ( f < -deadBand ) {
f += deadBand;
} else {
// inside the deadband
return 0;
}
// adjust so you can hit the limit even if the control is drawn at the very edge
// of the screen
f /= (0.95-deadBand);
if ( f > 1.0f ) {
f = 1.0f;
hud->drawAsLimit = true;
} else if ( f < -1.0f ) {
f = -1.0f;
hud->drawAsLimit = true;
}
if ( hud == &huds.turnStick && rampTurn->value ) {
// do "gamma corrected" movement, so changes are always proportional
if ( f > 0 ) {
f = 0.01 * pow( 1.047, f * 100 );
} else {
f = -0.01 * pow( 1.047, f * -100 );
}
}
return f;
}
static const float NOT_TOUCHED_STATE = 99999.0f;
float RotorControl( ibutton_t *hud ) {
if ( hud->buttonFlags & BF_IGNORE ) {
return 0;
}
touch_t *t = hud->touch;
if ( !t ) {
// no touches in the control
hud->touchState = NOT_TOUCHED_STATE;
return 0;
}
float delta[2];
int centerX = hud->x + hud->drawWidth / 2;
int centerY = hud->y + hud->drawHeight / 2;
delta[0] = t->x - centerX;
delta[1] = t->y - centerY;
float rotorAngle = atan2( delta[1], delta[0] );
if ( hud->touchState == NOT_TOUCHED_STATE ) {
// just touched, haven't moved yet
hud->touchState = rotorAngle;
return 0;
}
float deltaAngle = rotorAngle - hud->touchState;
// handle the wrap around cases
if ( deltaAngle >= M_PI ) {
deltaAngle = deltaAngle - 2*M_PI;
} else if ( deltaAngle <= -M_PI ) {
deltaAngle = 2*M_PI + deltaAngle;
}
hud->touchState = rotorAngle;
hud->drawState += deltaAngle;
return deltaAngle / (2*M_PI);
}
#define TURBOTHRESHOLD 0x32
static int ClampMove( int v ) {
if ( v > TURBOTHRESHOLD ) {
return TURBOTHRESHOLD;
}
if ( v < -TURBOTHRESHOLD ) {
return -TURBOTHRESHOLD;
}
return v;
}
/*
==================
iphoneBuildTiccmd
Use touch and tilt controls to set up a doom ticcmd_t
==================
*/
static void iphoneBuildTiccmd(ticcmd_t* cmd) {
memset(cmd,0,sizeof*cmd);
// cmd->consistancy = consistancy[consoleplayer][maketic & BACKUPTICMASK];
if ( menuState != IPM_GAME ) {
// if in the menus, always generate an empty event
return;
}
// the respawn button triggers a use
if ( respawnActive ) {
cmd->buttons |= BT_USE;
respawnActive = false;
}
if ( gamestate != GS_LEVEL ) {
// at intermissions, all taps equal attack
// FIXME: better latched value
if ( numTouches == numPrevTouches + 1 ) {
cmd->buttons |= BT_ATTACK;
}
return;
}
// don't allow movement control use during automap
if ( automapmode & am_active ) {
return;
}
// don't built a tic when dead, other than the respawn use
if ( players[consoleplayer].playerstate == PST_DEAD ) {
return;
}
//------------------------
// No controls during weapon-select screen
//------------------------
boolean weaponCycle = false;
if ( drawWeaponSelect ) {
// if the weaponSelect overlay is up, continue tracking held touches
// until the are released
for ( ibutton_t *hud = (ibutton_t *)&huds ; hud != (ibutton_t *)(&huds+1) ; hud++ ) {
if ( hud->touch || hud == &huds.weaponSelect ) {
UpdateHudTouch( hud );
}
}
// Re-tapping in the weapon select area will cycle to the next weapon.
// The action happens on initial touch.
touch_t *t = huds.weaponSelect.touch;
if ( t && t->down && t->stateCount == 1 ) {
drawWeaponSelect = false;
t->stateCount++; // ensure it won't bring it back up
weaponCycle = true;
} else {
return;
}
}
//------------------------
// gameplay controls
//------------------------
// update all the hud touch states
if ( menuState == IPM_GAME ) {
for ( ibutton_t *hud = (ibutton_t *)&huds ; hud != (ibutton_t *)(&huds+1) ; hud++ ) {
if ( hud != &huds.fire ) {
UpdateHudTouch( hud );
}
}
}
// tap in the lower center for weapon switch
touch_t *t = huds.weaponSelect.touch;
if ( t && t->down && t->stateCount == 1 ) {
drawWeaponSelect = true;
}
// hack to let a single touch control both hud elements on combo sticks
// This is dependent on the order in the structure, and probably not a good
// way to do things.
if ( huds.sideStick.x == huds.forwardStick.x && huds.sideStick.y == huds.forwardStick.y ) {
huds.sideStick.touch = huds.forwardStick.touch;
huds.sideStick.downX = huds.forwardStick.downX;
huds.sideStick.downY = huds.forwardStick.downY;
}
if ( huds.turnStick.x == huds.forwardStick.x && huds.turnStick.y == huds.forwardStick.y ) {
huds.turnStick.touch = huds.forwardStick.touch;
huds.turnStick.downX = huds.forwardStick.downX;
huds.turnStick.downY = huds.forwardStick.downY;
}
// the fire button doesn't grab touches
{
int x = huds.fire.x - ( huds.fire.drawWidth >> 1 );
int y = huds.fire.y - ( huds.fire.drawHeight >> 1 );
int w = huds.fire.drawWidth << 1;
int h = huds.fire.drawHeight << 1;
if ( AnyTouchInBounds( x, y, w, h ) ) {
cmd->buttons |= BT_ATTACK;
huds.fire.buttonFlags |= BF_DRAW_ACTIVE; // draw with color
} else {
huds.fire.buttonFlags &= ~BF_DRAW_ACTIVE;
}
}
int forwardmove;
int sidemove;
// the edge of the drawn control should give the maximum
// legal doom movement speed
huds.forwardStick.scale = stickMove->value / 128.0f;
huds.sideStick.scale = stickMove->value / 128.0f;
forwardmove = -TURBOTHRESHOLD * AxisHit( &huds.forwardStick );
sidemove = TURBOTHRESHOLD * AxisHit( &huds.sideStick );
huds.turnStick.scale = stickTurn->value / 128.0f;
cmd->angleturn = -1500.0f * AxisHit( &huds.turnStick );
// rotary wheel
cmd->angleturn -= rotorTurn->value * RotorControl( &huds.turnRotor );
// accelerometer tilting
sidemove += tiltMove->value * DeadBandAdjust( tilt, tiltDeadBand->value );
cmd->angleturn -= tiltTurn->value * DeadBandAdjust( tilt, tiltDeadBand->value );
// clamp movements
cmd->forwardmove = ClampMove( forwardmove );
cmd->sidemove = ClampMove( sidemove );
// tap in the upper center for use
if ( TouchPressed( 140, 0, 240, 200 ) ) {
cmd->buttons |= BT_USE;
}
// auto-use if the game thread found a usable line in front of the player
if ( autoUse->value && autoUseActive ) {
if ( cmd->buttons & BT_USE ) {
// Allow a tap to briefly cancel the auto-use, which works around
// some issues with incorrectly started auto-uses preventing
// a real door from opening.
cmd->buttons &= ~BT_USE;
} else {
cmd->buttons |= BT_USE;
}
}
if ( weaponSelected != -1 ) {
cmd->buttons |= BT_CHANGE;
cmd->buttons |= weaponSelected<<BT_WEAPONSHIFT;
weaponSelected = -1;
} else {
// auto-cycle weapons when firing on empty
if ( players[consoleplayer].attackdown && !P_CheckAmmo(&players[consoleplayer]) ) {
weaponCycle = true;
}
// weapon switch
int newweapon = wp_nochange;
if ( weaponCycle ) {
// witch to next weapon when out of ammo
newweapon = P_SwitchWeapon(&players[consoleplayer]);
}
if (newweapon != wp_nochange) {
cmd->buttons |= BT_CHANGE;
cmd->buttons |= newweapon<<BT_WEAPONSHIFT;
}
}
}
/*
==================
ShouldSendPacket
WiFi can suffer from bad "pileup" because of the link-level
retransmit behavior. What we would dearly love is an ioctl or
something that returned a value of how many packets are backed
up in the transmit queue, but that would be terribly driver
specific, and we are unlikely to ever see it.
We are going to infer that there is a pileup by looking at the
round trip latency. If we ever support internet connections with
real latencies that are this large, we will have to use something
else.
==================
*/
// while 1 is usual, some combinations of AsyncTic phases will give 2 commonly,
// and we don't want to throttle back in those cases.
static const int okPacketLatency = 4;
static const int okOneWayLatency = 70;
static boolean ShouldSendPacket( netPeer_t *peer, int packetLatency ) {
if ( throttle->value == 0 ) {
// disabled completely, always send
return true;
}
if ( peer == &netServer ) {
if ( throttle->value == 2 ) {
return false; // don't send client messages at all
}
} else {
if ( throttle->value == 3 ) { // don't send server messages at all
return false;
}
}
// immediately fire back a packet if it looks like we just got one through
// clearly
if ( peer->lastPacketAsyncTic == asyncTicNum && peer->oneWayLatency < okOneWayLatency ) {
return true;
}
if ( packetLatency <= okPacketLatency ) {
return true;
}
// limit from 1 to 4, in worst case only transmit a packet
// every 16 frames, or about half a second
packetLatency -= okPacketLatency;
if ( packetLatency > 4 ) {
packetLatency = 4;
}
if ( asyncTicNum & ((1<<packetLatency)-1) ) {
return false; // inhibit transmit this frame
}
printf( "Sending on packetLatency %i\n", packetLatency );
return true; // we are throttling back, but transmit this frame
}
/*
==================
iphoneAsyncTic
This is called by a 30hz scheduled timeer in the main application thread.
Commands are generated and sent to the packet server
on this regular basis, regardless of the frame rate held by iphoneFrame().
This thread should be higher priority, so it always interrupts the game
thread.
It might be nice to run the game tics here, but the rendering code is not
thread safe with the game, so it isn't an option.
==================
*/
void iphoneAsyncTic() {
// log our timing accuracy (seems to be within a few msec -- not bad)
static int prev;
int now = SysIphoneMilliseconds();
asyncStats_t *stats = &asyncStats[asyncTicNum&(MAX_ASYNC_LOGS-1)];
asyncTicNum++;
memset( stats, 0, sizeof( *stats ) );
stats->msecFromLast = now - prev;
stats->msecToExecute = 0;
prev = now;
// listen for changes to available servers
ProcessDNSMessages();
// send out the setup packets if we are just starting the game
SendSetupPacketIfNecessary();
// don't generate any commands while loading levels
if ( iphoneFrameNum == levelLoadFrameNum ) {
return;
}
// don't let the game thread mess with touches during the async tic execution
pthread_mutex_lock( &eventMutex );
int afterLock = SysIphoneMilliseconds();
// latch the current touches for processing
for ( int i = 0 ; i < MAX_TOUCHES ; i++ ) {
touch_t *t = &sysTouches[i];
gameTouches[i] = *t;
// handle the special case of a touch that went down and up
// inside a single frame
if ( t->stateCount == -1 ) {
gameTouches[i].stateCount = 1;
t->stateCount = 0;
t->down = false;
} else {
t->stateCount++;
}
}
//---------------------------------
// read network packets
//
// we may receive multiple packets in one frame due to timer skew
// even with only one other player
//---------------------------------
if ( !netGameFailure ) {
byte packet[1500];
while( gameSocket > 0 ) {
struct sockaddr from;
unsigned senderLen = sizeof( from );
int r = recvfrom( gameSocket, &packet, sizeof( packet ), 0, &from, &senderLen );
if ( r == -1 ) {
if ( errno != EAGAIN ) {
perror( "recvfrom" );
}
break;
}
stats->received++;
iphoneProcessPacket( &from, packet, r );
}
}
//---------------------------------
// Create local user command
//
// We always create one, but it might not wind up being used for a game
// tic if it doesn't make it to the server at the right time.
//---------------------------------
ticcmd_t cmd;
iphoneBuildTiccmd( &cmd );
//---------------------------------
// If we are a client, send our command to the server
//---------------------------------
if ( consoleplayer != 0 ) {
if ( gameID != 0 && netgame && !netGameFailure ) {
stats->latency = packetSequence - lastServerPacket.packetAcknowledge;
if ( ShouldSendPacket( &netServer, packetSequence - lastServerPacket.packetAcknowledge ) ) {
packetClient_t cp;
memset( &cp, 0, sizeof( cp ) );
cp.packetType = PACKET_VERSION_CLIENT;
cp.gameID = gameID;
cp.packetAcknowledge = lastServerPacket.packetSequence;
cp.milliseconds = SysIphoneMilliseconds();
cp.packetSequence = packetSequence++;
cp.consoleplayer = consoleplayer;
cp.gametic = gametic;
cp.cmd = cmd;
int r = sendto( gameSocket, &cp, sizeof( cp ), 0, &netServer.address, sizeof( netServer.address ) );
stats->sent++;
if ( r == -1 ) {
printf( "UDP sendTo failed: %s\n", strerror( errno ) );
close( gameSocket );
gameSocket = -1;
}
}
}
} else {
// take our command directly
netPlayers[0].pc.cmd = cmd;
netPlayers[0].pc.gametic = gametic;
netPlayers[0].peer.lastPacketTime = now;
//---------------------------------
// Decide if we want to latch the current commands for execution by the game
//
//---------------------------------
int ticIndex = maketic & BACKUPTICMASK;
int worstTic = gametic;
for ( int i = 0 ; i < MAXPLAYERS ; i++ ) {
if ( playeringame[i] ) {
netcmds[i][ticIndex] = netPlayers[i].pc.cmd;
if ( netPlayers[i].pc.gametic < worstTic ) {
worstTic = netPlayers[i].pc.gametic;
}
}
}
// only let the server get a few tics ahead of any client, so if
// anyone is having significant net delivery problems, everyone will
// stall instead of losing the player. If this is too small, then
// every little hitch that any player gets will cause everyone to hitch.
if ( maketic - worstTic < netBuffer->value ) {
maketic++;
}
//---------------------------------
// Build server packets to send to clients
//
// Always send out the current command set over the network
// even if we didn't create a new command, in case we are just
// recovering from a lot of dropped packets.
//---------------------------------
if ( netgame && !netGameFailure ) {
// since we are sampling a shared wireless network, any of the player's
// latencies should be a good enough metric
stats->latency = packetSequence - netPlayers[1].pc.packetAcknowledge;
if ( ShouldSendPacket( &netPlayers[1].peer, stats->latency ) ) {
packetServer_t gp;
memset( &gp, 0, sizeof( gp ) );
gp.packetType = PACKET_VERSION_SERVER;
gp.gameID = gameID;
gp.packetSequence = packetSequence++;
gp.maketic = maketic;
memcpy( gp.netcmds, netcmds, sizeof( gp.netcmds ) );
//---------------------------------
// Send network packets to the clients
//---------------------------------
for ( int i = 1 ; i < MAXPLAYERS ; i++ ) {
if ( !playeringame[i] ) {
continue;
}
if ( gameSocket <= 0 ) {
continue;
}
netPlayer_t *np = &netPlayers[i];
// only send over the ticcmd that this client needs
gp.starttic = np->pc.gametic;
ticcmd_t *cmd_p = gp.netcmds;
for ( int i = gp.starttic ; i < gp.maketic ; i++ ) {
for ( int j = 0 ; j < MAXPLAYERS ; j++ ) {
if ( playeringame[j] ) {
*cmd_p++ = netcmds[j][i&BACKUPTICMASK];
}
}
}
int packetSize = (byte *)cmd_p - (byte *)&gp;
// use the most recent tic that both the client and
// server have run
gp.consistancyTic = np->pc.gametic < gametic ? np->pc.gametic : gametic;
gp.consistancyTic--;
for ( int j = 0 ; j < MAXPLAYERS ; j++ ) {
gp.consistancy[j] = consistancy[j][gp.consistancyTic&BACKUPTICMASK];
}
gp.packetAcknowledge = np->pc.packetSequence;
gp.milliseconds = SysIphoneMilliseconds();
// transmit the packet
stats->sent++;
int r = sendto( gameSocket, &gp, packetSize, 0, &np->peer.address, sizeof( np->peer.address ) );
if ( r == -1 ) {
printf( "UDP sendTo failed: %s\n", strerror( errno ) );
close( gameSocket );
gameSocket = -1;
}
}
}
}
}
stats->msecToExecute = SysIphoneMilliseconds() - now;
if ( stats->msecToExecute > 6 ) {
printf( "long asyncTic %i: %i msec (%i in lock), %i packets\n", asyncTicNum - 1, stats->msecToExecute,
afterLock - now, stats->received );
}
// the game thread can now swap touches
pthread_mutex_unlock( &eventMutex );
// signal the main thread that is probably blocked on this semaphore
if ( sem_post( ticSemaphore ) == -1 ) {
perror( "sem_post");
}
}

View file

@ -0,0 +1,552 @@
/*
Copyright (C) 2009 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// this is the version number displayed on the menu screen
#define DOOM_IPHONE_VERSION 0.9
// if defined, the game runs in a separate thread from the app event loop
#define USE_GAME_THREAD
typedef enum menuState {
IPM_GAME,
IPM_MAIN,
IPM_MAPS,
IPM_MULTIPLAYER,
IPM_CONTROLS,
IPM_OPTIONS,
IPM_HUDEDIT,
IPM_PACKET_TEST
} menuState_t;
extern menuState_t menuState;
void iphoneDrawMenus();
#define VID_WIDTH 480
#define VID_HEIGHT 320
#define MAX_SKILLS 5
#define MAX_MAPS 200
#define MF_TRIED 1
#define MF_COMPLETED 2
#define MF_KILLS 4
#define MF_SECRETS 8
#define MF_TREASURE 16
#define MF_TIME 32
// we want to track mapStats for downloaded content, so we
// won't have a known number of these
typedef struct {
int dataset;
int episode;
int map;
int completionFlags[MAX_SKILLS];
} mapStats_t;
// the level select screen returns this
typedef struct {
int dataset;
int episode;
int map;
int skill;
} mapStart_t;
// this structure is saved out at the head of the binary save file,
// and allows all the menus to work without having to load a game save
typedef struct {
mapStart_t map; // this is the map currently being run
int saveGameIsValid; // when 0, resume game will just be a new game
// if someone downloads more than MAX_MAPS, they won't get stat tracking on them.
int numMapStats;
mapStats_t mapStats[MAX_MAPS];
} playState_t;
extern playState_t playState;
extern boolean levelHasBeenLoaded; // determines if "resume game" does a loadGame and exiting does a saveGame
extern pkTexture_t *arialFontTexture;
// set to 1 when app is exiting to cause game thread to do a save game,
// which would not be safe to do from the event thread
extern volatile int saveOnExitState;
extern int asyncTicNum; // 30hz
extern int iphoneFrameNum; // frame rate dependent, max of 30hz
extern int levelLoadFrameNum;
extern int consoleActive;
extern boolean iphoneTimeDemo;
extern int timeDemoStart;
extern char timeDemoResultString[80];
extern cvar_t *skill;
extern cvar_t *episode;
extern cvar_t *controlScheme;
extern cvar_t *stickMove;
extern cvar_t *stickTurn;
extern cvar_t *rotorTurn;
extern cvar_t *stickDeadBand;
extern cvar_t *tiltTurn;
extern cvar_t *tiltMove;
extern cvar_t *tiltDeadBand;
extern cvar_t *tiltAverages;
extern cvar_t *music;
extern cvar_t *miniNet;
extern cvar_t *showTilt;
extern cvar_t *showTime;
extern cvar_t *showNet;
extern cvar_t *showSound;
extern cvar_t *cropSprites;
extern cvar_t *revLand;
extern cvar_t *mapScale;
extern cvar_t *drawControls;
extern cvar_t *autoUse;
extern cvar_t *statusBar;
extern cvar_t *touchClick;
extern cvar_t *messages;
extern cvar_t *timeLimit;
extern cvar_t *fragLimit;
extern cvar_t *mpDeathmatch;
extern cvar_t *mpDataset;
extern cvar_t *mpSkill;
extern cvar_t *mpEpisode;
extern cvar_t *mpMap;
extern cvar_t *glfinish;
extern cvar_t *mapSelectY;
extern cvar_t *throttle;
extern cvar_t *centerSticks;
extern cvar_t *rampTurn;
extern cvar_t *netBuffer;
extern int numTouches;
extern int touches[5][2]; // [0] = x, [1] = y in landscape mode, raster order with y = 0 at top
// so we can detect button releases
extern int numPrevTouches;
extern int prevTouches[5][2];
extern float tilt; // -1.0 to 1.0
extern float tiltPitch;
extern boolean drawWeaponSelect; // true when the weapon select overlay is up
extern int weaponSelected; // -1 for no change
typedef unsigned char color4_t[4];
typedef unsigned char color3_t[3];
// networking
enum {
PACKET_VERSION_BASE = 0x24350010,
PACKET_VERSION_SETUP,
PACKET_VERSION_JOIN,
PACKET_VERSION_CLIENT,
PACKET_VERSION_SERVER
} packetType_t;
#define DOOM_PORT 14666 // setup packets will go to DOOM_PORT+1
// the server sends out a setup packet by broadcast, and also directly addressed
// to each client that has joined the game because broadcast packets have truly
// crappy delivery characteristics over WiFi
typedef struct {
int packetType;
int gameID; // every change to anything in packetSetup_t must change gameID
int startGame; // when this is set, start running the game
int sendCount; // just for packet drop tests
mapStart_t map;
int deathmatch;
int fraglimit;
int timelimit;
int playerID[MAXPLAYERS]; // 0 = not in game
} packetSetup_t;
// If we have received a recent setup packet before hitting the multiplayer
// button, we will send a join packet to that server. Otherwise, we will
// start acting as a new server.
typedef struct {
int packetType;
// this should match the packetSetup.gameID
int gameID;
int playerID;
} packetJoin_t;
typedef struct {
int packetType;
// gameID is determined randomly during setup, any packet that doesn't
// match is discarded
int gameID;
// this could be used to tell when we are dropping client packets
// but it isn't critical
int packetSequence;
// used to show current round trip latency
int packetAcknowledge;
// the client's clock at the time the packet was sent, used
// to track one-way latency
int milliseconds;
// the server could match this up based on ip alone, but it is nice to have
int consoleplayer;
// the last tic that the client has run
int gametic;
// some commands will get missed over the network
ticcmd_t cmd;
} packetClient_t;
typedef struct {
int packetType;
// gameID is determined randomly during setup, any packet that doesn't
// match is discarded
int gameID;
// used to detect packet drops
int packetSequence;
// used to show current round trip latency
int packetAcknowledge;
// the server's clock at the time the packet was sent, used
// to track one-way latency
int milliseconds;
// consistancyTic will be the last acknowledged gametic for this
// particular client
int consistancyTic;
// constancy is used to see if somehow the game running on the
// client has diverged from the one running on the server,
// which is an unrecoverable error
short consistancy[MAXPLAYERS];
// this will be the last pc.gametic from the player
int starttic;
// netcmds[][(maketic-1)&BACKUPTICMASK] is the most recent
int maketic;
// only the [playersInGame*(maketic-starttic)] will be transmitted
ticcmd_t netcmds[MAXPLAYERS*BACKUPTICS];
} packetServer_t;
extern int gameSocket;
extern int playerID;
extern int gameID;
extern int localGameID;
extern int packetSequence;
// Only one game can be set up at a time on a given wireless segment, although
// several independent games can be played.
// If a valid setupPacket has arrived in the last second, that will be the
// displayed game, otherwise the local system starts sending out setupPackets.
extern packetSetup_t setupPacket;
extern int setupPacketFrameNum;
extern int localGameID; // change every time we take over as the sender of setupPackets
// set after each game tic if a usable line is in front of the player
extern boolean autoUseActive;
extern boolean respawnActive;
typedef enum {
NF_NONE,
NF_CONSISTANCY,
NF_INTERRUPTED
} netFail_t;
extern netFail_t netGameFailure; // set by asyncThread
typedef struct {
int interfaceIndex; // we must use the right socket to send packets
struct sockaddr address;
int oneWayLatency; // will always have 30+ msec of jitter
int lastPacketAsyncTic; // to easily tell if it just arrived
int lastPacketTime; // local milliseconds of last receive
int lastTimeDelta; // packet milliseconds - local milliseconds
int lowestTimeDelta; // min'd with lastTimeDelta each arrival
int currentPingTics; // packetSequence - last packetAcknowledge
} netPeer_t;
typedef struct {
netPeer_t peer;
packetClient_t pc; // most recent packet received
// TODO: There would be some benefit to ensuring that no edge transitions on
// buttons are missed due to clock/net jitter.
} netPlayer_t;
// all received packets, whether bluetooth or WiFi, go through here
void iphoneProcessPacket( const struct sockaddr *from, const void *data, int len );
extern netPeer_t netServer;
extern netPlayer_t netPlayers[MAXPLAYERS];
extern sem_t * ticSemaphore;
typedef struct {
int numGameTics;
int numPingTics;
int enterFrame;
int afterSleep;
int beforeSwap;
int afterSwap;
} logTime_t;
#define MAX_LOGGED_TIMES 512
extern logTime_t loggedTimes[MAX_LOGGED_TIMES]; // indexed by iphoneFrameNum
void LoadWallTexture( int wallPicNum );
float StringFontWidth( const char *str );
int TouchDown( int x, int y, int w, int h );
int TouchReleased( int x, int y, int w, int h );
int TouchPressed( int x, int y, int w, int h );
// y is the baseline for font drawing
float iphoneDrawText( float x, float y, float scale, const char *str );
float iphoneCenterText( float x, float y, float scale, const char *str );
void StartGame();
void iphoneOpenAutomap();
void iphoneDrawNotifyText();
void iphoneSet2D( void );
void R_Draw_Fill( int x, int y, int w, int h, color3_t c );
void R_Draw_Blend( int x, int y, int w, int h, color4_t c );
void InitImmediateModeGL();
int iphoneRotateForLandscape();
void iphoneCheckForLandscapeReverse();
void iphonePacifierUpdate();
void iphoneDrawScreen();
extern int damageflash;
extern int bonusFrameNum;
extern int attackDirTime[2];
#define BF_IGNORE 1 // don't draw or process touches
#define BF_INACTIVE 2 // draw, but no touch processing at all
#define BF_GLOW 4 // animated overbright glow
#define BF_DIMMED 8 // draw darker, but still selectable
#define BF_CENTERTEXT 16 // text in middle of button, not underneath
#define BF_TRANSPARENT 32 // blend translucent
#define BF_HUDBUTTON 64 // don't process in UpdateHudTouch
#define BF_DRAW_ACTIVE 128 // for fire button
typedef struct {
int x, y;
int drawWidth, drawHeight;
pkTexture_t *texture;
const char *title;
struct touch_s *touch;
float scale; // ramps up and down after touches
int frameNum; // reset scale if not checked on previous frame
int buttonFlags;
boolean twoFingerPress; // if a second finger came down before a release for timedemo / etc
// stuff for hud controls
boolean drawAsLimit; // color tint when further movement won't do anything
float touchState; // rotor angle
float drawState; // offsets for rotors
int downX, downY; // initial touch went down here
} ibutton_t;
typedef struct {
ibutton_t forwardStick;
ibutton_t sideStick;
ibutton_t turnStick;
ibutton_t turnRotor;
ibutton_t fire;
ibutton_t menu;
ibutton_t map;
ibutton_t weaponSelect;
} hud_t;
extern hud_t huds;
void HudSetForScheme( int schemeNum );
void HudSetTexnums();
void HudEditFrame();
boolean StartNetGame();
int BackButton();
void ResumeGame();
//---------------------------------------
// Touch and button
//---------------------------------------
typedef struct touch_s {
boolean down;
int x, y;
// int prevX, prevY; // will be set to x, y on first touch, copied after each game frame
int stateCount; // set to 1 on first event that state changes, incremented each game frame (-1 is a special tapped-and-released code)
void *controlOwner;
} touch_t;
#define MAX_TOUCHES 5
extern touch_t sysTouches[MAX_TOUCHES];
extern touch_t gameTouches[MAX_TOUCHES];
extern pthread_mutex_t eventMutex; // used to sync between game and event threads
touch_t *TouchInBounds( int x, int y, int w, int h );
touch_t *AnyTouchInBounds( int x, int y, int w, int h );
touch_t *UpdateHudTouch( ibutton_t *hud );
bool NewTextButton( ibutton_t *b, const char *title, int x, int y, int w, int h );
void SetButtonPics( ibutton_t *button, const char *picName, const char *title, int x, int y );
void SetButtonPicsAndSizes( ibutton_t *button, const char *picBase, const char *title, int x, int y, int w, int h );
boolean HandleButton( ibutton_t *button );
//---------------------------------------
// Doom stuff we use directly
//---------------------------------------
void G_DoSaveGame (boolean menu);
extern short consistancy[MAXPLAYERS][BACKUPTICS];
extern boolean levelTimer;
extern int levelTimeCount;
extern boolean levelFragLimit;
extern int levelFragLimitCount;
//---------------------------------------
// iphone_sound.c
//---------------------------------------
void Sound_Init( void );
void Sound_StartLocalSound( const char *sound );
void Sound_StartLocalSoundAtVolume( const char *sound, float volume );
void ShowSound();
//---------------------------------------
// iphone_net.c
//---------------------------------------
// dump all the interfaces and ip addresses for debugging
void ReportNetworkInterfaces();
// open a UDP socket
// pass 0 for INADDR_ANY, otherwise it will be on a specific
// network interface to allow transmits on bluetooth vs wifi
int UDPSocket( int interfaceNum, int portnum );
// this can be called every frame in the menu to highlight
// the multiplayer icon when a server is already up
boolean NetworkServerAvailable();
// returns "WiFi", "BlueTooth", or "" for display on the
// main menu multiplayer icon
const char *NetworkServerTransport();
// this queries DNS for the actual address
boolean ResolveNetworkServer( struct sockaddr *addr );
// If we are starting a server instead of joining one, make
// us available as a bonjour service until we start the game
// or back out of the multiplayer menu. Returns false if
// someone else grabbed it just before we could.
boolean RegisterGameService();
void TerminateGameService();
// called by AsyncTic() to check for server state changes,
// registers for service browsing on first call.
void ProcessDNSMessages();
// draw a graph of packets sent and received
void ShowNet();
void ShowMiniNet();
//---------------------------------------
// iphone_mapSelect.c
//---------------------------------------
// returns false if nothing was selected
// if map->map is -1, the back button was hit instead of choosing a level
boolean iphoneMapSelectMenu( mapStart_t *map );
mapStats_t *FindMapStats( int dataset, int episode, int map, boolean create );
const char *FindMapName( int dataset, int episode, int map );
//---------------------------------------
// iphone_start.c
//
// game harness routines
//---------------------------------------
void ResumeGame();
boolean StartNetGame();
void StartSaveGame();
void StartSinglePlayerGame( mapStart_t map );
void StartDemoGame( boolean timeDemoMode );
//---------------------------------------
// interfaces from the original game code
//---------------------------------------
void iphoneSetNotifyText( const char *str, ... );
void iphoneIntermission( wbstartstruct_t* wbstartstruct );
void iphoneStartLevel();
void iphoneStartMusic();
void iphoneStopMusic();
void iphonePlayMusic( const char *name );
//---------------------------------------
// interfaces to Objective-C land
//---------------------------------------
// The event thread will fill this after hitting enter
// on the console. The game thread should check it,
// execute it, and clear it under mutex.
extern char consoleCommand[1024];
void SysIPhoneSwapBuffers();
void SysIPhoneVibrate();
void SysIPhoneOpenURL( const char *url );
void SysIPhoneSetUIKitOrientation( int isLandscapeRight );
const char * SysIPhoneGetConsoleTextField();
void SysIPhoneSetConsoleTextField(const char *);
void SysIPhoneInitAudioSession();
int SysIPhoneOtherAudioIsPlaying();
int SysIphoneMilliseconds();
int SysIphoneMicroseconds();
const char * SysIphoneGetAppDir();
const char * SysIphoneGetDocDir();
//---------------------------------------
// interfaces from Objective-C land
//---------------------------------------
void iphoneStartup();
void iphoneShutdown();
void iphoneFrame();
void iphoneAsyncTic();
void iphoneTiltEvent( float *tilts );

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,514 @@
/*
Copyright (C) 2004-2005 Michael Liebscher <johnnycanuck@users.sourceforge.net>
Copyright (C) 1997-2001 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
doom
----
modifications to config.h
don't add the d_ipxgate.c file
don't add d_server.c file
don't add mmus2mid.[ch] files
don't add w_memcache.c, use w_mmap.c instead
added new SDL_opengl.h, changed code files from <SDL_opengl.h> to "SDL_opengl.h"
commented out #include <SDL.h>
Commented out the static on D_DoomMainSetup();
Add define HAVE_CONFIG_H to the target settings
Add define _DEBUG
#if around uses of GL_TEXTURE_RESIDENT in gl_texture.c
// JDC: not in GLES, not needed since it is the default condition glDisable(GL_POLYGON_SMOOTH);
// JDC #define USE_VERTEX_ARRAYS in gl_main.c
add the iphoneRotateForLandscape calls
static JDC removed short consistancy[MAXPLAYERS][BACKUPTICS];
// JDC glDisableClientState(GL_TEXTURE_COORD_ARRAY);
// JDC glDisableClientState(GL_VERTEX_ARRAY);
#ifdef IPHONE // JDC
#define MAX_SCREENWIDTH 480
#define MAX_SCREENHEIGHT 320
#else
code notes
----------
all the fixed point mess
goofy polar clipping
path traverse should have used a BSP tree
rename vldoor_e close and open enums to not conflict with unistd
opengl_error_break
WiFi internet play
---------
voip instead of key chat
extra asset work
----------------------
perfect weapon scales
demo of each level?
additive art separation -- attacks, buttons, etc
tuned option
------------
last kill / last secret / last item messages
more achievements in general
better item pickup sounds
scale blood spray with distance
easier item pickup
crosshair
better movement clipping to walls
better key pickup sound
textured automap
better low health warning
better feedback on where bullets hit
better bob cycle when going down stairs
map item should also show all monsters and items to make it cool
barrels explode easier
wave FOV when berzerk
pistol shots are useless in deathmatch
show opponent / enemy health when attacking them?
cpu optimizations
-------------
convert to 16 bit vertex data
void gld_BindPatch(GLTexture *gltexture, int cm) is expensive
fixedMul / fixedDiv in asm (negligable performance gain)
atlas all of the non-character items (and bodies?)
remove the pitch changes from sound?
gpu optimizations
------------------
use fog instead of full screen blend for damage/pickup flash (3 msec on IP3G)
pvrtc walls and floors
art needed
----------
new map / menu button
awards on medals
icon
thumbsticks
settings gears
must do
-------
beta list
---------
E4M3 slowdown
E3M1/E3M9 eye switch
todo
----
disable bluetooth support
new menu / map button problems
don't accept fire from an owned touch?
text scaling in buttons isn't perfect
better view angle transport
audio bugs
rotor control shouldn't be dimmed
check dual stick controls
depress fire button instead of red
volume button hack?
change background color for networking
tapping weapon change to cycle
is openal thread safe? we issue touch clicks from asynctic
disable multiplayer button if no ethernet addresses found
touch latching issues
add one tic latency to server?
select new game while in netgame
multiplayer arrow colors
remove players with stale joins
rocket explosion offset
texture preload status bar stuff and blood / impacts
stereo panning for headphones
directly build 16 bit textures instead of translating from 32 bit
texture wrap seam after end of e3m8
sliders should be touch-latch controls
respawn flash sounds sometimes not playing?
don't allow starting on secret levels
loaded savegame spot on different level didn't get view height on first frame
use graphic?
don't ever close doors with auto-use
separators in map select
rotor speed adjust
check all powerup effects
remove uses of prboom.wad?
check patch outlining code
flash all controls on initial level load
touch sounds when cancelling demo playback
play sound on respawn
catch memory warning, purge textures
use wad sound data
stop sound cleanly
entire gun doesn't get fullbright with muzzle flash
require four touches in line for console
restartable pwad interface
somewhat normal based lighting on walls
help menu
visual tilt indicator
tilt draw the turnstick when active
console
*/
#include "../doomiphone.h"
cvar_t *skill;
cvar_t *episode;
cvar_t *controlScheme;
cvar_t *stickTurn;
cvar_t *stickMove;
cvar_t *stickDeadBand;
cvar_t *rotorTurn;
cvar_t *tiltTurn;
cvar_t *tiltMove;
cvar_t *tiltDeadBand;
cvar_t *tiltAverages;
cvar_t *miniNet;
cvar_t *music;
cvar_t *showTilt;
cvar_t *showTime;
cvar_t *showNet;
cvar_t *showSound;
cvar_t *cropSprites;
cvar_t *revLand;
cvar_t *mapScale;
cvar_t *drawControls;
cvar_t *autoUse;
cvar_t *statusBar;
cvar_t *touchClick;
cvar_t *messages;
cvar_t *timeLimit;
cvar_t *fragLimit;
cvar_t *mpDeathmatch;
cvar_t *mpSkill;
cvar_t *mpDataset;
cvar_t *mpEpisode;
cvar_t *mpMap;
cvar_t *noBlend;
cvar_t *glfinish;
cvar_t *mapSelectY;
cvar_t *throttle;
cvar_t *centerSticks;
cvar_t *rampTurn;
cvar_t *netBuffer;
#define VERSION_BCONFIG ( 0x89490000 + sizeof( huds ) + sizeof( playState ) )
void Sys_Error( const char *format, ... )
{
va_list argptr;
char string[ 1024 ];
va_start( argptr, format );
(void)vsnprintf( string, sizeof( string ), format, argptr );
va_end( argptr );
fprintf( stderr, "Error: %s\n", string );
_exit( 1 );
}
#define plyr (players+consoleplayer) /* the console player */
void Give_f() {
plyr->armorpoints = idfa_armor; // Ty 03/09/98 - deh
plyr->armortype = idfa_armor_class; // Ty 03/09/98 - deh
// You can't own weapons that aren't in the game // phares 02/27/98
for (int i=0;i<NUMWEAPONS;i++)
if (!(((i == wp_plasma || i == wp_bfg) && gamemode == shareware) ||
(i == wp_supershotgun && gamemode != commercial)))
plyr->weaponowned[i] = true;
for (int i=0;i<NUMAMMO;i++)
if (i!=am_cell || gamemode!=shareware)
plyr->ammo[i] = plyr->maxammo[i];
plyr->message = s_STSTR_FAADDED;
for (int i=0;i<NUMCARDS;i++)
if (!plyr->cards[i]) // only print message if at least one key added
{ // however, caller may overwrite message anyway
plyr->cards[i] = true;
}
}
void God_f() {
plyr->cheats ^= CF_GODMODE;
if (plyr->cheats & CF_GODMODE)
{
if (plyr->mo)
plyr->mo->health = god_health; // Ty 03/09/98 - deh
plyr->health = god_health;
plyr->message = s_STSTR_DQDON; // Ty 03/27/98 - externalized
}
else
plyr->message = s_STSTR_DQDOFF; // Ty 03/27/98 - externalized
}
void ResetMaps_f() {
playState.numMapStats = 0;
memset( playState.mapStats, 0, sizeof( playState.mapStats ) );
}
/*
==================
iphoneStartup
==================
*/
struct addrinfo *addrinfoHead;
void D_DoomMainSetup();
void iphoneStartup() {
int start = SysIphoneMilliseconds();
// microseconds will be plenty random for playerID and localGameID
playerID = localGameID = SysIphoneMicroseconds();
InitImmediateModeGL();
// FIXME: get args
// myargc = 0;
// myargv = NULL;
// start Doom memory system
// Z_Init();
// init OpenAL before pak file, so the pak file can
// make all the al static buffers
Sound_Init();
// get our new-style pak file
char pakFile[1024];
sprintf( pakFile, "%s/base/base.iPack", SysIphoneGetAppDir() );
PK_Init( pakFile );
// register console commands
Cmd_AddCommand( "listcvars", Cvar_List_f );
Cmd_AddCommand( "resetcvars", Cvar_Reset_f );
Cmd_AddCommand( "resetmaps", ResetMaps_f );
Cmd_AddCommand( "listcmds", Cmd_ListCommands_f );
Cmd_AddCommand( "give", Give_f );
Cmd_AddCommand( "god", God_f );
// register console variables
Cvar_Get( "version", va( "%3.1f %s %s", DOOM_IPHONE_VERSION, __DATE__, __TIME__ ), 0 );
skill = Cvar_Get( "skill", "1", CVAR_ARCHIVE );
episode = Cvar_Get( "episode", "0", CVAR_ARCHIVE );
controlScheme = Cvar_Get( "controlScheme", "0", CVAR_ARCHIVE );
stickTurn = Cvar_Get( "stickTurn", "128", CVAR_ARCHIVE );
stickMove = Cvar_Get( "stickMove", "128", CVAR_ARCHIVE );
stickDeadBand = Cvar_Get( "stickDeadBand", "0.2", CVAR_ARCHIVE );
rotorTurn = Cvar_Get( "rotorTurn", "50000", CVAR_ARCHIVE );
tiltTurn = Cvar_Get( "tiltTurn", "0", CVAR_ARCHIVE );
tiltMove = Cvar_Get( "tiltMove", "0", CVAR_ARCHIVE );
tiltDeadBand = Cvar_Get( "tiltDeadBand", "0.08", CVAR_ARCHIVE );
tiltAverages = Cvar_Get( "tiltAverages", "3", CVAR_ARCHIVE );
centerSticks = Cvar_Get( "centerSticks", "1", CVAR_ARCHIVE );
rampTurn = Cvar_Get( "rampTurn", "1", CVAR_ARCHIVE );
music = Cvar_Get( "music", "1", CVAR_ARCHIVE );
cropSprites = Cvar_Get( "cropSprites", "1", 0 );
revLand = Cvar_Get( "revLand", "0", CVAR_ARCHIVE );
mapScale = Cvar_Get( "mapScale", "10", CVAR_ARCHIVE );
drawControls = Cvar_Get( "drawControls", "1", CVAR_ARCHIVE );
autoUse = Cvar_Get( "autoUse", "0", CVAR_ARCHIVE );
statusBar = Cvar_Get( "statusBar", "1", CVAR_ARCHIVE );
touchClick = Cvar_Get( "touchClick", "0.15", CVAR_ARCHIVE );
messages = Cvar_Get( "messages", "1", CVAR_ARCHIVE );
mapSelectY = Cvar_Get( "mapSelectY", "0", CVAR_ARCHIVE );
miniNet = Cvar_Get( "miniNet", "1", CVAR_ARCHIVE );
// multiplayer setup
timeLimit = Cvar_Get( "timeLimit", "0", CVAR_ARCHIVE );
fragLimit = Cvar_Get( "fragLimit", "5", CVAR_ARCHIVE );
mpDeathmatch = Cvar_Get( "mpDeathmatch", "0", CVAR_ARCHIVE );
mpDataset = Cvar_Get( "mpDataset", "0", CVAR_ARCHIVE );
mpEpisode = Cvar_Get( "mpEpisode", "1", CVAR_ARCHIVE );
mpSkill = Cvar_Get( "mpSkill", "1", CVAR_ARCHIVE );
mpMap = Cvar_Get( "mpMap", "1", CVAR_ARCHIVE );
// debug tools
showTilt = Cvar_Get( "showTilt", "-1", 0 );
showTime = Cvar_Get( "showTime", "0", 0 );
showNet = Cvar_Get( "showNet", "0", 0 );
showSound = Cvar_Get( "showSound", "0", 0 );
noBlend = Cvar_Get( "noBlend", "0", 0 ); // disable the damae blends for screenshots
glfinish = Cvar_Get( "glfinish", "0", 0 );
throttle = Cvar_Get( "throttle", "1", 0 ); // network packet throttle enable
netBuffer = Cvar_Get( "netBuffer", "4", 0 ); // max tics to buffer ahead
// load the archived cvars
Cmd_ExecuteFile( va( "%s/config.cfg", SysIphoneGetDocDir() ) );
// make sure volume changes and incoming calls draw the right orientation
SysIPhoneSetUIKitOrientation( revLand->value );
// start the intro music if it wasn't disabled with the music cvar
iphonePlayMusic( "intro" );
// iphonePlayMusic( "e1m1" );
// these should get overwritten by the config loading
memset( &playState, 0, sizeof( playState ) );
playState.map.skill = 1;
playState.map.episode = 1;
playState.map.map = 1;
HudSetForScheme( 0 );
// load the binary config file
FILE *f = fopen( va( "%s/binaryConfig.bin", SysIphoneGetDocDir() ), "rb" );
if ( f ) {
int version;
version = 0;
fread( &version, 1, sizeof( version ), f );
if ( version != VERSION_BCONFIG ) {
Com_Printf( "Binary config file bad version.\n" );
} else {
fread( &playState, 1, sizeof( playState ), f );
fread( &huds, 1, sizeof( huds ), f );
version = 0;
fread( &version, 1, sizeof( version ), f );
if ( version != VERSION_BCONFIG ) {
Com_Error( "Binary config file bad trailing version.\n" );
}
}
fclose( f );
}
Com_Printf( "startup time: %i msec\n", SysIphoneMilliseconds() - start );
start = SysIphoneMilliseconds();
// the texnums might have been different in the savegame
HudSetTexnums();
arialFontTexture = PK_FindTexture( "iphone/arialImageLAL.tga" );
Com_Printf( "preloadBeforePlay(): %i msec\n", SysIphoneMilliseconds() - start );
Com_Printf( "---------- D_DoomMain ----------\n" );
D_DoomMainSetup();
// put savegames here
strcpy( basesavegame, SysIphoneGetDocDir() );
// prBoom seems to draw the static pic screens without setting up 2D, causing
// a bad first frame
iphoneSet2D();
menuState = IPM_MAIN;
#if 0
// jump right to the save spot for debugging
ResumeGame();
#endif
}
/*
==================
iphoneShutdown
Write out configs and save the game at this position
==================
*/
void iphoneShutdown() {
FILE *fp;
char path[1024];
cvar_t *var;
char buffer[1024];
// write the ascii config file
snprintf( path, sizeof( path ), "%s/config.cfg", SysIphoneGetDocDir() );
fp = fopen( path, "w" );
if( ! fp ) {
Com_Printf( "Could not write config.cfg.\n" );
return;
}
// write out commands to set the archived cvars
for( var = cvar_vars ; var ; var = var->next ) {
if( var->flags & CVAR_ARCHIVE ) {
snprintf( buffer, sizeof( buffer ), "%s %s\n", var->name, var->string );
fprintf( fp, "%s", buffer );
Com_Printf( "%s", buffer );
}
}
fclose( fp );
// write the binary config file
FILE *f = fopen( va( "%s/binaryConfig.bin", SysIphoneGetDocDir() ), "wb" );
if ( !f ) {
Com_Printf( "Could not write binaryConfig.cfg.\n" );
return;
}
int version = VERSION_BCONFIG;
fwrite( &version, 1, sizeof( version ), f );
fwrite( &playState, 1, sizeof( playState ), f );
fwrite( &huds, 1, sizeof( huds ), f );
fwrite( &version, 1, sizeof( version ), f );
fclose( f );
// write the Doom savegame, unless no game level
// was actually started on this app invokation, or we
// are at an intermission / finale, or we are dead
if ( levelHasBeenLoaded && !netgame && gamestate == GS_LEVEL
&& players[consoleplayer].playerstate != PST_DEAD ) {
// let the game thread perform a savegame, since it
// would be unsafe to do it in this thread
saveOnExitState = 1;
while( saveOnExitState != 2 ) {
sem_post( ticSemaphore );
usleep( 10000 );
}
}
// not sure if we should do this, or let UIKit exit...
exit( 0 );
}

View file

@ -0,0 +1,423 @@
/*
* iphone_mapSelect.c
* doom
*
* Created by John Carmack on 4/19/09.
* Copyright 2009 id Software. All rights reserved.
*
*/
#include "../doomiphone.h"
typedef struct {
int dataset;
int episode;
int map;
const char *name;
} mapData_t;
mapData_t mapData[] = {
{ 0, 1, 1, "E1M1: Hangar" },
{ 0, 1, 2, "E1M2: Nuclear Plant" },
{ 0, 1, 3, "E1M3: Toxin Refinery" },
{ 0, 1, 4, "E1M4: Command Control" },
{ 0, 1, 5, "E1M5: Phobos Lab" },
{ 0, 1, 6, "E1M6: Central Processing" },
{ 0, 1, 7, "E1M7: Computer Station" },
{ 0, 1, 8, "E1M8: Phobos Anomaly" },
{ 0, 1, 9, "E1M9: Military Base" },
{ 0, 2, 1, "E2M1: Deimos Anomaly" },
{ 0, 2, 2, "E2M2: Containment Area" },
{ 0, 2, 3, "E2M3: Refinery" },
{ 0, 2, 4, "E2M4: Deimos Lab" },
{ 0, 2, 5, "E2M5: Command Center" },
{ 0, 2, 6, "E2M6: Halls of the Damned" },
{ 0, 2, 7, "E2M7: Spawning Vats" },
{ 0, 2, 8, "E2M8: Tower of Babel" },
{ 0, 2, 9, "E2M9: Fortress of Mystery" },
{ 0, 3, 1, "E3M1: Hell Keep" },
{ 0, 3, 2, "E3M2: Slough of Despair" },
{ 0, 3, 3, "E3M3: Pandemonium" },
{ 0, 3, 4, "E3M4: House of Pain" },
{ 0, 3, 5, "E3M5: Unholy Cathedral" },
{ 0, 3, 6, "E3M6: Mt. Erebus" },
{ 0, 3, 7, "E3M7: Limbo" },
{ 0, 3, 8, "E3M8: Dis" },
{ 0, 3, 9, "E3M9: Warrens" },
{ 0, 4, 1, "E4M1: Hell Beneath" },
{ 0, 4, 2, "E4M2: Perfect Hatred" },
{ 0, 4, 3, "E4M3: Sever The Wicked" },
{ 0, 4, 4, "E4M4: Unruly Evil" },
{ 0, 4, 5, "E4M5: They Will Repent" },
{ 0, 4, 6, "E4M6: Against Thee Wickedly" },
{ 0, 4, 7, "E4M7: And Hell Followed" },
{ 0, 4, 8, "E4M8: Unto The Cruel" },
{ 0, 4, 9, "E4M9: Fear" },
#if 0
{ 0, 0, 0, "level 1: entryway" },
{ 0, 0, 0, "level 2: underhalls" },
{ 0, 0, 0, "level 3: the gantlet" },
{ 0, 0, 0, "level 4: the focus" },
{ 0, 0, 0, "level 5: the waste tunnels" },
{ 0, 0, 0, "level 6: the crusher" },
{ 0, 0, 0, "level 7: dead simple" },
{ 0, 0, 0, "level 8: tricks and traps" },
{ 0, 0, 0, "level 9: the pit" },
{ 0, 0, 0, "level 10: refueling base" },
{ 0, 0, 0, "level 11: 'o' of destruction!" },
{ 0, 0, 0, "level 12: the factory" },
{ 0, 0, 0, "level 13: downtown" },
{ 0, 0, 0, "level 14: the inmost dens" },
{ 0, 0, 0, "level 15: industrial zone" },
{ 0, 0, 0, "level 16: suburbs" },
{ 0, 0, 0, "level 17: tenements" },
{ 0, 0, 0, "level 18: the courtyard" },
{ 0, 0, 0, "level 19: the citadel" },
{ 0, 0, 0, "level 20: gotcha!" },
{ 0, 0, 0, "level 21: nirvana" },
{ 0, 0, 0, "level 22: the catacombs" },
{ 0, 0, 0, "level 23: barrels o' fun" },
{ 0, 0, 0, "level 24: the chasm" },
{ 0, 0, 0, "level 25: bloodfalls" },
{ 0, 0, 0, "level 26: the abandoned mines" },
{ 0, 0, 0, "level 27: monster condo" },
{ 0, 0, 0, "level 28: the spirit world" },
{ 0, 0, 0, "level 29: the living end" },
{ 0, 0, 0, "level 30: icon of sin" },
{ 0, 0, 0, "level 31: wolfenstein" },
{ 0, 0, 0, "level 32: grosse" },
{ 0, 0, 0, "level 1: congo" },
{ 0, 0, 0, "level 2: well of souls" },
{ 0, 0, 0, "level 3: aztec" },
{ 0, 0, 0, "level 4: caged" },
{ 0, 0, 0, "level 5: ghost town" },
{ 0, 0, 0, "level 6: baron's lair" },
{ 0, 0, 0, "level 7: caughtyard" },
{ 0, 0, 0, "level 8: realm" },
{ 0, 0, 0, "level 9: abattoire" },
{ 0, 0, 0, "level 10: onslaught" },
{ 0, 0, 0, "level 11: hunted" },
{ 0, 0, 0, "level 12: speed" },
{ 0, 0, 0, "level 13: the crypt" },
{ 0, 0, 0, "level 14: genesis" },
{ 0, 0, 0, "level 15: the twilight" },
{ 0, 0, 0, "level 16: the omen" },
{ 0, 0, 0, "level 17: compound" },
{ 0, 0, 0, "level 18: neurosphere" },
{ 0, 0, 0, "level 19: nme" },
{ 0, 0, 0, "level 20: the death domain" },
{ 0, 0, 0, "level 21: slayer" },
{ 0, 0, 0, "level 22: impossible mission" },
{ 0, 0, 0, "level 23: tombstone" },
{ 0, 0, 0, "level 24: the final frontier" },
{ 0, 0, 0, "level 25: the temple of darkness" },
{ 0, 0, 0, "level 26: bunker" },
{ 0, 0, 0, "level 27: anti-christ" },
{ 0, 0, 0, "level 28: the sewers" },
{ 0, 0, 0, "level 29: odyssey of noises" },
{ 0, 0, 0, "level 30: the gateway of hell" },
{ 0, 0, 0, "level 31: cyberden" },
{ 0, 0, 0, "level 32: go 2 it" },
{ 0, 0, 0, "level 1: system control" },
{ 0, 0, 0, "level 2: human bbq" },
{ 0, 0, 0, "level 3: power control" },
{ 0, 0, 0, "level 4: wormhole" },
{ 0, 0, 0, "level 5: hanger" },
{ 0, 0, 0, "level 6: open season" },
{ 0, 0, 0, "level 7: prison" },
{ 0, 0, 0, "level 8: metal" },
{ 0, 0, 0, "level 9: stronghold" },
{ 0, 0, 0, "level 10: redemption" },
{ 0, 0, 0, "level 11: storage facility" },
{ 0, 0, 0, "level 12: crater" },
{ 0, 0, 0, "level 13: nukage processing" },
{ 0, 0, 0, "level 14: steel works" },
{ 0, 0, 0, "level 15: dead zone" },
{ 0, 0, 0, "level 16: deepest reaches" },
{ 0, 0, 0, "level 17: processing area" },
{ 0, 0, 0, "level 18: mill" },
{ 0, 0, 0, "level 19: shipping/respawning" },
{ 0, 0, 0, "level 20: central processing" },
{ 0, 0, 0, "level 21: administration center" },
{ 0, 0, 0, "level 22: habitat" },
{ 0, 0, 0, "level 23: lunar mining project" },
{ 0, 0, 0, "level 24: quarry" },
{ 0, 0, 0, "level 25: baron's den" },
{ 0, 0, 0, "level 26: ballistyx" },
{ 0, 0, 0, "level 27: mount pain" },
{ 0, 0, 0, "level 28: heck" },
{ 0, 0, 0, "level 29: river styx" },
{ 0, 0, 0, "level 30: last call" },
{ 0, 0, 0, "level 31: pharaoh" },
{ 0, 0, 0, "level 32: caribbean" },
#endif
{ 0, 0, 0, NULL }
};
/*
===================
FindMapStats
Finds or creats a mapStats_t structure for the given level.
This can return NULL if the entire array is filled up, which may
happen when people have an absurd number of downloaded levels.
===================
*/
mapStats_t *FindMapStats( int dataset, int episode, int map, boolean create ) {
for ( int i = 0 ; i < playState.numMapStats ; i++ ) {
mapStats_t *ms = &playState.mapStats[i];
if ( ms->dataset == dataset && ms->episode == episode && ms->map == map ) {
return ms;
}
}
if ( playState.numMapStats == MAX_MAPS ) {
// all full.
return NULL;
}
if ( !create ) {
return NULL;
}
mapStats_t *cms = &playState.mapStats[playState.numMapStats];
cms->dataset = dataset;
cms->episode = episode;
cms->map = map;
playState.numMapStats++;
return cms;
}
/*
==================
FindMapName
episodes and maps are one base
==================
*/
const char *FindMapName( int dataset, int episode, int map ) {
for ( mapData_t *md = mapData ; md->name ; md++ ) {
if ( md->dataset == dataset && md->episode == episode && md->map == map ) {
return md->name;
}
}
return "UNKNOWN MAP NAME";
}
/*
==================
iphoneMapSelectMenu
Skills are zero based:
sk_baby=0,
sk_easy,
sk_medium,
sk_hard,
sk_nightmare=4
episodes are one base
==================
*/
static const int MAP_ROW_HEIGHT = 52;
ibutton_t btnSkills[4];
int dragVelocity;
ibutton_t dragScroll;
mapData_t *selectedMap;
int totalDrag; // for determining if a release will activate the level
boolean iphoneMapSelectMenu( mapStart_t *map ) {
static int prevDragY;
if ( !dragScroll.x ) {
// first initialization
dragScroll.drawWidth = 480 - 80 - 64;
dragScroll.drawHeight = 320;
dragScroll.x = 64 + dragScroll.drawWidth / 2;
dragScroll.y = 160;
static char * skillNames[4] = {
"iphone/skill_easy.tga",
"iphone/skill_normal.tga",
"iphone/skill_hard.tga",
"iphone/skill_nightmare.tga" }; // not really "nightmare" skill since easy is "baby"
for ( int i = 0 ; i < 4 ; i++ ) {
SetButtonPics( &btnSkills[i], skillNames[i], "", 400, i*80 );
}
}
// check for drag-scrolling
if ( dragScroll.touch ) {
if ( dragScroll.touch->y != prevDragY ) {
dragVelocity = dragScroll.touch->y - prevDragY;
prevDragY = dragScroll.touch->y;
totalDrag += abs( dragVelocity );
}
}
Cvar_SetValue( mapSelectY->name, mapSelectY->value - dragVelocity );
// decay the dragVelocity
for ( int i = 0 ; i < 2 ; i++ ) {
if ( dragVelocity < 0 ) {
dragVelocity++;
} else if ( dragVelocity > 0 ) {
dragVelocity--;
}
}
int iskill = (int)skill->value;
if ( iskill < 0 ) {
iskill = 0;
Cvar_SetValue( skill->name, iskill );
} else if ( iskill >= MAX_SKILLS ) {
iskill = MAX_SKILLS-1;
Cvar_SetValue( skill->name, iskill );
}
// snap back to bounds if dragging past end
if ( mapSelectY->value < 0 ) {
Cvar_SetValue( mapSelectY->name, 0 );
}
int numMaps = 0;
for ( mapData_t *map = mapData ; map->name != NULL ; map++ ) {
numMaps++;
}
if ( mapSelectY->value > numMaps * MAP_ROW_HEIGHT - 320 ) {
Cvar_SetValue( mapSelectY->name, numMaps * MAP_ROW_HEIGHT - 320 );
}
// scrolling display of levels
int y = -mapSelectY->value;
mapData_t *startMap = NULL;
for ( mapData_t *map = mapData ; map->name != NULL ; map++ ) {
if ( y > -64 && y < 320 ) {
// find the mapStat_t for this map, if it has ever been started
int completionFlags = 0;
mapStats_t *ms = FindMapStats( map->dataset, map->episode, map->map, false );
if ( ms ) {
completionFlags = ms->completionFlags[iskill];
}
// if we aren't already dragging, check for a touch on a map button
if ( !dragScroll.touch ) {
touch_t *touch = TouchInBounds( 120, y, 400-128, 48 );
if ( touch ) {
Sound_StartLocalSound( "iphone/bdown_01.wav" );
dragScroll.touch = touch;
prevDragY = touch->y;
touch->controlOwner = &dragScroll;
selectedMap = map;
}
}
// color background based on selected / entered / completed state
if ( selectedMap == map ) {
glColor4f( 1,1,1,1 ); // launch if released
} else if ( completionFlags & MF_COMPLETED ) {
glColor4f( 0.2, 0.5, 0.2, 1 );
} else if ( completionFlags & MF_TRIED ) {
glColor4f( 0.5, 0.2, 0.2, 1 );
} else {
glColor4f( 0.4, 0.4, 0.4, 1 );
}
// use -1 x to avoid a texture wrap seam
PK_StretchTexture( PK_FindTexture( "iphone/long_string_box.tga" ), 110, y, 400-114, 48 );
glColor4f( 1,1,1,1 );
// draw the text
float w = StringFontWidth( map->name );
float fontScale = 0.75;
if ( w > 360 ) {
fontScale *= ( 360 / w );
}
iphoneDrawText( 120, y+32, fontScale, map->name );
// add the awards
if ( completionFlags & MF_KILLS ) {
PK_DrawTexture( PK_FindTexture( "iphone/kills.tga" ), 80, y+4 );
}
if ( completionFlags & MF_TIME ) {
PK_DrawTexture( PK_FindTexture( "iphone/par.tga" ), 40, y+4 );
}
if ( completionFlags & MF_SECRETS ) {
PK_DrawTexture( PK_FindTexture( "iphone/secrets.tga" ), 0, y+4 );
}
}
y += MAP_ROW_HEIGHT;
}
if ( numTouches == 0 ) {
totalDrag = 0;
}
// draw the skill level
for ( int i = 0 ; i < 4 ; i++ ) {
if ( i == iskill ) {
btnSkills[i].buttonFlags = 0;
} else {
btnSkills[i].buttonFlags = BF_DIMMED;
}
if ( HandleButton( &btnSkills[i] ) ) {
Cvar_SetValue( skill->name, i );
}
}
glColor4f( 1, 1, 1, 1 );
// handle back button before checking for touches in the awards area
if ( BackButton() ) {
map->map = -1;
return true;
}
// if we aren't already dragging, check for a touch anywhere outside the skill buttons
if ( !dragScroll.touch ) {
touch_t *touch = TouchInBounds( 0, 0, 400-128, 320 );
if ( touch ) {
dragScroll.touch = touch;
prevDragY = touch->y;
touch->controlOwner = &dragScroll;
selectedMap = NULL;
Sound_StartLocalSoundAtVolume( "iphone/controller_down_01_SILENCE.wav", touchClick->value );
}
} else {
// if we dragged more than a few pixels, don't launch the level
if ( totalDrag > 8 ) {
selectedMap = NULL;
}
if ( !dragScroll.touch->down ) {
// lifted finger
dragScroll.touch = NULL;
if ( selectedMap ) {
Sound_StartLocalSound( "iphone/baction_01.wav" );
startMap = selectedMap;
selectedMap = NULL;
} else {
Sound_StartLocalSoundAtVolume( "iphone/controller_up_01_SILENCE.wav", touchClick->value );
}
}
}
if ( !startMap ) {
return false;
}
map->skill = iskill;
map->episode = startMap->episode;
map->map = startMap->map;
map->dataset = startMap->dataset;
return true;
}

View file

@ -0,0 +1,925 @@
/*
Copyright (C) 2009 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../doomiphone.h"
// Only one game can be set up at a time on a given wireless segment, although
// several independent games can be played.
// If a valid setupPacket has arrived in the last second, that will be the
// displayed game, otherwise the local system starts sending out setupPackets.
packetSetup_t setupPacket;
int setupPacketFrameNum;
int localGameID; // change every time we take over as the sender of setupPackets
boolean levelHasBeenLoaded; // determines if "resume game" does a loadGame and exiting does a saveGame
menuState_t menuState;
color4_t highlightColor = { 128, 128, 128, 255 };
color4_t colorPressed = { 128, 128, 0, 255 };
void SetupEmptyNetGame();
void R_Draw_Blend( int x, int y, int w, int h, color4_t c ) {
glDisable( GL_TEXTURE_2D );
glColor4ubv( c );
glBegin( GL_QUADS );
glVertex2i( x, y );
glVertex2i( x+w, y );
glVertex2i( x+w, y+h );
glVertex2i( x, y+h );
glEnd();
glColor3f( 1, 1, 1 );
glEnable( GL_TEXTURE_2D );
}
void R_Draw_Fill( int x, int y, int w, int h, color3_t c ) {
// as of 2.2 OS, doing a clear with a small scissor rect is MUCH slower
// than drawing geometry
color4_t c4;
c4[0] = c[0];
c4[1] = c[1];
c4[2] = c[2];
c4[3] = 255;
R_Draw_Blend( x, y, w, h, c4 );
}
/*
==================
iphoneSlider
Returns true if modified
==================
*/
#define SF_DISABLED 1 // grey out, don't respond to touches
#define SF_INTEGER 2 // don't add percent
boolean iphoneSlider( int x, int y, int w, int h, const char *title, cvar_t *cvar,
float min, float max, int sliderFlags ) {
float value = cvar->value;
char str[80];
float f = ( value - min ) / ( max - min );
if ( f < 0 ) {
f = 0;
}
if ( f > 1 ) {
f = 1;
}
// draw the background
PK_StretchTexture( PK_FindTexture( "iphone/slider_shadow.tga" ), x, y, w, h );
// draw the current range
PK_BindTexture( PK_FindTexture( "iphone/slider_bar.tga" ) );
#if 0
// proportional
glBegin( GL_QUADS );
glTexCoord2f( 0.0f, 0.0f ); glVertex2i( x, y );
glTexCoord2f( f, 0.0f ); glVertex2i( x+w*f, y );
glTexCoord2f( f, 1.0f ); glVertex2i( x+w*f, y+h );
glTexCoord2f( 0.0f, 1.0f ); glVertex2i( x, y+h );
glEnd();
#else
// dragging thumb
glBegin( GL_QUADS );
glTexCoord2f( 0.0f, 0.0f ); glVertex2i( x+w*f-8, y );
glTexCoord2f( 1.0f, 0.0f ); glVertex2i( x+w*f+8, y );
glTexCoord2f( 1.0f, 1.0f ); glVertex2i( x+w*f+8, y+h );
glTexCoord2f( 0.0f, 1.0f ); glVertex2i( x+w*f-8, y+h );
glEnd();
#endif
// draw the title and fraction
if ( sliderFlags & SF_INTEGER ) {
sprintf( str, "%s : %i", title, (int)value );
} else {
sprintf( str, "%s : %i%%", title, (int)(f*100+0.5) );
}
iphoneCenterText( x+ w/2, y+h-10, 0.75, str );
// check for touches
if ( numTouches > 0 && touches[0][0] >= x && touches[0][0] < x + w
&& touches[0][1] >= y && touches[0][1] < y+ h ) {
float newValue;
float delta;
f = (float)( touches[0][0] - x ) / w;
if ( sliderFlags & SF_INTEGER ) {
newValue = rint( min + f * ( max - min ) );
} else {
// round to tenths
f = (int)( ( f + 0.05 ) * 10 ) * 0.1f;
if ( f < 0 ) {
f = 0;
}
if ( f > 1.0 ) {
f = 1.0;
}
newValue = min + f * ( max - min );
}
delta = fabs( newValue - cvar->value );
if ( f == 0 && cvar->value == 0 ) {
// special case of disable-at-0
} else if ( delta > 0.01 ) {
Cvar_SetValue( cvar->name, newValue );
Sound_StartLocalSound( "iphone/slide_01.wav" );
return true;
}
return false;
}
return false;
}
/*
==================
BackButton
==================
*/
ibutton_t btnBack;
int BackButton() {
if ( !btnBack.texture ) {
SetButtonPicsAndSizes( &btnBack, "iphone/back_button.tga", "", 0, 0, 48, 48 );
}
return HandleButton( &btnBack );
}
void GetMoreLevels( int x, int y ) {
// directly to the app store for more levels
SysIPhoneOpenURL( "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=304694876" );
}
/*
==================
iphoneMainMenu
==================
*/
ibutton_t btnResumeGame;
ibutton_t btnNewGame;
ibutton_t btnControls;
ibutton_t btnMultiplayer;
ibutton_t btnWWW;
ibutton_t btnDemo;
void iphoneMainMenu() {
if ( !btnResumeGame.texture ) {
// initial setup
SetButtonPics( &btnResumeGame, "iphone/resume_game.tga", "Resume Game", 16, 4 );
SetButtonPics( &btnNewGame, "iphone/new_game.tga", "New Game", 176, 4 );
SetButtonPics( &btnDemo, "iphone/demo.tga", "Demos", 336, 4 );
SetButtonPics( &btnMultiplayer, "iphone/multiplay.tga", "Multiplayer", 16, 168 );
SetButtonPics( &btnWWW, "iphone/website.tga", "Website", 176, 168 );
SetButtonPics( &btnControls, "iphone/controls.tga", "Options", 336, 168 );
}
if ( HandleButton( &btnResumeGame ) ) {
ResumeGame();
}
if ( HandleButton( &btnNewGame ) ) {
menuState = IPM_MAPS;
}
if ( HandleButton( &btnControls ) ) {
menuState = IPM_CONTROLS;
}
if ( netgame ) {
// disable multiplayer if we are already in a netgame
btnMultiplayer.buttonFlags = BF_INACTIVE | BF_TRANSPARENT;
} else if ( NetworkServerAvailable() ) {
// blink the multiplayer button if a local server is available
btnMultiplayer.buttonFlags = BF_GLOW;
} else {
btnMultiplayer.buttonFlags = 0;
}
if ( HandleButton( &btnMultiplayer ) ) {
// get the address for the local service, which may
// start up a bluetooth personal area network
boolean serverResolved = ResolveNetworkServer( &netServer.address );
// open our socket now that the network interfaces have been configured
if ( gameSocket <= 0 ) {
gameSocket = UDPSocket( 0, DOOM_PORT );
}
// get the address for the local service
if ( !serverResolved ) {
// nobody else is acting as a server, so start one here
RegisterGameService();
SetupEmptyNetGame();
}
menuState = IPM_MULTIPLAYER;
}
// draw the available interfaces over the blinking net button
if ( NetworkServerAvailable() ) {
iphoneCenterText( btnMultiplayer.x + btnMultiplayer.drawWidth / 2,
btnMultiplayer.y + btnMultiplayer.drawHeight/2, 0.75,
NetworkServerTransport() );
}
if ( HandleButton( &btnWWW ) ) {
// menuState = IPM_PACKET_TEST; // !@# debug
SysIPhoneOpenURL( "http://www.idsoftware.com/doomclassic/" );
}
if ( HandleButton( &btnDemo ) ) {
StartDemoGame( btnDemo.twoFingerPress );
}
if ( btnDemo.twoFingerPress ) {
strcpy( timeDemoResultString, "TIMEDEMO" );
}
// draw the timedemo results on top of the button
if ( timeDemoResultString[0] ) {
iphoneCenterText( btnDemo.x + btnDemo.drawWidth / 2, btnDemo.y + btnDemo.drawHeight/2, 0.75,
timeDemoResultString );
}
}
/*
==================
iphoneControlMenu
==================
*/
ibutton_t btnSchemes[4];
ibutton_t btnSettings;
ibutton_t btnMove;
void iphoneControlMenu() {
int i;
// iphoneCenterText( 240, 16, 0.75, __DATE__" "__TIME__ );
// 112 units between
if ( BackButton() ) {
menuState = IPM_MAIN;
}
if ( NewTextButton( &btnSettings, "Settings", 480-128, 0, 128, 48 ) ) {
menuState = IPM_OPTIONS;
}
if ( NewTextButton( &btnMove, "Move Controls", 48 + (480-(128+160+48))/2, 0, 160, 48 ) ) {
menuState = IPM_HUDEDIT;
}
if ( !btnSchemes[0].texture ) {
for ( int i = 0 ; i < 3 ; i++ ) {
SetButtonPicsAndSizes( &btnSchemes[i], va("iphone/config_%i.tga",i+1), "",
32 + (96+64) * i, 48 + ( 112 - 64 )*0.5, 96, 64 );
}
}
for ( i = 0 ; i < 3 ; i++ ) {
char str[128];
sprintf( str, "iphone/config_%i.tga", i+1 );
if ( i != controlScheme->value ) {
btnSchemes[i].buttonFlags = BF_DIMMED;
} else {
btnSchemes[i].buttonFlags = 0;
}
if ( HandleButton( &btnSchemes[i] ) ) {
Cvar_SetValue( controlScheme->name, i );
HudSetForScheme( i );
}
}
iphoneSlider( 20, 160, 440, 40, "move stick size", stickMove, 64, 128, 0 );
iphoneSlider( 20, 210, 440, 40, "turn stick size", stickTurn, 64, 128, 0 );
iphoneSlider( 20, 260, 440, 40, "tilt move speed", tiltMove, 100, 300, 0 );
if ( tiltMove->value == 100 ) {
Cvar_SetValue( tiltMove->name, 0 );
}
if ( tiltMove->value ) {
Cvar_SetValue( tiltTurn->name, 0 );
}
#if 0
iphoneSlider( 20, 280, 440, 40, "tilt turn speed", tiltTurn, 1500, 3500, 0 );
if ( tiltTurn->value == 1500 ) {
Cvar_SetValue( tiltTurn->name, 0 );
}
if ( tiltTurn->value ) {
Cvar_SetValue( tiltMove->name, 0 );
}
#endif
}
void SetupEmptyNetGame() {
Com_Printf( "SetupEmptyNetGame()\n" );
// no current setup packet, so initialize with this phone's default values
localGameID = SysIphoneMicroseconds();
memset( &setupPacket, 0, sizeof( setupPacket ) );
setupPacket.gameID = localGameID;
setupPacket.packetType = PACKET_VERSION_SETUP;
setupPacket.map.dataset = mpDataset->value;
setupPacket.map.episode = mpEpisode->value;
setupPacket.map.map = mpMap->value;
setupPacket.map.skill = mpSkill->value;
setupPacket.deathmatch = mpDeathmatch->value;
setupPacket.timelimit = timeLimit->value;
setupPacket.fraglimit = fragLimit->value;
setupPacket.playerID[0] = playerID;
}
/*
==================
SendJoinPacket
These will be sent to the server ever frame we are in the multiplayer menu.
==================
*/
void SendJoinPacket() {
packetJoin_t pj;
pj.packetType = PACKET_VERSION_JOIN;
pj.gameID = setupPacket.gameID;
pj.playerID = playerID;
int r = sendto( gameSocket, &pj, sizeof( pj ), 0,
&netServer.address, sizeof( netServer.address ) );
if ( r == -1 ) {
Com_Printf( "UDP sendTo failed: %s\n", strerror( errno ) );
close( gameSocket );
gameSocket = -1;
}
}
/*
==================
iphoneMultiplayerMenu
==================
*/
ibutton_t btnCoop;
ibutton_t btnDeathmatch;
ibutton_t btnMap;
ibutton_t btnNetSettings;
typedef enum {
NM_MAIN,
NM_MAP_SELECT,
NM_OPTIONS
} netMenu_t;
netMenu_t netMenu;
void iphoneMultiplayerMenu() {
if ( gameSocket <= 0 ) {
// no socket, so no multiplayer
TerminateGameService(); // don't advertise for any more new players
setupPacket.gameID = 0; // stop sending packets
menuState = IPM_MAIN;
return;
}
boolean server = ( setupPacket.gameID == localGameID );
// different screen when selecting a map to play
if ( netMenu == NM_MAP_SELECT ) {
mapStart_t map;
if ( !iphoneMapSelectMenu( &map ) ) {
// haven't selected anything yet
return;
}
netMenu = NM_MAIN;
if ( map.map != -1 ) {
// selected something new, didn't hit the back arrow
setupPacket.map = map;
}
} else if ( netMenu == NM_OPTIONS ) {
Cvar_SetValue( fragLimit->name, setupPacket.fraglimit );
if ( iphoneSlider( 104, 64, 272, 40, "frag limit", fragLimit, 0, 20, SF_INTEGER ) ) {
if ( server ) {
setupPacket.fraglimit = fragLimit->value;
}
}
Cvar_SetValue( timeLimit->name, setupPacket.timelimit );
if ( iphoneSlider( 104, 64+56, 272, 40, "time limit", timeLimit, 0, 20, SF_INTEGER ) ) {
if ( server ) {
setupPacket.timelimit = timeLimit->value;
}
}
if ( BackButton() ) {
netMenu = NM_MAIN;
}
return;
}
if ( !btnDeathmatch.texture ) {
// initial setup
SetButtonPicsAndSizes( &btnDeathmatch, "iphone/deathmatch.tga", "Deathmatch", 4+48, 64, 96, 96 );
SetButtonPicsAndSizes( &btnCoop, "iphone/co-op.tga", "Cooperative", 480-148, 64, 96, 96 );
}
if ( BackButton() ) {
if ( server ) {
TerminateGameService(); // don't advertise for any more new players
setupPacket.gameID = 0; // stop sending packets
}
menuState = IPM_MAIN;
}
if ( !server ) {
// we aren't the server
// send our join packet every frame
SendJoinPacket();
if ( setupPacketFrameNum < iphoneFrameNum - 30 ) {
// haven't received a current server packet
char str[1024];
struct sockaddr_in *sin = (struct sockaddr_in *)&netServer.address;
byte *ip = (byte *)&sin->sin_addr;
sprintf( str, "Joining server at %i.%i.%i.%i:%i\n", ip[0], ip[1], ip[2], ip[3],
ntohs( sin->sin_port ) );
iphoneCenterText( 240, 160, 0.75, str );
return;
}
} else {
// cull out any players that haven't given us a packet in a couple seconds
int now = SysIphoneMilliseconds();
for ( int i = 1 ; i < MAXPLAYERS ; i++ ) {
if ( setupPacket.playerID[i] && now - netPlayers[i].peer.lastPacketTime > 1000 ) {
printf( "Dropping player %i: last:%i now:%i\n", i, netPlayers[i].peer.lastPacketTime, now );
setupPacket.playerID[i] = 0;
}
}
}
// draw the level and allow clicking to change
Cvar_SetValue( mpDataset->name, setupPacket.map.dataset );
Cvar_SetValue( mpEpisode->name, setupPacket.map.episode );
Cvar_SetValue( mpMap->name, setupPacket.map.map );
Cvar_SetValue( mpSkill->name, setupPacket.map.skill );
// map select button / display
if ( NewTextButton( &btnMap, FindMapName( mpDataset->value, mpEpisode->value, mpMap->value ), 64, 0, 480-128, 48 ) ) {
if ( server ) {
// clients can't go into this menu
netMenu = NM_MAP_SELECT;
}
}
if ( setupPacket.deathmatch ) {
btnDeathmatch.buttonFlags = 0;
btnCoop.buttonFlags = BF_DIMMED;
} else {
btnDeathmatch.buttonFlags = BF_DIMMED;
btnCoop.buttonFlags = 0;
}
if ( HandleButton( &btnDeathmatch ) ) {
if ( server ) {
Cvar_SetValue( mpDeathmatch->name, 3 ); // weapons stay, items respawn rules
setupPacket.deathmatch = mpDeathmatch->value;
}
}
if ( HandleButton( &btnCoop ) ) {
if ( server ) {
Cvar_SetValue( mpDeathmatch->name, 0 );
setupPacket.deathmatch = mpDeathmatch->value;
}
}
if ( NewTextButton( &btnNetSettings, "Settings", 240-64, 64+24, 128, 48 ) ) {
netMenu = NM_OPTIONS;
}
for ( int i = 0 ; i < 4 ; i ++ ) {
int x = 45 + ( 64+45) * i;
int y = 64+128;
// FIXME: show proper player colors
byte color[4][4] = { { 0, 255, 0, 255 }, { 128, 128, 128, 255 }, { 128,64,0, 255 }, {255,0,0, 255 } };
glColor4ubv( color[i] );
PK_DrawTexture( PK_FindTexture( "iphone/multi_backdrop.tga" ), x, y );
glColor4f( 1, 1, 1, 1 );
if ( setupPacket.playerID[i] == playerID ) {
// bigger outline for your player slot
PK_StretchTexture( PK_FindTexture( "iphone/multi_frame.tga" ), x, y, 64, 64 );
}
// draw doom guy face
if ( setupPacket.playerID[i] != 0 ) {
PK_DrawTexture( PK_FindTexture( "iphone/multi_face.tga" ), x, y );
#if 0
// temp display IP address
byte *ip = (byte *)&setupPacket.address[i].sin_addr;
iphoneDrawText( x-16, (i&1) ? y+16 : y+48, 0.75, va("%i.%i.%i.%i", ip[0], ip[1], ip[2], ip[3] ) );
#endif
}
}
if ( server ) {
// flash a tiny pic when transmitting
if ( iphoneFrameNum & 1 ) {
glColor4f( 1,1,1,1 );
} else {
glColor4f( 0.5,0.5,0.5,1 );
}
iphoneCenterText( 470, 310, 0.75, "*" );
glColor4f( 1,1,1,1 );
}
if ( setupPacketFrameNum == iphoneFrameNum ) {
iphoneCenterText( 450, 310, 0.75, "*" );
}
// iphoneDrawText( 0, 310, 0.75, va("%i:%i", localGameID, setupPacket.gameID ) );
// only draw the start button if we have at least two players in game
int numPlayers = 0;
for ( int i = 0 ; i < MAXPLAYERS ; i++ ) {
if ( setupPacket.playerID[i] != 0 ) {
numPlayers++;
}
}
if ( numPlayers > 1 ) {
if ( server ) {
static ibutton_t btnStart;
if ( NewTextButton( &btnStart, "Start game", 240-80, 320-48, 160, 48 ) ) {
setupPacket.startGame = 1;
StartNetGame();
TerminateGameService(); // don't advertise for any more new players
return;
}
} else {
iphoneCenterText( 240, 320-10, 0.75, "Waiting for server to start the game" );
}
} else {
iphoneCenterText( 240, 320-10, 0.75, va("Waiting for players on %s", NetworkServerTransport() ) );
}
}
static ibutton_t optionButtons[2][6];
boolean OptionButton( int col, int row, const char *title ) {
assert( col >= 0 && col < 2 && row >= 0 && row < 6 );
return NewTextButton( &optionButtons[col][row], title, 10 + 235 * col, 64 + 50 * row, 225, 48 );
}
/*
==================
iphoneOptionsMenu
==================
*/
void iphoneOptionsMenu() {
if ( BackButton() ) {
menuState = IPM_CONTROLS;
}
boolean musicState = music->value;
if ( SysIPhoneOtherAudioIsPlaying() ) {
// music always off when ipod music is playing
musicState = false;
}
if ( OptionButton( 0, 0, autoUse->value ? "Auto use: ON" : "Auto use: OFF" ) ) {
Cvar_SetValue( autoUse->name, !autoUse->value );
}
if ( OptionButton( 0, 1, statusBar->value ? "Status bar: ON" : "Status bar: OFF" ) ) {
Cvar_SetValue( statusBar->name, !statusBar->value );
}
if ( OptionButton( 0, 2, touchClick->value ? "Touch click: ON" : "Touch click: OFF" ) ) {
Cvar_SetValue( touchClick->name, !touchClick->value );
}
if ( OptionButton( 0, 3, messages->value ? "Text messages: ON" : "Text messages: OFF" ) ) {
Cvar_SetValue( messages->name, !messages->value );
}
if ( OptionButton( 1, 0, drawControls->value ? "Draw controls: ON" : "Draw controls: OFF" ) ) {
Cvar_SetValue( drawControls->name, !drawControls->value );
}
if ( OptionButton( 1, 1, musicState ? "Music: ON" : "Music: OFF" ) ) {
if ( !SysIPhoneOtherAudioIsPlaying() ) {
Cvar_SetValue( music->name, !music->value );
if ( music->value ) {
iphoneStartMusic();
} else {
iphoneStopMusic();
}
}
}
if ( OptionButton( 1, 2, centerSticks->value ? "Center sticks: ON" : "Center sticks: OFF" ) ) {
Cvar_SetValue( centerSticks->name, !centerSticks->value );
}
if ( OptionButton( 1, 3, rampTurn->value ? "Ramp turn: ON" : "Ramp turn: OFF" ) ) {
Cvar_SetValue( rampTurn->name, !rampTurn->value );
}
}
/*
===================
iphoneIntermission
The end-of-level switch was just hit, note the state and awards
for the map select menu
===================
*/
void iphoneIntermission( wbstartstruct_t* wb ) {
if ( deathmatch || netgame ) {
// no achievements in deathmatch mode
return;
}
// find the current episode / map combination
// if a mapStat_t doesn't exist for this yet, create one
// mark this level / skill combination as tried
mapStats_t *cms = FindMapStats( playState.map.dataset, playState.map.episode, playState.map.map, true );
if ( !cms ) {
return;
}
int skill = playState.map.skill;
cms->completionFlags[skill] |= MF_COMPLETED;
// add the awards
if ( wb->plyr[0].stime < wb->partime ) {
cms->completionFlags[skill] |= MF_TIME;
}
int numkills = 0;
int numsecrets = 0;
int numitems = 0;
for ( int i = 0 ; i < MAXPLAYERS ; i++ ) {
if ( wb->plyr[i].in ) {
numkills += wb->plyr[i].skills;
numitems += wb->plyr[i].sitems;
numsecrets += wb->plyr[i].ssecret;
}
}
if ( numkills >= wb->maxkills ) {
cms->completionFlags[skill] |= MF_KILLS;
}
if ( numitems >= wb->maxitems ) {
cms->completionFlags[skill] |= MF_TREASURE;
}
if ( numsecrets >= wb->maxsecret ) {
cms->completionFlags[skill] |= MF_SECRETS;
}
}
/*
===================
iphoneStartLevel
Do a savegame with the current state
===================
*/
void iphoneStartLevel() {
if ( deathmatch || netgame ) {
// no achievements in deathmatch mode
return;
}
playState.map.map = gamemap;
// automatic save game
G_SaveGame( 0, "entersave" );
G_DoSaveGame(true);
// mark this level as tried
mapStats_t *cms = FindMapStats( playState.map.dataset, playState.map.episode, playState.map.map, true );
if ( cms ) {
cms->completionFlags[playState.map.skill] |= MF_TRIED;
}
}
/*
===================
DrawLiveBackground
Draw a randomish moving cloudy background
===================
*/
void DrawLiveBackground() {
static float bgVectors[2][2] = { { 0.01, 0.015 }, { -0.01, -0.02 } };
float fade[2];
// slide and fade a couple textures around
static float tc[2][4][2];
for ( int i = 0 ; i < 2 ; i++ ) {
int ofs = iphoneFrameNum + i * 32;
float dist = ( ofs & 63 );
for ( int j = 0 ; j < 2 ; j ++ ) {
for ( int k = 0 ; k < 2 ; k++ ) {
if ( rand()&1 ) {
if ( bgVectors[j][k] < 0.03 ) {
bgVectors[j][k] += 0.0001;
}
} else {
if ( bgVectors[j][k] > -0.03 ) {
bgVectors[j][k] -= 0.0001;
}
}
}
}
fade[i] = sin( ( dist - 16 ) / 32.0 * M_PI ) * 0.5 + 0.5;
fade[i] *= 0.7;
for ( int j = 0 ; j < 2 ; j++ ) {
tc[i][0][j] += bgVectors[i][j];
tc[i][0][j] -= floor( tc[i][0][j] );
}
tc[i][1][0] = tc[i][0][0]+1;
tc[i][1][1] = tc[i][0][1]+0;
tc[i][2][0] = tc[i][0][0]+0;
tc[i][2][1] = tc[i][0][1]+1;
tc[i][3][0] = tc[i][0][0]+1;
tc[i][3][1] = tc[i][0][1]+1;
}
// Fill rate performance is an issue just for two scrolling layers under
// modest GUI objects. Using a PVR2 texture and a single multitexture
// pass helps. If all the GUI objects were drawn with depth buffering,
// the surface rejection would help out, but bumping depth after every
// draw would be a bit of a chore.
#if 0
glClear( GL_DEPTH_BUFFER_BIT );
glDepthMask( 1 ); // write the depth buffer
glEnable( GL_DEPTH_TEST ); // depth test this background
#endif
PK_BindTexture( PK_FindTexture( "iphone/livetile_1.tga" ) );
glDisable( GL_BLEND );
glDisable( GL_DEPTH_TEST );
// multitexture setup
glActiveTexture( GL_TEXTURE1 );
glClientActiveTexture( GL_TEXTURE1 );
glEnable( GL_TEXTURE_2D );
PK_BindTexture( PK_FindTexture( "iphone/livetile_1.tga" ) );
glTexCoordPointer( 2, GL_FLOAT, 8, tc[1][0] );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD );
// glColor4f( fade[0], fade[0], fade[0], fade[1] );
glBegin( GL_TRIANGLE_STRIP );
glTexCoord2f( tc[0][0][0], tc[0][0][1] ); glVertex3f( 0, 0, 0.5 );
glTexCoord2f( tc[0][1][0], tc[0][1][1] ); glVertex3f( 480, 0, 0.5 );
glTexCoord2f( tc[0][2][0], tc[0][2][1]+1 ); glVertex3f( 0, 320, 0.5 );
glTexCoord2f( tc[0][3][0], tc[0][3][1]+1 ); glVertex3f( 480, 320, 0.5 );
glEnd();
// unbind the second texture
glBindTexture( GL_TEXTURE_2D, 0 );
glDisable( GL_TEXTURE_2D );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glActiveTexture( GL_TEXTURE0 );
glClientActiveTexture( GL_TEXTURE0 );
glColor4f( 1, 1, 1, 1 );
glEnable( GL_BLEND );
#if 0
// Enable depth test, but not depth writes, so the tile dorting
// minimizes the amount of time drawing the background when it
// is mostly covered.
glEnable( GL_DEPTH_TEST );
glDepthMask( 0 );
#endif
}
#define MAX_PACKET_LOG 64
int currentPacketLog;
int packetLogMsec[MAX_PACKET_LOG];
void iphonePacketTester() {
glClear( GL_COLOR_BUFFER_BIT );
if ( BackButton() ) {
menuState = IPM_MAIN;
return;
}
struct sockaddr_in sender;
unsigned senderLen = sizeof( sender );
byte buffer[1024];
while( 1 ) {
int r = recvfrom( gameSocket, buffer, sizeof( buffer ), 0, (struct sockaddr *)&sender, &senderLen );
if ( r == -1 ) {
break;
}
packetSetup_t *sp = (packetSetup_t *)buffer;
if ( sp->sendCount == setupPacket.sendCount ) {
Com_Printf( "Duplicated receive: %i\n", sp->sendCount );
} else if ( sp->sendCount < setupPacket.sendCount ) {
Com_Printf( "Out of order receive: %i < %i\n", sp->sendCount, setupPacket.sendCount );
} else if ( sp->sendCount > setupPacket.sendCount + 1 ) {
Com_Printf( "Dropped %i packets before %i\n", sp->sendCount - 1 - setupPacket.sendCount, sp->sendCount );
}
setupPacket = *sp;
packetLogMsec[currentPacketLog&(MAX_PACKET_LOG-1)] = SysIphoneMilliseconds();
currentPacketLog++;
}
color4_t activeColor = { 0, 255, 0, 255 };
for ( int i = 1 ; i < MAX_PACKET_LOG ; i++ ) {
int t1 = packetLogMsec[(currentPacketLog - i)&(MAX_PACKET_LOG-1)];
int t2 = packetLogMsec[(currentPacketLog - i - 1)&(MAX_PACKET_LOG-1)];
int msec = t1 - t2;
R_Draw_Fill( 0, i * 4, msec, 2, activeColor );
}
}
/*
===================
iphoneStartMenu
===================
*/
void iphoneStartMenu() {
mapStart_t map;
if ( !iphoneMapSelectMenu( &map ) ) {
return;
}
if ( map.map == -1 ) {
// hit the back button
menuState = IPM_MAIN;
return;
}
StartSinglePlayerGame( map );
}
/*
===================
iphoneDrawMenus
===================
*/
void iphoneDrawMenus() {
if ( menuState == IPM_PACKET_TEST ) {
// do this before the slow drawing background to get 60hz update rate
iphonePacketTester();
return;
}
// draw the slow double-cloud layer
DrawLiveBackground();
// check for game start in a received setup packet
if ( !netgame && setupPacket.startGame ) {
if ( StartNetGame() ) {
setupPacket.startGame = false;
// we aren't in this game
return;
}
}
// interactive menus
switch ( menuState ) {
case IPM_MAIN: iphoneMainMenu(); break;
case IPM_MULTIPLAYER: iphoneMultiplayerMenu(); break;
case IPM_MAPS: iphoneStartMenu(); break;
case IPM_CONTROLS: iphoneControlMenu(); break;
case IPM_OPTIONS: iphoneOptionsMenu(); break;
case IPM_HUDEDIT: HudEditFrame(); break;
}
}

View file

@ -0,0 +1,492 @@
/*
* iphone_net.c
* doom
*
* Created by John Carmack on 7/8/09.
* Copyright 2009 id Software. All rights reserved.
*
*/
/*
Deal with all the DNS / bonjour service discovery and resolution
*/
#include "../doomiphone.h"
#include <dns_sd.h>
#include <netdb.h> // for gethostbyname
#include <net/if.h> // for if_nameindex()
DNSServiceRef browseRef;
DNSServiceRef clientServiceRef;
DNSServiceRef serviceRef;
boolean serviceRefValid;
typedef struct {
int interfaceIndex;
char browseName[1024];
char browseRegtype[1024];
char browseDomain[1024];
} service_t;
boolean localServer;
// we can find services on both WiFi and Bluetooth interfaces
#define MAX_SERVICE_INTEFACES 4
service_t serviceInterfaces[MAX_SERVICE_INTEFACES];
boolean gotServerAddress;
struct sockaddr resolvedServerAddress;
static const char *serviceName = "_DoomServer._udp.";
void DNSServiceRegisterReplyCallback (
DNSServiceRef sdRef,
DNSServiceFlags flags,
DNSServiceErrorType errorCode,
const char *name,
const char *regtype,
const char *domain,
void *context ) {
if ( errorCode == kDNSServiceErr_NoError ) {
localServer = true;
} else {
localServer = false;
}
}
boolean RegisterGameService() {
DNSServiceErrorType err = DNSServiceRegister(
&serviceRef,
kDNSServiceFlagsNoAutoRename, // we want a conflict error
0, // all interfaces
"iPhone Doom Classic",
serviceName,
NULL, // domain
NULL, // host
htons( DOOM_PORT ),
0, // txtLen
NULL, // txtRecord
DNSServiceRegisterReplyCallback,
NULL // context
);
if ( err != kDNSServiceErr_NoError ) {
printf( "DNSServiceRegister error\n" );
} else {
// block until we get a response, process it, and run the callback
err = DNSServiceProcessResult( serviceRef );
if ( err != kDNSServiceErr_NoError ) {
printf( "DNSServiceProcessResult error\n" );
}
}
return localServer;
}
void TerminateGameService() {
if ( localServer ) {
localServer = false;
}
DNSServiceRefDeallocate( serviceRef );
memset( serviceInterfaces, 0, sizeof( serviceInterfaces ) );
}
void DNSServiceQueryRecordReplyCallback (
DNSServiceRef DNSServiceRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
const char *fullname,
uint16_t rrtype,
uint16_t rrclass,
uint16_t rdlen,
const void *rdata,
uint32_t ttl,
void *context ) {
assert( rdlen == 4 );
const byte *ip = (const byte *)rdata;
char interfaceName[IF_NAMESIZE];
if_indextoname( interfaceIndex, interfaceName );
printf( "DNSServiceQueryRecordReplyCallback: %s, interface[%i] = %s, [%i] = %i.%i.%i.%i\n",
fullname, interfaceIndex, interfaceName, rdlen, ip[0], ip[1], ip[2], ip[3] );
ReportNetworkInterfaces();
memset( &resolvedServerAddress, 0, sizeof( resolvedServerAddress ) );
struct sockaddr_in *sin = (struct sockaddr_in *)&resolvedServerAddress;
sin->sin_len = sizeof( resolvedServerAddress );
sin->sin_family = AF_INET;
sin->sin_port = htons( DOOM_PORT );
memcpy( &sin->sin_addr, ip, 4 );
gotServerAddress = true;
}
DNSServiceFlags callbackFlags;
void DNSServiceResolveReplyCallback (
DNSServiceRef sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
const char *fullname,
const char *hosttarget,
uint16_t port,
uint16_t txtLen,
const unsigned char *txtRecord,
void *context ) {
char interfaceName[IF_NAMESIZE];
if_indextoname( interfaceIndex, interfaceName );
printf( "Resolve: interfaceIndex [%i]=%s : %s @ %s\n", interfaceIndex, interfaceName, fullname, hosttarget );
callbackFlags = flags;
#if 0
struct hostent * host = gethostbyname( hosttarget );
if ( host ) {
printf( "h_name: %s\n", host->h_name );
if ( host->h_aliases ) { // this can be NULL
for ( char **list = host->h_aliases ; *list ; list++ ) {
printf( "h_alias: %s\n", *list );
}
}
printf( "h_addrtype: %i\n", host->h_addrtype );
printf( "h_length: %i\n", host->h_length );
if ( !host->h_addr_list ) { // I doubt this would ever be NULL...
return;
}
for ( char **list = host->h_addr_list ; *list ; list++ ) {
printf( "addr: %i.%i.%i.%i\n", ((byte *)*list)[0], ((byte *)*list)[1], ((byte *)*list)[2], ((byte *)*list)[3] );
}
memset( &resolvedServerAddress, 0, sizeof( resolvedServerAddress ) );
resolvedServerAddress.sin_len = sizeof( resolvedServerAddress );
resolvedServerAddress.sin_family = host->h_addrtype;
resolvedServerAddress.sin_port = htons( DOOM_PORT );
assert( host->h_length == 4 );
memcpy( &resolvedServerAddress.sin_addr, *host->h_addr_list, host->h_length );
gotServerAddress = true;
}
#else
DNSServiceRef queryRef;
// look up the name for this host
DNSServiceErrorType err = DNSServiceQueryRecord (
&queryRef,
kDNSServiceFlagsForceMulticast,
interfaceIndex,
hosttarget,
kDNSServiceType_A, // we want the host address
kDNSServiceClass_IN,
DNSServiceQueryRecordReplyCallback,
NULL /* may be NULL */
);
if ( err != kDNSServiceErr_NoError ) {
printf( "DNSServiceQueryRecord error\n" );
} else {
// block until we get a response, process it, and run the callback
err = DNSServiceProcessResult( queryRef );
if ( err != kDNSServiceErr_NoError ) {
printf( "DNSServiceProcessResult error\n" );
}
DNSServiceRefDeallocate( queryRef );
}
#endif
}
boolean NetworkServerAvailable() {
for ( int i = 0 ; i < MAX_SERVICE_INTEFACES ; i++ ) {
if ( serviceInterfaces[i].interfaceIndex != 0 ) {
return true;
}
}
return false;
}
// returns "WiFi", "BlueTooth", or "" for display on the
// main menu multiplayer icon
const char *NetworkServerTransport() {
int count = 0;
for ( int i = 0 ; i < MAX_SERVICE_INTEFACES ; i++ ) {
if ( serviceInterfaces[i].interfaceIndex != 0 ) {
count++;
}
}
static char str[1024];
str[0] = 0;
for ( int i = 0 ; i < MAX_SERVICE_INTEFACES ; i++ ) {
int index = serviceInterfaces[i].interfaceIndex;
if ( index == 0 ) {
continue;
}
if ( str[0] ) {
strcat( str, "+" );
}
if ( index == -1 ) {
strcat( str, "BT-NEW" );
} else if ( index == 1 ) {
strcat( str, "LOOP" ); // we should never see this!
} else if ( index == 2 ) {
strcat( str, "WiFi" );
} else {
strcat( str, "BT-EST" );
}
}
return str;
}
boolean ResolveNetworkServer( struct sockaddr *addr ) {
if ( !NetworkServerAvailable() ) {
return false;
}
gotServerAddress = false;
DNSServiceRef resolveRef;
// An unconnected bluetooth service will report an interfaceIndex of -1, so if
// we have a wifi link with an interfaceIndex > 0, use that
// explicitly.
service_t *service = NULL;
for ( int i = 0 ; i < MAX_SERVICE_INTEFACES ; i++ ) {
if ( serviceInterfaces[i].interfaceIndex > 0 ) {
service = &serviceInterfaces[i];
char interfaceName[IF_NAMESIZE];
if_indextoname( service->interfaceIndex, interfaceName );
printf( "explicitly using resolving server on interface %i = %s\n", service->interfaceIndex, interfaceName );
break;
}
}
if ( !service ) {
// settle for the unconnected bluetooth service
for ( int i = 0 ; i < MAX_SERVICE_INTEFACES ; i++ ) {
if ( serviceInterfaces[i].interfaceIndex != 0 ) {
service = &serviceInterfaces[i];
break;
}
}
if ( !service ) {
printf( "No serviceInterface current.\n" );
return false;
}
}
// look up the name for this service
DNSServiceErrorType err = DNSServiceResolve (
&resolveRef,
kDNSServiceFlagsForceMulticast, // always on local link
service->interfaceIndex > 0 ? service->interfaceIndex : 0, // don't use -1 for bluetooth
service->browseName,
service->browseRegtype,
service->browseDomain,
DNSServiceResolveReplyCallback,
NULL /* context */
);
if ( err != kDNSServiceErr_NoError ) {
printf( "DNSServiceResolve error\n" );
} else {
// We can get two callbacks when both wifi and bluetooth are enabled
callbackFlags = 0;
do {
err = DNSServiceProcessResult( resolveRef );
if ( err != kDNSServiceErr_NoError ) {
printf( "DNSServiceProcessResult error\n" );
}
} while ( callbackFlags & kDNSServiceFlagsMoreComing );
DNSServiceRefDeallocate( resolveRef );
}
if ( gotServerAddress ) {
*addr = resolvedServerAddress;
return true;
}
return false;
}
void DNSServiceBrowseReplyCallback(
DNSServiceRef sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
const char *serviceName,
const char *regtype,
const char *replyDomain,
void *context ) {
printf( "DNSServiceBrowseReplyCallback %s: interface:%i name:%s regtype:%s domain:%s\n",
(flags & kDNSServiceFlagsAdd) ? "ADD" : "REMOVE",
interfaceIndex, serviceName, regtype, replyDomain );
if ( flags & kDNSServiceFlagsAdd ) {
// add it to the list
if ( interfaceIndex == 1 ) {
printf( "Not adding service on loopback interface.\n" );
} else {
for ( int i = 0 ; i < MAX_SERVICE_INTEFACES ; i++ ) {
service_t *service = &serviceInterfaces[i];
if ( service->interfaceIndex == 0 ) {
strncpy( service->browseName, serviceName, sizeof( service->browseName ) -1 );
strncpy( service->browseRegtype, regtype, sizeof( service->browseRegtype ) -1 );
strncpy( service->browseDomain, replyDomain, sizeof( service->browseDomain ) -1 );
service->interfaceIndex = interfaceIndex;
break;
}
}
}
} else {
// remove it from the list
for ( int i = 0 ; i < MAX_SERVICE_INTEFACES ; i++ ) {
if ( serviceInterfaces[i].interfaceIndex == interfaceIndex ) {
serviceInterfaces[i].interfaceIndex = 0;
}
}
}
}
void ProcessDNSMessages() {
static boolean initialized;
if ( !initialized ) {
initialized = true;
DNSServiceErrorType err = DNSServiceBrowse (
&browseRef,
0, /* flags */
0, /* interface */
serviceName,
NULL, /* domain */
DNSServiceBrowseReplyCallback,
NULL /* context */
);
if ( err != kDNSServiceErr_NoError ) {
printf( "DNSServiceBrowse error\n" );
return;
}
}
// poll the socket for updates
int socket = DNSServiceRefSockFD( browseRef );
if ( socket <= 0 ) {
return;
}
fd_set set;
FD_ZERO( &set );
FD_SET( socket, &set );
struct timeval tv;
memset( &tv, 0, sizeof( tv ) );
if ( select( socket+1, &set, NULL, NULL, &tv ) > 0 ) {
DNSServiceProcessResult( browseRef );
}
}
void ReportNetworkInterfaces() {
struct ifaddrs *ifap;
printf( "getifaddrs():\n" );
if ( getifaddrs( &ifap ) == -1 ) {
perror( "getifaddrs(): " );
} else {
for ( struct ifaddrs *ifa = ifap ; ifa ; ifa = ifa->ifa_next ) {
struct sockaddr_in *ina = (struct sockaddr_in *)ifa->ifa_addr;
if ( ina->sin_family == AF_INET ) {
byte *ip = (byte *)&ina->sin_addr;
// struct ifa_data *data = (struct ifa_data *)ifa->ifa_data;
printf( "ifa_name: %s ifa_flags: %i sa_family: %i=AF_INET ip: %i.%i.%i.%i\n", ifa->ifa_name, ifa->ifa_flags,
ina->sin_family, ip[0], ip[1], ip[2], ip[3] );
} else if ( ina->sin_family == AF_LINK ) {
struct if_data *data = (struct if_data *)ifa->ifa_data;
printf( "ifa_name: %s ifa_flags: %i sa_family: %i=AF_LINK ifi_ipackets: %i\n", ifa->ifa_name, ifa->ifa_flags,
ina->sin_family, data->ifi_ipackets );
} else {
printf( "ifa_name: %s ifa_flags: %i sa_family: %i=???\n", ifa->ifa_name, ifa->ifa_flags,
ina->sin_family );
}
}
freeifaddrs( ifap );
}
printf( "if_nameindex():\n" );
struct if_nameindex *ifnames = if_nameindex();
if ( !ifnames ) {
perror( "if_ameindex():" );
} else {
for ( int i = 0 ; ifnames[i].if_index != 0 ; i++ ) {
printf( "%i : %s\n", ifnames[i].if_index, ifnames[i].if_name );
}
if_freenameindex( ifnames );
}
}
int InterfaceIndexForAddress( struct sockaddr_in *adr ) {
return 0;
}
struct sockaddr_in AddressForInterfaceIndex( int interfaceIndex ) {
struct sockaddr_in addr;
addr.sin_len = sizeof( addr );
addr.sin_family = AF_INET;
if ( interfaceIndex == 0 ) {
addr.sin_addr.s_addr = INADDR_ANY;
} else {
}
return addr;
}
int UDPSocket( int interfaceIndex, int portnum ) {
int udpSocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
if ( udpSocket == -1 ) {
Com_Printf( "UDP socket failed: %s\n", strerror( errno ) );
return -1;
}
struct sockaddr_in addr = AddressForInterfaceIndex( interfaceIndex );
addr.sin_port = htons( portnum );
if ( bind( udpSocket, (struct sockaddr *)&addr, sizeof( addr ) ) == -1 ) {
Com_Printf( "UDP bind failed: %s\n", strerror( errno ) );
close( udpSocket );
return -1;
}
#if 0
// enable broadcast
int on = 1;
if ( setsockopt( udpSocket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on) ) == -1 ) {
Com_Printf( "UDP setsockopt failed: %s\n", strerror( errno ) );
close( udpSocket );
return -1;
}
#endif
#if 0
// set the type-of-service, in hopes that the link level drivers use it
// to stop buffering huge amounts of data when there are line errors
int tos = 0x10; /* IPTOS_LOWDELAY; */ /* see <netinet/in.h> */
if ( setsockopt( udpSocket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos) ) == -1 ) {
Com_Printf( "setsockopt IP_TOS failed: %s\n", strerror( errno ) );
}
#endif
// enable non-blocking IO
if ( fcntl( udpSocket, F_SETFL, O_NONBLOCK ) == -1 ) {
Com_Printf( "UDP fcntl failed: %s\n", strerror( errno ) );
close( udpSocket );
return -1;
}
return udpSocket;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,40 @@
/*
Copyright (C) 2009 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef IPHONE_QGL_ENUMERANTS_H
#define IPHONE_QGL_ENUMERANTS_H
#ifdef QGL_LOG_GL_CALLS
#include <OpenGLES/ES1/gl.h>
#ifdef __cplusplus
extern "C" {
#endif
const char *StringFromGLEnumerant( GLenum enumerant );
#ifdef __cplusplus
}
#endif
#endif // QGL_LOG_GL_CALLS
#endif // IPHONE_QGL_ENUMERANTS_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,268 @@
/*
* iphone_sound.c
* doom
*
* Created by John Carmack on 4/16/09.
* Copyright 2009 Id Software. All rights reserved.
*
*/
#include "../doomiphone.h"
#import <AudioToolbox/AudioServices.h>
typedef struct {
unsigned sourceName; // OpenAL sourceName
pkWav_t *sfx; // NULL if unused
float volume; // stored for showSound display
} channel_t;
static ALCcontext *Context;
static ALCdevice *Device;
#define MAX_CHANNELS 16
static channel_t s_channels[ MAX_CHANNELS ];
cvar_t *s_sfxVolume;
void Sound_StartLocalSound( const char *filename ) {
Sound_StartLocalSoundAtVolume( filename, 1.0f );
}
void Sound_StartLocalSoundAtVolume( const char *filename, float volume ) {
pkWav_t *sfx;
sfx = PK_FindWav( filename );
if( ! sfx ) {
Com_Printf( "Sound_StartLocalSound: could not cache (%s)\n", filename );
return;
}
// printf( "sound:%s\n", filename );
// channel 0 is reserved for UI sounds, the other channels
// are for DOOM sounds
channel_t *ch = &s_channels[ 0 ];
ch->sfx = sfx;
ch->volume = s_sfxVolume->value * volume;
alSourceStop( ch->sourceName );
alSourcef( ch->sourceName, AL_GAIN, ch->volume );
alSourcei( ch->sourceName, AL_BUFFER, sfx->alBufferNum );
alSourcef( ch->sourceName, AL_PITCH, 1.0f );
alSourcePlay( ch->sourceName );
}
static void Sound_Play_f( void ) {
if( Cmd_Argc() == 1 ) {
Com_Printf( "Usage: play <soundfile>\n" );
return;
}
Sound_StartLocalSound( Cmd_Argv( 1 ) );
}
// we won't allow music to be toggled on or off in the menu when this is true
int otherAudioIsPlaying;
int SysIPhoneOtherAudioIsPlaying() {
return otherAudioIsPlaying;
}
void interruptionListener( void *inUserData, UInt32 inInterruption)
{
printf("Session interrupted! --- %s ---", inInterruption == kAudioSessionBeginInterruption ? "Begin Interruption" : "End Interruption");
if ( inInterruption == kAudioSessionEndInterruption )
{
// make sure we are again the active session
UInt32 audioCategory = kAudioSessionCategory_AmbientSound;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory);
AudioSessionSetActive( true );
// do we need to re-initialize the sound subsystem in this case?
}
}
void Sound_Init( void ) {
Com_Printf( "\n------- Sound Initialization -------\n" );
s_sfxVolume = Cvar_Get( "s_sfxVolume", "1.0", 0 );
Cmd_AddCommand( "play", Sound_Play_f );
// make sure background ipod music mixes with our sound effects
Com_Printf( "...Initializing AudioSession\n" );
OSStatus status = 0;
status = AudioSessionInitialize(NULL, NULL, interruptionListener, NULL); // else "couldn't initialize audio session"
// if there is iPod music playing in the background, we want to use
// the AmbientSound catagory, otherwise we will leave it at the default.
// If we always set it to AmbientSound, then the mp3 background music
// playback goes to software on 3.0 for a huge slowdown.
UInt32 propOtherAudioIsPlaying = 'othr'; // kAudioSessionProperty_OtherAudioIsPlaying
UInt32 size = sizeof( otherAudioIsPlaying );
AudioSessionGetProperty( propOtherAudioIsPlaying, &size, &otherAudioIsPlaying );
Com_Printf("OtherAudioIsPlaying = %d\n", otherAudioIsPlaying );
if ( otherAudioIsPlaying ) {
UInt32 audioCategory = kAudioSessionCategory_AmbientSound;
status = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory);
}
status = AudioSessionSetActive(true); // else "couldn't set audio session active\n"
Com_Printf( "...Initializing OpenAL subsystem\n" );
// get the OpenAL device
Device = alcOpenDevice( NULL );
if( Device == NULL ) {
Com_Printf( "Failed to alcOpenDevice\n" );
}
// set the mixer output rate lower, so we don't waste time doing 44khz
// must be done before the context is created!
extern ALvoid alcMacOSXMixerOutputRate(const ALdouble value);
alcMacOSXMixerOutputRate( 22050 );
// Create context(s)
Context = alcCreateContext( Device, NULL );
if( Context == NULL ) {
Com_Error( "Failed to alcCreateContext\n" );
}
// Set active context
alcGetError( Device );
alcMakeContextCurrent( Context );
if( alcGetError( Device ) != ALC_NO_ERROR ) {
Com_Error( "Failed to alcMakeContextCurrent\n" );
}
// allocate all the channels we are going to use
channel_t *ch;
int i;
for( i = 0, ch = s_channels ; i < MAX_CHANNELS ; ++i, ++ch ) {
alGenSources( 1, &ch->sourceName );
if( alGetError() != AL_NO_ERROR ) {
Com_Error( "Allocating AL sound sources" );
}
alSourcei( ch->sourceName, AL_SOURCE_RELATIVE, AL_FALSE );
}
Com_Printf( "------------------------------------\n" );
}
/*
==================
ShowSound
Display active sound channels
==================
*/
void ShowSound() {
if ( !showSound->value ) {
return;
}
channel_t *ch;
int i;
for( i = 0, ch = s_channels ; i < MAX_CHANNELS ; ++i, ++ch ) {
int state;
alGetSourcei( ch->sourceName, AL_SOURCE_STATE, &state );
if ( state != AL_PLAYING ) {
continue;
}
int v = ch->volume * 255;
if ( v > 255 ) {
v = 255;
}
color4_t color = { v, v, v, 255 };
R_Draw_Fill( i*16, 0, 12, 12, color );
}
}
/*
==================================================================
PrBoom interface
==================================================================
*/
// Init at program start...
void I_InitSound(void) {}
// ... shut down and relase at program termination.
void I_ShutdownSound(void) {}
// Initialize channels?
void I_SetChannels(void) {}
// Get raw data lump index for sound descriptor.
int I_GetSfxLumpNum (sfxinfo_t *sfx) {
// find the pkWav_t for this sfxinfo
char upper[16], *d = upper;
for ( const char *c = sfx->name ; *c ; c++ ) {
*d++ = toupper( *c );
}
*d = 0;
pkWav_t *pkwav = PK_FindWav( va( "newsfx/DS%s.wav", upper ) );
return pkwav - pkWavs;
}
// Starts a sound in a particular sound channel.
// volume ranges 0 - 64
// seperation tanges is 128 straight ahead, 0 = all left ear, 255 = all right ear
// pitch centers around 128
int I_StartSound(int sfx_id, int channel, int vol, int sep, int pitch, int priority) {
sfxinfo_t *dsfx = &S_sfx[sfx_id];
assert( dsfx->lumpnum >= 0 && dsfx->lumpnum < pkHeader->wavs.count );
pkWav_t *sfx = &pkWavs[dsfx->lumpnum];
// printf( "sound: %s chan:%i vol:%i sep:%i pitch:%i priority:%i\n", sfx->wavData->name.name, channel, vol, sep, pitch, priority );
assert( channel >= 0 && channel < MAX_CHANNELS - 1 );
channel_t *ch = &s_channels[ 1+channel ];
alSourceStop( ch->sourceName );
if ( ch->sfx == sfx ) {
// restarting the same sound
alSourceRewind( ch->sourceName );
} else {
alSourcei( ch->sourceName, AL_BUFFER, sfx->alBufferNum );
}
ch->sfx = sfx;
ch->volume = s_sfxVolume->value * vol / 64.0;
alSourcef( ch->sourceName, AL_GAIN, ch->volume );
alSourcef( ch->sourceName, AL_PITCH, pitch / 128.0f );
alSourcePlay( ch->sourceName );
return (int)ch;
}
// Stops a sound channel.
void I_StopSound(int handle) {}
// Called by S_*() functions
// to see if a channel is still playing.
// Returns 0 if no longer playing, 1 if playing.
boolean I_SoundIsPlaying(int handle) {
channel_t *ch = (channel_t *)handle;
if ( !ch ) {
return false;
}
int state;
alGetSourcei( ch->sourceName, AL_SOURCE_STATE, &state );
return state == AL_PLAYING;
}
// Called by m_menu.c to let the quit sound play and quit right after it stops
boolean I_AnySoundStillPlaying(void) { return false; }
// Updates the volume, separation,
// and pitch of a sound channel.
void I_UpdateSoundParams(int handle, int vol, int sep, int pitch) {}

View file

@ -0,0 +1,210 @@
/*
* iphone_start.c
* doom
*
* Created by John Carmack on 7/7/09.
* Copyright 2009 id Software. All rights reserved.
*
*/
#include "../doomiphone.h"
/*
==================
ResumeGame
==================
*/
void ResumeGame() {
if ( levelHasBeenLoaded && !demoplayback ) {
// return to the already started game
drawWeaponSelect = false;
weaponSelected = -1;
automapmode = 0;
advancedemo = false;
menuState = IPM_GAME;
return;
}
if ( !playState.saveGameIsValid ) {
// they hit "resume game" on the first app lounch, so just start E1M1
mapStart_t map;
map.skill = 1;
map.episode = 1;
map.map = 1;
StartSinglePlayerGame( map );
} else {
StartSaveGame();
}
}
/*
==================
GameSetup
==================
*/
void GameSetup() {
// resume game just goes back to playing, it doesn't load anything
levelHasBeenLoaded = true;
// make sure doom doesn't cycle to the next demo loop and kill the new game
advancedemo = false;
// not in a timedemo yet
timeDemoStart = 0;
iphoneTimeDemo = false;
// display the game next time through the main loop
drawWeaponSelect = false;
weaponSelected = -1;
automapmode = 0;
menuState = IPM_GAME;
demoplayback = false;
levelTimer = false;
levelFragLimit = false;
// single player game
netgame = false;
deathmatch = false;
nomonsters = false;
memset( playeringame, 0, sizeof( playeringame ) );
consoleplayer = 0;
displayplayer = 0;
playeringame[consoleplayer] = 1;
}
/*
=======================
StartSaveGame
Can be called by both the resume game button after launch, or the
load game button after a player death
=======================
*/
void StartSaveGame() {
GameSetup();
G_LoadGame( 0, true );
G_DoLoadGame();
}
/*
=======================
StartSinglePlayerGame
=======================
*/
void StartSinglePlayerGame( mapStart_t map ) {
playState.map = map;
playState.saveGameIsValid = true; // assume we will save the game on exit
// mark this level / skill combination as tried
//
mapStats_t *cms = FindMapStats( playState.map.dataset, playState.map.episode, playState.map.map, true );
if ( cms ) {
// if we are at MAX_MAPS, no stat tracking...
cms->completionFlags[playState.map.skill] |= MF_TRIED;
}
GameSetup();
// start the map
G_InitNew( playState.map.skill, playState.map.episode, playState.map.map );
}
/*
=======================
StartNetGame
Begins a game based on the contents of setupPacket
=======================
*/
boolean StartNetGame() {
// make sure we are supposed to be in this game
int slot = -1;
for ( int i = 0 ; i < MAXPLAYERS ; i++ ) {
if ( setupPacket.playerID[i] == playerID ) {
slot = i;
}
}
if ( slot == -1 ) {
return false;
}
GameSetup();
consoleplayer = displayplayer = slot;
netgame = true; // respawn without restarting levels
if ( setupPacket.deathmatch ) {
// deathmatch game
deathmatch = setupPacket.deathmatch; // could be either 1 or 2 for altdeath
nomonsters = true;
if ( setupPacket.timelimit > 0 ) {
levelTimer = true;
// 30 hz, minutes
levelTimeCount = setupPacket.timelimit * 30 * 60;
}
if ( setupPacket.fraglimit > 0 ) {
levelFragLimit = true;
levelFragLimitCount = setupPacket.fraglimit;
}
} else {
// coop game
deathmatch = false;
nomonsters = false;
}
for ( int i = 0 ; i < MAXPLAYERS ; i++ ) {
if ( setupPacket.playerID[i] != 0 ) {
playeringame[i] = 1;
} else {
playeringame[i] = 0;
}
}
gametic = 0;
maketic = 1; // allow everyone to run the first frame without waiting for a packet
memset( netcmds, 0, sizeof( netcmds ) );
memset( consistancy, 0, sizeof( consistancy ) );
gameID = setupPacket.gameID;
// start the map
G_InitNew( setupPacket.map.skill, setupPacket.map.episode, setupPacket.map.map );
return true;
}
/*
=======================
StartDemoGame
The demo button has been hit on the main menu
=======================
*/
void StartDemoGame( boolean timeDemoMode ) {
if ( levelHasBeenLoaded ) {
// save the current game before starting the demos
levelHasBeenLoaded = false;
G_SaveGame( 0, "quicksave" );
G_DoSaveGame(true);
}
GameSetup();
if ( timeDemoMode ) {
iphoneTimeDemo = true;
}
// always skip to the next one on each exit from the menu
advancedemo = true;
}

View file

@ -0,0 +1,61 @@
/*
Copyright (C) 2009 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "../doomiphone.h"
#import <AudioToolbox/AudioServices.h>
int SysIphoneMicroseconds() {
struct timeval tp;
struct timezone tzp;
static int secbase;
gettimeofday( &tp, &tzp );
if( ! secbase ) {
secbase = tp.tv_sec;
return tp.tv_usec;
}
int curtime = (tp.tv_sec - secbase) * 1000000 + tp.tv_usec;
return curtime;
}
int SysIphoneMilliseconds() {
return SysIphoneMicroseconds()/1000;
}
extern char iphoneDocDirectory[1024];
extern char iphoneAppDirectory[1024];
const char *SysIphoneGetAppDir() {
return iphoneAppDirectory;
}
const char *SysIphoneGetDocDir() {
return iphoneDocDirectory;
}
void SysIPhoneVibrate() {
AudioServicesPlaySystemSound( kSystemSoundID_Vibrate );
}

View file

@ -0,0 +1,299 @@
/*
Copyright (C) 2009 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// define this to get only the first episode on selections, and the
// automatic sell screen at the end of episode 1
#define EPISODE_ONE_ONLY
// this is the version number displayed on the menu screen
#define DOOM_IPHONE_VERSION 0.1
// if defined, the game runs in a separate thread from the app event loop
#define USE_GAME_THREAD
typedef enum menuState {
IPM_GAME,
IPM_MAIN,
IPM_MAPS,
IPM_MULTIPLAYER,
IPM_MASTER,
IPM_CONTROLS,
IPM_OPTIONS,
IPM_HUDEDIT
} menuState_t;
extern menuState_t menuState;
void iphoneDrawMenus();
#define VID_WIDTH 480
#define VID_HEIGHT 320
#define MAX_SKILLS 5
#define MAX_MAPS 200
#define MF_TRIED 1
#define MF_COMPLETED 2
#define MF_KILLS 4
#define MF_SECRETS 8
#define MF_TREASURE 16
#define MF_TIME 32
// we want to track mapStats for downloaded content, so we
// won't have a known number of these
typedef struct {
int dataset;
int episode;
int map;
int completionFlags[MAX_SKILLS];
} mapStats_t;
// this structure is saved out at the head of the binary save file,
// and allows all the menus to work without having to load a game save
typedef struct {
int version;
int episode;
int map;
int skill;
int mapsStarted; // when 0, resume game will just be a new game
// if someone downloads more than MAX_MAPS, they won't get stat tracking on them.
int numMapStats;
mapStats_t mapStats[MAX_MAPS];
} currentMap_t;
extern currentMap_t currentMap;
extern boolean levelHasBeenLoaded; // determines if "resume game" does a loadGame and exiting does a saveGame
extern pkTexture_t *fontTexture;
extern pkTexture_t *numberPics[10];
extern int iphoneFrameNum;
extern int levelLoadFrameNum;
extern int consoleActive;
extern cvar_t *skill;
extern cvar_t *episode;
extern cvar_t *controlScheme;
extern cvar_t *stickMove;
extern cvar_t *stickTurn;
extern cvar_t *rotorTurn;
extern cvar_t *stickDeadBand;
extern cvar_t *tiltTurn;
extern cvar_t *tiltMove;
extern cvar_t *tiltDeadBand;
extern cvar_t *tiltAverages;
extern cvar_t *music;
extern cvar_t *showTilt;
extern cvar_t *showTime;
extern cvar_t *cropSprites;
extern cvar_t *revLand;
extern cvar_t *mapScale;
extern cvar_t *hideControls;
extern cvar_t *tapFire;
extern cvar_t *skipSleep;
extern cvar_t *autoUse;
extern cvar_t *statusBar;
extern cvar_t *touchClick;
extern int numTouches;
extern int touches[5][2]; // [0] = x, [1] = y in landscape mode, raster order with y = 0 at top
// so we can detect button releases
extern int numPrevTouches;
extern int prevTouches[5][2];
extern float tilt; // -1.0 to 1.0
extern float tiltPitch;
extern boolean drawWeaponSelect; // true when the weapon select overlay is up
extern int weaponSelected; // -1 for no change
typedef unsigned char color4_t[4];
typedef unsigned char color3_t[3];
typedef struct {
int enterFrame;
int beforeSwap;
int afterSwap;
int afterSleep;
} logTime_t;
#define MAX_LOGGED_TIMES 512
extern logTime_t loggedTimes[MAX_LOGGED_TIMES]; // indexed by iphoneFrameNum
void LoadWallTexture( int wallPicNum );
int TouchDown( int x, int y, int w, int h );
int TouchReleased( int x, int y, int w, int h );
int iphoneDrawText( int x, int y, const char *str );
int iphoneCenterText( int x, int y, const char *str );
void iphoneDrawNumber( int x, int y, int number, int charWidth, int charHeight );
void iphoneDrawPic( int x, int y, int w, int h, const char *pic );
int iphoneDrawPicWithTouch( int x, int y, int w, int h, const char *pic );
void StartGame();
void iphoneOpenAutomap();
void iphoneDrawNotifyText();
void iphoneSet2D( void );
bool TextButton( const char *title, int x, int y, int w, int h );
void R_Draw_Fill( int x, int y, int w, int h, color3_t c );
void R_Draw_Blend( int x, int y, int w, int h, color4_t c );
void InitImmediateModeGL();
int iphoneRotateForLandscape();
void iphoneCheckForLandscapeReverse();
void iphonePacifierUpdate();
void iphoneDrawScreen();
extern int damageflash;
extern int bonusFrameNum;
extern int attackDirTime[2];
#define HF_DISABLED 1
#define HF_NODRAW 2 // invisible button
typedef struct {
int x, y; // mdpoint
int drawWidth, drawHeight;
int touchWidth, touchHeight; // allow touches outside the actual bounds
pkTexture_t *texture;
boolean drawAsLimit; // draw with red tint to show further movement won't do anything
float touchState;
float drawState; // offsets for rotors
int hudFlags;
struct touch_s *touch;
} hudPic_t;
typedef struct {
hudPic_t forwardStick;
hudPic_t sideStick;
hudPic_t turnStick;
hudPic_t turnRotor;
hudPic_t fire;
hudPic_t menu;
hudPic_t map;
hudPic_t weaponSelect;
} hud_t;
extern hud_t huds;
void HudSetForScheme( int schemeNum );
void HudSetTexnums();
void HudEditFrame();
void Sound_StartLocalSound( const char *sound );
void Sound_StartLocalSoundAtVolume( const char *sound, float volume );
int BackButton();
void ResumeGame();
//---------------------------------------
// Touch and button
//---------------------------------------
typedef struct touch_s {
boolean down;
int x, y;
int prevX, prevY; // will be set to x, y on first touch, copied after each game frame
int stateCount; // set to 1 on first event that state changes, incremented each game frame
void *controlOwner;
void *identification;
} touch_t;
#define MAX_TOUCHES 5
extern touch_t sysTouches[MAX_TOUCHES];
extern touch_t gameTouches[MAX_TOUCHES];
extern pthread_mutex_t eventMutex; // used to sync between game and event threads
touch_t *TapInBounds( int x, int y, int w, int h );
touch_t *TouchInBounds( int x, int y, int w, int h );
touch_t *UpdateHudTouch( hudPic_t *hud );
typedef struct {
pkTexture_t *texture;
const char *title;
int x, y, w, h;
touch_t *touch;
float scale; // ramps up and down after touches
int frameNum; // reset scale if not checked on previous frame
} ibutton_t;
void SetButtonPics( ibutton_t *button, const char *picName, const char *title, int x, int y );
void SetButtonText( ibutton_t *button, const char *title, int x, int y, int w, int h );
boolean HandleButton( ibutton_t *button );
//---------------------------------------
// Doom stuff we call directly
//---------------------------------------
void G_DoSaveGame (boolean menu);
//---------------------------------------
// iphone_mapSelect.c
//---------------------------------------
void DisplayLoadingScreen();
void iphoneMapSelectMenu();
//---------------------------------------
// interfaces from the original game code
//---------------------------------------
void iphoneSetNotifyText( const char *str, ... );
void iphoneIntermission( wbstartstruct_t* wbstartstruct );
//---------------------------------------
// interfaces to Objective-C land
//---------------------------------------
// The event thread will fill this after hitting enter
// on the console. The game thread should check it,
// execute it, and clear it under mutex.
extern char consoleCommand[1024];
void SysIPhoneSwapBuffers();
void SysIPhoneVibrate();
void SysIPhoneOpenURL( const char *url );
void SysIPhoneSetUIKitOrientation( int isLandscapeRight );
const char * SysIPhoneGetConsoleTextField();
void SysIPhoneSetConsoleTextField(const char *);
void SysIPhoneInitAudioSession();
int SysIPhoneOtherAudioIsPlaying();
int SysIphoneMilliseconds();
int SysIphoneMicroseconds();
const char * SysIphoneGetAppDir();
const char * SysIphoneGetDocDir();
//---------------------------------------
// interfaces from Objective-C land
//---------------------------------------
void iphoneStartup();
void iphoneShutdown();
void iphoneFrame();
void iphoneTiltEvent( float *tilts );
void iphoneTouchEvent( int numTouches, int touches[16] );
void iphoneActivateConsole();
void iphoneDeactivateConsole();
void iphoneExecuteCommandLine();

View file

@ -0,0 +1,49 @@
/*
Copyright (C) 2009 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#import <UIKit/UIKit.h>
#include <unistd.h>
#include <string.h>
extern char iphoneAppDirectory[1024];
extern int myargc;
extern char **myargv;
int main(int argc, char *argv[]) {
// save for doom
myargc = argc;
myargv = argv;
// get the app directory based on argv[0]
strcpy( iphoneAppDirectory, argv[0] );
int len = strlen( iphoneAppDirectory );
for( int i = len-1; i >= 0; i-- ) {
if ( iphoneAppDirectory[i] == '/' ) {
iphoneAppDirectory[i] = 0;
break;
}
iphoneAppDirectory[i] = 0;
}
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}

View file

@ -0,0 +1,56 @@
/*
* misc.c
* doom
*
* Created by John Carmack on 4/13/09.
* Copyright 2009 idSoftware. All rights reserved.
*
*/
#include "../doomiphone.h"
void Com_Printf( const char *fmt, ... ) {
va_list argptr;
va_start( argptr, fmt );
vprintf( fmt, argptr );
va_end( argptr );
}
void Com_Error( const char *fmt, ... ) {
va_list argptr;
va_start( argptr, fmt );
vprintf( fmt, argptr );
va_end( argptr );
// drop into the editor
abort();
exit( 1 );
}
char *va( const char *format, ... ) {
va_list argptr;
static char string[ 1024 ];
va_start( argptr, format );
(void)vsnprintf( string, sizeof( string ), format, argptr );
va_end( argptr );
string[ sizeof( string ) - 1 ] = '\0';
return string;
}
int HashString( const char *string ) {
int hash = *string;
if( hash ) {
for( string += 1; *string != '\0'; ++string ) {
hash = (hash << 5) - hash + tolower(*string);
}
}
return hash;
}

View file

@ -0,0 +1,54 @@
/*
* misc.h
* doom
*
* Created by John Carmack on 4/13/09.
* Copyright 2009 idSoftware. All rights reserved.
*
*/
char *va( const char *format, ... );
void Com_Printf( const char *fmt, ... );
void Com_Error( const char *fmt, ... );
int HashString( const char *string );
/*
Command execution takes a NUL-terminated string, breaks it into tokens,
then searches for a command or variable that matches the first token.
*/
typedef void (*xcommand_t) (void);
// called by the init functions of other parts of the program to
// register commands and functions to call for them.
// The cmd_name is referenced later, so it should not be in temp memory
// if function is NULL, the command will be forwarded to the server
// as a clc_stringcmd instead of executed locally
void Cmd_AddCommand( const char *cmd_name, xcommand_t function );
// print all the added commands
void Cmd_ListCommands_f();
// attempts to match a partial command for automatic command line completion
// returns NULL if nothing fits
char *Cmd_CompleteCommand( const char *partial );
// The functions that execute commands get their parameters with these
// functions. Cmd_Argv () will return an empty string, not a NULL
// if arg > argc, so string operations are always safe.
int Cmd_Argc( void );
const char *Cmd_Argv( int arg );
// Takes a NUL-terminated string. Does not need to be /n terminated.
// breaks the string up into argc / argv tokens.
void Cmd_TokenizeString( const char *text );
// Parses a single line of text into arguments and tries to execute it
// as if it was typed at the console
void Cmd_ExecuteString( const char *text );
// execute each line of the config file
void Cmd_ExecuteFile( const char *fullPathName );

View file

@ -0,0 +1,344 @@
/*
* prboomInterface.c
* doom
*
* Created by John Carmack on 4/14/09.
* Copyright 2009 Id Software. All rights reserved.
*
* Stuff to get prboom to compile without SDL
*/
#include "../doomiphone.h"
int desired_fullscreen;
int usejoystick;
int joyright;
int joyleft;
int joydown;
int joyup;
int gl_colorbuffer_bits;
int gl_depthbuffer_bits;
int snd_card;
int mus_card;
int endoom_mode;
int use_fullscreen;
int snd_samplerate;
int ms_to_next_tick;
int realtic_clock_rate;
/* I_SafeExit
* This function is called instead of exit() by functions that might be called
* during the exit process (i.e. after exit() has already been called)
* Prevent infinitely recursive exits -- killough
*
* JDC: we don't do any atexit() calls on iphone, so this shouldn't be necessary
*/
void I_SafeExit(int rc) {
static int has_exited;
if (!has_exited) {
has_exited=rc ? 2 : 1;
exit(rc);
}
}
void I_uSleep( unsigned long usec ) {
usleep( usec );
}
/*
* HasTrailingSlash
*
* cphipps - simple test for trailing slash on dir names
*/
boolean HasTrailingSlash(const char* dn)
{
return ( (dn[strlen(dn)-1] == '/') );
}
char* I_FindFile(const char* wfname, const char* ext)
{
char *p = malloc( 1024 );
sprintf( p, "%s/base/%s", SysIphoneGetAppDir(), wfname );
if (access(p,F_OK))
strcat(p, ext); // try adding the extension
if (!access(p,F_OK)) {
lprintf(LO_INFO, " found %s\n", p);
return p;
}
free( p );
return NULL;
#if 0
// lookup table of directories to search
static const struct {
const char *dir; // directory
const char *sub; // subdirectory
const char *env; // environment variable
const char *(*func)(void); // for I_DoomExeDir
} search[] = {
{NULL}, // current working directory
{NULL, NULL, "DOOMWADDIR"}, // run-time $DOOMWADDIR
{DOOMWADDIR}, // build-time configured DOOMWADDIR
{NULL, "doom", "HOME"}, // ~/doom
{NULL, NULL, "HOME"}, // ~
{NULL, NULL, NULL, I_DoomExeDir}, // config directory
{"/usr/local/share/games/doom"},
{"/usr/share/games/doom"},
{"/usr/local/share/doom"},
{"/usr/share/doom"},
};
int i;
/* Precalculate a length we will need in the loop */
size_t pl = strlen(wfname) + strlen(ext) + 4;
for (i = 0; i < sizeof(search)/sizeof(*search); i++) {
char * p;
const char * d = NULL;
const char * s = NULL;
/* Each entry in the switch sets d to the directory to look in,
* and optionally s to a subdirectory of d */
// switch replaced with lookup table
if (search[i].env) {
if (!(d = getenv(search[i].env)))
continue;
} else if (search[i].func)
d = search[i].func();
else
d = search[i].dir;
s = search[i].sub;
p = malloc((d ? strlen(d) : 0) + (s ? strlen(s) : 0) + pl);
sprintf(p, "%s%s%s%s%s", d ? d : "", (d && !HasTrailingSlash(d)) ? "/" : "",
s ? s : "", (s && !HasTrailingSlash(s)) ? "/" : "",
wfname);
if (access(p,F_OK))
strcat(p, ext);
if (!access(p,F_OK)) {
lprintf(LO_INFO, " found %s\n", p);
return p;
}
free(p);
}
return NULL;
#endif
}
boolean I_StartDisplay(void) {
return true;
}
void I_EndDisplay(void) {}
int I_GetTime_RealTime(void) { return 0; }
fixed_t I_GetTimeFrac (void) { return 0; }
void I_GetTime_SaveMS(void) {}
unsigned long I_GetRandomTimeSeed(void) { return 0; }
//const char* I_GetVersionString(char* buf, size_t sz);
//const char* I_SigString(char* buf, size_t sz, int signum);
const char *I_DoomExeDir(void) { return SysIphoneGetAppDir(); }
//void I_SetAffinityMask(void);
/*
* I_Read
*
* cph 2001/11/18 - wrapper for read(2) which handles partial reads and aborts
* on error.
*/
void I_Read(int fd, void* vbuf, size_t sz)
{
unsigned char* buf = vbuf;
while (sz) {
int rc = read(fd,buf,sz);
if (rc <= 0) {
I_Error("I_Read: read failed: %s", rc ? strerror(errno) : "EOF");
}
sz -= rc; buf += rc;
}
}
/*
* I_Filelength
*
* Return length of an open file.
*/
int I_Filelength(int handle)
{
struct stat fileinfo;
if (fstat(handle,&fileinfo) == -1)
I_Error("I_Filelength: %s",strerror(errno));
return fileinfo.st_size;
}
//
// MUSIC I/O
//
void I_InitMusic(void) {}
void I_ShutdownMusic(void) {}
void I_UpdateMusic(void) {}
// Volume.
void I_SetMusicVolume(int volume) {}
// PAUSE game handling.
void I_PauseSong(int handle) {}
void I_ResumeSong(int handle) {}
// Registers a song handle to song data.
int I_RegisterSong(const void *data, size_t len) {
return 0;
}
// cournia - tries to load a music file
int I_RegisterMusic( const char* filename, musicinfo_t *music ) {
return 0;
}
// Called by anything that wishes to start music.
// plays a song, and when the song is done,
// starts playing it again in an endless loop.
// Horrible thing to do, considering.
void I_PlaySong(int handle, int looping) {
}
// Stops a song over 3 seconds.
void I_StopSong(int handle) {
}
// See above (register), then think backwards
void I_UnRegisterSong(int handle) {
}
void I_PreInitGraphics(void){}
void I_CalculateRes(unsigned int width, unsigned int height){}
void I_ShutdownGraphics(void){}
void I_SetPalette(int pal){}
void I_UpdateNoBlit (void){}
void I_FinishUpdate (void){}
int I_ScreenShot (const char *fname){return 0;}
// CPhipps -
// I_SetRes
// Sets the screen resolution
void I_SetRes(void)
{
int i;
I_CalculateRes(SCREENWIDTH, SCREENHEIGHT);
// set first three to standard values
for (i=0; i<3; i++) {
screens[i].width = SCREENWIDTH;
screens[i].height = SCREENHEIGHT;
screens[i].byte_pitch = SCREENPITCH;
screens[i].short_pitch = SCREENPITCH / V_GetModePixelDepth(VID_MODE16);
screens[i].int_pitch = SCREENPITCH / V_GetModePixelDepth(VID_MODE32);
}
// statusbar
screens[4].width = SCREENWIDTH;
screens[4].height = (ST_SCALED_HEIGHT+1);
screens[4].byte_pitch = SCREENPITCH;
screens[4].short_pitch = SCREENPITCH / V_GetModePixelDepth(VID_MODE16);
screens[4].int_pitch = SCREENPITCH / V_GetModePixelDepth(VID_MODE32);
lprintf(LO_INFO,"I_SetRes: Using resolution %dx%d\n", SCREENWIDTH, SCREENHEIGHT);
}
void I_UpdateVideoMode(void)
{
lprintf(LO_INFO, "I_UpdateVideoMode: %dx%d\n", SCREENWIDTH, SCREENHEIGHT );
V_InitMode(VID_MODEGL);
I_SetRes();
#if 0
screens[0].not_on_heap = true;
screens[0].data = NULL;
screens[0].byte_pitch = screen->pitch;
screens[0].short_pitch = screen->pitch / V_GetModePixelDepth(VID_MODE16);
screens[0].int_pitch = screen->pitch / V_GetModePixelDepth(VID_MODE32);
#endif
V_AllocScreens();
R_InitBuffer(SCREENWIDTH, SCREENHEIGHT);
gld_Init(SCREENWIDTH, SCREENHEIGHT);
}
void I_InitGraphics(void)
{
char titlebuffer[2048];
static int firsttime=1;
SCREENWIDTH = 480;
SCREENHEIGHT = 320;
if (firsttime)
{
firsttime = 0;
atexit(I_ShutdownGraphics);
lprintf(LO_INFO, "I_InitGraphics: %dx%d\n", SCREENWIDTH, SCREENHEIGHT);
/* Set the video mode */
I_UpdateVideoMode();
/* Setup the window title */
strcpy(titlebuffer,PACKAGE);
strcat(titlebuffer," ");
strcat(titlebuffer,VERSION);
// SDL_WM_SetCaption(titlebuffer, titlebuffer);
/* Initialize the input system */
// I_InitInputs();
}
}
/* I_StartTic
* Called by D_DoomLoop,
* called before processing each tic in a frame.
* Quick syncronous operations are performed here.
* Can call D_PostEvent.
*/
void I_StartTic (void){}
/* I_StartFrame
* Called by D_DoomLoop,
* called before processing any tics in a frame
* (just after displaying a frame).
* Time consuming syncronous operations
* are performed here (joystick reading).
* Can call D_PostEvent.
*/
void I_StartFrame (void){}
void I_Init(){}
unsigned int SDL_GetTicks() { return 0; };
int (*I_GetTime)(void) = I_GetTime_RealTime;

View file

@ -1,12 +1,7 @@
/*
* BackgroundMusic.cpp
* doom
*
* Created by John Carmack on 5/15/09.
* Copyright 2009 Id Software. All rights reserved.
*
*/
/*
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
@ -321,6 +316,7 @@ end:
OSStatus BackgroundTrackMgr::SetupQueue(BG_FileInfo *inFileInfo) {
UInt32 size = 0;
OSStatus err;
OSStatus result = AudioQueueNewOutput(&inFileInfo->mFileFormat, QueueCallback, this,
CFRunLoopGetMain() /* CFRunLoopGetCurrent() */, kCFRunLoopCommonModes, 0, &mQueue);
AssertNoError("Error creating queue", end);
@ -339,7 +335,7 @@ OSStatus BackgroundTrackMgr::SetupQueue(BG_FileInfo *inFileInfo) {
}
#endif
// channel layout
OSStatus err = AudioFileGetPropertyInfo(inFileInfo->mAFID, kAudioFilePropertyChannelLayout, &size, NULL);
err = AudioFileGetPropertyInfo(inFileInfo->mAFID, kAudioFilePropertyChannelLayout, &size, NULL);
if (err == noErr && size > 0) {
AudioChannelLayout *acl = (AudioChannelLayout *)malloc(size);
result = AudioFileGetProperty(inFileInfo->mAFID, kAudioFilePropertyChannelLayout, &size, acl);
@ -360,6 +356,7 @@ OSStatus BackgroundTrackMgr::SetupBuffers(BG_FileInfo *inFileInfo) {
int numBuffersToQueue = kNumberBuffers;
UInt32 maxPacketSize;
UInt32 size = sizeof(maxPacketSize);
bool isFormatVBR;
// we need to calculate how many packets we read at a time, and how big a buffer we need
// we base this on the size of the packets in the file and an approximate duration for each buffer
@ -367,7 +364,7 @@ OSStatus BackgroundTrackMgr::SetupBuffers(BG_FileInfo *inFileInfo) {
// than our allocation default size, that needs to become larger
OSStatus result = AudioFileGetProperty(inFileInfo->mAFID, kAudioFilePropertyPacketSizeUpperBound, &size, &maxPacketSize);
AssertNoError("Error getting packet upper bound size", end);
bool isFormatVBR = (inFileInfo->mFileFormat.mBytesPerPacket == 0 || inFileInfo->mFileFormat.mFramesPerPacket == 0);
isFormatVBR = (inFileInfo->mFileFormat.mBytesPerPacket == 0 || inFileInfo->mFileFormat.mFramesPerPacket == 0);
CalculateBytesForTime(inFileInfo->mFileFormat, maxPacketSize, 0.5/*seconds*/, &mBufferByteSize, &mNumPacketsToRead);
@ -489,11 +486,13 @@ static BackgroundTrackMgr sBackgroundTrackMgr;
static char currentMusicName[1024];
void iphonePauseMusic() {
if ( music->value == 0 ) {
// music is disabled
return;
}
AudioQueuePause(sBackgroundTrackMgr.mQueue);
if( music ) {
if ( music->value == 0 ) {
// music is disabled
return;
}
AudioQueuePause(sBackgroundTrackMgr.mQueue);
}
}
void iphoneResumeMusic() {
if ( music->value == 0 ) {

View file

@ -0,0 +1,47 @@
/*
=======================================================================================
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company. All Right Reserved.
This file is part of the DOOM Classic iOS v2.1 GPL Source Code.
=======================================================================================
*/
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
@interface ControlsMenuView : UIView {
IBOutlet UISlider * movestickSize;
IBOutlet UISlider * turnstickSize;
IBOutlet UISlider * tiltMoveSpeed;
IBOutlet UISlider * tiltTurnSpeed;
IBOutlet UIButton * singleThumbButton;
IBOutlet UIButton * dualThumbButton;
IBOutlet UIButton * dirWheelButton;
}
- (void) SetupSlider:(UISlider*)slider minimumTrack:(UIImage*)minImage
maximumTrack:(UIImage*)maxImage
thumb:(UIImage*)thumbImage;
- (void) SetOptions;
- (IBAction) BackToMain;
- (IBAction) HudLayoutPressed;
- (IBAction) SingleThumbpadPressed;
- (IBAction) DualThumbpadPressed;
- (IBAction) DirWheelPressed;
- (IBAction) MoveStickValChanged;
- (IBAction) TurnStickValChanged;
- (IBAction) TiltMoveValChanged;
- (IBAction) TiltTurnValChanged;
@end

View file

@ -0,0 +1,234 @@
/*
=======================================================================================
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company. All Right Reserved.
This file is part of the DOOM Classic iOS v2.1 GPL Source Code.
=======================================================================================
*/
#import "ControlsMenuView.h"
#import "doomAppDelegate.h"
#include "doomiphone.h"
@implementation ControlsMenuView
- (void) SetOptions {
movestickSize.value = stickMove->value / 255;
turnstickSize.value = stickTurn->value / 255;
tiltMoveSpeed.value = tiltMove->value;
tiltTurnSpeed.value = tiltTurn->value;
if( controlScheme->value == 0 ) {
singleThumbButton.enabled = NO;
dualThumbButton.enabled = YES;
dirWheelButton.enabled = YES;
} else if( controlScheme->value == 1 ) {
singleThumbButton.enabled = YES;
dualThumbButton.enabled = NO;
dirWheelButton.enabled = YES;
} else if( controlScheme->value == 2 ) {
singleThumbButton.enabled = YES;
dualThumbButton.enabled = YES;
dirWheelButton.enabled = NO;
}
}
- (void) SetupSlider:(UISlider*)slider minimumTrack:(UIImage*)minImage
maximumTrack:(UIImage*)maxImage
thumb:(UIImage*)thumbImage {
[slider setMinimumTrackImage:minImage forState:UIControlStateNormal];
[slider setMaximumTrackImage:maxImage forState:UIControlStateNormal];
[slider setThumbImage:thumbImage forState:UIControlStateNormal];
[slider setThumbImage:thumbImage forState:UIControlStateHighlighted];
}
- (void) initialize{
// Minimum track image setup.
UIImage* minimumTrackImage = [UIImage imageNamed:@"SliderBar.png"];
CGFloat minimumTrackImageCap = minimumTrackImage.size.width * 0.5f;
UIImage* minimumTrackImageCapped = [minimumTrackImage stretchableImageWithLeftCapWidth:minimumTrackImageCap topCapHeight: 0.0f];
// Maximum track image setup.
UIImage* maximumTrackImage = [UIImage imageNamed:@"SliderBackground.png"];
CGFloat maximumTrackImageCap = maximumTrackImage.size.width * 0.5f;
UIImage* maximumTrackImageCapped = [maximumTrackImage stretchableImageWithLeftCapWidth:maximumTrackImageCap topCapHeight: 0.0f];
// Thumb image.
UIImage* thumbImage = [UIImage imageNamed:@"SliderSkull.png"];
// Set up slider instances.
[self SetupSlider:movestickSize minimumTrack:minimumTrackImageCapped
maximumTrack:maximumTrackImageCapped
thumb:thumbImage];
[self SetupSlider:turnstickSize minimumTrack:minimumTrackImageCapped
maximumTrack:maximumTrackImageCapped
thumb:thumbImage];
[self SetupSlider:tiltMoveSpeed minimumTrack:minimumTrackImageCapped
maximumTrack:maximumTrackImageCapped
thumb:thumbImage];
[self SetupSlider:tiltTurnSpeed minimumTrack:minimumTrackImageCapped
maximumTrack:maximumTrackImageCapped
thumb:thumbImage];
}
- (void)awakeFromNib {
[self initialize];
}
- (id) initWithCoder:(NSCoder *)aCoder{
if(self = [super initWithCoder:aCoder] ) {
[self initialize];
}
return self;
}
- (id) initWithFrame:(CGRect)rect{
if(self = [super initWithFrame:rect] ) {
[self initialize];
}
return self;
}
- (IBAction) BackToMain {
[gAppDelegate MainMenu];
Sound_StartLocalSound( "iphone/controller_down_01_SILENCE.wav" );
}
- (IBAction) HudLayoutPressed {
[ gAppDelegate HUDLayout ];
}
- (IBAction) SingleThumbpadPressed {
Cvar_SetValue( controlScheme->name, 0 );
HudSetForScheme( 0 );
if( controlScheme->value == 0 ) {
singleThumbButton.enabled = NO;
dualThumbButton.enabled = YES;
dirWheelButton.enabled = YES;
} else if( controlScheme->value == 1 ) {
singleThumbButton.enabled = YES;
dualThumbButton.enabled = NO;
dirWheelButton.enabled = YES;
} else if( controlScheme->value == 2 ) {
singleThumbButton.enabled = YES;
dualThumbButton.enabled = YES;
dirWheelButton.enabled = NO;
}
}
- (IBAction) DualThumbpadPressed {
Cvar_SetValue( controlScheme->name, 1 );
HudSetForScheme( 1 );
if( controlScheme->value == 0 ) {
singleThumbButton.enabled = NO;
dualThumbButton.enabled = YES;
dirWheelButton.enabled = YES;
} else if( controlScheme->value == 1 ) {
singleThumbButton.enabled = YES;
dualThumbButton.enabled = NO;
dirWheelButton.enabled = YES;
} else if( controlScheme->value == 2 ) {
singleThumbButton.enabled = YES;
dualThumbButton.enabled = YES;
dirWheelButton.enabled = NO;
}
}
- (IBAction) DirWheelPressed {
Cvar_SetValue( controlScheme->name, 2 );
HudSetForScheme( 2 );
if( controlScheme->value == 0 ) {
singleThumbButton.enabled = NO;
dualThumbButton.enabled = YES;
dirWheelButton.enabled = YES;
} else if( controlScheme->value == 1 ) {
singleThumbButton.enabled = YES;
dualThumbButton.enabled = NO;
dirWheelButton.enabled = YES;
} else if( controlScheme->value == 2 ) {
singleThumbButton.enabled = YES;
dualThumbButton.enabled = YES;
dirWheelButton.enabled = NO;
}
}
- (IBAction) MoveStickValChanged {
Cvar_SetValue( stickMove->name, movestickSize.value * 256.0f );
}
- (IBAction) TurnStickValChanged {
Cvar_SetValue( stickTurn->name, turnstickSize.value * 256.0f );
}
- (IBAction) TiltMoveValChanged {
Cvar_SetValue( tiltMove->name, tiltMoveSpeed.value );
if ( tiltMove->value == 100 ) {
Cvar_SetValue( tiltMove->name, 0 );
tiltMoveSpeed.value = tiltMove->value;
}
if ( tiltMove->value ) {
Cvar_SetValue( tiltTurn->name, 0 );
tiltTurnSpeed.value = tiltTurn->value;
}
}
- (IBAction) TiltTurnValChanged {
Cvar_SetValue( tiltTurn->name, tiltTurnSpeed.value );
if ( tiltTurn->value == 1500 ) {
Cvar_SetValue( tiltTurn->name, 0 );
tiltTurnSpeed.value = tiltTurn->value;
}
if ( tiltTurn->value ) {
Cvar_SetValue( tiltMove->name, 0 );
tiltMoveSpeed.value = tiltMove->value;
}
}
@end

View file

@ -0,0 +1,11 @@
K 10
svn:ignore
V 32
cass.pbxuser
cass.perspectivev3
K 13
svn:mergeinfo
V 0
END

View file

@ -0,0 +1,62 @@
9
dir
119
svn://svn.eden.idsoftware.com/iphone/trunk/doom/code/iphone/doom.xcodeproj
svn://svn.eden.idsoftware.com/iphone
2009-07-09T01:53:18.542124Z
115
johnc
has-props
svn:special svn:externals svn:needs-lock
b138b6a2-c55d-40dd-9022-e27c2c4ed457
project.pbxproj
file
2009-07-09T01:33:43.000000Z
78569cb9feb1c9c991c2d5376879d32a
2009-07-09T01:53:18.542124Z
115
johnc
has-props
84338

View file

@ -0,0 +1 @@
9

View file

@ -0,0 +1,5 @@
K 14
svn:executable
V 1
*
END

File diff suppressed because it is too large Load diff

View file

@ -211,6 +211,7 @@
<string>active-combo-popup</string>
<string>action</string>
<string>NSToolbarFlexibleSpaceItem</string>
<string>debugger-enable-breakpoints</string>
<string>build-and-go</string>
<string>com.apple.ide.PBXToolbarStopButton</string>
<string>get-info</string>
@ -234,7 +235,6 @@
<array>
<string>1C37FBAC04509CD000000102</string>
<string>1C37FAAC04509CD000000102</string>
<string>1C08E77C0454961000C914BD</string>
<string>1C37FABC05509CD000000102</string>
<string>1C37FABC05539CD112110102</string>
<string>E2644B35053B69B200211256</string>
@ -266,6 +266,8 @@
<string>29B97314FDCFA39411CA2CEA</string>
<string>29B97315FDCFA39411CA2CEA</string>
<string>29B97317FDCFA39411CA2CEA</string>
<string>29B97323FDCFA39411CA2CEA</string>
<string>43E8D4DF0F51B48B003F09B2</string>
<string>19C28FACFE9D520D11CA2CBB</string>
<string>1C37FBAC04509CD000000102</string>
<string>1C37FABC05509CD000000102</string>
@ -273,13 +275,12 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array>
<array>
<integer>7</integer>
<integer>1</integer>
<integer>0</integer>
<integer>54</integer>
<integer>53</integer>
</array>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 0}, {186, 717}}</string>
<string>{{0, 81}, {186, 973}}</string>
</dict>
<key>PBXTopSmartGroupGIDs</key>
<array/>
@ -291,14 +292,14 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {203, 735}}</string>
<string>{{0, 0}, {203, 991}}</string>
<key>GroupTreeTableConfiguration</key>
<array>
<string>MainColumn</string>
<real>186</real>
</array>
<key>RubberWindowFrame</key>
<string>29 227 931 776 0 0 1680 1028 </string>
<string>0 145 877 1032 0 0 1920 1178 </string>
</dict>
<key>Module</key>
<string>PBXSmartGroupTreeModule</string>
@ -316,7 +317,7 @@
<key>PBXProjectModuleGUID</key>
<string>1CE0B20306471E060097A5F4</string>
<key>PBXProjectModuleLabel</key>
<string>iphone_sound.c</string>
<string>BackgroundMusic.cpp</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
@ -324,49 +325,26 @@
<key>PBXProjectModuleGUID</key>
<string>1CE0B20406471E060097A5F4</string>
<key>PBXProjectModuleLabel</key>
<string>iphone_sound.c</string>
<string>BackgroundMusic.cpp</string>
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
<string>EDFDF9C810A2114E0071CB9B</string>
<string>EDD2765D11C2B634004A9B9B</string>
<key>history</key>
<array>
<string>ED9BABDF1083850C00166CDA</string>
<string>ED2D127F10838A65003A9380</string>
<string>ED9AB3E410967730000B5852</string>
<string>ED9AB3E510967730000B5852</string>
<string>ED9AB3E610967730000B5852</string>
<string>ED9AB3E710967730000B5852</string>
<string>ED9AB3E910967730000B5852</string>
<string>EDAFC7F4109A575F002C3487</string>
<string>EDAFC7F5109A575F002C3487</string>
<string>EDAFC818109A5B94002C3487</string>
<string>EDAFC819109A5B94002C3487</string>
<string>EDFDF9B310A2054E0071CB9B</string>
<string>EDFDF9B410A2054E0071CB9B</string>
<string>EDFDF9C110A205F50071CB9B</string>
<string>EDFDF9C310A205F50071CB9B</string>
</array>
<key>nextStack</key>
<array>
<string>EDFDF9C410A205F50071CB9B</string>
</array>
<key>prevStack</key>
<array>
<string>ED9BABE11083850C00166CDA</string>
<string>ED9BABE21083850C00166CDA</string>
<string>ED2D128210838A65003A9380</string>
<string>ED9AB3EC10967730000B5852</string>
<string>ED9AB3ED10967730000B5852</string>
<string>ED9AB3EF10967730000B5852</string>
<string>ED9AB3F210967730000B5852</string>
<string>ED9AB3F310967730000B5852</string>
<string>EDAFC7F7109A575F002C3487</string>
<string>EDAFC7F8109A575F002C3487</string>
<string>EDAFC7F9109A575F002C3487</string>
<string>EDAFC81B109A5B94002C3487</string>
<string>EDFDF9B610A2054E0071CB9B</string>
<string>EDFDF9B710A2054E0071CB9B</string>
<string>ED60B15110B61ADE003A8B9F</string>
<string>ED60B15210B61ADE003A8B9F</string>
<string>ED80ABFC10E930AC006AAD9D</string>
<string>EDA4D0A6110A1FCD0014EF0F</string>
<string>EDD2763611C2B43F004A9B9B</string>
<string>EDD2763711C2B43F004A9B9B</string>
</array>
</dict>
<key>SplitCount</key>
@ -378,14 +356,14 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {723, 653}}</string>
<string>{{0, 0}, {669, 899}}</string>
<key>RubberWindowFrame</key>
<string>29 227 931 776 0 0 1680 1028 </string>
<string>0 145 877 1032 0 0 1920 1178 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
<string>653pt</string>
<string>899pt</string>
</dict>
<dict>
<key>ContentConfiguration</key>
@ -398,18 +376,18 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 658}, {723, 77}}</string>
<string>{{0, 904}, {669, 87}}</string>
<key>RubberWindowFrame</key>
<string>29 227 931 776 0 0 1680 1028 </string>
<string>0 145 877 1032 0 0 1920 1178 </string>
</dict>
<key>Module</key>
<string>XCDetailModule</string>
<key>Proportion</key>
<string>77pt</string>
<string>87pt</string>
</dict>
</array>
<key>Proportion</key>
<string>723pt</string>
<string>669pt</string>
</dict>
</array>
<key>Name</key>
@ -424,12 +402,14 @@
</array>
<key>TableOfContents</key>
<array>
<string>EDFDF99810A203830071CB9B</string>
<string>EDD2763911C2B43F004A9B9B</string>
<string>1CE0B1FE06471DED0097A5F4</string>
<string>EDFDF99910A203830071CB9B</string>
<string>EDD2763A11C2B43F004A9B9B</string>
<string>1CE0B20306471E060097A5F4</string>
<string>1CE0B20506471E060097A5F4</string>
</array>
<key>ToolbarConfigUserDefaultsMinorVersion</key>
<string>2</string>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.defaultV3</string>
</dict>
@ -560,16 +540,15 @@
<integer>5</integer>
<key>WindowOrderList</key>
<array>
<string>EDFDF9BB10A2054E0071CB9B</string>
<string>EDFDF9BC10A2054E0071CB9B</string>
<string>EDD2765E11C2B634004A9B9B</string>
<string>EDD2765F11C2B634004A9B9B</string>
<string>1CD10A99069EF8BA00B06720</string>
<string>ED9BABAD108380C600166CDA</string>
<string>1C78EAAD065D492600B07095</string>
<string>1C530D57069F1CE1000CFCEE</string>
<string>/Users/greghodges/doom/code/iphone/Doom.xcodeproj</string>
<string>/Volumes/Work/idMobileDepot/DoomClassicDepot/code/iphone/Doom.xcodeproj</string>
</array>
<key>WindowString</key>
<string>29 227 931 776 0 0 1680 1028 </string>
<string>0 145 877 1032 0 0 1920 1178 </string>
<key>WindowToolsV3</key>
<array>
<dict>
@ -590,29 +569,31 @@
<key>PBXProjectModuleGUID</key>
<string>1CD0528F0623707200166675</string>
<key>PBXProjectModuleLabel</key>
<string></string>
<string>BackgroundMusic.cpp</string>
<key>StatusBarVisibility</key>
<true/>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {500, 218}}</string>
<string>{{0, 0}, {1073, 761}}</string>
<key>RubberWindowFrame</key>
<string>103 475 500 500 0 0 1680 1028 </string>
<string>124 183 1073 925 0 0 1920 1178 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
<string>218pt</string>
<string>761pt</string>
</dict>
<dict>
<key>BecomeActive</key>
<true/>
<key>ContentConfiguration</key>
<dict>
<key>PBXProjectModuleGUID</key>
<string>XCMainBuildResultsModuleGUID</string>
<key>PBXProjectModuleLabel</key>
<string>Build</string>
<string>Build Results</string>
<key>XCBuildResultsTrigger_Collapse</key>
<integer>1021</integer>
<key>XCBuildResultsTrigger_Open</key>
@ -621,18 +602,18 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 223}, {500, 236}}</string>
<string>{{0, 766}, {1073, 118}}</string>
<key>RubberWindowFrame</key>
<string>103 475 500 500 0 0 1680 1028 </string>
<string>124 183 1073 925 0 0 1920 1178 </string>
</dict>
<key>Module</key>
<string>PBXBuildResultsModule</string>
<key>Proportion</key>
<string>236pt</string>
<string>118pt</string>
</dict>
</array>
<key>Proportion</key>
<string>459pt</string>
<string>884pt</string>
</dict>
</array>
<key>Name</key>
@ -646,14 +627,14 @@
<key>TableOfContents</key>
<array>
<string>ED9BABAD108380C600166CDA</string>
<string>EDFDF99A10A203830071CB9B</string>
<string>EDD2761111C2B1AF004A9B9B</string>
<string>1CD0528F0623707200166675</string>
<string>XCMainBuildResultsModuleGUID</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.buildV3</string>
<key>WindowString</key>
<string>103 475 500 500 0 0 1680 1028 </string>
<string>124 183 1073 925 0 0 1920 1178 </string>
<key>WindowToolGUID</key>
<string>ED9BABAD108380C600166CDA</string>
<key>WindowToolIsVisible</key>
@ -688,8 +669,8 @@
<string>yes</string>
<key>sizes</key>
<array>
<string>{{0, 0}, {316, 203}}</string>
<string>{{316, 0}, {378, 203}}</string>
<string>{{0, 0}, {347, 190}}</string>
<string>{{0, 190}, {347, 191}}</string>
</array>
</dict>
<key>VerticalSplitView</key>
@ -704,8 +685,8 @@
<string>yes</string>
<key>sizes</key>
<array>
<string>{{0, 0}, {694, 203}}</string>
<string>{{0, 203}, {694, 178}}</string>
<string>{{0, 0}, {347, 381}}</string>
<string>{{347, 0}, {347, 381}}</string>
</array>
</dict>
</dict>
@ -735,15 +716,15 @@
<string>Value</string>
<real>85</real>
<string>Summary</string>
<real>148</real>
<real>117</real>
</array>
<key>Frame</key>
<string>{{316, 0}, {378, 203}}</string>
<string>{{0, 190}, {347, 191}}</string>
<key>RubberWindowFrame</key>
<string>103 553 694 422 0 0 1680 1028 </string>
<string>128 689 694 422 0 0 1920 1178 </string>
</dict>
<key>RubberWindowFrame</key>
<string>103 553 694 422 0 0 1680 1028 </string>
<string>128 689 694 422 0 0 1920 1178 </string>
</dict>
<key>Module</key>
<string>PBXDebugSessionModule</string>
@ -766,18 +747,18 @@
<key>TableOfContents</key>
<array>
<string>1CD10A99069EF8BA00B06720</string>
<string>EDFDF9A510A203BA0071CB9B</string>
<string>EDD2763B11C2B43F004A9B9B</string>
<string>1C162984064C10D400B95A72</string>
<string>EDFDF9A610A203BA0071CB9B</string>
<string>EDFDF9A710A203BA0071CB9B</string>
<string>EDFDF9A810A203BA0071CB9B</string>
<string>EDFDF9A910A203BA0071CB9B</string>
<string>EDFDF9AA10A203BA0071CB9B</string>
<string>EDD2763C11C2B43F004A9B9B</string>
<string>EDD2763D11C2B43F004A9B9B</string>
<string>EDD2763E11C2B43F004A9B9B</string>
<string>EDD2763F11C2B43F004A9B9B</string>
<string>EDD2764011C2B43F004A9B9B</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.debugV3</string>
<key>WindowString</key>
<string>103 553 694 422 0 0 1680 1028 </string>
<string>128 689 694 422 0 0 1920 1178 </string>
<key>WindowToolGUID</key>
<string>1CD10A99069EF8BA00B06720</string>
<key>WindowToolIsVisible</key>
@ -806,25 +787,25 @@
<key>PBXProjectModuleGUID</key>
<string>1CDD528C0622207200134675</string>
<key>PBXProjectModuleLabel</key>
<string>misc.c</string>
<string>iphone_sound.c</string>
<key>StatusBarVisibility</key>
<true/>
</dict>
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {803, 376}}</string>
<string>{{0, 0}, {934, 674}}</string>
<key>RubberWindowFrame</key>
<string>50 252 803 728 0 0 1680 1028 </string>
<string>64 158 934 948 0 0 1920 1178 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
<string>803pt</string>
<string>934pt</string>
</dict>
</array>
<key>Proportion</key>
<string>376pt</string>
<string>674pt</string>
</dict>
<dict>
<key>ContentConfiguration</key>
@ -837,18 +818,18 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 381}, {803, 306}}</string>
<string>{{0, 679}, {934, 228}}</string>
<key>RubberWindowFrame</key>
<string>50 252 803 728 0 0 1680 1028 </string>
<string>64 158 934 948 0 0 1920 1178 </string>
</dict>
<key>Module</key>
<string>PBXProjectFindModule</string>
<key>Proportion</key>
<string>306pt</string>
<string>228pt</string>
</dict>
</array>
<key>Proportion</key>
<string>687pt</string>
<string>907pt</string>
</dict>
</array>
<key>Name</key>
@ -862,13 +843,13 @@
<key>TableOfContents</key>
<array>
<string>1C530D57069F1CE1000CFCEE</string>
<string>EDFDF9B910A2054E0071CB9B</string>
<string>EDFDF9BA10A2054E0071CB9B</string>
<string>EDFA718A1194DF840098FFFC</string>
<string>EDFA718B1194DF840098FFFC</string>
<string>1CDD528C0622207200134675</string>
<string>1CD0528E0623707200166675</string>
</array>
<key>WindowString</key>
<string>50 252 803 728 0 0 1680 1028 </string>
<string>64 158 934 948 0 0 1920 1178 </string>
<key>WindowToolGUID</key>
<string>1C530D57069F1CE1000CFCEE</string>
<key>WindowToolIsVisible</key>
@ -905,7 +886,7 @@
<key>Frame</key>
<string>{{0, 0}, {646, 511}}</string>
<key>RubberWindowFrame</key>
<string>400 464 646 552 0 0 1680 1028 </string>
<string>493 610 646 552 0 0 1920 1178 </string>
</dict>
<key>Module</key>
<string>PBXDebugCLIModule</string>
@ -928,13 +909,13 @@
<key>TableOfContents</key>
<array>
<string>1C78EAAD065D492600B07095</string>
<string>EDFDF9AB10A203BA0071CB9B</string>
<string>EDD2764111C2B43F004A9B9B</string>
<string>1C78EAAC065D492600B07095</string>
</array>
<key>ToolbarConfiguration</key>
<string>xcode.toolbar.config.consoleV3</string>
<key>WindowString</key>
<string>400 464 646 552 0 0 1680 1028 </string>
<string>493 610 646 552 0 0 1920 1178 </string>
<key>WindowToolGUID</key>
<string>1C78EAAD065D492600B07095</string>
<key>WindowToolIsVisible</key>

View file

@ -9,7 +9,7 @@
29B97313FDCFA39411CA2CEA /* Project object */ = {
activeBuildConfigurationName = Debug;
activeExecutable = ED9BAB90108380AC00166CDA /* Doom */;
activeSDKPreference = iphonesimulator2.0;
activeSDKPreference = iphoneos3.0;
activeTarget = 1D6058900D05DD3D006BFB54 /* Doom */;
addToTargets = (
1D6058900D05DD3D006BFB54 /* Doom */,
@ -38,7 +38,7 @@
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
484,
430,
20,
48,
43,
@ -72,7 +72,7 @@
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
444,
390,
60,
20,
48,
@ -89,41 +89,58 @@
PBXFileDataSource_Warnings_ColumnID,
);
};
PBXPerProjectTemplateStateSaveDate = 279053176;
PBXWorkspaceStateSaveDate = 279053176;
PBXPerProjectTemplateStateSaveDate = 297971964;
PBXWorkspaceStateSaveDate = 297971964;
};
perUserProjectItems = {
ED2D127F10838A65003A9380 /* PBXBookmark */ = ED2D127F10838A65003A9380 /* PBXBookmark */;
ED2D128210838A65003A9380 /* PBXBookmark */ = ED2D128210838A65003A9380 /* PBXBookmark */;
ED9AB3E410967730000B5852 /* PlistBookmark */ = ED9AB3E410967730000B5852 /* PlistBookmark */;
ED9AB3E510967730000B5852 /* PBXTextBookmark */ = ED9AB3E510967730000B5852 /* PBXTextBookmark */;
ED9AB3E610967730000B5852 /* PBXTextBookmark */ = ED9AB3E610967730000B5852 /* PBXTextBookmark */;
ED9AB3E710967730000B5852 /* PBXTextBookmark */ = ED9AB3E710967730000B5852 /* PBXTextBookmark */;
ED9AB3E910967730000B5852 /* PBXTextBookmark */ = ED9AB3E910967730000B5852 /* PBXTextBookmark */;
ED9AB3EC10967730000B5852 /* PBXTextBookmark */ = ED9AB3EC10967730000B5852 /* PBXTextBookmark */;
ED9AB3ED10967730000B5852 /* PBXTextBookmark */ = ED9AB3ED10967730000B5852 /* PBXTextBookmark */;
ED9AB3EF10967730000B5852 /* PBXTextBookmark */ = ED9AB3EF10967730000B5852 /* PBXTextBookmark */;
ED9AB3F210967730000B5852 /* PBXTextBookmark */ = ED9AB3F210967730000B5852 /* PBXTextBookmark */;
ED9AB3F310967730000B5852 /* PBXTextBookmark */ = ED9AB3F310967730000B5852 /* PBXTextBookmark */;
ED9BABDF1083850C00166CDA /* PlistBookmark */ = ED9BABDF1083850C00166CDA /* PlistBookmark */;
ED9BABE11083850C00166CDA /* PlistBookmark */ = ED9BABE11083850C00166CDA /* PlistBookmark */;
ED9BABE21083850C00166CDA /* PlistBookmark */ = ED9BABE21083850C00166CDA /* PlistBookmark */;
EDAFC7F4109A575F002C3487 /* PBXTextBookmark */ = EDAFC7F4109A575F002C3487 /* PBXTextBookmark */;
EDAFC7F5109A575F002C3487 /* PBXTextBookmark */ = EDAFC7F5109A575F002C3487 /* PBXTextBookmark */;
EDAFC7F7109A575F002C3487 /* PBXTextBookmark */ = EDAFC7F7109A575F002C3487 /* PBXTextBookmark */;
EDAFC7F8109A575F002C3487 /* PBXTextBookmark */ = EDAFC7F8109A575F002C3487 /* PBXTextBookmark */;
EDAFC7F9109A575F002C3487 /* PBXTextBookmark */ = EDAFC7F9109A575F002C3487 /* PBXTextBookmark */;
EDAFC818109A5B94002C3487 /* PBXTextBookmark */ = EDAFC818109A5B94002C3487 /* PBXTextBookmark */;
EDAFC819109A5B94002C3487 /* PBXTextBookmark */ = EDAFC819109A5B94002C3487 /* PBXTextBookmark */;
EDAFC81B109A5B94002C3487 /* PBXTextBookmark */ = EDAFC81B109A5B94002C3487 /* PBXTextBookmark */;
EDFDF9B310A2054E0071CB9B /* PBXTextBookmark */ = EDFDF9B310A2054E0071CB9B /* PBXTextBookmark */;
EDFDF9B410A2054E0071CB9B /* PBXTextBookmark */ = EDFDF9B410A2054E0071CB9B /* PBXTextBookmark */;
EDFDF9B610A2054E0071CB9B /* PBXTextBookmark */ = EDFDF9B610A2054E0071CB9B /* PBXTextBookmark */;
EDFDF9B710A2054E0071CB9B /* PBXTextBookmark */ = EDFDF9B710A2054E0071CB9B /* PBXTextBookmark */;
EDFDF9C110A205F50071CB9B /* PBXTextBookmark */ = EDFDF9C110A205F50071CB9B /* PBXTextBookmark */;
EDFDF9C310A205F50071CB9B /* PBXTextBookmark */ = EDFDF9C310A205F50071CB9B /* PBXTextBookmark */;
EDFDF9C410A205F50071CB9B /* PBXTextBookmark */ = EDFDF9C410A205F50071CB9B /* PBXTextBookmark */;
EDFDF9C810A2114E0071CB9B /* PBXTextBookmark */ = EDFDF9C810A2114E0071CB9B /* PBXTextBookmark */;
ED28ACA810AB233200DFC9C8 = ED28ACA810AB233200DFC9C8 /* PBXTextBookmark */;
ED28ACAB10AB233200DFC9C8 = ED28ACAB10AB233200DFC9C8 /* PBXTextBookmark */;
ED28ACAC10AB233200DFC9C8 = ED28ACAC10AB233200DFC9C8 /* PBXTextBookmark */;
ED28ACAD10AB233200DFC9C8 = ED28ACAD10AB233200DFC9C8 /* PBXTextBookmark */;
ED2D127F10838A65003A9380 = ED2D127F10838A65003A9380 /* PBXBookmark */;
ED2D128210838A65003A9380 = ED2D128210838A65003A9380 /* PBXBookmark */;
ED60B15110B61ADE003A8B9F = ED60B15110B61ADE003A8B9F /* PBXTextBookmark */;
ED60B15210B61ADE003A8B9F = ED60B15210B61ADE003A8B9F /* PBXTextBookmark */;
ED80ABFC10E930AC006AAD9D = ED80ABFC10E930AC006AAD9D /* PBXTextBookmark */;
ED80ABFF10E930AC006AAD9D = ED80ABFF10E930AC006AAD9D /* PBXTextBookmark */;
ED80AC0010E930AC006AAD9D = ED80AC0010E930AC006AAD9D /* PBXTextBookmark */;
ED9AB3E410967730000B5852 = ED9AB3E410967730000B5852 /* PlistBookmark */;
ED9AB3E610967730000B5852 = ED9AB3E610967730000B5852 /* PBXTextBookmark */;
ED9AB3E710967730000B5852 = ED9AB3E710967730000B5852 /* PBXTextBookmark */;
ED9AB3E910967730000B5852 = ED9AB3E910967730000B5852 /* PBXTextBookmark */;
ED9AB3EC10967730000B5852 = ED9AB3EC10967730000B5852 /* PBXTextBookmark */;
ED9AB3ED10967730000B5852 = ED9AB3ED10967730000B5852 /* PBXTextBookmark */;
ED9AB3EF10967730000B5852 = ED9AB3EF10967730000B5852 /* PBXTextBookmark */;
ED9AB3F210967730000B5852 = ED9AB3F210967730000B5852 /* PBXTextBookmark */;
ED9AB3F310967730000B5852 = ED9AB3F310967730000B5852 /* PBXTextBookmark */;
ED9BABDF1083850C00166CDA = ED9BABDF1083850C00166CDA /* PlistBookmark */;
ED9BABE11083850C00166CDA = ED9BABE11083850C00166CDA /* PlistBookmark */;
ED9BABE21083850C00166CDA = ED9BABE21083850C00166CDA /* PlistBookmark */;
EDA4D0A6110A1FCD0014EF0F = EDA4D0A6110A1FCD0014EF0F /* PBXTextBookmark */;
EDA4D0A7110A1FCD0014EF0F = EDA4D0A7110A1FCD0014EF0F /* PBXTextBookmark */;
EDA4D0A8110A1FCD0014EF0F = EDA4D0A8110A1FCD0014EF0F /* PBXTextBookmark */;
EDADAE4110ED10F70056382E = EDADAE4110ED10F70056382E /* PBXTextBookmark */;
EDADAE4210ED10F70056382E = EDADAE4210ED10F70056382E /* PBXTextBookmark */;
EDAFC7F5109A575F002C3487 = EDAFC7F5109A575F002C3487 /* PBXTextBookmark */;
EDAFC7F7109A575F002C3487 = EDAFC7F7109A575F002C3487 /* PBXTextBookmark */;
EDAFC7F8109A575F002C3487 = EDAFC7F8109A575F002C3487 /* PBXTextBookmark */;
EDAFC7F9109A575F002C3487 = EDAFC7F9109A575F002C3487 /* PBXTextBookmark */;
EDAFC818109A5B94002C3487 = EDAFC818109A5B94002C3487 /* PBXTextBookmark */;
EDAFC819109A5B94002C3487 = EDAFC819109A5B94002C3487 /* PBXTextBookmark */;
EDAFC81B109A5B94002C3487 = EDAFC81B109A5B94002C3487 /* PBXTextBookmark */;
EDD2763611C2B43F004A9B9B /* PlistBookmark */ = EDD2763611C2B43F004A9B9B /* PlistBookmark */;
EDD2763711C2B43F004A9B9B /* XCBuildMessageTextBookmark */ = EDD2763711C2B43F004A9B9B /* XCBuildMessageTextBookmark */;
EDD2763811C2B43F004A9B9B /* PBXTextBookmark */ = EDD2763811C2B43F004A9B9B /* PBXTextBookmark */;
EDD2764A11C2B47C004A9B9B /* PBXTextBookmark */ = EDD2764A11C2B47C004A9B9B /* PBXTextBookmark */;
EDD2764D11C2B499004A9B9B /* PBXTextBookmark */ = EDD2764D11C2B499004A9B9B /* PBXTextBookmark */;
EDD2765011C2B4C2004A9B9B /* XCBuildMessageTextBookmark */ = EDD2765011C2B4C2004A9B9B /* XCBuildMessageTextBookmark */;
EDD2765111C2B4C2004A9B9B /* PBXTextBookmark */ = EDD2765111C2B4C2004A9B9B /* PBXTextBookmark */;
EDD2765411C2B4E4004A9B9B /* PBXTextBookmark */ = EDD2765411C2B4E4004A9B9B /* PBXTextBookmark */;
EDD2765D11C2B634004A9B9B /* PBXTextBookmark */ = EDD2765D11C2B634004A9B9B /* PBXTextBookmark */;
EDFDF9B310A2054E0071CB9B = EDFDF9B310A2054E0071CB9B /* PBXTextBookmark */;
EDFDF9B410A2054E0071CB9B = EDFDF9B410A2054E0071CB9B /* PBXTextBookmark */;
EDFDF9B610A2054E0071CB9B = EDFDF9B610A2054E0071CB9B /* PBXTextBookmark */;
EDFDF9C110A205F50071CB9B = EDFDF9C110A205F50071CB9B /* PBXTextBookmark */;
};
sourceControlManager = ED9BABAF108380C600166CDA /* Source Control */;
userBuildSettings = {
@ -134,6 +151,20 @@
sepNavWindowFrame = "{{15, 250}, {800, 773}}";
};
};
434669A40F8D08C000EA7D6D /* doomAppDelegate.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {662, 621}}";
sepNavSelRange = "{898, 0}";
sepNavVisRange = "{0, 1144}";
};
};
434669A50F8D08C000EA7D6D /* doomAppDelegate.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {662, 3290}}";
sepNavSelRange = "{6607, 0}";
sepNavVisRange = "{1068, 1018}";
};
};
43CF03090F56D5C200E4A23D /* iphone_loop.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {732, 24640}}";
@ -155,18 +186,46 @@
sepNavVisRange = "{1199, 1295}";
};
};
7229CE460F6C89F8004123C5 /* EAGLView.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {662, 5236}}";
sepNavSelRange = "{9878, 0}";
sepNavVisRange = "{9018, 1103}";
};
};
724C531E0FBDBCEE000E4348 /* BackgroundMusic.cpp */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {810, 7490}}";
sepNavSelRange = "{11337, 0}";
sepNavVisRange = "{10271, 2574}";
};
};
72A55EEE1003A94300F788A5 /* iphone_start.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {662, 3066}}";
sepNavIntBoundsRect = "{{0, 0}, {924, 3332}}";
sepNavSelRange = "{2085, 10}";
sepNavVisRange = "{1556, 1013}";
};
};
72A560E11004FAEE00F788A5 /* iphone_net.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {924, 8568}}";
sepNavSelRange = "{13921, 0}";
sepNavVisRange = "{13317, 1419}";
};
};
72A7E8F30F5F2001005B83C0 /* iphone_doom.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {742, 7686}}";
sepNavSelRange = "{0, 0}";
sepNavVisRange = "{0, 757}";
sepNavVisRange = "{0, 933}";
};
};
72A7E8F60F5F2063005B83C0 /* iphone_menus.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {662, 13314}}";
sepNavSelRange = "{5284, 13}";
sepNavVisRange = "{4701, 1236}";
sepNavIntBoundsRect = "{{0, 0}, {924, 13034}}";
sepNavSelRange = "{16785, 7}";
sepNavVisRange = "{16110, 1348}";
};
};
72D50DBA0F8ED98000BB49E6 /* ipak.h */ = {
@ -185,11 +244,18 @@
};
72E731EA0F97E68100E702CD /* iphone_sound.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {864, 4214}}";
sepNavIntBoundsRect = "{{0, 0}, {864, 4172}}";
sepNavSelRange = "{4675, 0}";
sepNavVisRange = "{3563, 1771}";
};
};
72E8478F0F9400D700AB3C99 /* g_game.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {742, 42056}}";
sepNavSelRange = "{37902, 0}";
sepNavVisRange = "{38963, 593}";
};
};
72E847CA0F94096C00AB3C99 /* SDL_opengl.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {870, 3024}}";
@ -197,6 +263,20 @@
sepNavVisRange = "{0, 1327}";
};
};
72E847FD0F941A5900AB3C99 /* p_spec.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {742, 46256}}";
sepNavSelRange = "{65721, 11}";
sepNavVisRange = "{65587, 835}";
};
};
72E847FF0F941A5900AB3C99 /* p_switch.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {742, 16408}}";
sepNavSelRange = "{14154, 10}";
sepNavVisRange = "{13963, 628}";
};
};
72E8495E0F942B9300AB3C99 /* misc.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {742, 1218}}";
@ -204,6 +284,46 @@
sepNavVisRange = "{1132, 433}";
};
};
ED28ACA810AB233200DFC9C8 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 72E731EA0F97E68100E702CD /* iphone_sound.c */;
name = "iphone_sound.c: 148";
rLen = 0;
rLoc = 4675;
rType = 0;
vrLen = 1771;
vrLoc = 3563;
};
ED28ACAB10AB233200DFC9C8 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 72E731EA0F97E68100E702CD /* iphone_sound.c */;
name = "iphone_sound.c: 148";
rLen = 0;
rLoc = 4675;
rType = 0;
vrLen = 1771;
vrLoc = 3563;
};
ED28ACAC10AB233200DFC9C8 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 434669A50F8D08C000EA7D6D /* doomAppDelegate.m */;
name = "doomAppDelegate.m: 206";
rLen = 0;
rLoc = 6278;
rType = 0;
vrLen = 1081;
vrLoc = 5802;
};
ED28ACAD10AB233200DFC9C8 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 434669A40F8D08C000EA7D6D /* doomAppDelegate.h */;
name = "doomAppDelegate.h: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 1144;
vrLoc = 0;
};
ED2D127F10838A65003A9380 /* PBXBookmark */ = {
isa = PBXBookmark;
fRef = 434669950F8D058400EA7D6D /* Doom_icon.png */;
@ -212,6 +332,56 @@
isa = PBXBookmark;
fRef = 434669950F8D058400EA7D6D /* Doom_icon.png */;
};
ED60B15110B61ADE003A8B9F /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 434669A40F8D08C000EA7D6D /* doomAppDelegate.h */;
name = "doomAppDelegate.h: 27";
rLen = 0;
rLoc = 898;
rType = 0;
vrLen = 1144;
vrLoc = 0;
};
ED60B15210B61ADE003A8B9F /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 434669A50F8D08C000EA7D6D /* doomAppDelegate.m */;
name = "doomAppDelegate.m: 215";
rLen = 0;
rLoc = 6607;
rType = 0;
vrLen = 1018;
vrLoc = 1068;
};
ED80ABFC10E930AC006AAD9D /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 7229CE460F6C89F8004123C5 /* EAGLView.m */;
name = "EAGLView.m: 345";
rLen = 0;
rLoc = 9878;
rType = 0;
vrLen = 1103;
vrLoc = 9018;
};
ED80ABFF10E930AC006AAD9D /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 7229CE460F6C89F8004123C5 /* EAGLView.m */;
name = "EAGLView.m: 345";
rLen = 0;
rLoc = 9878;
rType = 0;
vrLen = 1103;
vrLoc = 9018;
};
ED80AC0010E930AC006AAD9D /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 72A560E11004FAEE00F788A5 /* iphone_net.c */;
name = "iphone_net.c: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 1501;
vrLoc = 16093;
};
ED9AB3CF10966E85000B5852 /* iphone_email.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {662, 621}}";
@ -238,16 +408,6 @@
rLen = 0;
rLoc = 2147483647;
};
ED9AB3E510967730000B5852 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 72A55EEE1003A94300F788A5 /* iphone_start.c */;
name = "iphone_start.c: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 757;
vrLoc = 0;
};
ED9AB3E610967730000B5852 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = ED9AB3CF10966E85000B5852 /* iphone_email.h */;
@ -339,6 +499,9 @@
configStateDict = {
};
customDataFormattersEnabled = 1;
dataTipCustomDataFormattersEnabled = 1;
dataTipShowTypeColumn = 1;
dataTipSortType = 0;
debuggerPlugin = GDBDebugging;
disassemblyDisplayState = 0;
dylibVariantSuffix = "";
@ -351,6 +514,7 @@
name = Doom;
savedGlobals = {
};
showTypeColumn = 0;
sourceDirectories = (
);
};
@ -359,6 +523,9 @@
fallbackIsa = XCSourceControlManager;
isSCMEnabled = 0;
scmConfiguration = {
repositoryNamesForRoots = {
"" = "";
};
};
};
ED9BABB0108380C600166CDA /* Code sense */ = {
@ -399,15 +566,55 @@
rLen = 0;
rLoc = 2147483647;
};
EDAFC7F4109A575F002C3487 /* PBXTextBookmark */ = {
EDA4D0A6110A1FCD0014EF0F /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 72A7E8F60F5F2063005B83C0 /* iphone_menus.c */;
name = "iphone_menus.c: 201";
rLen = 13;
rLoc = 5284;
name = "iphone_menus.c: 595";
rLen = 7;
rLoc = 16785;
rType = 0;
vrLen = 1236;
vrLoc = 4701;
vrLen = 1348;
vrLoc = 16110;
};
EDA4D0A7110A1FCD0014EF0F /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 72A7E8F60F5F2063005B83C0 /* iphone_menus.c */;
name = "iphone_menus.c: 595";
rLen = 7;
rLoc = 16785;
rType = 0;
vrLen = 1348;
vrLoc = 16110;
};
EDA4D0A8110A1FCD0014EF0F /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 72A560E11004FAEE00F788A5 /* iphone_net.c */;
name = "iphone_net.c: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 1499;
vrLoc = 13317;
};
EDADAE4110ED10F70056382E /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 72A55EEE1003A94300F788A5 /* iphone_start.c */;
name = "iphone_start.c: 94";
rLen = 10;
rLoc = 2085;
rType = 0;
vrLen = 1013;
vrLoc = 1556;
};
EDADAE4210ED10F70056382E /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 72A560E11004FAEE00F788A5 /* iphone_net.c */;
name = "iphone_net.c: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 1499;
vrLoc = 13317;
};
EDAFC7F5109A575F002C3487 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
@ -479,6 +686,95 @@
vrLen = 1190;
vrLoc = 359;
};
EDD2763611C2B43F004A9B9B /* PlistBookmark */ = {
isa = PlistBookmark;
fRef = 8D1107310486CEB800E47090 /* Info.plist */;
fallbackIsa = PBXBookmark;
isK = 0;
kPath = (
);
name = /Volumes/Work/idMobileDepot/DoomClassicDepot/code/iphone/Info.plist;
rLen = 0;
rLoc = 9223372036854775807;
};
EDD2763711C2B43F004A9B9B /* XCBuildMessageTextBookmark */ = {
isa = PBXTextBookmark;
comments = "Jump to label 'end'";
fRef = 724C531E0FBDBCEE000E4348 /* BackgroundMusic.cpp */;
fallbackIsa = XCBuildMessageTextBookmark;
rLen = 1;
rLoc = 355;
rType = 1;
};
EDD2763811C2B43F004A9B9B /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 724C531E0FBDBCEE000E4348 /* BackgroundMusic.cpp */;
name = "BackgroundMusic.cpp: 356";
rLen = 0;
rLoc = 11880;
rType = 0;
vrLen = 2847;
vrLoc = 10470;
};
EDD2764A11C2B47C004A9B9B /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 724C531E0FBDBCEE000E4348 /* BackgroundMusic.cpp */;
name = "BackgroundMusic.cpp: 344";
rLen = 0;
rLoc = 11438;
rType = 0;
vrLen = 2847;
vrLoc = 10470;
};
EDD2764D11C2B499004A9B9B /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 724C531E0FBDBCEE000E4348 /* BackgroundMusic.cpp */;
name = "BackgroundMusic.cpp: 344";
rLen = 0;
rLoc = 11438;
rType = 0;
vrLen = 2899;
vrLoc = 10470;
};
EDD2765011C2B4C2004A9B9B /* XCBuildMessageTextBookmark */ = {
isa = PBXTextBookmark;
comments = "Jump to label 'end'";
fRef = 724C531E0FBDBCEE000E4348 /* BackgroundMusic.cpp */;
fallbackIsa = XCBuildMessageTextBookmark;
rLen = 1;
rLoc = 355;
rType = 1;
};
EDD2765111C2B4C2004A9B9B /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 724C531E0FBDBCEE000E4348 /* BackgroundMusic.cpp */;
name = "BackgroundMusic.cpp: 364";
rLen = 0;
rLoc = 12089;
rType = 0;
vrLen = 1932;
vrLoc = 4187;
};
EDD2765411C2B4E4004A9B9B /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 724C531E0FBDBCEE000E4348 /* BackgroundMusic.cpp */;
name = "BackgroundMusic.cpp: 364";
rLen = 0;
rLoc = 12089;
rType = 0;
vrLen = 1932;
vrLoc = 4187;
};
EDD2765D11C2B634004A9B9B /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 724C531E0FBDBCEE000E4348 /* BackgroundMusic.cpp */;
name = "BackgroundMusic.cpp: 343";
rLen = 0;
rLoc = 11337;
rType = 0;
vrLen = 2574;
vrLoc = 10271;
};
EDFDF9B310A2054E0071CB9B /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 72D50DBA0F8ED98000BB49E6 /* ipak.h */;
@ -509,16 +805,6 @@
vrLen = 1502;
vrLoc = 287;
};
EDFDF9B710A2054E0071CB9B /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 72E8495E0F942B9300AB3C99 /* misc.c */;
name = "misc.c: 60";
rLen = 0;
rLoc = 1496;
rType = 0;
vrLen = 964;
vrLoc = 869;
};
EDFDF9C110A205F50071CB9B /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = EDFDF9C210A205F50071CB9B /* alc.h */;
@ -531,44 +817,9 @@
};
EDFDF9C210A205F50071CB9B /* alc.h */ = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = alc.h;
path = /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.0.sdk/System/Library/Frameworks/OpenAL.framework/Headers/alc.h;
sourceTree = "<absolute>";
};
EDFDF9C310A205F50071CB9B /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 72E731EA0F97E68100E702CD /* iphone_sound.c */;
name = "iphone_sound.c: 160";
rLen = 16;
rLoc = 5037;
rType = 0;
vrLen = 1820;
vrLoc = 3514;
};
EDFDF9C410A205F50071CB9B /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = EDFDF9C510A205F50071CB9B /* alc.h */;
name = "alc.h: 186";
rLen = 0;
rLoc = 3852;
rType = 0;
vrLen = 1365;
vrLoc = 3211;
};
EDFDF9C510A205F50071CB9B /* alc.h */ = {
isa = PBXFileReference;
name = alc.h;
path = /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.0.sdk/System/Library/Frameworks/OpenAL.framework/Headers/alc.h;
sourceTree = "<absolute>";
};
EDFDF9C810A2114E0071CB9B /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 72E731EA0F97E68100E702CD /* iphone_sound.c */;
name = "iphone_sound.c: 148";
rLen = 0;
rLoc = 4675;
rType = 0;
vrLen = 1771;
vrLoc = 3563;
};
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,859 @@
// !$*UTF8*$!
{
1D6058900D05DD3D006BFB54 /* Doom */ = {
activeExec = 0;
executables = (
C861F24F13BD2C7700DB34A8 /* Doom */,
);
};
29B97313FDCFA39411CA2CEA /* Project object */ = {
activeBuildConfigurationName = Distribution;
activeExecutable = C861F24F13BD2C7700DB34A8 /* Doom */;
activeSDKPreference = iphoneos4.3;
activeTarget = 1D6058900D05DD3D006BFB54 /* Doom */;
addToTargets = (
1D6058900D05DD3D006BFB54 /* Doom */,
);
breakpoints = (
C885311113D8CF7A00A5FBF7 /* gl_main.c:1961 */,
C885311313D8CF8000A5FBF7 /* gl_main.c:1958 */,
);
codeSenseManager = C861F25D13BD2C7A00DB34A8 /* Code sense */;
executables = (
C861F24F13BD2C7700DB34A8 /* Doom */,
);
perUserDictionary = {
PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
341,
20,
48,
43,
43,
20,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
PBXFileDataSource_Target_ColumnID,
);
};
PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
301,
60,
20,
48.16259765625,
43,
43,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXTargetDataSource_PrimaryAttribute,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
);
};
PBXPerProjectTemplateStateSaveDate = 335141858;
PBXWorkspaceStateSaveDate = 335141858;
};
sourceControlManager = C861F25C13BD2C7A00DB34A8 /* Source Control */;
userBuildSettings = {
};
};
29B97316FDCFA39411CA2CEA /* main.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1436, 837}}";
sepNavSelRange = "{807, 0}";
sepNavVisRange = "{0, 1417}";
sepNavWindowFrame = "{{258, 17}, {1495, 988}}";
};
};
434669A40F8D08C000EA7D6D /* doomAppDelegate.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {975, 946}}";
sepNavSelRange = "{1749, 38}";
sepNavVisRange = "{0, 2185}";
sepNavWindowFrame = "{{305, 0}, {1034, 1074}}";
};
};
434669A50F8D08C000EA7D6D /* doomAppDelegate.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {975, 5590}}";
sepNavSelRange = "{10774, 0}";
sepNavVisRange = "{9736, 1348}";
sepNavWindowFrame = "{{582, 18}, {1034, 1074}}";
};
};
43A945140F82D75900FFD32E /* iphone_sys.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1436, 860}}";
sepNavSelRange = "{1155, 0}";
sepNavVisRange = "{0, 1456}";
sepNavWindowFrame = "{{338, 149}, {1495, 988}}";
};
};
43CF02FE0F56974E00E4A23D /* Default.png */ = {
uiCtxt = {
sepNavWindowFrame = "{{141, 122}, {1494, 988}}";
};
};
43CF03090F56D5C200E4A23D /* iphone_loop.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 23244}}";
sepNavSelRange = "{35580, 16}";
sepNavVisRange = "{34567, 1066}";
sepNavWindowFrame = "{{422, 82}, {1495, 988}}";
};
};
43DD8391100295F70006E1DD /* iphone_async.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 12766}}";
sepNavSelRange = "{15359, 0}";
sepNavVisRange = "{14906, 953}";
sepNavWindowFrame = "{{385, 87}, {1020, 1074}}";
};
};
43E8D2DF0F4FC61E003F09B2 /* iphone_main.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1436, 6370}}";
sepNavSelRange = "{13195, 24}";
sepNavVisRange = "{12907, 1397}";
sepNavWindowFrame = "{{378, 95}, {1495, 988}}";
};
};
7229CC8E0F6B3363004123C5 /* doomiphone.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1436, 1729}}";
sepNavSelRange = "{2545, 0}";
sepNavVisRange = "{1637, 1684}";
sepNavWindowFrame = "{{250, 102}, {1495, 988}}";
};
};
7229CE450F6C89F8004123C5 /* EAGLView.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1436, 837}}";
sepNavSelRange = "{1326, 0}";
sepNavVisRange = "{0, 1452}";
sepNavWindowFrame = "{{339, 120}, {1495, 988}}";
};
};
7229CE460F6C89F8004123C5 /* EAGLView.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {795, 5239}}";
sepNavSelRange = "{10535, 0}";
sepNavVisRange = "{9431, 1714}";
sepNavWindowFrame = "{{339, 120}, {1495, 988}}";
};
};
7229CE540F6C8CDE004123C5 /* gles_glue.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {961, 2613}}";
sepNavSelRange = "{4886, 0}";
sepNavVisRange = "{2348, 1738}";
sepNavWindowFrame = "{{117, 57}, {1020, 1074}}";
};
};
7239452B0F9C0E7500EADD62 /* iphone_mapSelect.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 6032}}";
sepNavSelRange = "{9756, 0}";
sepNavVisRange = "{9339, 1082}";
sepNavWindowFrame = "{{432, 79}, {1020, 1074}}";
};
};
72484E5D0FB0E99900124E1C /* iphone_render.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 23283}}";
sepNavSelRange = "{39537, 12}";
sepNavVisRange = "{38797, 993}";
sepNavWindowFrame = "{{442, 119}, {1495, 988}}";
};
};
724C531E0FBDBCEE000E4348 /* BackgroundMusic.cpp */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1027, 7306}}";
sepNavSelRange = "{17453, 0}";
sepNavVisRange = "{16201, 1360}";
sepNavWindowFrame = "{{814, 31}, {1013, 1096}}";
};
};
727886A20FBDBA740020D469 /* gles_glue.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1436, 837}}";
sepNavSelRange = "{813, 0}";
sepNavVisRange = "{0, 1318}";
sepNavWindowFrame = "{{143, 122}, {1495, 988}}";
};
};
72A55EEE1003A94300F788A5 /* iphone_start.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 2951}}";
sepNavSelRange = "{1098, 16}";
sepNavVisRange = "{871, 652}";
sepNavWindowFrame = "{{330, 73}, {1013, 1096}}";
};
};
72A560E11004FAEE00F788A5 /* iphone_net.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {943, 7917}}";
sepNavSelRange = "{11148, 0}";
sepNavVisRange = "{10878, 2023}";
};
};
72A7E8F30F5F2001005B83C0 /* iphone_doom.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1436, 7267}}";
sepNavSelRange = "{3966, 0}";
sepNavVisRange = "{3109, 1821}";
sepNavWindowFrame = "{{338, 79}, {1495, 988}}";
};
};
72A7E8F60F5F2063005B83C0 /* iphone_menus.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 11713}}";
sepNavSelRange = "{12956, 11}";
sepNavVisRange = "{12441, 1092}";
sepNavWindowFrame = "{{361, 84}, {1495, 988}}";
};
};
72B5FF380F7E5C3D00C8A372 /* hud.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1435, 2899}}";
sepNavSelRange = "{2031, 0}";
sepNavVisRange = "{1549, 2560}";
sepNavWindowFrame = "{{478, 283}, {1494, 988}}";
};
};
72D50DBA0F8ED98000BB49E6 /* ipak.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1436, 2379}}";
sepNavSelRange = "{1539, 0}";
sepNavVisRange = "{2918, 1995}";
sepNavWindowFrame = "{{166, 101}, {1495, 988}}";
};
};
72D50DBB0F8ED98000BB49E6 /* ipak.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 4901}}";
sepNavSelRange = "{3115, 0}";
sepNavVisRange = "{2968, 1187}";
};
};
72E731EA0F97E68100E702CD /* iphone_sound.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 3731}}";
sepNavSelRange = "{4780, 0}";
sepNavVisRange = "{4469, 975}";
sepNavWindowFrame = "{{74, 99}, {1034, 1074}}";
};
};
72E847640F93C61900AB3C99 /* am_map.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 20709}}";
sepNavSelRange = "{40979, 11}";
sepNavVisRange = "{40171, 1067}";
};
};
72E847680F93FF2F00AB3C99 /* config.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 1391}}";
sepNavSelRange = "{5, 25}";
sepNavVisRange = "{0, 779}";
};
};
72E847700F93FFDB00AB3C99 /* d_deh.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 40040}}";
sepNavSelRange = "{90350, 3}";
sepNavVisRange = "{89773, 1257}";
};
};
72E8477C0F9400D700AB3C99 /* d_main.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 22971}}";
sepNavSelRange = "{8166, 19}";
sepNavVisRange = "{5621, 886}";
};
};
72E847820F9400D700AB3C99 /* d_ticcmd.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {975, 946}}";
sepNavSelRange = "{0, 0}";
sepNavVisRange = "{0, 2087}";
sepNavWindowFrame = "{{120, 57}, {1034, 1074}}";
};
};
72E847840F9400D700AB3C99 /* doomdef.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 637}}";
sepNavSelRange = "{0, 0}";
sepNavVisRange = "{923, 791}";
};
};
72E847850F9400D700AB3C99 /* doomdef.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 4511}}";
sepNavSelRange = "{3355, 0}";
sepNavVisRange = "{3067, 869}";
};
};
72E847870F9400D700AB3C99 /* doomstat.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {795, 4407}}";
sepNavSelRange = "{8186, 103}";
sepNavVisRange = "{1261, 2035}";
};
};
72E847880F9400D700AB3C99 /* doomtype.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {954, 1677}}";
sepNavSelRange = "{1683, 36}";
sepNavVisRange = "{1780, 2766}";
sepNavWindowFrame = "{{117, 35}, {1013, 1096}}";
};
};
72E8478D0F9400D700AB3C99 /* f_wipe.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 2613}}";
sepNavSelRange = "{1943, 15}";
sepNavVisRange = "{1511, 568}";
};
};
72E8478F0F9400D700AB3C99 /* g_game.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1133, 38753}}";
sepNavSelRange = "{45949, 0}";
sepNavVisRange = "{45385, 979}";
sepNavWindowFrame = "{{432, 40}, {1020, 1074}}";
};
};
72E847900F9400D700AB3C99 /* g_game.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1133, 2301}}";
sepNavSelRange = "{2038, 0}";
sepNavVisRange = "{1507, 1552}";
};
};
72E847920F9400D700AB3C99 /* gl_main.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {957, 38675}}";
sepNavSelRange = "{68792, 0}";
sepNavVisRange = "{67681, 1381}";
};
};
72E847940F9400D700AB3C99 /* gl_texture.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 14833}}";
sepNavSelRange = "{4039, 9}";
sepNavVisRange = "{2189, 719}";
};
};
72E847950F9400D700AB3C99 /* hu_lib.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 9594}}";
sepNavSelRange = "{6401, 9}";
sepNavVisRange = "{6054, 847}";
};
};
72E847AA0F9400D700AB3C99 /* m_menu.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 73606}}";
sepNavSelRange = "{75941, 9}";
sepNavVisRange = "{75515, 846}";
};
};
72E847AC0F9400D700AB3C99 /* m_misc.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {803, 14274}}";
sepNavSelRange = "{2940, 48}";
sepNavVisRange = "{2182, 1395}";
sepNavWindowFrame = "{{120, 143}, {1495, 988}}";
};
};
72E847CA0F94096C00AB3C99 /* SDL_opengl.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 2834}}";
sepNavSelRange = "{1988, 9}";
sepNavVisRange = "{1587, 1159}";
};
};
72E847E80F941A5900AB3C99 /* p_enemy.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 33345}}";
sepNavSelRange = "{57961, 8}";
sepNavVisRange = "{57509, 924}";
};
};
72E847EF0F941A5900AB3C99 /* p_map.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {579, 30563}}";
sepNavSelRange = "{62364, 0}";
sepNavVisRange = "{60545, 1308}";
sepNavWindowFrame = "{{161, 15}, {1020, 1074}}";
};
};
72E847F10F941A5900AB3C99 /* p_maputl.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {579, 8307}}";
sepNavSelRange = "{12207, 5}";
sepNavVisRange = "{11014, 1594}";
};
};
72E847F30F941A5900AB3C99 /* p_mobj.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {614, 19903}}";
sepNavSelRange = "{36423, 0}";
sepNavVisRange = "{24142, 1382}";
};
};
72E847F80F941A5900AB3C99 /* p_saveg.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {795, 13546}}";
sepNavSelRange = "{7502, 0}";
sepNavVisRange = "{6470, 1758}";
};
};
72E847FA0F941A5900AB3C99 /* p_setup.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {795, 22386}}";
sepNavSelRange = "{52386, 0}";
sepNavVisRange = "{51170, 1404}";
};
};
72E848010F941A5900AB3C99 /* p_tick.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {975, 3796}}";
sepNavSelRange = "{1529, 0}";
sepNavVisRange = "{6515, 1880}";
sepNavWindowFrame = "{{441, 79}, {1034, 1074}}";
};
};
72E8481F0F941A8300AB3C99 /* r_data.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {663, 9490}}";
sepNavSelRange = "{18820, 0}";
sepNavVisRange = "{18175, 1283}";
};
};
72E848210F941A8300AB3C99 /* r_defs.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 5772}}";
sepNavSelRange = "{13256, 15}";
sepNavVisRange = "{12677, 758}";
};
};
72E848240F941A8300AB3C99 /* r_draw.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1436, 14534}}";
sepNavSelRange = "{2082, 0}";
sepNavVisRange = "{0, 2309}";
sepNavWindowFrame = "{{97, 164}, {1495, 988}}";
};
};
72E8482C0F941AAC00AB3C99 /* r_fps.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1076, 5408}}";
sepNavSelRange = "{6475, 0}";
sepNavVisRange = "{5696, 1799}";
};
};
72E8482E0F941AAC00AB3C99 /* r_main.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {615, 8489}}";
sepNavSelRange = "{10582, 0}";
sepNavVisRange = "{10221, 944}";
};
};
72E8482F0F941AAC00AB3C99 /* r_main.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1436, 1677}}";
sepNavSelRange = "{1669, 9}";
sepNavVisRange = "{726, 1672}";
sepNavWindowFrame = "{{74, 185}, {1495, 988}}";
};
};
72E848390F941AAC00AB3C99 /* r_things.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 13858}}";
sepNavSelRange = "{23894, 10}";
sepNavVisRange = "{23446, 766}";
};
};
72E8483B0F941AAC00AB3C99 /* s_sound.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 9620}}";
sepNavSelRange = "{14012, 15}";
sepNavVisRange = "{13585, 796}";
};
};
72E8484B0F941ADC00AB3C99 /* st_stuff.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {615, 1469}}";
sepNavSelRange = "{1775, 54}";
sepNavVisRange = "{1111, 1199}";
};
};
72E848540F941ADC00AB3C99 /* w_wad.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {705, 5629}}";
sepNavSelRange = "{8919, 0}";
sepNavVisRange = "{9326, 1979}";
};
};
72E8495C0F942B9300AB3C99 /* cvar.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {795, 4784}}";
sepNavSelRange = "{5299, 0}";
sepNavVisRange = "{4783, 1173}";
sepNavWindowFrame = "{{235, 38}, {1495, 988}}";
};
};
72E8495E0F942B9300AB3C99 /* misc.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {795, 1183}}";
sepNavSelRange = "{959, 0}";
sepNavVisRange = "{654, 1355}";
};
};
72E8495F0F942B9300AB3C99 /* misc.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1436, 975}}";
sepNavSelRange = "{905, 0}";
sepNavVisRange = "{128, 2344}";
sepNavWindowFrame = "{{97, 164}, {1495, 988}}";
};
};
72E849F50F94ED1100AB3C99 /* prboomInterface.c */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {607, 4602}}";
sepNavSelRange = "{1876, 0}";
sepNavVisRange = "{1393, 1085}";
sepNavWindowFrame = "{{120, 143}, {1495, 988}}";
};
};
8D1107310486CEB800E47090 /* Info.plist */ = {
uiCtxt = {
sepNavWindowFrame = "{{430, 53}, {1020, 1074}}";
};
};
C8139A7813F9E0440094C2C0 /* UICustomSlider.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1211, 925}}";
sepNavSelRange = "{381, 0}";
sepNavVisRange = "{0, 489}";
sepNavWindowFrame = "{{188, 450}, {1270, 1076}}";
};
};
C8139AB213FADA800094C2C0 /* SliderSkull@2x.png */ = {
uiCtxt = {
sepNavWindowFrame = "{{120, 455}, {1270, 1076}}";
};
};
C8139AB413FADA9D0094C2C0 /* SliderSkull~ipad.png */ = {
uiCtxt = {
sepNavWindowFrame = "{{143, 434}, {1270, 1076}}";
};
};
C81E0C7013DF471000B1049A /* UIFontButton.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {975, 946}}";
sepNavSelRange = "{337, 0}";
sepNavVisRange = "{0, 617}";
sepNavWindowFrame = "{{598, 99}, {1034, 1074}}";
};
};
C81E0C7113DF471000B1049A /* UIFontButton.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {975, 1547}}";
sepNavSelRange = "{487, 0}";
sepNavVisRange = "{34, 1751}";
sepNavWindowFrame = "{{859, 141}, {1034, 1074}}";
};
};
C81E0C8D13DF4A1B00B1049A /* UIFontLabel.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {975, 923}}";
sepNavSelRange = "{207, 0}";
sepNavVisRange = "{0, 216}";
};
};
C81E0C8E13DF4A1B00B1049A /* UIFontLabel.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {975, 923}}";
sepNavSelRange = "{0, 0}";
sepNavVisRange = "{0, 341}";
sepNavWindowFrame = "{{720, 70}, {1034, 1074}}";
};
};
C81E104113E1CCA000B1049A /* Button.png */ = {
uiCtxt = {
sepNavWindowFrame = "{{1105, 424}, {1289, 1086}}";
};
};
C84F829013D76E96006D01AB /* MapMenuView.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {961, 4381}}";
sepNavSelRange = "{3960, 0}";
sepNavVisRange = "{3339, 1855}";
sepNavWindowFrame = "{{362, 0}, {1020, 1074}}";
};
};
C84F829113D76E96006D01AB /* MapMenuView.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {961, 1352}}";
sepNavSelRange = "{234, 0}";
sepNavVisRange = "{0, 1787}";
sepNavWindowFrame = "{{801, 14}, {1020, 1074}}";
};
};
C84F83F413D7A99C006D01AB /* GenericMenuView.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {961, 946}}";
sepNavSelRange = "{560, 16}";
sepNavVisRange = "{0, 851}";
sepNavWindowFrame = "{{437, 37}, {1020, 1074}}";
};
};
C84F83F513D7A99C006D01AB /* GenericMenuView.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {961, 1404}}";
sepNavSelRange = "{1234, 0}";
sepNavVisRange = "{727, 1690}";
sepNavWindowFrame = "{{445, 418}, {1020, 1074}}";
};
};
C84F855713D8B55C006D01AB /* SettingsMenuView.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {961, 946}}";
sepNavSelRange = "{501, 0}";
sepNavVisRange = "{0, 983}";
sepNavWindowFrame = "{{737, 146}, {1020, 1074}}";
};
};
C84F855813D8B55C006D01AB /* SettingsMenuView.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {961, 1508}}";
sepNavSelRange = "{968, 0}";
sepNavVisRange = "{867, 1642}";
sepNavWindowFrame = "{{731, 79}, {1020, 1074}}";
};
};
C861F24F13BD2C7700DB34A8 /* Doom */ = {
isa = PBXExecutable;
activeArgIndices = (
);
argumentStrings = (
);
autoAttachOnCrash = 1;
breakpointsEnabled = 1;
configStateDict = {
};
customDataFormattersEnabled = 1;
dataTipCustomDataFormattersEnabled = 1;
dataTipShowTypeColumn = 1;
dataTipSortType = 0;
debuggerPlugin = GDBDebugging;
disassemblyDisplayState = 0;
dylibVariantSuffix = "";
enableDebugStr = 1;
environmentEntries = (
);
executableSystemSymbolLevel = 0;
executableUserSymbolLevel = 0;
libgmallocEnabled = 0;
name = Doom;
savedGlobals = {
};
showTypeColumn = 0;
sourceDirectories = (
);
variableFormatDictionary = {
};
};
C861F25C13BD2C7A00DB34A8 /* Source Control */ = {
isa = PBXSourceControlManager;
fallbackIsa = XCSourceControlManager;
isSCMEnabled = 0;
scmConfiguration = {
repositoryNamesForRoots = {
../.. = Rage;
};
};
};
C861F25D13BD2C7A00DB34A8 /* Code sense */ = {
isa = PBXCodeSenseManager;
indexTemplatePath = "";
};
C86F965513D615F70069B7B6 /* MainMenuView.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {954, 945}}";
sepNavSelRange = "{634, 182}";
sepNavVisRange = "{0, 1366}";
sepNavWindowFrame = "{{660, 48}, {1013, 1096}}";
};
};
C86F966613D617740069B7B6 /* MenuViewController.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {954, 945}}";
sepNavSelRange = "{242, 0}";
sepNavVisRange = "{0, 253}";
sepNavWindowFrame = "{{74, 77}, {1013, 1096}}";
};
};
C86F966713D617740069B7B6 /* MenuViewController.mm */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {957, 968}}";
sepNavSelRange = "{309, 0}";
sepNavVisRange = "{0, 442}";
sepNavWindowFrame = "{{542, 55}, {1013, 1096}}";
};
};
C86F975C13D6377B0069B7B6 /* IBGlue.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1127, 585}}";
sepNavSelRange = "{226, 0}";
sepNavVisRange = "{0, 0}";
sepNavWindowFrame = "{{517, 25}, {1020, 1074}}";
};
};
C86F975D13D6377B0069B7B6 /* IBGlue.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {961, 946}}";
sepNavSelRange = "{310, 0}";
sepNavVisRange = "{0, 311}";
sepNavWindowFrame = "{{545, 24}, {1020, 1074}}";
};
};
C879308513F5D8AA003D834F /* DifficultyBackground.png */ = {
uiCtxt = {
sepNavWindowFrame = "{{143, 424}, {1289, 1086}}";
};
};
C879308C13F5D8AA003D834F /* MissonBackground.png */ = {
uiCtxt = {
sepNavWindowFrame = "{{960, 209}, {1289, 1086}}";
};
};
C879308E13F5D8AA003D834F /* UpArrow.png */ = {
uiCtxt = {
sepNavWindowFrame = "{{120, 445}, {1289, 1086}}";
};
};
C87931E013F610B9003D834F /* Divide.png */ = {
uiCtxt = {
sepNavWindowFrame = "{{189, 382}, {1289, 1086}}";
};
};
C87931E813F610B9003D834F /* SettingsButton.png */ = {
uiCtxt = {
sepNavWindowFrame = "{{212, 361}, {1289, 1086}}";
};
};
C87931EB13F610B9003D834F /* SliderSkull.png */ = {
uiCtxt = {
sepNavWindowFrame = "{{568, 448}, {1270, 1076}}";
};
};
C87931FF13F6143C003D834F /* UICustomSwitch.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1230, 958}}";
sepNavSelRange = "{226, 0}";
sepNavVisRange = "{0, 278}";
};
};
C879320013F6143C003D834F /* UICustomSwitch.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1230, 935}}";
sepNavSelRange = "{495, 0}";
sepNavVisRange = "{0, 719}";
sepNavWindowFrame = "{{405, 455}, {1289, 1086}}";
};
};
C88530C813D8CBEA00A5FBF7 /* MainMenuView.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {795, 3263}}";
sepNavSelRange = "{506, 0}";
sepNavVisRange = "{153, 1477}";
sepNavWindowFrame = "{{500, 378}, {1013, 1096}}";
};
};
C885311113D8CF7A00A5FBF7 /* gl_main.c:1961 */ = {
isa = PBXFileBreakpoint;
actions = (
);
breakpointStyle = 0;
continueAfterActions = 0;
countType = 0;
delayBeforeContinue = 0;
fileReference = 72E847920F9400D700AB3C99 /* gl_main.c */;
functionName = "gld_StartDrawScene()";
hitCount = 0;
ignoreCount = 0;
lineNumber = 1961;
modificationTime = 335298652.845627;
originalNumberOfMultipleMatches = 1;
state = 1;
};
C885311313D8CF8000A5FBF7 /* gl_main.c:1958 */ = {
isa = PBXFileBreakpoint;
actions = (
);
breakpointStyle = 0;
continueAfterActions = 0;
countType = 0;
delayBeforeContinue = 0;
fileReference = 72E847920F9400D700AB3C99 /* gl_main.c */;
functionName = "gld_StartDrawScene()";
hitCount = 0;
ignoreCount = 0;
lineNumber = 1958;
modificationTime = 335298652.845659;
originalNumberOfMultipleMatches = 1;
state = 1;
};
C885314213D8D79400A5FBF7 /* ControlsMenuView.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {975, 2899}}";
sepNavSelRange = "{1432, 0}";
sepNavVisRange = "{912, 2131}";
sepNavWindowFrame = "{{205, 358}, {1034, 1074}}";
};
};
C885314313D8D79400A5FBF7 /* ControlsMenuView.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {975, 946}}";
sepNavSelRange = "{466, 14}";
sepNavVisRange = "{0, 781}";
};
};
ED9AB3CF10966E85000B5852 /* iphone_email.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 468}}";
sepNavSelRange = "{7, 14}";
sepNavVisRange = "{0, 955}";
sepNavWindowFrame = "{{93, 78}, {1020, 1074}}";
};
};
ED9AB3D010966E85000B5852 /* iphone_email.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1170, 3094}}";
sepNavSelRange = "{888, 14}";
sepNavVisRange = "{303, 924}";
sepNavWindowFrame = "{{93, 78}, {1020, 1074}}";
};
};
}

View file

@ -8,16 +8,11 @@
/* Begin PBXBuildFile section */
1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; };
28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD14FF0DC6FC520079059D /* OpenGLES.framework */; };
4333CCE80F5CC23E00AE2B6F /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4333CCE70F5CC23E00AE2B6F /* AudioToolbox.framework */; };
434669960F8D058400EA7D6D /* Doom_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 434669950F8D058400EA7D6D /* Doom_icon.png */; };
434669A60F8D08C000EA7D6D /* doomAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 434669A50F8D08C000EA7D6D /* doomAppDelegate.m */; };
4364BF3F0F5CB25900F29317 /* dist.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4364BF3E0F5CB25900F29317 /* dist.plist */; };
43A945150F82D75900FFD32E /* iphone_sys.c in Sources */ = {isa = PBXBuildFile; fileRef = 43A945140F82D75900FFD32E /* iphone_sys.c */; };
43AE7E9F0F67387500B2F562 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43AE7E9E0F67387500B2F562 /* CoreGraphics.framework */; };
43CF02FF0F56974E00E4A23D /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 43CF02FE0F56974E00E4A23D /* Default.png */; };
43CF030A0F56D5C200E4A23D /* iphone_loop.c in Sources */ = {isa = PBXBuildFile; fileRef = 43CF03090F56D5C200E4A23D /* iphone_loop.c */; };
43DD8392100295F70006E1DD /* iphone_async.c in Sources */ = {isa = PBXBuildFile; fileRef = 43DD8391100295F70006E1DD /* iphone_async.c */; };
@ -118,24 +113,92 @@
72F1F9BC0F96C18800AD49AC /* sweep.c in Sources */ = {isa = PBXBuildFile; fileRef = 72F1F9AE0F96C18800AD49AC /* sweep.c */; };
72F1F9BD0F96C18800AD49AC /* tess.c in Sources */ = {isa = PBXBuildFile; fileRef = 72F1F9B00F96C18800AD49AC /* tess.c */; };
72F1F9BE0F96C18800AD49AC /* tessmono.c in Sources */ = {isa = PBXBuildFile; fileRef = 72F1F9B20F96C18800AD49AC /* tessmono.c */; };
C8139A7913F9E0440094C2C0 /* UICustomSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = C8139A7813F9E0440094C2C0 /* UICustomSlider.m */; };
C8139AB313FADA800094C2C0 /* SliderSkull@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C8139AB213FADA800094C2C0 /* SliderSkull@2x.png */; };
C8139AB513FADA9D0094C2C0 /* SliderSkull~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = C8139AB413FADA9D0094C2C0 /* SliderSkull~ipad.png */; };
C81E0C7213DF471000B1049A /* UIFontButton.m in Sources */ = {isa = PBXBuildFile; fileRef = C81E0C7113DF471000B1049A /* UIFontButton.m */; };
C81E0C8F13DF4A1B00B1049A /* UIFontLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = C81E0C8E13DF4A1B00B1049A /* UIFontLabel.m */; };
C81E0E5E13E076E400B1049A /* idGinzaNar-Md2.otf in Resources */ = {isa = PBXBuildFile; fileRef = C81E0E5D13E076E400B1049A /* idGinzaNar-Md2.otf */; };
C81E104C13E1CCA000B1049A /* BackButton.png in Resources */ = {isa = PBXBuildFile; fileRef = C81E104013E1CCA000B1049A /* BackButton.png */; };
C81E104D13E1CCA000B1049A /* Button.png in Resources */ = {isa = PBXBuildFile; fileRef = C81E104113E1CCA000B1049A /* Button.png */; };
C81E104E13E1CCA000B1049A /* DOOM_sigil_decal.png in Resources */ = {isa = PBXBuildFile; fileRef = C81E104213E1CCA000B1049A /* DOOM_sigil_decal.png */; };
C81E104F13E1CCA000B1049A /* DoomLogo.png in Resources */ = {isa = PBXBuildFile; fileRef = C81E104313E1CCA000B1049A /* DoomLogo.png */; };
C81E105013E1CCA000B1049A /* Easy.png in Resources */ = {isa = PBXBuildFile; fileRef = C81E104413E1CCA000B1049A /* Easy.png */; };
C81E105113E1CCA000B1049A /* Hard.png in Resources */ = {isa = PBXBuildFile; fileRef = C81E104513E1CCA000B1049A /* Hard.png */; };
C81E105213E1CCA000B1049A /* MapOverlay.png in Resources */ = {isa = PBXBuildFile; fileRef = C81E104613E1CCA000B1049A /* MapOverlay.png */; };
C81E105313E1CCA000B1049A /* Medium.png in Resources */ = {isa = PBXBuildFile; fileRef = C81E104713E1CCA000B1049A /* Medium.png */; };
C81E105413E1CCA000B1049A /* MenuBackground.png in Resources */ = {isa = PBXBuildFile; fileRef = C81E104813E1CCA000B1049A /* MenuBackground.png */; };
C81E105513E1CCA000B1049A /* Nightmare.png in Resources */ = {isa = PBXBuildFile; fileRef = C81E104913E1CCA000B1049A /* Nightmare.png */; };
C81E105613E1CCA000B1049A /* ResumeButton.png in Resources */ = {isa = PBXBuildFile; fileRef = C81E104A13E1CCA000B1049A /* ResumeButton.png */; };
C81E105713E1CCA000B1049A /* SelectedBracket.png in Resources */ = {isa = PBXBuildFile; fileRef = C81E104B13E1CCA000B1049A /* SelectedBracket.png */; };
C84F829213D76E96006D01AB /* MapMenuView.m in Sources */ = {isa = PBXBuildFile; fileRef = C84F829013D76E96006D01AB /* MapMenuView.m */; };
C84F83F613D7A99C006D01AB /* GenericMenuView.m in Sources */ = {isa = PBXBuildFile; fileRef = C84F83F513D7A99C006D01AB /* GenericMenuView.m */; };
C84F855913D8B55C006D01AB /* SettingsMenuView.m in Sources */ = {isa = PBXBuildFile; fileRef = C84F855813D8B55C006D01AB /* SettingsMenuView.m */; };
C861F27213BD2DC600DB34A8 /* MainWindow-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = C861F27113BD2DC600DB34A8 /* MainWindow-iPad.xib */; };
C86F966813D617740069B7B6 /* MenuViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = C86F966713D617740069B7B6 /* MenuViewController.mm */; };
C86F975E13D6377B0069B7B6 /* IBGlue.m in Sources */ = {isa = PBXBuildFile; fileRef = C86F975D13D6377B0069B7B6 /* IBGlue.m */; };
C8792ED813F5AFE5003D834F /* BackButton_Highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = C8792ED113F5AFE5003D834F /* BackButton_Highlighted.png */; };
C8792ED913F5AFE6003D834F /* Button_Highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = C8792ED213F5AFE5003D834F /* Button_Highlighted.png */; };
C8792EDA13F5AFE6003D834F /* NextButton_Highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = C8792ED313F5AFE5003D834F /* NextButton_Highlighted.png */; };
C8792EDB13F5AFE6003D834F /* NextButton.png in Resources */ = {isa = PBXBuildFile; fileRef = C8792ED413F5AFE5003D834F /* NextButton.png */; };
C8792EDC13F5AFE6003D834F /* SubMenuBackground.png in Resources */ = {isa = PBXBuildFile; fileRef = C8792ED513F5AFE5003D834F /* SubMenuBackground.png */; };
C8792EDD13F5AFE6003D834F /* SubMenuButton_Highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = C8792ED613F5AFE5003D834F /* SubMenuButton_Highlighted.png */; };
C8792EDE13F5AFE6003D834F /* SubMenuButton.png in Resources */ = {isa = PBXBuildFile; fileRef = C8792ED713F5AFE5003D834F /* SubMenuButton.png */; };
C879308F13F5D8AA003D834F /* DifficultyBackground.png in Resources */ = {isa = PBXBuildFile; fileRef = C879308513F5D8AA003D834F /* DifficultyBackground.png */; };
C879309013F5D8AA003D834F /* DownArrow_Highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = C879308613F5D8AA003D834F /* DownArrow_Highlighted.png */; };
C879309113F5D8AA003D834F /* DownArrow.png in Resources */ = {isa = PBXBuildFile; fileRef = C879308713F5D8AA003D834F /* DownArrow.png */; };
C879309213F5D8AA003D834F /* Episode1Background.png in Resources */ = {isa = PBXBuildFile; fileRef = C879308813F5D8AA003D834F /* Episode1Background.png */; };
C879309313F5D8AA003D834F /* Episode2Background.png in Resources */ = {isa = PBXBuildFile; fileRef = C879308913F5D8AA003D834F /* Episode2Background.png */; };
C879309413F5D8AA003D834F /* Episode3Background.png in Resources */ = {isa = PBXBuildFile; fileRef = C879308A13F5D8AA003D834F /* Episode3Background.png */; };
C879309513F5D8AA003D834F /* Episode4Background.png in Resources */ = {isa = PBXBuildFile; fileRef = C879308B13F5D8AA003D834F /* Episode4Background.png */; };
C879309613F5D8AA003D834F /* MissonBackground.png in Resources */ = {isa = PBXBuildFile; fileRef = C879308C13F5D8AA003D834F /* MissonBackground.png */; };
C879309713F5D8AA003D834F /* UpArrow_Highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = C879308D13F5D8AA003D834F /* UpArrow_Highlighted.png */; };
C879309813F5D8AA003D834F /* UpArrow.png in Resources */ = {isa = PBXBuildFile; fileRef = C879308E13F5D8AA003D834F /* UpArrow.png */; };
C87930E513F5EC1B003D834F /* Episode1Background_Highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = C87930E113F5EC1B003D834F /* Episode1Background_Highlighted.png */; };
C87930E613F5EC1B003D834F /* Episode2Background_Highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = C87930E213F5EC1B003D834F /* Episode2Background_Highlighted.png */; };
C87930E713F5EC1B003D834F /* Episode3Background_Highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = C87930E313F5EC1B003D834F /* Episode3Background_Highlighted.png */; };
C87930E813F5EC1B003D834F /* Episode4Background_Highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = C87930E413F5EC1B003D834F /* Episode4Background_Highlighted.png */; };
C87931EC13F610B9003D834F /* AdvancedButton_Highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = C87931DE13F610B9003D834F /* AdvancedButton_Highlighted.png */; };
C87931ED13F610B9003D834F /* AdvancedButton.png in Resources */ = {isa = PBXBuildFile; fileRef = C87931DF13F610B9003D834F /* AdvancedButton.png */; };
C87931EE13F610B9003D834F /* Divide.png in Resources */ = {isa = PBXBuildFile; fileRef = C87931E013F610B9003D834F /* Divide.png */; };
C87931EF13F610B9003D834F /* LayoutDualButton_Highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = C87931E113F610B9003D834F /* LayoutDualButton_Highlighted.png */; };
C87931F013F610B9003D834F /* LayoutDualButton.png in Resources */ = {isa = PBXBuildFile; fileRef = C87931E213F610B9003D834F /* LayoutDualButton.png */; };
C87931F113F610B9003D834F /* LayoutSingleButton_Highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = C87931E313F610B9003D834F /* LayoutSingleButton_Highlighted.png */; };
C87931F213F610B9003D834F /* LayoutSingleButton.png in Resources */ = {isa = PBXBuildFile; fileRef = C87931E413F610B9003D834F /* LayoutSingleButton.png */; };
C87931F313F610B9003D834F /* LayoutWheelButton_Highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = C87931E513F610B9003D834F /* LayoutWheelButton_Highlighted.png */; };
C87931F413F610B9003D834F /* LayoutWheelButton.png in Resources */ = {isa = PBXBuildFile; fileRef = C87931E613F610B9003D834F /* LayoutWheelButton.png */; };
C87931F513F610B9003D834F /* SettingsButton_Highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = C87931E713F610B9003D834F /* SettingsButton_Highlighted.png */; };
C87931F613F610B9003D834F /* SettingsButton.png in Resources */ = {isa = PBXBuildFile; fileRef = C87931E813F610B9003D834F /* SettingsButton.png */; };
C87931F713F610B9003D834F /* SliderBackground.png in Resources */ = {isa = PBXBuildFile; fileRef = C87931E913F610B9003D834F /* SliderBackground.png */; };
C87931F813F610B9003D834F /* SliderBar.png in Resources */ = {isa = PBXBuildFile; fileRef = C87931EA13F610B9003D834F /* SliderBar.png */; };
C87931F913F610B9003D834F /* SliderSkull.png in Resources */ = {isa = PBXBuildFile; fileRef = C87931EB13F610B9003D834F /* SliderSkull.png */; };
C879320113F6143C003D834F /* UICustomSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = C879320013F6143C003D834F /* UICustomSwitch.m */; };
C88530C913D8CBEA00A5FBF7 /* MainMenuView.m in Sources */ = {isa = PBXBuildFile; fileRef = C88530C813D8CBEA00A5FBF7 /* MainMenuView.m */; };
C885314413D8D79400A5FBF7 /* ControlsMenuView.m in Sources */ = {isa = PBXBuildFile; fileRef = C885314213D8D79400A5FBF7 /* ControlsMenuView.m */; };
C8D1CF6813DE1EB600F0EAC6 /* DOOM_57.png in Resources */ = {isa = PBXBuildFile; fileRef = C8D1CF6713DE1EB600F0EAC6 /* DOOM_57.png */; };
C8D1CF6A13DE1EF500F0EAC6 /* DOOM_114.png in Resources */ = {isa = PBXBuildFile; fileRef = C8D1CF6913DE1EF500F0EAC6 /* DOOM_114.png */; };
C8D1CF6C13DE1F0600F0EAC6 /* DOOM_72.png in Resources */ = {isa = PBXBuildFile; fileRef = C8D1CF6B13DE1F0600F0EAC6 /* DOOM_72.png */; };
C8D1CF8613DF792D00F0EAC6 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C8D1CF8513DF792D00F0EAC6 /* Default@2x.png */; };
C8D1CF8813DF79BC00F0EAC6 /* Default~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = C8D1CF8713DF79BC00F0EAC6 /* Default~ipad.png */; };
C8D1CFA813E1CDBD00F0EAC6 /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = C8D1CFA713E1CDBD00F0EAC6 /* Default-Portrait~ipad.png */; };
C8D1CFAA13E1CDC600F0EAC6 /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = C8D1CFA913E1CDC600F0EAC6 /* Default-Landscape~ipad.png */; };
ED9AB3D110966E85000B5852 /* iphone_email.m in Sources */ = {isa = PBXBuildFile; fileRef = ED9AB3D010966E85000B5852 /* iphone_email.m */; };
EDD2760511C2B19E004A9B9B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDD2760411C2B19E004A9B9B /* CoreGraphics.framework */; };
EDD2760711C2B19E004A9B9B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDD2760611C2B19E004A9B9B /* Foundation.framework */; };
EDD2760911C2B19E004A9B9B /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDD2760811C2B19E004A9B9B /* OpenGLES.framework */; };
EDD2760B11C2B19E004A9B9B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDD2760A11C2B19E004A9B9B /* UIKit.framework */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
1D6058910D05DD3D006BFB54 /* Doom.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Doom.app; sourceTree = BUILT_PRODUCTS_DIR; };
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = "<group>"; };
28FD14FF0DC6FC520079059D /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
4333CCE70F5CC23E00AE2B6F /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = "<absolute>"; };
434669950F8D058400EA7D6D /* Doom_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Doom_icon.png; sourceTree = "<group>"; };
434669A30F8D08C000EA7D6D /* doom_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = doom_Prefix.pch; sourceTree = "<group>"; };
434669A40F8D08C000EA7D6D /* doomAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = doomAppDelegate.h; sourceTree = "<group>"; };
434669A50F8D08C000EA7D6D /* doomAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = doomAppDelegate.m; sourceTree = "<group>"; };
4364BF3E0F5CB25900F29317 /* dist.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = dist.plist; sourceTree = "<group>"; };
43A945140F82D75900FFD32E /* iphone_sys.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = iphone_sys.c; sourceTree = "<group>"; };
43AE7E9E0F67387500B2F562 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
43CF02FE0F56974E00E4A23D /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = "<group>"; };
43CF03090F56D5C200E4A23D /* iphone_loop.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = iphone_loop.c; sourceTree = "<group>"; };
43DD8391100295F70006E1DD /* iphone_async.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = iphone_async.c; sourceTree = "<group>"; };
@ -336,8 +399,92 @@
72F1F9B20F96C18800AD49AC /* tessmono.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tessmono.c; path = ../libtess/tessmono.c; sourceTree = SOURCE_ROOT; };
72F1F9B30F96C18800AD49AC /* tessmono.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tessmono.h; path = ../libtess/tessmono.h; sourceTree = SOURCE_ROOT; };
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C8139A7713F9E0440094C2C0 /* UICustomSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UICustomSlider.h; sourceTree = "<group>"; };
C8139A7813F9E0440094C2C0 /* UICustomSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UICustomSlider.m; sourceTree = "<group>"; };
C8139AB213FADA800094C2C0 /* SliderSkull@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "SliderSkull@2x.png"; path = "../../IB Images/SliderSkull@2x.png"; sourceTree = SOURCE_ROOT; };
C8139AB413FADA9D0094C2C0 /* SliderSkull~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "SliderSkull~ipad.png"; path = "../../IB Images/SliderSkull~ipad.png"; sourceTree = SOURCE_ROOT; };
C81E0C7013DF471000B1049A /* UIFontButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIFontButton.h; sourceTree = "<group>"; };
C81E0C7113DF471000B1049A /* UIFontButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIFontButton.m; sourceTree = "<group>"; };
C81E0C8D13DF4A1B00B1049A /* UIFontLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIFontLabel.h; sourceTree = "<group>"; };
C81E0C8E13DF4A1B00B1049A /* UIFontLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIFontLabel.m; sourceTree = "<group>"; };
C81E0E5D13E076E400B1049A /* idGinzaNar-Md2.otf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "idGinzaNar-Md2.otf"; path = "../../idGinzaNar-Md2.otf"; sourceTree = SOURCE_ROOT; };
C81E104013E1CCA000B1049A /* BackButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = BackButton.png; path = "../../IB Images/BackButton.png"; sourceTree = SOURCE_ROOT; };
C81E104113E1CCA000B1049A /* Button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Button.png; path = "../../IB Images/Button.png"; sourceTree = SOURCE_ROOT; };
C81E104213E1CCA000B1049A /* DOOM_sigil_decal.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = DOOM_sigil_decal.png; path = "../../IB Images/DOOM_sigil_decal.png"; sourceTree = SOURCE_ROOT; };
C81E104313E1CCA000B1049A /* DoomLogo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = DoomLogo.png; path = "../../IB Images/DoomLogo.png"; sourceTree = SOURCE_ROOT; };
C81E104413E1CCA000B1049A /* Easy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Easy.png; path = "../../IB Images/Easy.png"; sourceTree = SOURCE_ROOT; };
C81E104513E1CCA000B1049A /* Hard.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Hard.png; path = "../../IB Images/Hard.png"; sourceTree = SOURCE_ROOT; };
C81E104613E1CCA000B1049A /* MapOverlay.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = MapOverlay.png; path = "../../IB Images/MapOverlay.png"; sourceTree = SOURCE_ROOT; };
C81E104713E1CCA000B1049A /* Medium.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Medium.png; path = "../../IB Images/Medium.png"; sourceTree = SOURCE_ROOT; };
C81E104813E1CCA000B1049A /* MenuBackground.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = MenuBackground.png; path = "../../IB Images/MenuBackground.png"; sourceTree = SOURCE_ROOT; };
C81E104913E1CCA000B1049A /* Nightmare.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Nightmare.png; path = "../../IB Images/Nightmare.png"; sourceTree = SOURCE_ROOT; };
C81E104A13E1CCA000B1049A /* ResumeButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ResumeButton.png; path = "../../IB Images/ResumeButton.png"; sourceTree = SOURCE_ROOT; };
C81E104B13E1CCA000B1049A /* SelectedBracket.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = SelectedBracket.png; path = "../../IB Images/SelectedBracket.png"; sourceTree = SOURCE_ROOT; };
C84F829013D76E96006D01AB /* MapMenuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MapMenuView.m; sourceTree = "<group>"; };
C84F829113D76E96006D01AB /* MapMenuView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapMenuView.h; sourceTree = "<group>"; };
C84F83F413D7A99C006D01AB /* GenericMenuView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericMenuView.h; sourceTree = "<group>"; };
C84F83F513D7A99C006D01AB /* GenericMenuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GenericMenuView.m; sourceTree = "<group>"; };
C84F855713D8B55C006D01AB /* SettingsMenuView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsMenuView.h; sourceTree = "<group>"; };
C84F855813D8B55C006D01AB /* SettingsMenuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsMenuView.m; sourceTree = "<group>"; };
C861F27113BD2DC600DB34A8 /* MainWindow-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "MainWindow-iPad.xib"; path = "Resources-iPad/MainWindow-iPad.xib"; sourceTree = "<group>"; };
C86F965513D615F70069B7B6 /* MainMenuView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainMenuView.h; sourceTree = "<group>"; };
C86F966613D617740069B7B6 /* MenuViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MenuViewController.h; sourceTree = "<group>"; };
C86F966713D617740069B7B6 /* MenuViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MenuViewController.mm; sourceTree = "<group>"; };
C86F975C13D6377B0069B7B6 /* IBGlue.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = IBGlue.h; sourceTree = "<group>"; };
C86F975D13D6377B0069B7B6 /* IBGlue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IBGlue.m; sourceTree = "<group>"; };
C8792ED113F5AFE5003D834F /* BackButton_Highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = BackButton_Highlighted.png; path = "../../IB Images/BackButton_Highlighted.png"; sourceTree = SOURCE_ROOT; };
C8792ED213F5AFE5003D834F /* Button_Highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Button_Highlighted.png; path = "../../IB Images/Button_Highlighted.png"; sourceTree = SOURCE_ROOT; };
C8792ED313F5AFE5003D834F /* NextButton_Highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = NextButton_Highlighted.png; path = "../../IB Images/NextButton_Highlighted.png"; sourceTree = SOURCE_ROOT; };
C8792ED413F5AFE5003D834F /* NextButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = NextButton.png; path = "../../IB Images/NextButton.png"; sourceTree = SOURCE_ROOT; };
C8792ED513F5AFE5003D834F /* SubMenuBackground.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = SubMenuBackground.png; path = "../../IB Images/SubMenuBackground.png"; sourceTree = SOURCE_ROOT; };
C8792ED613F5AFE5003D834F /* SubMenuButton_Highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = SubMenuButton_Highlighted.png; path = "../../IB Images/SubMenuButton_Highlighted.png"; sourceTree = SOURCE_ROOT; };
C8792ED713F5AFE5003D834F /* SubMenuButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = SubMenuButton.png; path = "../../IB Images/SubMenuButton.png"; sourceTree = SOURCE_ROOT; };
C879308513F5D8AA003D834F /* DifficultyBackground.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = DifficultyBackground.png; path = "../../IB Images/DifficultyBackground.png"; sourceTree = SOURCE_ROOT; };
C879308613F5D8AA003D834F /* DownArrow_Highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = DownArrow_Highlighted.png; path = "../../IB Images/DownArrow_Highlighted.png"; sourceTree = SOURCE_ROOT; };
C879308713F5D8AA003D834F /* DownArrow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = DownArrow.png; path = "../../IB Images/DownArrow.png"; sourceTree = SOURCE_ROOT; };
C879308813F5D8AA003D834F /* Episode1Background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Episode1Background.png; path = "../../IB Images/Episode1Background.png"; sourceTree = SOURCE_ROOT; };
C879308913F5D8AA003D834F /* Episode2Background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Episode2Background.png; path = "../../IB Images/Episode2Background.png"; sourceTree = SOURCE_ROOT; };
C879308A13F5D8AA003D834F /* Episode3Background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Episode3Background.png; path = "../../IB Images/Episode3Background.png"; sourceTree = SOURCE_ROOT; };
C879308B13F5D8AA003D834F /* Episode4Background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Episode4Background.png; path = "../../IB Images/Episode4Background.png"; sourceTree = SOURCE_ROOT; };
C879308C13F5D8AA003D834F /* MissonBackground.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = MissonBackground.png; path = "../../IB Images/MissonBackground.png"; sourceTree = SOURCE_ROOT; };
C879308D13F5D8AA003D834F /* UpArrow_Highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = UpArrow_Highlighted.png; path = "../../IB Images/UpArrow_Highlighted.png"; sourceTree = SOURCE_ROOT; };
C879308E13F5D8AA003D834F /* UpArrow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = UpArrow.png; path = "../../IB Images/UpArrow.png"; sourceTree = SOURCE_ROOT; };
C87930E113F5EC1B003D834F /* Episode1Background_Highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Episode1Background_Highlighted.png; path = "../../IB Images/Episode1Background_Highlighted.png"; sourceTree = SOURCE_ROOT; };
C87930E213F5EC1B003D834F /* Episode2Background_Highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Episode2Background_Highlighted.png; path = "../../IB Images/Episode2Background_Highlighted.png"; sourceTree = SOURCE_ROOT; };
C87930E313F5EC1B003D834F /* Episode3Background_Highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Episode3Background_Highlighted.png; path = "../../IB Images/Episode3Background_Highlighted.png"; sourceTree = SOURCE_ROOT; };
C87930E413F5EC1B003D834F /* Episode4Background_Highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Episode4Background_Highlighted.png; path = "../../IB Images/Episode4Background_Highlighted.png"; sourceTree = SOURCE_ROOT; };
C87931DE13F610B9003D834F /* AdvancedButton_Highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = AdvancedButton_Highlighted.png; path = "../../IB Images/AdvancedButton_Highlighted.png"; sourceTree = SOURCE_ROOT; };
C87931DF13F610B9003D834F /* AdvancedButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = AdvancedButton.png; path = "../../IB Images/AdvancedButton.png"; sourceTree = SOURCE_ROOT; };
C87931E013F610B9003D834F /* Divide.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Divide.png; path = "../../IB Images/Divide.png"; sourceTree = SOURCE_ROOT; };
C87931E113F610B9003D834F /* LayoutDualButton_Highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = LayoutDualButton_Highlighted.png; path = "../../IB Images/LayoutDualButton_Highlighted.png"; sourceTree = SOURCE_ROOT; };
C87931E213F610B9003D834F /* LayoutDualButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = LayoutDualButton.png; path = "../../IB Images/LayoutDualButton.png"; sourceTree = SOURCE_ROOT; };
C87931E313F610B9003D834F /* LayoutSingleButton_Highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = LayoutSingleButton_Highlighted.png; path = "../../IB Images/LayoutSingleButton_Highlighted.png"; sourceTree = SOURCE_ROOT; };
C87931E413F610B9003D834F /* LayoutSingleButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = LayoutSingleButton.png; path = "../../IB Images/LayoutSingleButton.png"; sourceTree = SOURCE_ROOT; };
C87931E513F610B9003D834F /* LayoutWheelButton_Highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = LayoutWheelButton_Highlighted.png; path = "../../IB Images/LayoutWheelButton_Highlighted.png"; sourceTree = SOURCE_ROOT; };
C87931E613F610B9003D834F /* LayoutWheelButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = LayoutWheelButton.png; path = "../../IB Images/LayoutWheelButton.png"; sourceTree = SOURCE_ROOT; };
C87931E713F610B9003D834F /* SettingsButton_Highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = SettingsButton_Highlighted.png; path = "../../IB Images/SettingsButton_Highlighted.png"; sourceTree = SOURCE_ROOT; };
C87931E813F610B9003D834F /* SettingsButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = SettingsButton.png; path = "../../IB Images/SettingsButton.png"; sourceTree = SOURCE_ROOT; };
C87931E913F610B9003D834F /* SliderBackground.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = SliderBackground.png; path = "../../IB Images/SliderBackground.png"; sourceTree = SOURCE_ROOT; };
C87931EA13F610B9003D834F /* SliderBar.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = SliderBar.png; path = "../../IB Images/SliderBar.png"; sourceTree = SOURCE_ROOT; };
C87931EB13F610B9003D834F /* SliderSkull.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = SliderSkull.png; path = "../../IB Images/SliderSkull.png"; sourceTree = SOURCE_ROOT; };
C87931FF13F6143C003D834F /* UICustomSwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UICustomSwitch.h; sourceTree = "<group>"; };
C879320013F6143C003D834F /* UICustomSwitch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UICustomSwitch.m; sourceTree = "<group>"; };
C88530C813D8CBEA00A5FBF7 /* MainMenuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainMenuView.m; sourceTree = "<group>"; };
C885314213D8D79400A5FBF7 /* ControlsMenuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ControlsMenuView.m; sourceTree = "<group>"; };
C885314313D8D79400A5FBF7 /* ControlsMenuView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ControlsMenuView.h; sourceTree = "<group>"; };
C8D1CF6713DE1EB600F0EAC6 /* DOOM_57.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = DOOM_57.png; sourceTree = "<group>"; };
C8D1CF6913DE1EF500F0EAC6 /* DOOM_114.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = DOOM_114.png; sourceTree = "<group>"; };
C8D1CF6B13DE1F0600F0EAC6 /* DOOM_72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = DOOM_72.png; sourceTree = "<group>"; };
C8D1CF8513DF792D00F0EAC6 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = "<group>"; };
C8D1CF8713DF79BC00F0EAC6 /* Default~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default~ipad.png"; sourceTree = "<group>"; };
C8D1CFA713E1CDBD00F0EAC6 /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait~ipad.png"; sourceTree = "<group>"; };
C8D1CFA913E1CDC600F0EAC6 /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape~ipad.png"; sourceTree = "<group>"; };
ED9AB3CF10966E85000B5852 /* iphone_email.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iphone_email.h; sourceTree = "<group>"; };
ED9AB3D010966E85000B5852 /* iphone_email.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iphone_email.m; sourceTree = "<group>"; };
EDD2760411C2B19E004A9B9B /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
EDD2760611C2B19E004A9B9B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
EDD2760811C2B19E004A9B9B /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
EDD2760A11C2B19E004A9B9B /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -345,13 +492,13 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */,
43E8D4E00F51B48B003F09B2 /* OpenAL.framework in Frameworks */,
4333CCE80F5CC23E00AE2B6F /* AudioToolbox.framework in Frameworks */,
43AE7E9F0F67387500B2F562 /* CoreGraphics.framework in Frameworks */,
720EBBAE0F82E0BB003F989A /* QuartzCore.framework in Frameworks */,
EDD2760511C2B19E004A9B9B /* CoreGraphics.framework in Frameworks */,
EDD2760711C2B19E004A9B9B /* Foundation.framework in Frameworks */,
EDD2760911C2B19E004A9B9B /* OpenGLES.framework in Frameworks */,
EDD2760B11C2B19E004A9B9B /* UIKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -370,11 +517,17 @@
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
isa = PBXGroup;
children = (
C8D1CFA913E1CDC600F0EAC6 /* Default-Landscape~ipad.png */,
C8D1CFA713E1CDBD00F0EAC6 /* Default-Portrait~ipad.png */,
C8D1CF8713DF79BC00F0EAC6 /* Default~ipad.png */,
C8D1CF8513DF792D00F0EAC6 /* Default@2x.png */,
C8D1CF6B13DE1F0600F0EAC6 /* DOOM_72.png */,
C8D1CF6913DE1EF500F0EAC6 /* DOOM_114.png */,
C8D1CF6713DE1EB600F0EAC6 /* DOOM_57.png */,
29B97315FDCFA39411CA2CEA /* Other Sources */,
29B97317FDCFA39411CA2CEA /* Resources */,
29B97323FDCFA39411CA2CEA /* Frameworks */,
19C28FACFE9D520D11CA2CBB /* Products */,
43AE7E9E0F67387500B2F562 /* CoreGraphics.framework */,
);
name = CustomTemplate;
sourceTree = "<group>";
@ -382,6 +535,7 @@
29B97315FDCFA39411CA2CEA /* Other Sources */ = {
isa = PBXGroup;
children = (
C86F965213D615BB0069B7B6 /* InterfaceBuilder */,
72F1F94B0F96B55B00AD49AC /* libtess */,
72E847620F93C5F900AB3C99 /* prboom */,
72E8495C0F942B9300AB3C99 /* cvar.c */,
@ -423,7 +577,8 @@
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
434669950F8D058400EA7D6D /* Doom_icon.png */,
C84F820613D73D28006D01AB /* Interface Builder Images */,
C861F27113BD2DC600DB34A8 /* MainWindow-iPad.xib */,
43CF02FE0F56974E00E4A23D /* Default.png */,
28AD733E0D9D9553002E5188 /* MainWindow.xib */,
8D1107310486CEB800E47090 /* Info.plist */,
@ -437,9 +592,10 @@
720EBBAD0F82E0BB003F989A /* QuartzCore.framework */,
4333CCE70F5CC23E00AE2B6F /* AudioToolbox.framework */,
43E8D4DF0F51B48B003F09B2 /* OpenAL.framework */,
28FD14FF0DC6FC520079059D /* OpenGLES.framework */,
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
1D30AB110D05D00D00671497 /* Foundation.framework */,
EDD2760411C2B19E004A9B9B /* CoreGraphics.framework */,
EDD2760611C2B19E004A9B9B /* Foundation.framework */,
EDD2760811C2B19E004A9B9B /* OpenGLES.framework */,
EDD2760A11C2B19E004A9B9B /* UIKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@ -629,6 +785,92 @@
name = libtess;
sourceTree = "<group>";
};
C84F820613D73D28006D01AB /* Interface Builder Images */ = {
isa = PBXGroup;
children = (
C8139AB413FADA9D0094C2C0 /* SliderSkull~ipad.png */,
C8139AB213FADA800094C2C0 /* SliderSkull@2x.png */,
C87931DE13F610B9003D834F /* AdvancedButton_Highlighted.png */,
C87931DF13F610B9003D834F /* AdvancedButton.png */,
C87931E013F610B9003D834F /* Divide.png */,
C87931E113F610B9003D834F /* LayoutDualButton_Highlighted.png */,
C87931E213F610B9003D834F /* LayoutDualButton.png */,
C87931E313F610B9003D834F /* LayoutSingleButton_Highlighted.png */,
C87931E413F610B9003D834F /* LayoutSingleButton.png */,
C87931E513F610B9003D834F /* LayoutWheelButton_Highlighted.png */,
C87931E613F610B9003D834F /* LayoutWheelButton.png */,
C87931E713F610B9003D834F /* SettingsButton_Highlighted.png */,
C87931E813F610B9003D834F /* SettingsButton.png */,
C87931E913F610B9003D834F /* SliderBackground.png */,
C87931EA13F610B9003D834F /* SliderBar.png */,
C87931EB13F610B9003D834F /* SliderSkull.png */,
C87930E113F5EC1B003D834F /* Episode1Background_Highlighted.png */,
C87930E213F5EC1B003D834F /* Episode2Background_Highlighted.png */,
C87930E313F5EC1B003D834F /* Episode3Background_Highlighted.png */,
C87930E413F5EC1B003D834F /* Episode4Background_Highlighted.png */,
C879308513F5D8AA003D834F /* DifficultyBackground.png */,
C879308613F5D8AA003D834F /* DownArrow_Highlighted.png */,
C879308713F5D8AA003D834F /* DownArrow.png */,
C879308813F5D8AA003D834F /* Episode1Background.png */,
C879308913F5D8AA003D834F /* Episode2Background.png */,
C879308A13F5D8AA003D834F /* Episode3Background.png */,
C879308B13F5D8AA003D834F /* Episode4Background.png */,
C879308C13F5D8AA003D834F /* MissonBackground.png */,
C879308D13F5D8AA003D834F /* UpArrow_Highlighted.png */,
C879308E13F5D8AA003D834F /* UpArrow.png */,
C8792ED113F5AFE5003D834F /* BackButton_Highlighted.png */,
C8792ED213F5AFE5003D834F /* Button_Highlighted.png */,
C8792ED313F5AFE5003D834F /* NextButton_Highlighted.png */,
C8792ED413F5AFE5003D834F /* NextButton.png */,
C8792ED513F5AFE5003D834F /* SubMenuBackground.png */,
C8792ED613F5AFE5003D834F /* SubMenuButton_Highlighted.png */,
C8792ED713F5AFE5003D834F /* SubMenuButton.png */,
C81E104013E1CCA000B1049A /* BackButton.png */,
C81E104113E1CCA000B1049A /* Button.png */,
C81E104213E1CCA000B1049A /* DOOM_sigil_decal.png */,
C81E104313E1CCA000B1049A /* DoomLogo.png */,
C81E104413E1CCA000B1049A /* Easy.png */,
C81E104513E1CCA000B1049A /* Hard.png */,
C81E104613E1CCA000B1049A /* MapOverlay.png */,
C81E104713E1CCA000B1049A /* Medium.png */,
C81E104813E1CCA000B1049A /* MenuBackground.png */,
C81E104913E1CCA000B1049A /* Nightmare.png */,
C81E104A13E1CCA000B1049A /* ResumeButton.png */,
C81E104B13E1CCA000B1049A /* SelectedBracket.png */,
C81E0E5D13E076E400B1049A /* idGinzaNar-Md2.otf */,
);
name = "Interface Builder Images";
sourceTree = "<group>";
};
C86F965213D615BB0069B7B6 /* InterfaceBuilder */ = {
isa = PBXGroup;
children = (
C8139A7713F9E0440094C2C0 /* UICustomSlider.h */,
C8139A7813F9E0440094C2C0 /* UICustomSlider.m */,
C84F83F413D7A99C006D01AB /* GenericMenuView.h */,
C84F83F513D7A99C006D01AB /* GenericMenuView.m */,
C84F829013D76E96006D01AB /* MapMenuView.m */,
C84F829113D76E96006D01AB /* MapMenuView.h */,
C84F855713D8B55C006D01AB /* SettingsMenuView.h */,
C84F855813D8B55C006D01AB /* SettingsMenuView.m */,
C885314213D8D79400A5FBF7 /* ControlsMenuView.m */,
C885314313D8D79400A5FBF7 /* ControlsMenuView.h */,
C86F966613D617740069B7B6 /* MenuViewController.h */,
C86F966713D617740069B7B6 /* MenuViewController.mm */,
C86F965513D615F70069B7B6 /* MainMenuView.h */,
C88530C813D8CBEA00A5FBF7 /* MainMenuView.m */,
C86F975C13D6377B0069B7B6 /* IBGlue.h */,
C86F975D13D6377B0069B7B6 /* IBGlue.m */,
C81E0C7013DF471000B1049A /* UIFontButton.h */,
C81E0C7113DF471000B1049A /* UIFontButton.m */,
C81E0C8D13DF4A1B00B1049A /* UIFontLabel.h */,
C81E0C8E13DF4A1B00B1049A /* UIFontLabel.m */,
C87931FF13F6143C003D834F /* UICustomSwitch.h */,
C879320013F6143C003D834F /* UICustomSwitch.m */,
);
name = InterfaceBuilder;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -657,10 +899,17 @@
isa = PBXProject;
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Doom" */;
compatibilityVersion = "Xcode 3.1";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
Japanese,
French,
German,
);
mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
projectDirPath = "";
projectRoot = "";
projectRoot = ../..;
targets = (
1D6058900D05DD3D006BFB54 /* Doom */,
);
@ -675,7 +924,64 @@
28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */,
43CF02FF0F56974E00E4A23D /* Default.png in Resources */,
4364BF3F0F5CB25900F29317 /* dist.plist in Resources */,
434669960F8D058400EA7D6D /* Doom_icon.png in Resources */,
C861F27213BD2DC600DB34A8 /* MainWindow-iPad.xib in Resources */,
C8D1CF6813DE1EB600F0EAC6 /* DOOM_57.png in Resources */,
C8D1CF6A13DE1EF500F0EAC6 /* DOOM_114.png in Resources */,
C8D1CF6C13DE1F0600F0EAC6 /* DOOM_72.png in Resources */,
C8D1CF8613DF792D00F0EAC6 /* Default@2x.png in Resources */,
C8D1CF8813DF79BC00F0EAC6 /* Default~ipad.png in Resources */,
C81E0E5E13E076E400B1049A /* idGinzaNar-Md2.otf in Resources */,
C81E104C13E1CCA000B1049A /* BackButton.png in Resources */,
C81E104D13E1CCA000B1049A /* Button.png in Resources */,
C81E104E13E1CCA000B1049A /* DOOM_sigil_decal.png in Resources */,
C81E104F13E1CCA000B1049A /* DoomLogo.png in Resources */,
C81E105013E1CCA000B1049A /* Easy.png in Resources */,
C81E105113E1CCA000B1049A /* Hard.png in Resources */,
C81E105213E1CCA000B1049A /* MapOverlay.png in Resources */,
C81E105313E1CCA000B1049A /* Medium.png in Resources */,
C81E105413E1CCA000B1049A /* MenuBackground.png in Resources */,
C81E105513E1CCA000B1049A /* Nightmare.png in Resources */,
C81E105613E1CCA000B1049A /* ResumeButton.png in Resources */,
C81E105713E1CCA000B1049A /* SelectedBracket.png in Resources */,
C8D1CFA813E1CDBD00F0EAC6 /* Default-Portrait~ipad.png in Resources */,
C8D1CFAA13E1CDC600F0EAC6 /* Default-Landscape~ipad.png in Resources */,
C8792ED813F5AFE5003D834F /* BackButton_Highlighted.png in Resources */,
C8792ED913F5AFE6003D834F /* Button_Highlighted.png in Resources */,
C8792EDA13F5AFE6003D834F /* NextButton_Highlighted.png in Resources */,
C8792EDB13F5AFE6003D834F /* NextButton.png in Resources */,
C8792EDC13F5AFE6003D834F /* SubMenuBackground.png in Resources */,
C8792EDD13F5AFE6003D834F /* SubMenuButton_Highlighted.png in Resources */,
C8792EDE13F5AFE6003D834F /* SubMenuButton.png in Resources */,
C879308F13F5D8AA003D834F /* DifficultyBackground.png in Resources */,
C879309013F5D8AA003D834F /* DownArrow_Highlighted.png in Resources */,
C879309113F5D8AA003D834F /* DownArrow.png in Resources */,
C879309213F5D8AA003D834F /* Episode1Background.png in Resources */,
C879309313F5D8AA003D834F /* Episode2Background.png in Resources */,
C879309413F5D8AA003D834F /* Episode3Background.png in Resources */,
C879309513F5D8AA003D834F /* Episode4Background.png in Resources */,
C879309613F5D8AA003D834F /* MissonBackground.png in Resources */,
C879309713F5D8AA003D834F /* UpArrow_Highlighted.png in Resources */,
C879309813F5D8AA003D834F /* UpArrow.png in Resources */,
C87930E513F5EC1B003D834F /* Episode1Background_Highlighted.png in Resources */,
C87930E613F5EC1B003D834F /* Episode2Background_Highlighted.png in Resources */,
C87930E713F5EC1B003D834F /* Episode3Background_Highlighted.png in Resources */,
C87930E813F5EC1B003D834F /* Episode4Background_Highlighted.png in Resources */,
C87931EC13F610B9003D834F /* AdvancedButton_Highlighted.png in Resources */,
C87931ED13F610B9003D834F /* AdvancedButton.png in Resources */,
C87931EE13F610B9003D834F /* Divide.png in Resources */,
C87931EF13F610B9003D834F /* LayoutDualButton_Highlighted.png in Resources */,
C87931F013F610B9003D834F /* LayoutDualButton.png in Resources */,
C87931F113F610B9003D834F /* LayoutSingleButton_Highlighted.png in Resources */,
C87931F213F610B9003D834F /* LayoutSingleButton.png in Resources */,
C87931F313F610B9003D834F /* LayoutWheelButton_Highlighted.png in Resources */,
C87931F413F610B9003D834F /* LayoutWheelButton.png in Resources */,
C87931F513F610B9003D834F /* SettingsButton_Highlighted.png in Resources */,
C87931F613F610B9003D834F /* SettingsButton.png in Resources */,
C87931F713F610B9003D834F /* SliderBackground.png in Resources */,
C87931F813F610B9003D834F /* SliderBar.png in Resources */,
C87931F913F610B9003D834F /* SliderSkull.png in Resources */,
C8139AB313FADA800094C2C0 /* SliderSkull@2x.png in Resources */,
C8139AB513FADA9D0094C2C0 /* SliderSkull~ipad.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -704,6 +1010,7 @@
files = (
1D60589B0D05DD56006BFB54 /* main.m in Sources */,
43E8D2E10F4FC61E003F09B2 /* iphone_main.c in Sources */,
C86F975E13D6377B0069B7B6 /* IBGlue.m in Sources */,
43CF030A0F56D5C200E4A23D /* iphone_loop.c in Sources */,
72A7E8F70F5F2063005B83C0 /* iphone_menus.c in Sources */,
7229CE4A0F6C89F8004123C5 /* EAGLView.m in Sources */,
@ -798,11 +1105,21 @@
72E731EB0F97E68100E702CD /* iphone_sound.c in Sources */,
7239452C0F9C0E7500EADD62 /* iphone_mapSelect.c in Sources */,
72484E5E0FB0E99900124E1C /* iphone_render.c in Sources */,
724C531F0FBDBCEE000E4348 /* BackgroundMusic.cpp in Sources */,
43DD8392100295F70006E1DD /* iphone_async.c in Sources */,
72A55EEF1003A94300F788A5 /* iphone_start.c in Sources */,
72A560E21004FAEE00F788A5 /* iphone_net.c in Sources */,
ED9AB3D110966E85000B5852 /* iphone_email.m in Sources */,
C86F966813D617740069B7B6 /* MenuViewController.mm in Sources */,
C84F829213D76E96006D01AB /* MapMenuView.m in Sources */,
C84F83F613D7A99C006D01AB /* GenericMenuView.m in Sources */,
C84F855913D8B55C006D01AB /* SettingsMenuView.m in Sources */,
724C531F0FBDBCEE000E4348 /* BackgroundMusic.cpp in Sources */,
C88530C913D8CBEA00A5FBF7 /* MainMenuView.m in Sources */,
C885314413D8D79400A5FBF7 /* ControlsMenuView.m in Sources */,
C81E0C7213DF471000B1049A /* UIFontButton.m in Sources */,
C81E0C8F13DF4A1B00B1049A /* UIFontLabel.m in Sources */,
C879320113F6143C003D834F /* UICustomSwitch.m in Sources */,
C8139A7913F9E0440094C2C0 /* UICustomSlider.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -813,7 +1130,8 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: John Carmack";
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
@ -826,8 +1144,12 @@
);
HEADER_SEARCH_PATHS = "";
INFOPLIST_FILE = Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 3.2;
PRODUCT_NAME = Doom;
PROFILE_PREFIX = com.idsoftware;
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
@ -835,7 +1157,8 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: John Carmack";
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = doom_Prefix.pch;
@ -845,8 +1168,12 @@
);
HEADER_SEARCH_PATHS = "";
INFOPLIST_FILE = Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 3.2;
PRODUCT_NAME = Doom;
PROFILE_PREFIX = com.idsoftware;
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
@ -855,15 +1182,18 @@
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CODE_SIGN_ENTITLEMENTS = dist.plist;
CODE_SIGN_IDENTITY = "iPhone Developer: John Carmack";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: John Carmack";
CODE_SIGN_IDENTITY = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_THUMB_SUPPORT = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = "";
PREBINDING = NO;
PRODUCT_NAME = Doom;
SDKROOT = iphoneos2.0;
PROVISIONING_PROFILE = "";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
SDKROOT = iphoneos3.0;
};
name = AdHocDist;
};
@ -871,7 +1201,8 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: id Software";
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = doom_Prefix.pch;
@ -881,8 +1212,12 @@
);
HEADER_SEARCH_PATHS = "";
INFOPLIST_FILE = Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 3.2;
PRODUCT_NAME = Doom;
PROFILE_PREFIX = com.idsoftware;
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = AdHocDist;
};
@ -890,15 +1225,16 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CODE_SIGN_IDENTITY = "iPhone Developer: John Carmack";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: John Carmack";
CODE_SIGN_IDENTITY = "iPhone Developer: Gregory Hodges (255R7FQ4L3)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Gregory Hodges (255R7FQ4L3)";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_THUMB_SUPPORT = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = "";
PREBINDING = NO;
PRODUCT_NAME = Doom;
SDKROOT = iphoneos2.0;
SDKROOT = iphoneos3.0;
};
name = ReleaseLite;
};
@ -906,7 +1242,9 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: John Carmack";
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = doom_Prefix.pch;
@ -916,8 +1254,13 @@
);
HEADER_SEARCH_PATHS = "";
INFOPLIST_FILE = Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 3.2;
PRODUCT_NAME = DoomLite;
PROFILE_PREFIX = com.idsoftware;
PROVISIONING_PROFILE = "";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = ReleaseLite;
};
@ -925,15 +1268,16 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CODE_SIGN_IDENTITY = "iPhone Developer: John Carmack";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: John Carmack";
CODE_SIGN_IDENTITY = "iPhone Developer: Gregory Hodges (255R7FQ4L3)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Gregory Hodges (255R7FQ4L3)";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = "";
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
PRODUCT_NAME = Doom;
SDKROOT = iphoneos2.0;
SDKROOT = iphoneos3.0;
};
name = DebugLite;
};
@ -941,7 +1285,9 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: John Carmack";
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
@ -953,8 +1299,13 @@
);
HEADER_SEARCH_PATHS = "";
INFOPLIST_FILE = Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 3.2;
PRODUCT_NAME = DoomLite;
PROFILE_PREFIX = com.idsoftware;
PROVISIONING_PROFILE = "";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = DebugLite;
};
@ -962,16 +1313,19 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CODE_SIGN_IDENTITY = "iPhone Developer: John Carmack";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: John Carmack";
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_PREPROCESSOR_DEFINITIONS = "HAVE_CONFIG_H=1";
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = "";
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
PRODUCT_NAME = Doom;
SDKROOT = iphoneos2.0;
PROVISIONING_PROFILE = "";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
SDKROOT = iphoneos;
};
name = Debug;
};
@ -979,18 +1333,19 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CODE_SIGN_IDENTITY = "iPhone Developer: John Carmack";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: John Carmack";
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_PREPROCESSOR_DEFINITIONS = HAVE_CONFIG_H;
GCC_THUMB_SUPPORT = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = "";
PREBINDING = NO;
PRODUCT_NAME = Doom;
PROVISIONING_PROFILE = "156B7F53-1BDC-4116-B0CC-F8CB2252E722";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "156B7F53-1BDC-4116-B0CC-F8CB2252E722";
SDKROOT = iphoneos2.0;
PROVISIONING_PROFILE = "";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
SDKROOT = iphoneos3.0;
};
name = Release;
};
@ -1005,11 +1360,12 @@
GCC_THUMB_SUPPORT = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = "";
PREBINDING = NO;
PRODUCT_NAME = Doom;
PROVISIONING_PROFILE = "31C73095-0DD9-4ABA-BB25-8D23F661F10F";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "31C73095-0DD9-4ABA-BB25-8D23F661F10F";
SDKROOT = iphoneos2.0;
SDKROOT = iphoneos3.0;
};
name = Distribution;
};
@ -1017,6 +1373,8 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CODE_SIGN_IDENTITY = "iPhone Distribution: id Software";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: id Software";
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
@ -1027,9 +1385,13 @@
);
HEADER_SEARCH_PATHS = "";
INFOPLIST_FILE = Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 3.2;
PRODUCT_NAME = Doom;
PROFILE_PREFIX = com.idsoftware;
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "31C73095-0DD9-4ABA-BB25-8D23F661F10F";
PROVISIONING_PROFILE = "2ADBE5F0-FC02-4DBF-BEC1-220CF6D12D16";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "18BCE49D-8823-4A0C-B597-CFE83C7820BE";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Distribution;
};

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Doom.xcodeproj">
</FileRef>
</Workspace>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEWorkspaceUserSettings_HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
<true/>
<key>IDEWorkspaceUserSettings_SnapshotAutomaticallyBeforeSignificantChanges</key>
<false/>
</dict>
</plist>

View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "1"
version = "1.0">
<FileBreakpoints>
<FileBreakpoint
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
isPathRelative = "0"
filePath = "/Volumes/Work/idMobileDepot/Archive/DoomClassicDepot/code/prboom/gl_main.c"
timestampString = "333653885.8398299"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "1961"
endingLineNumber = "1961">
</FileBreakpoint>
<FileBreakpoint
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
isPathRelative = "0"
filePath = "/Volumes/Work/idMobileDepot/Archive/DoomClassicDepot/code/prboom/gl_main.c"
timestampString = "333653885.884298"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "1958"
endingLineNumber = "1958">
</FileBreakpoint>
</FileBreakpoints>
</Bucket>

View file

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1D6058900D05DD3D006BFB54"
BuildableName = "Doom.app"
BlueprintName = "Doom"
ReferencedContainer = "container:Doom.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.GDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.GDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
displayScaleIsEnabled = "NO"
displayScale = "1.00"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1D6058900D05DD3D006BFB54"
BuildableName = "Doom.app"
BlueprintName = "Doom"
ReferencedContainer = "container:Doom.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
displayScaleIsEnabled = "NO"
displayScale = "1.00"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1D6058900D05DD3D006BFB54"
BuildableName = "Doom.app"
BlueprintName = "Doom"
ReferencedContainer = "container:Doom.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Doom.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>1D6058900D05DD3D006BFB54</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

View file

@ -1,5 +1,5 @@
/*
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
Copyright (C) 2009 Id Software, Inc.
This program is free software; you can redistribute it and/or
@ -33,16 +33,16 @@ Note that setting the view non-opaque will only work if the EAGL surface has an
@public
UITextField *textField;
GLuint mViewRenderbuffer;
GLuint mViewFramebuffer;
GLuint mDepthRenderbuffer;
@private
/* The pixel dimensions of the backbuffer */
GLint backingWidth;
GLint backingHeight;
/* OpenGL names for the renderbuffer and framebuffers used to render to this view */
GLuint viewRenderbuffer, viewFramebuffer;
/* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
GLuint depthRenderbuffer;
}
@end

View file

@ -1,12 +1,5 @@
//
// EAGLView.m
// Doom
//
// Created by Cass Everitt on 2/20/09.
// Copyright Id Software 2009. All rights reserved.
//
/*
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
Copyright (C) 2009 Id Software, Inc.
This program is free software; you can redistribute it and/or
@ -48,6 +41,8 @@ EAGLContext *context;
return [CAEAGLLayer class];
}
float screenResolutionScale = 1.0f;
CAEAGLLayer *eaglLayer;
//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
@ -59,6 +54,16 @@ CAEAGLLayer *eaglLayer;
// allow multiple touch events
self.multipleTouchEnabled = true;
// Double the resolution on iPhone 4.
if ( [[UIScreen mainScreen] respondsToSelector:@selector(scale)] &&
[self respondsToSelector:@selector(setContentScaleFactor:)] ) {
screenResolutionScale = [UIScreen mainScreen].scale;
// set scaling factor
[self setContentScaleFactor:[UIScreen mainScreen].scale];
}
// Get the layer
eaglLayer = (CAEAGLLayer *)self.layer;
@ -85,29 +90,38 @@ CAEAGLLayer *eaglLayer;
[self release];
return nil;
}
glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
glGenFramebuffersOES(1, &mViewFramebuffer);
glGenRenderbuffersOES(1, &mViewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, mViewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, mViewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, mViewRenderbuffer);
glGenRenderbuffersOES(1, &depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
// the backing sizes should be the same as the screen
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
displaywidth = backingHeight;
displayheight = backingWidth;
glGenRenderbuffersOES(1, &mDepthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, mDepthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, mDepthRenderbuffer);
// the framebuffer will stay constant
glBindRenderbufferOES(GL_RENDERBUFFER_OES, mViewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, mViewFramebuffer);
if ( glCheckFramebufferStatusOES( GL_FRAMEBUFFER_OES ) != GL_FRAMEBUFFER_COMPLETE_OES ) {
printf( "Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES( GL_FRAMEBUFFER_OES ) );
assert( 0 );
}
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
return self;
}
@ -128,19 +142,24 @@ CAEAGLLayer *eaglLayer;
for (UITouch *myTouch in touches)
{
CGPoint touchLocation = [myTouch locationInView:nil];
// Scale Touches with the screen resolution.
touchLocation.x *= screenResolutionScale;
touchLocation.y *= screenResolutionScale;
// handle landscape mode and flipping
int x, y;
if ( revLand->value ) {
x = touchLocation.y;
y = 319 - touchLocation.x;
y = ( displayheight - 1 ) - touchLocation.x;
} else {
x = 479 - touchLocation.y;
x = ( displaywidth - 1) - touchLocation.y;
y = touchLocation.x;
}
// printf( "%i, %i\n", x, y );
touchCount++;
touch_t *t2;
// find which one it is closest to
@ -332,7 +351,12 @@ void SysIPhoneSetConsoleTextField( const char * str) {
}
void SysIPhoneSwapBuffers() {
glBindRenderbufferOES(GL_RENDERBUFFER_OES, eaglview->mViewRenderbuffer);
// present the renderbuffer for display
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
void SysIPhoneOpenURL( const char *url ) {

View file

@ -0,0 +1,42 @@
/*
=======================================================================================
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company. All Right Reserved.
This file is part of the DOOM Classic iOS v2.1 GPL Source Code.
=======================================================================================
*/
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "UIFontButton.h"
@interface GenericMenuView : UIView {
IBOutlet UIScrollView * scrollView;
IBOutlet UILabel * lastItem;
IBOutlet UIFontButton * epi1Button;
IBOutlet UIFontButton * epi2Button;
IBOutlet UIFontButton * epi3Button;
IBOutlet UIFontButton * epi4Button;
int episodeSelection;
IBOutlet UIFontButton * nextButton;
IBOutlet UIFontLabel * nextLabel;
}
- (IBAction) BackToMain;
- (IBAction) NextToMissions;
- (IBAction) SelectEpisode1;
- (IBAction) SelectEpisode2;
- (IBAction) SelectEpisode3;
- (IBAction) SelectEpisode4;
@end

View file

@ -0,0 +1,111 @@
/*
=======================================================================================
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company. All Right Reserved.
This file is part of the DOOM Classic iOS v2.1 GPL Source Code.
=======================================================================================
*/
#import "GenericMenuView.h"
#import "doomAppDelegate.h"
#include "doomiphone.h"
@implementation GenericMenuView
- (void) initialize{
if( scrollView != nil ) {
[scrollView setContentSize:CGSizeMake(
scrollView.bounds.size.width,
CGRectGetMaxY(lastItem.frame)
)];
}
episodeSelection = -1;
[ nextButton setEnabled: NO ];
[ nextLabel setEnabled: NO ];
}
- (void)awakeFromNib {
[self initialize];
}
- (id) initWithCoder:(NSCoder *)aCoder{
if(self = [super initWithCoder:aCoder] ) {
[self initialize];
}
return self;
}
- (id) initWithFrame:(CGRect)rect{
if(self = [super initWithFrame:rect] ) {
[self initialize];
}
return self;
}
- (IBAction) BackToMain {
[gAppDelegate MainMenu];
Sound_StartLocalSound( "iphone/controller_down_01_SILENCE.wav" );
}
- (IBAction) NextToMissions {
[gAppDelegate SelectEpisode: episodeSelection ];
Sound_StartLocalSound( "iphone/controller_down_01_SILENCE.wav" );
}
- (IBAction) SelectEpisode1 {
[ nextButton setEnabled: YES ];
[ nextLabel setEnabled: YES ];
episodeSelection = 0;
[ epi1Button setEnabled: NO ];
[ epi2Button setEnabled: YES ];
[ epi3Button setEnabled: YES ];
[ epi4Button setEnabled: YES ];
}
- (IBAction) SelectEpisode2 {
[ nextButton setEnabled: YES ];
[ nextLabel setEnabled: YES ];
episodeSelection = 1;
[ epi1Button setEnabled: YES ];
[ epi2Button setEnabled: NO ];
[ epi3Button setEnabled: YES ];
[ epi4Button setEnabled: YES ];
}
- (IBAction) SelectEpisode3 {
[ nextButton setEnabled: YES ];
[ nextLabel setEnabled: YES ];
episodeSelection = 2;
[ epi1Button setEnabled: YES ];
[ epi2Button setEnabled: YES ];
[ epi3Button setEnabled: NO ];
[ epi4Button setEnabled: YES ];
}
- (IBAction) SelectEpisode4 {
[ nextButton setEnabled: YES ];
[ nextLabel setEnabled: YES ];
episodeSelection = 3;
[ epi1Button setEnabled: YES ];
[ epi2Button setEnabled: YES ];
[ epi3Button setEnabled: YES ];
[ epi4Button setEnabled: NO ];
}
@end

47
code/iphone/IBGlue.h Normal file
View file

@ -0,0 +1,47 @@
/*
=======================================================================================
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company. All Right Reserved.
This file is part of the DOOM Classic iOS v2.1 GPL Source Code.
=======================================================================================
*/
// Tells Interface Builder to go to the Main Menu.
void IB_GotoMainMenu();

20
code/iphone/IBGlue.m Normal file
View file

@ -0,0 +1,20 @@
/*
=======================================================================================
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company. All Right Reserved.
This file is part of the DOOM Classic iOS v2.1 GPL Source Code.
=======================================================================================
*/
#include "IBGlue.h"
#import "doomAppDelegate.h"
#include "doomiphone.h"
// Tells Interface Builder to go to the Main Menu.
void IB_GotoMainMenu() {
[ gAppDelegate MainMenu];
}

View file

@ -2,8 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key></key>
<string></string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDisplayName</key>
@ -11,9 +9,15 @@
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string>${PRODUCT_NAME}_icon.png</string>
<string>DOOM_57.png</string>
<key>CFBundleIconFiles</key>
<array>
<string>DOOM_57.png</string>
<string>DOOM_114.png</string>
<string>DOOM_72.png</string>
</array>
<key>CFBundleIdentifier</key>
<string>${PROFILE_PREFIX}.${PRODUCT_NAME:identifier}</string>
<string>com.idsoftware.${PRODUCT_NAME:identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
@ -23,18 +27,38 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<string>2.1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSMainNibFile</key>
<string>MainWindow</string>
<key>NSMainNibFile~ipad</key>
<string>MainWindow-iPad</string>
<key>UIAppFonts</key>
<array>
<string>idGinzaNar-Md2.otf</string>
</array>
<key>UIInterfaceOrientation</key>
<string>UIInterfaceOrientationLandscapeLeft</string>
<key>UIPrerenderedIcon</key>
<true/>
<key>UIRequiresPersistentWiFi</key>
<true/>
<key>UIStatusBarHidden</key>
<true/>
<key>UIPrerenderedIcon</key>
<false/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationPortrait</string>
</array>
</dict>
</plist>

View file

@ -0,0 +1,70 @@
/*
=======================================================================================
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company. All Right Reserved.
This file is part of the DOOM Classic iOS v2.1 GPL Source Code.
=======================================================================================
*/
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "UIFontLabel.h"
#import "UIFontButton.h"
@interface Banner_SubItem : UIFontButton {
@public
}
@end
@interface Banner_SubMenu: UIView {
@public
BOOL isHidden;
}
- (void) Hide;
- (void) Show;
@end
@interface MainMenuView : UIView {
@public
IBOutlet UIFontButton * mPlayButton;
IBOutlet UIFontButton * mSettingsButton;
IBOutlet UIFontButton * mAboutButton;
IBOutlet UIFontButton * mExtrasButton;
IBOutlet Banner_SubMenu * mPlaySubMenu;
IBOutlet Banner_SubMenu * mSettingsSubMenu;
IBOutlet Banner_SubMenu * mAboutSubMenu;
IBOutlet Banner_SubMenu * mExtrasSubMenu;
}
// Sub Menu Banner Actions
- (IBAction) ShowPlayBanner;
- (IBAction) ShowSettingsBanner;
- (IBAction) ShowAboutBanner;
- (IBAction) ShowExtrasBanner;
- (void) ResetMenu;
// Interface Builder Actions ( Connected through IB )
- (IBAction) ResumeGamePressed;
- (IBAction) NewGamePressed;
- (IBAction) MultiplayerPressed;
- (IBAction) CreditsPressed;
- (IBAction) SupportPressed;
- (IBAction) LegalPressed;
- (IBAction) DemoPressed;
- (IBAction) OtherIdGamesPressed;
- (IBAction) ControlsOptionsPressed;
- (IBAction) SettingsOptionsPressed;
@end

255
code/iphone/MainMenuView.m Normal file
View file

@ -0,0 +1,255 @@
/*
=======================================================================================
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company. All Right Reserved.
This file is part of the DOOM Classic iOS v2.1 GPL Source Code.
=======================================================================================
*/
#import "MainMenuView.h"
#import "doomAppDelegate.h"
#include "doomiphone.h"
@implementation Banner_SubItem
@end
@implementation Banner_SubMenu
- (void)awakeFromNib {
isHidden = YES;
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *hitView = [super hitTest:point withEvent:event];
if (hitView != self) {
return hitView;
}
return nil;
}
- (void) Hide {
if( !isHidden ) {
isHidden = YES;
[UIView beginAnimations:@"Show" context:nil];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
[UIView setAnimationBeginsFromCurrentState:NO];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(Disable)];
self.alpha = 1.0f;
[ self viewWithTag: 0 ].alpha = 0.0f;
[UIView commitAnimations];
}
}
- (void) Show {
if( isHidden ) {
isHidden = NO;
[UIView beginAnimations:@"Show" context:nil];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
[UIView setAnimationBeginsFromCurrentState:NO];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(Enable)];
self.alpha = 1.0f;
[ self viewWithTag: 0 ].alpha = 1.0f;
[UIView commitAnimations];
}
}
@end
@implementation MainMenuView
- (void) initialize{
// Hide Everything.
[self ResetMenu];
}
- (void)awakeFromNib {
[self initialize];
}
- (void) ResetMenu {
}
- (IBAction) ResumeGamePressed {
[ gAppDelegate ResumeGame ];
Sound_StartLocalSound( "iphone/baborted_01.wav" );
}
- (IBAction) NewGamePressed {
// Go to the Map Menu.
[gAppDelegate NewGame];
Sound_StartLocalSound( "iphone/baborted_01.wav" );
}
- (IBAction) MultiplayerPressed {
// Go to the MP Menu.
// get the address for the local service, which may
// start up a bluetooth personal area network
boolean serverResolved = ResolveNetworkServer( &netServer.address );
// open our socket now that the network interfaces have been configured
// Explicitly open on interface 1, which is en0. If bluetooth ever starts
// working better, we can handle multiple interfaces.
if ( gameSocket <= 0 ) {
gameSocket = UDPSocket( "en0", DOOM_PORT );
}
// get the address for the local service
if ( !serverResolved ) {
// nobody else is acting as a server, so start one here
RegisterGameService();
SetupEmptyNetGame();
}
menuState = IPM_MULTIPLAYER;
[gAppDelegate HideIB];
Sound_StartLocalSound( "iphone/baborted_01.wav" );
}
- (IBAction) CreditsPressed {
[gAppDelegate CreditsMenu];
Sound_StartLocalSound( "iphone/baborted_01.wav" );
}
- (IBAction) SupportPressed {
[gAppDelegate GotoSupport];
Sound_StartLocalSound( "iphone/baborted_01.wav" );
}
- (IBAction) LegalPressed {
[gAppDelegate LegalMenu];
Sound_StartLocalSound( "iphone/baborted_01.wav" );
}
- (IBAction) DemoPressed {
[gAppDelegate DemoGame ];
Sound_StartLocalSound( "iphone/baborted_01.wav" );
}
- (IBAction) OtherIdGamesPressed {
[gAppDelegate idSoftwareApps];
Sound_StartLocalSound( "iphone/baborted_01.wav" );
}
- (IBAction) ControlsOptionsPressed {
[gAppDelegate ControlsMenu];
Sound_StartLocalSound( "iphone/baborted_01.wav" );
}
- (IBAction) SettingsOptionsPressed {
[gAppDelegate SettingsMenu ];
Sound_StartLocalSound( "iphone/baborted_01.wav" );
}
- (void) ShowPlayBanner {
[ mPlayButton setEnabled: NO ];
[ mSettingsButton setEnabled: YES ];
[ mAboutButton setEnabled: YES ];
[ mExtrasButton setEnabled: YES ];
[ mPlaySubMenu Show ];
[ mSettingsSubMenu Hide ];
[ mExtrasSubMenu Hide ];
[ mAboutSubMenu Hide ];
}
- (void) ShowSettingsBanner {
[ mPlayButton setEnabled: YES ];
[ mSettingsButton setEnabled: NO ];
[ mAboutButton setEnabled: YES ];
[ mExtrasButton setEnabled: YES ];
[ mSettingsSubMenu Show ];
[ mPlaySubMenu Hide ];
[ mExtrasSubMenu Hide ];
[ mAboutSubMenu Hide ];
}
- (void) ShowAboutBanner {
[ mPlayButton setEnabled: YES ];
[ mSettingsButton setEnabled: YES ];
[ mAboutButton setEnabled: NO ];
[ mExtrasButton setEnabled: YES ];
[ mAboutSubMenu Show ];
[ mPlaySubMenu Hide ];
[ mSettingsSubMenu Hide ];
[ mExtrasSubMenu Hide ];
}
- (void) ShowExtrasBanner {
[ mPlayButton setEnabled: YES ];
[ mSettingsButton setEnabled: YES ];
[ mAboutButton setEnabled: YES ];
[ mExtrasButton setEnabled: NO ];
[ mExtrasSubMenu Show ];
[ mPlaySubMenu Hide ];
[ mSettingsSubMenu Hide ];
[ mAboutSubMenu Hide ];
}
@end

File diff suppressed because it is too large Load diff

112
code/iphone/MapMenuView.h Normal file
View file

@ -0,0 +1,112 @@
/*
=======================================================================================
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company. All Right Reserved.
This file is part of the DOOM Classic iOS v2.1 GPL Source Code.
=======================================================================================
*/
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "UIFontLabel.h"
#import "UIFontButton.h"
@interface MapMenuView : UIView {
@public
IBOutlet UIScrollView * mapScroller1;
IBOutlet UIScrollView * mapScroller2;
IBOutlet UIScrollView * mapScroller3;
IBOutlet UIScrollView * mapScroller4;
IBOutlet UIButton * lastElement1;
IBOutlet UIButton * lastElement2;
IBOutlet UIButton * lastElement3;
IBOutlet UIButton * lastElement4;
IBOutlet UIImageView * easySelection;
IBOutlet UIImageView * mediumSelection;
IBOutlet UIImageView * hardSelection;
IBOutlet UIImageView * NightmareSelection;
UIScrollView * selectedScroller;
IBOutlet UIFontLabel * easySelectionLabel;
IBOutlet UIFontLabel * mediumSelectionLabel;
IBOutlet UIFontLabel * hardSelectionLabel;
IBOutlet UIFontLabel * nightmareSelectionLabel;
IBOutlet UIFontButton * playButton;
IBOutlet UIFontLabel * playLabel;
UIFontButton * selectedMap;
int episodeSelected;
int mapSelected;
}
- (int) getSkill;
- (void) playMap: (int) dataset: (int) episode: (int) map;
- (void) resetDifficulty;
- (void) setEpisode: (int) episode;
-(IBAction) BackPressed;
-(IBAction) Play;
-(IBAction) UpMission;
-(IBAction) DownMission;
// Difficulty Setting
-(IBAction) EasyPressed;
-(IBAction) MediumPressed;
-(IBAction) HardPressed;
-(IBAction) NightmarePressed;
// DOOM EPISODES
-(IBAction) E1M1;
-(IBAction) E1M2;
-(IBAction) E1M3;
-(IBAction) E1M4;
-(IBAction) E1M5;
-(IBAction) E1M6;
-(IBAction) E1M7;
-(IBAction) E1M8;
-(IBAction) E1M9;
-(IBAction) E2M1;
-(IBAction) E2M2;
-(IBAction) E2M3;
-(IBAction) E2M4;
-(IBAction) E2M5;
-(IBAction) E2M6;
-(IBAction) E2M7;
-(IBAction) E2M8;
-(IBAction) E2M9;
-(IBAction) E3M1;
-(IBAction) E3M2;
-(IBAction) E3M3;
-(IBAction) E3M4;
-(IBAction) E3M5;
-(IBAction) E3M6;
-(IBAction) E3M7;
-(IBAction) E3M8;
-(IBAction) E3M9;
-(IBAction) E4M1;
-(IBAction) E4M2;
-(IBAction) E4M3;
-(IBAction) E4M4;
-(IBAction) E4M5;
-(IBAction) E4M6;
-(IBAction) E4M7;
-(IBAction) E4M8;
-(IBAction) E4M9;
@end

356
code/iphone/MapMenuView.m Normal file
View file

@ -0,0 +1,356 @@
/*
=======================================================================================
Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company. All Right Reserved.
This file is part of the DOOM Classic iOS v2.1 GPL Source Code.
=======================================================================================
*/
#import "MapMenuView.h"
#import "doomAppDelegate.h"
@implementation MapMenuView
- (void) initialize{
[self resetDifficulty ];
[mapScroller1 setContentSize:CGSizeMake(
mapScroller1.bounds.size.width,
CGRectGetMaxY(lastElement1.frame)
)];
[mapScroller2 setContentSize:CGSizeMake(
mapScroller2.bounds.size.width,
CGRectGetMaxY(lastElement2.frame)
)];
[mapScroller3 setContentSize:CGSizeMake(
mapScroller3.bounds.size.width,
CGRectGetMaxY(lastElement3.frame)
)];
[mapScroller4 setContentSize:CGSizeMake(
mapScroller4.bounds.size.width,
CGRectGetMaxY(lastElement4.frame)
)];
[ playButton setEnabled: NO ];
[ playLabel setEnabled: NO ];
selectedMap = nil;
episodeSelected = -1;
mapSelected = -1;
}
- (void)awakeFromNib {
[self initialize];
}
- (id) initWithCoder:(NSCoder *)aCoder{
if(self = [super initWithCoder:aCoder] ) {
[self initialize];
}
return self;
}
- (id) initWithFrame:(CGRect)rect{
if(self = [super initWithFrame:rect] ) {
[self initialize];
}
return self;
}
- (void) resetDifficulty {
easySelection.hidden = NO;
easySelectionLabel.hidden = NO;
mediumSelection.hidden = YES;
mediumSelectionLabel.hidden = YES;
hardSelection.hidden = YES;
hardSelectionLabel.hidden = YES;
NightmareSelection.hidden = YES;
nightmareSelectionLabel.hidden = YES;
}
- (void) setEpisode: (int) episode {
mapScroller1.alpha = 0.0f;
mapScroller2.alpha = 0.0f;
mapScroller3.alpha = 0.0f;
mapScroller4.alpha = 0.0f;
switch( episode ) {
case 0:
selectedScroller = mapScroller1;
break;
case 1:
selectedScroller = mapScroller2;
break;
case 2:
selectedScroller = mapScroller3;
break;
case 3:
selectedScroller = mapScroller4;
break;
};
selectedScroller.alpha = 1.0f;
}
-(IBAction) BackPressed {
// Go Back to MainMenu.
[gAppDelegate NewGame ];
Sound_StartLocalSound( "iphone/controller_down_01_SILENCE.wav" );
}
- (int) getSkill {
if( easySelection.hidden == NO ) {
return 0;
} else if( mediumSelection.hidden == NO ) {
return 1;
} else if( hardSelection.hidden == NO ) {
return 2;
} else if( NightmareSelection.hidden == NO ) {
return 3;
}
return 0;
}
-(IBAction) UpMission {
CGFloat xOffset = selectedScroller.contentOffset.x;
CGFloat yOffset = selectedScroller.contentOffset.y;
if (selectedScroller.contentOffset.y > 10 )
{
[selectedScroller setContentOffset:CGPointMake(xOffset, yOffset - 50 ) animated:YES];
}
}
-(IBAction) DownMission {
CGFloat xOffset = selectedScroller.contentOffset.x;
CGFloat yOffset = selectedScroller.contentOffset.y;
if (selectedScroller.contentOffset.y < 300 )
{
[selectedScroller setContentOffset:CGPointMake(xOffset, yOffset + 50 ) animated:YES];
}
}
-(IBAction) Play {
int skillLevel = [self getSkill];
[gAppDelegate playMap: 0: episodeSelected: mapSelected: skillLevel ];
}
- (void) playMap: (int) dataset: (int) episode: (int) map {
[ playButton setEnabled: YES ];
[ playLabel setEnabled: YES ];
if( selectedMap != nil ) {
[ selectedMap setEnabled: YES ];
}
episodeSelected = episode;
mapSelected = map;
int mapTag = episode * 10 + ( map - 1 );
selectedMap = (UIFontButton *)[ self viewWithTag: mapTag ];
[selectedMap setEnabled: NO];
Sound_StartLocalSound( "iphone/controller_down_01_SILENCE.wav" );
}
// Difficulty Setting
-(IBAction) EasyPressed {
[self resetDifficulty];
Sound_StartLocalSound( "iphone/controller_down_01_SILENCE.wav" );
}
-(IBAction) MediumPressed {
easySelection.hidden = YES;
mediumSelection.hidden = NO;
hardSelection.hidden = YES;
NightmareSelection.hidden = YES;
easySelectionLabel.hidden = YES;
mediumSelectionLabel.hidden = NO;
hardSelectionLabel.hidden = YES;
nightmareSelectionLabel.hidden = YES;
Sound_StartLocalSound( "iphone/controller_down_01_SILENCE.wav" );
}
-(IBAction) HardPressed {
easySelection.hidden = YES;
mediumSelection.hidden = YES;
hardSelection.hidden = NO;
NightmareSelection.hidden = YES;
easySelectionLabel.hidden = YES;
mediumSelectionLabel.hidden = YES;
hardSelectionLabel.hidden = NO;
nightmareSelectionLabel.hidden = YES;
Sound_StartLocalSound( "iphone/controller_down_01_SILENCE.wav" );
}
-(IBAction) NightmarePressed{
easySelection.hidden = YES;
mediumSelection.hidden = YES;
hardSelection.hidden = YES;
NightmareSelection.hidden = NO;
easySelectionLabel.hidden = YES;
mediumSelectionLabel.hidden = YES;
hardSelectionLabel.hidden = YES;
nightmareSelectionLabel.hidden = NO;
Sound_StartLocalSound( "iphone/controller_down_01_SILENCE.wav" );
}
// DOOM EPISODES
-(IBAction) E1M1 {
[ self playMap: 0: 1: 1 ];
}
-(IBAction) E1M2{
[ self playMap: 0: 1: 2 ];
}
-(IBAction) E1M3{
[ self playMap: 0: 1: 3 ];
}
-(IBAction) E1M4{
[ self playMap: 0: 1: 4 ];
}
-(IBAction) E1M5{
[ self playMap: 0: 1: 5 ];
}
-(IBAction) E1M6{
[ self playMap: 0: 1: 6 ];
}
-(IBAction) E1M7{
[ self playMap: 0: 1: 7 ];
}
-(IBAction) E1M8{
[ self playMap: 0: 1: 8 ];
}
-(IBAction) E1M9{
[ self playMap: 0: 1: 9 ];
}
-(IBAction) E2M1{
[ self playMap: 0: 2: 1 ];
}
-(IBAction) E2M2{
[ self playMap: 0: 2: 2 ];
}
-(IBAction) E2M3{
[ self playMap: 0: 2: 3 ];
}
-(IBAction) E2M4{
[ self playMap: 0: 2: 4 ];
}
-(IBAction) E2M5{
[ self playMap: 0: 2: 5 ];
}
-(IBAction) E2M6{
[ self playMap: 0: 2: 6 ];
}
-(IBAction) E2M7{
[ self playMap: 0: 2: 7 ];
}
-(IBAction) E2M8{
[ self playMap: 0: 2: 8 ];
}
-(IBAction) E2M9{
[ self playMap: 0: 2: 9 ];
}
-(IBAction) E3M1{
[ self playMap: 0: 3: 1 ];
}
-(IBAction) E3M2{
[ self playMap: 0: 3: 2 ];
}
-(IBAction) E3M3{
[ self playMap: 0: 3: 3 ];
}
-(IBAction) E3M4{
[ self playMap: 0: 3: 4 ];
}
-(IBAction) E3M5{
[ self playMap: 0: 3: 5 ];
}
-(IBAction) E3M6{
[ self playMap: 0: 3: 6 ];
}
-(IBAction) E3M7 {
[ self playMap: 0: 3: 7 ];
}
-(IBAction) E3M8{
[ self playMap: 0: 3: 8 ];
}
-(IBAction) E3M9{
[ self playMap: 0: 3: 9 ];
}
-(IBAction) E4M1{
[ self playMap: 0: 4: 1 ];
}
-(IBAction) E4M2{
[ self playMap: 0: 4: 2 ];
}
-(IBAction) E4M3{
[ self playMap: 0: 4: 3 ];
}
-(IBAction) E4M4{
[ self playMap: 0: 4: 4 ];
}
-(IBAction) E4M5{
[ self playMap: 0: 4: 5 ];
}
-(IBAction) E4M6{
[ self playMap: 0: 4: 6 ];
}
-(IBAction) E4M7{
[ self playMap: 0: 4: 7 ];
}
-(IBAction) E4M8{
[ self playMap: 0: 4: 8 ];
}
-(IBAction) E4M9{
[ self playMap: 0: 4: 9 ];
}
@end

Some files were not shown because too many files have changed in this diff Show more