From e2d3ce1aedda72f06b3317138e2336af53033d10 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sun, 3 Aug 2014 21:02:04 -0400 Subject: [PATCH] keep the old SDL interface --- src/sdl12/IMG_xpm.c | 506 ++ src/sdl12/MakeCYG.cfg | 17 + src/sdl12/MakeNIX.cfg | 92 + src/sdl12/Makefile.cfg | 163 + src/sdl12/SDL_icon.xpm | 80 + src/sdl12/SDL_main/SDL_dummy_main.c | 12 + src/sdl12/SDL_main/SDL_macosx_main.h | 11 + src/sdl12/SDL_main/SDL_macosx_main.m | 374 ++ src/sdl12/SDL_main/SDL_openxdk_main.c | 7 + src/sdl12/SDL_main/SDL_win32_main.c | 406 ++ src/sdl12/SRB2CE/Makefile.cfg | 12 + src/sdl12/SRB2CE/SRB2CE.zip | Bin 0 -> 34234 bytes src/sdl12/SRB2CE/cehelp.c | 447 ++ src/sdl12/SRB2CE/cehelp.h | 63 + src/sdl12/SRB2DC/.gitignore | 1 + src/sdl12/SRB2DC/IP.BIN | Bin 0 -> 32768 bytes src/sdl12/SRB2DC/Makefile.cfg | 53 + src/sdl12/SRB2DC/SELFBOOT.BIN | Bin 0 -> 1408808 bytes src/sdl12/SRB2DC/VMU.xbm | 19 + src/sdl12/SRB2DC/dchelp.c | 134 + src/sdl12/SRB2DC/dchelp.h | 51 + src/sdl12/SRB2DC/i_udp.c | 455 ++ src/sdl12/SRB2DC/scramble.c | 259 + src/sdl12/SRB2PS3/ICON0.png | Bin 0 -> 3678 bytes src/sdl12/SRB2PS3/Makefile.cfg | 139 + src/sdl12/SRB2PS3/sfo.xml | 39 + src/sdl12/SRB2PSP/ICON0.png | Bin 0 -> 3678 bytes src/sdl12/SRB2PSP/Makefile.cfg | 126 + src/sdl12/SRB2PSP/PIC1.png | Bin 0 -> 20300 bytes src/sdl12/SRB2PSP/psp-prxsign/.gitignore | 2 + src/sdl12/SRB2PSP/psp-prxsign/Makefile | 22 + src/sdl12/SRB2PSP/psp-prxsign/cmac.c | 130 + src/sdl12/SRB2PSP/psp-prxsign/cmac.h | 38 + src/sdl12/SRB2PSP/psp-prxsign/kirk_header.h | 25 + src/sdl12/SRB2PSP/psp-prxsign/main.c | 190 + src/sdl12/SRB2PSP/psp-prxsign/psp_header.h | 29 + src/sdl12/SRB2Pandora/Makefile.cfg | 39 + src/sdl12/SRB2Pandora/PXML.xml | 17 + src/sdl12/SRB2Pandora/icon.png | Bin 0 -> 1690 bytes src/sdl12/SRB2WII/Makefile.cfg | 124 + src/sdl12/SRB2WII/icon.png | Bin 0 -> 11247 bytes src/sdl12/SRB2WII/meta.xml | 18 + src/sdl12/SRB2XBOX/Makefile.cfg | 44 + src/sdl12/SRB2XBOX/xboxhelp.c | 91 + src/sdl12/SRB2XBOX/xboxhelp.h | 6 + src/sdl12/Srb2SDL-vc10.vcxproj | 1464 +++++ src/sdl12/Srb2SDL-vc9.vcproj | 5845 +++++++++++++++++ src/sdl12/Srb2SDL.dsp | 1057 +++ src/sdl12/Srb2SDL.dsw | 74 + src/sdl12/Srb2SDL.ico | Bin 0 -> 2238 bytes src/sdl12/dosstr.c | 38 + src/sdl12/endtxt.c | 236 + src/sdl12/endtxt.h | 24 + src/sdl12/filter/filters.c | 1000 +++ src/sdl12/filter/filters.h | 212 + src/sdl12/filter/hq2x.c | 3125 +++++++++ src/sdl12/filter/hq2x.h | 1824 +++++ src/sdl12/filter/interp.h | 306 + src/sdl12/filter/lq2x.c | 564 ++ src/sdl12/filter/lq2x.h | 1284 ++++ src/sdl12/filter/main.c | 15 + src/sdl12/hwsym_sdl.c | 183 + src/sdl12/hwsym_sdl.h | 23 + src/sdl12/i_cdmus.c | 588 ++ src/sdl12/i_main.c | 247 + src/sdl12/i_net.c | 442 ++ src/sdl12/i_system.c | 3115 +++++++++ src/sdl12/i_ttf.c | 340 + src/sdl12/i_ttf.h | 88 + src/sdl12/i_video.c | 2100 ++++++ .../macosx/English.lproj/InfoPlist.strings | 0 src/sdl12/macosx/Info.plist | 28 + src/sdl12/macosx/Srb2mac.icns | Bin 0 -> 79787 bytes .../macosx/Srb2mac.pbproj/project.pbxproj | 3546 ++++++++++ .../macosx/Srb2mac.xcodeproj/project.pbxproj | 1510 +++++ src/sdl12/macosx/mac_alert.c | 45 + src/sdl12/macosx/mac_alert.h | 27 + src/sdl12/mixer_sound.c | 824 +++ src/sdl12/ogl_sdl.c | 315 + src/sdl12/ogl_sdl.h | 30 + src/sdl12/sdl_sound.c | 2030 ++++++ src/sdl12/sdlmain.h | 65 + src/sdl12/srb2.ttf | Bin 0 -> 318280 bytes 83 files changed, 36855 insertions(+) create mode 100644 src/sdl12/IMG_xpm.c create mode 100644 src/sdl12/MakeCYG.cfg create mode 100644 src/sdl12/MakeNIX.cfg create mode 100644 src/sdl12/Makefile.cfg create mode 100644 src/sdl12/SDL_icon.xpm create mode 100644 src/sdl12/SDL_main/SDL_dummy_main.c create mode 100644 src/sdl12/SDL_main/SDL_macosx_main.h create mode 100644 src/sdl12/SDL_main/SDL_macosx_main.m create mode 100644 src/sdl12/SDL_main/SDL_openxdk_main.c create mode 100644 src/sdl12/SDL_main/SDL_win32_main.c create mode 100644 src/sdl12/SRB2CE/Makefile.cfg create mode 100644 src/sdl12/SRB2CE/SRB2CE.zip create mode 100644 src/sdl12/SRB2CE/cehelp.c create mode 100644 src/sdl12/SRB2CE/cehelp.h create mode 100644 src/sdl12/SRB2DC/.gitignore create mode 100644 src/sdl12/SRB2DC/IP.BIN create mode 100644 src/sdl12/SRB2DC/Makefile.cfg create mode 100644 src/sdl12/SRB2DC/SELFBOOT.BIN create mode 100644 src/sdl12/SRB2DC/VMU.xbm create mode 100644 src/sdl12/SRB2DC/dchelp.c create mode 100644 src/sdl12/SRB2DC/dchelp.h create mode 100644 src/sdl12/SRB2DC/i_udp.c create mode 100644 src/sdl12/SRB2DC/scramble.c create mode 100644 src/sdl12/SRB2PS3/ICON0.png create mode 100644 src/sdl12/SRB2PS3/Makefile.cfg create mode 100644 src/sdl12/SRB2PS3/sfo.xml create mode 100644 src/sdl12/SRB2PSP/ICON0.png create mode 100644 src/sdl12/SRB2PSP/Makefile.cfg create mode 100644 src/sdl12/SRB2PSP/PIC1.png create mode 100644 src/sdl12/SRB2PSP/psp-prxsign/.gitignore create mode 100644 src/sdl12/SRB2PSP/psp-prxsign/Makefile create mode 100644 src/sdl12/SRB2PSP/psp-prxsign/cmac.c create mode 100644 src/sdl12/SRB2PSP/psp-prxsign/cmac.h create mode 100644 src/sdl12/SRB2PSP/psp-prxsign/kirk_header.h create mode 100644 src/sdl12/SRB2PSP/psp-prxsign/main.c create mode 100644 src/sdl12/SRB2PSP/psp-prxsign/psp_header.h create mode 100644 src/sdl12/SRB2Pandora/Makefile.cfg create mode 100644 src/sdl12/SRB2Pandora/PXML.xml create mode 100644 src/sdl12/SRB2Pandora/icon.png create mode 100644 src/sdl12/SRB2WII/Makefile.cfg create mode 100644 src/sdl12/SRB2WII/icon.png create mode 100644 src/sdl12/SRB2WII/meta.xml create mode 100644 src/sdl12/SRB2XBOX/Makefile.cfg create mode 100644 src/sdl12/SRB2XBOX/xboxhelp.c create mode 100644 src/sdl12/SRB2XBOX/xboxhelp.h create mode 100644 src/sdl12/Srb2SDL-vc10.vcxproj create mode 100644 src/sdl12/Srb2SDL-vc9.vcproj create mode 100644 src/sdl12/Srb2SDL.dsp create mode 100644 src/sdl12/Srb2SDL.dsw create mode 100644 src/sdl12/Srb2SDL.ico create mode 100644 src/sdl12/dosstr.c create mode 100644 src/sdl12/endtxt.c create mode 100644 src/sdl12/endtxt.h create mode 100644 src/sdl12/filter/filters.c create mode 100644 src/sdl12/filter/filters.h create mode 100644 src/sdl12/filter/hq2x.c create mode 100644 src/sdl12/filter/hq2x.h create mode 100644 src/sdl12/filter/interp.h create mode 100644 src/sdl12/filter/lq2x.c create mode 100644 src/sdl12/filter/lq2x.h create mode 100644 src/sdl12/filter/main.c create mode 100644 src/sdl12/hwsym_sdl.c create mode 100644 src/sdl12/hwsym_sdl.h create mode 100644 src/sdl12/i_cdmus.c create mode 100644 src/sdl12/i_main.c create mode 100644 src/sdl12/i_net.c create mode 100644 src/sdl12/i_system.c create mode 100644 src/sdl12/i_ttf.c create mode 100644 src/sdl12/i_ttf.h create mode 100644 src/sdl12/i_video.c create mode 100644 src/sdl12/macosx/English.lproj/InfoPlist.strings create mode 100644 src/sdl12/macosx/Info.plist create mode 100644 src/sdl12/macosx/Srb2mac.icns create mode 100644 src/sdl12/macosx/Srb2mac.pbproj/project.pbxproj create mode 100644 src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj create mode 100644 src/sdl12/macosx/mac_alert.c create mode 100644 src/sdl12/macosx/mac_alert.h create mode 100644 src/sdl12/mixer_sound.c create mode 100644 src/sdl12/ogl_sdl.c create mode 100644 src/sdl12/ogl_sdl.h create mode 100644 src/sdl12/sdl_sound.c create mode 100644 src/sdl12/sdlmain.h create mode 100644 src/sdl12/srb2.ttf diff --git a/src/sdl12/IMG_xpm.c b/src/sdl12/IMG_xpm.c new file mode 100644 index 000000000..e08736d66 --- /dev/null +++ b/src/sdl12/IMG_xpm.c @@ -0,0 +1,506 @@ +/* + SDL_image: An example image loading library for use with SDL + Copyright (C) 1999-2004 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +/* $Id: IMG_xpm.c,v 1.10 2004/01/04 22:04:38 slouken Exp $ */ + +/* + * XPM (X PixMap) image loader: + * + * Supports the XPMv3 format, EXCEPT: + * - hotspot coordinates are ignored + * - only colour ('c') colour symbols are used + * - rgb.txt is not used (for portability), so only RGB colours + * are recognized (#rrggbb etc) - only a few basic colour names are + * handled + * + * The result is an 8bpp indexed surface if possible, otherwise 32bpp. + * The colourkey is correctly set if transparency is used. + * + * Besides the standard API, also provides + * + * SDL_Surface *IMG_ReadXPMFromArray(char **xpm) + * + * that reads the image data from an XPM file included in the C source. + * + * TODO: include rgb.txt here. The full table (from solaris 2.6) only + * requires about 13K in binary form. + */ + +#include +#include +#include +#include + +//#include "SDL_image.h" + + +#ifdef LOAD_XPM + +/* See if an image is contained in a data source */ +#if 0 +int IMG_isXPM(SDL_RWops *src) +{ + char magic[9]; + + return (SDL_RWread(src, magic, sizeof (magic), 1) + && memcmp(magic, "/* XPM */", 9) == 0); +} +#endif + +/* Hash table to look up colors from pixel strings */ +#define STARTING_HASH_SIZE 256 + +struct hash_entry { + char *key; + Uint32 color; + struct hash_entry *next; +}; + +struct color_hash { + struct hash_entry **table; + struct hash_entry *entries; /* array of all entries */ + struct hash_entry *next_free; + size_t size; + int maxnum; +}; + +static int hash_key(const char *key, int cpp, size_t size) +{ + int hash; + + hash = 0; + while ( cpp-- > 0 ) { + hash = hash * 33 + *key++; + } + return (int)(hash & (size - 1)); +} + +static struct color_hash *create_colorhash(int maxnum) +{ + size_t bytes; + int s; + struct color_hash *hash; + + /* we know how many entries we need, so we can allocate + everything here */ + hash = malloc(sizeof *hash); + if (!hash) + return NULL; + + /* use power-of-2 sized hash table for decoding speed */ + for (s = STARTING_HASH_SIZE; s < maxnum; s <<= 1) + ; + hash->size = s; + hash->maxnum = maxnum; + bytes = hash->size * sizeof (struct hash_entry **); + hash->entries = NULL; /* in case malloc fails */ + hash->table = malloc(bytes); + if (!hash->table) + return NULL; + memset(hash->table, 0, bytes); + hash->entries = malloc(maxnum * sizeof (struct hash_entry)); + if (!hash->entries) + { + free(hash->table); + return NULL; + } + hash->next_free = hash->entries; + return hash; +} + +static int add_colorhash(struct color_hash *hash, + char *key, int cpp, Uint32 color) +{ + const int indexkey = hash_key(key, cpp, hash->size); + struct hash_entry *e = hash->next_free++; + e->color = color; + e->key = key; + e->next = hash->table[indexkey]; + hash->table[indexkey] = e; + return 1; +} + +/* fast lookup that works if cpp == 1 */ +#define QUICK_COLORHASH(hash, key) ((hash)->table[*(const Uint8 *)(key)]->color) + +static Uint32 get_colorhash(struct color_hash *hash, const char *key, int cpp) +{ + struct hash_entry *entry = hash->table[hash_key(key, cpp, hash->size)]; + while (entry) { + if (memcmp(key, entry->key, cpp) == 0) + return entry->color; + entry = entry->next; + } + return 0; /* garbage in - garbage out */ +} + +static void free_colorhash(struct color_hash *hash) +{ + if (hash && hash->table) { + free(hash->table); + free(hash->entries); + free(hash); + } +} + +/* portable case-insensitive string comparison */ +static int string_equal(const char *a, const char *b, size_t n) +{ + while (*a && *b && n) { + if (toupper((unsigned char)*a) != toupper((unsigned char)*b)) + return 0; + a++; + b++; + n--; + } + return *a == *b; +} + +#undef ARRAYSIZE +#define ARRAYSIZE(a) (int)(sizeof (a) / sizeof ((a)[0])) + +/* + * convert colour spec to RGB (in 0xrrggbb format). + * return 1 if successful. + */ +static int color_to_rgb(const char *spec, size_t speclen, Uint32 *rgb) +{ + /* poor man's rgb.txt */ + static struct { const char *name; Uint32 rgb; } known[] = { + {"none", 0xffffffff}, + {"black", 0x00000000}, + {"white", 0x00ffffff}, + {"red", 0x00ff0000}, + {"green", 0x0000ff00}, + {"blue", 0x000000ff} + }; + + if (spec[0] == '#') { + char buf[7]; + switch (speclen) { + case 4: + buf[0] = buf[1] = spec[1]; + buf[2] = buf[3] = spec[2]; + buf[4] = buf[5] = spec[3]; + break; + case 7: + memcpy(buf, spec + 1, 6); + break; + case 13: + buf[0] = spec[1]; + buf[1] = spec[2]; + buf[2] = spec[5]; + buf[3] = spec[6]; + buf[4] = spec[9]; + buf[5] = spec[10]; + break; + } + buf[6] = '\0'; + *rgb = (Uint32)strtol(buf, NULL, 16); + return 1; + } else { + int i; + for (i = 0; i < ARRAYSIZE(known); i++) + if (string_equal(known[i].name, spec, speclen)) { + *rgb = known[i].rgb; + return 1; + } + return 0; + } +} + +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif + +static char *linebuf; +static int buflen; +static const char *error; + +/* + * Read next line from the source. + * If len > 0, it's assumed to be at least len chars (for efficiency). + * Return NULL and set error upon EOF or parse error. + */ +static const char *get_next_line(const char ***lines, SDL_RWops *src, int len) +{ + char *linebufnew; + if (lines) { + return *(*lines)++; + } else { + char c; + int n; + do { + if (SDL_RWread(src, &c, 1, 1) <= 0) { + error = "Premature end of data"; + return NULL; + } + } while (c != '"'); + if (len) { + len += 4; /* "\",\n\0" */ + if (len > buflen){ + buflen = len; + linebufnew = realloc(linebuf, buflen); + if(!linebufnew) { + free(linebuf); + error = "Out of memory"; + return NULL; + } + linebuf = linebufnew; + } + if (SDL_RWread(src, linebuf, len - 1, 1) <= 0) { + error = "Premature end of data"; + return NULL; + } + n = len - 2; + } else { + n = 0; + do { + if (n >= buflen - 1) { + if (buflen == 0) + buflen = 16; + buflen *= 2; + linebufnew = realloc(linebuf, buflen); + if(!linebufnew) { + free(linebuf); + error = "Out of memory"; + return NULL; + } + linebuf = linebufnew; + } + if (SDL_RWread(src, linebuf + n, 1, 1) <= 0) { + error = "Premature end of data"; + return NULL; + } + } while (linebuf[n++] != '"'); + n--; + } + linebuf[n] = '\0'; + return linebuf; + } +} + +#define SKIPSPACE(p) \ +do { \ + while (isspace((unsigned char)*(p))) \ + ++(p); \ +} while (0) + +#define SKIPNONSPACE(p) \ +do { \ + while (!isspace((unsigned char)*(p)) && *p) \ + ++(p); \ +} while (0) + +/* read XPM from either array or RWops */ +static SDL_Surface *load_xpm(const char **xpm, SDL_RWops *src) +{ + SDL_Surface *image = NULL; + int indexc; + int x, y; + int w, h, ncolors, cpp; + int indexed; + Uint8 *dst; + struct color_hash *colors = NULL; + SDL_Color *im_colors = NULL; + char *keystrings = NULL, *nextkey; + const char *line; + const char ***xpmlines = NULL; + int pixels_len; + + error = NULL; + linebuf = NULL; + buflen = 0; + + if (xpm) + xpmlines = &xpm; + + line = get_next_line(xpmlines, src, 0); + if (!line) + goto done; + /* + * The header string of an XPMv3 image has the format + * + * [ ] + * + * where the hotspot coords are intended for mouse cursors. + * Right now we don't use the hotspots but it should be handled + * one day. + */ + if (sscanf(line, "%d %d %d %d", &w, &h, &ncolors, &cpp) != 4 + || w <= 0 || h <= 0 || ncolors <= 0 || cpp <= 0) { + error = "Invalid format description"; + goto done; + } + + keystrings = malloc(ncolors * cpp); + if (!keystrings) { + error = "Out of memory"; + goto done; + } + nextkey = keystrings; + + /* Create the new surface */ + if (ncolors <= 256) { + indexed = 1; + image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, + 0, 0, 0, 0); + im_colors = image->format->palette->colors; + image->format->palette->ncolors = ncolors; + } else { + indexed = 0; + image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, + 0xff0000, 0x00ff00, 0x0000ff, 0); + } + if (!image) { + /* Hmm, some SDL error (out of memory?) */ + goto done; + } + + /* Read the colors */ + colors = create_colorhash(ncolors); + if (!colors) { + error = "Out of memory"; + goto done; + } + for (indexc = 0; indexc < ncolors; ++indexc ) { + const char *p; + line = get_next_line(xpmlines, src, 0); + if (!line) + goto done; + + p = line + cpp + 1; + + /* parse a colour definition */ + for (;;) { + char nametype; + const char *colname; + Uint32 rgb, pixel; + + SKIPSPACE(p); + if (!*p) { + error = "colour parse error"; + goto done; + } + nametype = *p; + SKIPNONSPACE(p); + SKIPSPACE(p); + colname = p; + SKIPNONSPACE(p); + if (nametype == 's') + continue; /* skip symbolic colour names */ + + if (!color_to_rgb(colname, p - colname, &rgb)) + continue; + + memcpy(nextkey, line, cpp); + if (indexed) { + SDL_Color *c = im_colors + indexc; + c->r = (Uint8)(rgb >> 16); + c->g = (Uint8)(rgb >> 8); + c->b = (Uint8)(rgb); + pixel = indexc; + } else + pixel = rgb; + add_colorhash(colors, nextkey, cpp, pixel); + nextkey += cpp; + if (rgb == 0xffffffff) + SDL_SetColorKey(image, SDL_SRCCOLORKEY, pixel); + break; + } + } + + /* Read the pixels */ + pixels_len = w * cpp; + dst = image->pixels; + for (y = 0; y < h; y++) { + line = get_next_line(xpmlines, src, pixels_len); + if (indexed) { + /* optimization for some common cases */ + if (cpp == 1) + for (x = 0; x < w; x++) + dst[x] = (Uint8)QUICK_COLORHASH(colors, + line + x); + else + for (x = 0; x < w; x++) + dst[x] = (Uint8)get_colorhash(colors, + line + x * cpp, + cpp); + } else { + for (x = 0; x < w; x++) + ((Uint32*)dst)[x] = get_colorhash(colors, + line + x * cpp, + cpp); + } + dst += image->pitch; + } + +done: + if (error) { + SDL_FreeSurface(image); + image = NULL; + SDL_SetError(error); + } + free(keystrings); + free_colorhash(colors); + free(linebuf); + return(image); +} + +/* Load a XPM type image from an RWops datasource */ +#if 0 +SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src) +{ + if ( !src ) { + /* The error message has been set in SDL_RWFromFile */ + return NULL; + } + return load_xpm(NULL, src); +} +#endif + +static inline SDL_Surface *IMG_ReadXPMFromArray(const char **xpm) +{ + return load_xpm(xpm, NULL); +} + +#else /* not LOAD_XPM */ + +/* See if an image is contained in a data source */ +#if 0 +int IMG_isXPM(SDL_RWops *src) +{ + return(0); +} + +/* Load a XPM type image from an SDL datasource */ +SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src) +{ + return(NULL); +} +#endif + +static inline SDL_Surface *IMG_ReadXPMFromArray(const char **xpm) +{ + return NULL; +} +#endif /* not LOAD_XPM */ diff --git a/src/sdl12/MakeCYG.cfg b/src/sdl12/MakeCYG.cfg new file mode 100644 index 000000000..5907579c1 --- /dev/null +++ b/src/sdl12/MakeCYG.cfg @@ -0,0 +1,17 @@ +# +# sdl/makeCYG.cfg for SRB2/Cygwin +# + +# +#Cygwin, for debugging + + NOHW=1 + NOHS=1 + NOASM=1 + + OPTS+=-DLINUX + + i_system_o+=$(OBJDIR)/SRB2.res + + # name of the exefile + EXENAME?=lsdlsrb2.exe diff --git a/src/sdl12/MakeNIX.cfg b/src/sdl12/MakeNIX.cfg new file mode 100644 index 000000000..457f52301 --- /dev/null +++ b/src/sdl12/MakeNIX.cfg @@ -0,0 +1,92 @@ +# +# sdl/makeNIX.cfg for SRB2/?nix +# + +#Valgrind support +ifdef VALGRIND +VALGRIND_PKGCONFIG?=valgrind +VALGRIND_CFLAGS?=$(shell $(PKG_CONFIG) $(VALGRIND_PKGCONFIG) --cflags) +VALGRIND_LDFLAGS?=$(shell $(PKG_CONFIG) $(VALGRIND_PKGCONFIG) --libs) +ZDEBUG=1 +LIBS+=$(VALGRIND_LDFLAGS) +ifdef GCC46 +WFLAGS+=-Wno-error=unused-but-set-variable +WFLAGS+=-Wno-unused-but-set-variable +endif +endif + +# +#here is GNU/Linux and other +# + + OPTS=-DUNIXCOMMON + + #LDFLAGS = -L/usr/local/lib + LIBS=-lm +ifdef LINUX + LIBS+=-lrt +ifdef NOTERMIOS + OPTS+=-DNOTERMIOS +endif +endif + +# +#here is Solaris +# +ifdef SOLARIS + NOIPX=1 + NOASM=1 + OPTS+=-DSOLARIS -DINADDR_NONE=INADDR_ANY -DBSD_COMP + OPTS+=-I/usr/local/include -I/opt/sfw/include + LDFLAGS+=-L/opt/sfw/lib + LIBS+=-lsocket -lnsl +endif + +# +#here is FreeBSD +# +ifdef FREEBSD + OPTS+=-DLINUX -DFREEBSD -I/usr/X11R6/include + SDL_CONFIG?=sdl11-config + LDFLAGS+=-L/usr/X11R6/lib + LIBS+=-lipx -lkvm +endif + +# +#here is GP2x (arm-gp2x-linux) +# +ifdef GP2X + PNG_CONFIG?=$(PREFIX)-libpng12-config +ifdef STATIC #need a better setting name + CFLAGS+=-I$(OPEN2X)/include +ifndef NOMIXER + LIBS+=-lvorbisidec +ifdef MIKMOD + LIBS+=-lmikmod +endif +ifdef SMPEGLIB + LIBS+=-lsmpeg + LD=$(CXX) +endif +endif + NONET=1 +endif +ifndef ARCHNAME +"error" +endif + NONX86=1 + NOHW=1 + NOHS=1 + NOMD5=1 + WFLAGS+=-O0 + OPTS+=-DGP2X -ffast-math -mcpu=arm920t + EXENAME?=SRB2GP2X.gpe +endif + +ifndef NOHW + OPTS+=-I/usr/X11R6/include + LDFLAGS+=-L/usr/X11R6/lib +endif + + # name of the exefile + EXENAME?=lsdlsrb2 diff --git a/src/sdl12/Makefile.cfg b/src/sdl12/Makefile.cfg new file mode 100644 index 000000000..1f9c7204f --- /dev/null +++ b/src/sdl12/Makefile.cfg @@ -0,0 +1,163 @@ +# +# sdl/makefile.cfg for SRB2/SDL +# + +# +#SDL...., *looks at Alam*, THIS IS A MESS! +# + +ifdef UNIXCOMMON +include sdl/MakeNIX.cfg +endif + +ifdef PANDORA +include sdl/SRB2Pandora/Makefile.cfg +endif #ifdef PANDORA + +ifdef DC +include sdl/SRB2DC/Makefile.cfg +endif #ifdef DC + +ifdef PS3N +include sdl/SRB2PS3/Makefile.cfg +endif #ifdef PS3N + +ifdef PSP +include sdl/SRB2PSP/Makefile.cfg +endif #ifdef PSP + +ifdef XBOX +include sdl/SRB2XBOX/Makefile.cfg +endif #ifdef XBOX + +ifdef WINCE +include sdl/SRB2CE/Makefile.cfg +endif #ifef WINCE + +ifdef CYGWIN32 +include sdl/MakeCYG.cfg +endif #ifdef CYGWIN32 + +ifdef SDL_PKGCONFIG +SDL_CFLAGS?=$(shell $(PKG_CONFIG) $(SDL_PKGCONFIG) --cflags) +SDL_LDFLAGS?=$(shell $(PKG_CONFIG) $(SDL_PKGCONFIG) --libs) +else +ifdef PREFIX + SDL_CONFIG?=$(PREFIX)-sdl-config +else + SDL_CONFIG?=sdl-config +endif + +ifdef STATIC + SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags) + SDL_LDFLAGS?=$(shell $(SDL_CONFIG) --static-libs) +else + SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags) + SDL_LDFLAGS?=$(shell $(SDL_CONFIG) --libs) +endif +endif + + + #use the x86 asm code +ifndef CYGWIN32 +ifndef NOASM + USEASM=1 +endif +endif + + OBJS+=$(OBJDIR)/i_video.o $(OBJDIR)/dosstr.o $(OBJDIR)/endtxt.o $(OBJDIR)/hwsym_sdl.o + + OPTS+=-DDIRECTFULLSCREEN -DSDL + +ifndef NOHW + OBJS+=$(OBJDIR)/r_opengl.o $(OBJDIR)/ogl_sdl.o +endif + +ifndef NOHS +ifdef OPENAL + OBJS+=$(OBJDIR)/s_openal.o + OPTS+=-DSTATIC3DS + STATICHS=1 +else +ifdef FMOD + OBJS+=$(OBJDIR)/s_fmod.o + OPTS+=-DSTATIC3DS + STATICHS=1 +else +ifdef MINGW +ifdef DS3D + OBJS+=$(OBJDIR)/s_ds3d.o + OPTS+=-DSTATIC3DS + STATICHS=1 +endif +endif +endif +endif +endif + +ifdef FILTERS + OBJS+=$(OBJDIR)/filters.o $(OBJDIR)/hq2x.o $(OBJDIR)/lq2x.o + OPTS+=-DHAVE_FILTER +endif + +ifdef NOMIXER + i_sound_o=$(OBJDIR)/sdl_sound.o +else + i_sound_o=$(OBJDIR)/mixer_sound.o + OPTS+=-DHAVE_MIXER + SDL_LDFLAGS+=-lSDL_mixer +endif + +ifdef SDL_TTF + OPTS+=-DHAVE_TTF + SDL_LDFLAGS+=-lSDL_ttf -lfreetype -lz + OBJS+=$(OBJDIR)/i_ttf.o +endif + +#ifdef SDL_IMAGE +# OPTS+=-DHAVE_IMAGE +# SDL_LDFLAGS+=-lSDL_image +#endif + +ifdef SDL_NET + OPTS+=-DHAVE_SDLNET + SDL_LDFLAGS+=-lSDL_net +endif + +ifdef SDLMAIN + OPTS+=-DSDLMAIN +else +ifdef MINGW + SDL_CFLAGS+=-Umain + SDL_LDFLAGS+=-mconsole +endif +endif + +ifndef NOHW +ifdef OPENAL +ifdef MINGW + LIBS:=-lopenal32 $(LIBS) +else + LIBS:=-lopenal $(LIBS) +endif +else +ifdef MINGW +ifdef DS3D + LIBS:=-ldsound -luuid $(LIBS) +endif +endif +endif +endif + +# FIXME: DevkitPPC and ready-compiled SDL Wii require these things to be in a silly order +ifdef WII +include sdl/SRB2WII/Makefile.cfg +endif #ifdef WII + +CFLAGS+=$(SDL_CFLAGS) +LIBS:=$(SDL_LDFLAGS) $(LIBS) +ifndef WII +ifdef STATIC + LIBS+=$(shell $(SDL_CONFIG) --static-libs) +endif +endif diff --git a/src/sdl12/SDL_icon.xpm b/src/sdl12/SDL_icon.xpm new file mode 100644 index 000000000..70bb02d3c --- /dev/null +++ b/src/sdl12/SDL_icon.xpm @@ -0,0 +1,80 @@ +/* XPM */ +static const char * SDL_icon_xpm[] = { +"32 32 45 1", +" c None", +". c #6B6BFF", +"+ c #3D00B9", +"@ c #4848FF", +"# c #2525FF", +"$ c #310096", +"% c #003196", +"& c #003DB9", +"* c #620096", +"= c #6E6E6E", +"- c #966200", +"; c #250073", +"> c #626262", +", c #FF8F6B", +"' c #FFC66B", +") c #FFAB8E", +"! c #000080", +"~ c #B6B6B6", +"{ c #929292", +"] c #FFD48E", +"^ c #0000B9", +"/ c #565656", +"( c #868686", +"_ c #808080", +": c #C0C0C0", +"< c #DADADA", +"[ c #F2F2F2", +"} c #FFFFFF", +"| c #CECECE", +"1 c #AAAAAA", +"2 c #E6E6E6", +"3 c #000096", +"4 c #AB8EFF", +"5 c #190050", +"6 c #000000", +"7 c #8E8EFF", +"8 c #3E3E3E", +"9 c #7A7A7A", +"0 c #0E0E0E", +"a c #9E9E9E", +"b c #001950", +"c c #C2C2C2", +"d c #323232", +"e c #002573", +"f c #A0A0A4", +" ", +" ", +" ", +" .+@##@. ", +" @@.@#######@ ", +" @@....######### ", +" .. .@.....@+##$%%%&&% ", +" ..@# @@....@+#*=-;%%%%% ", +" ..@#@......@>,')!%%%$ ", +" ~..$#.........{])^#+%/ ", +" +##@.........()^@@@@@_ ", +" $####@........#=#######+ ", +" +######....@@##^#########_ ", +" +#####=:<<:+##############/ ", +"[<=####{<}}}}|###############= ", +" }1###=2}}}}}}.############### ", +" }<3#3~}}}}}}}4################ ", +" }<5#6:}}}}}}}7################/", +" }:6861}}}}}}}.########$$ 9 .@$", +" }:0a6~}}}}}}}@######5b ", +"22cd262}}}}}}2######5b$ ", +" 2>1a}}}}}}}{(*###%be## ", +" 860)1<[22c1)]]+##be### ", +" ~)]]]))))]]]]]=#bb#### ", +" )]]]]]]]]](]]=eb$#### ", +" :]]]]]]]]]'9bbb$##### ", +" ),'''''( >db+### ", +" =##f ", +" { ", +" ", +" ", +" "}; diff --git a/src/sdl12/SDL_main/SDL_dummy_main.c b/src/sdl12/SDL_main/SDL_dummy_main.c new file mode 100644 index 000000000..d8cfdd5bb --- /dev/null +++ b/src/sdl12/SDL_main/SDL_dummy_main.c @@ -0,0 +1,12 @@ +/* Include the SDL main definition header */ +#include "SDL_main.h" + +#ifdef main +#undef main +int main(int argc, char *argv[]) +{ + return(SDL_main(argc, argv)); +} +#else +/* Nothing to do on this platform */; +#endif diff --git a/src/sdl12/SDL_main/SDL_macosx_main.h b/src/sdl12/SDL_main/SDL_macosx_main.h new file mode 100644 index 000000000..4683df57a --- /dev/null +++ b/src/sdl12/SDL_main/SDL_macosx_main.h @@ -0,0 +1,11 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#import + +@interface SDLMain : NSObject +@end diff --git a/src/sdl12/SDL_main/SDL_macosx_main.m b/src/sdl12/SDL_main/SDL_macosx_main.m new file mode 100644 index 000000000..226afe13d --- /dev/null +++ b/src/sdl12/SDL_main/SDL_macosx_main.m @@ -0,0 +1,374 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#import "SDL.h" +#import "SDL_macosx_main.h" +#import /* for MAXPATHLEN */ +#import + +/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, + but the method still is there and works. To avoid warnings, we declare + it ourselves here. */ +@interface NSApplication(SDL_Missing_Methods) +- (void)setAppleMenu:(NSMenu *)menu; +@end + +/* Use this flag to determine whether we use SDLMain.nib or not */ +#define SDL_USE_NIB_FILE 0 + +/* Use this flag to determine whether we use CPS (docking) or not */ +#define SDL_USE_CPS 1 +#if SDL_USE_CPS +/* Portions of CPS.h */ +typedef struct CPSProcessSerNum +{ + UInt32 lo; + UInt32 hi; +} CPSProcessSerNum; + +extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); +extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); +extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); + +#endif /* SDL_USE_CPS */ + +static int gArgc; +static char **gArgv; +static BOOL gFinderLaunch; + +static void addArgument(const char *value) +{ + if(!gArgc) + gArgv = (char **)malloc(sizeof(*gArgv)); + else + { + char **newgArgv = (char **)realloc(gArgv, sizeof(*gArgv) * (gArgc + 1)); + if (!newgArgv) + { + newgArgv = malloc(sizeof(*gArgv) * (gArgc + 1)); + memcpy(newgArgv, gArgv, sizeof(*gArgv) * gArgc); + free(gArgv); + } + gArgv = newgArgv; + } + gArgc++; + gArgv[gArgc - 1] = (char *)malloc(sizeof(char) * (strlen(value) + 1)); + strcpy(gArgv[gArgc - 1], value); +} + +static NSString *getApplicationName(void) +{ + NSDictionary *dict; + NSString *appName = NULL; + + /* Determine the application name */ + dict = ( NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); + if (dict) + appName = [dict objectForKey: @"CFBundleName"]; + + if (![appName length]) + appName = [[NSProcessInfo processInfo] processName]; + + return appName; +} + +#if SDL_USE_NIB_FILE +/* A helper category for NSString */ +@interface NSString (ReplaceSubString) +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; +@end +#endif + +@interface SDLApplication : NSApplication +@end + +@implementation SDLApplication +/* Invoked from the Quit menu item */ +- (void)terminate:(id)sender +{ +#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) + (void)sender; +#endif + /* Post a SDL_QUIT event */ + SDL_Event event; + event.type = SDL_QUIT; + SDL_PushEvent(&event); +} +@end + +/* The main class of the application, the application's delegate */ +@implementation SDLMain + +/* Set the working directory to the .app's parent directory */ +- (void) setupWorkingDirectory:(BOOL)shouldChdir +{ + if (shouldChdir) + { + char parentdir[MAXPATHLEN]; + CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); + CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); + if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) + { + assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */ + } + CFRelease(url); + CFRelease(url2); + } + +} + +#if SDL_USE_NIB_FILE + +/* Fix menu to contain the real app name instead of "SDL App" */ +- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName +{ + NSRange aRange; + NSEnumerator *enumerator; + NSMenuItem *menuItem; + + aRange = [[aMenu title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; + + enumerator = [[aMenu itemArray] objectEnumerator]; + while ((menuItem = [enumerator nextObject])) + { + aRange = [[menuItem title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; + if ([menuItem hasSubmenu]) + [self fixMenu:[menuItem submenu] withAppName:appName]; + } + [ aMenu sizeToFit ]; +} + +#else + +static void setApplicationMenu(void) +{ + /* warning: this code is very odd */ + NSMenu *appleMenu; + NSMenuItem *menuItem; + NSString *title; + NSString *appName; + + appName = getApplicationName(); + appleMenu = [[NSMenu alloc] initWithTitle:@""]; + + /* Add menu items */ + title = [@"About " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; + + [appleMenu addItem:[NSMenuItem separatorItem]]; + + title = [@"Hide " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; + + menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; + [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; + + [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; + + [appleMenu addItem:[NSMenuItem separatorItem]]; + + title = [@"Quit " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; + + + /* Put menu into the menubar */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; + [menuItem setSubmenu:appleMenu]; + [[NSApp mainMenu] addItem:menuItem]; + + /* Tell the application object that this is now the application menu */ + [NSApp setAppleMenu:appleMenu]; + + /* Finally give up our references to the objects */ + [appleMenu release]; + [menuItem release]; +} + +/* Create a window menu */ +static void setupWindowMenu(void) +{ + NSMenu *windowMenu; + NSMenuItem *windowMenuItem; + NSMenuItem *menuItem; + + windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; + + /* "Minimize" item */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; + [windowMenu addItem:menuItem]; + [menuItem release]; + + /* Put menu into the menubar */ + windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; + [windowMenuItem setSubmenu:windowMenu]; + [[NSApp mainMenu] addItem:windowMenuItem]; + + /* Tell the application object that this is now the window menu */ + [NSApp setWindowsMenu:windowMenu]; + + /* Finally give up our references to the objects */ + [windowMenu release]; + [windowMenuItem release]; +} + +/* Replacement for NSApplicationMain */ +static void CustomApplicationMain (int argc, char **argv) +{ +#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) + (void)argc; + (void)argv; +#endif + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + SDLMain *sdlMain; + + /* Ensure the application object is initialised */ + [SDLApplication sharedApplication]; + +#if SDL_USE_CPS + { + CPSProcessSerNum PSN; + /* Tell the dock about us */ + if (!CPSGetCurrentProcess(&PSN)) + if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) + if (!CPSSetFrontProcess(&PSN)) + [SDLApplication sharedApplication]; + } +#endif /* SDL_USE_CPS */ + + /* Set up the menubar */ + [NSApp setMainMenu:[[NSMenu alloc] init]]; + setApplicationMenu(); + setupWindowMenu(); + + /* Create SDLMain and make it the app delegate */ + sdlMain = [[SDLMain alloc] init]; + [NSApp setDelegate:sdlMain]; + + /* Start the main event loop */ + [NSApp run]; + + [sdlMain release]; + [pool release]; +} + +#endif + +- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename +{ +#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) + (void)theApplication; +#endif + addArgument("-iwad"); + addArgument([filename UTF8String]); + return YES; +} + +/* Called when the internal event loop has just started running */ +- (void) applicationDidFinishLaunching: (NSNotification *) note +{ +#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) + (void)note; +#endif + int status; + + /* Set the working directory to the .app's parent directory */ + [self setupWorkingDirectory:gFinderLaunch]; + +#if SDL_USE_NIB_FILE + /* Set the main menu to contain the real app name instead of "SDL App" */ + [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; +#endif + + if (!getenv("SRB2WADDIR")) + setenv("SRB2WADDIR", [[[NSBundle mainBundle] resourcePath] UTF8String], 1); + + /* Hand off to main application code */ + status = SDL_main (gArgc, gArgv); + + /* We're done, thank you for playing */ + exit(status); +} +@end + + +@implementation NSString (ReplaceSubString) + +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString +{ + size_t bufferSize; + size_t selfLen = [self length]; + size_t aStringLen = [aString length]; + unichar *buffer; + NSRange localRange; + NSString *result; + + bufferSize = selfLen + aStringLen - aRange.length; + buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar)); + + /* Get first part into buffer */ + localRange.location = 0; + localRange.length = aRange.location; + [self getCharacters:buffer range:localRange]; + + /* Get middle part into buffer */ + localRange.location = 0; + localRange.length = aStringLen; + [aString getCharacters:(buffer+aRange.location) range:localRange]; + + /* Get last part into buffer */ + localRange.location = aRange.location + aRange.length; + localRange.length = selfLen - localRange.location; + [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; + + /* Build output string */ + result = [NSString stringWithCharacters:buffer length:bufferSize]; + + NSDeallocateMemoryPages(buffer, bufferSize); + + return result; +} + +@end + + + +#ifdef main +# undef main +#endif + + +/* Main entry point to executable - should *not* be SDL_main! */ +int main (int argc, char **argv) +{ + + /* Copy the arguments into a global variable */ + + /* This is passed if we are launched by double-clicking */ + if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { + gArgc = 1; + gFinderLaunch = YES; + } else { + gArgc = argc; + gFinderLaunch = NO; + } + gArgv = argv; + + /* Some additional arguments we always want to run with. */ + //addArgument("-opengl"); + +#if SDL_USE_NIB_FILE + [SDLApplication poseAsClass:[NSApplication class]]; + NSApplicationMain (argc, argv); +#else + CustomApplicationMain (argc, argv); +#endif + return 0; +} diff --git a/src/sdl12/SDL_main/SDL_openxdk_main.c b/src/sdl12/SDL_main/SDL_openxdk_main.c new file mode 100644 index 000000000..63db8da2d --- /dev/null +++ b/src/sdl12/SDL_main/SDL_openxdk_main.c @@ -0,0 +1,7 @@ +/* Include the SDL main definition header */ +#include "SDL_main.h" + +void XBoxStartup() +{ + SDL_main(0, NULL); /// \todo ? +} diff --git a/src/sdl12/SDL_main/SDL_win32_main.c b/src/sdl12/SDL_main/SDL_win32_main.c new file mode 100644 index 000000000..46b20d0bd --- /dev/null +++ b/src/sdl12/SDL_main/SDL_win32_main.c @@ -0,0 +1,406 @@ +/* + SDL_main.c, placed in the public domain by Sam Lantinga 4/13/98 + + The WinMain function -- calls your program's main() function +*/ + +#include +#include +#include +#include +#define RPC_NO_WINDOWS_H +#include +#include /* For _alloca() */ + +#include + +#ifdef _WIN32_WCE +# define DIR_SEPERATOR TEXT("\\") +# define _tgetcwd(str,len) wcscpy(str,TEXT("")) +# define setbuf(f,b) +# define setvbuf(w,x,y,z) +# define _tremove(x) DeleteFile(x) +#else +# define DIR_SEPERATOR TEXT("/") +# include +#endif + +/* Include the SDL main definition header */ +#ifdef _MSC_VER +#pragma warning(disable : 4214 4244) +#endif +#include "SDL.h" +#include "SDL_main.h" +#ifdef _MSC_VER +#pragma warning(default : 4214 4244) +#endif +#include "../../win32/win_dbg.h" +#define USE_MESSAGEBOX + +#ifdef main +# ifndef _WIN32_WCE_EMULATION +# undef main +# endif /* _WIN32_WCE_EMULATION */ +#endif /* main */ + +/* The standard output files */ +//#ifdef _WIN32_WCE +//#define STDOUT_FILE TEXT("/Storage Card/SRB2DEMO/stdout.txt") +//#define STDERR_FILE TEXT("/Storage Card/SRB2DEMO/stderr.txt") +//#else +#define STDOUT_FILE TEXT("stdout.txt") +#define STDERR_FILE TEXT("stderr.txt") +//#endif + +#ifndef NO_STDIO_REDIRECT + static TCHAR stdoutPath[MAX_PATH]; + static TCHAR stderrPath[MAX_PATH]; +#endif + +#if defined(_WIN32_WCE) && _WIN32_WCE < 300 +/* seems to be undefined in Win CE although in online help */ +#define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t')) + +/* seems to be undefined in Win CE although in online help */ +char *strrchr(char *str, int c) +{ + char *p; + + /* Skip to the end of the string */ + p=str; + while (*p) + p++; + + /* Look for the given character */ + while ( (p >= str) && (*p != (CHAR)c) ) + p--; + + /* Return NULL if character not found */ + if ( p < str ) { + p = NULL; + } + return p; +} +#endif /* _WIN32_WCE < 300 */ + +/* Parse a command line buffer into arguments */ +static int ParseCommandLine(char *cmdline, char **argv) +{ + char *bufp; + int argc; + + argc = 0; + for ( bufp = cmdline; *bufp; ) { + /* Skip leading whitespace */ + while ( isspace(*bufp) ) { + ++bufp; + } + /* Skip over argument */ + if ( *bufp == '"' ) { + ++bufp; + if ( *bufp ) { + if ( argv ) { + argv[argc] = bufp; + } + ++argc; + } + /* Skip over word */ + while ( *bufp && (*bufp != '"') ) { + ++bufp; + } + } else { + if ( *bufp ) { + if ( argv ) { + argv[argc] = bufp; + } + ++argc; + } + /* Skip over word */ + while ( *bufp && ! isspace(*bufp) ) { + ++bufp; + } + } + if ( *bufp ) { + if ( argv ) { + *bufp = '\0'; + } + ++bufp; + } + } + if ( argv ) { + argv[argc] = NULL; + } + return(argc); +} + +/* Show an error message */ +static void ShowError(const char *title, const char *message) +{ +/* If USE_MESSAGEBOX is defined, you need to link with user32.lib */ +#ifdef USE_MESSAGEBOX + MessageBoxA(NULL, + message, + title, + MB_ICONEXCLAMATION|MB_OK); +#else + fprintf(stderr, "%s: %s\n", title, message); +#endif +} + +/* Pop up an out of memory message, returns to Windows */ +static BOOL OutOfMemory(void) +{ + ShowError("Fatal Error", "Out of memory - aborting"); + return FALSE; +} + +/* Remove the output files if there was no output written */ +static void __cdecl cleanup_output(void) +{ +#ifndef NO_STDIO_REDIRECT + FILE *file; + int empty; +#endif + + /* Flush the output in case anything is queued */ + fclose(stdout); + fclose(stderr); + +#ifndef NO_STDIO_REDIRECT + /* See if the files have any output in them */ + if ( stdoutPath[0] ) { + file = _tfopen(stdoutPath, TEXT("rb")); + if ( file ) { + empty = (fgetc(file) == EOF) ? 1 : 0; + fclose(file); + if ( empty ) { + _tremove(stdoutPath); + } + } + } + if ( stderrPath[0] ) { + file = _tfopen(stderrPath, TEXT("rb")); + if ( file ) { + empty = (fgetc(file) == EOF) ? 1 : 0; + fclose(file); + if ( empty ) { + _tremove(stderrPath); + } + } + } +#endif +} + +#if defined(_MSC_VER) && !defined(_WIN32_WCE) +/* The VC++ compiler needs main defined */ +#define console_main main +#endif + +/* This is where execution begins [console apps] */ +int console_main(int argc, char *argv[]) +{ + size_t n; + int st; + char *bufp, *appname; + + /* Get the class name from argv[0] */ + appname = argv[0]; + if ( (bufp=strrchr(argv[0], '\\')) != NULL ) { + appname = bufp+1; + } else + if ( (bufp=strrchr(argv[0], '/')) != NULL ) { + appname = bufp+1; + } + + if ( (bufp=strrchr(appname, '.')) == NULL ) + n = strlen(appname); + else + n = (bufp-appname); + + bufp = (char *)alloca(n+1); + if ( bufp == NULL ) { + return OutOfMemory(); + } + strncpy(bufp, appname, n); + bufp[n] = '\0'; + appname = bufp; + + /* Load SDL dynamic link library */ + if ( SDL_Init(SDL_INIT_NOPARACHUTE) < 0 ) { + ShowError("WinMain() error", SDL_GetError()); + return(FALSE); + } + atexit(cleanup_output); + atexit(SDL_Quit); + +#ifndef DISABLE_VIDEO +#if 0 + /* Create and register our class * + DJM: If we do this here, the user nevers gets a chance to + putenv(SDL_WINDOWID). This is already called later by + the (DIB|DX5)_CreateWindow function, so it should be + safe to comment it out here. + if ( SDL_RegisterApp(appname, CS_BYTEALIGNCLIENT, + GetModuleHandle(NULL)) < 0 ) { + ShowError("WinMain() error", SDL_GetError()); + exit(1); + }*/ +#else + /* Sam: + We still need to pass in the application handle so that + DirectInput will initialize properly when SDL_RegisterApp() + is called later in the video initialization. + */ + SDL_SetModuleHandle(GetModuleHandle(NULL)); +#endif /* 0 */ +#endif /* !DISABLE_VIDEO */ + + /* Run the application main() code */ + st = SDL_main(argc, argv); + + /* Exit cleanly, calling atexit() functions */ + //exit(0); + cleanup_output(); + SDL_Quit(); + + /* Hush little compiler, don't you cry... */ + return st; +} + +/* This is where execution begins [windowed apps] */ +#ifdef _WIN32_WCE +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPWSTR szCmdLine, int sw) +#else +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) +#endif +{ + HINSTANCE handle; + int Result = -1; + char **argv; + int argc; + LPSTR cmdline; +#ifdef _WIN32_WCE + size_t nLen; + LPTSTR bufp; +#else + LPSTR bufp; +#endif +#ifndef NO_STDIO_REDIRECT + FILE *newfp; +#endif + + /* Start up DDHELP.EXE before opening any files, so DDHELP doesn't + keep them open. This is a hack.. hopefully it will be fixed + someday. DDHELP.EXE starts up the first time DDRAW.DLL is loaded. + */ + hPrev = hInst = NULL; + sw = 0; + handle = LoadLibrary(TEXT("DDRAW.DLL")); + if ( handle != NULL ) { + FreeLibrary(handle); + } + +#ifndef NO_STDIO_REDIRECT + _tgetcwd( stdoutPath, sizeof( stdoutPath ) ); + _tcscat( stdoutPath, DIR_SEPERATOR STDOUT_FILE ); + + /* Redirect standard input and standard output */ + newfp = _tfreopen(stdoutPath, TEXT("w"), stdout); + +#ifndef _WIN32_WCE + if ( newfp == NULL ) { /* This happens on NT */ +#if !defined(stdout) + stdout = _tfopen(stdoutPath, TEXT("w")); +#else + newfp = _tfopen(stdoutPath, TEXT("w")); + if ( newfp ) { + *stdout = *newfp; + } +#endif + } +#endif /* _WIN32_WCE */ + + _tgetcwd( stderrPath, sizeof( stderrPath ) ); + _tcscat( stderrPath, DIR_SEPERATOR STDERR_FILE ); + + newfp = _tfreopen(stderrPath, TEXT("w"), stderr); +#ifndef _WIN32_WCE + if ( newfp == NULL ) { /* This happens on NT */ +#if !defined(stderr) + stderr = _tfopen(stderrPath, TEXT("w")); +#else + newfp = _tfopen(stderrPath, TEXT("w")); + if ( newfp ) { + *stderr = *newfp; + } +#endif + } +#endif /* _WIN32_WCE */ + + setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* Line buffered */ + setbuf(stderr, NULL); /* No buffering */ +#endif /* !NO_STDIO_REDIRECT */ + +#ifdef _WIN32_WCE + nLen = wcslen(szCmdLine)+128+1; + bufp = (wchar_t *)alloca(nLen*2); + wcscpy (bufp, TEXT("\"")); + GetModuleFileName(NULL, bufp+1, 128-3); + wcscpy (bufp+wcslen(bufp), TEXT("\" ")); + wcsncpy(bufp+wcslen(bufp), szCmdLine,nLen-wcslen(bufp)); + nLen = wcslen(bufp)+1; + cmdline = (char *)alloca(nLen); + if ( cmdline == NULL ) { + return OutOfMemory(); + } + WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL); +#else + szCmdLine = NULL; + /* Grab the command line (use alloca() on Windows) */ + bufp = GetCommandLineA(); + cmdline = (LPSTR)alloca(strlen(bufp)+1); + if ( cmdline == NULL ) { + return OutOfMemory(); + } + strcpy(cmdline, bufp); +#endif + + /* Parse it into argv and argc */ + argc = ParseCommandLine(cmdline, NULL); + argv = (char **)alloca((argc+1)*(sizeof *argv)); + if ( argv == NULL ) { + return OutOfMemory(); + } + ParseCommandLine(cmdline, argv); + +#ifdef BUGTRAP + /* Try BugTrap. */ + if(InitBugTrap()) + Result = console_main(argc, argv); + else + { +#endif + + /* Run the main program (after a little SDL initialization) */ +#ifndef _WIN32_WCE + __try +#endif + { + Result = console_main(argc, argv); + } +#ifndef _WIN32_WCE + __except ( RecordExceptionInfo(GetExceptionInformation())) + { + SetUnhandledExceptionFilter(EXCEPTION_CONTINUE_SEARCH); //Do nothing here. + } +#endif + +#ifdef BUGTRAP + } /* BT failure clause. */ + + /* This is safe even if BT didn't start. */ + ShutdownBugTrap(); +#endif + + return Result; +} diff --git a/src/sdl12/SRB2CE/Makefile.cfg b/src/sdl12/SRB2CE/Makefile.cfg new file mode 100644 index 000000000..8d4ae3e48 --- /dev/null +++ b/src/sdl12/SRB2CE/Makefile.cfg @@ -0,0 +1,12 @@ +# +# Makefile.cfg for WinCE with GCC +# + +OPTS+=-D_WIN32_WCE -D_UNICODE +SDL_CFLAGS?= +SDL_LDFLAGS?= +NOHS=1 +NOHW=1 +NONET=1 +NOMIXER=1 +NOPNG=1 diff --git a/src/sdl12/SRB2CE/SRB2CE.zip b/src/sdl12/SRB2CE/SRB2CE.zip new file mode 100644 index 0000000000000000000000000000000000000000..3ac8530dcb124cbda512a7d469da933c3fc974bf GIT binary patch literal 34234 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 HAkhB;OHxy? literal 0 HcmV?d00001 diff --git a/src/sdl12/SRB2CE/cehelp.c b/src/sdl12/SRB2CE/cehelp.c new file mode 100644 index 000000000..b9fafd040 --- /dev/null +++ b/src/sdl12/SRB2CE/cehelp.c @@ -0,0 +1,447 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 2004 by Sonic Team Jr. +// +// 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. +// +// DESCRIPTION: +// stub and replacement "ANSI" C functions for use under Windows CE +// +//----------------------------------------------------------------------------- + +#include "../../doomdef.h" +#include "cehelp.h" + +#define _SEC_IN_MINUTE 60 +#define _SEC_IN_HOUR 3600 +#define _SEC_IN_DAY 86400 + +static const int DAYS_IN_MONTH[12] = +{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +#define _DAYS_IN_MONTH(x) ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x]) + +static const int _DAYS_BEFORE_MONTH[12] = +{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + +#define _ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || (((y)+1900) % 400) == 0)) +#define _DAYS_IN_YEAR(year) (_ISLEAP(year) ? 366 : 365) + +char *strerror(int ecode) +{ + static char buff[1024 + 1]; + DWORD dwMsgLen = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, + ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &buff[0], 1024, NULL); + return buff; +} + +int unlink( const char *filename ) +{ + return remove(filename); +} + +int remove( const char *path ) +{ + return DeleteFileA(path)-1; +} + +int rename( const char *oldname, const char *newname ) +{ + return MoveFileA(oldname, newname)!=0; +} + +static inline void STToTM(const SYSTEMTIME *st, struct tm *tm) +{ + if (!st || !tm) return; + tm->tm_sec = st->wSecond; + tm->tm_min = st->wMinute; + tm->tm_hour = st->wHour; + tm->tm_mday = st->wDay; + tm->tm_mon = st->wMonth - 1; + tm->tm_year = st->wYear - 1900; + tm->tm_wday = st->wDayOfWeek; + tm->tm_yday = 0; + tm->tm_isdst = 0; +} + +time_t time(time_t *T) +{ + time_t returntime; + SYSTEMTIME st; + struct tm stft; + GetSystemTime(&st); + STToTM(&st,&stft); + returntime = mktime(&stft); + if (T) *T = returntime; + return returntime; +} + +static inline UINT64 TTtoFT(const time_t wt, FILETIME *ft) +{ + UINT64 temptime = wt; // FILETIME: 1/(10^7) secs since January 1, 1601 + temptime *= 10000000; // time_t : 1 secs since January 1, 1970 + // 369 years * 365 days * 24 hours * 60 mins * 60 secs * 10 + // 123 leaps days * 24 hours * 60 mins * 60 secs * 10 + temptime += 116444736000000000; + if (ft) CopyMemory(ft,&temptime,sizeof (ULARGE_INTEGER)); + return temptime; +} + +static struct tm cehelptm; + +struct tm * localtime(const time_t *CLOCK) +{ + SYSTEMTIME st; + FILETIME stft; + UINT64 ftli = 0; + if (CLOCK) ftli = TTtoFT(*CLOCK, &stft); + if (ftli) + FileTimeToSystemTime(&stft,&st); + else + GetSystemTime(&st); + STToTM(&st,&cehelptm); + if (st.wYear >= 1970) + return &cehelptm; + else + return NULL; +} + +static void validate_structure (struct tm *tim_p) // from newlib +{ + div_t res; + int days_in_feb = 28; + + /* calculate time & date to account for out of range values */ + if (tim_p->tm_sec < 0 || tim_p->tm_sec > 59) + { + res = div (tim_p->tm_sec, 60); + tim_p->tm_min += res.quot; + if ((tim_p->tm_sec = res.rem) < 0) + { + tim_p->tm_sec += 60; + --tim_p->tm_min; + } + } + + if (tim_p->tm_min < 0 || tim_p->tm_min > 59) + { + res = div (tim_p->tm_min, 60); + tim_p->tm_hour += res.quot; + if ((tim_p->tm_min = res.rem) < 0) + { + tim_p->tm_min += 60; + --tim_p->tm_hour; + } + } + + if (tim_p->tm_hour < 0 || tim_p->tm_hour > 23) + { + res = div (tim_p->tm_hour, 24); + tim_p->tm_mday += res.quot; + if ((tim_p->tm_hour = res.rem) < 0) + { + tim_p->tm_hour += 24; + --tim_p->tm_mday; + } + } + + if (tim_p->tm_mon > 11) + { + res = div (tim_p->tm_mon, 12); + tim_p->tm_year += res.quot; + if ((tim_p->tm_mon = res.rem) < 0) + { + tim_p->tm_mon += 12; + --tim_p->tm_year; + } + } + + if (_DAYS_IN_YEAR (tim_p->tm_year) == 366) + days_in_feb = 29; + + if (tim_p->tm_mday <= 0) + { + while (tim_p->tm_mday <= 0) + { + if (--tim_p->tm_mon == -1) + { + tim_p->tm_year--; + tim_p->tm_mon = 11; + days_in_feb = + ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? + 29 : 28); + } + tim_p->tm_mday += _DAYS_IN_MONTH (tim_p->tm_mon); + } + } + else + { + while (tim_p->tm_mday > _DAYS_IN_MONTH (tim_p->tm_mon)) + { + tim_p->tm_mday -= _DAYS_IN_MONTH (tim_p->tm_mon); + if (++tim_p->tm_mon == 12) + { + tim_p->tm_year++; + tim_p->tm_mon = 0; + days_in_feb = + ((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ? + 29 : 28); + } + } + } +} + +time_t mktime (struct tm *tim_p) // from newlib +{ + time_t tim = 0; + long days = 0; + int year; + + /* validate structure */ + validate_structure (tim_p); + + /* compute hours, minutes, seconds */ + tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) + + (tim_p->tm_hour * _SEC_IN_HOUR); + + /* compute days in year */ + days += tim_p->tm_mday - 1; + days += _DAYS_BEFORE_MONTH[tim_p->tm_mon]; + if (tim_p->tm_mon > 1 && _DAYS_IN_YEAR (tim_p->tm_year) == 366) + days++; + + /* compute day of the year */ + tim_p->tm_yday = days; + + if (tim_p->tm_year > 10000 + || tim_p->tm_year < -10000) + { + return (time_t) -1; + } + + /* compute days in other years */ + if (tim_p->tm_year > 70) + { + for (year = 70; year < tim_p->tm_year; year++) + days += _DAYS_IN_YEAR (year); + } + else if (tim_p->tm_year < 70) + { + for (year = 69; year > tim_p->tm_year; year--) + days -= _DAYS_IN_YEAR (year); + days -= _DAYS_IN_YEAR (year); + } + + /* compute day of the week */ + if ((tim_p->tm_wday = (days + 4) % 7) < 0) + tim_p->tm_wday += 7; + + /* compute total seconds */ + tim += (days * _SEC_IN_DAY); + + return tim; +} + +#undef WINAPI +#define WINAPI __stdcall //__delcspec(dllexport) + +#ifdef _MSC_VER +//#pragma warning(disable : 4273) +#endif + + +static __forceinline int STRtoWSTR(LPCSTR lpMultiByteStr, int cchMultiByte, + LPWSTR lpWideCharStr, int cchWideChar) +{ + return MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,lpMultiByteStr, + cchMultiByte,lpWideCharStr,cchWideChar); +} + +static __forceinline int WSTRtoSTR(LPCWSTR lpWideCharStr, int cchWideChar, + LPSTR lpMultiByteStr, int cbMultiByte) +{ + return WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK|WC_SEPCHARS, + lpWideCharStr,cchWideChar,lpMultiByteStr,cbMultiByte,NULL,NULL); +} + +DWORD WINAPI FormatMessageA( + DWORD dwFlags, + LPCVOID lpSource, + DWORD dwMessageId, + DWORD dwLanguageId, + LPSTR lpBuffer, + DWORD nSize, + va_list *Arguments) +{ + const int nSizeW = STRtoWSTR(lpBuffer,nSize,NULL,0); + int nSizeF = 0; + LPWSTR lpBufferW = alloca(sizeof (wchar_t)*nSizeW); + LPWSTR lpSourceW = NULL; + + if (!lpBufferW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ZeroMemory(lpBuffer,nSize); + return nSizeF; + } + + if (dwFlags & FORMAT_MESSAGE_FROM_STRING) + { + const int sLen = STRtoWSTR(lpSource, -1, NULL, 0); + lpSourceW = alloca(sizeof (wchar_t)*sLen); + + if (lpSourceW) + STRtoWSTR(lpSource, -1, lpSourceW, sLen); + else + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return nSizeF; + } + } + + if (lpSourceW) + nSizeF = FormatMessageW(dwFlags, lpSourceW, dwMessageId, dwLanguageId, + lpBufferW, nSizeW, Arguments); + else + nSizeF = FormatMessageW(dwFlags, lpSource, dwMessageId, dwLanguageId, + lpBufferW, nSizeW, Arguments); + + return WSTRtoSTR(lpBufferW, nSizeF, lpBuffer, nSize); +} + +BOOL WINAPI DeleteFileA( + LPCSTR lpFileName) +{ + const int sLen = STRtoWSTR(lpFileName, -1, NULL, 0); + LPWSTR lpFileNameW = alloca(sizeof (wchar_t)*sLen); + + if (lpFileNameW) + STRtoWSTR(lpFileName, -1, lpFileNameW, sLen); + else + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + + return DeleteFileW(lpFileNameW); +} + +BOOL WINAPI MoveFileA( + LPCSTR lpExistingFileName, + LPCSTR lpNewFileName +) +{ + const int sLen1 = STRtoWSTR(lpExistingFileName, -1, NULL, 0); + LPWSTR lpExistingFileNameW = alloca(sizeof (wchar_t)*sLen1); + + const int sLen2 = STRtoWSTR(lpNewFileName, -1, NULL, 0); + LPWSTR lpNewFileNameW = alloca(sizeof (wchar_t)*sLen2); + + + if (!lpExistingFileNameW || !lpNewFileNameW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + + STRtoWSTR(lpExistingFileName, -1, lpExistingFileNameW, sLen1); + STRtoWSTR(lpNewFileName, -1, lpNewFileNameW, sLen2); + + return MoveFileW(lpExistingFileNameW, lpNewFileNameW); +} + + +HANDLE WINAPI CreateFileA( + LPCSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile) +{ + const int sLen = STRtoWSTR(lpFileName, -1, NULL, 0); + LPWSTR lpFileNameW = alloca(sizeof (wchar_t)*sLen); + + if (lpFileNameW) + STRtoWSTR(lpFileName, -1, lpFileNameW, sLen); + else + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return INVALID_HANDLE_VALUE; + } + + return CreateFileW(lpFileNameW, dwDesiredAccess, dwShareMode, + lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, + hTemplateFile); +} + +BOOL WINAPI CreateDirectoryA( + LPCSTR lpPathName, + LPSECURITY_ATTRIBUTES lpSecurityAttributes) +{ + const int sLen = STRtoWSTR(lpPathName, -1, NULL, 0); + LPWSTR lpPathNameW = alloca(sizeof (wchar_t)*sLen); + + if (lpPathNameW) + STRtoWSTR(lpPathName, -1, lpPathNameW, sLen); + else + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + + return CreateDirectoryW(lpPathNameW, lpSecurityAttributes); +} + +int WINAPI MessageBoxA( + HWND hWnd , + LPCSTR lpText, + LPCSTR lpCaption, + UINT uType) +{ + const int sLen1 = STRtoWSTR(lpText, -1, NULL, 0); + LPWSTR lpTextW = alloca(sizeof (wchar_t)*sLen1); + + const int sLen2 = STRtoWSTR(lpCaption, -1, NULL, 0); + LPWSTR lpCaptionW = alloca(sizeof (wchar_t)*sLen2); + + + if (!lpTextW || !lpCaptionW) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + + STRtoWSTR(lpText, -1, lpTextW, sLen1); + STRtoWSTR(lpCaption, -1, lpCaptionW, sLen2); + + return MessageBoxW(hWnd, lpTextW, lpCaptionW, uType); +} + +VOID WINAPI OutputDebugStringA( + LPCSTR lpOutputString) +{ + const int sLen = STRtoWSTR(lpOutputString, -1, NULL, 0); + LPWSTR lpOutputStringW = alloca(sizeof (wchar_t)*sLen); + + if (lpOutputStringW) + STRtoWSTR(lpOutputString, -1, lpOutputStringW, sLen); + else + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return; + } + + OutputDebugStringW(lpOutputStringW); +} + diff --git a/src/sdl12/SRB2CE/cehelp.h b/src/sdl12/SRB2CE/cehelp.h new file mode 100644 index 000000000..bc265b058 --- /dev/null +++ b/src/sdl12/SRB2CE/cehelp.h @@ -0,0 +1,63 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 2004 by Sonic Team Jr. +// +// 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. +// +// DESCRIPTION: +// stub and replacement "ANSI" C functions for use under Windows CE +// +//----------------------------------------------------------------------------- + +#ifndef __I_WINCE__ +#define __I_WINCE__ + +#ifdef USEASMCE +#define USEASM // Remline if NASM doesn't work on x86 targets +#endif + +char *strerror(int ecode); +int access(const char *path, int amode); +int unlink( const char *filename ); +int remove( const char *path ); +int rename( const char *oldname, const char *newname ); +//CreateDirectoryEx( const char *currectpath, const char *path,SECURITY_ATTRIBUTES) + +#ifndef _TIME_T_DEFINED +typedef long time_t; /* time value */ +#define _TIME_T_DEFINED /* avoid multiple def's of time_t */ +#endif + +time_t time(time_t *T); + +#ifndef __GNUC__ +#ifndef _TM_DEFINED +struct tm { + int tm_sec; /* seconds after the minute - [0,59] */ + int tm_min; /* minutes after the hour - [0,59] */ + int tm_hour; /* hours since midnight - [0,23] */ + int tm_mday; /* day of the month - [1,31] */ + int tm_mon; /* months since January - [0,11] */ + int tm_year; /* years since 1900 */ + int tm_wday; /* days since Sunday - [0,6] */ + int tm_yday; /* days since January 1 - [0,365] */ + int tm_isdst; /* daylight savings time flag */ + }; +#define _TM_DEFINED +#endif + +struct tm * localtime(const time_t *CLOCK); + +time_t mktime (struct tm *tim_p); +#endif + +#endif diff --git a/src/sdl12/SRB2DC/.gitignore b/src/sdl12/SRB2DC/.gitignore new file mode 100644 index 000000000..a966585d4 --- /dev/null +++ b/src/sdl12/SRB2DC/.gitignore @@ -0,0 +1 @@ +/scramble diff --git a/src/sdl12/SRB2DC/IP.BIN b/src/sdl12/SRB2DC/IP.BIN new file mode 100644 index 0000000000000000000000000000000000000000..c3366213bde1c6b5dc03db4cfdab85c1c74ef5fc GIT binary patch literal 32768 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 literal 0 HcmV?d00001 diff --git a/src/sdl12/SRB2DC/Makefile.cfg b/src/sdl12/SRB2DC/Makefile.cfg new file mode 100644 index 000000000..3edaf8a16 --- /dev/null +++ b/src/sdl12/SRB2DC/Makefile.cfg @@ -0,0 +1,53 @@ +# +# Makefile.cfg for SRB2/Dreamcast +# + +#include $(KOS_BASE)/Makefile.rules + +# +#hmmm, the Dreamcast +# + + HOSTCC:=$(CC) + CC=$(KOS_CC) + PREFIX=$(KOS_CC_BASE)/bin/$(KOS_CC_PREFIX) + OBJDUMP=$(PREFIX)-objdump + OBJCOPY=$(PREFIX)-objcopy + + #NOHW=1 #No working MiniGL right now + NOHS=1 #No HWSound right now +ifndef LWIP + NONET=1 #No LWIP +endif + #i_net_o=$(OBJDIR)/i_udp.o #use KOS's UDP + #NOMIXER=1 #Basic sound only + NOIPX=1 #No IPX network code + NOPNG=1 #No Screenshot + + OPTS=$(KOS_CFLAGS) -DUNIXCOMMON -DDC +ifndef NOHW + OPTS+=-DSTATIC_OPENGL -DMINI_GL_COMPATIBILITY -DKOS_GL_COMPATIBILITY +endif + SDL_CFLAGS?=-I$(KOS_BASE)/addons/include/SDL + SDL_LDFLAGS?=-lSDL + LDFLAGS=$(KOS_LDFLAGS) + LIBS:=$(KOS_LIBS) -lconio -lm +ifndef NOMIXER + LIBS:=-loggvorbisplay -lSDL $(LIBS) +endif + +ifdef LWIP + OPTS+=-I$(KOS_BASE)/../kos-ports/lwip/kos/include -I$(KOS_BASE)/../kos-ports/lwip/lwip/src/include/ipv4 -I$(KOS_BASE)/../kos-ports/lwip/lwip/src/include -DIPv4 + LIBS:=-llwip4 -lkosutils $(LIBS) + OPTS+=-DHAVE_LWIP +endif +ifndef NOHW + LIBS+=-lgl +endif + + i_system_o+=$(OBJDIR)/dchelp.o + i_main_o=$(KOS_START) $(OBJDIR)/i_main.o $(OBJEXTRA) + + # name of the exefile + EXENAME?=SRB2.elf + BINNAME?=SRB2.BIN diff --git a/src/sdl12/SRB2DC/SELFBOOT.BIN b/src/sdl12/SRB2DC/SELFBOOT.BIN new file mode 100644 index 0000000000000000000000000000000000000000..a87ee386927e4dd72d947aa08faecd1b94677c93 GIT binary patch literal 1408808 zcmeI(dz8)f;{WlzhnPZ5E=4r988PHeQ=)PyQDSn>rDn{GjK7;T_7fLkr9a_#g`;Xt+Ykk-H{qx3A zcq2f7009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5;&|4RZ1ZIiO+CNy1DI;+Z(gxhMx<;@Ac8d@Gos5)%b+=N5bs}@ZvzP!>8 zRez{@WsSJ&67KmRsh~{J^67)xeO*2&uUP3#55$z+T(V}BY6VS#+iqx_K4Q-0yUOgl zVrPSdQ0|ZhzfHU}5dKe0kx=v8{sVGDDfI&}g^XvC>s-KWlhY?FCo3;A)O={d(e{aZ z`UJ~ASvKpMl~YS*#qCKb^FwSxrDlnFwQrxDJ!sH?+zVe?D>fJm7JhN7+Vzt|%^!R) zH}k@y3*V(vR{zWkpERP>)uqmVQc8nR$H5sHnK_~0&JuwZRW1#LRt6`9|7?GpLLKwc z`e)^&UHJ03gX0Q+%Hg-)lQt}Ld*-mb%-pQsNBk}I_wkJ;PwjWdv-8tx)!$n`W=dk8 z-F+4%SKC?jlM>AnGn%E9ukyo`__X5B+*H3zYM|L=^|5$3Z z_P=D62>jA_{leg+z|#NRHT9t#!QX!m1lkVB8TKXvqPP7(+UTY^I#}+=YZ^t3op*Ra&Ta?`lqMF=EgQF zS+8lm5`kdKrNP42XVAd3!W#uTrVTm&$F=O6nN|ptHz1VPH#5}bp3WJ?r_G)eGcxgx z#G|$H0tu5=uB(&SbX7t@r|NmdCMU&ZCrnFEsC8Xl>hcHrmQBbGWn7Zb?(wCSM%`ozII&QmVIZ`{e9SD zg)1vIIiY>g{UzG`aXK^c{A-#pZA@bPuw|jDTbpF2_nS3;V%17FYzr2ido~SDtn^T& z1)ZzxD$!zP#?*&ix^HHU5))STEjn!1O^Fkp&8)byMDvvynT_wfKCfxie3uY9}KAO=iyXc6=7G#VlnVpgMVn*Mjt?heuPAJ=J>$BNKtF^6CxWeG8 z!KNc(5^5#o-IG!5@!3_g2P6!xQ8M9!Ce>;+?O)`{#FLu_7rr2SD<%Xp3g3TPF`;O% zaN!w+|6F(t`{oW9dSUqW0vBGvfB&s-TR6T!7d~`mK;DJ-$=_TZNH6>z|NfMYDWL{A z8KIUXCzPEKH=%4^!)eJ0?SG6NUvgbAVO+lnaT$SPOUrL5zqMKUxZ=T1SCkICS$$fW zkuSt0ygIZ>>6B&(+35)x?GySJUTpBZ@zdswh{*_kb$oor%ePOSTr4i(mir#;6zo6m z&Q9Iur?>1=kg};^ks;+;CQf-Jw#bpI8Wx+}Fmr0}bGf0kiixZ0j9hr<QIf z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 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 E52|=-G5`Po literal 0 HcmV?d00001 diff --git a/src/sdl12/SRB2DC/VMU.xbm b/src/sdl12/SRB2DC/VMU.xbm new file mode 100644 index 000000000..0d56985f3 --- /dev/null +++ b/src/sdl12/SRB2DC/VMU.xbm @@ -0,0 +1,19 @@ +#define VMU_width 48 +#define VMU_height 32 +static unsigned char VMU_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x58, 0x75, 0x00, 0x00, 0x00, 0x00, 0xee, 0xaa, 0x00, 0x00, + 0x00, 0x86, 0x55, 0x55, 0x01, 0x00, 0x00, 0xda, 0xc8, 0xaf, 0x00, 0x00, + 0x00, 0x62, 0x55, 0x54, 0x00, 0x00, 0x00, 0x32, 0xa2, 0x6c, 0x00, 0x00, + 0x00, 0x5c, 0x55, 0xfd, 0x01, 0x00, 0x00, 0xac, 0x88, 0xaa, 0x02, 0x00, + 0x00, 0x54, 0x75, 0x55, 0x05, 0x00, 0x00, 0xac, 0xbf, 0xaa, 0x0a, 0x00, + 0x00, 0xd6, 0x61, 0x55, 0x15, 0x00, 0x00, 0xe9, 0xc0, 0xaa, 0x2a, 0x00, + 0x00, 0x39, 0x40, 0x55, 0x55, 0x00, 0x00, 0x6d, 0xc0, 0xaa, 0xbe, 0x00, + 0x00, 0x6d, 0x40, 0xd5, 0xc3, 0x00, 0x00, 0x6d, 0xc0, 0xea, 0x00, 0x00, + 0x00, 0x29, 0x60, 0xf5, 0x00, 0x00, 0x00, 0x26, 0xe0, 0xfa, 0x00, 0x00, + 0x00, 0x58, 0xb8, 0xbd, 0x00, 0x00, 0x00, 0x84, 0x07, 0xdf, 0x00, 0x00, + 0x00, 0x08, 0x20, 0xae, 0x00, 0x00, 0x00, 0x30, 0xc0, 0x5f, 0x01, 0x00, + 0x00, 0xc0, 0x3f, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; diff --git a/src/sdl12/SRB2DC/dchelp.c b/src/sdl12/SRB2DC/dchelp.c new file mode 100644 index 000000000..5fdf04bc2 --- /dev/null +++ b/src/sdl12/SRB2DC/dchelp.c @@ -0,0 +1,134 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 2006 by Sonic Team Jr. +// +// 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. +// +// DESCRIPTION: +// stub and replacement "ANSI" C functions for use on Dreamcast/KOS +// +//----------------------------------------------------------------------------- +#include +#include +#ifndef HAVE_LWIP +#include +#endif +#include "../../doomdef.h" +#include "dchelp.h" + +int access(const char *path, int amode) +{ + file_t handle = FILEHND_INVALID; + + if (amode == F_OK || amode == R_OK) + handle=fs_open(path,O_RDONLY); + else if (amode == (R_OK|W_OK)) + handle=fs_open(path,O_RDWR); + else if (amode == W_OK) + handle=fs_open(path,O_WRONLY); + + if (handle != FILEHND_INVALID) + { + fs_close(handle); + return 0; + } + + return -1; +} + +double hypot(double x, double y) +{ + double ax, yx, yx2, yx1; + if (abs(y) > abs(x)) // |y|>|x| + { + ax = abs(y); // |y| => ax + yx = (x/y); + } + else // |x|>|y| + { + ax = abs(x); // |x| => ax + yx = (x/y); + } + yx2 = yx*yx; // (x/y)^2 + yx1 = sqrt(1+yx2); // (1 + (x/y)^2)^1/2 + return ax*yx1; // |x|*((1 + (x/y)^2)^1/2) +} + +#if !(defined (NONET) || defined (NOMD5)) +#ifdef HAVE_LWIP + +#include + +static uint8 ip[4]; +static char *h_addr_listtmp[2] = {ip, NULL}; +static struct hostent hostenttmp = {NULL, NULL, 0, 1, h_addr_listtmp}; + +struct hostent *gethostbyname(const char *name) +{ + struct sockaddr_in dnssrv; + dnssrv.sin_family = AF_INET; + dnssrv.sin_port = htons(53); + dnssrv.sin_addr.s_addr = htonl(0x0a030202); ///< what? + if (lwip_gethostbyname(&dnssrv, name, ip) < 0) + return NULL; + else + return &hostenttmp; +} +#else + +struct hostent *gethostbyname(const char *name) +{ + (void)name; + return NULL; +} + +int ioctl(int s, long cmd, void *argp) +{ + return fs_ioctl(s, argp, cmd); //FIONBIO? +} + +int select(int maxfdp1, void *readset, void *writeset, void *exceptset, + void *timeout) +{ + (void)maxfdp1; + (void)readset; + (void)writeset; + (void)exceptset; + (void)timeout; + errno = EAFNOSUPPORT; + return -1; +} + +int getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen) +{ + (void)s; + (void)level; //SOL_SOCKET + (void)optname; //SO_RCVBUF, SO_ERROR + (void)optval; + (void)optlen; + errno = EAFNOSUPPORT; + return -1; +} + +int setsockopt (int s, int level, int optname, void *optval, socklen_t optlen) +{ + (void)s; + (void)level; //SOL_SOCKET + (void)optname; //SO_REUSEADDR, SO_BROADCAST, SO_RCVBUF + (void)optval; + (void)optlen; + errno = EAFNOSUPPORT; + return -1; +} + +#endif +#endif diff --git a/src/sdl12/SRB2DC/dchelp.h b/src/sdl12/SRB2DC/dchelp.h new file mode 100644 index 000000000..236f31110 --- /dev/null +++ b/src/sdl12/SRB2DC/dchelp.h @@ -0,0 +1,51 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 2006 by Sonic Team Jr. +// +// 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. +// +// DESCRIPTION: +// stub and replacement "ANSI" C functions for use on Dreamcast/KOS +// +//----------------------------------------------------------------------------- + +#ifndef __I_DREAMCAST__ +#define __I_DREAMCAST__ + +struct hostent +{ + char *h_name; /* Official name of host. */ + char **h_aliases; /* Alias list. */ + int h_addrtype; /* Host address type. */ + int h_length; /* Length of address. */ + char **h_addr_list; /* List of addresses from name server. */ +#define h_addr h_addr_list[0] /* Address, for backward compatibility. */ +}; + +struct hostent *gethostbyname(const char *name); + +#ifndef HAVE_LWIP +#define INADDR_NONE ((uint32) 0xffffffff) +#define INADDR_LOOPBACK ((uint32) 0x7f000001) +#define SOCK_STREAM 1 +#define FIONBIO 0 +#define SOL_SOCKET 0 +#define SO_ERROR 0 +#define SO_REUSEADDR 0 +#define SO_BROADCAST 0 +#define SO_RCVBUF 0 +int ioctl(int s, long cmd, void *argp); +int select(int maxfdp1, void *readset, void *writeset, void *exceptset, void *timeout); +int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); +int setsockopt(int s, int level, int optname, void *optval, socklen_t optlen); +#endif +#endif diff --git a/src/sdl12/SRB2DC/i_udp.c b/src/sdl12/SRB2DC/i_udp.c new file mode 100644 index 000000000..ec5e305fc --- /dev/null +++ b/src/sdl12/SRB2DC/i_udp.c @@ -0,0 +1,455 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Portions Copyright (C) 2005 by Sonic Team Jr. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief KOS UDP network interface + +#include "../../doomdef.h" + +#include "../../i_system.h" +#include "../../d_event.h" +#include "../../d_net.h" +#include "../../m_argv.h" + +#include "../../doomstat.h" + +#include "../../i_net.h" + +#include "../../z_zone.h" + +#include "../../i_tcp.h" + +#include +//#include +#define NET_NONE 0x00000000 +#define NET_LOCAL 0x0100007F +#define NET_ANY 0xFFFFFFFF + +#define MAXBANS 20 + +typedef struct +{ + uint32 host; + uint16 port; +} IPaddress; + +static IPaddress clientaddress[MAXNETNODES+1]; +static boolean nodeconnected[MAXNETNODES+1]; + +static int mysocket = 0; +static boolean init_KOSUDP_driver = false; + +static size_t numbans = 0; +static IPaddress banned[MAXBANS]; +static boolean KOSUDP_bannednode[MAXNETNODES+1]; /// \note do we really need the +1? + +static inline int net_udp_sendto(int sock, const uint8 *data, int size, uint16 rem_port, uint32 rem_addr) +{ + uint8 dst_ip[4] = {((uint8*)(&(rem_addr)))[0], + ((uint8*)(&(rem_addr)))[1], + ((uint8*)(&(rem_addr)))[2], + ((uint8*)(&(rem_addr)))[3]}; + return net_udp_send_raw(net_default_dev, clientaddress[0].port, rem_port, dst_ip, data, size); + (void)sock; +} + +static inline int net_udp_recvfrom(int sock, uint8 *buf, int size, uint16 *rem_port, uint32 *rem_addr) +{ + return net_udp_recv(sock, buf, size); + (void)rem_port; + (void)rem_addr; +} + +static const char *KOSUDP_AddrToStr(IPaddress* sk) +{ + static char s[22]; // 255.255.255.255:65535 + sprintf(s,"%d.%d.%d.%d:%d", + ((uint8*)(&(sk->host)))[3], + ((uint8*)(&(sk->host)))[2], + ((uint8*)(&(sk->host)))[1], + ((uint8*)(&(sk->host)))[0], + net_ntohs(sk->port)); + return s; +} + +static const char *KOSUDP_GetNodeAddress(int node) +{ + if (!nodeconnected[node]) + return NULL; + return KOSUDP_AddrToStr(&clientaddress[node]); +} + +static const char *KOSUDP_GetBanAddress(size_t ban) +{ + if (ban > numbans) + return NULL; + return KOSUDP_AddrToStr(&banned[ban]); +} + +static boolean KOSUDP_cmpaddr(IPaddress* a, IPaddress* b) +{ + return (a->host == b->host && (b->port == 0 || a->port == b->port)); +} + +static SINT8 getfreenode(void) +{ + SINT8 j; + + for (j = 0; j < MAXNETNODES; j++) + if (!nodeconnected[j]) + { + nodeconnected[j] = true; + return j; + } + return -1; +} + +static void KOSUDP_Get(void) +{ + int size; + size_t i; + SINT8 j; + IPaddress temp = {clientaddress[BROADCASTADDR].host,clientaddress[BROADCASTADDR].port}; + + size = net_udp_recvfrom(mysocket,(char *)&doomcom->data, MAXPACKETLENGTH, &temp.port, &temp.host); + if (size == 0) + { + doomcom->remotenode = -1; // no packet + return; + } + + // find remote node number + for (i = 0; i < MAXNETNODES; i++) + if (KOSUDP_cmpaddr(&temp, &(clientaddress[i]))) + { + doomcom->remotenode = (INT16)i; // good packet from a game player + doomcom->datalength = (INT16)size; + return; + } + + // not found + + // find a free slot + j = getfreenode(); + if (j > 0) + { + M_Memcpy(&clientaddress[j], &temp, sizeof (temp)); + DEBFILE(va("New node detected: node:%d address:%s\n", j, + KOSUDP_GetNodeAddress(j))); + doomcom->remotenode = (INT16)j; // good packet from a game player + doomcom->datalength = (INT16)size; + // check if it's a banned dude so we can send a refusal later + for (i = 0; i < numbans; i++) + if (KOSUDP_cmpaddr(&temp, &banned[i])) + { + KOSUDP_bannednode[j] = true; + DEBFILE("This dude has been banned\n"); + break; + } + if (i == numbans) + KOSUDP_bannednode[j] = false; + return; + } + + DEBFILE("New node detected: No more free slots\n"); + doomcom->remotenode = -1; // no packet +} + +#if 0 +static boolean KOSUDP_CanSend(void) +{ + return true; +} +#endif + +static void KOSUDP_Send(void) +{ + const IPaddress *nodeinfo; + + if (!doomcom->remotenode || !nodeconnected[doomcom->remotenode]) + return; + + nodeinfo = clientaddress + doomcom->remotenode; + + if (net_udp_sendto(mysocket, (char *)&doomcom->data, doomcom->datalength, nodeinfo->port, nodeinfo->host) == -1) + { + CONS_Printf("KOSUDP: error sending data\n"); + } +} + +static void KOSUDP_FreeNodenum(int numnode) +{ + // can't disconnect from self :) + if (!numnode) + return; + + DEBFILE(va("Free node %d (%s)\n", numnode, KOSUDP_GetNodeAddress(numnode))); + + nodeconnected[numnode] = false; + + memset(&clientaddress[numnode], 0, sizeof (IPaddress)); +} + +static int KOSUDP_Socket(void) +{ + int temp = 0; + uint16 portnum = 0; + const uint32 hostip = net_default_dev?net_ntohl(net_ipv4_address(net_default_dev->ip_addr)):NET_LOCAL; + //Hurdler: I'd like to put a server and a client on the same computer + //Logan: Me too + //BP: in fact for client we can use any free port we want i have read + // in some doc that connect in udp can do it for us... + //Alam: where? + if (M_CheckParm("-clientport")) + { + if (!M_IsNextParm()) + I_Error("syntax: -clientport "); + portnum = net_ntohs(atoi(M_GetNextParm())); + } + else + portnum = net_ntohs(sock_port); + + temp = net_udp_sock_open(portnum, hostip, portnum, NET_NONE); + if (temp) + { + int btemp = net_udp_sock_open(portnum, hostip, portnum, NET_ANY); + clientaddress[0].port = portnum; + clientaddress[0].host = NET_NONE; + if (btemp) + { + clientaddress[BROADCASTADDR].port = net_ntohs(sock_port); + clientaddress[BROADCASTADDR].host = NET_ANY; + } + else + { + CONS_Printf("KOSUDP: can't setup broadcast sock\n"); + net_udp_sock_close(temp); + return 0; + } + } + else + { + CONS_Printf("KOSUDP: can't setup main sock\n"); + return 0; + } + + doomcom->extratics = 1; // internet is very high ping + + return temp; +} + +static void I_ShutdownKOSUDPDriver(void) +{ + //net_shutdown(); + init_KOSUDP_driver = false; +} + +static void I_InitKOSUDPDriver(void) +{ + if (init_KOSUDP_driver) + I_ShutdownKOSUDPDriver(); + else + net_init(); + D_SetDoomcom(); + memset(&clientaddress,0,sizeof (clientaddress)); + init_KOSUDP_driver = true; +} + +static void KOSUDP_CloseSocket(void) +{ + if (mysocket) + net_udp_sock_close(mysocket); + mysocket = 0; +} + +static SINT8 KOSUDP_NetMakeNodewPort(const char *hostname, const char* port) +{ + SINT8 newnode; + uint16 portnum = net_ntohs(sock_port); + + if (port && !port[0]) + portnum = net_ntohs((UINT16)atoi(port)); + + newnode = getfreenode(); + if (newnode == -1) + return -1; + // find ip of the server + clientaddress[newnode].port = portnum; + clientaddress[newnode].host = inet_addr(hostname); + + if (clientaddress[newnode].host == NET_NONE) + { + free(hostname); + return -1; + } + return newnode; +} + +static boolean KOSUDP_OpenSocket(void) +{ + size_t i; + + memset(clientaddress, 0, sizeof (clientaddress)); + + for (i = 0; i < MAXNETNODES; i++) + nodeconnected[i] = false; + + //CONS_Printf("KOSUDP Code starting up\n"); + + nodeconnected[0] = true; // always connected to self + nodeconnected[BROADCASTADDR] = true; + I_NetSend = KOSUDP_Send; + I_NetGet = KOSUDP_Get; + I_NetCloseSocket = KOSUDP_CloseSocket; + I_NetFreeNodenum = KOSUDP_FreeNodenum; + I_NetMakeNodewPort = KOSUDP_NetMakeNodewPort; + + //I_NetCanSend = KOSUDP_CanSend; + + // build the socket but close it first + KOSUDP_CloseSocket(); + mysocket = KOSUDP_Socket(); + + if (mysocket) + { +#if 0 + // for select + myset = SDLNet_AllocSocketSet(1); + if (!myset) + { + CONS_Printf("SDL_Net: %s",SDLNet_GetError()); + return false; + } + if (SDLNet_UDP_AddSocket(myset,mysocket) == -1) + { + CONS_Printf("SDL_Net: %s",SDLNet_GetError()); + return false; + } +#endif + return true; + } + return false; +} + +static boolean KOSUDP_Ban(int node) +{ + if (numbans == MAXBANS) + return false; + + M_Memcpy(&banned[numbans], &clientaddress[node], sizeof (IPaddress)); + banned[numbans].port = 0' + numbans++; + return true; +} + +static void KOSUDP_ClearBans(void) +{ + numbans = 0; +} + +// +// I_InitNetwork +// Only required for DOS, so this is more a dummy +// +boolean I_InitNetwork(void) +{ + char serverhostname[255]; + boolean ret = false; + //if (!M_CheckParm ("-kosnet")) + // return false; + // initilize the driver + I_InitKOSUDPDriver(); + I_AddExitFunc(I_ShutdownKOSUDPDriver); + if (!init_KOSUDP_driver) + return false; + + if (M_CheckParm("-udpport")) + { + if (M_IsNextParm()) + sock_port = (UINT16)atoi(M_GetNextParm()); + else + sock_port = 0; + } + + // parse network game options, + if (M_CheckParm("-server") || dedicated) + { + server = true; + + // If a number of clients (i.e. nodes) is specified, the server will wait for the clients + // to connect before starting. + // If no number is specified here, the server starts with 1 client, and others can join + // in-game. + // Since Boris has implemented join in-game, there is no actual need for specifying a + // particular number here. + // FIXME: for dedicated server, numnodes needs to be set to 0 upon start +/* if (M_IsNextParm()) + doomcom->numnodes = (INT16)atoi(M_GetNextParm()); + else */if (dedicated) + doomcom->numnodes = 0; + else + doomcom->numnodes = 1; + + if (doomcom->numnodes < 0) + doomcom->numnodes = 0; + if (doomcom->numnodes > MAXNETNODES) + doomcom->numnodes = MAXNETNODES; + + // server + servernode = 0; + // FIXME: + // ??? and now ? + // server on a big modem ??? 4*isdn + net_bandwidth = 16000; + hardware_MAXPACKETLENGTH = INETPACKETLENGTH; + + ret = true; + } + else if (M_CheckParm("-connect")) + { + if (M_IsNextParm()) + strcpy(serverhostname, M_GetNextParm()); + else + serverhostname[0] = 0; // assuming server in the LAN, use broadcast to detect it + + // server address only in ip + if (serverhostname[0]) + { + COM_BufAddText("connect \""); + COM_BufAddText(serverhostname); + COM_BufAddText("\"\n"); + + // probably modem + hardware_MAXPACKETLENGTH = INETPACKETLENGTH; + } + else + { + // so we're on a LAN + COM_BufAddText("connect any\n"); + + net_bandwidth = 800000; + hardware_MAXPACKETLENGTH = MAXPACKETLENGTH; + } + } + + I_NetOpenSocket = KOSUDP_OpenSocket; + I_Ban = KOSUDP_Ban; + I_ClearBans = KOSUDP_ClearBans; + I_GetNodeAddress = KOSUDP_GetNodeAddress; + I_GetBanAddress = KOSUDP_GetBanAddress; + bannednode = KOSUDP_bannednode; + + return ret; +} diff --git a/src/sdl12/SRB2DC/scramble.c b/src/sdl12/SRB2DC/scramble.c new file mode 100644 index 000000000..a3483b00d --- /dev/null +++ b/src/sdl12/SRB2DC/scramble.c @@ -0,0 +1,259 @@ +#include +#include + +#define MAXCHUNK (2048*1024) + +static unsigned int seed; + +void my_srand(unsigned int n) +{ + seed = n & 0xffff; +} + +unsigned int my_rand() +{ + seed = (seed * 2109 + 9273) & 0x7fff; + return (seed + 0xc000) & 0xffff; +} + +void load(FILE *fh, unsigned char *ptr, unsigned long sz) +{ + if (fread(ptr, 1, sz, fh) != sz) + { + fprintf(stderr, "Read error!\n"); + exit(1); + } +} + +void load_chunk(FILE *fh, unsigned char *ptr, unsigned long sz) +{ + static int idx[MAXCHUNK/32]; + int i; + + /* Convert chunk size to number of slices */ + sz /= 32; + + /* Initialize index table with unity, + so that each slice gets loaded exactly once */ + for (i = 0; i < sz; i++) + idx[i] = i; + + for (i = sz-1; i >= 0; --i) + { + /* Select a replacement index */ + int x = (my_rand() * i) >> 16; + + /* Swap */ + int tmp = idx[i]; + idx[i] = idx[x]; + idx[x] = tmp; + + /* Load resulting slice */ + load(fh, ptr+32*idx[i], 32); + } +} + +void load_file(FILE *fh, unsigned char *ptr, unsigned long filesz) +{ + unsigned long chunksz; + + my_srand(filesz); + + /* Descramble 2 meg blocks for as long as possible, then + gradually reduce the window down to 32 bytes (1 slice) */ + for (chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1) + while (filesz >= chunksz) + { + load_chunk(fh, ptr, chunksz); + filesz -= chunksz; + ptr += chunksz; + } + + /* Load final incomplete slice */ + if (filesz) + load(fh, ptr, filesz); +} + +void read_file(char *filename, unsigned char **ptr, unsigned long *sz) +{ + FILE *fh = fopen(filename, "rb"); + if (fh == NULL) + { + fprintf(stderr, "Can't open \"%s\".\n", filename); + exit(1); + } + if (fseek(fh, 0, SEEK_END)<0) + { + fprintf(stderr, "Seek error.\n"); + exit(1); + } + *sz = ftell(fh); + *ptr = malloc(*sz); + if ( *ptr == NULL ) + { + fprintf(stderr, "Out of memory.\n"); + exit(1); + } + if (fseek(fh, 0, SEEK_SET)<0) + { + fprintf(stderr, "Seek error.\n"); + exit(1); + } + load_file(fh, *ptr, *sz); + fclose(fh); +} + +void save(FILE *fh, unsigned char *ptr, unsigned long sz) +{ + if (fwrite(ptr, 1, sz, fh) != sz) + { + fprintf(stderr, "Write error!\n"); + exit(1); + } +} + +void save_chunk(FILE *fh, unsigned char *ptr, unsigned long sz) +{ + static int idx[MAXCHUNK/32]; + int i; + + /* Convert chunk size to number of slices */ + sz /= 32; + + /* Initialize index table with unity, + so that each slice gets saved exactly once */ + for (i = 0; i < sz; i++) + idx[i] = i; + + for (i = sz-1; i >= 0; --i) + { + /* Select a replacement index */ + int x = (my_rand() * i) >> 16; + + /* Swap */ + int tmp = idx[i]; + idx[i] = idx[x]; + idx[x] = tmp; + + /* Save resulting slice */ + save(fh, ptr+32*idx[i], 32); + } +} + +void save_file(FILE *fh, unsigned char *ptr, unsigned long filesz) +{ + unsigned long chunksz; + + my_srand(filesz); + + /* Descramble 2 meg blocks for as long as possible, then + gradually reduce the window down to 32 bytes (1 slice) */ + for (chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1) + while (filesz >= chunksz) + { + save_chunk(fh, ptr, chunksz); + filesz -= chunksz; + ptr += chunksz; + } + + /* Save final incomplete slice */ + if (filesz) + save(fh, ptr, filesz); +} + +void write_file(char *filename, unsigned char *ptr, unsigned long sz) +{ + FILE *fh = fopen(filename, "wb"); + if (fh == NULL) + { + fprintf(stderr, "Can't open \"%s\".\n", filename); + exit(1); + } + save_file(fh, ptr, sz); + fclose(fh); +} + +void descramble(char *src, char *dst) +{ + unsigned char *ptr = NULL; + unsigned long sz = 0; + FILE *fh; + + read_file(src, &ptr, &sz); + + fh = fopen(dst, "wb"); + if (fh == NULL) + { + fprintf(stderr, "Can't open \"%s\".\n", dst); + exit(1); + } + if ( fwrite(ptr, 1, sz, fh) != sz ) + { + fprintf(stderr, "Write error.\n"); + exit(1); + } + fclose(fh); + free(ptr); +} + +void scramble(char *src, char *dst) +{ + unsigned char *ptr = NULL; + unsigned long sz = 0; + FILE *fh; + + fh = fopen(src, "rb"); + if (fh == NULL) + { + fprintf(stderr, "Can't open \"%s\".\n", src); + exit(1); + } + if (fseek(fh, 0, SEEK_END)<0) + { + fprintf(stderr, "Seek error.\n"); + exit(1); + } + sz = ftell(fh); + ptr = malloc(sz); + if ( ptr == NULL ) + { + fprintf(stderr, "Out of memory.\n"); + exit(1); + } + if (fseek(fh, 0, SEEK_SET)<0) + { + fprintf(stderr, "Seek error.\n"); + exit(1); + } + if ( fread(ptr, 1, sz, fh) != sz ) + { + fprintf(stderr, "Read error.\n"); + exit(1); + } + fclose(fh); + + write_file(dst, ptr, sz); + + free(ptr); +} + +int main(int argc, char *argv[]) +{ + int opt = 0; + + if (argc > 1 && !strcmp(argv[1], "-d")) + opt ++; + + if (argc != 3+opt) + { + fprintf(stderr, "Usage: %s [-d] from to\n", argv[0]); + exit(1); + } + + if (opt) + descramble(argv[2], argv[3]); + else + scramble(argv[1], argv[2]); + + return 0; +} diff --git a/src/sdl12/SRB2PS3/ICON0.png b/src/sdl12/SRB2PS3/ICON0.png new file mode 100644 index 0000000000000000000000000000000000000000..140230c1e17bcf341498374ede7feea16ac5b54c GIT binary patch literal 3678 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 literal 0 HcmV?d00001 diff --git a/src/sdl12/SRB2PS3/Makefile.cfg b/src/sdl12/SRB2PS3/Makefile.cfg new file mode 100644 index 000000000..a4a01714a --- /dev/null +++ b/src/sdl12/SRB2PS3/Makefile.cfg @@ -0,0 +1,139 @@ +# +# Makefile.cfg for SRB2 for the PlayStation 3 using PSL1GHT +# + +# Check if PS3DEV and PSL1GHT is set in the environment. If so, continue with compilation. +.SUFFIXES: + +ifeq ($(strip $(PS3DEV)),) +$(error "Please set PS3DEV in your environment. export PS3DEV=ps3dev-toolchain") +endif + +ifeq ($(strip $(PSL1GHT)),) +$(error "Please set PSL1GHT in your environment. export PSL1GHT=PSL1GHT") +endif + +# Set compiler flags + +# Disable same warning flags +WFLAGS+=-Wno-shadow -Wno-char-subscripts -Wno-format + +ifdef JAILBREAK +EXENAME?=SRB2PS3-jb.elf +PKGNAME?=SRB2PS3-jb.pkg +else +EXENAME?=SRB2PS3.elf +PKGNAME?=SRB2PS3.pkg +endif +DGBNAME?=$(EXENAME).debug + +SRB2PS3DIR=sdl/SRB2PS3 +ICON0?=$(SRB2PS3DIR)/ICON0.png +SFOXML?=sfo.xml +SRB2TTF?=sdl/srb2.ttf + +TITLE=Sonic Robo Blast 2 v2.0.6 +APPID=SRB2-PS3 +CONTENTID=UP0001-$(APPID)_00-0000000000000000 + +FSELF=$(PS3DEV)/bin/fself.py +MAKE_SELF_NPDRM=$(PS3DEV)/ps3publictools/make_self_npdrm +FINALIZE=$(PS3DEV)/ps3publictools/package_finalize +SFO=$(PS3DEV)/bin/sfo.py +PKG=$(PS3DEV)/bin/pkg.py +PS3LOADEXE=$(PS3DEV)/ps3tools/ps3load +SED=sed +MV=mv +XARGS=xargs +FOR=for +SHXARGS:=$(XARGS) +SHSED:=$(SED) +SPRXLINKER=$(PS3DEV)/bin/sprxlinker + +ifdef JAILBREAK +PKGDIR=$(BIN)/pkg-jb +else +PKGDIR=$(BIN)/pkg +endif +USRDIR=$(PKGDIR)/USRDIR +ETCDIR=$(USRDIR)/etc +WGET=wget -P $(ETCDIR) -c -nc + +ifndef ECHO + FSELF:=@$(FSELF) + MAKE_SELF_NPDRM:=@$(MAKE_SELF_NPDRM) + FINALIZE:=@$(FINALIZE) + SFO:=@$(SFO) + PKG:=@$(PKG) + PS3LOADEXE:=@$(PS3LOADEXE) + SED:=@$(SED) + MV:=@$(MV) + SPRXLINKER:=@$(SPRXLINKER) + XARGS:=@$(XARGS) + FOR:=@(FOR) +endif + +# SRB2PS3 needs SDL_ttf to display any console text +SDL_TTF=1 + +# newlib has no support for networking +#NONET=1 + +# use absolute paths because changing PATH variable breaks distcc +PREFIX := $(PS3DEV)/ppu/bin/$(PREFIX) + +# PS3DEV toolchain libdir and includedir +PS3DEV_INC := $(PS3DEV)/ppu/include +PS3DEV_LIB := $(PS3DEV)/ppu/lib + +# PSL1GHT libdir and includedir +PSL1GHT_INC := $(PSL1GHT)/ppu/include +PSL1GHT_LIB := $(PSL1GHT)/ppu/lib + +PS3PORTS := $(PS3DEV)/portlibs +PS3PORTS_BIN := $(PS3PORTS)/ppu/bin +PS3PORTS_INC := $(PS3PORTS)/ppu/include + +PNG_CONFIG := $(PS3PORTS_BIN)/libpng-config +# static compilation +PNG_STATIC=1 + +SDL_CONFIG := $(PS3PORTS_BIN)/sdl-config + +INCLUDE := -I$(PSL1GHT_INC) -I$(PS3DEV_INC) -I$(PS3PORTS_INC) + +OPTS+=-D_PS3 -DUNIXCOMMON +CFLAGS+= -g $(INCLUDE) -L$(PSL1GHT_LIB) -L$(PS3DEV_LIB) -L$(PS3DEV)/lib +CXXFLAGS+=$(CFLAGS) +LDFLAGS+= -B$(PSL1GHT_LIB) -B$(PS3DEV_LIB) -B$(PS3DEV)/lib +LIBS+=-lrsx +ifndef NONET +LIBS+=-lnet -lsysmodule +endif + +$(BIN)/$(PKGNAME): $(OBJS) $(BIN)/$(EXENAME) + @echo Linking $(PKGNAME)... + -$(MKDIR) $(ETCDIR) + $(CP) $(ICON0) $(PKGDIR) + $(CP) $(SRB2TTF) $(ETCDIR) +ifdef WITHDATA + $(FOR) datafile in $(shell echo $(D_FILES) | $(SHSED) 's/\.srb/\.wad/' | $(SHXARGS) -n 1 basename); do \ + $(WGET) http://alam.srb2.org/SRB2/2.0.6-Final/Resources/$$datafile; \ + done +endif + $(SPRXLINKER) $(BIN)/$(EXENAME) +ifdef JAILBREAK + $(SED) 's/@@PS3_SYSTEM_VER@@/3.41/' $(SRB2PS3DIR)/$(SFOXML) > $(BIN)/$(SFOXML) + $(FSELF) -n $(BIN)/$(EXENAME) $(USRDIR)/EBOOT.BIN +else + $(SED) 's/@@PS3_SYSTEM_VER@@/3.55/' $(SRB2PS3DIR)/$(SFOXML) > $(BIN)/$(SFOXML) + $(MAKE_SELF_NPDRM) $(BIN)/$(EXENAME) $(USRDIR)/EBOOT.BIN $(CONTENTID) +endif + $(SFO) --title "$(TITLE)" --appid "$(APPID)" -f $(BIN)/$(SFOXML) $(PKGDIR)/PARAM.SFO + $(PKG) --contentid $(CONTENTID) $(PKGDIR)/ $(BIN)/$(PKGNAME) +ifndef JAILBREAK + $(FINALIZE) $(BIN)/$(PKGNAME) +endif + +run: $(BIN)/$(EXENAME) + $(PS3LOADEXE) $(USRDIR)/EBOOT.BIN diff --git a/src/sdl12/SRB2PS3/sfo.xml b/src/sdl12/SRB2PS3/sfo.xml new file mode 100644 index 000000000..d7719b540 --- /dev/null +++ b/src/sdl12/SRB2PS3/sfo.xml @@ -0,0 +1,39 @@ + + + + 02.06 + + + 0 + + + 1 + + + HG + + + This application was created with the official non-official SDK called PSL1GHT, for more information visit http://www.psl1ght.com/ . This is in no way associated with Sony Computer Entertainment Inc., please do not contact them for help, they will not be able to provide it. + + + 0 + + + 0@@PS3_SYSTEM_VER@@00 + + + 63 + + + 279 + + + Sonic Robo Blast 2 + + + SRB200000 + + + 02.06 + + diff --git a/src/sdl12/SRB2PSP/ICON0.png b/src/sdl12/SRB2PSP/ICON0.png new file mode 100644 index 0000000000000000000000000000000000000000..140230c1e17bcf341498374ede7feea16ac5b54c GIT binary patch literal 3678 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 literal 0 HcmV?d00001 diff --git a/src/sdl12/SRB2PSP/Makefile.cfg b/src/sdl12/SRB2PSP/Makefile.cfg new file mode 100644 index 000000000..f9ec6416b --- /dev/null +++ b/src/sdl12/SRB2PSP/Makefile.cfg @@ -0,0 +1,126 @@ +# +# Makefile.cfg for SRB2/PSP +# + +# +#hmmm, the PSP +# + + PSPSDK=$(shell psp-config -p) + PSPDEV=$(shell psp-config -d) + PSPPREFIX=$(shell psp-config -P) + STRIP=psp-strip + MKSFO?=mksfoex -d MEMSIZE=1 + #MKSFO=mksfo + PACK_PBP=pack-pbp + FIXUP=psp-fixup-imports + HOSTCC:=$(CC) + CC=$(PSPDEV)/bin/psp-gcc + OBJCOPY=psp-objcopy + OBJDUMP=psp-objdump +ifdef FIXEDPRX + PRXGEN=psp-prxgen +else + PRXGEN=$(OBJCOPY) +endif +ifndef PRXSIGN + SIGNER:=$(PSPDEV)/bin/$(OBJCOPY) +endif + +ifndef ECHO + MKSFO:=@$(MKSFO) + PACK_PBP:=@$(PACK_PBP) + FIXUP:=@$(FIXUP) + PRXGEN:=@$(PRXGEN) +endif + + PSP_EBOOT_TITLE=SRB2-PSP vME + PSP_EBOOT_SFO=$(BIN)/PARAM.SFO + PSP_EBOOT_ICON=sdl/SRB2PSP/ICON0.png + PSP_EBOOT_ICON1=NULL + PSP_EBOOT_UNKPNG=NULL + PSP_EBOOT_PIC1=sdl/SRB2PSP/PIC1.png + PSP_EBOOT_SND0=NULL + PSP_EBOOT_PSAR=NULL + + SIGNER?=sdl/SRB2PSP/psp-prxsign/psp-prxsign + + SDL=1 + PREFIX=psp + NONX86=1 + #NOHW=1 + NOHS=1 + NOMD5=1 + NONET=1 #No TCPIP code + NOPNG=1 #No Screenshot + + OPTS=-I$(PSPPREFIX)/include -I$(PSPSDK)/include + OPTS+=-DUNIXCOMMON -DFORCESDLMAIN -G0 + WFLAGS+=-Wno-undef + WFLAGS+=-O1 + LIBS=-lm + SDL_CONFIG?=$(PSPPREFIX)/bin/sdl-config + #SDL_CFLAGS?=-I$(PSPDEV)/psp/include/SDL + #SDL_LDFLAGS?=-lSDLmain -lSDL -lglut -lGLU -lGL -lpspgu -lpspaudiolib -lpspaudio -lpsphprm -lpspvfpu -lpsprtc +ifndef NOMIXER + LIBS:=-liberty -lvorbisfile -lvorbis -logg -lSDL $(LIBS) +endif +ifndef NOHW + OPTS+=-DSTATIC_OPENGL -DMINI_GL_COMPATIBILITY + LIBS+=-lGLU -lGL -lm +endif + #PSPSDK_LIBS=-L$(PSPSDK)/lib -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk + #LIBS+=$(PSPSDK_LIBS) -lc -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser -lpspkernel +ifdef FIXEDPRX + LDFLAGS := -specs=$(PSPSDK)/lib/prxspecs -Wl,-q,-T$(PSPSDK)/lib/linkfile.prx $(LDFLAGS) + LIBS+=$(PSPSDK)/lib/prxexports.o +endif + +ifeq ($(PSP_FW_VERSION),) +PSP_FW_VERSION=150 +endif + + CPPFLAGS:=-D_PSP_FW_VERSION=$(PSP_FW_VERSION) $(CPPFLAGS) + + + # name of the exefile + EXENAME?=SRB2PSP.elf + PRXNAME?=SRB2PSP.prx + DBGNAME?=SRB2PSP.debug + +post-build: $(BIN)/EBOOT.PBP + +kxploit: $(BIN)/$(EXENAME) $(PSP_EBOOT_SFO) + -$(MKDIR) "$(BIN)/kxploit/srb2" + @echo emitting kxploit/srb2/ + $(STRIP) $(BIN)/$(EXENAME) -o $(BIN)/kxploit/srb2/EBOOT.PBP + @echo emitting kxploit/srb2% + -$(MKDIR) "$(BIN)/kxploit/srb2%/" + $(PACK_PBP) "$(BIN)/kxploit/srb2%/EBOOT.PBP" $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \ + $(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \ + $(PSP_EBOOT_SND0) NULL $(PSP_EBOOT_PSAR) + +sdl/SRB2PSP/psp-prxsign/psp-prxsign: + -$(MAKE) -C sdl/SRB2PSP/psp-prxsign CFLAGS=-pipe CC="$(HOSTCC)" + +fix-up: $(BIN)/$(EXENAME) + @echo Running psp-fixup-imports on $(EXENAME) + $(FIXUP) $(BIN)/$(EXENAME) + +$(BIN)/$(PRXNAME): $(BIN)/$(EXENAME) fix-up + @echo Building $(PRXNAME) out of $(EXENAME) + $(PRXGEN) $(BIN)/$(EXENAME) $@ + +$(BIN)/EBOOT.PBP: $(BIN)/$(PRXNAME) $(SIGNER) $(PSP_EBOOT_SFO) + @echo Signing and running pack-pbp to make PBP + $(SIGNER) $(BIN)/$(PRXNAME) $(BIN)/$(PRXNAME).sign + $(PACK_PBP) $@ $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \ + $(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \ + $(PSP_EBOOT_SND0) $(BIN)/$(PRXNAME).sign $(PSP_EBOOT_PSAR) + $(REMOVE) $(BIN)/$(PRXNAME).sign + +$(PSP_EBOOT_SFO): + -$(MKDIR) $(BIN) + $(MKSFO) '$(PSP_EBOOT_TITLE)' $@ + +#include $(PSPSDK)/lib/build.mak diff --git a/src/sdl12/SRB2PSP/PIC1.png b/src/sdl12/SRB2PSP/PIC1.png new file mode 100644 index 0000000000000000000000000000000000000000..0722a96bc78ce4c82edaed348bc6f86826e5690a GIT binary patch literal 20300 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 literal 0 HcmV?d00001 diff --git a/src/sdl12/SRB2PSP/psp-prxsign/.gitignore b/src/sdl12/SRB2PSP/psp-prxsign/.gitignore new file mode 100644 index 000000000..6a07f1a5a --- /dev/null +++ b/src/sdl12/SRB2PSP/psp-prxsign/.gitignore @@ -0,0 +1,2 @@ +/psp-prxsign +/psp-prxsign.exe diff --git a/src/sdl12/SRB2PSP/psp-prxsign/Makefile b/src/sdl12/SRB2PSP/psp-prxsign/Makefile new file mode 100644 index 000000000..4a9b7da0f --- /dev/null +++ b/src/sdl12/SRB2PSP/psp-prxsign/Makefile @@ -0,0 +1,22 @@ +EXE=psp-prxsign +SRC=main.c cmac.c +OBJ=$(SRC:.c=.o)# replaces the .c from SRC with .o + +OPENSSL_PKGCONFIG?=openssl +OPENSSL_CFLAGS?=$(shell pkg-config $(OPENSSL_PKGCONFIG) --cflags) +OPENSSL_LDFLAGS?=$(shell pkg-config $(OPENSSL_PKGCONFIG) --libs) + +CFLAGS+=$(OPENSSL_CFLAGS) +LDFLAGS+=$(OPENSSL_LDFLAGS) + +.PHONY : all # .PHONY ignores files named all + +all: $(EXE) # all is dependent on $(BIN) to be complete + + +$(EXE): $(OBJ) # $(EXE) is dependent on all of the files in $(OBJ) to exist + $(CC) $^ $(LDFLAGS) -o $@ + +.PHONY : clean # .PHONY ignores files named clean +clean: + -$(RM) $(OBJ) $(EXE) diff --git a/src/sdl12/SRB2PSP/psp-prxsign/cmac.c b/src/sdl12/SRB2PSP/psp-prxsign/cmac.c new file mode 100644 index 000000000..f527f7a71 --- /dev/null +++ b/src/sdl12/SRB2PSP/psp-prxsign/cmac.c @@ -0,0 +1,130 @@ +#include "cmac.h" + +#define AES_128 0 +unsigned char const_Rb[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 +}; +unsigned char const_Zero[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +void xor_128(unsigned char *a, unsigned char *b, unsigned char *out) +{ + int i; + for (i=0;i<16; i++) + { + out[i] = a[i] ^ b[i]; + } +} + +/* AES-CMAC Generation Function */ + +static inline void leftshift_onebit(unsigned char *input,unsigned char *output) +{ + int i; + unsigned char overflow = 0; + + for ( i=15; i>=0; i-- ) + { + output[i] = input[i] << 1; + output[i] |= overflow; + overflow = (input[i] & 0x80)?1:0; + } +} + +void generate_subkey(unsigned char *key, unsigned char *K1, unsigned char *K2) +{ + unsigned char L[16]; + unsigned char Z[16]; + unsigned char tmp[16]; + int i; + + for ( i=0; i<16; i++ ) Z[i] = 0; + + AES_KEY aes; + AES_set_encrypt_key(key, 128, &aes); + + AES_encrypt(Z, L, &aes); + + if ( (L[0] & 0x80) == 0 ) /* If MSB(L) = 0, then K1 = L << 1 */ + { + leftshift_onebit(L,K1); + } else { /* Else K1 = ( L << 1 ) (+) Rb */ + leftshift_onebit(L,tmp); + xor_128(tmp,const_Rb,K1); + } + + if ( (K1[0] & 0x80) == 0 ) + { + leftshift_onebit(K1,K2); + } else { + leftshift_onebit(K1,tmp); + xor_128(tmp,const_Rb,K2); + } +} + +static inline void padding ( unsigned char *lastb, unsigned char *pad, int length ) +{ + int j; + + /* original last block */ + for ( j=0; j<16; j++ ) + { + if ( j < length ) + { + pad[j] = lastb[j]; + } else if ( j == length ) { + pad[j] = 0x80; + } else { + pad[j] = 0x00; + } + } +} + +void AES_CMAC ( unsigned char *key, unsigned char *input, int length, unsigned char *mac ) +{ + unsigned char X[16],Y[16], M_last[16], padded[16]; + unsigned char K1[16], K2[16]; + int n, i, flag; + generate_subkey(key,K1,K2); + + n = (length+15) / 16; /* n is number of rounds */ + + if ( n == 0 ) + { + n = 1; + flag = 0; + } else { + if ( (length%16) == 0 ) { /* last block is a complete block */ + flag = 1; + } else { /* last block is not complete block */ + flag = 0; + } + + } + + if ( flag ) { /* last block is complete block */ + xor_128(&input[16*(n-1)],K1,M_last); + } else { + padding(&input[16*(n-1)],padded,length%16); + xor_128(padded,K2,M_last); + } + AES_KEY aes; + AES_set_encrypt_key(key, 128, &aes); + + for ( i=0; i<16; i++ ) X[i] = 0; + for ( i=0; i +#include + +void xor_128(unsigned char *a, unsigned char *b, unsigned char *out); +void generate_subkey(unsigned char *key, unsigned char *K1, unsigned char *K2); +void AES_CMAC(unsigned char *key, unsigned char *input, int length, unsigned char *mac); + +#endif diff --git a/src/sdl12/SRB2PSP/psp-prxsign/kirk_header.h b/src/sdl12/SRB2PSP/psp-prxsign/kirk_header.h new file mode 100644 index 000000000..76c921ef0 --- /dev/null +++ b/src/sdl12/SRB2PSP/psp-prxsign/kirk_header.h @@ -0,0 +1,25 @@ +#ifndef __kirk_header__ +#define __kirk_header__ + +static unsigned int size_kirk_header = 272; +static unsigned char kirk_header[] __attribute__((aligned(16))) = { + 0x2a, 0x4f, 0x3c, 0x49, 0x8a, 0x73, 0x4e, 0xd1, 0xf4, 0x55, 0x93, 0x0b, 0x9b, 0x69, 0xdc, 0x65, + 0x73, 0x22, 0x69, 0xd3, 0x73, 0x96, 0x7a, 0x60, 0x66, 0x8c, 0x88, 0xcf, 0x2f, 0x83, 0x58, 0xbc, + 0xb2, 0x00, 0x0a, 0x11, 0x72, 0x43, 0xc5, 0xde, 0xef, 0xbb, 0x2c, 0xbf, 0x97, 0x79, 0x6b, 0x9c, + 0x10, 0x1e, 0x7c, 0x57, 0x0e, 0xdb, 0x1d, 0x61, 0x6e, 0xb5, 0xf9, 0x3d, 0x35, 0xe9, 0x5c, 0xd8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x33, 0x55, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7e, 0x50, 0x53, 0x50, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x22, 0x74, 0x69, 0x66, 0x70, 0x73, + 0x70, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x33, 0x55, 0x00, 0x50, 0x34, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x67, 0x3d, 0x00, 0x50, 0x55, 0x0a, 0x01, 0x10, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x6b, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4c, 0x6b, 0x3d, 0x00, 0xcc, 0xbb, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, +}; + +#endif diff --git a/src/sdl12/SRB2PSP/psp-prxsign/main.c b/src/sdl12/SRB2PSP/psp-prxsign/main.c new file mode 100644 index 000000000..a970ae6c1 --- /dev/null +++ b/src/sdl12/SRB2PSP/psp-prxsign/main.c @@ -0,0 +1,190 @@ +#include +#include +#include +#include +#include +#include "cmac.h" +#include "kirk_header.h" +#include "psp_header.h" + +typedef unsigned char byte; + +typedef struct { + byte key[16]; + byte ckey[16]; + byte head_hash[16]; + byte data_hash[16]; + byte unused[32]; + int unk1; // 1 + int unk2; // 0 + int unk3[2]; + int datasize; + int dataoffset; + int unk4[6]; +} kirk1head_t; + +// secret kirk command 1 key +byte kirk_key[] = { + 0x98, 0xc9, 0x40, 0x97, 0x5c, 0x1d, 0x10, 0xe8, 0x7f, 0xe6, 0x0e, 0xa3, 0xfd, 0x03, 0xa8, 0xba +}; + +int main(int argc, char **argv) +{ + int i, relrem, size, fullsize, blocks, datasize; + size_t j; + kirk1head_t kirk; + byte iv[16]; + byte cmac[32]; + byte subk[32]; + byte psph[0x150]; + byte *datablob; + byte *filebuff; + FILE *f; + AES_KEY aesKey; + Elf32_Ehdr *ehdr; + Elf32_Shdr *shdr; + Elf32_Rel *relo; + + if(argc < 3) { + printf("Usage: %s unsigned.prx signed.prx\n", argv[0]); + return 1; + } + + // clean kirk header, use modified PRXdecrypter to get it + /*f = fopen(argv[1], "rb"); + if(!f) { + printf("failed to open %s\n", argv[1]); + return 1; + } + fread(&kirk, 1, sizeof(kirk1head_t), f); + fclose(f);*/ + //memcpy(&kirk, kirk_header, size_kirk_header); + memcpy(&kirk, kirk_header, sizeof(kirk1head_t)); + + datasize = kirk.datasize; + if(datasize % 16) datasize += 16 - (datasize % 16); + + // original ~PSP header + /*f = fopen(argv[2], "rb"); + if(!f) { + free(datablob); + printf("failed to open %s\n", argv[2]); + return 1; + } + fread(psph, 1, 0x150, f); + fclose(f);*/ + memcpy(&psph, psp_header, size_psp_header); + + // file to encrypt + f = fopen(argv[1], "rb"); + if(!f) { + printf("psp-prxsign: Unable to open PRX\n"); + return 1; + } + fseek(f, 0, SEEK_END); + size = ftell(f); + if(size > datasize - 16) { + fclose(f); + printf("psp-prxsign: PRX is too large\n"); + return 1; + } + printf("%s : %i\n", argv[1], size); + fseek(f, 0, SEEK_SET); + + fullsize = datasize + 0x30 + kirk.dataoffset; + + // datablob holds everything needed to calculate data HASH + datablob = malloc(fullsize); + if(!datablob) { + fclose(f); + printf("psp-prxsign: Failed to allocate memory for blob\n"); + return 1; + } + memset(datablob, 0, fullsize); + memcpy(datablob, &kirk.unk1, 0x30); + memcpy(datablob + 0x30, psph, kirk.dataoffset); + filebuff = datablob + 0x30 + kirk.dataoffset; + + int whocares = fread(filebuff, 1, size, f); + (void)whocares; + fclose(f); + + // remove relocations type 7 + relrem = 0; + ehdr = (void *)filebuff; + if(!memcmp(ehdr->e_ident, ELFMAG, 4) && ehdr->e_shnum) { + shdr = (void *)(filebuff + ehdr->e_shoff); + for(i = 0; i < ehdr->e_shnum; i++) { + if(shdr[i].sh_type == 0x700000A0) { + relo = (void *)(filebuff + shdr[i].sh_offset); + for(j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++) { + if((relo[j].r_info & 0xFF) == 7) { + relo[j].r_info = 0; + relrem++; + } + } + } + } + } + //printf("%i relocations type 7 removed\ncalculating ...\n", relrem); + + // get AES/CMAC key + AES_set_decrypt_key(kirk_key, 128, &aesKey); + memset(iv, 0, 16); + AES_cbc_encrypt(kirk.key, kirk.key, 32, &aesKey, iv, AES_DECRYPT); + + // check header hash, optional + // if you take correct kirk header, hash is always correct +/* AES_CMAC(kirk.ckey, datablob, 0x30, cmac); + if(memcmp(cmac, kirk.head_hash, 16)) { + free(datablob); + printf("header hash invalid\n"); + return 1; + } +*/ + + // encrypt input file + AES_set_encrypt_key(kirk.key, 128, &aesKey); + memset(iv, 0, 16); + AES_cbc_encrypt(filebuff, filebuff, datasize, &aesKey, iv, AES_ENCRYPT); + + // make CMAC correct + generate_subkey(kirk.ckey, subk, subk + 16); + AES_set_encrypt_key(kirk.ckey, 128, &aesKey); + blocks = fullsize / 16; + memset(cmac, 0, 16); + for(i = 0; i < blocks - 1; i++) { + xor_128(cmac, &datablob[16 * i], cmac + 16); + AES_encrypt(cmac + 16, cmac, &aesKey); + } + + AES_set_decrypt_key(kirk.ckey, 128, &aesKey); + AES_decrypt(kirk.data_hash, iv, &aesKey); + xor_128(cmac, iv, iv); + xor_128(iv, subk, &datablob[16 * (blocks-1)]); + // check it, optional + // it works, this is only if you want to change something +/* AES_CMAC(kirk.ckey, datablob, fullsize, cmac); + if(memcmp(cmac, kirk.data_hash, 16)) { + fclose(f); + free(datablob); + printf("data hash calculation error\n"); + return 1; + } +*/ + f = fopen(argv[2], "wb"); + if(!f) { + free(datablob); + printf("psp-prxsign: Failed to write signed PRX\n"); + return 1; + } + //printf("saving ...\n"); + // save ~PSP header + fwrite(psph, 1, 0x150, f); + // save encrypted file + fwrite(filebuff, 1, fullsize - 0x30 - kirk.dataoffset, f); + fclose(f); + free(datablob); + //printf("everything done\n"); + return 0; +} diff --git a/src/sdl12/SRB2PSP/psp-prxsign/psp_header.h b/src/sdl12/SRB2PSP/psp-prxsign/psp_header.h new file mode 100644 index 000000000..7faef832c --- /dev/null +++ b/src/sdl12/SRB2PSP/psp-prxsign/psp_header.h @@ -0,0 +1,29 @@ +#ifndef __psp_header__ +#define __psp_header__ + +static unsigned int size_psp_header = 336; +static unsigned char psp_header[] __attribute__((aligned(16))) = { + 0x7e, 0x50, 0x53, 0x50, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x22, 0x74, 0x69, 0x66, 0x70, 0x73, + 0x70, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x33, 0x55, 0x00, 0x50, 0x34, 0x55, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x67, 0x3d, 0x00, 0x50, 0x55, 0x0a, 0x01, 0x10, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x6b, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4c, 0x6b, 0x3d, 0x00, 0xcc, 0xbb, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x90, 0x82, 0x4c, 0x48, 0xa3, 0x53, 0xb2, 0x1b, 0x13, 0x95, 0x2f, 0xf1, 0x0b, 0x90, 0x9c, 0x11, + 0x61, 0x40, 0x20, 0x67, 0xf8, 0xdb, 0xfc, 0x95, 0x5c, 0xbe, 0x8c, 0x80, 0xf3, 0x92, 0x03, 0x01, + 0xb0, 0xbe, 0xf5, 0xf8, 0xa1, 0xaf, 0xaf, 0xa8, 0x38, 0x26, 0x63, 0x09, 0x26, 0x0e, 0xb7, 0xd5, + 0x00, 0x33, 0x55, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5c, 0x3e, 0x03, 0x22, 0xe5, 0x7d, 0xb9, 0xd1, 0x13, 0x67, 0x97, 0xa3, 0x5b, 0xd8, 0x77, 0x1f, + 0xf0, 0x05, 0xf3, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x4a, 0xd7, 0x37, + 0xc2, 0x8f, 0x15, 0x43, 0x33, 0x93, 0x4d, 0x5b, 0xc0, 0x6e, 0xe4, 0x00, 0xc6, 0x0a, 0x71, 0x11, + 0x98, 0xb6, 0xc3, 0xb7, 0x59, 0x66, 0x21, 0xa8, 0x65, 0xf6, 0x53, 0xa9, 0x7a, 0x48, 0x17, 0xb6, +}; + +#endif diff --git a/src/sdl12/SRB2Pandora/Makefile.cfg b/src/sdl12/SRB2Pandora/Makefile.cfg new file mode 100644 index 000000000..c7f0f8449 --- /dev/null +++ b/src/sdl12/SRB2Pandora/Makefile.cfg @@ -0,0 +1,39 @@ +# Quick Pandora target to make a compliant SRB2 PND file. + +PNDNAME=SRB2.pnd +PNDDIR=$(BIN)/pnd +ICON=sdl/SRB2Pandora/icon.png +PXML=sdl/SRB2Pandora/PXML.xml + +SED=sed +CAT=cat +CP=cp +XARGS=xargs +FOR=for +WGET=wget -P $(PNDDIR) -c -nc + +SHXARGS:=$(XARGS) +SHSED:=$(SED) + +ifndef ECHO + CP:=@$(CP) + CAT:=@$(CAT) + SED:=@$(SED) + XARGS:=@$(XARGS) + FOR:=@(FOR) +endif + +$(BIN)/$(PNDNAME): $(BIN)/$(EXENAME) + @echo Linking $(PNDNAME)... + $(MKDIR) $(PNDDIR) + $(CP) $(BIN)/$(EXENAME) $(PNDDIR) + $(CP) $(ICON) $(PNDDIR) + $(CP) $(PXML) $(PNDDIR) +ifdef WITHDATA + $(FOR) datafile in $(shell echo $(D_FILES) | $(SHSED) 's/\.srb/\.wad/' | $(SHXARGS) -n 1 basename); do \ + $(WGET) http://alam.srb2.org/SRB2/2.0.6-Final/Resources/$$datafile; \ + done +endif + $(MKISOFS) -l -r -o $@ $(PNDDIR) + $(CAT) $(PXML) >> $@ + $(REMOVE) -r $(PNDDIR) diff --git a/src/sdl12/SRB2Pandora/PXML.xml b/src/sdl12/SRB2Pandora/PXML.xml new file mode 100644 index 000000000..33a9587db --- /dev/null +++ b/src/sdl12/SRB2Pandora/PXML.xml @@ -0,0 +1,17 @@ + + + + Sonic Robo Blast 2 + ソニック・ロボ・ブラスト・2 + A 3D Sonic fangame with a huge fanbase developing custom content, including characters, levels, and even large-scale modifications + + + + + + + + + + + diff --git a/src/sdl12/SRB2Pandora/icon.png b/src/sdl12/SRB2Pandora/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..63af73ac3a4e3046783312465aec2d985172f726 GIT binary patch literal 1690 zcmV;L24(q)P)O!-2lB^gLcZMPU)B9hVuf<6yDwU?fX z3ky{b9)wn$97OyF7K$k7!Y+%HJ!Fs`_8_7N3oYwmd#LMDR_Z(CP+?IDQqitximl=- z%<|pC{K!l*NoUfO-9q1`O(rwn_j%vXd*Amyi6Vr+ezp$mb2|X=Ut3!fKnNjCa|i$d z=m+oxhzJ0{%mCgvpL`8f{Rx(3DZ5=$X-5(ZA>`1|Eyr<+aVLY>*cF&v0kEv1B+>!s zAY$JY0&~1)F<*tM-i!^TB><|b%6$I&5Xb!vQ41kqFqa@iB{B#loleWGtt};b)Tbm- z88)?>g_#`Q2iyZipjaFbB9}V@B3&}OiN;7K@4z%o08oN-DFdK}QLj0`4mf{KxXyE1 ztB@jukj3JUPPOoJ*G@1YW?@-H5Ix;7>a~cwjxz`b-~cuZ9iZmBV6Pd2LP7}i_4Uc| z@t;GJkohWzrXxD9JFg7r#Lhi6D;YYN4X?Crx0RJEv6EN;!20^S!pySvV0&?92GO+l zUNf`rWiSJU!V-uQJ^%#X;r>>f4^*L4DkaaH`8716J119nu3 zhCLfjiJr#L(C@IUqKpl|=A_=F(zuI6c{F*aF@vzMun~h81fr*rb|cVA6pMezXw4X7 zZ0tUc965rQFJEF~Bj;-$s9}Atr{(V33lBiCSd@13^&P9rg$w^+aB#5h%AGrZg1HqZ zqcnRZ2r;WP1hBBMAQu-GF*i5eFcO8r3??QfplKQg2M5v9)8k#;+}y;wckgia>_UVf zv=2lF0E~=`$kEYJoH%i!VZARDW-vK9iDSo(;rQ|60p|fg(=_CAIo!K9*7km@@0p@vsYx}=cBU~!g&6A%$e+KXx07F%;z_Nh%@88FI_>(6L zU|=`(rXhX&W}4^gWtFwHH3+ecLg8;zDi#3X!-o%h98Y!*EOr970?V?(LPCC9Akj3t`U#A-+5EjZ5cBu#7%? z_AKzhuC6W+5e^+X1OU$Y5a+;&CZjNy?C2B07Q|YV79T!*=)I9jrQq(y*w`3URmJe| za17@;g1E&1&3UaXInA4@s@B7{IDlabG#KZmAixN+kK3WWly)lFnF8Z=FVpI$pz zsZ{c5LgCFFqqHqG%igXCaXtP_T&-4>yLa!(d_Ircw{PR^+qXEE&w~hfLxiJ8kK*v* z!#h4~Zf*`b0dCW2uwg3^0T3MOyuBHxu(EPf#+i-1X0ETVPiC`OEH5v67pICvl*>8{ zhZZ9vBk1n#4ve2`Yirot+{Bytd1uH8M*Qrz3s_yf7aD!P^EC>dj5Qy7WpsUg9pmG@ zn3$yzBF4=3~sF*W-tuqpmgFn|Jpw=Hf`2a zRc%R?sDZdNi;`iqbfA{K-Lt_we*8G#d=&fm@mzc4^-LxsuYH|`uE+V}g5e6q*M9j6 zuU_@~+8ElF1Jv-4i&{=2eLrApr@c;|))TU%6k?f@q0-c?mo(SL`V)Y{^ zqf!}e9{|4-sZdevkitPPC") +endif + +# Set compiler flags + +SRB2NAME?=srb2wii +EXENAME?=$(SRB2NAME).elf +DBGNAME?=$(SRB2NAME).elf.debug +DOLNAME?=$(SRB2NAME).dol + +ICONPNG?=sdl/SRB2WII/icon.png +METAXML?=sdl/SRB2WII/meta.xml + +APPDIR=apps/$(SRB2NAME) +ZIPNAME=$(SRB2NAME).zip + +ELF2DOL=$(DEVKITPPC)/bin/elf2dol +WIILOADEXE=$(DEVKITPPC)/bin/wiiload +ZIP=zip -r -9 +WGET=wget -P srb2wii -c -nc +SED=sed +XARGS=xargs +SHXARGS:=$(XARGS) +SHSED:=$(SED) +FOR=for + +ifndef ECHO + ELF2DOL:=@$(ELF2DOL) + WIILOADEXE:=@$(WIILOADEXE) + ZIP:=@$(ZIP) + SED:=@$(SED) + XARGS:=@$(XARGS) + FOR:=@$(FOR) +endif + +# Disable same warning flags +WFLAGS+=-Wno-shadow -Wno-char-subscripts -Wno-old-style-definition -Wno-unsuffixed-float-constants + +# newlib has no support for networking +NONET=1 + +# use pkgconfig for PKG +PNG_PKGCONFIG=libpng + +# use absolute paths because changing PATH variable breaks distcc +PREFIX := $(DEVKITPPC)/bin/$(PREFIX) + +# FIXME: DevkitPPC and ready-compiled SDL Wii require these things to be in a silly order +# libogc/DevkitPro required stuff +LIBOGC := $(DEVKITPRO)/libogc +LIBOGC_INC := $(LIBOGC)/include +LIBOGC_LIB := $(LIBOGC)/lib + +PORTLIBS := $(DEVKITPRO)/portlibs/ppc +PORTLIBS_INC := $(PORTLIBS)/include +PORTLIBS_LIB := $(PORTLIBS)/lib + +SDL_CPPFLAGS := -I$(LIBOGC_INC)/SDL +SDL_LIB := $(DEVKITPRO)/libogc/lib/wii +INCLUDE := -I$(LIBOGC_INC) $(SDL_CPPFLAGS) -I$(PORTLIBS_INC) + +PKG_CONFIG_PATH := $(PORTLIBS)/lib/pkgconfig +PKG_BROKEN_SWTICH := --static --define-variable=DEVKITPRO=$(DEVKITPRO) +PNG_PKGCONFIG := $(PKG_CONFIG_PATH)/libpng.pc $(PKG_BROKEN_SWTICH) +ZLIB_PKGCONFIG := $(PKG_CONFIG_PATH)/zlib.pc $(PKG_BROKEN_SWTICH) + +ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags) +ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs) + +ifdef RDB + LIBS+=-ldb + OPTS+=-DREMOTE_DEBUGGING=$(RDB) +endif + +LIBS+= -L$(SDL_LIB) +ifndef NOMIXER + LD=$(CXX) + LIBS+=-lSDL_mixer -lvorbisidec -lsmpeg +endif +LIBS+=-lSDL + +LIBS+=$(ZLIB_LDFLAGS) -lfat -lwiiuse -lbte -logc -lm -lwiikeyboard -L$(LIBOGC_LIB) + +MACHDEP = -DGEKKO -mrvl -mcpu=750 -meabi -mhard-float +OPTS+=-DWII -D_WII -DUNIXCOMMON +CFLAGS+=-D__BIG_ENDIAN__ -g -O3 -fsigned-char $(MACHDEP) $(INCLUDE) +CXXFLAGS+=$(CFLAGS) +LDFLAGS+=-g $(MACHDEP) -Wl,-Map,$(notdir $@).map + +SDL_CONFIG=/bin/true +SDL_CFLAGS= +SDL_LDFLAGS= + +$(BIN)/$(DOLNAME): $(BIN)/$(EXENAME) + @echo Linking $(DOLNAME)... + $(ELF2DOL) $(BIN)/$(EXENAME) $(BIN)/$(DOLNAME) + @echo Creating /apps/$(SRB2NAME)... + $(MKDIR) $(APPDIR) + $(CP) $(BIN)/$(DOLNAME) $(APPDIR)/boot.dol + $(CP) $(ICONPNG) $(APPDIR) + $(CP) $(METAXML) $(APPDIR) +ifdef WITHDATA + $(MKDIR) srb2wii + $(FOR) datafile in $(shell echo $(D_FILES) | $(SHSED) -e 's/\.srb/\.wad/' -e 's/music.dta//' | $(SHXARGS) -n 1 basename); do \ + $(WGET) http://alam.srb2.org/SRB2/2.0.6-Final/Resources/$$datafile; \ + done + # downsampled music.dta specially for SRB2Wii + $(WGET) http://repos.srb2.org/srb2ports/music.dta + $(ZIP) $(BIN)/$(ZIPNAME) $(APPDIR) srb2wii +else + $(ZIP) $(BIN)/$(ZIPNAME) $(APPDIR) +endif + $(REMOVE) -r $(APPDIR) + +run: $(BIN)/$(EXENAME) + $(WIILOADEXE) $(BIN)/$(DBGNAME) diff --git a/src/sdl12/SRB2WII/icon.png b/src/sdl12/SRB2WII/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d22324bc6a9e51dac5c2e82cb2d78ca73d277c23 GIT binary patch literal 11247 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 Z{vWl3$A6Dk3OWD)002ovPDHLkV1k2@h&uoP literal 0 HcmV?d00001 diff --git a/src/sdl12/SRB2WII/meta.xml b/src/sdl12/SRB2WII/meta.xml new file mode 100644 index 000000000..843176d3a --- /dev/null +++ b/src/sdl12/SRB2WII/meta.xml @@ -0,0 +1,18 @@ + + + SRB2Wii + Callum + 2.0.6 + 20101207 + A 3D Sonic fangame + Sonic Robo Blast 2 is a 3D fangame by a small group called +Sonic Team Junior, using the Doom engine as a base. +The game has been worked on for almost 11 years so far, and +it is still being very much developed today, with a huge +fanbase developing custom content, including characters, +levels, and even large-scale modifications that play out +a brand new adventure. +Based on the Doom II engine, SRB2's system requirements +are very low, even the oldest computers can play it at a +decent speed. + diff --git a/src/sdl12/SRB2XBOX/Makefile.cfg b/src/sdl12/SRB2XBOX/Makefile.cfg new file mode 100644 index 000000000..56966d438 --- /dev/null +++ b/src/sdl12/SRB2XBOX/Makefile.cfg @@ -0,0 +1,44 @@ +# +# Makefile.cfg for SRB2/XBOX +# + +# +#hmmm, the XBOX +# + + NOHW=1 #No working OpenGL right now + NOHS=1 #No HWSound right now + NOASM=1 #No Fast code + NONET=1 #No network code + NOMD5=1 #No Slow MD5 + NOPNG=1 #No Screenshot + #SDLMAIN=1 #SDLMain! + +ifndef OPENXDK + OPENXDK=/usr/local/openxdk +endif + + CXBE=$(OPENXDK)/bin/cxbe + +ifdef ECHO + CXBE:=@$(CXBE) +endif + +ifndef NOHW + OPTS+=-DMINI_GL_COMPATIBILITY +endif + + BUILTLM=-fno-builtin + CFLAGS+=-D_XBOX -std=gnu99 -ffreestanding $(BUILTLM) -fno-exceptions + CFLAGS+=-I$(OPENXDK)/i386-pc-xbox/include -I$(OPENXDK)/include + OPTS+=-nostdlib -mno-cygwin -march=i386 + LDFLAGS+=-nostdlib -Wl,--file-alignment,0x20 -Wl,--section-alignment,0x20 -shared -Wl,--entry,_WinMainCRTStartup -Wl,--strip-all -L$(OPENXDK)/i386-pc-xbox/lib -L$(OPENXDK)/lib + LIBS=-lg -lc -lm + SDL_CFLAGS?=-I$(OPENXDK)/include/SDL + SDL_LDFLAGS?=-lSDL -lopenxdk -lhal -lc -lhal -lusb -lhal -lc -lxboxkrnl + + i_system_o+=$(OBJDIR)/xboxhelp.o + + # name of the exefile + EXENAME?=SRB2XBOX.EXE + BINNAME?=default.xbe diff --git a/src/sdl12/SRB2XBOX/xboxhelp.c b/src/sdl12/SRB2XBOX/xboxhelp.c new file mode 100644 index 000000000..9de01712f --- /dev/null +++ b/src/sdl12/SRB2XBOX/xboxhelp.c @@ -0,0 +1,91 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 2004 by Sonic Team Jr. +// +// 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. +// +// DESCRIPTION: +// stub and replacement "ANSI" C functions for use under OpenXDK +// +//----------------------------------------------------------------------------- + +#include "../../doomdef.h" +#include "xboxhelp.h" +#ifdef __GNUC__ +#include +#else +#include +#endif + +char *getcwd(char *_buf, size_t _size ) +{ + (void)_buf; + (void)_size; + return _buf; +} + +#ifdef _MSC_VER +int mkdir(const char *path) +{ + (void)path; + return 0; +} +#elif 0 //__GNUC__? +int mkdir(const char *path, mode_t _mode) +{ + (void)path; + (void)_mode; + return 0; +} +#endif + +int chdir (const char *__path ) +{ + (void)__path; + return 0; +} + +time_t time(time_t *T) +{ + long returntime = 0; + (void)T; +/* + SYSTEMTIME st; + FILETIME stft; + INT64 ftli; + if (!T) return returntime; + GetSystemTime(&st); + SystemTimeToFileTime(&st,&stft); + CopyMemory(&ftli,&stft,sizeof (LARGE_INTEGER)); + returntime = (long)ftli; + *T = returntime; +*/ + return returntime; +} + +#ifdef _MSC_VER +#include +void __cdecl _RTC_Initialize(void) +{ +} +char *getenv(const char *__env) +{ + __env = NULL; + return NULL; +} + +int putenv(const char *__env) +{ + __env = NULL; + return 0; +} +#endif diff --git a/src/sdl12/SRB2XBOX/xboxhelp.h b/src/sdl12/SRB2XBOX/xboxhelp.h new file mode 100644 index 000000000..97ef0a3be --- /dev/null +++ b/src/sdl12/SRB2XBOX/xboxhelp.h @@ -0,0 +1,6 @@ +#if defined (_MSC_VER) +int access(const char *path, int amode); +char *getcwd(char *_buf, size_t _size ); +int mkdir(const char *path); +int chdir (const char *__path ); +#endif diff --git a/src/sdl12/Srb2SDL-vc10.vcxproj b/src/sdl12/Srb2SDL-vc10.vcxproj new file mode 100644 index 000000000..192f19156 --- /dev/null +++ b/src/sdl12/Srb2SDL-vc10.vcxproj @@ -0,0 +1,1464 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + Srb2SDL + {61BA7D3C-F77D-4D31-B718-1177FE482CF2} + Srb2SDL + + + + Application + false + + + Application + false + + + Application + false + + + Application + false + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\..\..\bin\VC10\$(Platform)\$(Configuration)\ + .\..\..\objs\VC10\$(Platform)\$(Configuration)\SDL\ + true + .\..\..\bin\VC10\$(Platform)\$(Configuration)\ + .\..\..\objs\VC10\$(Platform)\$(Configuration)\SDL\ + true + .\..\..\bin\VC10\$(Platform)\$(Configuration)\ + .\..\..\objs\VC10\$(Platform)\$(Configuration)\SDL\ + false + .\..\..\bin\VC10\$(Platform)\$(Configuration)\ + .\..\..\objs\VC10\$(Platform)\$(Configuration)\SDL\ + false + $(SDL12_PREFIX)\include;$(SDL12_MIXER_PREFIX)\include;$(FMOD3_PREFIX)api\inc;$(IncludePath) + $(SDL12_PREFIX)\include;$(SDL12_MIXER_PREFIX)\include;$(FMOD3_PREFIX)api\inc;$(IncludePath) + $(SDL12_PREFIX)\include;$(SDL12_MIXER_PREFIX)\include;$(FMOD3_PREFIX)api\inc;$(IncludePath) + $(SDL12_PREFIX)\include;$(SDL12_MIXER_PREFIX)\include;$(FMOD3_PREFIX)api\inc;$(IncludePath) + $(SDL12_PREFIX)\lib;$(SDL12_MIXER_PREFIX)\lib;$(LibraryPath) + $(SDL12_PREFIX)\lib;$(SDL12_MIXER_PREFIX)\lib;$(LibraryPath) + $(SDL12_PREFIX)\lib\x64;$(SDL12_MIXER_PREFIX)\lib\x64;$(LibraryPath) + $(SDL12_PREFIX)\lib\x64;$(SDL12_MIXER_PREFIX)\lib\x64;$(LibraryPath) + + + + Getting revision number from the SCM system + "$(ProjectDir)..\..\comptime.bat" "$(ProjectDir).." + + + .\..\..\bin\VC10\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.tlb + + + + + Disabled + $(ProjectDir)..\..\libs\libpng-src;$(ProjectDir)..\..\libs\zlib;%(AdditionalIncludeDirectories) + _DEBUG;USE_WGL_SWAP;DIRECTFULLSCREEN;SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;USEASM;HAVE_PNG;COMPVERSION;HAVE_BLUA;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + $(IntDir) + $(IntDir)Srb2SDL.pdb + true + Level4 + true + true + EditAndContinue + CompileAsC + 4121;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + SDL.lib;SDL_mixer.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)srb2sdl.exe + true + true + $(OutDir)srb2sdl.pdb + Console + false + + + MachineX86 + + + true + $(OutDir)Srb2sdl.bsc + + + + + Getting revision number from the SCM system + "$(ProjectDir)..\..\comptime.bat" "$(ProjectDir).." + + + X64 + .\..\..\bin\VC10\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.tlb + + + + + Disabled + $(ProjectDir)..\..\libs\libpng-src;$(ProjectDir)..\..\libs\zlib;%(AdditionalIncludeDirectories) + _DEBUG;USE_WGL_SWAP;DIRECTFULLSCREEN;SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;HAVE_PNG;COMPVERSION;HAVE_BLUA;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + $(IntDir) + $(IntDir)Srb2SDL.pdb + true + Level4 + true + true + ProgramDatabase + CompileAsC + 4121;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + SDL.lib;SDL_mixer.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)srb2sdl.exe + true + true + $(OutDir)srb2sdl.pdb + Console + false + + + MachineX64 + + + true + $(OutDir)Srb2sdl.bsc + + + + + Getting revision number from the SCM system + "$(ProjectDir)..\..\comptime.bat" "$(ProjectDir).." + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\..\..\bin\VC10\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.tlb + + + + + /MP %(AdditionalOptions) + Disabled + OnlyExplicitInline + true + Speed + true + $(ProjectDir)..\..\libs\libpng-src;$(ProjectDir)..\..\libs\zlib;%(AdditionalIncludeDirectories) + NDEBUG;SDLMAIN;NO_STDIO_REDIRECT;USE_WGL_SWAP;DIRECTFULLSCREEN;SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;USEASM;HAVE_PNG;COMPVERSION;HAVE_BLUA;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + true + MultiThreaded + .\..\..\objs\VC10\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.pch + $(IntDir) + $(IntDir)Srb2SDL.pdb + true + Level3 + true + ProgramDatabase + CompileAsC + 4121;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + SDL.lib;SDL_mixer.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)srb2sdl.exe + true + true + $(OutDir)srb2sdl.pdb + Windows + false + + + MachineX86 + + + true + $(OutDir)Srb2sdl.bsc + + + + + Getting revision number from the SCM system + "$(ProjectDir)..\..\comptime.bat" "$(ProjectDir).." + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\..\..\bin\VC10\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.tlb + + + + + /MP %(AdditionalOptions) + Disabled + OnlyExplicitInline + true + Speed + true + $(ProjectDir)..\..\libs\libpng-src;$(ProjectDir)..\..\libs\zlib;%(AdditionalIncludeDirectories) + NDEBUG;SDLMAIN;NO_STDIO_REDIRECT;USE_WGL_SWAP;DIRECTFULLSCREEN;SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;HAVE_PNG;COMPVERSION;HAVE_BLUA;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + true + MultiThreaded + .\..\..\objs\VC10\$(Platform)\$(Configuration)\SDL\Srb2SDL-vc9.pch + $(IntDir) + $(IntDir)Srb2SDL.pdb + true + Level3 + true + ProgramDatabase + CompileAsC + 4121;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + SDL.lib;SDL_mixer.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)srb2sdl.exe + true + true + $(OutDir)srb2sdl.pdb + Windows + false + + + MachineX64 + + + true + $(OutDir)Srb2sdl.bsc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Compiling %(Filename).nas with NASM... + nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)" + $(IntDir)%(Filename).obj;%(Outputs) + true + Compiling %(Filename).nas with NASM... + nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)" + $(IntDir)%(Filename).obj;%(Outputs) + Compiling %(Filename).nas with NASM... + nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)" + $(IntDir)%(Filename).obj;%(Outputs) + true + Compiling %(Filename).nas with NASM... + nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)" + $(IntDir)%(Filename).obj;%(Outputs) + + + Compiling %(Filename).nas with NASM... + nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)" + $(IntDir)%(Filename).obj;%(Outputs) + true + Compiling %(Filename).nas with NASM... + nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)" + $(IntDir)%(Filename).obj;%(Outputs) + Compiling %(Filename).nas with NASM... + nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)" + $(IntDir)%(Filename).obj;%(Outputs) + true + Compiling %(Filename).nas with NASM... + nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)" + $(IntDir)%(Filename).obj;%(Outputs) + + + Compiling %(Filename).nas with NASM... + nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)" + $(IntDir)%(Filename).obj;%(Outputs) + true + Compiling %(Filename).nas with NASM... + nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)" + $(IntDir)%(Filename).obj;%(Outputs) + Compiling %(Filename).nas with NASM... + nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)" + $(IntDir)%(Filename).obj;%(Outputs) + true + Compiling %(Filename).nas with NASM... + nasm -g -o $(IntDir)%(Filename).obj -f win32 "%(FullPath)" + $(IntDir)%(Filename).obj;%(Outputs) + + + + + + + + + + %(PreprocessorDefinitions) + \Users\alam\svn\srb2mods\SRB2\branches\ALAM\src\win32;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + \Users\alam\svn\srb2mods\SRB2\branches\ALAM\src\win32;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + \Users\alam\svn\srb2mods\SRB2\branches\ALAM\src\win32;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + \Users\alam\svn\srb2mods\SRB2\branches\ALAM\src\win32;%(AdditionalIncludeDirectories) + + + + + {72b01aca-7a1a-4f7b-acef-2607299cf052} + false + + + {73a5729c-7323-41d4-ab48-8a03c9f81603} + false + + + + + + \ No newline at end of file diff --git a/src/sdl12/Srb2SDL-vc9.vcproj b/src/sdl12/Srb2SDL-vc9.vcproj new file mode 100644 index 000000000..620202bdf --- /dev/null +++ b/src/sdl12/Srb2SDL-vc9.vcproj @@ -0,0 +1,5845 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/sdl12/Srb2SDL.dsp b/src/sdl12/Srb2SDL.dsp new file mode 100644 index 000000000..02c3b2701 --- /dev/null +++ b/src/sdl12/Srb2SDL.dsp @@ -0,0 +1,1057 @@ +# Microsoft Developer Studio Project File - Name="Srb2SDL" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Srb2SDL - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Srb2SDL.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Srb2SDL.mak" CFG="Srb2SDL - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Srb2SDL - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Srb2SDL - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Srb2SDL - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\..\bin\VC\Release\SDL" +# PROP Intermediate_Dir "..\..\objs\VC\Release\SDL" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /G5 /W3 /GX /Zi /Ot /Og /Oi /Op /Oy /Ob1 /I "..\..\libs\libpng-src" /I "..\..\libs\zlib" /D "NDEBUG" /D "SDLMAIN" /D "NO_STDIO_REDIRECT" /D "USE_WGL_SWAP" /D "DIRECTFULLSCREEN" /D "SDL" /D "HWRENDER" /D "HW3SOUND" /D "HAVE_FILTER" /D "HAVE_MIXER" /D "USEASM" /D "HAVE_PNG" /FR /FD /GF /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +# SUBTRACT RSC /x +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo /o"..\..\objs\SDL\Release\SRB2.bsc" +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 SDL.lib SDL_mixer.lib user32.lib advapi32.lib ws2_32.lib /nologo /subsystem:windows /pdb:"C:\srb2demo2\srb2sdl.pdb" /debug /machine:I386 /out:"C:\srb2demo2\srb2sdl.exe" +# SUBTRACT LINK32 /profile /pdb:none /incremental:yes + +!ELSEIF "$(CFG)" == "Srb2SDL - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\..\bin\VC\Debug\SDL" +# PROP Intermediate_Dir "..\..\objs\VC\Debug\SDL" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +MTL=midl.exe +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /G6 /W4 /WX /Gm /GX /ZI /Od /Op /I "..\..\libs\libpng-src" /I "..\..\libs\zlib" /D "_DEBUG" /D "USE_WGL_SWAP" /D "DIRECTFULLSCREEN" /D "SDL" /D "HWRENDER" /D "HW3SOUND" /D "HAVE_FILTER" /D "HAVE_MIXER" /D "USEASM" /D "HAVE_PNG" /FR /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +# SUBTRACT RSC /x +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo /o"..\..\objs\SDL\Debug\SRB2.bsc" +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 SDL.lib SDL_mixer.lib user32.lib advapi32.lib ws2_32.lib /nologo /subsystem:console /pdb:"C:\srb2demo2\srb2sdldebug.pdb" /debug /machine:I386 /out:"C:\srb2demo2\srb2sdldebug.exe" /pdbtype:sept +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "Srb2SDL - Win32 Release" +# Name "Srb2SDL - Win32 Debug" +# Begin Group "SDLapp" + +# PROP Default_Filter "" +# Begin Group "filter" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\filter\filters.c +# End Source File +# Begin Source File + +SOURCE=.\filter\filters.h +# End Source File +# Begin Source File + +SOURCE=.\filter\hq2x.c +# End Source File +# Begin Source File + +SOURCE=.\filter\hq2x.h +# End Source File +# Begin Source File + +SOURCE=.\filter\interp.h +# End Source File +# Begin Source File + +SOURCE=.\filter\lq2x.c +# End Source File +# Begin Source File + +SOURCE=.\filter\lq2x.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\dosstr.c +# End Source File +# Begin Source File + +SOURCE=.\endtxt.c +# End Source File +# Begin Source File + +SOURCE=.\endtxt.h +# End Source File +# Begin Source File + +SOURCE=..\filesrch.c +# End Source File +# Begin Source File + +SOURCE=..\filesrch.h +# End Source File +# Begin Source File + +SOURCE=.\hwsym_sdl.c +# End Source File +# Begin Source File + +SOURCE=.\hwsym_sdl.h +# End Source File +# Begin Source File + +SOURCE=.\i_cdmus.c +# End Source File +# Begin Source File + +SOURCE=.\i_main.c +# End Source File +# Begin Source File + +SOURCE=.\i_net.c +# End Source File +# Begin Source File + +SOURCE=.\i_sound.c +# End Source File +# Begin Source File + +SOURCE=.\i_system.c +# End Source File +# Begin Source File + +SOURCE=.\i_video.c +# End Source File +# Begin Source File + +SOURCE=.\IMG_xpm.c +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=.\ogl_sdl.c +# End Source File +# Begin Source File + +SOURCE=.\ogl_sdl.h +# End Source File +# Begin Source File + +SOURCE=..\hardware\r_opengl\r_opengl.c +# End Source File +# Begin Source File + +SOURCE=..\hardware\r_opengl\r_opengl.h +# End Source File +# Begin Source File + +SOURCE=.\SDL_icon.xpm +# End Source File +# Begin Source File + +SOURCE=.\SDL_main\SDL_win32_main.c + +!IF "$(CFG)" == "Srb2SDL - Win32 Release" + +!ELSEIF "$(CFG)" == "Srb2SDL - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sdlmain.h +# End Source File +# Begin Source File + +SOURCE=..\win32\Srb2win.rc +# End Source File +# Begin Source File + +SOURCE=..\win32\win_dbg.c +# End Source File +# Begin Source File + +SOURCE=..\win32\win_dbg.h +# End Source File +# Begin Source File + +SOURCE=..\win32\win_main.h +# End Source File +# End Group +# Begin Group "A_Asm" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\p5prof.h +# End Source File +# Begin Source File + +SOURCE=..\tmap.nas + +!IF "$(CFG)" == "Srb2SDL - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Compiling $(InputName).nas with NASM... +IntDir=.\..\..\objs\VC\Release\SDL +InputPath=..\tmap.nas +InputName=tmap + +"$(IntDir)/$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + nasm -g -o $(IntDir)/$(InputName).obj -f win32 $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "Srb2SDL - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Compiling $(InputName).nas with NASM... +IntDir=.\..\..\objs\VC\Debug\SDL +InputPath=..\tmap.nas +InputName=tmap + +"$(IntDir)/$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + nasm -g -o $(IntDir)/$(InputName).obj -f win32 $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\tmap_mmx.nas + +!IF "$(CFG)" == "Srb2SDL - Win32 Release" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Compiling $(InputName).nas with NASM... +IntDir=.\..\..\objs\VC\Release\SDL +InputPath=..\tmap_mmx.nas +InputName=tmap_mmx + +"$(IntDir)/$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + nasm -g -o $(IntDir)/$(InputName).obj -f win32 $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "Srb2SDL - Win32 Debug" + +# PROP Ignore_Default_Tool 1 +# Begin Custom Build - Compiling $(InputName).nas with NASM... + +IntDir=.\..\..\objs\VC\Debug\SDL +InputPath=..\tmap_mmx.nas +InputName=tmap_mmx + +"$(IntDir)/$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + nasm -g -o $(IntDir)/$(InputName).obj -f win32 $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\tmap_vc.nas + +!IF "$(CFG)" == "Srb2SDL - Win32 Release" + +# Begin Custom Build - Compiling $(InputName).nas with NASM... +IntDir=.\..\..\objs\VC\Release\SDL +InputPath=..\tmap_vc.nas +InputName=tmap_vc + +"$(IntDir)/$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + nasm -g -o $(IntDir)/$(InputName).obj -f win32 $(InputPath) + +# End Custom Build + +!ELSEIF "$(CFG)" == "Srb2SDL - Win32 Debug" + +# Begin Custom Build - Compiling $(InputName).nas with NASM... +IntDir=.\..\..\objs\VC\Debug\SDL +InputPath=..\tmap_vc.nas +InputName=tmap_vc + +"$(IntDir)/$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + nasm -g -o $(IntDir)/$(InputName).obj -f win32 $(InputPath) + +# End Custom Build + +!ENDIF + +# End Source File +# End Group +# Begin Group "D_Doom" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\comptime.c +# End Source File +# Begin Source File + +SOURCE=..\d_clisrv.c +# End Source File +# Begin Source File + +SOURCE=..\d_clisrv.h +# End Source File +# Begin Source File + +SOURCE=..\d_event.h +# End Source File +# Begin Source File + +SOURCE=..\d_main.c +# End Source File +# Begin Source File + +SOURCE=..\d_main.h +# End Source File +# Begin Source File + +SOURCE=..\d_net.c +# End Source File +# Begin Source File + +SOURCE=..\d_net.h +# End Source File +# Begin Source File + +SOURCE=..\d_netcmd.c +# End Source File +# Begin Source File + +SOURCE=..\d_netcmd.h +# End Source File +# Begin Source File + +SOURCE=..\d_netfil.c +# End Source File +# Begin Source File + +SOURCE=..\d_netfil.h +# End Source File +# Begin Source File + +SOURCE=..\d_player.h +# End Source File +# Begin Source File + +SOURCE=..\d_think.h +# End Source File +# Begin Source File + +SOURCE=..\d_ticcmd.h +# End Source File +# Begin Source File + +SOURCE=..\dehacked.c +# End Source File +# Begin Source File + +SOURCE=..\dehacked.h +# End Source File +# Begin Source File + +SOURCE=..\doomdata.h +# End Source File +# Begin Source File + +SOURCE=..\doomdef.h +# End Source File +# Begin Source File + +SOURCE=..\doomstat.h +# End Source File +# Begin Source File + +SOURCE=..\doomtype.h +# End Source File +# Begin Source File + +SOURCE=..\z_zone.c +# End Source File +# Begin Source File + +SOURCE=..\z_zone.h +# End Source File +# End Group +# Begin Group "F_Frame" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\f_finale.c +# End Source File +# Begin Source File + +SOURCE=..\f_finale.h +# End Source File +# Begin Source File + +SOURCE=..\f_wipe.c +# End Source File +# End Group +# Begin Group "G_Game" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\g_game.c +# End Source File +# Begin Source File + +SOURCE=..\g_game.h +# End Source File +# Begin Source File + +SOURCE=..\g_input.c +# End Source File +# Begin Source File + +SOURCE=..\g_input.h +# End Source File +# Begin Source File + +SOURCE=..\g_state.h +# End Source File +# End Group +# Begin Group "H_Hud" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\am_map.c +# End Source File +# Begin Source File + +SOURCE=..\am_map.h +# End Source File +# Begin Source File + +SOURCE=..\command.c +# End Source File +# Begin Source File + +SOURCE=..\command.h +# End Source File +# Begin Source File + +SOURCE=..\console.c +# End Source File +# Begin Source File + +SOURCE=..\console.h +# End Source File +# Begin Source File + +SOURCE=..\hu_stuff.c +# End Source File +# Begin Source File + +SOURCE=..\hu_stuff.h +# End Source File +# Begin Source File + +SOURCE=..\st_stuff.c +# End Source File +# Begin Source File + +SOURCE=..\st_stuff.h +# End Source File +# Begin Source File + +SOURCE=..\y_inter.c +# End Source File +# Begin Source File + +SOURCE=..\y_inter.h +# End Source File +# End Group +# Begin Group "Hw_Hardware" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\hardware\hw3dsdrv.h +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw3sound.c +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw3sound.h +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_bsp.c +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_cache.c +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_data.h +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_defs.h +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_dll.h +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_draw.c +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_drv.h +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_glide.h +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_glob.h +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_light.c +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_light.h +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_main.c +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_main.h +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_md2.c +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_md2.h +# End Source File +# Begin Source File + +SOURCE=..\hardware\hw_trick.c +# End Source File +# Begin Source File + +SOURCE=..\hardware\hws_data.h +# End Source File +# End Group +# Begin Group "I_Interface" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\byteptr.h +# End Source File +# Begin Source File + +SOURCE=..\i_joy.h +# End Source File +# Begin Source File + +SOURCE=..\i_net.h +# End Source File +# Begin Source File + +SOURCE=..\i_sound.h +# End Source File +# Begin Source File + +SOURCE=..\i_system.h +# End Source File +# Begin Source File + +SOURCE=..\i_tcp.c +# End Source File +# Begin Source File + +SOURCE=..\i_tcp.h +# End Source File +# Begin Source File + +SOURCE=..\i_video.h +# End Source File +# Begin Source File + +SOURCE=..\keys.h +# End Source File +# Begin Source File + +SOURCE=..\mserv.c +# End Source File +# Begin Source File + +SOURCE=..\mserv.h +# End Source File +# End Group +# Begin Group "M_Misc" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\m_argv.c +# End Source File +# Begin Source File + +SOURCE=..\m_argv.h +# End Source File +# Begin Source File + +SOURCE=..\m_bbox.c +# End Source File +# Begin Source File + +SOURCE=..\m_bbox.h +# End Source File +# Begin Source File + +SOURCE=..\m_cheat.c +# End Source File +# Begin Source File + +SOURCE=..\m_cheat.h +# End Source File +# Begin Source File + +SOURCE=..\m_dllist.h +# End Source File +# Begin Source File + +SOURCE=..\m_fixed.c +# End Source File +# Begin Source File + +SOURCE=..\m_fixed.h +# End Source File +# Begin Source File + +SOURCE=..\m_menu.c +# End Source File +# Begin Source File + +SOURCE=..\m_menu.h +# End Source File +# Begin Source File + +SOURCE=..\m_misc.c +# End Source File +# Begin Source File + +SOURCE=..\m_misc.h +# End Source File +# Begin Source File + +SOURCE=..\m_queue.c +# End Source File +# Begin Source File + +SOURCE=..\m_queue.h +# End Source File +# Begin Source File + +SOURCE=..\m_random.c +# End Source File +# Begin Source File + +SOURCE=..\m_random.h +# End Source File +# Begin Source File + +SOURCE=..\m_swap.h +# End Source File +# Begin Source File + +SOURCE=..\string.c +# End Source File +# End Group +# Begin Group "P_Play" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\info.c +# End Source File +# Begin Source File + +SOURCE=..\info.h +# End Source File +# Begin Source File + +SOURCE=..\p_ceilng.c +# End Source File +# Begin Source File + +SOURCE=..\p_enemy.c +# End Source File +# Begin Source File + +SOURCE=..\p_fab.c +# End Source File +# Begin Source File + +SOURCE=..\p_floor.c +# End Source File +# Begin Source File + +SOURCE=..\p_inter.c +# End Source File +# Begin Source File + +SOURCE=..\p_lights.c +# End Source File +# Begin Source File + +SOURCE=..\p_local.h +# End Source File +# Begin Source File + +SOURCE=..\p_map.c +# End Source File +# Begin Source File + +SOURCE=..\p_maputl.c +# End Source File +# Begin Source File + +SOURCE=..\p_maputl.h +# End Source File +# Begin Source File + +SOURCE=..\p_mobj.c +# End Source File +# Begin Source File + +SOURCE=..\p_mobj.h +# End Source File +# Begin Source File + +SOURCE=..\p_polyobj.c +# End Source File +# Begin Source File + +SOURCE=..\p_polyobj.h +# End Source File +# Begin Source File + +SOURCE=..\p_pspr.h +# End Source File +# Begin Source File + +SOURCE=..\p_saveg.c +# End Source File +# Begin Source File + +SOURCE=..\p_saveg.h +# End Source File +# Begin Source File + +SOURCE=..\p_setup.c +# End Source File +# Begin Source File + +SOURCE=..\p_setup.h +# End Source File +# Begin Source File + +SOURCE=..\p_sight.c +# End Source File +# Begin Source File + +SOURCE=..\p_spec.c +# End Source File +# Begin Source File + +SOURCE=..\p_spec.h +# End Source File +# Begin Source File + +SOURCE=..\p_telept.c +# End Source File +# Begin Source File + +SOURCE=..\p_tick.c +# End Source File +# Begin Source File + +SOURCE=..\p_tick.h +# End Source File +# Begin Source File + +SOURCE=..\p_user.c +# End Source File +# Begin Source File + +SOURCE=..\tables.c +# End Source File +# Begin Source File + +SOURCE=..\tables.h +# End Source File +# End Group +# Begin Group "R_Rend" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\r_bsp.c +# End Source File +# Begin Source File + +SOURCE=..\r_bsp.h +# End Source File +# Begin Source File + +SOURCE=..\r_data.c +# End Source File +# Begin Source File + +SOURCE=..\r_data.h +# End Source File +# Begin Source File + +SOURCE=..\r_defs.h +# End Source File +# Begin Source File + +SOURCE=..\r_draw.c +# End Source File +# Begin Source File + +SOURCE=..\r_draw.h +# End Source File +# Begin Source File + +SOURCE=..\r_draw16.c +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=..\r_draw8.c +# PROP Exclude_From_Build 1 +# End Source File +# Begin Source File + +SOURCE=..\r_local.h +# End Source File +# Begin Source File + +SOURCE=..\r_main.c +# End Source File +# Begin Source File + +SOURCE=..\r_main.h +# End Source File +# Begin Source File + +SOURCE=..\r_plane.c +# End Source File +# Begin Source File + +SOURCE=..\r_plane.h +# End Source File +# Begin Source File + +SOURCE=..\r_segs.c +# End Source File +# Begin Source File + +SOURCE=..\r_segs.h +# End Source File +# Begin Source File + +SOURCE=..\r_sky.c +# End Source File +# Begin Source File + +SOURCE=..\r_sky.h +# End Source File +# Begin Source File + +SOURCE=..\r_splats.c +# End Source File +# Begin Source File + +SOURCE=..\r_splats.h +# End Source File +# Begin Source File + +SOURCE=..\r_state.h +# End Source File +# Begin Source File + +SOURCE=..\r_things.c +# End Source File +# Begin Source File + +SOURCE=..\r_things.h +# End Source File +# Begin Source File + +SOURCE=..\screen.c +# End Source File +# Begin Source File + +SOURCE=..\screen.h +# End Source File +# Begin Source File + +SOURCE=..\v_video.c +# End Source File +# Begin Source File + +SOURCE=..\v_video.h +# End Source File +# End Group +# Begin Group "S_Sounds" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\s_sound.c +# End Source File +# Begin Source File + +SOURCE=..\s_sound.h +# End Source File +# Begin Source File + +SOURCE=..\sounds.c +# End Source File +# Begin Source File + +SOURCE=..\sounds.h +# End Source File +# End Group +# Begin Group "W_Wad" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\lzf.c +# End Source File +# Begin Source File + +SOURCE=..\lzf.h +# End Source File +# Begin Source File + +SOURCE=..\md5.c +# End Source File +# Begin Source File + +SOURCE=..\md5.h +# End Source File +# Begin Source File + +SOURCE=..\w_wad.c +# End Source File +# Begin Source File + +SOURCE=..\w_wad.h +# End Source File +# End Group +# Begin Group "Docs" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\doc\copying +# End Source File +# Begin Source File + +SOURCE=..\..\doc\faq.txt +# End Source File +# Begin Source File + +SOURCE=..\..\readme.txt +# End Source File +# Begin Source File + +SOURCE=..\..\doc\source.txt +# End Source File +# End Group +# Begin Source File + +SOURCE=..\win32\Srb2win.ico +# End Source File +# End Target +# End Project diff --git a/src/sdl12/Srb2SDL.dsw b/src/sdl12/Srb2SDL.dsw new file mode 100644 index 000000000..4f8f7bdce --- /dev/null +++ b/src/sdl12/Srb2SDL.dsw @@ -0,0 +1,74 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Srb2SDL"=.\Srb2SDL.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libpng + End Project Dependency + Begin Project Dependency + Project_Dep_Name zlib + End Project Dependency +}}} + +############################################################################### + +Project: "libpng"="..\..\libs\libpng-src\projects\visualc6\libpng.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name zlib + End Project Dependency +}}} + +############################################################################### + +Project: "s_openal"=..\hardware\s_openal\s_openal.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "zlib"=..\..\libs\zlib\projects\visualc6\zlib.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/src/sdl12/Srb2SDL.ico b/src/sdl12/Srb2SDL.ico new file mode 100644 index 0000000000000000000000000000000000000000..5ab791af37f815c0164e6053c34879ecf0c3fff0 GIT binary patch literal 2238 zcmc)MF-Rj>7{Ku_cLzDP@DL%Qupn6?*P33vQd8Mz`oK0Ph`Dgiyx^jhY&KvZg{5q< z97j^6k=O-`1g@}}N-UNHtTxHa7)=(1cmJ8mME5w$R{Pgigxg5B@1QM4sA*;#Kng;i=JRG^BCe5c{t`$Q_FItBBSZKZ1s) z!+y~6>ElPSY%R66mSaoHc2mn*T}z^Z^P+q$l0O&8oQR}yBFPQ0I`|g8iZ9`F_%wEt zSjR8pm+%Sv9G-b=HT*Gt8^4B6VEr4y3tsSomksIQTlgxzgwNsA_)Yw}T+1?k37^2v z;ca{yZ{eHxI=+Ih;LG?tK7&u;lX#8Sc#YS1jn{auUQ^GhC)6Bu!}m76jkoYkd>!x2 zUO|`9d2|MyLMNHOgKy!h_!2&cPvbZ7>-c5-5S!!vKKhCjw{g; z-@;e%C43H_#&6=+@yo2{604bDHRtd)zKyr=O?(|+!B_BQd>)^{r|?O<#%sLBYrMv5 zJU4XB4V|-HCu~=a?b_H7vGHxZg>T~P_zM1o*GD?|7QTuv;dA&j{)N|vc`d2okMZ01 zHGBg9(gIn!gKy!h_!6F#)@l5|FOa2ed>e1!oA^4O#d%?YEEb|h9248b8j&DgS|HbT z<>ux_uCA`+^72wHE-vKk>`W?^ikzOFO1WH?qoX6q=kv0&vm=>IMz*%LB$Z0Z%F2o) zlSx@zT$K6wd6}A;;*I!!%3$W(>-HTd+7G*&p;F)E<8NlYa(8<>GZ;M63h()5Y zu*}{Ui^VKirJmC9FdMsz#fBe({O%<0c=vZ(yS*>nuI)m&bnydu zH_Z3DBlmVXD1*DVqzWDg(+qp;N;k-Ny_uED6|?tYzCRt+x8jT^FhdZgB|06I2XV)F zBgiY2%?|GeL&MBE)4iNR1!XVHhv%>Mbnl&d=Zy2ehW+80kuL4w_y#BQkMpj4>9H3| z4SL=T{c(4A8giSiw;9Y3?e(HTGt8>5-c$6)o%b_$hRO5oPtvb~hxE70H1?d|4T|zF zhnZ}U!33t4^2=R(-}K6Ou!v(ASrulDK`g$nb_@QMgX!-L!wkopqc^kh?+S%NHpp>g zxT%Jwe*tq>y&b;(jeMaHf{|f(TWth)fKXYo@83^A2!kmm54RWgKb;Zd{Z-~u@AHf&LuPdK7(rJ^eQjQPkQ1 literal 0 HcmV?d00001 diff --git a/src/sdl12/dosstr.c b/src/sdl12/dosstr.c new file mode 100644 index 000000000..f9bbee9b4 --- /dev/null +++ b/src/sdl12/dosstr.c @@ -0,0 +1,38 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// This file is in the public domain. +// (Re)written by Graue in 2006. +// +//----------------------------------------------------------------------------- +/// \file +/// \brief String uppercasing/lowercasing functions for non-DOS non-Win32 +/// systems + +#include "../doomtype.h" + +#ifndef HAVE_DOSSTR_FUNCS + +#include + +int strupr(char *n) +{ + while (*n != '\0') + { + *n = toupper(*n); + n++; + } + return 1; +} + +int strlwr(char *n) +{ + while (*n != '\0') + { + *n = tolower(*n); + n++; + } + return 1; +} + +#endif diff --git a/src/sdl12/endtxt.c b/src/sdl12/endtxt.c new file mode 100644 index 000000000..1d7756b4d --- /dev/null +++ b/src/sdl12/endtxt.c @@ -0,0 +1,236 @@ +/* + * Function to write the SRB2 end message text + * + * Copyright (C) 1998 by Udo Munk + * + * This code is provided AS IS and there are no guarantees, none. + * Feel free to share and modify. + */ +//----------------------------------------------------------------------------- +/// \file +/// \brief Support to show ENDOOM text +/// +/// Loads the lump ENDOOM, set up the console to print +/// out the colors and text + +#include +#include + +// need this 19990118 by Kin +#include "../doomdef.h" +#include "../w_wad.h" +#include "../z_zone.h" +#include "endtxt.h" +/** \brief The ShowEndTxt function + + + Prints out the ENDOOM the way DOOM.EXE/DOOM2.EXE did for Win32 or Linux/GNU + + \return void + + +*/ + +void ShowEndTxt(void) +{ +#if !(defined (_WIN32_WCE) || defined (_XBOX) || defined (_arch_dreamcast)) + INT32 i; + UINT16 j, att = 0; + INT32 nlflag = 1; +#ifdef _WIN32 + HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD mode, bytesWritten; + CONSOLE_SCREEN_BUFFER_INFO backupcon; + COORD resizewin = {80,-1}; + CHAR let = 0; +#endif + UINT16 *ptext; + void *data; + lumpnum_t endoomnum = W_GetNumForName("ENDOOM"); + //char *col; + + /* if the xterm has more then 80 columns we need to add nl's */ + /* doesn't work, COLUMNS is not in the environment at this time ??? + col = I_getenv("COLUMNS"); + if (col) { + if (atoi(col) > 80) + nlflag++; + } + */ + + /* get the lump with the text */ + data = ptext = W_CacheLumpNum(endoomnum, PU_CACHE); + +#ifdef _WIN32 + if (co == INVALID_HANDLE_VALUE || GetFileType(co) != FILE_TYPE_CHAR || !GetConsoleMode(co, &mode)) // test if it a good handle + { + Z_Free(data); + return; + } + + backupcon.wAttributes = FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE; // Just in case + GetConsoleScreenBufferInfo(co, &backupcon); //Store old state + resizewin.Y = backupcon.dwSize.Y; + if (backupcon.dwSize.X < resizewin.X) + SetConsoleScreenBufferSize(co, resizewin); + + for (i=1; i<=80*25; i++) // print 80x25 text and deal with the attributes too + { + j = (UINT16)(*ptext >> 8); // attribute first + let = (char)(*ptext & 0xff); // text second + if (j != att) // attribute changed? + { + att = j; // save current attribute + SetConsoleTextAttribute(co, j); //set fg and bg color for buffer + } + + WriteConsoleA(co, &let, 1, &bytesWritten, NULL); // now the text + + if (nlflag && !(i % 80) && backupcon.dwSize.X > resizewin.X) // do we need a nl? + { + att = backupcon.wAttributes; + SetConsoleTextAttribute(co, att); // all attributes off + WriteConsoleA(co, "\n", 1, &bytesWritten, NULL); // newline to console + } + ptext++; + } + SetConsoleTextAttribute(co, backupcon.wAttributes); // all attributes off +#else + /* print 80x25 text and deal with the attributes too */ + for (i=1; i<=80*25; i++) { + /* attribute first */ + /* attribute changed? */ + if ((j = *ptext >> 8) != att) { + /* save current attribute */ + att = j; + /* set new attribute, forground color first */ + printf("\033["); + switch (j & 0x0f) { + case 0: /* black */ + printf("30"); + break; + case 1: /* blue */ + printf("34"); + break; + case 2: /* green */ + printf("32"); + break; + case 3: /* cyan */ + printf("36"); + break; + case 4: /* red */ + printf("31"); + break; + case 5: /* magenta */ + printf("35"); + break; + case 6: /* brown */ + printf("33"); + break; + case 7: /* bright grey */ + printf("37"); + break; + case 8: /* dark grey */ + printf("1;30"); + break; + case 9: /* bright blue */ + printf("1;34"); + break; + case 10: /* bright green */ + printf("1;32"); + break; + case 11: /* bright cyan */ + printf("1;36"); + break; + case 12: /* bright red */ + printf("1;31"); + break; + case 13: /* bright magenta */ + printf("1;35"); + break; + case 14: /* yellow */ + printf("1;33"); + break; + case 15: /* white */ + printf("1;37"); + break; + } + printf("m"); + /* now background color */ + printf("\033["); + switch ((j >> 4) & 0x0f) { + case 0: /* black */ + printf("40"); + break; + case 1: /* blue */ + printf("44"); + break; + case 2: /* green */ + printf("42"); + break; + case 3: /* cyan */ + printf("46"); + break; + case 4: /* red */ + printf("41"); + break; + case 5: /* magenta */ + printf("45"); + break; + case 6: /* brown */ + printf("43"); + break; + case 7: /* bright grey */ + printf("47"); + break; + case 8: /* dark grey */ + printf("1;40"); + break; + case 9: /* bright blue */ + printf("1;44"); + break; + case 10: /* bright green */ + printf("1;42"); + break; + case 11: /* bright cyan */ + printf("1;46"); + break; + case 12: /* bright red */ + printf("1;41"); + break; + case 13: /* bright magenta */ + printf("1;45"); + break; + case 14: /* yellow */ + printf("1;43"); + break; + case 15: /* white */ + printf("1;47"); + break; + } + printf("m"); + } + + /* now the text */ + printf("%c",*ptext++ & 0xff); + + /* do we need a nl? */ + if (nlflag) + { + if (!(i % 80)) + { + printf("\033[0m"); + att = 0; + printf("\n"); + } + } + } + /* all attributes off */ + printf("\033[0m"); +#endif + if (nlflag) + printf("\n"); + + Z_Free(data); +#endif +} diff --git a/src/sdl12/endtxt.h b/src/sdl12/endtxt.h new file mode 100644 index 000000000..41f8e51ad --- /dev/null +++ b/src/sdl12/endtxt.h @@ -0,0 +1,24 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1998-2000 by DooM Legacy Team. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief Support to show ENDOOM text + +#ifndef __ENDTXT__ +#define __ENDTXT__ + +void ShowEndTxt (void); + +#endif diff --git a/src/sdl12/filter/filters.c b/src/sdl12/filter/filters.c new file mode 100644 index 000000000..1b2346e8e --- /dev/null +++ b/src/sdl12/filter/filters.c @@ -0,0 +1,1000 @@ +#include +#include "filters.h" + +//Alam_GBC: C file based on sms_sdl's filter.c + +/* 2X SAI Filter */ +static Uint32 colorMask = 0xF7DEF7DE; +static Uint32 lowPixelMask = 0x08210821; +static Uint32 qcolorMask = 0xE79CE79C; +static Uint32 qlowpixelMask = 0x18631863; +static Uint32 redblueMask = 0xF81F; +static Uint32 greenMask = 0x7E0; + +SDL_Surface *filter_2x(SDL_Surface *src, SDL_Rect *srcclp, filter_2 filter) +{ + return filter_2xe(src,srcclp,filter,0,0,0); +} + +SDL_Surface *filter_2xe(SDL_Surface *src, SDL_Rect *srcclp, filter_2 filter,Uint8 R, Uint8 G, Uint8 B) +{ + SDL_Surface *srcfilter = NULL; + SDL_Rect dstclp = {0,3,0,0}; + SDL_Surface *dstfilter = NULL; + Uint32 Fillcolor = 0; + if(!src || !filter) return NULL; // Need src and filter + if(srcclp) // size by clp + { + dstclp.w = srcclp->w; //clp's width + dstclp.h = srcclp->h; //clp's height + } + else // size by src + { + dstclp.w = (Uint16)src->w; //src's width + dstclp.h = (Uint16)src->h; //src's height + } + if(filter == hq2x32 || filter == lq2x32) // src 0888 surface + srcfilter = SDL_CreateRGBSurface(SDL_SWSURFACE,dstclp.w,dstclp.h+6,32,0x00FF0000,0x0000FF00,0x000000FF,0x00); + else // src 565 surface + srcfilter = SDL_CreateRGBSurface(SDL_SWSURFACE,dstclp.w,dstclp.h+6,16,0x0000F800,0x000007E0,0x0000001F,0x00); + if(!srcfilter) return NULL; //No Memory? + Fillcolor = SDL_MapRGB(srcfilter->format,R,G,B); //Choose color + SDL_FillRect(srcfilter,NULL,Fillcolor); //fill it + if(filter == filter_hq2x || filter == hq2x32 || filter == lq2x32) // dst 0888 surface + dstfilter = SDL_CreateRGBSurface(SDL_SWSURFACE,dstclp.w*2,dstclp.h*2,32,0x00FF0000,0x0000FF00,0x000000FF,0x00); + else // dst 565 surface + dstfilter = SDL_CreateRGBSurface(SDL_SWSURFACE,dstclp.w*2,dstclp.h*2,16,0x0000F800,0x000007E0,0x0000001F,0x00); + if(!dstfilter || SDL_BlitSurface(src,srcclp,srcfilter,&dstclp) == -1) // No dstfilter or Blit failed + { + SDL_FreeSurface(srcfilter); // Free memory + return NULL; //No Memory? + } + else // have dstfilter ready and srcfilter done + { + SDL_FillRect(dstfilter,NULL,Fillcolor); //fill it too + filter(FILTER(srcfilter,dstfilter)); //filtering + SDL_FreeSurface(srcfilter); //almost + } + return dstfilter; //done +} + + +int filter_init_2xsai(SDL_PixelFormat *BitFormat) +{ + if (!BitFormat || BitFormat->BytesPerPixel != 2 ||BitFormat->Amask != 0x0) + { + return 0; + } + else if (BitFormat->Rmask == 0xF800 && BitFormat->Gmask == 0x7E0 + && BitFormat->Bmask == 0x1F && BitFormat->BitsPerPixel == 16) //565 + { + colorMask = 0xF7DEF7DE; + lowPixelMask = 0x08210821; + qcolorMask = 0xE79CE79C; + qlowpixelMask = 0x18631863; + redblueMask = 0xF81F; + greenMask = 0x7E0; + } + else if (BitFormat->Rmask == 0x7C00 && BitFormat->Gmask == 0x3E0 + && BitFormat->Bmask == 0x1F && BitFormat->BitsPerPixel == 15) //555 + { + colorMask = 0x7BDE7BDE; + lowPixelMask = 0x04210421; + qcolorMask = 0x739C739C; + qlowpixelMask = 0x0C630C63; + redblueMask = 0x7C1F; + greenMask = 0x3E0; + } + else + { + return 0; + } +#ifdef MMX + if(BitFormat->Gmask == 0x7E0) Init_2xSaIMMX(565); + else Init_2xSaIMMX(555); +#endif + return 1; +} + + +FUNCINLINE static ATTRINLINE int GetResult1 (Uint32 A, Uint32 B, Uint32 C, Uint32 D, Uint32 E) +{ + int x = 0; + int y = 0; + int r = 0; + (void)E; + + if (A == C) + x += 1; + else if (B == C) + y += 1; + if (A == D) + x += 1; + else if (B == D) + y += 1; + if (x <= 1) + r += 1; + if (y <= 1) + r -= 1; + return r; +} + +FUNCINLINE static ATTRINLINE int GetResult2 (Uint32 A, Uint32 B, Uint32 C, Uint32 D, Uint32 E) +{ + int x = 0; + int y = 0; + int r = 0; + (void)E; + + if (A == C) + x += 1; + else if (B == C) + y += 1; + if (A == D) + x += 1; + else if (B == D) + y += 1; + if (x <= 1) + r -= 1; + if (y <= 1) + r += 1; + return r; +} + +FUNCINLINE static ATTRINLINE int GetResult (Uint32 A, Uint32 B, Uint32 C, Uint32 D) +{ + int x = 0; + int y = 0; + int r = 0; + + if (A == C) + x += 1; + else if (B == C) + y += 1; + if (A == D) + x += 1; + else if (B == D) + y += 1; + if (x <= 1) + r += 1; + if (y <= 1) + r -= 1; + return r; +} + +FUNCINLINE static ATTRINLINE Uint32 INTERPOLATE (Uint32 A, Uint32 B) +{ + if (A != B) + { + return (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + + (A & B & lowPixelMask)); + } + else + return A; +} + +FUNCINLINE static ATTRINLINE Uint32 Q_INTERPOLATE (Uint32 A, Uint32 B, Uint32 C, Uint32 D) +{ + register Uint32 x = ((A & qcolorMask) >> 2) + + ((B & qcolorMask) >> 2) + + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2); + register Uint32 y = (A & qlowpixelMask) + + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask); + y = (y >> 2) & qlowpixelMask; + return x + y; +} + +#define BLUE_MASK565 0x001F001F +#define RED_MASK565 0xF800F800 +#define GREEN_MASK565 0x07E007E0 + +#define BLUE_MASK555 0x001F001F +#define RED_MASK555 0x7C007C00 +#define GREEN_MASK555 0x03E003E0 + +void filter_super2xsai(Uint8 *srcPtr, Uint32 srcPitch, + Uint8 *dstPtr, Uint32 dstPitch, + int width, int height) +{ + Uint16 *bP; + Uint8 *dP; + Uint32 inc_bP; + Uint32 Nextline = srcPitch >> 1; + + Uint32 finish; + inc_bP = 1; + + for (; height; height--) + { + bP = (Uint16 *) srcPtr; + dP = (Uint8 *) dstPtr; + + for (finish = width; finish; finish -= inc_bP) + { + Uint32 color4, color5, color6; + Uint32 color1, color2, color3; + Uint32 colorA0, colorA1, colorA2, colorA3, + colorB0, colorB1, colorB2, colorB3, colorS1, colorS2; + Uint32 product1a, product1b, product2a, product2b; + +//--------------------------------------- B1 B2 +// 4 5 6 S2 +// 1 2 3 S1 +// A1 A2 + + colorB0 = *(bP - Nextline - 1); + colorB1 = *(bP - Nextline); + colorB2 = *(bP - Nextline + 1); + colorB3 = *(bP - Nextline + 2); + + color4 = *(bP - 1); + color5 = *(bP); + color6 = *(bP + 1); + colorS2 = *(bP + 2); + + color1 = *(bP + Nextline - 1); + color2 = *(bP + Nextline); + color3 = *(bP + Nextline + 1); + colorS1 = *(bP + Nextline + 2); + + colorA0 = *(bP + Nextline + Nextline - 1); + colorA1 = *(bP + Nextline + Nextline); + colorA2 = *(bP + Nextline + Nextline + 1); + colorA3 = *(bP + Nextline + Nextline + 2); + +//-------------------------------------- + if (color2 == color6 && color5 != color3) + { + product2b = product1b = color2; + } + else if (color5 == color3 && color2 != color6) + { + product2b = product1b = color5; + } + else if (color5 == color3 && color2 == color6) + { + register int r = 0; + + r += GetResult (color6, color5, color1, colorA1); + r += GetResult (color6, color5, color4, colorB1); + r += GetResult (color6, color5, colorA2, colorS1); + r += GetResult (color6, color5, colorB2, colorS2); + + if (r > 0) + product2b = product1b = color6; + else if (r < 0) + product2b = product1b = color5; + else + { + product2b = product1b = INTERPOLATE (color5, color6); + } + } + else + { + if (color6 == color3 && color3 == colorA1 + && color2 != colorA2 && color3 != colorA0) + product2b = + Q_INTERPOLATE (color3, color3, color3, color2); + else if (color5 == color2 && color2 == colorA2 + && colorA1 != color3 && color2 != colorA3) + product2b = + Q_INTERPOLATE (color2, color2, color2, color3); + else + product2b = INTERPOLATE (color2, color3); + + if (color6 == color3 && color6 == colorB1 + && color5 != colorB2 && color6 != colorB0) + product1b = + Q_INTERPOLATE (color6, color6, color6, color5); + else if (color5 == color2 && color5 == colorB2 + && colorB1 != color6 && color5 != colorB3) + product1b = + Q_INTERPOLATE (color6, color5, color5, color5); + else + product1b = INTERPOLATE (color5, color6); + } + + if (color5 == color3 && color2 != color6 && color4 == color5 + && color5 != colorA2) + product2a = INTERPOLATE (color2, color5); + else + if (color5 == color1 && color6 == color5 + && color4 != color2 && color5 != colorA0) + product2a = INTERPOLATE (color2, color5); + else + product2a = color2; + + if (color2 == color6 && color5 != color3 && color1 == color2 + && color2 != colorB2) + product1a = INTERPOLATE (color2, color5); + else + if (color4 == color2 && color3 == color2 + && color1 != color5 && color2 != colorB0) + product1a = INTERPOLATE (color2, color5); + else + product1a = color5; + +#ifdef LSB_FIRST + product1a = product1a | (product1b << 16); + product2a = product2a | (product2b << 16); +#else + product1a = (product1a << 16) | product1b; + product2a = (product2a << 16) | product2b; +#endif + *((Uint32 *) dP) = product1a; + *((Uint32 *) (dP + dstPitch)) = product2a; + + bP += inc_bP; + dP += sizeof (Uint32); + } // end of for ( finish= width etc..) + + srcPtr += srcPitch; + dstPtr += dstPitch * 2; + } // endof: for (; height; height--) +} + +void filter_supereagle(Uint8 *srcPtr, Uint32 srcPitch, /* Uint8 *deltaPtr, */ + Uint8 *dstPtr, Uint32 dstPitch, int width, int height) +{ + Uint8 *dP; + Uint16 *bP; + Uint32 inc_bP; + + + + Uint32 finish; + Uint32 Nextline = srcPitch >> 1; + + inc_bP = 1; + + for (; height ; height--) + { + bP = (Uint16 *) srcPtr; + dP = dstPtr; + for (finish = width; finish; finish -= inc_bP) + { + Uint32 color4, color5, color6; + Uint32 color1, color2, color3; + Uint32 colorA1, colorA2, colorB1, colorB2, colorS1, colorS2; + Uint32 product1a, product1b, product2a, product2b; + colorB1 = *(bP - Nextline); + colorB2 = *(bP - Nextline + 1); + + color4 = *(bP - 1); + color5 = *(bP); + color6 = *(bP + 1); + colorS2 = *(bP + 2); + + color1 = *(bP + Nextline - 1); + color2 = *(bP + Nextline); + color3 = *(bP + Nextline + 1); + colorS1 = *(bP + Nextline + 2); + + colorA1 = *(bP + Nextline + Nextline); + colorA2 = *(bP + Nextline + Nextline + 1); + // -------------------------------------- + if (color2 == color6 && color5 != color3) + { + product1b = product2a = color2; + if ((color1 == color2) || (color6 == colorB2)) + { + product1a = INTERPOLATE (color2, color5); + product1a = INTERPOLATE (color2, product1a); +// product1a = color2; + } + else + { + product1a = INTERPOLATE (color5, color6); + } + + if ((color6 == colorS2) || (color2 == colorA1)) + { + product2b = INTERPOLATE (color2, color3); + product2b = INTERPOLATE (color2, product2b); +// product2b = color2; + } + else + { + product2b = INTERPOLATE (color2, color3); + } + } + else if (color5 == color3 && color2 != color6) + { + product2b = product1a = color5; + + if ((colorB1 == color5) || (color3 == colorS1)) + { + product1b = INTERPOLATE (color5, color6); + product1b = INTERPOLATE (color5, product1b); +// product1b = color5; + } + else + { + product1b = INTERPOLATE (color5, color6); + } + + if ((color3 == colorA2) || (color4 == color5)) + { + product2a = INTERPOLATE (color5, color2); + product2a = INTERPOLATE (color5, product2a); +// product2a = color5; + } + else + { + product2a = INTERPOLATE (color2, color3); + } + + } + else if (color5 == color3 && color2 == color6) + { + register int r = 0; + + r += GetResult (color6, color5, color1, colorA1); + r += GetResult (color6, color5, color4, colorB1); + r += GetResult (color6, color5, colorA2, colorS1); + r += GetResult (color6, color5, colorB2, colorS2); + + if (r > 0) + { + product1b = product2a = color2; + product1a = product2b = INTERPOLATE (color5, color6); + } + else if (r < 0) + { + product2b = product1a = color5; + product1b = product2a = INTERPOLATE (color5, color6); + } + else + { + product2b = product1a = color5; + product1b = product2a = color2; + } + } + else + { + product2b = product1a = INTERPOLATE (color2, color6); + product2b = + Q_INTERPOLATE (color3, color3, color3, product2b); + product1a = + Q_INTERPOLATE (color5, color5, color5, product1a); + + product2a = product1b = INTERPOLATE (color5, color3); + product2a = + Q_INTERPOLATE (color2, color2, color2, product2a); + product1b = + Q_INTERPOLATE (color6, color6, color6, product1b); + +// product1a = color5; +// product1b = color6; +// product2a = color2; +// product2b = color3; + } +#ifdef LSB_FIRST + product1a = product1a | (product1b << 16); + product2a = product2a | (product2b << 16); +#else + product1a = (product1a << 16) | product1b; + product2a = (product2a << 16) | product2b; +#endif + + *((Uint32 *) dP) = product1a; + *((Uint32 *) (dP + dstPitch)) = product2a; + + bP += inc_bP; + dP += sizeof (Uint32); + } // end of for ( finish= width etc..) + srcPtr += srcPitch; + dstPtr += dstPitch * 2; + } // endof: for (height; height; height--) +} + +void filter_2xsai (Uint8 *srcPtr, Uint32 srcPitch, + Uint8 *dstPtr, Uint32 dstPitch, int width, int height) +{ + Uint8 *dP; + Uint16 *bP; + Uint32 inc_bP; + + + Uint32 finish; + Uint32 Nextline = srcPitch >> 1; + inc_bP = 1; + + + for (; height; height--) + { + bP = (Uint16 *) srcPtr; + dP = dstPtr; + + for (finish = width; finish; finish -= inc_bP) + { + + register Uint32 colorA, colorB; + Uint32 colorC, colorD, + colorE, colorF, colorG, colorH, + colorI, colorJ, colorK, colorL, + + colorM, colorN, colorO, colorP; + Uint32 product, product1, product2; + +//--------------------------------------- +// Map of the pixels: I|E F|J +// G|A B|K +// H|C D|L +// M|N O|P + colorI = *(bP - Nextline - 1); + colorE = *(bP - Nextline); + colorF = *(bP - Nextline + 1); + colorJ = *(bP - Nextline + 2); + + colorG = *(bP - 1); + colorA = *(bP); + colorB = *(bP + 1); + colorK = *(bP + 2); + + colorH = *(bP + Nextline - 1); + colorC = *(bP + Nextline); + colorD = *(bP + Nextline + 1); + colorL = *(bP + Nextline + 2); + + colorM = *(bP + Nextline + Nextline - 1); + colorN = *(bP + Nextline + Nextline); + colorO = *(bP + Nextline + Nextline + 1); + colorP = *(bP + Nextline + Nextline + 2); + + if ((colorA == colorD) && (colorB != colorC)) + { + if (((colorA == colorE) && (colorB == colorL)) || + ((colorA == colorC) && (colorA == colorF) + && (colorB != colorE) && (colorB == colorJ))) + { + product = colorA; + } + else + { + product = INTERPOLATE (colorA, colorB); + } + + if (((colorA == colorG) && (colorC == colorO)) || + ((colorA == colorB) && (colorA == colorH) + && (colorG != colorC) && (colorC == colorM))) + { + product1 = colorA; + } + else + { + product1 = INTERPOLATE (colorA, colorC); + } + product2 = colorA; + } + else if ((colorB == colorC) && (colorA != colorD)) + { + if (((colorB == colorF) && (colorA == colorH)) || + ((colorB == colorE) && (colorB == colorD) + && (colorA != colorF) && (colorA == colorI))) + { + product = colorB; + } + else + { + product = INTERPOLATE (colorA, colorB); + } + + if (((colorC == colorH) && (colorA == colorF)) || + ((colorC == colorG) && (colorC == colorD) + && (colorA != colorH) && (colorA == colorI))) + { + product1 = colorC; + } + else + { + product1 = INTERPOLATE (colorA, colorC); + } + product2 = colorB; + } + else if ((colorA == colorD) && (colorB == colorC)) + { + if (colorA == colorB) + { + product = colorA; + product1 = colorA; + product2 = colorA; + } + else + { + register int r = 0; + + product1 = INTERPOLATE (colorA, colorC); + product = INTERPOLATE (colorA, colorB); + + r += + GetResult1 (colorA, colorB, colorG, colorE, + colorI); + r += + GetResult2 (colorB, colorA, colorK, colorF, + colorJ); + r += + GetResult2 (colorB, colorA, colorH, colorN, + colorM); + r += + GetResult1 (colorA, colorB, colorL, colorO, + colorP); + + if (r > 0) + product2 = colorA; + else if (r < 0) + product2 = colorB; + else + { + product2 = + Q_INTERPOLATE (colorA, colorB, colorC, + colorD); + } + } + } + else + { + product2 = Q_INTERPOLATE (colorA, colorB, colorC, colorD); + + if ((colorA == colorC) && (colorA == colorF) + && (colorB != colorE) && (colorB == colorJ)) + { + product = colorA; + } + else + if ((colorB == colorE) && (colorB == colorD) + && (colorA != colorF) && (colorA == colorI)) + { + product = colorB; + } + else + { + product = INTERPOLATE (colorA, colorB); + } + + if ((colorA == colorB) && (colorA == colorH) + && (colorG != colorC) && (colorC == colorM)) + { + product1 = colorA; + } + else + if ((colorC == colorG) && (colorC == colorD) + && (colorA != colorH) && (colorA == colorI)) + { + product1 = colorC; + } + else + { + product1 = INTERPOLATE (colorA, colorC); + } + } +#ifdef LSB_FIRST + product = colorA | (product << 16); + product1 = product1 | (product2 << 16); +#else + product = (colorA << 16) | product; + product1 = (product1 << 16) | product2; +#endif + *((Uint32 *) dP) = product; + *((Uint32 *) (dP + dstPitch)) = product1; + + bP += inc_bP; + dP += sizeof (Uint32); + } // end of for ( finish= width etc..) + + srcPtr += srcPitch; + dstPtr += dstPitch * 2; + } // endof: for (height; height; height--) +} + +#if 0 +static inline Uint32 Bilinear(Uint32 A, Uint32 B, Uint32 x) +{ + unsigned long areaA, areaB; + unsigned long result; + + if (A == B) + return A; + + areaB = (x >> 11) & 0x1f; // reduce 16 bit fraction to 5 bits + areaA = 0x20 - areaB; + + A = (A & redblueMask) | ((A & greenMask) << 16); + B = (B & redblueMask) | ((B & greenMask) << 16); + + result = ((areaA * A) + (areaB * B)) >> 5; + + return (result & redblueMask) | ((result >> 16) & greenMask); + +} + +static inline Uint32 Bilinear4 (Uint32 A, Uint32 B, Uint32 C, Uint32 D, Uint32 x, + Uint32 y) +{ + unsigned long areaA, areaB, areaC, areaD; + unsigned long result, xy; + + x = (x >> 11) & 0x1f; + y = (y >> 11) & 0x1f; + xy = (x * y) >> 5; + + A = (A & redblueMask) | ((A & greenMask) << 16); + B = (B & redblueMask) | ((B & greenMask) << 16); + C = (C & redblueMask) | ((C & greenMask) << 16); + D = (D & redblueMask) | ((D & greenMask) << 16); + + areaA = 0x20 + xy - x - y; + areaB = x - xy; + areaC = y - xy; + areaD = xy; + + result = ((areaA * A) + (areaB * B) + (areaC * C) + (areaD * D)) >> 5; + + return (result & redblueMask) | ((result >> 16) & greenMask); +} +#endif + + +void filter_advmame2x(Uint8 *srcPtr, Uint32 srcPitch, + Uint8 *dstPtr, Uint32 dstPitch, + int width, int height) +{ + unsigned int nextlineSrc = srcPitch / sizeof(short); + short *p = (short *)srcPtr; + + unsigned int nextlineDst = dstPitch / sizeof(short); + short *q = (short *)dstPtr; + + while(height--) { + int i = 0, j = 0; + for(i = 0; i < width; ++i, j += 2) { + short B = *(p + i - nextlineSrc); + short D = *(p + i - 1); + short E = *(p + i); + short F = *(p + i + 1); + short H = *(p + i + nextlineSrc); + + *(q + j) = (short)(D == B && B != F && D != H ? D : E); + *(q + j + 1) = (short)(B == F && B != D && F != H ? F : E); + *(q + j + nextlineDst) = (short)(D == H && D != B && H != F ? D : E); + *(q + j + nextlineDst + 1) = (short)(H == F && D != H && B != F ? F : E); + } + p += nextlineSrc; + q += nextlineDst << 1; + } +} + + +void filter_tv2x(Uint8 *srcPtr, Uint32 srcPitch, + Uint8 *dstPtr, Uint32 dstPitch, + int width, int height) +{ + unsigned int nextlineSrc = srcPitch / sizeof(Uint16); + Uint16 *p = (Uint16 *)srcPtr; + + unsigned int nextlineDst = dstPitch / sizeof(Uint16); + Uint16 *q = (Uint16 *)dstPtr; + + while(height--) { + int i = 0, j = 0; + for(; i < width; ++i, j += 2) { + Uint16 p1 = *(p + i); + Uint32 pi; + + pi = (((p1 & redblueMask) * 7) >> 3) & redblueMask; + pi |= (((p1 & greenMask) * 7) >> 3) & greenMask; + + *(q + j) = (Uint16)p1; + *(q + j + 1) = (Uint16)p1; + *(q + j + nextlineDst) = (Uint16)pi; + *(q + j + nextlineDst + 1) = (Uint16)pi; + } + p += nextlineSrc; + q += nextlineDst << 1; + } +} + +void filter_normal2x(Uint8 *srcPtr, Uint32 srcPitch, + Uint8 *dstPtr, Uint32 dstPitch, + int width, int height) +{ + unsigned int nextlineSrc = srcPitch / sizeof(Uint16); + Uint16 *p = (Uint16 *)srcPtr; + + unsigned int nextlineDst = dstPitch / sizeof(Uint16); + Uint16 *q = (Uint16 *)dstPtr; + + while(height--) { + int i = 0, j = 0; + for(; i < width; ++i, j += 2) { + Uint16 color = *(p + i); + + *(q + j) = color; + *(q + j + 1) = color; + *(q + j + nextlineDst) = color; + *(q + j + nextlineDst + 1) = color; + } + p += nextlineSrc; + q += nextlineDst << 1; + } +} + +void filter_scan50(Uint8 *srcPtr, Uint32 srcPitch, + Uint8 *dstPtr, Uint32 dstPitch, + int width, int height) +{ + + unsigned int nextlineSrc = srcPitch / sizeof(Uint16); + Uint16 *p = (Uint16 *)srcPtr; + + unsigned int nextlineDst = dstPitch / sizeof(Uint16); + Uint16 *q = (Uint16 *)dstPtr; + + while(height--) { + int i = 0, j = 0; + for(; i < width; ++i, j += 2) { + Uint16 p1 = *(p + i); + Uint16 p2 = *(p + i + nextlineSrc); + // 0111 1011 1110 1111 == 0x7BEF + Uint16 pm = (Uint16)(((p1 + p2) >> 2) & 0x7BEF); + + *(q + j) = p1; + *(q + j + 1) = p1; + *(q + j + nextlineDst) = pm; + *(q + j + nextlineDst + 1) = pm; + + } + p += nextlineSrc; + q += nextlineDst << 1; + } +} + + +void filter_scan100(Uint8 *srcPtr, Uint32 srcPitch, + Uint8 *dstPtr, Uint32 dstPitch, + int width, int height) +{ + unsigned int nextlineSrc = srcPitch / sizeof(Uint16); + Uint16 *p = (Uint16 *)srcPtr; + + unsigned int nextlineDst = dstPitch / sizeof(Uint16); + Uint16 *q = (Uint16 *)dstPtr; + + while(height--) { + int i = 0, j = 0; + for(; i < width; ++i, j += 2) { + *(q + j) = *(q + j + 1) = *(p + i); + } + p += nextlineSrc; + q += nextlineDst << 1; + } +} + + +FUNCINLINE static ATTRINLINE Uint16 DOT_16(Uint16 c, int j, int i) { + static const Uint16 dotmatrix[16] = { + 0x01E0, 0x0007, 0x3800, 0x0000, + 0x39E7, 0x0000, 0x39E7, 0x0000, + 0x3800, 0x0000, 0x01E0, 0x0007, + 0x39E7, 0x0000, 0x39E7, 0x0000 + }; + return (Uint16)(c - ((c >> 2) & *(dotmatrix + ((j & 3) << 2) + (i & 3)))); +} + +void filter_dotmatrix(Uint8 *srcPtr, Uint32 srcPitch, + Uint8 *dstPtr, Uint32 dstPitch, + int width, int height) +{ + unsigned int nextlineSrc = srcPitch / sizeof(Uint16); + Uint16 *p = (Uint16 *)srcPtr; + + unsigned int nextlineDst = dstPitch / sizeof(Uint16); + Uint16 *q = (Uint16 *)dstPtr; + + int i, ii, j, jj; + for(j = 0, jj = 0; j < height; ++j, jj += 2) { + for(i = 0, ii = 0; i < width; ++i, ii += 2) { + Uint16 c = *(p + i); + *(q + ii) = DOT_16(c, jj, ii); + *(q + ii + 1) = DOT_16(c, jj, ii + 1); + *(q + ii + nextlineDst) = DOT_16(c, jj + 1, ii); + *(q + ii + nextlineDst + 1) = DOT_16(c, jj + 1, ii + 1); + } + p += nextlineSrc; + q += nextlineDst << 1; + } +} + + +void filter_bilinear(Uint8 *srcPtr, Uint32 srcPitch, + Uint8 *dstPtr, Uint32 dstPitch, + int width, int height) +{ + unsigned int nextlineSrc = srcPitch / sizeof(Uint16); + Uint16 *p = (Uint16 *)srcPtr; + unsigned int nextlineDst = dstPitch / sizeof(Uint16); + Uint16 *q = (Uint16 *)dstPtr; + + while(height--) { + int i, ii; + for(i = 0, ii = 0; i < width; ++i, ii += 2) { + Uint16 A = *(p + i); + Uint16 B = *(p + i + 1); + Uint16 C = *(p + i + nextlineSrc); + Uint16 D = *(p + i + nextlineSrc + 1); + *(q + ii) = A; + *(q + ii + 1) = (Uint16)INTERPOLATE(A, B); + *(q + ii + nextlineDst) = (Uint16)INTERPOLATE(A, C); + *(q + ii + nextlineDst + 1) = (Uint16)Q_INTERPOLATE(A, B, C, D); + } + p += nextlineSrc; + q += nextlineDst << 1; + } +} + + +// NEED_OPTIMIZE +static void MULT(Uint16 c, float* r, float* g, float* b, float alpha) { + *r += alpha * ((c & RED_MASK565 ) >> 11); + *g += alpha * ((c & GREEN_MASK565) >> 5); + *b += alpha * ((c & BLUE_MASK565 ) >> 0); +} + +static Uint16 MAKE_RGB565(float r, float g, float b) { + return (Uint16) + (((((Uint8)r) << 11) & RED_MASK565 ) | + ((((Uint8)g) << 5) & GREEN_MASK565) | + ((((Uint8)b) << 0) & BLUE_MASK565 )); +} + +FUNCINLINE static ATTRINLINE float CUBIC_WEIGHT(float x) { + // P(x) = { x, x>0 | 0, x<=0 } + // P(x + 2) ^ 3 - 4 * P(x + 1) ^ 3 + 6 * P(x) ^ 3 - 4 * P(x - 1) ^ 3 + double r = 0.; + if(x + 2 > 0) r += pow(x + 2, 3); + if(x + 1 > 0) r += -4 * pow(x + 1, 3); + if(x > 0) r += 6 * pow(x , 3); + if(x - 1 > 0) r += -4 * pow(x - 1, 3); + return (float)r / 6; +} + +void filter_bicubic(Uint8 *srcPtr, Uint32 srcPitch, + Uint8 *dstPtr, Uint32 dstPitch, + int width, int height) +{ + unsigned int nextlineSrc = srcPitch / sizeof(Uint16); + Uint16 *p = (Uint16 *)srcPtr; + unsigned int nextlineDst = dstPitch / sizeof(Uint16); + Uint16 *q = (Uint16 *)dstPtr; + int dx = width << 1, dy = height << 1; + float fsx = (float)width / dx; + float fsy = (float)height / dy; + float v = 0.0f; + int j = 0; + for(; j < dy; ++j) { + float u = 0.0f; + int iv = (int)v; + float decy = v - iv; + int i = 0; + for(; i < dx; ++i) { + int iu = (int)u; + float decx = u - iu; + float r, g, b; + int m; + r = g = b = 0.; + for(m = -1; m <= 2; ++m) { + float r1 = CUBIC_WEIGHT(decy - m); + int n; + for(n = -1; n <= 2; ++n) { + float r2 = CUBIC_WEIGHT(n - decx); + Uint16* pIn = p + (iu + n) + (iv + m) * nextlineSrc; + MULT(*pIn, &r, &g, &b, r1 * r2); + } + } + *(q + i) = MAKE_RGB565(r, g, b); + u += fsx; + } + q += nextlineDst; + v += fsy; + } +} diff --git a/src/sdl12/filter/filters.h b/src/sdl12/filter/filters.h new file mode 100644 index 000000000..c4a84b4c9 --- /dev/null +++ b/src/sdl12/filter/filters.h @@ -0,0 +1,212 @@ +#ifndef __FILTERS_H__ +#define __FILTERS_H__ + +#ifdef _MSC_VER +#pragma warning(disable : 4514 4214 4244) +#endif + +#include "SDL.h" + +#ifdef _MSC_VER +#pragma warning(default : 4214 4244) +#endif + +typedef enum { + FILTER_2XSAI = 0, + FILTER_SUPER2XSAI, + FILTER_SUPEREAGLE, + FILTER_ADVMAME2X , + FILTER_TV2X , + FILTER_NORMAL2X , + FILTER_BILINEAR , + FILTER_DOTMATRIX , + FILTER_NUM , +} t_filter; + +typedef void (*filter_2)(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); +SDL_Surface *filter_2x(SDL_Surface *src, SDL_Rect *srcclp, filter_2 filter); +SDL_Surface *filter_2xe(SDL_Surface *src, SDL_Rect *srcclp, filter_2 filter,Uint8 R, Uint8 G, Uint8 B); +//Alam_GBC: Header file based on sms_sdl's filter.h +//Note: need 3 lines at the bottom and top? + +//int filter_init_2xsai(SDL_PixelFormat *BitFormat); +#define FILTER(src,dst) (Uint8 *)(src->pixels)+src->pitch*3, (Uint32)src->pitch, (Uint8 *)dst->pixels, (Uint32)dst->pitch, src->w, src->h-6 +#define SDLFILTER(src,dst) (Uint8 *)src->pixels, (Uint32)src->pitch, (Uint8 *)dst->pixels, (Uint32)dst->pitch, src->w, src->h +int filter_init_2xsai(SDL_PixelFormat *BitFormat); //unless? +void filter_scan50(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); +void filter_scan100(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); + +void filter_2xsai(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); +void filter_super2xsai(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); +void filter_supereagle(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); +void filter_advmame2x(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); +void filter_tv2x(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); +void filter_normal2x(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); +void filter_bilinear(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); +void filter_dotmatrix(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); +void filter_bicubic(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); +void lq2x16(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); +void hq2x16(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); + +void filter_hq2x(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); +void lq2x32(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); +void hq2x32(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height); + +#ifdef FILTERS +typedef struct filter_s { filter_2 filter; int bpp; } filter_t; +#define NUMFILTERS 13 +static filter_t filtermode[NUMFILTERS+1] = { + {NULL , 0}, //None + {filter_normal2x , 16}, //2xNormal + {filter_advmame2x , 16}, //AdvMAME2x + {filter_tv2x , 16}, //TV2x + {filter_bilinear , 16}, //Bilinear + {filter_dotmatrix , 16}, //DotMatrix + {lq2x16 , 16}, //16LQ2x + {hq2x16 , 16}, //16HQ2x + {lq2x32 , 32}, //32LQ2x + {hq2x32 , 32}, //32HQ2x +// {filter_bicubic , 16}, //Slow Bicubic + // BAD + {filter_2xsai , 16}, //2xSAI + {filter_super2xsai, 16}, //Super2xSAI + {filter_supereagle, 16}, //SuperEagle +}; +CV_PossibleValue_t CV_Filters[] = {{ 0, "None"}, { 1, "2xNormal"}, + { 2, "AdvMAME2x"}, { 3, "TV2x"}, { 4, "Bilinear"} , { 5, "DotMatrix"}, + { 6, "16LQ2x"}, { 7, "16HQ2x"}, { 8, "32LQ2x"} , { 9, "32HQ2x"}, + {10, "2xSAI"}, {11, "Super2xSAI"}, {12, "SuperEagle"}, {0, NULL},}; +static void Filterchange(void); +consvar_t cv_filter = {"filter", "None", CV_CALL|CV_NOINIT, CV_Filters,Filterchange,0,NULL,NULL,0,0,NULL}; +static filter_2 blitfilter = NULL; +static SDL_Surface *preSurface = NULL; +static SDL_Surface *f2xSurface = NULL; + +static void Filterchange(void) +{ + if(blitfilter) // only filtering? + { + int i=0; + for(;i < NUMFILTERS; i++)//find old filter + { + if(filtermode[i].filter == blitfilter) //Found it + break; //Stop + } + if(i < NUMFILTERS && filtermode[i].bpp == filtermode[cv_filter.value].bpp) //Easy to swap? + blitfilter = filtermode[cv_filter.value].filter; // Swap with new filter + } +} + +FUNCINLINE static ATTRINLINE void FilterBlit(SDL_Surface *froSurface) +{ + if(froSurface && blitfilter && preSurface && f2xSurface) + { + SDL_Rect dstclp = {0,3,0,0}; + int lockedpre = 0, lockedf2x = 0, blitpre = 0; + blitpre = SDL_BlitSurface(froSurface,NULL,preSurface,&dstclp); + if(SDL_MUSTLOCK(preSurface)) lockedpre = SDL_LockSurface(preSurface); + if(SDL_MUSTLOCK(f2xSurface)) lockedf2x = SDL_LockSurface(f2xSurface); + if(lockedpre == 0 && preSurface->pixels && lockedf2x == 0 && f2xSurface->pixels && blitpre == 0) + { + blitfilter(FILTER(preSurface,f2xSurface)); + if(SDL_MUSTLOCK(preSurface)) SDL_UnlockSurface(preSurface); + if(SDL_MUSTLOCK(f2xSurface)) SDL_UnlockSurface(f2xSurface); + } + } + else + { + blitfilter = NULL; + if(preSurface) SDL_FreeSurface(preSurface); + preSurface = NULL; + if(f2xSurface) SDL_FreeSurface(f2xSurface); + f2xSurface = NULL; + } +} + +FUNCINLINE static ATTRINLINE int Setupf2x(int width, int height, int bpp) +{ + blitfilter = NULL; + if(preSurface) SDL_FreeSurface(preSurface); + preSurface = NULL; + if(f2xSurface) SDL_FreeSurface(f2xSurface); + f2xSurface = NULL; + if( !(width%2) && !(height%2) && width >= BASEVIDWIDTH*2 && height >= BASEVIDHEIGHT*2 && cv_filter.value + && cv_filter.value <= NUMFILTERS && filtermode[cv_filter.value].filter && filtermode[cv_filter.value].bpp) + { + int hwidth = width/2 + 6; + int heighth = height/2 + 6; + int hbpp = filtermode[cv_filter.value].bpp; + switch(hbpp) + { + case 8: + preSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,hwidth,heighth, 8,0x00000000,0x00000000,0x00000000,0x00); + f2xSurface = SDL_CreateRGBSurface(SDL_HWSURFACE, width,height , 8,0x00000000,0x00000000,0x00000000,0x00); + case 15: + preSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,hwidth,heighth,15,0x00007C00,0x000003E0,0x0000001F,0x00); + f2xSurface = SDL_CreateRGBSurface(SDL_HWSURFACE, width,height ,15,0x00007C00,0x000003E0,0x0000001F,0x00); + break; + case 16: + preSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,hwidth,heighth,16,0x0000F800,0x000007E0,0x0000001F,0x00); + f2xSurface = SDL_CreateRGBSurface(SDL_HWSURFACE, width,height ,16,0x0000F800,0x000007E0,0x0000001F,0x00); + break; + case 24: + preSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,hwidth,heighth,24,0x00FF0000,0x0000FF00,0x000000FF,0x00); + f2xSurface = SDL_CreateRGBSurface(SDL_HWSURFACE, width,height ,24,0x00FF0000,0x0000FF00,0x000000FF,0x00); + break; + case 32: + preSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,hwidth,heighth,32,0x00FF0000,0x0000FF00,0x000000FF,0x00); + f2xSurface = SDL_CreateRGBSurface(SDL_HWSURFACE, width,height ,32,0x00FF0000,0x0000FF00,0x000000FF,0x00); + break; + default: + //I_Error("Filter help"); + break; + } + if(preSurface && f2xSurface) + { + blitfilter = filtermode[cv_filter.value].filter; + if(bpp < hbpp) bpp = hbpp; + } + else + { + if(preSurface) SDL_FreeSurface(preSurface); + preSurface = NULL; + if(f2xSurface) SDL_FreeSurface(f2xSurface); + f2xSurface = NULL; + } + } + return bpp; +} +#else + +#ifdef __GNUC__ // __attribute__ ((X)) +#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +#define FUNCINLINE __attribute__((always_inline)) +#endif +#define FUNCNOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) +#define inline __inline +#define ATTRNORETURN __declspec(noreturn) +#define ATTRINLINE __forceinline +#if _MSC_VER > 1200 +#define ATTRNOINLINE __declspec(noinline) +#endif +#endif + + + +#ifndef FUNCINLINE +#define FUNCINLINE +#endif +#ifndef FUNCNOINLINE +#define FUNCNOINLINE +#endif +#ifndef ATTRINLINE +#define ATTRINLINE inline +#endif +#ifndef ATTRNOINLINE +#define ATTRNOINLINE +#endif + +#endif + +#endif diff --git a/src/sdl12/filter/hq2x.c b/src/sdl12/filter/hq2x.c new file mode 100644 index 000000000..acdbcb168 --- /dev/null +++ b/src/sdl12/filter/hq2x.c @@ -0,0 +1,3125 @@ +//hq2x filter demo program +//---------------------------------------------------------- +//Copyright (C) 2003 MaxSt ( maxst@hiend3d.com ) + +//This program is free software; you can redistribute it and/or +//modify it under the terms of the GNU Lesser General Public +//License as published by the Free Software Foundation; either +//version 2.1 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 +//Lesser General Public License for more details. +// +//You should have received a copy of the GNU Lesser 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 "filters.h" +#include +#ifdef __GNUC__ +#include +#endif + + +#if (defined(__GNUC__) && defined(__i386__)) || (defined(_MSC_VER) && defined(_X86_)) +#define HQ2XASM +#endif + +#ifdef _MSC_VER +//#define HQ2XMMXASM +#endif + +static int LUT16to32[65536]; +static int RGBtoYUV[65536]; +#ifdef HQ2XMMXASM +#include "SDL_cpuinfo.h" +static SDL_bool hasMMX = 0; +const Sint64 reg_blank = 0; +const Sint64 const3 = 0x0000000300030003; +const Sint64 const5 = 0x0000000500050005; +const Sint64 const6 = 0x0000000600060006; +const Sint64 const14 = 0x0000000E000E000E; +const Sint64 tr3eshold = 0x0000000000300706; +#endif +static int YUV1, YUV2; +const int Ymask = 0x00FF0000; +const int Umask = 0x0000FF00; +const int Vmask = 0x000000FF; +const int trY = 0x00300000; +const int trU = 0x00000700; +const int trV = 0x00000006; + +FUNCINLINE static ATTRINLINE void Interp1(Uint8 * pc, int c1, int c2) +{ +#ifdef HQ2XASM + //*((int*)pc) = (c1*3+c2)/4; +#ifdef __GNUC__ + int c3 = c1; + __asm__("shl $2, %1; add %2, %1; sub %3, %1; shr $2, %1":"=d"(*((int*)pc)):"d"(c1),"r"(c2),"r"(c3):"memory"); +#else + __asm + { + mov eax, pc + mov edx, c1 + shl edx, 2 + add edx, c2 + sub edx, c1 + shr edx, 2 + mov [eax], edx + } +#endif +#else + *((int*)pc) = (c1*3+c2) >> 2; +#endif +} + +FUNCINLINE static ATTRINLINE void Interp2(Uint8 * pc, int c1, int c2, int c3) +{ +#ifdef HQ2XASM +// *((int*)pc) = (c1*2+c2+c3) >> 2; +#ifdef __GNUC__ + __asm__("shl $1, %1; add %2, %1; add %3, %1; shr $2, %1":"=d"(*((int*)pc)):"d"(c1),"r"(c2),"r"(c3):"memory"); +#else + __asm + { + mov eax, pc + mov edx, c1 + shl edx, 1 + add edx, c2 + add edx, c3 + shr edx, 2 + mov [eax], edx + } +#endif +#else + *((int*)pc) = (c1*2+c2+c3) >> 2; +#endif +} + +#if 0 +static inline void Interp5(Uint8 * pc, int c1, int c2) +{ +#ifdef HQ2XASM + //*((int*)pc) = (c1+c2)/2; +#ifdef __GNUC__ + __asm__("add %2, %1; shr $1, %1":"=d"(*((int*)pc)):"d"(c1),"r"(c2):"memory"); +#else + __asm + { + mov eax, pc + mov edx, c1 + add edx, c2 + shr edx, 1 + mov [eax], edx + } +#endif +#else + *((int*)pc) = (c1+c2) >> 1; +#endif +} +#endif + +FUNCINLINE static ATTRINLINE void Interp6(Uint8 * pc, int c1, int c2, int c3) +{ +#ifdef HQ2XMMXASM + //*((int*)pc) = (c1*5+c2*2+c3)/8; + if(hasMMX) +#ifdef __GNUC__ + __asm__("movd %1, %%mm1; movd %2, %%mm2, movd %3, %%mm3; punpcklbw $_reg_blank, %%mm1; punpcklbw $_reg_blank, %%mm2; punpcklbw $_reg_blank, %%mm3; pmullw $_const5, %%mm1; psllw $1, %%mm2; paddw %%mm3, %%mm1; paddw %%mm2, %%mm1; psrlw $3, %%mm1; packuswb $_reg_blank, %%mm1; movd %%mm1, %0" : "=r"(*((int*)pc)) : "r" (c1),"r" (c2),"r" (c3) : "memory"); +#else + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + movd mm3, c3 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + punpcklbw mm3, reg_blank + pmullw mm1, const5 + psllw mm2, 1 + paddw mm1, mm3 + paddw mm1, mm2 + psrlw mm1, 3 + packuswb mm1, reg_blank + movd [eax], mm1 + } +#endif + else +#endif + *((int*)pc) = ((((c1 & 0x00FF00)*5 + (c2 & 0x00FF00)*2 + (c3 & 0x00FF00) ) & 0x0007F800) + + (((c1 & 0xFF00FF)*5 + (c2 & 0xFF00FF)*2 + (c3 & 0xFF00FF) ) & 0x07F807F8)) >> 3; +} + +FUNCINLINE static ATTRINLINE void Interp7(Uint8 * pc, int c1, int c2, int c3) +{ +#ifdef HQ2XMMXASM + //*((int*)pc) = (c1*6+c2+c3)/8; + if(hasMMX) +#ifdef __GNUC__ + __asm__("movd %1, %%mm1; movd %2, %%mm2, movd %3, %%mm3; punpcklbw $_reg_blank, %%mm1; punpcklbw $_reg_blank, %%mm2; punpcklbw $_reg_blank, %%mm3; pmull2 $_const6, %%mm1; padw %%mm3, %%mm2; paddw %%mm2, %%mm1; psrlw $3, %%mm1; packuswb $_reg_blank, %%mm1; movd %%mm1, %0 " : "=r" (*((int*)pc)): "r"(c1), "r"(c2), "r"(c3) : "memory"); +#else + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + movd mm3, c3 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + punpcklbw mm3, reg_blank + pmullw mm1, const6 + paddw mm2, mm3 + paddw mm1, mm2 + psrlw mm1, 3 + packuswb mm1, reg_blank + movd [eax], mm1 + } +#endif + else +#endif + *((int*)pc) = ((((c1 & 0x00FF00)*6 + (c2 & 0x00FF00) + (c3 & 0x00FF00) ) & 0x0007F800) + + (((c1 & 0xFF00FF)*6 + (c2 & 0xFF00FF) + (c3 & 0xFF00FF) ) & 0x07F807F8)) >> 3; +} + +FUNCINLINE static ATTRINLINE void Interp9(Uint8 * pc, int c1, int c2, int c3) +{ +#ifdef HQ2XMMXASM + //*((int*)pc) = (c1*2+(c2+c3)*3)/8; + if(hasMMX) +#ifdef __GNUC__ + __asm__("movd %1, %%mm1; movd %2, %%mm2, movd %3, %%mm3; punpcklbw $_reg_blank, %%mm1; punpcklbw $_reg_blank, %%mm2; punpcklbw $_reg_blank, %%mm3; psllw $1, %%mm1; paddw %%mm3, %%mm2; pmullw $_const3, %%mm2; padw %%mm2, %%mm1; psrlw $3, %%mm1; packuswb $_reg_blank, %%mm1; movd %%mm1, %0;" : "=r"(*((int*)pc)) : "r" (c1),"r" (c2),"r" (c3) : "memory"); +#else + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + movd mm3, c3 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + punpcklbw mm3, reg_blank + psllw mm1, 1 + paddw mm2, mm3 + pmullw mm2, const3 + paddw mm1, mm2 + psrlw mm1, 3 + packuswb mm1, reg_blank + movd [eax], mm1 + } +#endif + else +#endif + *((int*)pc) = ((((c1 & 0x00FF00)*2 + ((c2 & 0x00FF00) + (c3 & 0x00FF00))*3 ) & 0x0007F800) + + (((c1 & 0xFF00FF)*2 + ((c2 & 0xFF00FF) + (c3 & 0xFF00FF))*3 ) & 0x07F807F8)) >> 3; +} + +FUNCINLINE static ATTRINLINE void Interp10(Uint8 * pc, int c1, int c2, int c3) +{ +#ifdef HQ2XMMXASM + //*((int*)pc) = (c1*14+c2+c3)/16; + if(hasMMX) +#ifdef __GNUC__ + __asm__("movd %1, %%mm1; movd %2, %%mm2, movd %3, %%mm3; punpcklbw $_reg_blank, %%mm1; punpcklbw $_reg_blank, %%mm2; punpcklbw $_reg_blank, %%mm3; pmullw $_const14, %%mm1; paddw %%mm3, %%mm2; paddw %%mm2, %%mm1; psrlw $4, %%mm1; packuswb $_req_blank, %%mm1; movd %%mm1, %0;" : "=r"(*((int*)pc)) : "r" (c1),"r" (c2),"r" (c3) : "memory"); +#else + __asm + { + mov eax, pc + movd mm1, c1 + movd mm2, c2 + movd mm3, c3 + punpcklbw mm1, reg_blank + punpcklbw mm2, reg_blank + punpcklbw mm3, reg_blank + pmullw mm1, const14 + paddw mm2, mm3 + paddw mm1, mm2 + psrlw mm1, 4 + packuswb mm1, reg_blank + movd [eax], mm1 + } +#endif + else +#endif + *((int*)pc) = ((((c1 & 0x00FF00)*14 + (c2 & 0x00FF00) + (c3 & 0x00FF00) ) & 0x000FF000) + + (((c1 & 0xFF00FF)*14 + (c2 & 0xFF00FF) + (c3 & 0xFF00FF) ) & 0x0FF00FF0)) >> 4; +} +#define PIXEL00_0 *((int*)(pOut)) = c[5]; +#define PIXEL00_10 Interp1(pOut, c[5], c[1]); +#define PIXEL00_11 Interp1(pOut, c[5], c[4]); +#define PIXEL00_12 Interp1(pOut, c[5], c[2]); +#define PIXEL00_20 Interp2(pOut, c[5], c[4], c[2]); +#define PIXEL00_21 Interp2(pOut, c[5], c[1], c[2]); +#define PIXEL00_22 Interp2(pOut, c[5], c[1], c[4]); +#define PIXEL00_60 Interp6(pOut, c[5], c[2], c[4]); +#define PIXEL00_61 Interp6(pOut, c[5], c[4], c[2]); +#define PIXEL00_70 Interp7(pOut, c[5], c[4], c[2]); +#define PIXEL00_90 Interp9(pOut, c[5], c[4], c[2]); +#define PIXEL00_100 Interp10(pOut, c[5], c[4], c[2]); +#define PIXEL01_0 *((int*)(pOut+4)) = c[5]; +#define PIXEL01_10 Interp1(pOut+4, c[5], c[3]); +#define PIXEL01_11 Interp1(pOut+4, c[5], c[2]); +#define PIXEL01_12 Interp1(pOut+4, c[5], c[6]); +#define PIXEL01_20 Interp2(pOut+4, c[5], c[2], c[6]); +#define PIXEL01_21 Interp2(pOut+4, c[5], c[3], c[6]); +#define PIXEL01_22 Interp2(pOut+4, c[5], c[3], c[2]); +#define PIXEL01_60 Interp6(pOut+4, c[5], c[6], c[2]); +#define PIXEL01_61 Interp6(pOut+4, c[5], c[2], c[6]); +#define PIXEL01_70 Interp7(pOut+4, c[5], c[2], c[6]); +#define PIXEL01_90 Interp9(pOut+4, c[5], c[2], c[6]); +#define PIXEL01_100 Interp10(pOut+4, c[5], c[2], c[6]); +#define PIXEL10_0 *((int*)(pOut+BpL)) = c[5]; +#define PIXEL10_10 Interp1(pOut+BpL, c[5], c[7]); +#define PIXEL10_11 Interp1(pOut+BpL, c[5], c[8]); +#define PIXEL10_12 Interp1(pOut+BpL, c[5], c[4]); +#define PIXEL10_20 Interp2(pOut+BpL, c[5], c[8], c[4]); +#define PIXEL10_21 Interp2(pOut+BpL, c[5], c[7], c[4]); +#define PIXEL10_22 Interp2(pOut+BpL, c[5], c[7], c[8]); +#define PIXEL10_60 Interp6(pOut+BpL, c[5], c[4], c[8]); +#define PIXEL10_61 Interp6(pOut+BpL, c[5], c[8], c[4]); +#define PIXEL10_70 Interp7(pOut+BpL, c[5], c[8], c[4]); +#define PIXEL10_90 Interp9(pOut+BpL, c[5], c[8], c[4]); +#define PIXEL10_100 Interp10(pOut+BpL, c[5], c[8], c[4]); +#define PIXEL11_0 *((int*)(pOut+BpL+4)) = c[5]; +#define PIXEL11_10 Interp1(pOut+BpL+4, c[5], c[9]); +#define PIXEL11_11 Interp1(pOut+BpL+4, c[5], c[6]); +#define PIXEL11_12 Interp1(pOut+BpL+4, c[5], c[8]); +#define PIXEL11_20 Interp2(pOut+BpL+4, c[5], c[6], c[8]); +#define PIXEL11_21 Interp2(pOut+BpL+4, c[5], c[9], c[8]); +#define PIXEL11_22 Interp2(pOut+BpL+4, c[5], c[9], c[6]); +#define PIXEL11_60 Interp6(pOut+BpL+4, c[5], c[8], c[6]); +#define PIXEL11_61 Interp6(pOut+BpL+4, c[5], c[6], c[8]); +#define PIXEL11_70 Interp7(pOut+BpL+4, c[5], c[6], c[8]); +#define PIXEL11_90 Interp9(pOut+BpL+4, c[5], c[6], c[8]); +#define PIXEL11_100 Interp10(pOut+BpL+4, c[5], c[6], c[8]); + +#ifdef _MSC_VER +#pragma warning(disable: 4035) +#endif + +FUNCINLINE static ATTRINLINE int Diff(Uint32 w1, Uint32 w2) +{ +#ifdef HQ2XMMXASM + if(hasMMX) + { +#ifdef __GNUC__ + int diffresult = 0; + if(w1 != w2) + __asm__("movd %3+%1*4, %%mm1; movq %%mm1, %%mm5; movd %3+%2*4, %%mm2; psubusb %%mm2, %%mm1; psubusb %%mm5, %%mm2; por %%mm2, %%mm1; psubusb $_treshold, %%mm1; movd %%mm1, %0" : "=c" (diffresult):"d" (w1),"q" (w2),"c" (RGBtoYUV) : "memory"); + return diffresult; +#else + __asm + { + xor eax,eax + mov ebx,w1 + mov edx,w2 + cmp ebx,edx + je FIN + mov ecx,offset RGBtoYUV + movd mm1,[ecx + ebx*4] + movq mm5,mm1 + movd mm2,[ecx + edx*4] + psubusb mm1,mm2 + psubusb mm2,mm5 + por mm1,mm2 + psubusb mm1,treshold + movd eax,mm1 +FIN: + }// returns result in eax register +#endif + } + else +#endif + { + YUV1 = RGBtoYUV[w1]; + YUV2 = RGBtoYUV[w2]; + return ( ( abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY ) || + ( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) || + ( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) ); + } +} + + +#ifdef _MSC_VER +#pragma warning(default: 4035) +#endif + + +static void hq2x_32( Uint8 * pIn, Uint8 * pOut, int Xres, int Yres, int BpL ) +{ + int i, j, k; + int prevline, nextline; + int w[10]; + int c[10]; + + // +----+----+----+ + // | | | | + // | w1 | w2 | w3 | + // +----+----+----+ + // | | | | + // | w4 | w5 | w6 | + // +----+----+----+ + // | | | | + // | w7 | w8 | w9 | + // +----+----+----+ + + for (j=0; j0) prevline = -Xres*2; else prevline = 0; + if (j0) + { + w[1] = *((Uint16*)(pIn + prevline - 2)); + w[4] = *((Uint16*)(pIn - 2)); + w[7] = *((Uint16*)(pIn + nextline - 2)); + } + else + { + w[1] = w[2]; + w[4] = w[5]; + w[7] = w[8]; + } + + if (i trY ) || + ( abs((YUV1 & Umask) - (YUV2 & Umask)) > trU ) || + ( abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV ) ) + pattern |= flag; + } + flag <<= 1; + } + } + + for (k=1; k<=9; k++) + c[k] = LUT16to32[w[k]]; + + switch (pattern) + { + case 0: + case 1: + case 4: + case 32: + case 128: + case 5: + case 132: + case 160: + case 33: + case 129: + case 36: + case 133: + case 164: + case 161: + case 37: + case 165: + { + PIXEL00_20 + PIXEL01_20 + PIXEL10_20 + PIXEL11_20 + break; + } + case 2: + case 34: + case 130: + case 162: + { + PIXEL00_22 + PIXEL01_21 + PIXEL10_20 + PIXEL11_20 + break; + } + case 16: + case 17: + case 48: + case 49: + { + PIXEL00_20 + PIXEL01_22 + PIXEL10_20 + PIXEL11_21 + break; + } + case 64: + case 65: + case 68: + case 69: + { + PIXEL00_20 + PIXEL01_20 + PIXEL10_21 + PIXEL11_22 + break; + } + case 8: + case 12: + case 136: + case 140: + { + PIXEL00_21 + PIXEL01_20 + PIXEL10_22 + PIXEL11_20 + break; + } + case 3: + case 35: + case 131: + case 163: + { + PIXEL00_11 + PIXEL01_21 + PIXEL10_20 + PIXEL11_20 + break; + } + case 6: + case 38: + case 134: + case 166: + { + PIXEL00_22 + PIXEL01_12 + PIXEL10_20 + PIXEL11_20 + break; + } + case 20: + case 21: + case 52: + case 53: + { + PIXEL00_20 + PIXEL01_11 + PIXEL10_20 + PIXEL11_21 + break; + } + case 144: + case 145: + case 176: + case 177: + { + PIXEL00_20 + PIXEL01_22 + PIXEL10_20 + PIXEL11_12 + break; + } + case 192: + case 193: + case 196: + case 197: + { + PIXEL00_20 + PIXEL01_20 + PIXEL10_21 + PIXEL11_11 + break; + } + case 96: + case 97: + case 100: + case 101: + { + PIXEL00_20 + PIXEL01_20 + PIXEL10_12 + PIXEL11_22 + break; + } + case 40: + case 44: + case 168: + case 172: + { + PIXEL00_21 + PIXEL01_20 + PIXEL10_11 + PIXEL11_20 + break; + } + case 9: + case 13: + case 137: + case 141: + { + PIXEL00_12 + PIXEL01_20 + PIXEL10_22 + PIXEL11_20 + break; + } + case 18: + case 50: + { + PIXEL00_22 + if (Diff(w[2], w[6])) + { + PIXEL01_10 + } + else + { + PIXEL01_20 + } + PIXEL10_20 + PIXEL11_21 + break; + } + case 80: + case 81: + { + PIXEL00_20 + PIXEL01_22 + PIXEL10_21 + if (Diff(w[6], w[8])) + { + PIXEL11_10 + } + else + { + PIXEL11_20 + } + break; + } + case 72: + case 76: + { + PIXEL00_21 + PIXEL01_20 + if (Diff(w[8], w[4])) + { + PIXEL10_10 + } + else + { + PIXEL10_20 + } + PIXEL11_22 + break; + } + case 10: + case 138: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + } + else + { + PIXEL00_20 + } + PIXEL01_21 + PIXEL10_22 + PIXEL11_20 + break; + } + case 66: + { + PIXEL00_22 + PIXEL01_21 + PIXEL10_21 + PIXEL11_22 + break; + } + case 24: + { + PIXEL00_21 + PIXEL01_22 + PIXEL10_22 + PIXEL11_21 + break; + } + case 7: + case 39: + case 135: + { + PIXEL00_11 + PIXEL01_12 + PIXEL10_20 + PIXEL11_20 + break; + } + case 148: + case 149: + case 180: + { + PIXEL00_20 + PIXEL01_11 + PIXEL10_20 + PIXEL11_12 + break; + } + case 224: + case 228: + case 225: + { + PIXEL00_20 + PIXEL01_20 + PIXEL10_12 + PIXEL11_11 + break; + } + case 41: + case 169: + case 45: + { + PIXEL00_12 + PIXEL01_20 + PIXEL10_11 + PIXEL11_20 + break; + } + case 22: + case 54: + { + PIXEL00_22 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + PIXEL10_20 + PIXEL11_21 + break; + } + case 208: + case 209: + { + PIXEL00_20 + PIXEL01_22 + PIXEL10_21 + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 104: + case 108: + { + PIXEL00_21 + PIXEL01_20 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + PIXEL11_22 + break; + } + case 11: + case 139: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_21 + PIXEL10_22 + PIXEL11_20 + break; + } + case 19: + case 51: + { + if (Diff(w[2], w[6])) + { + PIXEL00_11 + PIXEL01_10 + } + else + { + PIXEL00_60 + PIXEL01_90 + } + PIXEL10_20 + PIXEL11_21 + break; + } + case 146: + case 178: + { + PIXEL00_22 + if (Diff(w[2], w[6])) + { + PIXEL01_10 + PIXEL11_12 + } + else + { + PIXEL01_90 + PIXEL11_61 + } + PIXEL10_20 + break; + } + case 84: + case 85: + { + PIXEL00_20 + if (Diff(w[6], w[8])) + { + PIXEL01_11 + PIXEL11_10 + } + else + { + PIXEL01_60 + PIXEL11_90 + } + PIXEL10_21 + break; + } + case 112: + case 113: + { + PIXEL00_20 + PIXEL01_22 + if (Diff(w[6], w[8])) + { + PIXEL10_12 + PIXEL11_10 + } + else + { + PIXEL10_61 + PIXEL11_90 + } + break; + } + case 200: + case 204: + { + PIXEL00_21 + PIXEL01_20 + if (Diff(w[8], w[4])) + { + PIXEL10_10 + PIXEL11_11 + } + else + { + PIXEL10_90 + PIXEL11_60 + } + break; + } + case 73: + case 77: + { + if (Diff(w[8], w[4])) + { + PIXEL00_12 + PIXEL10_10 + } + else + { + PIXEL00_61 + PIXEL10_90 + } + PIXEL01_20 + PIXEL11_22 + break; + } + case 42: + case 170: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + PIXEL10_11 + } + else + { + PIXEL00_90 + PIXEL10_60 + } + PIXEL01_21 + PIXEL11_20 + break; + } + case 14: + case 142: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + PIXEL01_12 + } + else + { + PIXEL00_90 + PIXEL01_61 + } + PIXEL10_22 + PIXEL11_20 + break; + } + case 67: + { + PIXEL00_11 + PIXEL01_21 + PIXEL10_21 + PIXEL11_22 + break; + } + case 70: + { + PIXEL00_22 + PIXEL01_12 + PIXEL10_21 + PIXEL11_22 + break; + } + case 28: + { + PIXEL00_21 + PIXEL01_11 + PIXEL10_22 + PIXEL11_21 + break; + } + case 152: + { + PIXEL00_21 + PIXEL01_22 + PIXEL10_22 + PIXEL11_12 + break; + } + case 194: + { + PIXEL00_22 + PIXEL01_21 + PIXEL10_21 + PIXEL11_11 + break; + } + case 98: + { + PIXEL00_22 + PIXEL01_21 + PIXEL10_12 + PIXEL11_22 + break; + } + case 56: + { + PIXEL00_21 + PIXEL01_22 + PIXEL10_11 + PIXEL11_21 + break; + } + case 25: + { + PIXEL00_12 + PIXEL01_22 + PIXEL10_22 + PIXEL11_21 + break; + } + case 26: + case 31: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + PIXEL10_22 + PIXEL11_21 + break; + } + case 82: + case 214: + { + PIXEL00_22 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + PIXEL10_21 + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 88: + case 248: + { + PIXEL00_21 + PIXEL01_22 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 74: + case 107: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_21 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + PIXEL11_22 + break; + } + case 27: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_10 + PIXEL10_22 + PIXEL11_21 + break; + } + case 86: + { + PIXEL00_22 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + PIXEL10_21 + PIXEL11_10 + break; + } + case 216: + { + PIXEL00_21 + PIXEL01_22 + PIXEL10_10 + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 106: + { + PIXEL00_10 + PIXEL01_21 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + PIXEL11_22 + break; + } + case 30: + { + PIXEL00_10 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + PIXEL10_22 + PIXEL11_21 + break; + } + case 210: + { + PIXEL00_22 + PIXEL01_10 + PIXEL10_21 + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 120: + { + PIXEL00_21 + PIXEL01_22 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + PIXEL11_10 + break; + } + case 75: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_21 + PIXEL10_10 + PIXEL11_22 + break; + } + case 29: + { + PIXEL00_12 + PIXEL01_11 + PIXEL10_22 + PIXEL11_21 + break; + } + case 198: + { + PIXEL00_22 + PIXEL01_12 + PIXEL10_21 + PIXEL11_11 + break; + } + case 184: + { + PIXEL00_21 + PIXEL01_22 + PIXEL10_11 + PIXEL11_12 + break; + } + case 99: + { + PIXEL00_11 + PIXEL01_21 + PIXEL10_12 + PIXEL11_22 + break; + } + case 57: + { + PIXEL00_12 + PIXEL01_22 + PIXEL10_11 + PIXEL11_21 + break; + } + case 71: + { + PIXEL00_11 + PIXEL01_12 + PIXEL10_21 + PIXEL11_22 + break; + } + case 156: + { + PIXEL00_21 + PIXEL01_11 + PIXEL10_22 + PIXEL11_12 + break; + } + case 226: + { + PIXEL00_22 + PIXEL01_21 + PIXEL10_12 + PIXEL11_11 + break; + } + case 60: + { + PIXEL00_21 + PIXEL01_11 + PIXEL10_11 + PIXEL11_21 + break; + } + case 195: + { + PIXEL00_11 + PIXEL01_21 + PIXEL10_21 + PIXEL11_11 + break; + } + case 102: + { + PIXEL00_22 + PIXEL01_12 + PIXEL10_12 + PIXEL11_22 + break; + } + case 153: + { + PIXEL00_12 + PIXEL01_22 + PIXEL10_22 + PIXEL11_12 + break; + } + case 58: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + } + else + { + PIXEL00_70 + } + if (Diff(w[2], w[6])) + { + PIXEL01_10 + } + else + { + PIXEL01_70 + } + PIXEL10_11 + PIXEL11_21 + break; + } + case 83: + { + PIXEL00_11 + if (Diff(w[2], w[6])) + { + PIXEL01_10 + } + else + { + PIXEL01_70 + } + PIXEL10_21 + if (Diff(w[6], w[8])) + { + PIXEL11_10 + } + else + { + PIXEL11_70 + } + break; + } + case 92: + { + PIXEL00_21 + PIXEL01_11 + if (Diff(w[8], w[4])) + { + PIXEL10_10 + } + else + { + PIXEL10_70 + } + if (Diff(w[6], w[8])) + { + PIXEL11_10 + } + else + { + PIXEL11_70 + } + break; + } + case 202: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + } + else + { + PIXEL00_70 + } + PIXEL01_21 + if (Diff(w[8], w[4])) + { + PIXEL10_10 + } + else + { + PIXEL10_70 + } + PIXEL11_11 + break; + } + case 78: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + } + else + { + PIXEL00_70 + } + PIXEL01_12 + if (Diff(w[8], w[4])) + { + PIXEL10_10 + } + else + { + PIXEL10_70 + } + PIXEL11_22 + break; + } + case 154: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + } + else + { + PIXEL00_70 + } + if (Diff(w[2], w[6])) + { + PIXEL01_10 + } + else + { + PIXEL01_70 + } + PIXEL10_22 + PIXEL11_12 + break; + } + case 114: + { + PIXEL00_22 + if (Diff(w[2], w[6])) + { + PIXEL01_10 + } + else + { + PIXEL01_70 + } + PIXEL10_12 + if (Diff(w[6], w[8])) + { + PIXEL11_10 + } + else + { + PIXEL11_70 + } + break; + } + case 89: + { + PIXEL00_12 + PIXEL01_22 + if (Diff(w[8], w[4])) + { + PIXEL10_10 + } + else + { + PIXEL10_70 + } + if (Diff(w[6], w[8])) + { + PIXEL11_10 + } + else + { + PIXEL11_70 + } + break; + } + case 90: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + } + else + { + PIXEL00_70 + } + if (Diff(w[2], w[6])) + { + PIXEL01_10 + } + else + { + PIXEL01_70 + } + if (Diff(w[8], w[4])) + { + PIXEL10_10 + } + else + { + PIXEL10_70 + } + if (Diff(w[6], w[8])) + { + PIXEL11_10 + } + else + { + PIXEL11_70 + } + break; + } + case 55: + case 23: + { + if (Diff(w[2], w[6])) + { + PIXEL00_11 + PIXEL01_0 + } + else + { + PIXEL00_60 + PIXEL01_90 + } + PIXEL10_20 + PIXEL11_21 + break; + } + case 182: + case 150: + { + PIXEL00_22 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + PIXEL11_12 + } + else + { + PIXEL01_90 + PIXEL11_61 + } + PIXEL10_20 + break; + } + case 213: + case 212: + { + PIXEL00_20 + if (Diff(w[6], w[8])) + { + PIXEL01_11 + PIXEL11_0 + } + else + { + PIXEL01_60 + PIXEL11_90 + } + PIXEL10_21 + break; + } + case 241: + case 240: + { + PIXEL00_20 + PIXEL01_22 + if (Diff(w[6], w[8])) + { + PIXEL10_12 + PIXEL11_0 + } + else + { + PIXEL10_61 + PIXEL11_90 + } + break; + } + case 236: + case 232: + { + PIXEL00_21 + PIXEL01_20 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + PIXEL11_11 + } + else + { + PIXEL10_90 + PIXEL11_60 + } + break; + } + case 109: + case 105: + { + if (Diff(w[8], w[4])) + { + PIXEL00_12 + PIXEL10_0 + } + else + { + PIXEL00_61 + PIXEL10_90 + } + PIXEL01_20 + PIXEL11_22 + break; + } + case 171: + case 43: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL10_11 + } + else + { + PIXEL00_90 + PIXEL10_60 + } + PIXEL01_21 + PIXEL11_20 + break; + } + case 143: + case 15: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_12 + } + else + { + PIXEL00_90 + PIXEL01_61 + } + PIXEL10_22 + PIXEL11_20 + break; + } + case 124: + { + PIXEL00_21 + PIXEL01_11 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + PIXEL11_10 + break; + } + case 203: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_21 + PIXEL10_10 + PIXEL11_11 + break; + } + case 62: + { + PIXEL00_10 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + PIXEL10_11 + PIXEL11_21 + break; + } + case 211: + { + PIXEL00_11 + PIXEL01_10 + PIXEL10_21 + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 118: + { + PIXEL00_22 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + PIXEL10_12 + PIXEL11_10 + break; + } + case 217: + { + PIXEL00_12 + PIXEL01_22 + PIXEL10_10 + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 110: + { + PIXEL00_10 + PIXEL01_12 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + PIXEL11_22 + break; + } + case 155: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_10 + PIXEL10_22 + PIXEL11_12 + break; + } + case 188: + { + PIXEL00_21 + PIXEL01_11 + PIXEL10_11 + PIXEL11_12 + break; + } + case 185: + { + PIXEL00_12 + PIXEL01_22 + PIXEL10_11 + PIXEL11_12 + break; + } + case 61: + { + PIXEL00_12 + PIXEL01_11 + PIXEL10_11 + PIXEL11_21 + break; + } + case 157: + { + PIXEL00_12 + PIXEL01_11 + PIXEL10_22 + PIXEL11_12 + break; + } + case 103: + { + PIXEL00_11 + PIXEL01_12 + PIXEL10_12 + PIXEL11_22 + break; + } + case 227: + { + PIXEL00_11 + PIXEL01_21 + PIXEL10_12 + PIXEL11_11 + break; + } + case 230: + { + PIXEL00_22 + PIXEL01_12 + PIXEL10_12 + PIXEL11_11 + break; + } + case 199: + { + PIXEL00_11 + PIXEL01_12 + PIXEL10_21 + PIXEL11_11 + break; + } + case 220: + { + PIXEL00_21 + PIXEL01_11 + if (Diff(w[8], w[4])) + { + PIXEL10_10 + } + else + { + PIXEL10_70 + } + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 158: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + } + else + { + PIXEL00_70 + } + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + PIXEL10_22 + PIXEL11_12 + break; + } + case 234: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + } + else + { + PIXEL00_70 + } + PIXEL01_21 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + PIXEL11_11 + break; + } + case 242: + { + PIXEL00_22 + if (Diff(w[2], w[6])) + { + PIXEL01_10 + } + else + { + PIXEL01_70 + } + PIXEL10_12 + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 59: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + if (Diff(w[2], w[6])) + { + PIXEL01_10 + } + else + { + PIXEL01_70 + } + PIXEL10_11 + PIXEL11_21 + break; + } + case 121: + { + PIXEL00_12 + PIXEL01_22 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + if (Diff(w[6], w[8])) + { + PIXEL11_10 + } + else + { + PIXEL11_70 + } + break; + } + case 87: + { + PIXEL00_11 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + PIXEL10_21 + if (Diff(w[6], w[8])) + { + PIXEL11_10 + } + else + { + PIXEL11_70 + } + break; + } + case 79: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_12 + if (Diff(w[8], w[4])) + { + PIXEL10_10 + } + else + { + PIXEL10_70 + } + PIXEL11_22 + break; + } + case 122: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + } + else + { + PIXEL00_70 + } + if (Diff(w[2], w[6])) + { + PIXEL01_10 + } + else + { + PIXEL01_70 + } + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + if (Diff(w[6], w[8])) + { + PIXEL11_10 + } + else + { + PIXEL11_70 + } + break; + } + case 94: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + } + else + { + PIXEL00_70 + } + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + if (Diff(w[8], w[4])) + { + PIXEL10_10 + } + else + { + PIXEL10_70 + } + if (Diff(w[6], w[8])) + { + PIXEL11_10 + } + else + { + PIXEL11_70 + } + break; + } + case 218: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + } + else + { + PIXEL00_70 + } + if (Diff(w[2], w[6])) + { + PIXEL01_10 + } + else + { + PIXEL01_70 + } + if (Diff(w[8], w[4])) + { + PIXEL10_10 + } + else + { + PIXEL10_70 + } + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 91: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + if (Diff(w[2], w[6])) + { + PIXEL01_10 + } + else + { + PIXEL01_70 + } + if (Diff(w[8], w[4])) + { + PIXEL10_10 + } + else + { + PIXEL10_70 + } + if (Diff(w[6], w[8])) + { + PIXEL11_10 + } + else + { + PIXEL11_70 + } + break; + } + case 229: + { + PIXEL00_20 + PIXEL01_20 + PIXEL10_12 + PIXEL11_11 + break; + } + case 167: + { + PIXEL00_11 + PIXEL01_12 + PIXEL10_20 + PIXEL11_20 + break; + } + case 173: + { + PIXEL00_12 + PIXEL01_20 + PIXEL10_11 + PIXEL11_20 + break; + } + case 181: + { + PIXEL00_20 + PIXEL01_11 + PIXEL10_20 + PIXEL11_12 + break; + } + case 186: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + } + else + { + PIXEL00_70 + } + if (Diff(w[2], w[6])) + { + PIXEL01_10 + } + else + { + PIXEL01_70 + } + PIXEL10_11 + PIXEL11_12 + break; + } + case 115: + { + PIXEL00_11 + if (Diff(w[2], w[6])) + { + PIXEL01_10 + } + else + { + PIXEL01_70 + } + PIXEL10_12 + if (Diff(w[6], w[8])) + { + PIXEL11_10 + } + else + { + PIXEL11_70 + } + break; + } + case 93: + { + PIXEL00_12 + PIXEL01_11 + if (Diff(w[8], w[4])) + { + PIXEL10_10 + } + else + { + PIXEL10_70 + } + if (Diff(w[6], w[8])) + { + PIXEL11_10 + } + else + { + PIXEL11_70 + } + break; + } + case 206: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + } + else + { + PIXEL00_70 + } + PIXEL01_12 + if (Diff(w[8], w[4])) + { + PIXEL10_10 + } + else + { + PIXEL10_70 + } + PIXEL11_11 + break; + } + case 205: + case 201: + { + PIXEL00_12 + PIXEL01_20 + if (Diff(w[8], w[4])) + { + PIXEL10_10 + } + else + { + PIXEL10_70 + } + PIXEL11_11 + break; + } + case 174: + case 46: + { + if (Diff(w[4], w[2])) + { + PIXEL00_10 + } + else + { + PIXEL00_70 + } + PIXEL01_12 + PIXEL10_11 + PIXEL11_20 + break; + } + case 179: + case 147: + { + PIXEL00_11 + if (Diff(w[2], w[6])) + { + PIXEL01_10 + } + else + { + PIXEL01_70 + } + PIXEL10_20 + PIXEL11_12 + break; + } + case 117: + case 116: + { + PIXEL00_20 + PIXEL01_11 + PIXEL10_12 + if (Diff(w[6], w[8])) + { + PIXEL11_10 + } + else + { + PIXEL11_70 + } + break; + } + case 189: + { + PIXEL00_12 + PIXEL01_11 + PIXEL10_11 + PIXEL11_12 + break; + } + case 231: + { + PIXEL00_11 + PIXEL01_12 + PIXEL10_12 + PIXEL11_11 + break; + } + case 126: + { + PIXEL00_10 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + PIXEL11_10 + break; + } + case 219: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_10 + PIXEL10_10 + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 125: + { + if (Diff(w[8], w[4])) + { + PIXEL00_12 + PIXEL10_0 + } + else + { + PIXEL00_61 + PIXEL10_90 + } + PIXEL01_11 + PIXEL11_10 + break; + } + case 221: + { + PIXEL00_12 + if (Diff(w[6], w[8])) + { + PIXEL01_11 + PIXEL11_0 + } + else + { + PIXEL01_60 + PIXEL11_90 + } + PIXEL10_10 + break; + } + case 207: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL01_12 + } + else + { + PIXEL00_90 + PIXEL01_61 + } + PIXEL10_10 + PIXEL11_11 + break; + } + case 238: + { + PIXEL00_10 + PIXEL01_12 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + PIXEL11_11 + } + else + { + PIXEL10_90 + PIXEL11_60 + } + break; + } + case 190: + { + PIXEL00_10 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + PIXEL11_12 + } + else + { + PIXEL01_90 + PIXEL11_61 + } + PIXEL10_11 + break; + } + case 187: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + PIXEL10_11 + } + else + { + PIXEL00_90 + PIXEL10_60 + } + PIXEL01_10 + PIXEL11_12 + break; + } + case 243: + { + PIXEL00_11 + PIXEL01_10 + if (Diff(w[6], w[8])) + { + PIXEL10_12 + PIXEL11_0 + } + else + { + PIXEL10_61 + PIXEL11_90 + } + break; + } + case 119: + { + if (Diff(w[2], w[6])) + { + PIXEL00_11 + PIXEL01_0 + } + else + { + PIXEL00_60 + PIXEL01_90 + } + PIXEL10_12 + PIXEL11_10 + break; + } + case 237: + case 233: + { + PIXEL00_12 + PIXEL01_20 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_100 + } + PIXEL11_11 + break; + } + case 175: + case 47: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_100 + } + PIXEL01_12 + PIXEL10_11 + PIXEL11_20 + break; + } + case 183: + case 151: + { + PIXEL00_11 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_100 + } + PIXEL10_20 + PIXEL11_12 + break; + } + case 245: + case 244: + { + PIXEL00_20 + PIXEL01_11 + PIXEL10_12 + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_100 + } + break; + } + case 250: + { + PIXEL00_10 + PIXEL01_10 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 123: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_10 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + PIXEL11_10 + break; + } + case 95: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + PIXEL10_10 + PIXEL11_10 + break; + } + case 222: + { + PIXEL00_10 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + PIXEL10_10 + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 252: + { + PIXEL00_21 + PIXEL01_11 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_100 + } + break; + } + case 249: + { + PIXEL00_12 + PIXEL01_22 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_100 + } + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 235: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_21 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_100 + } + PIXEL11_11 + break; + } + case 111: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_100 + } + PIXEL01_12 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + PIXEL11_22 + break; + } + case 63: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_100 + } + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + PIXEL10_11 + PIXEL11_21 + break; + } + case 159: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_100 + } + PIXEL10_22 + PIXEL11_12 + break; + } + case 215: + { + PIXEL00_11 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_100 + } + PIXEL10_21 + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 246: + { + PIXEL00_22 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + PIXEL10_12 + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_100 + } + break; + } + case 254: + { + PIXEL00_10 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_100 + } + break; + } + case 253: + { + PIXEL00_12 + PIXEL01_11 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_100 + } + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_100 + } + break; + } + case 251: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + PIXEL01_10 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_100 + } + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 239: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_100 + } + PIXEL01_12 + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_100 + } + PIXEL11_11 + break; + } + case 127: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_100 + } + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_20 + } + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_20 + } + PIXEL11_10 + break; + } + case 191: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_100 + } + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_100 + } + PIXEL10_11 + PIXEL11_12 + break; + } + case 223: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_20 + } + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_100 + } + PIXEL10_10 + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_20 + } + break; + } + case 247: + { + PIXEL00_11 + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_100 + } + PIXEL10_12 + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_100 + } + break; + } + case 255: + { + if (Diff(w[4], w[2])) + { + PIXEL00_0 + } + else + { + PIXEL00_100 + } + if (Diff(w[2], w[6])) + { + PIXEL01_0 + } + else + { + PIXEL01_100 + } + if (Diff(w[8], w[4])) + { + PIXEL10_0 + } + else + { + PIXEL10_100 + } + if (Diff(w[6], w[8])) + { + PIXEL11_0 + } + else + { + PIXEL11_100 + } + break; + } + } + pIn+=2; + pOut+=8; + } + pOut+=BpL; + } +} + +FUNCINLINE static ATTRINLINE void InitLUTs(void) +{ + int i, j, k, r, g, b, Y, u, v; + +#ifdef HQ2XMMXASM + hasMMX = SDL_HasMMX(); +#endif + + for (i=0; i<65536; i++) + LUT16to32[i] = ((i & 0xF800) << 8) + ((i & 0x07E0) << 5) + ((i & 0x001F) << 3); + + for (i=0; i<32; i++) + for (j=0; j<64; j++) + for (k=0; k<32; k++) + { + r = i << 3; + g = j << 2; + b = k << 3; + Y = (r + g + b) >> 2; + u = 128 + ((r - b) >> 2); + v = 128 + ((-r + 2*g -b)>>3); + RGBtoYUV[ (i << 11) + (j << 5) + k ] = (Y<<16) + (u<<8) + v; + } +} + +void filter_hq2x(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, Uint32 dstPitch, int width, int height) +{ + static Uint8 doneLUT = 1; + (void)srcPitch; + if(doneLUT) InitLUTs(); + else doneLUT = 0; + hq2x_32( srcPtr, dstPtr, width, height, dstPitch ); +} diff --git a/src/sdl12/filter/hq2x.h b/src/sdl12/filter/hq2x.h new file mode 100644 index 000000000..49c0b2687 --- /dev/null +++ b/src/sdl12/filter/hq2x.h @@ -0,0 +1,1824 @@ +case 0 : +case 1 : +case 4 : +case 5 : +case 32 : +case 33 : +case 36 : +case 37 : +case 128 : +case 129 : +case 132 : +case 133 : +case 160 : +case 161 : +case 164 : +case 165 : +{ + P0 = I211(4, 1, 3); + P1 = I211(4, 1, 5); + P2 = I211(4, 3, 7); + P3 = I211(4, 5, 7); +} break; +case 2 : +case 34 : +case 130 : +case 162 : +{ + P0 = I31(4, 0); + P1 = I31(4, 2); + P2 = I211(4, 3, 7); + P3 = I211(4, 5, 7); +} break; +case 3 : +case 35 : +case 131 : +case 163 : +{ + P0 = I31(4, 3); + P1 = I31(4, 2); + P2 = I211(4, 3, 7); + P3 = I211(4, 5, 7); +} break; +case 6 : +case 38 : +case 134 : +case 166 : +{ + P0 = I31(4, 0); + P1 = I31(4, 5); + P2 = I211(4, 3, 7); + P3 = I211(4, 5, 7); +} break; +case 7 : +case 39 : +case 135 : +case 167 : +{ + P0 = I31(4, 3); + P1 = I31(4, 5); + P2 = I211(4, 3, 7); + P3 = I211(4, 5, 7); +} break; +case 8 : +case 12 : +case 136 : +case 140 : +{ + P0 = I31(4, 0); + P1 = I211(4, 1, 5); + P2 = I31(4, 6); + P3 = I211(4, 5, 7); +} break; +case 9 : +case 13 : +case 137 : +case 141 : +{ + P0 = I31(4, 1); + P1 = I211(4, 1, 5); + P2 = I31(4, 6); + P3 = I211(4, 5, 7); +} break; +case 10 : +case 138 : +{ + P1 = I31(4, 2); + P2 = I31(4, 6); + P3 = I211(4, 5, 7); + if (MUL) { + P0 = I31(4, 0); + } else { + P0 = I211(4, 1, 3); + } +} break; +case 11 : +case 139 : +{ + P1 = I31(4, 2); + P2 = I31(4, 6); + P3 = I211(4, 5, 7); + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } +} break; +case 14 : +case 142 : +{ + P2 = I31(4, 6); + P3 = I211(4, 5, 7); + if (MUL) { + P0 = I31(4, 0); + P1 = I31(4, 5); + } else { + P0 = I332(1, 3, 4); + P1 = I521(4, 1, 5); + } +} break; +case 15 : +case 143 : +{ + P2 = I31(4, 6); + P3 = I211(4, 5, 7); + if (MUL) { + P0 = IC(4); + P1 = I31(4, 5); + } else { + P0 = I332(1, 3, 4); + P1 = I521(4, 1, 5); + } +} break; +case 16 : +case 17 : +case 48 : +case 49 : +{ + P0 = I211(4, 1, 3); + P1 = I31(4, 2); + P2 = I211(4, 3, 7); + P3 = I31(4, 8); +} break; +case 18 : +case 50 : +{ + P0 = I31(4, 0); + P2 = I211(4, 3, 7); + P3 = I31(4, 8); + if (MUR) { + P1 = I31(4, 2); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 19 : +case 51 : +{ + P2 = I211(4, 3, 7); + P3 = I31(4, 8); + if (MUR) { + P0 = I31(4, 3); + P1 = I31(4, 2); + } else { + P0 = I521(4, 1, 3); + P1 = I332(1, 5, 4); + } +} break; +case 20 : +case 21 : +case 52 : +case 53 : +{ + P0 = I211(4, 1, 3); + P1 = I31(4, 1); + P2 = I211(4, 3, 7); + P3 = I31(4, 8); +} break; +case 22 : +case 54 : +{ + P0 = I31(4, 0); + P2 = I211(4, 3, 7); + P3 = I31(4, 8); + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 23 : +case 55 : +{ + P2 = I211(4, 3, 7); + P3 = I31(4, 8); + if (MUR) { + P0 = I31(4, 3); + P1 = IC(4); + } else { + P0 = I521(4, 1, 3); + P1 = I332(1, 5, 4); + } +} break; +case 24 : +case 66 : +{ + P0 = I31(4, 0); + P1 = I31(4, 2); + P2 = I31(4, 6); + P3 = I31(4, 8); +} break; +case 25 : +{ + P0 = I31(4, 1); + P1 = I31(4, 2); + P2 = I31(4, 6); + P3 = I31(4, 8); +} break; +case 26 : +case 31 : +case 95 : +{ + P2 = I31(4, 6); + P3 = I31(4, 8); + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 27 : +case 75 : +{ + P1 = I31(4, 2); + P2 = I31(4, 6); + P3 = I31(4, 8); + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } +} break; +case 28 : +{ + P0 = I31(4, 0); + P1 = I31(4, 1); + P2 = I31(4, 6); + P3 = I31(4, 8); +} break; +case 29 : +{ + P0 = I31(4, 1); + P1 = I31(4, 1); + P2 = I31(4, 6); + P3 = I31(4, 8); +} break; +case 30 : +case 86 : +{ + P0 = I31(4, 0); + P2 = I31(4, 6); + P3 = I31(4, 8); + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 40 : +case 44 : +case 168 : +case 172 : +{ + P0 = I31(4, 0); + P1 = I211(4, 1, 5); + P2 = I31(4, 7); + P3 = I211(4, 5, 7); +} break; +case 41 : +case 45 : +case 169 : +case 173 : +{ + P0 = I31(4, 1); + P1 = I211(4, 1, 5); + P2 = I31(4, 7); + P3 = I211(4, 5, 7); +} break; +case 42 : +case 170 : +{ + P1 = I31(4, 2); + P3 = I211(4, 5, 7); + if (MUL) { + P0 = I31(4, 0); + P2 = I31(4, 7); + } else { + P0 = I332(1, 3, 4); + P2 = I521(4, 3, 7); + } +} break; +case 43 : +case 171 : +{ + P1 = I31(4, 2); + P3 = I211(4, 5, 7); + if (MUL) { + P0 = IC(4); + P2 = I31(4, 7); + } else { + P0 = I332(1, 3, 4); + P2 = I521(4, 3, 7); + } +} break; +case 46 : +case 174 : +{ + P1 = I31(4, 5); + P2 = I31(4, 7); + P3 = I211(4, 5, 7); + if (MUL) { + P0 = I31(4, 0); + } else { + P0 = I611(4, 1, 3); + } +} break; +case 47 : +case 175 : +{ + P1 = I31(4, 5); + P2 = I31(4, 7); + P3 = I211(4, 5, 7); + if (MUL) { + P0 = IC(4); + } else { + P0 = I1411(4, 1, 3); + } +} break; +case 56 : +{ + P0 = I31(4, 0); + P1 = I31(4, 2); + P2 = I31(4, 7); + P3 = I31(4, 8); +} break; +case 57 : +{ + P0 = I31(4, 1); + P1 = I31(4, 2); + P2 = I31(4, 7); + P3 = I31(4, 8); +} break; +case 58 : +{ + P2 = I31(4, 7); + P3 = I31(4, 8); + if (MUL) { + P0 = I31(4, 0); + } else { + P0 = I611(4, 1, 3); + } + if (MUR) { + P1 = I31(4, 2); + } else { + P1 = I611(4, 1, 5); + } +} break; +case 59 : +{ + P2 = I31(4, 7); + P3 = I31(4, 8); + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } + if (MUR) { + P1 = I31(4, 2); + } else { + P1 = I611(4, 1, 5); + } +} break; +case 60 : +{ + P0 = I31(4, 0); + P1 = I31(4, 1); + P2 = I31(4, 7); + P3 = I31(4, 8); +} break; +case 61 : +{ + P0 = I31(4, 1); + P1 = I31(4, 1); + P2 = I31(4, 7); + P3 = I31(4, 8); +} break; +case 62 : +{ + P0 = I31(4, 0); + P2 = I31(4, 7); + P3 = I31(4, 8); + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 63 : +{ + P2 = I31(4, 7); + P3 = I31(4, 8); + if (MUL) { + P0 = IC(4); + } else { + P0 = I1411(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 64 : +case 65 : +case 68 : +case 69 : +{ + P0 = I211(4, 1, 3); + P1 = I211(4, 1, 5); + P2 = I31(4, 6); + P3 = I31(4, 8); +} break; +case 67 : +{ + P0 = I31(4, 3); + P1 = I31(4, 2); + P2 = I31(4, 6); + P3 = I31(4, 8); +} break; +case 70 : +{ + P0 = I31(4, 0); + P1 = I31(4, 5); + P2 = I31(4, 6); + P3 = I31(4, 8); +} break; +case 71 : +{ + P0 = I31(4, 3); + P1 = I31(4, 5); + P2 = I31(4, 6); + P3 = I31(4, 8); +} break; +case 72 : +case 76 : +{ + P0 = I31(4, 0); + P1 = I211(4, 1, 5); + P3 = I31(4, 8); + if (MDL) { + P2 = I31(4, 6); + } else { + P2 = I211(4, 3, 7); + } +} break; +case 73 : +case 77 : +{ + P1 = I211(4, 1, 5); + P3 = I31(4, 8); + if (MDL) { + P0 = I31(4, 1); + P2 = I31(4, 6); + } else { + P0 = I521(4, 3, 1); + P2 = I332(3, 7, 4); + } +} break; +case 74 : +case 107 : +case 123 : +{ + P1 = I31(4, 2); + P3 = I31(4, 8); + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } +} break; +case 78 : +{ + P1 = I31(4, 5); + P3 = I31(4, 8); + if (MDL) { + P2 = I31(4, 6); + } else { + P2 = I611(4, 3, 7); + } + if (MUL) { + P0 = I31(4, 0); + } else { + P0 = I611(4, 1, 3); + } +} break; +case 79 : +{ + P1 = I31(4, 5); + P3 = I31(4, 8); + if (MDL) { + P2 = I31(4, 6); + } else { + P2 = I611(4, 3, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } +} break; +case 80 : +case 81 : +{ + P0 = I211(4, 1, 3); + P1 = I31(4, 2); + P2 = I31(4, 6); + if (MDR) { + P3 = I31(4, 8); + } else { + P3 = I211(4, 5, 7); + } +} break; +case 82 : +case 214 : +case 222 : +{ + P0 = I31(4, 0); + P2 = I31(4, 6); + if (MDR) { + P3 = IC(4); + } else { + P3 = I211(4, 5, 7); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 83 : +{ + P0 = I31(4, 3); + P2 = I31(4, 6); + if (MDR) { + P3 = I31(4, 8); + } else { + P3 = I611(4, 5, 7); + } + if (MUR) { + P1 = I31(4, 2); + } else { + P1 = I611(4, 1, 5); + } +} break; +case 84 : +case 85 : +{ + P0 = I211(4, 1, 3); + P2 = I31(4, 6); + if (MDR) { + P1 = I31(4, 1); + P3 = I31(4, 8); + } else { + P1 = I521(4, 5, 1); + P3 = I332(5, 7, 4); + } +} break; +case 87 : +{ + P0 = I31(4, 3); + P2 = I31(4, 6); + if (MDR) { + P3 = I31(4, 8); + } else { + P3 = I611(4, 5, 7); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 88 : +case 248 : +case 250 : +{ + P0 = I31(4, 0); + P1 = I31(4, 2); + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } + if (MDR) { + P3 = IC(4); + } else { + P3 = I211(4, 5, 7); + } +} break; +case 89 : +{ + P0 = I31(4, 1); + P1 = I31(4, 2); + if (MDL) { + P2 = I31(4, 6); + } else { + P2 = I611(4, 3, 7); + } + if (MDR) { + P3 = I31(4, 8); + } else { + P3 = I611(4, 5, 7); + } +} break; +case 90 : +{ + if (MDL) { + P2 = I31(4, 6); + } else { + P2 = I611(4, 3, 7); + } + if (MDR) { + P3 = I31(4, 8); + } else { + P3 = I611(4, 5, 7); + } + if (MUL) { + P0 = I31(4, 0); + } else { + P0 = I611(4, 1, 3); + } + if (MUR) { + P1 = I31(4, 2); + } else { + P1 = I611(4, 1, 5); + } +} break; +case 91 : +{ + if (MDL) { + P2 = I31(4, 6); + } else { + P2 = I611(4, 3, 7); + } + if (MDR) { + P3 = I31(4, 8); + } else { + P3 = I611(4, 5, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } + if (MUR) { + P1 = I31(4, 2); + } else { + P1 = I611(4, 1, 5); + } +} break; +case 92 : +{ + P0 = I31(4, 0); + P1 = I31(4, 1); + if (MDL) { + P2 = I31(4, 6); + } else { + P2 = I611(4, 3, 7); + } + if (MDR) { + P3 = I31(4, 8); + } else { + P3 = I611(4, 5, 7); + } +} break; +case 93 : +{ + P0 = I31(4, 1); + P1 = I31(4, 1); + if (MDL) { + P2 = I31(4, 6); + } else { + P2 = I611(4, 3, 7); + } + if (MDR) { + P3 = I31(4, 8); + } else { + P3 = I611(4, 5, 7); + } +} break; +case 94 : +{ + if (MDL) { + P2 = I31(4, 6); + } else { + P2 = I611(4, 3, 7); + } + if (MDR) { + P3 = I31(4, 8); + } else { + P3 = I611(4, 5, 7); + } + if (MUL) { + P0 = I31(4, 0); + } else { + P0 = I611(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 96 : +case 97 : +case 100 : +case 101 : +{ + P0 = I211(4, 1, 3); + P1 = I211(4, 1, 5); + P2 = I31(4, 3); + P3 = I31(4, 8); +} break; +case 98 : +{ + P0 = I31(4, 0); + P1 = I31(4, 2); + P2 = I31(4, 3); + P3 = I31(4, 8); +} break; +case 99 : +{ + P0 = I31(4, 3); + P1 = I31(4, 2); + P2 = I31(4, 3); + P3 = I31(4, 8); +} break; +case 102 : +{ + P0 = I31(4, 0); + P1 = I31(4, 5); + P2 = I31(4, 3); + P3 = I31(4, 8); +} break; +case 103 : +{ + P0 = I31(4, 3); + P1 = I31(4, 5); + P2 = I31(4, 3); + P3 = I31(4, 8); +} break; +case 104 : +case 108 : +{ + P0 = I31(4, 0); + P1 = I211(4, 1, 5); + P3 = I31(4, 8); + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } +} break; +case 105 : +case 109 : +{ + P1 = I211(4, 1, 5); + P3 = I31(4, 8); + if (MDL) { + P0 = I31(4, 1); + P2 = IC(4); + } else { + P0 = I521(4, 3, 1); + P2 = I332(3, 7, 4); + } +} break; +case 106 : +case 120 : +{ + P0 = I31(4, 0); + P1 = I31(4, 2); + P3 = I31(4, 8); + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } +} break; +case 110 : +{ + P0 = I31(4, 0); + P1 = I31(4, 5); + P3 = I31(4, 8); + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } +} break; +case 111 : +{ + P1 = I31(4, 5); + P3 = I31(4, 8); + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I1411(4, 1, 3); + } +} break; +case 112 : +case 113 : +{ + P0 = I211(4, 1, 3); + P1 = I31(4, 2); + if (MDR) { + P2 = I31(4, 3); + P3 = I31(4, 8); + } else { + P2 = I521(4, 7, 3); + P3 = I332(5, 7, 4); + } +} break; +case 114 : +{ + P0 = I31(4, 0); + P2 = I31(4, 3); + if (MDR) { + P3 = I31(4, 8); + } else { + P3 = I611(4, 5, 7); + } + if (MUR) { + P1 = I31(4, 2); + } else { + P1 = I611(4, 1, 5); + } +} break; +case 115 : +{ + P0 = I31(4, 3); + P2 = I31(4, 3); + if (MDR) { + P3 = I31(4, 8); + } else { + P3 = I611(4, 5, 7); + } + if (MUR) { + P1 = I31(4, 2); + } else { + P1 = I611(4, 1, 5); + } +} break; +case 116 : +case 117 : +{ + P0 = I211(4, 1, 3); + P1 = I31(4, 1); + P2 = I31(4, 3); + if (MDR) { + P3 = I31(4, 8); + } else { + P3 = I611(4, 5, 7); + } +} break; +case 118 : +{ + P0 = I31(4, 0); + P2 = I31(4, 3); + P3 = I31(4, 8); + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 119 : +{ + P2 = I31(4, 3); + P3 = I31(4, 8); + if (MUR) { + P0 = I31(4, 3); + P1 = IC(4); + } else { + P0 = I521(4, 1, 3); + P1 = I332(1, 5, 4); + } +} break; +case 121 : +{ + P0 = I31(4, 1); + P1 = I31(4, 2); + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } + if (MDR) { + P3 = I31(4, 8); + } else { + P3 = I611(4, 5, 7); + } +} break; +case 122 : +{ + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } + if (MDR) { + P3 = I31(4, 8); + } else { + P3 = I611(4, 5, 7); + } + if (MUL) { + P0 = I31(4, 0); + } else { + P0 = I611(4, 1, 3); + } + if (MUR) { + P1 = I31(4, 2); + } else { + P1 = I611(4, 1, 5); + } +} break; +case 124 : +{ + P0 = I31(4, 0); + P1 = I31(4, 1); + P3 = I31(4, 8); + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } +} break; +case 125 : +{ + P1 = I31(4, 1); + P3 = I31(4, 8); + if (MDL) { + P0 = I31(4, 1); + P2 = IC(4); + } else { + P0 = I521(4, 3, 1); + P2 = I332(3, 7, 4); + } +} break; +case 126 : +{ + P0 = I31(4, 0); + P3 = I31(4, 8); + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 127 : +{ + P3 = I31(4, 8); + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I1411(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 144 : +case 145 : +case 176 : +case 177 : +{ + P0 = I211(4, 1, 3); + P1 = I31(4, 2); + P2 = I211(4, 3, 7); + P3 = I31(4, 7); +} break; +case 146 : +case 178 : +{ + P0 = I31(4, 0); + P2 = I211(4, 3, 7); + if (MUR) { + P1 = I31(4, 2); + P3 = I31(4, 7); + } else { + P1 = I332(1, 5, 4); + P3 = I521(4, 5, 7); + } +} break; +case 147 : +case 179 : +{ + P0 = I31(4, 3); + P2 = I211(4, 3, 7); + P3 = I31(4, 7); + if (MUR) { + P1 = I31(4, 2); + } else { + P1 = I611(4, 1, 5); + } +} break; +case 148 : +case 149 : +case 180 : +case 181 : +{ + P0 = I211(4, 1, 3); + P1 = I31(4, 1); + P2 = I211(4, 3, 7); + P3 = I31(4, 7); +} break; +case 150 : +case 182 : +{ + P0 = I31(4, 0); + P2 = I211(4, 3, 7); + if (MUR) { + P1 = IC(4); + P3 = I31(4, 7); + } else { + P1 = I332(1, 5, 4); + P3 = I521(4, 5, 7); + } +} break; +case 151 : +case 183 : +{ + P0 = I31(4, 3); + P2 = I211(4, 3, 7); + P3 = I31(4, 7); + if (MUR) { + P1 = IC(4); + } else { + P1 = I1411(4, 1, 5); + } +} break; +case 152 : +{ + P0 = I31(4, 0); + P1 = I31(4, 2); + P2 = I31(4, 6); + P3 = I31(4, 7); +} break; +case 153 : +{ + P0 = I31(4, 1); + P1 = I31(4, 2); + P2 = I31(4, 6); + P3 = I31(4, 7); +} break; +case 154 : +{ + P2 = I31(4, 6); + P3 = I31(4, 7); + if (MUL) { + P0 = I31(4, 0); + } else { + P0 = I611(4, 1, 3); + } + if (MUR) { + P1 = I31(4, 2); + } else { + P1 = I611(4, 1, 5); + } +} break; +case 155 : +{ + P1 = I31(4, 2); + P2 = I31(4, 6); + P3 = I31(4, 7); + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } +} break; +case 156 : +{ + P0 = I31(4, 0); + P1 = I31(4, 1); + P2 = I31(4, 6); + P3 = I31(4, 7); +} break; +case 157 : +{ + P0 = I31(4, 1); + P1 = I31(4, 1); + P2 = I31(4, 6); + P3 = I31(4, 7); +} break; +case 158 : +{ + P2 = I31(4, 6); + P3 = I31(4, 7); + if (MUL) { + P0 = I31(4, 0); + } else { + P0 = I611(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 159 : +{ + P2 = I31(4, 6); + P3 = I31(4, 7); + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I1411(4, 1, 5); + } +} break; +case 184 : +{ + P0 = I31(4, 0); + P1 = I31(4, 2); + P2 = I31(4, 7); + P3 = I31(4, 7); +} break; +case 185 : +{ + P0 = I31(4, 1); + P1 = I31(4, 2); + P2 = I31(4, 7); + P3 = I31(4, 7); +} break; +case 186 : +{ + P2 = I31(4, 7); + P3 = I31(4, 7); + if (MUL) { + P0 = I31(4, 0); + } else { + P0 = I611(4, 1, 3); + } + if (MUR) { + P1 = I31(4, 2); + } else { + P1 = I611(4, 1, 5); + } +} break; +case 187 : +{ + P1 = I31(4, 2); + P3 = I31(4, 7); + if (MUL) { + P0 = IC(4); + P2 = I31(4, 7); + } else { + P0 = I332(1, 3, 4); + P2 = I521(4, 3, 7); + } +} break; +case 188 : +{ + P0 = I31(4, 0); + P1 = I31(4, 1); + P2 = I31(4, 7); + P3 = I31(4, 7); +} break; +case 189 : +{ + P0 = I31(4, 1); + P1 = I31(4, 1); + P2 = I31(4, 7); + P3 = I31(4, 7); +} break; +case 190 : +{ + P0 = I31(4, 0); + P2 = I31(4, 7); + if (MUR) { + P1 = IC(4); + P3 = I31(4, 7); + } else { + P1 = I332(1, 5, 4); + P3 = I521(4, 5, 7); + } +} break; +case 191 : +{ + P2 = I31(4, 7); + P3 = I31(4, 7); + if (MUL) { + P0 = IC(4); + } else { + P0 = I1411(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I1411(4, 1, 5); + } +} break; +case 192 : +case 193 : +case 196 : +case 197 : +{ + P0 = I211(4, 1, 3); + P1 = I211(4, 1, 5); + P2 = I31(4, 6); + P3 = I31(4, 5); +} break; +case 194 : +{ + P0 = I31(4, 0); + P1 = I31(4, 2); + P2 = I31(4, 6); + P3 = I31(4, 5); +} break; +case 195 : +{ + P0 = I31(4, 3); + P1 = I31(4, 2); + P2 = I31(4, 6); + P3 = I31(4, 5); +} break; +case 198 : +{ + P0 = I31(4, 0); + P1 = I31(4, 5); + P2 = I31(4, 6); + P3 = I31(4, 5); +} break; +case 199 : +{ + P0 = I31(4, 3); + P1 = I31(4, 5); + P2 = I31(4, 6); + P3 = I31(4, 5); +} break; +case 200 : +case 204 : +{ + P0 = I31(4, 0); + P1 = I211(4, 1, 5); + if (MDL) { + P2 = I31(4, 6); + P3 = I31(4, 5); + } else { + P2 = I332(3, 7, 4); + P3 = I521(4, 7, 5); + } +} break; +case 201 : +case 205 : +{ + P0 = I31(4, 1); + P1 = I211(4, 1, 5); + P3 = I31(4, 5); + if (MDL) { + P2 = I31(4, 6); + } else { + P2 = I611(4, 3, 7); + } +} break; +case 202 : +{ + P1 = I31(4, 2); + P3 = I31(4, 5); + if (MDL) { + P2 = I31(4, 6); + } else { + P2 = I611(4, 3, 7); + } + if (MUL) { + P0 = I31(4, 0); + } else { + P0 = I611(4, 1, 3); + } +} break; +case 203 : +{ + P1 = I31(4, 2); + P2 = I31(4, 6); + P3 = I31(4, 5); + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } +} break; +case 206 : +{ + P1 = I31(4, 5); + P3 = I31(4, 5); + if (MDL) { + P2 = I31(4, 6); + } else { + P2 = I611(4, 3, 7); + } + if (MUL) { + P0 = I31(4, 0); + } else { + P0 = I611(4, 1, 3); + } +} break; +case 207 : +{ + P2 = I31(4, 6); + P3 = I31(4, 5); + if (MUL) { + P0 = IC(4); + P1 = I31(4, 5); + } else { + P0 = I332(1, 3, 4); + P1 = I521(4, 1, 5); + } +} break; +case 208 : +case 209 : +{ + P0 = I211(4, 1, 3); + P1 = I31(4, 2); + P2 = I31(4, 6); + if (MDR) { + P3 = IC(4); + } else { + P3 = I211(4, 5, 7); + } +} break; +case 210 : +case 216 : +{ + P0 = I31(4, 0); + P1 = I31(4, 2); + P2 = I31(4, 6); + if (MDR) { + P3 = IC(4); + } else { + P3 = I211(4, 5, 7); + } +} break; +case 211 : +{ + P0 = I31(4, 3); + P1 = I31(4, 2); + P2 = I31(4, 6); + if (MDR) { + P3 = IC(4); + } else { + P3 = I211(4, 5, 7); + } +} break; +case 212 : +case 213 : +{ + P0 = I211(4, 1, 3); + P2 = I31(4, 6); + if (MDR) { + P1 = I31(4, 1); + P3 = IC(4); + } else { + P1 = I521(4, 5, 1); + P3 = I332(5, 7, 4); + } +} break; +case 215 : +{ + P0 = I31(4, 3); + P2 = I31(4, 6); + if (MDR) { + P3 = IC(4); + } else { + P3 = I211(4, 5, 7); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I1411(4, 1, 5); + } +} break; +case 217 : +{ + P0 = I31(4, 1); + P1 = I31(4, 2); + P2 = I31(4, 6); + if (MDR) { + P3 = IC(4); + } else { + P3 = I211(4, 5, 7); + } +} break; +case 218 : +{ + if (MDL) { + P2 = I31(4, 6); + } else { + P2 = I611(4, 3, 7); + } + if (MDR) { + P3 = IC(4); + } else { + P3 = I211(4, 5, 7); + } + if (MUL) { + P0 = I31(4, 0); + } else { + P0 = I611(4, 1, 3); + } + if (MUR) { + P1 = I31(4, 2); + } else { + P1 = I611(4, 1, 5); + } +} break; +case 219 : +{ + P1 = I31(4, 2); + P2 = I31(4, 6); + if (MDR) { + P3 = IC(4); + } else { + P3 = I211(4, 5, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } +} break; +case 220 : +{ + P0 = I31(4, 0); + P1 = I31(4, 1); + if (MDL) { + P2 = I31(4, 6); + } else { + P2 = I611(4, 3, 7); + } + if (MDR) { + P3 = IC(4); + } else { + P3 = I211(4, 5, 7); + } +} break; +case 221 : +{ + P0 = I31(4, 1); + P2 = I31(4, 6); + if (MDR) { + P1 = I31(4, 1); + P3 = IC(4); + } else { + P1 = I521(4, 5, 1); + P3 = I332(5, 7, 4); + } +} break; +case 223 : +{ + P2 = I31(4, 6); + if (MDR) { + P3 = IC(4); + } else { + P3 = I211(4, 5, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I1411(4, 1, 5); + } +} break; +case 224 : +case 225 : +case 228 : +case 229 : +{ + P0 = I211(4, 1, 3); + P1 = I211(4, 1, 5); + P2 = I31(4, 3); + P3 = I31(4, 5); +} break; +case 226 : +{ + P0 = I31(4, 0); + P1 = I31(4, 2); + P2 = I31(4, 3); + P3 = I31(4, 5); +} break; +case 227 : +{ + P0 = I31(4, 3); + P1 = I31(4, 2); + P2 = I31(4, 3); + P3 = I31(4, 5); +} break; +case 230 : +{ + P0 = I31(4, 0); + P1 = I31(4, 5); + P2 = I31(4, 3); + P3 = I31(4, 5); +} break; +case 231 : +{ + P0 = I31(4, 3); + P1 = I31(4, 5); + P2 = I31(4, 3); + P3 = I31(4, 5); +} break; +case 232 : +case 236 : +{ + P0 = I31(4, 0); + P1 = I211(4, 1, 5); + if (MDL) { + P2 = IC(4); + P3 = I31(4, 5); + } else { + P2 = I332(3, 7, 4); + P3 = I521(4, 7, 5); + } +} break; +case 233 : +case 237 : +{ + P0 = I31(4, 1); + P1 = I211(4, 1, 5); + P3 = I31(4, 5); + if (MDL) { + P2 = IC(4); + } else { + P2 = I1411(4, 3, 7); + } +} break; +case 234 : +{ + P1 = I31(4, 2); + P3 = I31(4, 5); + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } + if (MUL) { + P0 = I31(4, 0); + } else { + P0 = I611(4, 1, 3); + } +} break; +case 235 : +{ + P1 = I31(4, 2); + P3 = I31(4, 5); + if (MDL) { + P2 = IC(4); + } else { + P2 = I1411(4, 3, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } +} break; +case 238 : +{ + P0 = I31(4, 0); + P1 = I31(4, 5); + if (MDL) { + P2 = IC(4); + P3 = I31(4, 5); + } else { + P2 = I332(3, 7, 4); + P3 = I521(4, 7, 5); + } +} break; +case 239 : +{ + P1 = I31(4, 5); + P3 = I31(4, 5); + if (MDL) { + P2 = IC(4); + } else { + P2 = I1411(4, 3, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I1411(4, 1, 3); + } +} break; +case 240 : +case 241 : +{ + P0 = I211(4, 1, 3); + P1 = I31(4, 2); + if (MDR) { + P2 = I31(4, 3); + P3 = IC(4); + } else { + P2 = I521(4, 7, 3); + P3 = I332(5, 7, 4); + } +} break; +case 242 : +{ + P0 = I31(4, 0); + P2 = I31(4, 3); + if (MDR) { + P3 = IC(4); + } else { + P3 = I211(4, 5, 7); + } + if (MUR) { + P1 = I31(4, 2); + } else { + P1 = I611(4, 1, 5); + } +} break; +case 243 : +{ + P0 = I31(4, 3); + P1 = I31(4, 2); + if (MDR) { + P2 = I31(4, 3); + P3 = IC(4); + } else { + P2 = I521(4, 7, 3); + P3 = I332(5, 7, 4); + } +} break; +case 244 : +case 245 : +{ + P0 = I211(4, 1, 3); + P1 = I31(4, 1); + P2 = I31(4, 3); + if (MDR) { + P3 = IC(4); + } else { + P3 = I1411(4, 5, 7); + } +} break; +case 246 : +{ + P0 = I31(4, 0); + P2 = I31(4, 3); + if (MDR) { + P3 = IC(4); + } else { + P3 = I1411(4, 5, 7); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 247 : +{ + P0 = I31(4, 3); + P2 = I31(4, 3); + if (MDR) { + P3 = IC(4); + } else { + P3 = I1411(4, 5, 7); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I1411(4, 1, 5); + } +} break; +case 249 : +{ + P0 = I31(4, 1); + P1 = I31(4, 2); + if (MDL) { + P2 = IC(4); + } else { + P2 = I1411(4, 3, 7); + } + if (MDR) { + P3 = IC(4); + } else { + P3 = I211(4, 5, 7); + } +} break; +case 251 : +{ + P1 = I31(4, 2); + if (MDL) { + P2 = IC(4); + } else { + P2 = I1411(4, 3, 7); + } + if (MDR) { + P3 = IC(4); + } else { + P3 = I211(4, 5, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } +} break; +case 252 : +{ + P0 = I31(4, 0); + P1 = I31(4, 1); + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } + if (MDR) { + P3 = IC(4); + } else { + P3 = I1411(4, 5, 7); + } +} break; +case 253 : +{ + P0 = I31(4, 1); + P1 = I31(4, 1); + if (MDL) { + P2 = IC(4); + } else { + P2 = I1411(4, 3, 7); + } + if (MDR) { + P3 = IC(4); + } else { + P3 = I1411(4, 5, 7); + } +} break; +case 254 : +{ + P0 = I31(4, 0); + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } + if (MDR) { + P3 = IC(4); + } else { + P3 = I1411(4, 5, 7); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 255 : +{ + if (MDL) { + P2 = IC(4); + } else { + P2 = I1411(4, 3, 7); + } + if (MDR) { + P3 = IC(4); + } else { + P3 = I1411(4, 5, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I1411(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I1411(4, 1, 5); + } +} break; diff --git a/src/sdl12/filter/interp.h b/src/sdl12/filter/interp.h new file mode 100644 index 000000000..e994387fb --- /dev/null +++ b/src/sdl12/filter/interp.h @@ -0,0 +1,306 @@ +/* + * This file is part of the Advance project. + * + * Copyright (C) 2003 Andrea Mazzoleni + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * In addition, as a special exception, Andrea Mazzoleni + * gives permission to link the code of this program with + * the MAME library (or with modified versions of MAME that use the + * same license as MAME), and distribute linked combinations including + * the two. You must obey the GNU General Public License in all + * respects for all of the code used other than MAME. If you modify + * this file, you may extend this exception to your version of the + * file, but you are not obligated to do so. If you do not wish to + * do so, delete this exception statement from your version. + */ + +#ifndef __INTERP_H +#define __INTERP_H + +/***************************************************************************/ +/* Basic types */ + +/***************************************************************************/ +/* interpolation */ + +static Uint32 interp_mask[2] = {0xF81F,0x07E0}; +static Uint32 interp_bits_per_pixel = 16; + +#define INTERP_16_MASK_1(v) (v & interp_mask[0]) +#define INTERP_16_MASK_2(v) (v & interp_mask[1]) + +FUNCINLINE static ATTRINLINE Uint16 interp_16_521(Uint16 p1, Uint16 p2, Uint16 p3) +{ + return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*2 + INTERP_16_MASK_1(p3)*1) / 8) + | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*2 + INTERP_16_MASK_2(p3)*1) / 8)); +} + +FUNCINLINE static ATTRINLINE Uint16 interp_16_332(Uint16 p1, Uint16 p2, Uint16 p3) +{ + return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)*2) / 8) + | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)*2) / 8)); +} + +FUNCINLINE static ATTRINLINE Uint16 interp_16_611(Uint16 p1, Uint16 p2, Uint16 p3) +{ + return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*6 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 8) + | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*6 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 8)); +} + +/* +FUNCINLINE static ATTRINLINE Uint16 interp_16_71(Uint16 p1, Uint16 p2) +{ + return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*7 + INTERP_16_MASK_1(p2)) / 8) + | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*7 + INTERP_16_MASK_2(p2)) / 8)); +} +*/ + +FUNCINLINE static ATTRINLINE Uint16 interp_16_211(Uint16 p1, Uint16 p2, Uint16 p3) +{ + return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*2 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 4) + | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*2 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 4)); +} + +/* +FUNCINLINE static ATTRINLINE Uint16 interp_16_772(Uint16 p1, Uint16 p2, Uint16 p3) +{ + return (Uint16)(INTERP_16_MASK_1(((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2))*7 + INTERP_16_MASK_1(p3)*2) / 16) + | INTERP_16_MASK_2(((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2))*7 + INTERP_16_MASK_2(p3)*2) / 16)); +} + +FUNCINLINE static ATTRINLINE Uint16 interp_16_11(Uint16 p1, Uint16 p2) +{ + return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2)) / 2) + | INTERP_16_MASK_2((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2)) / 2)); +} +*/ + +FUNCINLINE static ATTRINLINE Uint16 interp_16_31(Uint16 p1, Uint16 p2) +{ + return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)) / 4) + | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)) / 4)); +} + +FUNCINLINE static ATTRINLINE Uint16 interp_16_1411(Uint16 p1, Uint16 p2, Uint16 p3) +{ + return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*14 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 16) + | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*14 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 16)); +} + +/* +FUNCINLINE static ATTRINLINE Uint16 interp_16_431(Uint16 p1, Uint16 p2, Uint16 p3) +{ + return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*4 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)) / 8) + | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*4 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)) / 8)); +} + +FUNCINLINE static ATTRINLINE Uint16 interp_16_53(Uint16 p1, Uint16 p2) +{ + return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*3) / 8) + | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*3) / 8)); +} + +FUNCINLINE static ATTRINLINE Uint16 interp_16_151(Uint16 p1, Uint16 p2) +{ + return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*15 + INTERP_16_MASK_1(p2)) / 16) + | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*15 + INTERP_16_MASK_2(p2)) / 16)); +} + +FUNCINLINE static ATTRINLINE Uint16 interp_16_97(Uint16 p1, Uint16 p2) +{ + return (Uint16)(INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*9 + INTERP_16_MASK_1(p2)*7) / 16) + | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*9 + INTERP_16_MASK_2(p2)*7) / 16)); +} +*/ + +#define INTERP_32_MASK_1(v) (v & 0xFF00FF) +#define INTERP_32_MASK_2(v) (v & 0x00FF00) + +FUNCINLINE static ATTRINLINE Uint32 interp_32_521(Uint32 p1, Uint32 p2, Uint32 p3) +{ + return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*2 + INTERP_32_MASK_1(p3)*1) / 8) + | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*2 + INTERP_32_MASK_2(p3)*1) / 8); +} + +FUNCINLINE static ATTRINLINE Uint32 interp_32_332(Uint32 p1, Uint32 p2, Uint32 p3) +{ + return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)*2) / 8) + | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)*2) / 8); +} + +FUNCINLINE static ATTRINLINE Uint32 interp_32_211(Uint32 p1, Uint32 p2, Uint32 p3) +{ + return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*2 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 4) + | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*2 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 4); +} + +FUNCINLINE static ATTRINLINE Uint32 interp_32_611(Uint32 p1, Uint32 p2, Uint32 p3) +{ + return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*6 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 8) + | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*6 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 8); +} + +/* +FUNCINLINE static ATTRINLINE Uint32 interp_32_71(Uint32 p1, Uint32 p2) +{ + return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*7 + INTERP_32_MASK_1(p2)) / 8) + | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*7 + INTERP_32_MASK_2(p2)) / 8); +} + +FUNCINLINE static ATTRINLINE Uint32 interp_32_772(Uint32 p1, Uint32 p2, Uint32 p3) +{ + return INTERP_32_MASK_1(((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2))*7 + INTERP_32_MASK_1(p3)*2) / 16) + | INTERP_32_MASK_2(((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2))*7 + INTERP_32_MASK_2(p3)*2) / 16); +} + +FUNCINLINE static ATTRINLINE Uint32 interp_32_11(Uint32 p1, Uint32 p2) +{ + return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2)) / 2) + | INTERP_32_MASK_2((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2)) / 2); +} +*/ + +FUNCINLINE static ATTRINLINE Uint32 interp_32_31(Uint32 p1, Uint32 p2) +{ + return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)) / 4) + | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)) / 4); +} + +FUNCINLINE static ATTRINLINE Uint32 interp_32_1411(Uint32 p1, Uint32 p2, Uint32 p3) +{ + return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*14 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 16) + | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*14 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 16); +} + +/* +FUNCINLINE static ATTRINLINE Uint32 interp_32_431(Uint32 p1, Uint32 p2, Uint32 p3) +{ + return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*4 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)) / 8) + | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*4 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)) / 8); +} + +FUNCINLINE static ATTRINLINE Uint32 interp_32_53(Uint32 p1, Uint32 p2) +{ + return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*3) / 8) + | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*3) / 8); +} + +FUNCINLINE static ATTRINLINE Uint32 interp_32_151(Uint32 p1, Uint32 p2) +{ + return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*15 + INTERP_32_MASK_1(p2)) / 16) + | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*15 + INTERP_32_MASK_2(p2)) / 16); +} + +FUNCINLINE static ATTRINLINE Uint32 interp_32_97(Uint32 p1, Uint32 p2) +{ + return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*9 + INTERP_32_MASK_1(p2)*7) / 16) + | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*9 + INTERP_32_MASK_2(p2)*7) / 16); +} +*/ + +/***************************************************************************/ +/* diff */ + +#define INTERP_Y_LIMIT (0x30*4) +#define INTERP_U_LIMIT (0x07*4) +#define INTERP_V_LIMIT (0x06*8) + +static int interp_16_diff(Uint16 p1, Uint16 p2) +{ + int r, g, b; + int y, u, v; + + if (p1 == p2) + return 0; + + if (interp_bits_per_pixel == 16) { + b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3; + g = (int)((p1 & 0x7E0) - (p2 & 0x7E0)) >> 3; + r = (int)((p1 & 0xF800) - (p2 & 0xF800)) >> 8; + } else { + b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3; + g = (int)((p1 & 0x3E0) - (p2 & 0x3E0)) >> 2; + r = (int)((p1 & 0x7C00) - (p2 & 0x7C00)) >> 7; + } + + y = r + g + b; + u = r - b; + v = -r + 2*g - b; + + if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT) + return 1; + + if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT) + return 1; + + if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT) + return 1; + + return 0; +} + +static int interp_32_diff(Uint32 p1, Uint32 p2) +{ + int r, g, b; + int y, u, v; + + if ((p1 & 0xF8F8F8) == (p2 & 0xF8F8F8)) + return 0; + + b = (int)((p1 & 0xFF) - (p2 & 0xFF)); + g = (int)((p1 & 0xFF00) - (p2 & 0xFF00)) >> 8; + r = (int)((p1 & 0xFF0000) - (p2 & 0xFF0000)) >> 16; + + y = r + g + b; + u = r - b; + v = -r + 2*g - b; + + if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT) + return 1; + + if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT) + return 1; + + if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT) + return 1; + + return 0; +} + +/* +static void interp_set(Uint32 bits_per_pixel) +{ + interp_bits_per_pixel = bits_per_pixel; + + switch (bits_per_pixel) { + case 15 : + interp_mask[0] = 0x7C1F; + interp_mask[1] = 0x03E0; + break; + case 16 : + interp_mask[0] = 0xF81F; + interp_mask[1] = 0x07E0; + break; + case 32 : + interp_mask[0] = 0xFF00FF; + interp_mask[1] = 0x00FF00; + break; + } +} +*/ + +#endif diff --git a/src/sdl12/filter/lq2x.c b/src/sdl12/filter/lq2x.c new file mode 100644 index 000000000..8d06fa8cc --- /dev/null +++ b/src/sdl12/filter/lq2x.c @@ -0,0 +1,564 @@ +#include "filters.h" +#include "interp.h" + +static void hq2x_16_def(Uint16* dst0, Uint16* dst1, const Uint16* src0, const Uint16* src1, const Uint16* src2, Uint32 count) +{ + Uint32 i; + + for(i=0;i0) { + c[0] = src0[-1]; + c[3] = src1[-1]; + c[6] = src2[-1]; + } else { + c[0] = c[1]; + c[3] = c[4]; + c[6] = c[7]; + } + + if (i0) { + c[0] = src0[-1]; + c[3] = src1[-1]; + c[6] = src2[-1]; + } else { + c[0] = c[1]; + c[3] = c[4]; + c[6] = c[7]; + } + + if (i0) { + c[0] = src0[-1]; + c[3] = src1[-1]; + c[6] = src2[-1]; + } else { + c[0] = c[1]; + c[3] = c[4]; + c[6] = c[7]; + } + + if (i0) { + c[0] = src0[-1]; + c[3] = src1[-1]; + c[6] = src2[-1]; + } else { + c[0] = c[1]; + c[3] = c[4]; + c[6] = c[7]; + } + + if (i> 1); + + Uint16 *src0 = (Uint16 *)srcPtr; + Uint16 *src1 = src0 + (srcPitch >> 1); + Uint16 *src2 = src1 + (srcPitch >> 1); + int count = height-2; + + hq2x_16_def(dst0, dst1, src0, src0, src1, width); + + while(count) { + dst0 += dstPitch; + dst1 += dstPitch; + hq2x_16_def(dst0, dst1, src0, src1, src2, width); + src0 = src1; + src1 = src2; + src2 += srcPitch >> 1; + --count; + } + dst0 += dstPitch; + dst1 += dstPitch; + hq2x_16_def(dst0, dst1, src0, src1, src1, width); +} + +void hq2x32(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, + Uint32 dstPitch, int width, int height) +{ + Uint32 *dst0 = (Uint32 *)dstPtr; + Uint32 *dst1 = dst0 + (dstPitch >> 2); + + Uint32 *src0 = (Uint32 *)srcPtr; + Uint32 *src1 = src0 + (srcPitch >> 2); + Uint32 *src2 = src1 + (srcPitch >> 2); + int count = height-2; + + hq2x_32_def(dst0, dst1, src0, src0, src1, width); + + while(count) { + dst0 += dstPitch >> 1; + dst1 += dstPitch >> 1; + hq2x_32_def(dst0, dst1, src0, src1, src2, width); + src0 = src1; + src1 = src2; + src2 += srcPitch >> 2; + --count; + } + dst0 += dstPitch >> 1; + dst1 += dstPitch >> 1; + hq2x_32_def(dst0, dst1, src0, src1, src1, width); +} + +void lq2x16(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, + Uint32 dstPitch, int width, int height) +{ + Uint16 *dst0 = (Uint16 *)dstPtr; + Uint16 *dst1 = dst0 + (dstPitch >> 1); + + Uint16 *src0 = (Uint16 *)srcPtr; + Uint16 *src1 = src0 + (srcPitch >> 1); + Uint16 *src2 = src1 + (srcPitch >> 1); + int count = height-2; + + lq2x_16_def(dst0, dst1, src0, src0, src1, width); + + while(count) { + dst0 += dstPitch; + dst1 += dstPitch; + lq2x_16_def(dst0, dst1, src0, src1, src2, width); + src0 = src1; + src1 = src2; + src2 += srcPitch >> 1; + --count; + } + dst0 += dstPitch; + dst1 += dstPitch; + lq2x_16_def(dst0, dst1, src0, src1, src1, width); +} + +void lq2x32(Uint8 *srcPtr, Uint32 srcPitch, Uint8 *dstPtr, + Uint32 dstPitch, int width, int height) +{ + Uint32 *dst0 = (Uint32 *)dstPtr; + Uint32 *dst1 = dst0 + (dstPitch >> 2); + + Uint32 *src0 = (Uint32 *)srcPtr; + Uint32 *src1 = src0 + (srcPitch >> 2); + Uint32 *src2 = src1 + (srcPitch >> 2); + int count = height-2; + + lq2x_32_def(dst0, dst1, src0, src0, src1, width); + + while(count) { + dst0 += dstPitch >> 1; + dst1 += dstPitch >> 1; + lq2x_32_def(dst0, dst1, src0, src1, src2, width); + src0 = src1; + src1 = src2; + src2 += srcPitch >> 2; + --count; + } + dst0 += dstPitch >> 1; + dst1 += dstPitch >> 1; + lq2x_32_def(dst0, dst1, src0, src1, src1, width); +} + +/* +static inline void hq2x_init(Uint32 bits_per_pixel) +{ + interp_set(bits_per_pixel); +} +*/ diff --git a/src/sdl12/filter/lq2x.h b/src/sdl12/filter/lq2x.h new file mode 100644 index 000000000..094c2b5ae --- /dev/null +++ b/src/sdl12/filter/lq2x.h @@ -0,0 +1,1284 @@ +case 0 : +case 2 : +case 4 : +case 6 : +case 8 : +case 12 : +case 16 : +case 20 : +case 24 : +case 28 : +case 32 : +case 34 : +case 36 : +case 38 : +case 40 : +case 44 : +case 48 : +case 52 : +case 56 : +case 60 : +case 64 : +case 66 : +case 68 : +case 70 : +case 96 : +case 98 : +case 100 : +case 102 : +case 128 : +case 130 : +case 132 : +case 134 : +case 136 : +case 140 : +case 144 : +case 148 : +case 152 : +case 156 : +case 160 : +case 162 : +case 164 : +case 166 : +case 168 : +case 172 : +case 176 : +case 180 : +case 184 : +case 188 : +case 192 : +case 194 : +case 196 : +case 198 : +case 224 : +case 226 : +case 228 : +case 230 : +{ + P0 = IC(0); + P1 = IC(0); + P2 = IC(0); + P3 = IC(0); +} break; +case 1 : +case 5 : +case 9 : +case 13 : +case 17 : +case 21 : +case 25 : +case 29 : +case 33 : +case 37 : +case 41 : +case 45 : +case 49 : +case 53 : +case 57 : +case 61 : +case 65 : +case 69 : +case 97 : +case 101 : +case 129 : +case 133 : +case 137 : +case 141 : +case 145 : +case 149 : +case 153 : +case 157 : +case 161 : +case 165 : +case 169 : +case 173 : +case 177 : +case 181 : +case 185 : +case 189 : +case 193 : +case 197 : +case 225 : +case 229 : +{ + P0 = IC(1); + P1 = IC(1); + P2 = IC(1); + P3 = IC(1); +} break; +case 3 : +case 35 : +case 67 : +case 99 : +case 131 : +case 163 : +case 195 : +case 227 : +{ + P0 = IC(2); + P1 = IC(2); + P2 = IC(2); + P3 = IC(2); +} break; +case 7 : +case 39 : +case 71 : +case 103 : +case 135 : +case 167 : +case 199 : +case 231 : +{ + P0 = IC(3); + P1 = IC(3); + P2 = IC(3); + P3 = IC(3); +} break; +case 10 : +case 138 : +{ + P1 = IC(0); + P2 = IC(0); + P3 = IC(0); + if (MUL) { + P0 = IC(0); + } else { + P0 = I211(0, 1, 3); + } +} break; +case 11 : +case 27 : +case 75 : +case 139 : +case 155 : +case 203 : +{ + P1 = IC(2); + P2 = IC(2); + P3 = IC(2); + if (MUL) { + P0 = IC(2); + } else { + P0 = I211(2, 1, 3); + } +} break; +case 14 : +case 142 : +{ + P2 = IC(0); + P3 = IC(0); + if (MUL) { + P0 = IC(0); + P1 = IC(0); + } else { + P0 = I332(1, 3, 0); + P1 = I31(0, 1); + } +} break; +case 15 : +case 143 : +case 207 : +{ + P2 = IC(4); + P3 = IC(4); + if (MUL) { + P0 = IC(4); + P1 = IC(4); + } else { + P0 = I332(1, 3, 4); + P1 = I31(4, 1); + } +} break; +case 18 : +case 22 : +case 30 : +case 50 : +case 54 : +case 62 : +case 86 : +case 118 : +{ + P0 = IC(0); + P2 = IC(0); + P3 = IC(0); + if (MUR) { + P1 = IC(0); + } else { + P1 = I211(0, 1, 5); + } +} break; +case 19 : +case 51 : +{ + P2 = IC(2); + P3 = IC(2); + if (MUR) { + P0 = IC(2); + P1 = IC(2); + } else { + P0 = I31(2, 1); + P1 = I332(1, 5, 2); + } +} break; +case 23 : +case 55 : +case 119 : +{ + P2 = IC(3); + P3 = IC(3); + if (MUR) { + P0 = IC(3); + P1 = IC(3); + } else { + P0 = I31(3, 1); + P1 = I332(1, 5, 3); + } +} break; +case 26 : +{ + P2 = IC(0); + P3 = IC(0); + if (MUL) { + P0 = IC(0); + } else { + P0 = I211(0, 1, 3); + } + if (MUR) { + P1 = IC(0); + } else { + P1 = I211(0, 1, 5); + } +} break; +case 31 : +case 95 : +{ + P2 = IC(4); + P3 = IC(4); + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 42 : +case 170 : +{ + P1 = IC(0); + P3 = IC(0); + if (MUL) { + P0 = IC(0); + P2 = IC(0); + } else { + P0 = I332(1, 3, 0); + P2 = I31(0, 3); + } +} break; +case 43 : +case 171 : +case 187 : +{ + P1 = IC(2); + P3 = IC(2); + if (MUL) { + P0 = IC(2); + P2 = IC(2); + } else { + P0 = I332(1, 3, 2); + P2 = I31(2, 3); + } +} break; +case 46 : +case 174 : +{ + P1 = IC(0); + P2 = IC(0); + P3 = IC(0); + if (MUL) { + P0 = IC(0); + } else { + P0 = I611(0, 1, 3); + } +} break; +case 47 : +case 175 : +{ + P1 = IC(4); + P2 = IC(4); + P3 = IC(4); + if (MUL) { + P0 = IC(4); + } else { + P0 = I1411(4, 1, 3); + } +} break; +case 58 : +case 154 : +case 186 : +{ + P2 = IC(0); + P3 = IC(0); + if (MUL) { + P0 = IC(0); + } else { + P0 = I611(0, 1, 3); + } + if (MUR) { + P1 = IC(0); + } else { + P1 = I611(0, 1, 5); + } +} break; +case 59 : +{ + P2 = IC(2); + P3 = IC(2); + if (MUL) { + P0 = IC(2); + } else { + P0 = I211(2, 1, 3); + } + if (MUR) { + P1 = IC(2); + } else { + P1 = I611(2, 1, 5); + } +} break; +case 63 : +{ + P2 = IC(4); + P3 = IC(4); + if (MUL) { + P0 = IC(4); + } else { + P0 = I1411(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 72 : +case 76 : +case 104 : +case 106 : +case 108 : +case 110 : +case 120 : +case 124 : +{ + P0 = IC(0); + P1 = IC(0); + P3 = IC(0); + if (MDL) { + P2 = IC(0); + } else { + P2 = I211(0, 3, 7); + } +} break; +case 73 : +case 77 : +case 105 : +case 109 : +case 125 : +{ + P1 = IC(1); + P3 = IC(1); + if (MDL) { + P0 = IC(1); + P2 = IC(1); + } else { + P0 = I31(1, 3); + P2 = I332(3, 7, 1); + } +} break; +case 74 : +{ + P1 = IC(0); + P3 = IC(0); + if (MDL) { + P2 = IC(0); + } else { + P2 = I211(0, 3, 7); + } + if (MUL) { + P0 = IC(0); + } else { + P0 = I211(0, 1, 3); + } +} break; +case 78 : +case 202 : +case 206 : +{ + P1 = IC(0); + P3 = IC(0); + if (MDL) { + P2 = IC(0); + } else { + P2 = I611(0, 3, 7); + } + if (MUL) { + P0 = IC(0); + } else { + P0 = I611(0, 1, 3); + } +} break; +case 79 : +{ + P1 = IC(4); + P3 = IC(4); + if (MDL) { + P2 = IC(4); + } else { + P2 = I611(4, 3, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } +} break; +case 80 : +case 208 : +case 210 : +case 216 : +{ + P0 = IC(0); + P1 = IC(0); + P2 = IC(0); + if (MDR) { + P3 = IC(0); + } else { + P3 = I211(0, 5, 7); + } +} break; +case 81 : +case 209 : +case 217 : +{ + P0 = IC(1); + P1 = IC(1); + P2 = IC(1); + if (MDR) { + P3 = IC(1); + } else { + P3 = I211(1, 5, 7); + } +} break; +case 82 : +case 214 : +case 222 : +{ + P0 = IC(0); + P2 = IC(0); + if (MDR) { + P3 = IC(0); + } else { + P3 = I211(0, 5, 7); + } + if (MUR) { + P1 = IC(0); + } else { + P1 = I211(0, 1, 5); + } +} break; +case 83 : +case 115 : +{ + P0 = IC(2); + P2 = IC(2); + if (MDR) { + P3 = IC(2); + } else { + P3 = I611(2, 5, 7); + } + if (MUR) { + P1 = IC(2); + } else { + P1 = I611(2, 1, 5); + } +} break; +case 84 : +case 212 : +{ + P0 = IC(0); + P2 = IC(0); + if (MDR) { + P1 = IC(0); + P3 = IC(0); + } else { + P1 = I31(0, 5); + P3 = I332(5, 7, 0); + } +} break; +case 85 : +case 213 : +case 221 : +{ + P0 = IC(1); + P2 = IC(1); + if (MDR) { + P1 = IC(1); + P3 = IC(1); + } else { + P1 = I31(1, 5); + P3 = I332(5, 7, 1); + } +} break; +case 87 : +{ + P0 = IC(3); + P2 = IC(3); + if (MDR) { + P3 = IC(3); + } else { + P3 = I611(3, 5, 7); + } + if (MUR) { + P1 = IC(3); + } else { + P1 = I211(3, 1, 5); + } +} break; +case 88 : +case 248 : +case 250 : +{ + P0 = IC(0); + P1 = IC(0); + if (MDL) { + P2 = IC(0); + } else { + P2 = I211(0, 3, 7); + } + if (MDR) { + P3 = IC(0); + } else { + P3 = I211(0, 5, 7); + } +} break; +case 89 : +case 93 : +{ + P0 = IC(1); + P1 = IC(1); + if (MDL) { + P2 = IC(1); + } else { + P2 = I611(1, 3, 7); + } + if (MDR) { + P3 = IC(1); + } else { + P3 = I611(1, 5, 7); + } +} break; +case 90 : +{ + if (MDL) { + P2 = IC(0); + } else { + P2 = I611(0, 3, 7); + } + if (MDR) { + P3 = IC(0); + } else { + P3 = I611(0, 5, 7); + } + if (MUL) { + P0 = IC(0); + } else { + P0 = I611(0, 1, 3); + } + if (MUR) { + P1 = IC(0); + } else { + P1 = I611(0, 1, 5); + } +} break; +case 91 : +{ + if (MDL) { + P2 = IC(2); + } else { + P2 = I611(2, 3, 7); + } + if (MDR) { + P3 = IC(2); + } else { + P3 = I611(2, 5, 7); + } + if (MUL) { + P0 = IC(2); + } else { + P0 = I211(2, 1, 3); + } + if (MUR) { + P1 = IC(2); + } else { + P1 = I611(2, 1, 5); + } +} break; +case 92 : +{ + P0 = IC(0); + P1 = IC(0); + if (MDL) { + P2 = IC(0); + } else { + P2 = I611(0, 3, 7); + } + if (MDR) { + P3 = IC(0); + } else { + P3 = I611(0, 5, 7); + } +} break; +case 94 : +{ + if (MDL) { + P2 = IC(0); + } else { + P2 = I611(0, 3, 7); + } + if (MDR) { + P3 = IC(0); + } else { + P3 = I611(0, 5, 7); + } + if (MUL) { + P0 = IC(0); + } else { + P0 = I611(0, 1, 3); + } + if (MUR) { + P1 = IC(0); + } else { + P1 = I211(0, 1, 5); + } +} break; +case 107 : +case 123 : +{ + P1 = IC(2); + P3 = IC(2); + if (MDL) { + P2 = IC(2); + } else { + P2 = I211(2, 3, 7); + } + if (MUL) { + P0 = IC(2); + } else { + P0 = I211(2, 1, 3); + } +} break; +case 111 : +{ + P1 = IC(4); + P3 = IC(4); + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I1411(4, 1, 3); + } +} break; +case 112 : +case 240 : +{ + P0 = IC(0); + P1 = IC(0); + if (MDR) { + P2 = IC(0); + P3 = IC(0); + } else { + P2 = I31(0, 7); + P3 = I332(5, 7, 0); + } +} break; +case 113 : +case 241 : +{ + P0 = IC(1); + P1 = IC(1); + if (MDR) { + P2 = IC(1); + P3 = IC(1); + } else { + P2 = I31(1, 7); + P3 = I332(5, 7, 1); + } +} break; +case 114 : +{ + P0 = IC(0); + P2 = IC(0); + if (MDR) { + P3 = IC(0); + } else { + P3 = I611(0, 5, 7); + } + if (MUR) { + P1 = IC(0); + } else { + P1 = I611(0, 1, 5); + } +} break; +case 116 : +{ + P0 = IC(0); + P1 = IC(0); + P2 = IC(0); + if (MDR) { + P3 = IC(0); + } else { + P3 = I611(0, 5, 7); + } +} break; +case 117 : +{ + P0 = IC(1); + P1 = IC(1); + P2 = IC(1); + if (MDR) { + P3 = IC(1); + } else { + P3 = I611(1, 5, 7); + } +} break; +case 121 : +{ + P0 = IC(1); + P1 = IC(1); + if (MDL) { + P2 = IC(1); + } else { + P2 = I211(1, 3, 7); + } + if (MDR) { + P3 = IC(1); + } else { + P3 = I611(1, 5, 7); + } +} break; +case 122 : +{ + if (MDL) { + P2 = IC(0); + } else { + P2 = I211(0, 3, 7); + } + if (MDR) { + P3 = IC(0); + } else { + P3 = I611(0, 5, 7); + } + if (MUL) { + P0 = IC(0); + } else { + P0 = I611(0, 1, 3); + } + if (MUR) { + P1 = IC(0); + } else { + P1 = I611(0, 1, 5); + } +} break; +case 126 : +{ + P0 = IC(0); + P3 = IC(0); + if (MDL) { + P2 = IC(0); + } else { + P2 = I211(0, 3, 7); + } + if (MUR) { + P1 = IC(0); + } else { + P1 = I211(0, 1, 5); + } +} break; +case 127 : +{ + P3 = IC(4); + if (MDL) { + P2 = IC(4); + } else { + P2 = I211(4, 3, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I1411(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I211(4, 1, 5); + } +} break; +case 146 : +case 150 : +case 178 : +case 182 : +case 190 : +{ + P0 = IC(0); + P2 = IC(0); + if (MUR) { + P1 = IC(0); + P3 = IC(0); + } else { + P1 = I332(1, 5, 0); + P3 = I31(0, 5); + } +} break; +case 147 : +case 179 : +{ + P0 = IC(2); + P2 = IC(2); + P3 = IC(2); + if (MUR) { + P1 = IC(2); + } else { + P1 = I611(2, 1, 5); + } +} break; +case 151 : +case 183 : +{ + P0 = IC(3); + P2 = IC(3); + P3 = IC(3); + if (MUR) { + P1 = IC(3); + } else { + P1 = I1411(3, 1, 5); + } +} break; +case 158 : +{ + P2 = IC(0); + P3 = IC(0); + if (MUL) { + P0 = IC(0); + } else { + P0 = I611(0, 1, 3); + } + if (MUR) { + P1 = IC(0); + } else { + P1 = I211(0, 1, 5); + } +} break; +case 159 : +{ + P2 = IC(4); + P3 = IC(4); + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I1411(4, 1, 5); + } +} break; +case 191 : +{ + P2 = IC(4); + P3 = IC(4); + if (MUL) { + P0 = IC(4); + } else { + P0 = I1411(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I1411(4, 1, 5); + } +} break; +case 200 : +case 204 : +case 232 : +case 236 : +case 238 : +{ + P0 = IC(0); + P1 = IC(0); + if (MDL) { + P2 = IC(0); + P3 = IC(0); + } else { + P2 = I332(3, 7, 0); + P3 = I31(0, 7); + } +} break; +case 201 : +case 205 : +{ + P0 = IC(1); + P1 = IC(1); + P3 = IC(1); + if (MDL) { + P2 = IC(1); + } else { + P2 = I611(1, 3, 7); + } +} break; +case 211 : +{ + P0 = IC(2); + P1 = IC(2); + P2 = IC(2); + if (MDR) { + P3 = IC(2); + } else { + P3 = I211(2, 5, 7); + } +} break; +case 215 : +{ + P0 = IC(3); + P2 = IC(3); + if (MDR) { + P3 = IC(3); + } else { + P3 = I211(3, 5, 7); + } + if (MUR) { + P1 = IC(3); + } else { + P1 = I1411(3, 1, 5); + } +} break; +case 218 : +{ + if (MDL) { + P2 = IC(0); + } else { + P2 = I611(0, 3, 7); + } + if (MDR) { + P3 = IC(0); + } else { + P3 = I211(0, 5, 7); + } + if (MUL) { + P0 = IC(0); + } else { + P0 = I611(0, 1, 3); + } + if (MUR) { + P1 = IC(0); + } else { + P1 = I611(0, 1, 5); + } +} break; +case 219 : +{ + P1 = IC(2); + P2 = IC(2); + if (MDR) { + P3 = IC(2); + } else { + P3 = I211(2, 5, 7); + } + if (MUL) { + P0 = IC(2); + } else { + P0 = I211(2, 1, 3); + } +} break; +case 220 : +{ + P0 = IC(0); + P1 = IC(0); + if (MDL) { + P2 = IC(0); + } else { + P2 = I611(0, 3, 7); + } + if (MDR) { + P3 = IC(0); + } else { + P3 = I211(0, 5, 7); + } +} break; +case 223 : +{ + P2 = IC(4); + if (MDR) { + P3 = IC(4); + } else { + P3 = I211(4, 5, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I211(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I1411(4, 1, 5); + } +} break; +case 233 : +case 237 : +{ + P0 = IC(1); + P1 = IC(1); + P3 = IC(1); + if (MDL) { + P2 = IC(1); + } else { + P2 = I1411(1, 3, 7); + } +} break; +case 234 : +{ + P1 = IC(0); + P3 = IC(0); + if (MDL) { + P2 = IC(0); + } else { + P2 = I211(0, 3, 7); + } + if (MUL) { + P0 = IC(0); + } else { + P0 = I611(0, 1, 3); + } +} break; +case 235 : +{ + P1 = IC(2); + P3 = IC(2); + if (MDL) { + P2 = IC(2); + } else { + P2 = I1411(2, 3, 7); + } + if (MUL) { + P0 = IC(2); + } else { + P0 = I211(2, 1, 3); + } +} break; +case 239 : +{ + P1 = IC(4); + P3 = IC(4); + if (MDL) { + P2 = IC(4); + } else { + P2 = I1411(4, 3, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I1411(4, 1, 3); + } +} break; +case 242 : +{ + P0 = IC(0); + P2 = IC(0); + if (MDR) { + P3 = IC(0); + } else { + P3 = I211(0, 5, 7); + } + if (MUR) { + P1 = IC(0); + } else { + P1 = I611(0, 1, 5); + } +} break; +case 243 : +{ + P0 = IC(2); + P1 = IC(2); + if (MDR) { + P2 = IC(2); + P3 = IC(2); + } else { + P2 = I31(2, 7); + P3 = I332(5, 7, 2); + } +} break; +case 244 : +{ + P0 = IC(0); + P1 = IC(0); + P2 = IC(0); + if (MDR) { + P3 = IC(0); + } else { + P3 = I1411(0, 5, 7); + } +} break; +case 245 : +{ + P0 = IC(1); + P1 = IC(1); + P2 = IC(1); + if (MDR) { + P3 = IC(1); + } else { + P3 = I1411(1, 5, 7); + } +} break; +case 246 : +{ + P0 = IC(0); + P2 = IC(0); + if (MDR) { + P3 = IC(0); + } else { + P3 = I1411(0, 5, 7); + } + if (MUR) { + P1 = IC(0); + } else { + P1 = I211(0, 1, 5); + } +} break; +case 247 : +{ + P0 = IC(3); + P2 = IC(3); + if (MDR) { + P3 = IC(3); + } else { + P3 = I1411(3, 5, 7); + } + if (MUR) { + P1 = IC(3); + } else { + P1 = I1411(3, 1, 5); + } +} break; +case 249 : +{ + P0 = IC(1); + P1 = IC(1); + if (MDL) { + P2 = IC(1); + } else { + P2 = I1411(1, 3, 7); + } + if (MDR) { + P3 = IC(1); + } else { + P3 = I211(1, 5, 7); + } +} break; +case 251 : +{ + P1 = IC(2); + if (MDL) { + P2 = IC(2); + } else { + P2 = I1411(2, 3, 7); + } + if (MDR) { + P3 = IC(2); + } else { + P3 = I211(2, 5, 7); + } + if (MUL) { + P0 = IC(2); + } else { + P0 = I211(2, 1, 3); + } +} break; +case 252 : +{ + P0 = IC(0); + P1 = IC(0); + if (MDL) { + P2 = IC(0); + } else { + P2 = I211(0, 3, 7); + } + if (MDR) { + P3 = IC(0); + } else { + P3 = I1411(0, 5, 7); + } +} break; +case 253 : +{ + P0 = IC(1); + P1 = IC(1); + if (MDL) { + P2 = IC(1); + } else { + P2 = I1411(1, 3, 7); + } + if (MDR) { + P3 = IC(1); + } else { + P3 = I1411(1, 5, 7); + } +} break; +case 254 : +{ + P0 = IC(0); + if (MDL) { + P2 = IC(0); + } else { + P2 = I211(0, 3, 7); + } + if (MDR) { + P3 = IC(0); + } else { + P3 = I1411(0, 5, 7); + } + if (MUR) { + P1 = IC(0); + } else { + P1 = I211(0, 1, 5); + } +} break; +case 255 : +{ + if (MDL) { + P2 = IC(4); + } else { + P2 = I1411(4, 3, 7); + } + if (MDR) { + P3 = IC(4); + } else { + P3 = I1411(4, 5, 7); + } + if (MUL) { + P0 = IC(4); + } else { + P0 = I1411(4, 1, 3); + } + if (MUR) { + P1 = IC(4); + } else { + P1 = I1411(4, 1, 5); + } +} break; diff --git a/src/sdl12/filter/main.c b/src/sdl12/filter/main.c new file mode 100644 index 000000000..98ab1541c --- /dev/null +++ b/src/sdl12/filter/main.c @@ -0,0 +1,15 @@ +#include "filters.h" + +int main(int argc, char *argv[]) +{ + SDL_Surface *src = NULL; + SDL_Surface *dst = NULL; + src = SDL_LoadBMP("src.bmp"); //load + if(!src) return -1; //check + dst = filter_2x(src, NULL, hq2x32); //prcoess + SDL_FreeSurface(src); //free + if(!dst) return 0; //error + SDL_SaveBMP(dst, "dst.bmp"); //save + SDL_FreeSurface(dst); //free + return 1; //good +} diff --git a/src/sdl12/hwsym_sdl.c b/src/sdl12/hwsym_sdl.c new file mode 100644 index 000000000..43c71f7bf --- /dev/null +++ b/src/sdl12/hwsym_sdl.c @@ -0,0 +1,183 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1998-2000 by DooM Legacy Team. +// +// 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. + +/// \file +/// \brief Tool for dynamic referencing of hardware rendering functions +/// +/// Declaration and definition of the HW rendering +/// functions do have the same name. Originally, the +/// implementation was stored in a separate library. +/// For SDL, we need some function to return the addresses, +/// otherwise we have a conflict with the compiler. + +#include "hwsym_sdl.h" +#include "../doomdef.h" + +#ifdef _MSC_VER +#pragma warning(disable : 4214 4244) +#endif + +#ifdef SDL + +#include "SDL.h" + +#ifdef _MSC_VER +#pragma warning(default : 4214 4244) +#endif + +#if defined (_XBOX) || defined (_arch_dreamcast) || defined(GP2X) +#define NOLOADSO +#endif + +#if SDL_VERSION_ATLEAST(1,2,6) && !defined (NOLOADSO) +#include "SDL_loadso.h" // 1.2.6+ +#elif !defined (NOLOADSO) +#define NOLOADSO +#endif + +#define _CREATE_DLL_ // necessary for Unix AND Windows + +#ifdef HWRENDER +#include "../hardware/hw_drv.h" +#include "ogl_sdl.h" +#ifdef STATIC_OPENGL +#include "../hardware/r_opengl/r_opengl.h" +#endif +#endif + +#ifdef HW3SOUND +#include "../hardware/hw3dsdrv.h" +#endif + +#define GETFUNC(func) \ + else if (0 == strcmp(#func, funcName)) \ + funcPointer = &func \ +// +// +/** \brief The *hwSym function + + Stupid function to return function addresses + + \param funcName the name of the function + \param handle an object to look in(NULL for self) + + \return void +*/ +// +void *hwSym(const char *funcName,void *handle) +{ + void *funcPointer = NULL; +#ifdef HWRENDER + if (0 == strcmp("SetPalette", funcName)) + funcPointer = &OglSdlSetPalette; + GETFUNC(Init); + GETFUNC(Draw2DLine); + GETFUNC(DrawPolygon); + GETFUNC(SetBlend); + GETFUNC(ClearBuffer); + GETFUNC(SetTexture); + GETFUNC(ReadRect); + GETFUNC(GClipRect); + GETFUNC(ClearMipMapCache); + GETFUNC(SetSpecialState); + GETFUNC(GetTextureUsed); + GETFUNC(DrawMD2); + GETFUNC(DrawMD2i); + GETFUNC(SetTransform); + GETFUNC(GetRenderVersion); +#ifdef SHUFFLE + GETFUNC(PostImgRedraw); +#endif //SHUFFLE + GETFUNC(StartScreenWipe); + GETFUNC(EndScreenWipe); + GETFUNC(DoScreenWipe); + GETFUNC(DrawIntermissionBG); + GETFUNC(MakeScreenTexture); +#else //HWRENDER + if (0 == strcmp("FinishUpdate", funcName)) + return funcPointer; //&FinishUpdate; +#endif //!HWRENDER +#ifdef STATIC3DS + GETFUNC(Startup); + GETFUNC(AddSfx); + GETFUNC(AddSource); + GETFUNC(StartSource); + GETFUNC(StopSource); + GETFUNC(GetHW3DSVersion); + GETFUNC(BeginFrameUpdate); + GETFUNC(EndFrameUpdate); + GETFUNC(IsPlaying); + GETFUNC(UpdateListener); + GETFUNC(UpdateSourceParms); + GETFUNC(SetGlobalSfxVolume); + GETFUNC(SetCone); + GETFUNC(Update3DSource); + GETFUNC(ReloadSource); + GETFUNC(KillSource); + GETFUNC(Shutdown); + GETFUNC(GetHW3DSTitle); +#endif +#ifdef NOLOADSO + else + funcPointer = handle; +#else + else if (handle) + funcPointer = SDL_LoadFunction(handle,funcName); +#endif + if (!funcPointer) + I_OutputMsg("hwSym for %s: %s\n", funcName, SDL_GetError()); + return funcPointer; +} + +/** \brief The *hwOpen function + + \param hwfile Open a handle to the SO + + \return Handle to SO + + +*/ + +void *hwOpen(const char *hwfile) +{ +#ifdef NOLOADSO + (void)hwfile; + return NULL; +#else + void *tempso = NULL; + tempso = SDL_LoadObject(hwfile); + if (!tempso) I_OutputMsg("hwOpen of %s: %s\n", hwfile, SDL_GetError()); + return tempso; +#endif +} + +/** \brief The hwClose function + + \param handle Close the handle of the SO + + \return void + + +*/ + +void hwClose(void *handle) +{ +#ifdef NOLOADSO + (void)handle; +#else + SDL_UnloadObject(handle); +#endif +} +#endif diff --git a/src/sdl12/hwsym_sdl.h b/src/sdl12/hwsym_sdl.h new file mode 100644 index 000000000..7297587bf --- /dev/null +++ b/src/sdl12/hwsym_sdl.h @@ -0,0 +1,23 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1998-2000 by DooM Legacy Team. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief Tool for dynamic referencing of hardware rendering/3D sound functions + +void *hwSym(const char *funcName,void *handle); + +void *hwOpen(const char *hwfile); + +void hwClose(void *handle); diff --git a/src/sdl12/i_cdmus.c b/src/sdl12/i_cdmus.c new file mode 100644 index 000000000..adab39c90 --- /dev/null +++ b/src/sdl12/i_cdmus.c @@ -0,0 +1,588 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1998-2000 by DooM Legacy Team. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief cd music interface +/// + +#ifdef SDL + +#if defined (DC) || defined (_WIN32_WCE) || defined(GP2X) || defined(_PS3) +#define NOSDLCD +#endif + +#include +#ifndef NOSDLCD + +#ifdef _MSC_VER +#pragma warning(disable : 4214 4244) +#endif + +#include "SDL.h" + +#ifdef _MSC_VER +#pragma warning(default : 4214 4244) +#endif + +#endif + +#include "../doomtype.h" +#include "../i_sound.h" +#include "../command.h" +#include "../m_argv.h" +#include "../s_sound.h" + +#define MAX_CD_TRACKS 256 + +#ifdef _XBOX +INT32 SDL_SYS_CDInit(void) +{ + return(0); +} + +void SDL_SYS_CDQuit(void) +{ + return; +} +#endif + +UINT8 cdaudio_started = 0; // for system startup/shutdown + +consvar_t cd_volume = {"cd_volume","31",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; + +#ifndef NOSDLCD +static SDL_bool cdValid = SDL_FALSE; +static SDL_bool cdPlaying = SDL_FALSE; +static SDL_bool wasPlaying = SDL_FALSE; +static SDL_bool cdEnabled = SDL_FALSE; +static SDL_bool playLooping = SDL_FALSE; +static Uint8 playTrack = 0; +static Uint8 maxTrack = MAX_CD_TRACKS-1; +static Uint8 cdRemap[MAX_CD_TRACKS]; +static INT32 cdvolume = -1; +static SDL_CD *cdrom = NULL; +static CDstatus cdStatus = CD_ERROR; + +/************************************************************************** + * + * function: CDAudio_GetAudioDiskInfo + * + * description: + * set number of tracks if CD is available + * + **************************************************************************/ +static INT32 CDAudio_GetAudioDiskInfo(void) +{ + cdValid = SDL_FALSE; + maxTrack = 0; + + if (!cdrom) + return 0;//Alam: Lies! + + cdStatus = SDL_CDStatus(cdrom); + + if (!CD_INDRIVE(cdStatus)) + { + CONS_Printf("%s", M_GetText("No CD in drive\n")); + return -1; + } + + if (cdStatus == CD_ERROR) + { + CONS_Printf(M_GetText("CD Error: %s\n"), SDL_GetError()); + return -1; + } + + cdValid = SDL_TRUE; + maxTrack = (Uint8)cdrom->numtracks; + + return 0; +} + + +/************************************************************************** + * + * function: I_EjectCD + * + * description: + * + * + **************************************************************************/ +static void I_EjectCD(void) +{ + if (!cdrom || !cdEnabled) + return; // no cd init'd + + I_StopCD(); + + if (SDL_CDEject(cdrom)) + CONS_Printf("%s", M_GetText("CD eject failed\n")); +} + +/************************************************************************** + * + * function: Command_Cd_f + * + * description: + * handles all CD commands from the console + * + **************************************************************************/ +static void Command_Cd_f (void) +{ + const char *command; + size_t ret, n; + + if (!cdaudio_started) + return; + + if (COM_Argc() < 2) + { + CONS_Printf ("%s", M_GetText("cd [on] [off] [remap] [reset] [select]\n" + " [open] [info] [play ] [resume]\n" + " [stop] [pause] [loop ]\n")); + return; + } + + command = COM_Argv (1); + + if (!strncmp(command, "on", 2)) + { + cdEnabled = SDL_TRUE; + return; + } + + if (!strncmp(command, "off", 3)) + { + I_StopCD(); + cdEnabled = SDL_FALSE; + return; + } + + if (!strncmp(command, "select", 6)) + { + INT32 newcddrive; + newcddrive = atoi(COM_Argv(2)); + command = SDL_CDName(newcddrive); + I_StopCD(); + cdEnabled = SDL_FALSE; + SDL_CDClose(cdrom); + cdrom = SDL_CDOpen(newcddrive); + if (cdrom) + { + cdEnabled = SDL_TRUE; + CONS_Printf(M_GetText("Opened CD-ROM drive %s\n"), command ? command : COM_Argv(2)); + } + else CONS_Printf(M_GetText("Couldn't open CD-ROM drive %s: %s\n"), command ? command : COM_Argv(2), SDL_GetError()); + return; + } + + if (!strncmp(command, "remap", 5)) + { + ret = COM_Argc() - 2; + if (ret <= 0) + { + for (n = 1; n < MAX_CD_TRACKS; n++) + { + if (cdRemap[n] != n) + CONS_Printf(" %s -> %u\n", sizeu1(n), cdRemap[n]); + } + return; + } + for (n = 1; n <= ret; n++) + cdRemap[n] = (Uint8)atoi(COM_Argv (n+1)); + return; + } + + if (!strncmp(command, "reset", 5)) + { + if (!cdrom) return; + cdEnabled = SDL_TRUE; + I_StopCD(); + for (n = 0; n < MAX_CD_TRACKS; n++) + cdRemap[n] = (Uint8)n; + CDAudio_GetAudioDiskInfo(); + return; + } + + if (!cdValid) + { + if (CDAudio_GetAudioDiskInfo()==-1 && !cdValid) + { + CONS_Printf("%s", M_GetText("No CD in drive\n")); + return; + } + } + + if (!strncmp(command, "open", 4)) + { + I_EjectCD(); + cdValid = SDL_FALSE; + return; + } + + if (!strncmp(command, "info", 4)) + { + CONS_Printf(M_GetText("%u tracks\n"), maxTrack); + if (cdPlaying) + CONS_Printf(M_GetText("Currently %s track %u\n"), playLooping ? M_GetText("looping") : M_GetText("playing"), playTrack); + else if (wasPlaying) + CONS_Printf(M_GetText("Paused %s track %u\n"), playLooping ? M_GetText("looping") : M_GetText("playing"), playTrack); + CONS_Printf(M_GetText("Volume is %d\n"), cdvolume); + return; + } + + if (!strncmp(command, "play", 4)) + { + I_PlayCD((UINT8)atoi(COM_Argv (2)), SDL_FALSE); + return; + } + + if (!strncmp(command, "loop", 4)) + { + I_PlayCD((UINT8)atoi(COM_Argv (2)), true); + return; + } + + if (!strncmp(command, "stop", 4)) + { + I_StopCD(); + return; + } + if (!strncmp(command, "pause", 5)) + { + I_PauseCD(); + return; + } + + if (!strncmp(command, "resume", 6)) + { + I_ResumeCD(); + return; + } + + CONS_Printf(M_GetText("Invalid CD command \"CD %s\"\n"), COM_Argv(1)); +} +#endif + +/************************************************************************** + * + * function: StopCD + * + * description: + * + * + **************************************************************************/ +void I_StopCD(void) +{ +#ifndef NOSDLCD + if (!cdrom || !cdEnabled) + return; + + if (!(cdPlaying || wasPlaying)) + return; + + if (SDL_CDStop(cdrom)) + I_OutputMsg("cdromstop failed\n"); + + wasPlaying = SDL_FALSE; + cdPlaying = SDL_FALSE; +#endif +} + +/************************************************************************** + * + * function: PauseCD + * + * description: + * + * + **************************************************************************/ +void I_PauseCD (void) +{ +#ifndef NOSDLCD + if (!cdrom || !cdEnabled) + return; + + if (!cdPlaying) + return; + + if (SDL_CDPause(cdrom)) + I_OutputMsg("cdrompause failed\n"); + + wasPlaying = cdPlaying; + cdPlaying = SDL_FALSE; +#endif +} + +/************************************************************************** + * + * function: ResumeCD + * + * description: + * + * + **************************************************************************/ +// continue after a pause +void I_ResumeCD (void) +{ +#ifndef NOSDLCD + if (!cdrom || !cdEnabled) + return; + + if (!cdValid) + return; + + if (!wasPlaying) + return; + + if (cd_volume.value == 0) + return; + + if (SDL_CDResume(cdrom)) + I_OutputMsg("cdromresume failed\n"); + + cdPlaying = SDL_TRUE; + wasPlaying = SDL_FALSE; +#endif +} + + +/************************************************************************** + * + * function: ShutdownCD + * + * description: + * + * + **************************************************************************/ +void I_ShutdownCD (void) +{ +#ifndef NOSDLCD + if (!cdaudio_started) + return; + + I_StopCD(); + + CONS_Printf("I_ShutdownCD: "); + SDL_CDClose(cdrom); + cdrom = NULL; + cdaudio_started = false; + CONS_Printf("%s", M_GetText("shut down\n")); + SDL_QuitSubSystem(SDL_INIT_CDROM); + cdEnabled = SDL_FALSE; +#endif +} + +/************************************************************************** + * + * function: InitCD + * + * description: + * Initialize the first CD drive SDL detects and add console command 'cd' + * + **************************************************************************/ +void I_InitCD (void) +{ +#ifndef NOSDLCD + INT32 i; + + // Has been checked in d_main.c, but doesn't hurt here + if (M_CheckParm ("-nocd")) + return; + + CONS_Printf("%s", M_GetText("I_InitCD: Init CD audio\n")); + + // Initialize SDL first + if (SDL_InitSubSystem(SDL_INIT_CDROM) < 0) + { + CONS_Printf(M_GetText("Couldn't initialize SDL CDROM: %s\n"), SDL_GetError()); + return; + } + + // Open drive + cdrom = SDL_CDOpen(0); + + if (!cdrom) + { + const char *cdName = SDL_CDName(0); + if (!cdName) + CONS_Printf(M_GetText("Couldn't open CD-ROM drive %s: %s\n"), "\b", SDL_GetError()); + else + CONS_Printf(M_GetText("Couldn't open CD-ROM drive %s: %s\n"), cdName, SDL_GetError()); + //return; + } + + for (i = 0; i < MAX_CD_TRACKS; i++) + cdRemap[i] = (Uint8)i; + + cdaudio_started = true; + if (cdrom) cdEnabled = SDL_TRUE; + + if (CDAudio_GetAudioDiskInfo()==-1) + { + CONS_Printf("%s", M_GetText("No CD in drive\n")); + cdValid = SDL_FALSE; + } + + COM_AddCommand ("cd", Command_Cd_f); + + CONS_Printf("%s", M_GetText("CD audio Initialized\n")); +#endif +} + + + +// +/************************************************************************** + * + * function: UpdateCD + * + * description: + * sets CD volume (may have changed) and initiates play evey 2 seconds + * in case the song has elapsed + * + **************************************************************************/ +void I_UpdateCD (void) +{ +#ifndef NOSDLCD + static Uint32 lastchk = 0; + + if (!cdEnabled || !cdrom) + return; + + I_SetVolumeCD(cd_volume.value); + + if (cdPlaying && lastchk < SDL_GetTicks()) + { + lastchk = SDL_GetTicks() + 2000; //two seconds between chks + + if (CDAudio_GetAudioDiskInfo()==-1) + { + cdPlaying = SDL_FALSE; + return; + } + + if (cdStatus != CD_PLAYING && cdStatus != CD_PAUSED) + { + cdPlaying = SDL_FALSE; + if (playLooping) + I_PlayCD(playTrack, true); + } + } +#endif +} + + + +/************************************************************************** + * + * function: PlayCD + * + * description: + * play the requested track and set the looping flag + * pauses the CD if volume is 0 + * + **************************************************************************/ + +void I_PlayCD (UINT8 track, UINT8 looping) +{ +#ifdef NOSDLCD + (void)track; + (void)looping; +#else + if (!cdrom || !cdEnabled) + return; + + if (!cdValid) + { + CDAudio_GetAudioDiskInfo(); + if (!cdValid) + return; + } + + track = cdRemap[track]; + + if (track < 1 || track > maxTrack) + { + CONS_Printf(M_GetText("Bad track number %u.\n"), track); + return; + } + + // don't try to play a non-audio track + if (cdrom->track[track].type == SDL_DATA_TRACK) + { + CONS_Printf(M_GetText("Track %u is not audio\n"), track); + return; + } + + if (cdPlaying) + { + if (playTrack == track) + return; + I_StopCD(); + } + + if (SDL_CDPlayTracks(cdrom, track, 0, 1, 0)) + { + CONS_Printf(M_GetText("Error playing track %d: %s\n"), track, SDL_GetError()); + return; + } + + playLooping = looping; + playTrack = (Uint8)track; + cdPlaying = SDL_TRUE; + + if (cd_volume.value == 0) + I_PauseCD(); +#endif +} + + +/************************************************************************** + * + * function: SetVolumeCD + * + * description: + * SDL does not support setting the CD volume + * use pause instead and toggle between full and no music + * + **************************************************************************/ + +boolean I_SetVolumeCD (INT32 volume) +{ +#ifdef NOSDLCD + (void)volume; +#else + if (volume != cdvolume) + { + if (volume > 0 && volume < 16) + { + CV_SetValue(&cd_volume, 31); + cdvolume = 31; + I_ResumeCD(); + } + else if (volume > 15 && volume < 31) + { + CV_SetValue(&cd_volume, 0); + cdvolume = 0; + I_PauseCD(); + } + } +#endif + return false; +} + +#endif diff --git a/src/sdl12/i_main.c b/src/sdl12/i_main.c new file mode 100644 index 000000000..85abb7041 --- /dev/null +++ b/src/sdl12/i_main.c @@ -0,0 +1,247 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 1998-2000 by DooM Legacy Team. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief Main program, simply calls D_SRB2Main and D_SRB2Loop, the high level loop. + +#include "../doomdef.h" +#include "../m_argv.h" +#include "../d_main.h" +#include "../i_system.h" + +#ifdef __GNUC__ +#include +#endif + +#ifdef _WII +#include +#include +#include +#ifdef REMOTE_DEBUGGING +#include +#endif +static char wiicwd[PATH_MAX] = "sd:/"; +static char localip[16] = {0}; +static char gateway[16] = {0}; +static char netmask[16] = {0}; +#endif + +#ifdef _PSP +#include +#include +PSP_HEAP_SIZE_KB(24*1024); +PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER | PSP_THREAD_ATTR_VFPU); +PSP_MAIN_THREAD_NAME("SRB2"); +PSP_MAIN_THREAD_STACK_SIZE_KB(256); +#endif + +#ifdef SDL + +#ifdef HAVE_TTF +#include "SDL.h" +#include "i_ttf.h" +#endif + +#ifdef SDLMAIN +#include "SDL_main.h" +#elif defined(FORCESDLMAIN) +extern int SDL_main(int argc, char *argv[]); +#endif + +#ifdef LOGMESSAGES +FILE *logstream = NULL; +#endif + +#ifndef DOXYGEN +#ifndef O_TEXT +#define O_TEXT 0 +#endif + +#ifndef O_SEQUENTIAL +#define O_SEQUENTIAL 0 +#endif +#endif + +#if defined (_WIN32) && !defined (_XBOX) +#include "../win32/win_dbg.h" +typedef BOOL (WINAPI *p_IsDebuggerPresent)(VOID); +#endif + +#ifdef _arch_dreamcast +#include +KOS_INIT_FLAGS(INIT_DEFAULT +//| INIT_NET +//| INIT_MALLOCSTATS +//| INIT_QUIET +//| INIT_OCRAM +//| INIT_NO_DCLOAD +); +#endif + +#if defined (_WIN32) && !defined (_XBOX) && !defined (_WIN32_WCE) +static inline VOID MakeCodeWritable(VOID) +{ +#ifdef USEASM // Disable write-protection of code segment + DWORD OldRights; + const DWORD NewRights = PAGE_EXECUTE_READWRITE; + PBYTE pBaseOfImage = (PBYTE)GetModuleHandle(NULL); + PIMAGE_DOS_HEADER dosH =(PIMAGE_DOS_HEADER)pBaseOfImage; + PIMAGE_NT_HEADERS ntH = (PIMAGE_NT_HEADERS)(pBaseOfImage + dosH->e_lfanew); + PIMAGE_OPTIONAL_HEADER oH = (PIMAGE_OPTIONAL_HEADER) + ((PBYTE)ntH + sizeof (IMAGE_NT_SIGNATURE) + sizeof (IMAGE_FILE_HEADER)); + LPVOID pA = pBaseOfImage+oH->BaseOfCode; + SIZE_T pS = oH->SizeOfCode; +#if 1 // try to find the text section + PIMAGE_SECTION_HEADER ntS = IMAGE_FIRST_SECTION (ntH); + WORD s; + for (s = 0; s < ntH->FileHeader.NumberOfSections; s++) + { + if (memcmp (ntS[s].Name, ".text\0\0", 8) == 0) + { + pA = pBaseOfImage+ntS[s].VirtualAddress; + pS = ntS[s].Misc.VirtualSize; + break; + } + } +#endif + + if (!VirtualProtect(pA,pS,NewRights,&OldRights)) + I_Error("Could not make code writable\n"); +#endif +} +#endif + + +/** \brief The main function + + \param argc number of arg + \param *argv string table + + \return int +*/ +FUNCNORETURN +#if defined (_XBOX) && defined (__GNUC__) +void XBoxStartup() +{ + const char *logdir = NULL; + myargc = -1; + myargv = NULL; +#else +#ifdef FORCESDLMAIN +int SDL_main(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif +{ + const char *logdir = NULL; + myargc = argc; + myargv = argv; /// \todo pull out path to exe from this string +#endif + +#ifdef HAVE_TTF +#ifdef _PS3 + // apparently there is a bug in SDL_PSL1GHT which needs this to be set to work around + SDL_setenv("SDL_VIDEODRIVER", "psl1ght", 1); + I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO, SDL_SWSURFACE|SDL_DOUBLEBUF); +#elif defined(_WIN32) + I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO|SDL_INIT_AUDIO, SDL_SWSURFACE); +#else + I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO, SDL_SWSURFACE); +#endif +#endif + +#ifdef _PS3 + // initialise controllers. + //ioPadInit(7); +#endif + +// init Wii-specific stuff +#ifdef _WII + // Start network + if_config(localip, netmask, gateway, TRUE); + +#ifdef REMOTE_DEBUGGING +#if REMOTE_DEBUGGING == 0 + DEBUG_Init(GDBSTUB_DEVICE_TCP, GDBSTUB_DEF_TCPPORT); // Port 2828 +#elif REMOTE_DEBUGGING > 2 + DEBUG_Init(GDBSTUB_DEVICE_TCP, REMOTE_DEBUGGING); // Custom Port +#elif REMOTE_DEBUGGING < 0 + DEBUG_Init(GDBSTUB_DEVICE_USB, GDBSTUB_DEF_CHANNEL); // Slot 1 +#else + DEBUG_Init(GDBSTUB_DEVICE_USB, REMOTE_DEBUGGING-1); // Custom Slot +#endif +#endif + // Start FAT filesystem + fatInitDefault(); + + if (getcwd(wiicwd, PATH_MAX)) + I_PutEnv(va("HOME=%ssrb2wii", wiicwd)); +#endif + + logdir = D_Home(); + +#ifdef LOGMESSAGES +#if defined(_WIN32_WCE) || defined(GP2X) + logstream = fopen(va("%s.log",argv[0]), "a"); +#elif defined (_WII) + logstream = fopen(va("%s/srb2log.txt",logdir), "a"); +#elif defined (DEFAULTDIR) + if (logdir) + logstream = fopen(va("%s/"DEFAULTDIR"/srb2log.txt",logdir), "a"); + else +#endif + logstream = fopen("./srb2log.txt", "a"); +#endif + + //I_OutputMsg("I_StartupSystem() ...\n"); + I_StartupSystem(); +#if defined (_WIN32) && !defined (_XBOX) +#ifndef _WIN32_WCE + { + p_IsDebuggerPresent pfnIsDebuggerPresent = (p_IsDebuggerPresent)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsDebuggerPresent"); + if ((!pfnIsDebuggerPresent || !pfnIsDebuggerPresent()) +#ifdef BUGTRAP + && !InitBugTrap() +#endif + ) + { + LoadLibraryA("exchndl.dll"); + } + } +#endif + prevExceptionFilter = SetUnhandledExceptionFilter(RecordExceptionInfo); +#ifndef _WIN32_WCE + MakeCodeWritable(); +#endif +#endif + // startup SRB2 + CONS_Printf("%s", M_GetText("Setting up SRB2...\n")); + D_SRB2Main(); + CONS_Printf("%s", M_GetText("Entering main game loop...\n")); + // never return + D_SRB2Loop(); + +#ifdef BUGTRAP + // This is safe even if BT didn't start. + ShutdownBugTrap(); +#endif + + // return to OS +#ifndef __GNUC__ + return 0; +#endif +} +#endif diff --git a/src/sdl12/i_net.c b/src/sdl12/i_net.c new file mode 100644 index 000000000..c31935acf --- /dev/null +++ b/src/sdl12/i_net.c @@ -0,0 +1,442 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1993-1996 by id Software, Inc. +// Portions Copyright (C) 1998-2000 by DooM Legacy Team. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief SDL network interface + +#include "../doomdef.h" + +#include "../i_system.h" +#include "../d_event.h" +#include "../d_net.h" +#include "../m_argv.h" + +#include "../doomstat.h" + +#include "../i_net.h" + +#include "../z_zone.h" + +#include "../i_tcp.h" + +#ifdef SDL + +#ifdef HAVE_SDLNET + +#include "SDL_net.h" + +#define MAXBANS 20 + +static IPaddress clientaddress[MAXNETNODES+1]; +static IPaddress banned[MAXBANS]; + +static UDPpacket mypacket; +static UDPsocket mysocket = NULL; +static SDLNet_SocketSet myset = NULL; + +static size_t numbans = 0; +static boolean NET_bannednode[MAXNETNODES+1]; /// \note do we really need the +1? +static boolean init_SDLNet_driver = false; + +static const char *NET_AddrToStr(IPaddress* sk) +{ + static char s[22]; // 255.255.255.255:65535 + strcpy(s, SDLNet_ResolveIP(sk)); + if (sk->port != 0) strcat(s, va(":%d", sk->port)); + return s; +} + +static const char *NET_GetNodeAddress(INT32 node) +{ + if (!nodeconnected[node]) + return NULL; + return NET_AddrToStr(&clientaddress[node]); +} + +static const char *NET_GetBanAddress(size_t ban) +{ + if (ban > numbans) + return NULL; + return NET_AddrToStr(&banned[ban]); +} + +static boolean NET_cmpaddr(IPaddress* a, IPaddress* b) +{ + return (a->host == b->host && (b->port == 0 || a->port == b->port)); +} + +static boolean NET_CanGet(void) +{ + return myset?(SDLNet_CheckSockets(myset,0) == 1):false; +} + +static void NET_Get(void) +{ + INT32 mystatus; + INT32 newnode; + mypacket.len = MAXPACKETLENGTH; + if (!NET_CanGet()) + { + doomcom->remotenode = -1; // no packet + return; + } + mystatus = SDLNet_UDP_Recv(mysocket,&mypacket); + if (mystatus != -1) + { + if (mypacket.channel != -1) + { + doomcom->remotenode = mypacket.channel+1; // good packet from a game player + doomcom->datalength = mypacket.len; + return; + } + newnode = SDLNet_UDP_Bind(mysocket,-1,&mypacket.address); + if (newnode != -1) + { + size_t i; + newnode++; + M_Memcpy(&clientaddress[newnode], &mypacket.address, sizeof (IPaddress)); + DEBFILE(va("New node detected: node:%d address:%s\n", newnode, + NET_GetNodeAddress(newnode))); + doomcom->remotenode = newnode; // good packet from a game player + doomcom->datalength = mypacket.len; + for (i = 0; i < numbans; i++) + { + if (NET_cmpaddr(&mypacket.address, &banned[i])) + { + DEBFILE("This dude has been banned\n"); + NET_bannednode[newnode] = true; + break; + } + } + if (i == numbans) + NET_bannednode[newnode] = false; + return; + } + else + I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); + } + else if (mystatus == -1) + { + I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); + } + + DEBFILE("New node detected: No more free slots\n"); + doomcom->remotenode = -1; // no packet +} + +#if 0 +static boolean NET_CanSend(void) +{ + return true; +} +#endif + +static void NET_Send(void) +{ + if (!doomcom->remotenode) + return; + mypacket.len = doomcom->datalength; + if (SDLNet_UDP_Send(mysocket,doomcom->remotenode-1,&mypacket) == 0) + { + I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); + } +} + +static void NET_FreeNodenum(INT32 numnode) +{ + // can't disconnect from self :) + if (!numnode) + return; + + DEBFILE(va("Free node %d (%s)\n", numnode, NET_GetNodeAddress(numnode))); + + SDLNet_UDP_Unbind(mysocket,numnode-1); + + memset(&clientaddress[numnode], 0, sizeof (IPaddress)); +} + +static UDPsocket NET_Socket(void) +{ + UDPsocket temp = NULL; + Uint16 portnum = 0; + IPaddress tempip = {INADDR_BROADCAST,0}; + //Hurdler: I'd like to put a server and a client on the same computer + //Logan: Me too + //BP: in fact for client we can use any free port we want i have read + // in some doc that connect in udp can do it for us... + //Alam: where? + if (M_CheckParm("-clientport")) + { + if (!M_IsNextParm()) + I_Error("syntax: -clientport "); + portnum = atoi(M_GetNextParm()); + } + else + portnum = sock_port; + temp = SDLNet_UDP_Open(portnum); + if (!temp) + { + I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); + return NULL; + } + if (SDLNet_UDP_Bind(temp,BROADCASTADDR-1,&tempip) == -1) + { + I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); + SDLNet_UDP_Close(temp); + return NULL; + } + clientaddress[BROADCASTADDR].port = sock_port; + clientaddress[BROADCASTADDR].host = INADDR_BROADCAST; + + doomcom->extratics = 1; // internet is very high ping + + return temp; +} + +static void I_ShutdownSDLNetDriver(void) +{ + if (myset) SDLNet_FreeSocketSet(myset); + myset = NULL; + SDLNet_Quit(); + init_SDLNet_driver = false; +} + +static void I_InitSDLNetDriver(void) +{ + if (init_SDLNet_driver) + I_ShutdownSDLNetDriver(); + if (SDLNet_Init() == -1) + { + I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); + return; // No good! + } + D_SetDoomcom(); + mypacket.data = doomcom->data; + init_SDLNet_driver = true; +} + +static void NET_CloseSocket(void) +{ + if (mysocket) + SDLNet_UDP_Close(mysocket); + mysocket = NULL; +} + +static SINT8 NET_NetMakeNodewPort(const char *hostname, const char *port) +{ + INT32 newnode; + UINT16 portnum = sock_port; + IPaddress hostnameIP; + + // retrieve portnum from address! + if (port && !port[0]) + portnum = atoi(port); + + if (SDLNet_ResolveHost(&hostnameIP,hostname,portnum) == -1) + { + I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); + return -1; + } + newnode = SDLNet_UDP_Bind(mysocket,-1,&hostnameIP); + if (newnode == -1) + { + I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); + return newnode; + } + newnode++; + M_Memcpy(&clientaddress[newnode],&hostnameIP,sizeof (IPaddress)); + return (SINT8)newnode; +} + + +static boolean NET_OpenSocket(void) +{ + memset(clientaddress, 0, sizeof (clientaddress)); + + //I_OutputMsg("SDL_Net Code starting up\n"); + + I_NetSend = NET_Send; + I_NetGet = NET_Get; + I_NetCloseSocket = NET_CloseSocket; + I_NetFreeNodenum = NET_FreeNodenum; + I_NetMakeNodewPort = NET_NetMakeNodewPort; + + //I_NetCanSend = NET_CanSend; + + // build the socket but close it first + NET_CloseSocket(); + mysocket = NET_Socket(); + + if (!mysocket) + return false; + + // for select + myset = SDLNet_AllocSocketSet(1); + if (!myset) + { + I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); + return false; + } + if (SDLNet_UDP_AddSocket(myset,mysocket) == -1) + { + I_OutputMsg("SDL_Net: %s",SDLNet_GetError()); + return false; + } + return true; +} + +static boolean NET_Ban(INT32 node) +{ + if (numbans == MAXBANS) + return false; + + M_Memcpy(&banned[numbans], &clientaddress[node], sizeof (IPaddress)); + banned[numbans].port = 0; + numbans++; + return true; +} + +static boolean NET_SetBanAddress(const char *address, const char *mask) +{ + (void)mask; + if (bans == MAXBANS) + return false; + + if (SDLNet_ResolveHost(&banned[numbans], address, 0) == -1) + return false; + numbans++; + return true; +} + +static void NET_ClearBans(void) +{ + numbans = 0; +} +#endif + +// +// I_InitNetwork +// Only required for DOS, so this is more a dummy +// +boolean I_InitNetwork(void) +{ +#ifdef HAVE_SDLNET + char serverhostname[255]; + boolean ret = false; + SDL_version SDLcompiled; + const SDL_version *SDLlinked = SDLNet_Linked_Version(); + SDL_NET_VERSION(&SDLcompiled) + I_OutputMsg("Compiled for SDL_Net version: %d.%d.%d\n", + SDLcompiled.major, SDLcompiled.minor, SDLcompiled.patch); + I_OutputMsg("Linked with SDL_Net version: %d.%d.%d\n", + SDLlinked->major, SDLlinked->minor, SDLlinked->patch); + //if (!M_CheckParm ("-sdlnet")) + // return false; + // initilize the driver + I_InitSDLNetDriver(); + I_AddExitFunc(I_ShutdownSDLNetDriver); + if (!init_SDLNet_driver) + return false; + + if (M_CheckParm("-udpport")) + { + if (M_IsNextParm()) + sock_port = (UINT16)atoi(M_GetNextParm()); + else + sock_port = 0; + } + + // parse network game options, + if (M_CheckParm("-server") || dedicated) + { + server = true; + + // If a number of clients (i.e. nodes) is specified, the server will wait for the clients + // to connect before starting. + // If no number is specified here, the server starts with 1 client, and others can join + // in-game. + // Since Boris has implemented join in-game, there is no actual need for specifying a + // particular number here. + // FIXME: for dedicated server, numnodes needs to be set to 0 upon start +/* if (M_IsNextParm()) + doomcom->numnodes = (INT16)atoi(M_GetNextParm()); + else */if (dedicated) + doomcom->numnodes = 0; + else + doomcom->numnodes = 1; + + if (doomcom->numnodes < 0) + doomcom->numnodes = 0; + if (doomcom->numnodes > MAXNETNODES) + doomcom->numnodes = MAXNETNODES; + + // server + servernode = 0; + // FIXME: + // ??? and now ? + // server on a big modem ??? 4*isdn + net_bandwidth = 16000; + hardware_MAXPACKETLENGTH = INETPACKETLENGTH; + + ret = true; + } + else if (M_CheckParm("-connect")) + { + if (M_IsNextParm()) + strcpy(serverhostname, M_GetNextParm()); + else + serverhostname[0] = 0; // assuming server in the LAN, use broadcast to detect it + + // server address only in ip + if (serverhostname[0]) + { + COM_BufAddText("connect \""); + COM_BufAddText(serverhostname); + COM_BufAddText("\"\n"); + + // probably modem + hardware_MAXPACKETLENGTH = INETPACKETLENGTH; + } + else + { + // so we're on a LAN + COM_BufAddText("connect any\n"); + + net_bandwidth = 800000; + hardware_MAXPACKETLENGTH = MAXPACKETLENGTH; + } + } + + mypacket.maxlen = hardware_MAXPACKETLENGTH; + I_NetOpenSocket = NET_OpenSocket; + I_Ban = NET_Ban; + I_ClearBans = NET_ClearBans; + I_GetNodeAddress = NET_GetNodeAddress; + I_GetBenAddress = NET_GetBenAddress; + I_SetBanAddress = NET_SetBanAddress; + bannednode = NET_bannednode; + + return ret; +#else + if ( M_CheckParm ("-net") ) + { + I_Error("-net not supported, use -server and -connect\n" + "see docs for more\n"); + } + return false; +#endif +} +#endif diff --git a/src/sdl12/i_system.c b/src/sdl12/i_system.c new file mode 100644 index 000000000..1e03edd88 --- /dev/null +++ b/src/sdl12/i_system.c @@ -0,0 +1,3115 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1993-1996 by id Software, Inc. +// Portions Copyright (C) 1998-2000 by DooM Legacy Team. +// +// 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. +// +// Changes by Graue are in the public domain. +// +//----------------------------------------------------------------------------- +/// \file +/// \brief SRB2 system stuff for SDL + +#ifndef _WIN32_WCE +#include +#endif + +#ifdef _XBOX +#include "SRB2XBOX/xboxhelp.h" +#endif + +#if defined (_WIN32) && !defined (_XBOX) +#define RPC_NO_WINDOWS_H +#include +#include "../doomtype.h" +#ifndef _WIN32_WCE +typedef BOOL (WINAPI *p_GetDiskFreeSpaceExA)(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); +typedef BOOL (WINAPI *p_IsProcessorFeaturePresent) (DWORD); +typedef DWORD (WINAPI *p_timeGetTime) (void); +typedef UINT (WINAPI *p_timeEndPeriod) (UINT); +typedef HANDLE (WINAPI *p_OpenFileMappingA) (DWORD, BOOL, LPCSTR); +typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); +typedef HANDLE (WINAPI *p_GetCurrentProcess) (VOID); +typedef BOOL (WINAPI *p_GetProcessAffinityMask) (HANDLE, PDWORD_PTR, PDWORD_PTR); +typedef BOOL (WINAPI *p_SetProcessAffinityMask) (HANDLE, DWORD_PTR); +#endif +#endif +#include +#include +#include +#ifdef __GNUC__ +#include +#elif defined (_MSC_VER) +#include +#endif +#if defined (__unix__) || defined (UNIXCOMMON) +#include +#endif + +#ifdef _arch_dreamcast +#include +#include +#include +#include +void __set_fpscr(long); // in libgcc / kernel's startup.s? +#else +#include +#if defined (_WIN32) && !defined (_WIN32_WCE) && !defined (_XBOX) +#include +#endif +#endif + +#ifdef _MSC_VER +#pragma warning(disable : 4214 4244) +#endif + +#ifdef SDL + +#include "SDL.h" + +#ifdef HAVE_TTF +#include "i_ttf.h" +#endif + +#ifdef _MSC_VER +#pragma warning(default : 4214 4244) +#endif + +#if SDL_VERSION_ATLEAST(1,2,7) && !defined (DC) +#include "SDL_cpuinfo.h" // 1.2.7 or greater +#define HAVE_SDLCPUINFO +#endif + +#ifdef _PSP +//#include +#elif !defined(_PS3) +#if defined (__unix__) || defined(__APPLE__) || (defined (UNIXCOMMON) && !defined (_arch_dreamcast) && !defined (__HAIKU__) && !defined (_WII)) +#if defined (__linux__) +#include +#else +#include +#include +/*For meminfo*/ +#include +#ifdef FREEBSD +#include +#endif +#include +#include +#endif +#endif +#endif + +#ifndef _PS3 +#if defined (__linux__) || (defined (UNIXCOMMON) && !defined (_arch_dreamcast) && !defined (_PSP) && !defined (__HAIKU__) && !defined (_WII)) +#ifndef NOTERMIOS +#include +#include // ioctl +#define HAVE_TERMIOS +#endif +#endif +#endif + +#ifndef NOMUMBLE +#if defined (__linux__) && !defined(_PS3) // need -lrt +#include +#ifdef MAP_FAILED +#define HAVE_SHM +#endif +#include +#endif + +#if defined (_WIN32) && !defined (_WIN32_WCE) && !defined (_XBOX) +#define HAVE_MUMBLE +#define WINMUMBLE +#elif defined (HAVE_SHM) +#define HAVE_MUMBLE +#endif +#endif // NOMUMBLE + +#ifdef _WIN32_WCE +#include "SRB2CE/cehelp.h" +#endif + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +// Locations for searching the srb2.srb +#ifdef _arch_dreamcast +#define DEFAULTWADLOCATION1 "/cd" +#define DEFAULTWADLOCATION2 "/pc" +#define DEFAULTWADLOCATION3 "/pc/home/alam/srb2code/data" +#define DEFAULTSEARCHPATH1 "/cd" +#define DEFAULTSEARCHPATH2 "/pc" +//#define DEFAULTSEARCHPATH3 "/pc/home/alam/srb2code/data" +#elif defined (GP2X) +#define DEFAULTWADLOCATION1 "/mnt/sd" +#define DEFAULTWADLOCATION2 "/mnt/sd/SRB2" +#define DEFAULTWADLOCATION3 "/tmp/mnt/sd" +#define DEFAULTWADLOCATION4 "/tmp/mnt/sd/SRB2" +#define DEFAULTSEARCHPATH1 "/mnt/sd" +#define DEFAULTSEARCHPATH2 "/tmp/mnt/sd" +#elif defined (_WII) +#define NOCWD +#define NOHOME +#define NEED_SDL_GETENV +#define DEFAULTWADLOCATION1 "sd:/srb2wii" +#define DEFAULTWADLOCATION2 "usb:/srb2wii" +#define DEFAULTSEARCHPATH1 "sd:/srb2wii" +#define DEFAULTSEARCHPATH2 "usb:/srb2wii" +// PS3: TODO: this will need modification most likely +#elif defined (_PS3) +#define NOCWD +#define NOHOME +#define DEFAULTWADLOCATION1 "/dev_hdd0/game/SRB2-PS3_/USRDIR/etc" +#define DEFAULTWADLOCATION2 "/dev_usb/SRB2PS3" +#define DEFAULTSEARCHPATH1 "/dev_hdd0/game/SRB2-PS3_/USRDIR/etc" +#define DEFAULTSEARCHPATH2 "/dev_usb/SRB2PS3" +#elif defined (_PSP) +#define NOCWD +#define NOHOME +#define DEFAULTWADLOCATION1 "host0:/bin/Resources" +#define DEFAULTWADLOCATION2 "ms0:/PSP/GAME/SRB2PSP" +#define DEFAULTSEARCHPATH1 "host0:/" +#define DEFAULTSEARCHPATH2 "ms0:/PSP/GAME/SRB2PSP" +#elif defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2" +#define DEFAULTWADLOCATION2 "/usr/local/games/SRB2" +#define DEFAULTWADLOCATION3 "/usr/share/games/SRB2" +#define DEFAULTWADLOCATION4 "/usr/games/SRB2" +#define DEFAULTSEARCHPATH1 "/usr/local/games" +#define DEFAULTSEARCHPATH2 "/usr/games" +#define DEFAULTSEARCHPATH3 "/usr/local" +#elif defined (_XBOX) +#define NOCWD +#ifdef __GNUC__ +#include +#endif +#define DEFAULTWADLOCATION1 "c:\\srb2" +#define DEFAULTWADLOCATION2 "d:\\srb2" +#define DEFAULTWADLOCATION3 "e:\\srb2" +#define DEFAULTWADLOCATION4 "f:\\srb2" +#define DEFAULTWADLOCATION5 "g:\\srb2" +#define DEFAULTWADLOCATION6 "h:\\srb2" +#define DEFAULTWADLOCATION7 "i:\\srb2" +#elif defined (_WIN32_WCE) +#define NOCWD +#define NOHOME +#define DEFAULTWADLOCATION1 "\\Storage Card\\SRB2DEMO" +#define DEFAULTSEARCHPATH1 "\\Storage Card" +#elif defined (_WIN32) +#define DEFAULTWADLOCATION1 "c:\\games\\srb2" +#define DEFAULTWADLOCATION2 "\\games\\srb2" +#define DEFAULTSEARCHPATH1 "c:\\games" +#define DEFAULTSEARCHPATH2 "\\games" +#endif + +/** \brief WAD file to look for +*/ +#define WADKEYWORD1 "srb2.srb" +#define WADKEYWORD2 "srb2.wad" +/** \brief holds wad path +*/ +static char returnWadPath[256]; + +//Alam_GBC: SDL + +#include "../doomdef.h" +#include "../m_misc.h" +#include "../i_video.h" +#include "../i_sound.h" +#include "../i_system.h" +#include "../screen.h" //vid.WndParent +#include "../d_net.h" +#include "../g_game.h" +#include "../filesrch.h" +#include "endtxt.h" +#include "sdlmain.h" + +#include "../i_joy.h" + +#include "../m_argv.h" + +#ifdef MAC_ALERT +#include "macosx/mac_alert.h" +#endif + +#include "../d_main.h" + +#if !defined(NOMUMBLE) && defined(HAVE_MUMBLE) +// Mumble context string +#include "../d_clisrv.h" +#include "../byteptr.h" +#endif + +/** \brief The JoyReset function + + \param JoySet Joystick info to reset + + \return void +*/ +static void JoyReset(SDLJoyInfo_t *JoySet) +{ + if (JoySet->dev) + { +#ifdef GP2X //GP2X's SDL does an illegal free on the 1st joystick... + if (SDL_JoystickIndex(JoySet->dev) != 0) +#endif + SDL_JoystickClose(JoySet->dev); + } + JoySet->dev = NULL; + JoySet->oldjoy = -1; + JoySet->axises = JoySet->buttons = JoySet->hats = JoySet->balls = 0; + //JoySet->scale +} + +/** \brief First joystick up and running +*/ +static INT32 joystick_started = 0; + +/** \brief SDL info about joystick 1 +*/ +SDLJoyInfo_t JoyInfo; + + +/** \brief Second joystick up and running +*/ +static INT32 joystick2_started = 0; + +/** \brief SDL inof about joystick 2 +*/ +SDLJoyInfo_t JoyInfo2; + +#ifdef HAVE_TERMIOS +static INT32 fdmouse2 = -1; +static INT32 mouse2_started = 0; +#endif + +SDL_bool consolevent = SDL_FALSE; +SDL_bool framebuffer = SDL_FALSE; + +UINT8 keyboard_started = false; + +#if 0 +static void signal_handler(INT32 num) +{ + //static char msg[] = "oh no! back to reality!\r\n"; + char * sigmsg; + char sigdef[32]; + + switch (num) + { + case SIGINT: + sigmsg = "interrupt"; + break; + case SIGILL: + sigmsg = "illegal instruction - invalid function image"; + break; + case SIGFPE: + sigmsg = "floating point exception"; + break; + case SIGSEGV: + sigmsg = "segment violation"; + break; + case SIGTERM: + sigmsg = "Software termination signal from kill"; + break; +#if !(defined (__unix_) || defined (UNIXCOMMON)) + case SIGBREAK: + sigmsg = "Ctrl-Break sequence"; + break; +#endif + case SIGABRT: + sigmsg = "abnormal termination triggered by abort call"; + break; + default: + sprintf(sigdef,"signal number %d", num); + sigmsg = sigdef; + } + + I_OutputMsg("signal_handler() error: %s\n", sigmsg); + signal(num, SIG_DFL); //default signal action + raise(num); + I_Quit(); +} +#endif + +#if defined (NDEBUG) && !defined (DC) && !defined (_WIN32_WCE) +FUNCNORETURN static ATTRNORETURN void quit_handler(int num) +{ + signal(num, SIG_DFL); //default signal action + raise(num); + I_Quit(); +} +#endif + +#ifdef HAVE_TERMIOS +// TERMIOS console code from Quake3: thank you! +SDL_bool stdin_active = SDL_TRUE; + +typedef struct +{ + size_t cursor; + char buffer[256]; +} feild_t; + +feild_t tty_con; + +// when printing general stuff to stdout stderr (Sys_Printf) +// we need to disable the tty console stuff +// this increments so we can recursively disable +static INT32 ttycon_hide = 0; +// some key codes that the terminal may be using +// TTimo NOTE: I'm not sure how relevant this is +static INT32 tty_erase; +static INT32 tty_eof; + +static struct termios tty_tc; + +// ============================================================= +// tty console routines +// NOTE: if the user is editing a line when something gets printed to the early console then it won't look good +// so we provide tty_Clear and tty_Show to be called before and after a stdout or stderr output +// ============================================================= + +// flush stdin, I suspect some terminals are sending a LOT of garbage +// FIXME TTimo relevant? +#if 0 +static inline void tty_FlushIn(void) +{ + char key; + while (read(STDIN_FILENO, &key, 1)!=-1); +} +#endif + +// do a backspace +// TTimo NOTE: it seems on some terminals just sending '\b' is not enough +// so for now, in any case we send "\b \b" .. yeah well .. +// (there may be a way to find out if '\b' alone would work though) +static void tty_Back(void) +{ + char key; + ssize_t d; + key = '\b'; + d = write(STDOUT_FILENO, &key, 1); + key = ' '; + d = write(STDOUT_FILENO, &key, 1); + key = '\b'; + d = write(STDOUT_FILENO, &key, 1); + (void)d; +} + +static void tty_Clear(void) +{ + size_t i; + if (tty_con.cursor>0) + { + for (i=0; i0); + ttycon_hide--; + if (ttycon_hide == 0 && tty_con.cursor) + { + for (i=0; i 0) + { + tty_con.cursor--; + tty_con.buffer[tty_con.cursor] = '\0'; + tty_Back(); + } + ev.data1 = KEY_BACKSPACE; + } + else if (key < ' ') // check if this is a control char + { + if (key == '\n') + { + tty_Clear(); + tty_con.cursor = 0; + ev.data1 = KEY_ENTER; + } + else return; + } + else + { + // push regular character + ev.data1 = tty_con.buffer[tty_con.cursor] = key; + tty_con.cursor++; + // print the current line (this is differential) + d = write(STDOUT_FILENO, &key, 1); + } + if (ev.data1) D_PostEvent(&ev); + //tty_FlushIn(); + (void)d; +} + +#elif defined (_WIN32) && !(defined (_XBOX) || defined (_WIN32_WCE)) +static BOOL I_ReadyConsole(HANDLE ci) +{ + DWORD gotinput; + if (ci == INVALID_HANDLE_VALUE) return FALSE; + if (WaitForSingleObject(ci,0) != WAIT_OBJECT_0) return FALSE; + if (GetFileType(ci) != FILE_TYPE_CHAR) return FALSE; + if (!GetConsoleMode(ci, &gotinput)) return FALSE; + return (GetNumberOfConsoleInputEvents(ci, &gotinput) && gotinput); +} + +static boolean entering_con_command = false; + +void I_GetConsoleEvents(void) +{ + event_t ev = {0,0,0,0}; + HANDLE ci = GetStdHandle(STD_INPUT_HANDLE); + HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO CSBI; + INPUT_RECORD input; + DWORD t; + + while (I_ReadyConsole(ci) && ReadConsoleInput(ci, &input, 1, &t) && t) + { + memset(&ev,0x00,sizeof (ev)); + switch (input.EventType) + { + case KEY_EVENT: + if (input.Event.KeyEvent.bKeyDown) + { + ev.type = ev_console; + entering_con_command = true; + switch (input.Event.KeyEvent.wVirtualKeyCode) + { + case VK_ESCAPE: + case VK_TAB: + ev.data1 = KEY_NULL; + break; + case VK_SHIFT: + ev.data1 = KEY_LSHIFT; + break; + case VK_RETURN: + entering_con_command = false; + // Fall through. + default: + ev.data1 = MapVirtualKey(input.Event.KeyEvent.wVirtualKeyCode,2); // convert in to char + } + if (co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &t)) + { + if (ev.data1 && ev.data1 != KEY_LSHIFT && ev.data1 != KEY_RSHIFT) + { +#ifdef _UNICODE + WriteConsole(co, &input.Event.KeyEvent.uChar.UnicodeChar, 1, &t, NULL); +#else + WriteConsole(co, &input.Event.KeyEvent.uChar.AsciiChar, 1 , &t, NULL); +#endif + } + if (input.Event.KeyEvent.wVirtualKeyCode == VK_BACK + && GetConsoleScreenBufferInfo(co,&CSBI)) + { + WriteConsoleOutputCharacterA(co, " ",1, CSBI.dwCursorPosition, &t); + } + } + } + else + { + ev.type = ev_keyup; + switch (input.Event.KeyEvent.wVirtualKeyCode) + { + case VK_SHIFT: + ev.data1 = KEY_LSHIFT; + break; + default: + break; + } + } + if (ev.data1) D_PostEvent(&ev); + break; + case MOUSE_EVENT: + case WINDOW_BUFFER_SIZE_EVENT: + case MENU_EVENT: + case FOCUS_EVENT: + break; + } + } +} + +static void I_StartupConsole(void) +{ + HANDLE ci, co; + const INT32 ded = M_CheckParm("-dedicated"); +#ifdef SDLMAIN + BOOL gotConsole = FALSE; + if (M_CheckParm("-console") || ded) + gotConsole = AllocConsole(); +#else + BOOL gotConsole = TRUE; + if (M_CheckParm("-detachconsole")) + { + FreeConsole(); + gotConsole = AllocConsole(); + } +#ifdef _DEBUG + else if (M_CheckParm("-noconsole") && !ded) +#else + else if (!M_CheckParm("-console") && !ded) +#endif + { + FreeConsole(); + gotConsole = FALSE; + } +#endif + + if (gotConsole) + { + SetConsoleTitleA("SRB2 Console"); + consolevent = SDL_TRUE; + } + + //Let get the real console HANDLE, because Mingw's Bash is bad! + ci = CreateFile(TEXT("CONIN$") , GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + co = CreateFile(TEXT("CONOUT$"), GENERIC_WRITE|GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (ci != INVALID_HANDLE_VALUE) + { + const DWORD CM = ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT; + SetStdHandle(STD_INPUT_HANDLE, ci); + if (GetFileType(ci) == FILE_TYPE_CHAR) + SetConsoleMode(ci, CM); //default mode but no ENABLE_MOUSE_INPUT + } + if (co != INVALID_HANDLE_VALUE) + { + SetStdHandle(STD_OUTPUT_HANDLE, co); + SetStdHandle(STD_ERROR_HANDLE, co); + } +} +static inline void I_ShutdownConsole(void){} +#else +void I_GetConsoleEvents(void){} +static inline void I_StartupConsole(void) +{ +#ifdef _arch_dreamcast + char title[] = "SRB2 for Dreamcast!\n"; + __set_fpscr(0x00040000); /* ignore FPU underflow */ + //printf("\nHello world!\n\n"); + pvr_init_defaults(); + conio_init(CONIO_TTY_PVR, CONIO_INPUT_LINE); + conio_set_theme(CONIO_THEME_MATRIX); + conio_clear(); + conio_putstr(title); + //printf("\nHello world!\n\n"); +#endif +#ifdef _DEBUG + consolevent = !M_CheckParm("-noconsole"); +#else + consolevent = M_CheckParm("-console"); +#endif + + framebuffer = M_CheckParm("-framebuffer"); + + if (framebuffer) + consolevent = SDL_FALSE; +} +static inline void I_ShutdownConsole(void){} +#endif + +// +// StartupKeyboard +// +void I_StartupKeyboard (void) +{ +#if defined (NDEBUG) && !defined (DC) +#ifdef SIGILL +// signal(SIGILL , signal_handler); +#endif +#ifdef SIGINT + signal(SIGINT , quit_handler); +#endif +#ifdef SIGSEGV +// signal(SIGSEGV , signal_handler); +#endif +#ifdef SIGBREAK + signal(SIGBREAK , quit_handler); +#endif +#ifdef SIGABRT +// signal(SIGABRT , signal_handler); +#endif +#ifdef SIGTERM + signal(SIGTERM , quit_handler); +#endif +#endif +} + +// +//I_OutputMsg +// +void I_OutputMsg(const char *fmt, ...) +{ + size_t len; + XBOXSTATIC char txt[8192]; + va_list argptr; + +#ifdef _arch_dreamcast + if (!keyboard_started) conio_printf(fmt); +#endif + + va_start(argptr,fmt); + vsprintf(txt, fmt, argptr); + va_end(argptr); + +#ifdef HAVE_TTF + if (TTF_WasInit()) I_TTFDrawText(currentfont, solid, DEFAULTFONTFGR, DEFAULTFONTFGG, DEFAULTFONTFGB, DEFAULTFONTFGA, + DEFAULTFONTBGR, DEFAULTFONTBGG, DEFAULTFONTBGB, DEFAULTFONTBGA, txt); +#endif + +#if defined (_WIN32) && !defined (_XBOX) && defined (_MSC_VER) + OutputDebugStringA(txt); +#endif + + len = strlen(txt); + +#ifdef LOGMESSAGES + if (logstream) + { + size_t d = fwrite(txt, len, 1, logstream); + fflush(logstream); + (void)d; + } +#endif + +#if defined (_WIN32) && !defined (_XBOX) && !defined(_WIN32_WCE) +#ifdef DEBUGFILE + if (debugfile != stderr) +#endif + { + HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD bytesWritten; + + if (co == INVALID_HANDLE_VALUE) + return; + + if (GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &bytesWritten)) + { + static COORD coordNextWrite = {0,0}; + LPVOID oldLines = NULL; + INT oldLength; + CONSOLE_SCREEN_BUFFER_INFO csbi; + + // Save the lines that we're going to obliterate. + GetConsoleScreenBufferInfo(co, &csbi); + oldLength = csbi.dwSize.X * (csbi.dwCursorPosition.Y - coordNextWrite.Y) + csbi.dwCursorPosition.X - coordNextWrite.X; + + if (oldLength > 0) + { + LPVOID blank = malloc(oldLength); + if (!blank) return; + memset(blank, ' ', oldLength); // Blank out. + oldLines = malloc(oldLength*sizeof(TCHAR)); + if (!oldLines) + { + free(blank); + return; + } + + ReadConsoleOutputCharacter(co, oldLines, oldLength, coordNextWrite, &bytesWritten); + + // Move to where we what to print - which is where we would've been, + // had console input not been in the way, + SetConsoleCursorPosition(co, coordNextWrite); + + WriteConsoleA(co, blank, oldLength, &bytesWritten, NULL); + free(blank); + + // And back to where we want to print again. + SetConsoleCursorPosition(co, coordNextWrite); + } + + // Actually write the string now! + WriteConsoleA(co, txt, (DWORD)len, &bytesWritten, NULL); + + // Next time, output where we left off. + GetConsoleScreenBufferInfo(co, &csbi); + coordNextWrite = csbi.dwCursorPosition; + + // Restore what was overwritten. + if (oldLines && entering_con_command) + WriteConsole(co, oldLines, oldLength, &bytesWritten, NULL); + if (oldLines) free(oldLines); + } + else // Redirected to a file. + WriteFile(co, txt, (DWORD)len, &bytesWritten, NULL); + } +#else +#ifdef HAVE_TERMIOS + if (consolevent) + { + tty_Hide(); + } +#endif + + if (!framebuffer) + fprintf(stderr, "%s", txt); +#ifdef HAVE_TERMIOS + if (consolevent) + { + tty_Show(); + } +#endif + + // 2004-03-03 AJR Since not all messages end in newline, some were getting displayed late. + if (!framebuffer) + fflush(stderr); + +#endif +} + +// +// I_GetKey +// +INT32 I_GetKey (void) +{ + // Warning: I_GetKey empties the event queue till next keypress + event_t *ev; + INT32 rc = 0; + + // return the first keypress from the event queue + for (; eventtail != eventhead; eventtail = (eventtail+1)&(MAXEVENTS-1)) + { + ev = &events[eventtail]; + if (ev->type == ev_keydown || ev->type == ev_console) + { + rc = ev->data1; + continue; + } + } + + return rc; +} + +// +// I_JoyScale +// +void I_JoyScale(void) +{ +#ifdef GP2X + if (JoyInfo.dev && SDL_JoystickIndex(JoyInfo.dev) == 0) + Joystick.bGamepadStyle = true; + else +#endif + Joystick.bGamepadStyle = cv_joyscale.value==0; + JoyInfo.scale = Joystick.bGamepadStyle?1:cv_joyscale.value; +} + +void I_JoyScale2(void) +{ +#ifdef GP2X + if (JoyInfo2.dev && SDL_JoystickIndex(JoyInfo2.dev) == 0) + Joystick.bGamepadStyle = true; + else +#endif + Joystick2.bGamepadStyle = cv_joyscale2.value==0; + JoyInfo2.scale = Joystick2.bGamepadStyle?1:cv_joyscale2.value; +} + +/** \brief Joystick 1 buttons states +*/ +static UINT64 lastjoybuttons = 0; + +/** \brief Joystick 1 hats state +*/ +static UINT64 lastjoyhats = 0; + +/** \brief Shuts down joystick 1 + + + \return void + + +*/ +static void I_ShutdownJoystick(void) +{ + INT32 i; + event_t event; + event.type=ev_keyup; + event.data2 = 0; + event.data3 = 0; + + lastjoybuttons = lastjoyhats = 0; + + // emulate the up of all joystick buttons + for (i=0;i= 0; i--) + { + joybuttons <<= 1; + if (SDL_JoystickGetButton(JoyInfo.dev,i)) + joybuttons |= 1; + } + + if (joybuttons != lastjoybuttons) + { + INT64 j = 1; // keep only bits that changed since last time + INT64 newbuttons = joybuttons ^ lastjoybuttons; + lastjoybuttons = joybuttons; + + for (i = 0; i < JOYBUTTONS; i++, j <<= 1) + { + if (newbuttons & j) // button changed state? + { + if (joybuttons & j) + event.type = ev_keydown; + else + event.type = ev_keyup; +#ifdef _PSP + if (i == 12) + event.data1 = KEY_ESCAPE; + else +#endif + event.data1 = KEY_JOY1 + i; + D_PostEvent(&event); + } + } + } +#endif + + for (i = JoyInfo.hats - 1; i >= 0; i--) + { + Uint8 hat = SDL_JoystickGetHat(JoyInfo.dev, i); + + if (hat & SDL_HAT_UP ) joyhats|=(UINT64)0x1<<(0 + 4*i); + if (hat & SDL_HAT_DOWN ) joyhats|=(UINT64)0x1<<(1 + 4*i); + if (hat & SDL_HAT_LEFT ) joyhats|=(UINT64)0x1<<(2 + 4*i); + if (hat & SDL_HAT_RIGHT) joyhats|=(UINT64)0x1<<(3 + 4*i); + } + + if (joyhats != lastjoyhats) + { + INT64 j = 1; // keep only bits that changed since last time + INT64 newhats = joyhats ^ lastjoyhats; + lastjoyhats = joyhats; + + for (i = 0; i < JOYHATS*4; i++, j <<= 1) + { + if (newhats & j) // hat changed state? + { + if (joyhats & j) + event.type = ev_keydown; + else + event.type = ev_keyup; + event.data1 = KEY_HAT1 + i; + D_PostEvent(&event); + } + } + } + +#if 0 + // send joystick axis positions + event.type = ev_joystick; + + for (i = JOYAXISSET - 1; i >= 0; i--) + { + event.data1 = i; + if (i*2 + 1 <= JoyInfo.axises) + axisx = SDL_JoystickGetAxis(JoyInfo.dev, i*2 + 0); + else axisx = 0; + if (i*2 + 2 <= JoyInfo.axises) + axisy = SDL_JoystickGetAxis(JoyInfo.dev, i*2 + 1); + else axisy = 0; + +#ifdef _arch_dreamcast // -128 to 127 + axisx = axisx*8; + axisy = axisy*8; +#else // -32768 to 32767 + axisx = axisx/32; + axisy = axisy/32; +#endif + + if (Joystick.bGamepadStyle) + { + // gamepad control type, on or off, live or die + if (axisx < -(JOYAXISRANGE/2)) + event.data2 = -1; + else if (axisx > (JOYAXISRANGE/2)) + event.data2 = 1; + else event.data2 = 0; + if (axisy < -(JOYAXISRANGE/2)) + event.data3 = -1; + else if (axisy > (JOYAXISRANGE/2)) + event.data3 = 1; + else event.data3 = 0; + } + else + { + + axisx = JoyInfo.scale?((axisx/JoyInfo.scale)*JoyInfo.scale):axisx; + axisy = JoyInfo.scale?((axisy/JoyInfo.scale)*JoyInfo.scale):axisy; + +#ifdef SDL_JDEADZONE + if (-SDL_JDEADZONE <= axisx && axisx <= SDL_JDEADZONE) axisx = 0; + if (-SDL_JDEADZONE <= axisy && axisy <= SDL_JDEADZONE) axisy = 0; +#endif + + // analog control style , just send the raw data + event.data2 = axisx; // x axis + event.data3 = axisy; // y axis + } + D_PostEvent(&event); + } +#endif +} + +/** \brief Open joystick handle + + \param fname name of joystick + + \return axises + + +*/ +static int joy_open(const char *fname) +{ + int joyindex = atoi(fname); + int num_joy = 0; + int i; + + if (joystick_started == 0 && joystick2_started == 0) + { + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) + { + CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError()); + return -1; + } + else + { + num_joy = SDL_NumJoysticks(); + } + + if (num_joy < joyindex) + { + CONS_Printf(M_GetText("Cannot use joystick #%d/(%s), it doesn't exist\n"),joyindex,fname); + for (i = 0; i < num_joy; i++) + CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickName(i)); + I_ShutdownJoystick(); + return -1; + } + } + else + { + JoyReset(&JoyInfo); + //I_ShutdownJoystick(); + //joy_open(fname); + } + + num_joy = SDL_NumJoysticks(); + + if (joyindex <= 0 || num_joy == 0 || JoyInfo.oldjoy == joyindex) + { +// I_OutputMsg("Unable to use that joystick #(%s), non-number\n",fname); + if (num_joy != 0) + { + CONS_Printf(M_GetText("Found %d joysticks on this system\n"), num_joy); + for (i = 0; i < num_joy; i++) + CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickName(i)); + } + else + CONS_Printf("%s", M_GetText("Found no joysticks on this system\n")); + if (joyindex <= 0 || num_joy == 0) return 0; + } + + JoyInfo.dev = SDL_JoystickOpen(joyindex-1); + CONS_Printf(M_GetText("Joystick: %s\n"), SDL_JoystickName(joyindex-1)); + + if (JoyInfo.dev == NULL) + { + CONS_Printf(M_GetText("Couldn't open joystick: %s\n"), SDL_GetError()); + I_ShutdownJoystick(); + return -1; + } + else + { + JoyInfo.axises = SDL_JoystickNumAxes(JoyInfo.dev); + if (JoyInfo.axises > JOYAXISSET*2) + JoyInfo.axises = JOYAXISSET*2; +/* if (joyaxes<2) + { + I_OutputMsg("Not enought axes?\n"); + I_ShutdownJoystick(); + return 0; + }*/ + + JoyInfo.buttons = SDL_JoystickNumButtons(JoyInfo.dev); + if (JoyInfo.buttons > JOYBUTTONS) + JoyInfo.buttons = JOYBUTTONS; + +#ifdef DC + JoyInfo.hats = 0; +#else + JoyInfo.hats = SDL_JoystickNumHats(JoyInfo.dev); + if (JoyInfo.hats > JOYHATS) + JoyInfo.hats = JOYHATS; + + JoyInfo.balls = SDL_JoystickNumBalls(JoyInfo.dev); +#endif + + //Joystick.bGamepadStyle = !stricmp(SDL_JoystickName(SDL_JoystickIndex(JoyInfo.dev)), "pad"); + + return JoyInfo.axises; + } +} + +//Joystick2 + +/** \brief Joystick 2 buttons states +*/ +static UINT64 lastjoy2buttons = 0; + +/** \brief Joystick 2 hats state +*/ +static UINT64 lastjoy2hats = 0; + +/** \brief Shuts down joystick 2 + + + \return void +*/ +static void I_ShutdownJoystick2(void) +{ + INT32 i; + event_t event; + event.type = ev_keyup; + event.data2 = 0; + event.data3 = 0; + + lastjoy2buttons = lastjoy2hats = 0; + + // emulate the up of all joystick buttons + for (i = 0; i < JOYBUTTONS; i++) + { + event.data1 = KEY_2JOY1 + i; + D_PostEvent(&event); + } + + // emulate the up of all joystick hats + for (i = 0; i < JOYHATS*4; i++) + { + event.data1 = KEY_2HAT1 + i; + D_PostEvent(&event); + } + + // reset joystick position + event.type = ev_joystick2; + for (i = 0; i < JOYAXISSET; i++) + { + event.data1 = i; + D_PostEvent(&event); + } + + JoyReset(&JoyInfo2); + if (!joystick_started && !joystick2_started && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) + { + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + if (cv_usejoystick2.value == 0) + { + DEBFILE("I_Joystick2: SDL's Joystick system has been shutdown\n"); + } + } +} + +void I_GetJoystick2Events(void) +{ + static event_t event = {0,0,0,0}; + INT32 i = 0; + UINT64 joyhats = 0; +#if 0 + INT64 joybuttons = 0; + INT32 axisx, axisy; +#endif + + if (!joystick2_started) + return; + + if (!JoyInfo2.dev) //I_ShutdownJoystick2(); + return; + + +#if 0 + //faB: look for as much buttons as g_input code supports, + // we don't use the others + for (i = JoyInfo2.buttons - 1; i >= 0; i--) + { + joybuttons <<= 1; + if (SDL_JoystickGetButton(JoyInfo2.dev,i)) + joybuttons |= 1; + } + + if (joybuttons != lastjoy2buttons) + { + INT64 j = 1; // keep only bits that changed since last time + INT64 newbuttons = joybuttons ^ lastjoy2buttons; + lastjoy2buttons = joybuttons; + + for (i = 0; i < JOYBUTTONS; i++, j <<= 1) + { + if (newbuttons & j) // button changed state? + { + if (joybuttons & j) + event.type = ev_keydown; + else + event.type = ev_keyup; + event.data1 = KEY_2JOY1 + i; + D_PostEvent(&event); + } + } + } +#endif + + for (i = JoyInfo2.hats - 1; i >= 0; i--) + { + Uint8 hat = SDL_JoystickGetHat(JoyInfo2.dev, i); + + if (hat & SDL_HAT_UP ) joyhats|=(UINT64)0x1<<(0 + 4*i); + if (hat & SDL_HAT_DOWN ) joyhats|=(UINT64)0x1<<(1 + 4*i); + if (hat & SDL_HAT_LEFT ) joyhats|=(UINT64)0x1<<(2 + 4*i); + if (hat & SDL_HAT_RIGHT) joyhats|=(UINT64)0x1<<(3 + 4*i); + } + + if (joyhats != lastjoy2hats) + { + INT64 j = 1; // keep only bits that changed since last time + INT64 newhats = joyhats ^ lastjoy2hats; + lastjoy2hats = joyhats; + + for (i = 0; i < JOYHATS*4; i++, j <<= 1) + { + if (newhats & j) // hat changed state? + { + if (joyhats & j) + event.type = ev_keydown; + else + event.type = ev_keyup; + event.data1 = KEY_2HAT1 + i; + D_PostEvent(&event); + } + } + } + +#if 0 + // send joystick axis positions + event.type = ev_joystick2; + + for (i = JOYAXISSET - 1; i >= 0; i--) + { + event.data1 = i; + if (i*2 + 1 <= JoyInfo2.axises) + axisx = SDL_JoystickGetAxis(JoyInfo2.dev, i*2 + 0); + else axisx = 0; + if (i*2 + 2 <= JoyInfo2.axises) + axisy = SDL_JoystickGetAxis(JoyInfo2.dev, i*2 + 1); + else axisy = 0; + +#ifdef _arch_dreamcast // -128 to 127 + axisx = axisx*8; + axisy = axisy*8; +#else // -32768 to 32767 + axisx = axisx/32; + axisy = axisy/32; +#endif + + if (Joystick2.bGamepadStyle) + { + // gamepad control type, on or off, live or die + if (axisx < -(JOYAXISRANGE/2)) + event.data2 = -1; + else if (axisx > (JOYAXISRANGE/2)) + event.data2 = 1; + else + event.data2 = 0; + if (axisy < -(JOYAXISRANGE/2)) + event.data3 = -1; + else if (axisy > (JOYAXISRANGE/2)) + event.data3 = 1; + else + event.data3 = 0; + } + else + { + + axisx = JoyInfo2.scale?((axisx/JoyInfo2.scale)*JoyInfo2.scale):axisx; + axisy = JoyInfo2.scale?((axisy/JoyInfo2.scale)*JoyInfo2.scale):axisy; + +#ifdef SDL_JDEADZONE + if (-SDL_JDEADZONE <= axisx && axisx <= SDL_JDEADZONE) axisx = 0; + if (-SDL_JDEADZONE <= axisy && axisy <= SDL_JDEADZONE) axisy = 0; +#endif + + // analog control style , just send the raw data + event.data2 = axisx; // x axis + event.data3 = axisy; // y axis + } + D_PostEvent(&event); + } +#endif + +} + +/** \brief Open joystick handle + + \param fname name of joystick + + \return axises + + +*/ +static int joy_open2(const char *fname) +{ + int joyindex = atoi(fname); + int num_joy = 0; + int i; + + if (joystick_started == 0 && joystick2_started == 0) + { + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) + { + CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError()); + return -1; + } + else + num_joy = SDL_NumJoysticks(); + + if (num_joy < joyindex) + { + CONS_Printf(M_GetText("Cannot use joystick #%d/(%s), it doesn't exist\n"),joyindex,fname); + for (i = 0; i < num_joy; i++) + CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickName(i)); + I_ShutdownJoystick2(); + return -1; + } + } + else + { + JoyReset(&JoyInfo2); + //I_ShutdownJoystick(); + //joy_open(fname); + } + + num_joy = SDL_NumJoysticks(); + + if (joyindex <= 0 || num_joy == 0 || JoyInfo2.oldjoy == joyindex) + { +// I_OutputMsg("Unable to use that joystick #(%s), non-number\n",fname); + if (num_joy != 0) + { + CONS_Printf(M_GetText("Found %d joysticks on this system\n"), num_joy); + for (i = 0; i < num_joy; i++) + CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickName(i)); + } + else + CONS_Printf("%s", M_GetText("Found no joysticks on this system\n")); + if (joyindex <= 0 || num_joy == 0) return 0; + } + + JoyInfo2.dev = SDL_JoystickOpen(joyindex-1); + CONS_Printf(M_GetText("Joystick2: %s\n"), SDL_JoystickName(joyindex-1)); + + if (!JoyInfo2.dev) + { + CONS_Printf(M_GetText("Couldn't open joystick2: %s\n"), SDL_GetError()); + I_ShutdownJoystick2(); + return -1; + } + else + { + JoyInfo2.axises = SDL_JoystickNumAxes(JoyInfo2.dev); + if (JoyInfo2.axises > JOYAXISSET*2) + JoyInfo2.axises = JOYAXISSET*2; +/* if (joyaxes < 2) + { + I_OutputMsg("Not enought axes?\n"); + I_ShutdownJoystick2(); + return 0; + }*/ + + JoyInfo2.buttons = SDL_JoystickNumButtons(JoyInfo2.dev); + if (JoyInfo2.buttons > JOYBUTTONS) + JoyInfo2.buttons = JOYBUTTONS; + +#ifdef DC + JoyInfo2.hats = 0; +#else + JoyInfo2.hats = SDL_JoystickNumHats(JoyInfo2.dev); + if (JoyInfo2.hats > JOYHATS) + JoyInfo2.hats = JOYHATS; + + JoyInfo2.balls = SDL_JoystickNumBalls(JoyInfo2.dev); +#endif + + //Joystick.bGamepadStyle = !stricmp(SDL_JoystickName(SDL_JoystickIndex(JoyInfo2.dev)), "pad"); + + return JoyInfo2.axises; + } +} + +// +// I_InitJoystick +// +void I_InitJoystick(void) +{ + I_ShutdownJoystick(); + if (!strcmp(cv_usejoystick.string, "0") || M_CheckParm("-nojoy")) + return; + if (joy_open(cv_usejoystick.string) != -1) + JoyInfo.oldjoy = atoi(cv_usejoystick.string); + else + { + cv_usejoystick.value = 0; + return; + } + joystick_started = 1; +} + +void I_InitJoystick2(void) +{ + I_ShutdownJoystick2(); + if (!strcmp(cv_usejoystick2.string, "0") || M_CheckParm("-nojoy")) + return; + if (joy_open2(cv_usejoystick2.string) != -1) + JoyInfo2.oldjoy = atoi(cv_usejoystick2.string); + else + { + cv_usejoystick2.value = 0; + return; + } + joystick2_started = 1; +} + +static void I_ShutdownInput(void) +{ + if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) + { + JoyReset(&JoyInfo); + JoyReset(&JoyInfo2); + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + } + +} + +INT32 I_NumJoys(void) +{ + INT32 numjoy = 0; + if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) + { + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != -1) + numjoy = SDL_NumJoysticks(); + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + } + else + numjoy = SDL_NumJoysticks(); + return numjoy; +} + +const char *I_GetJoyName(INT32 joyindex) +{ + const char *joyname = "NA"; + joyindex--; //SDL's Joystick System starts at 0, not 1 + if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) + { + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != -1) + joyname = SDL_JoystickName(joyindex); + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + } + else + joyname = SDL_JoystickName(joyindex); + return joyname; +} + +#ifndef NOMUMBLE +#ifdef HAVE_MUMBLE +// Best Mumble positional audio settings: +// Minimum distance 3.0 m +// Bloom 175% +// Maximum distance 80.0 m +// Minimum volume 50% +#define DEG2RAD (0.017453292519943295769236907684883l) // TAU/360 or PI/180 +#define MUMBLEUNIT (64.0f) // FRACUNITS in a Meter + +static struct { +#ifdef WINMUMBLE + UINT32 uiVersion; + DWORD uiTick; +#else + Uint32 uiVersion; + Uint32 uiTick; +#endif + float fAvatarPosition[3]; + float fAvatarFront[3]; + float fAvatarTop[3]; // defaults to Y-is-up (only used for leaning) + wchar_t name[256]; // game name + float fCameraPosition[3]; + float fCameraFront[3]; + float fCameraTop[3]; // defaults to Y-is-up (only used for leaning) + wchar_t identity[256]; // player id +#ifdef WINMUMBLE + UINT32 context_len; +#else + Uint32 context_len; +#endif + unsigned char context[256]; // server/team + wchar_t description[2048]; // game description +} *mumble = NULL; +#endif // HAVE_MUMBLE + +static void I_SetupMumble(void) +{ +#ifdef WINMUMBLE + HANDLE hMap = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink"); + if (!hMap) + return; + + mumble = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(*mumble)); + if (!mumble) + CloseHandle(hMap); +#elif defined (HAVE_SHM) + int shmfd; + char memname[256]; + + snprintf(memname, 256, "/MumbleLink.%d", getuid()); + shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR); + + if(shmfd < 0) + return; + + mumble = mmap(NULL, sizeof(*mumble), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0); + if (mumble == MAP_FAILED) + mumble = NULL; +#endif +} + +void I_UpdateMumble(const mobj_t *mobj, const listener_t listener) +{ +#ifdef HAVE_MUMBLE + double angle; + fixed_t anglef; + + if (!mumble) + return; + + if(mumble->uiVersion != 2) { + wcsncpy(mumble->name, L"SRB2 "VERSIONSTRING, 256); + wcsncpy(mumble->description, L"Sonic Robo Blast 2 with integrated Mumble Link support.", 2048); + mumble->uiVersion = 2; + } + mumble->uiTick++; + + if (!netgame || gamestate != GS_LEVEL) { // Zero out, but never delink. + mumble->fAvatarPosition[0] = mumble->fAvatarPosition[1] = mumble->fAvatarPosition[2] = 0.0f; + mumble->fAvatarFront[0] = 1.0f; + mumble->fAvatarFront[1] = mumble->fAvatarFront[2] = 0.0f; + mumble->fCameraPosition[0] = mumble->fCameraPosition[1] = mumble->fCameraPosition[2] = 0.0f; + mumble->fCameraFront[0] = 1.0f; + mumble->fCameraFront[1] = mumble->fCameraFront[2] = 0.0f; + return; + } + + { + UINT8 *p = mumble->context; + WRITEMEM(p, server_context, 8); + WRITEINT16(p, gamemap); + mumble->context_len = p - mumble->context; + } + + if (mobj) { + mumble->fAvatarPosition[0] = FIXED_TO_FLOAT(mobj->x) / MUMBLEUNIT; + mumble->fAvatarPosition[1] = FIXED_TO_FLOAT(mobj->z) / MUMBLEUNIT; + mumble->fAvatarPosition[2] = FIXED_TO_FLOAT(mobj->y) / MUMBLEUNIT; + + anglef = AngleFixed(mobj->angle); + angle = FIXED_TO_FLOAT(anglef)*DEG2RAD; + mumble->fAvatarFront[0] = (float)cos(angle); + mumble->fAvatarFront[1] = 0.0f; + mumble->fAvatarFront[2] = (float)sin(angle); + } else { + mumble->fAvatarPosition[0] = mumble->fAvatarPosition[1] = mumble->fAvatarPosition[2] = 0.0f; + mumble->fAvatarFront[0] = 1.0f; + mumble->fAvatarFront[1] = mumble->fAvatarFront[2] = 0.0f; + } + + mumble->fCameraPosition[0] = FIXED_TO_FLOAT(listener.x) / MUMBLEUNIT; + mumble->fCameraPosition[1] = FIXED_TO_FLOAT(listener.z) / MUMBLEUNIT; + mumble->fCameraPosition[2] = FIXED_TO_FLOAT(listener.y) / MUMBLEUNIT; + + anglef = AngleFixed(listener.angle); + angle = FIXED_TO_FLOAT(anglef)*DEG2RAD; + mumble->fCameraFront[0] = (float)cos(angle); + mumble->fCameraFront[1] = 0.0f; + mumble->fCameraFront[2] = (float)sin(angle); +#else + (void)mobj; + (void)listener; +#endif // HAVE_MUMBLE +} +#undef WINMUMBLE +#endif // NOMUMBLE + +#ifdef HAVE_TERMIOS + +void I_GetMouseEvents(void) +{ + static UINT8 mdata[5]; + static INT32 i = 0,om2b = 0; + INT32 di, j, mlp, button; + event_t event; + const INT32 mswap[8] = {0, 4, 1, 5, 2, 6, 3, 7}; + + if (!mouse2_started) return; + for (mlp = 0; mlp < 20; mlp++) + { + for (; i < 5; i++) + { + di = read(fdmouse2, mdata+i, 1); + if (di == -1) return; + } + if ((mdata[0] & 0xf8) != 0x80) + { + for (j = 1; j < 5; j++) + if ((mdata[j] & 0xf8) == 0x80) + for (i = 0; i < 5-j; i++) // shift + mdata[i] = mdata[i+j]; + if (i < 5) continue; + } + else + { + button = mswap[~mdata[0] & 0x07]; + for (j = 0; j < MOUSEBUTTONS; j++) + { + if (om2b & (1<> 4); + } + else if (bytenum == 3) + { + dx = (char)((combytes[0] & 3) << 6); + dy = (char)((combytes[0] & 12) << 4); + dx = (char)(dx + combytes[1]); + dy = (char)(dy + combytes[2]); + handlermouse2x+= dx; + handlermouse2y+= dy; + } + else if (bytenum == 4) // fourth UINT8 (logitech mouses) + { + if (buffer[i] & 32) + handlermouse2buttons |= 4; + else + handlermouse2buttons &= ~4; + } + } +} + +void I_GetMouseEvents(void) +{ + static UINT8 lastbuttons2 = 0; //mouse movement + event_t event; + + if (mouse2filehandle == INVALID_HANDLE_VALUE) + return; + + I_PoolMouse2(); + // post key event for buttons + if (handlermouse2buttons != lastbuttons2) + { + INT32 i, j = 1, k; + k = (handlermouse2buttons ^ lastbuttons2); // only changed bit to 1 + lastbuttons2 = (UINT8)handlermouse2buttons; + + for (i = 0; i < MOUSEBUTTONS; i++, j <<= 1) + if (k & j) + { + if (handlermouse2buttons & j) + event.type = ev_keydown; + else + event.type = ev_keyup; + event.data1 = KEY_2MOUSE1+i; + D_PostEvent(&event); + } + } + + if (handlermouse2x != 0 || handlermouse2y != 0) + { + event.type = ev_mouse2; + event.data1 = 0; +// event.data1 = buttons; // not needed + event.data2 = handlermouse2x << 1; + event.data3 = -handlermouse2y << 1; + handlermouse2x = 0; + handlermouse2y = 0; + + D_PostEvent(&event); + } +} +#else +void I_GetMouseEvents(void){}; +#endif + +// +// I_StartupMouse2 +// +void I_StartupMouse2(void) +{ +#ifdef HAVE_TERMIOS + struct termios m2tio; + size_t i; + INT32 dtr = -1, rts = -1;; + I_ShutdownMouse2(); + if (cv_usemouse2.value == 0) return; + if ((fdmouse2 = open(cv_mouse2port.string, O_RDONLY|O_NONBLOCK|O_NOCTTY)) == -1) + { + CONS_Printf(M_GetText("Error opening %s!\n"), cv_mouse2port.string); + return; + } + tcflush(fdmouse2, TCIOFLUSH); + m2tio.c_iflag = IGNBRK; + m2tio.c_oflag = 0; + m2tio.c_cflag = CREAD|CLOCAL|HUPCL|CS8|CSTOPB|B1200; + m2tio.c_lflag = 0; + m2tio.c_cc[VTIME] = 0; + m2tio.c_cc[VMIN] = 1; + tcsetattr(fdmouse2, TCSANOW, &m2tio); + for (i = 0; i < strlen(cv_mouse2opt.string); i++) + { + if (toupper(cv_mouse2opt.string[i]) == 'D') + { + if (cv_mouse2opt.string[i+1] == '-') + dtr = 0; + else + dtr = 1; + } + if (toupper(cv_mouse2opt.string[i]) == 'R') + { + if (cv_mouse2opt.string[i+1] == '-') + rts = 0; + else + rts = 1; + } + if (dtr != -1 || rts != -1) + { + INT32 c; + if (!ioctl(fdmouse2, TIOCMGET, &c)) + { + if (!dtr) + c &= ~TIOCM_DTR; + else if (dtr > 0) + c |= TIOCM_DTR; + } + if (!rts) + c &= ~TIOCM_RTS; + else if (rts > 0) + c |= TIOCM_RTS; + ioctl(fdmouse2, TIOCMSET, &c); + } + } + mouse2_started = 1; + I_AddExitFunc(I_ShutdownMouse2); +#elif defined (_WIN32) && !defined (_XBOX) + DCB dcb; + + if (mouse2filehandle != INVALID_HANDLE_VALUE) + I_ShutdownMouse2(); + + if (cv_usemouse2.value == 0) + return; + + if (mouse2filehandle == INVALID_HANDLE_VALUE) + { + // COM file handle + mouse2filehandle = CreateFileA(cv_mouse2port.string, GENERIC_READ | GENERIC_WRITE, + 0, // exclusive access + NULL, // no security attrs + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (mouse2filehandle == INVALID_HANDLE_VALUE) + { + INT32 e = GetLastError(); + if (e == 5) + CONS_Alert(CONS_ERROR, M_GetText("Can't open %s: Access denied\n"), cv_mouse2port.string); + else + CONS_Alert(CONS_ERROR, M_GetText("Can't open %s: error %d\n"), cv_mouse2port.string, e); + return; + } + } + + // getevent when somthing happens + //SetCommMask(mouse2filehandle, EV_RXCHAR); + + // buffers + SetupComm(mouse2filehandle, MOUSECOMBUFFERSIZE, MOUSECOMBUFFERSIZE); + + // purge buffers + PurgeComm(mouse2filehandle, PURGE_TXABORT | PURGE_RXABORT + | PURGE_TXCLEAR | PURGE_RXCLEAR); + + // setup port to 1200 7N1 + dcb.DCBlength = sizeof (DCB); + + GetCommState(mouse2filehandle, &dcb); + + dcb.BaudRate = CBR_1200; + dcb.ByteSize = 7; + dcb.Parity = NOPARITY; + dcb.StopBits = ONESTOPBIT; + + dcb.fDtrControl = DTR_CONTROL_ENABLE; + dcb.fRtsControl = RTS_CONTROL_ENABLE; + + dcb.fBinary = TRUE; + dcb.fParity = TRUE; + + SetCommState(mouse2filehandle, &dcb); + I_AddExitFunc(I_ShutdownMouse2); +#endif +} + +// +// I_Tactile +// +void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect) +{ + // UNUSED. + (void)pFFType; + (void)FFEffect; +} + +void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect) +{ + // UNUSED. + (void)pFFType; + (void)FFEffect; +} + +/** \brief empty ticcmd for player 1 +*/ +static ticcmd_t emptycmd; + +ticcmd_t *I_BaseTiccmd(void) +{ + return &emptycmd; +} + +/** \brief empty ticcmd for player 2 +*/ +static ticcmd_t emptycmd2; + +ticcmd_t *I_BaseTiccmd2(void) +{ + return &emptycmd2; +} + +#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) +static HMODULE winmm = NULL; +static DWORD starttickcount = 0; // hack for win2k time bug +static p_timeGetTime pfntimeGetTime = NULL; + +// --------- +// I_GetTime +// Use the High Resolution Timer if available, +// else use the multimedia timer which has 1 millisecond precision on Windowz 95, +// but lower precision on Windows NT +// --------- + +tic_t I_GetTime(void) +{ + tic_t newtics = 0; + + if (!starttickcount) // high precision timer + { + LARGE_INTEGER currtime; // use only LowPart if high resolution counter is not available + static LARGE_INTEGER basetime = {{0, 0}}; + + // use this if High Resolution timer is found + static LARGE_INTEGER frequency; + + if (!basetime.LowPart) + { + if (!QueryPerformanceFrequency(&frequency)) + frequency.QuadPart = 0; + else + QueryPerformanceCounter(&basetime); + } + + if (frequency.LowPart && QueryPerformanceCounter(&currtime)) + { + newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * NEWTICRATE + / frequency.QuadPart); + } + else if (pfntimeGetTime) + { + currtime.LowPart = pfntimeGetTime(); + if (!basetime.LowPart) + basetime.LowPart = currtime.LowPart; + newtics = ((currtime.LowPart - basetime.LowPart)/(1000/NEWTICRATE)); + } + } + else + newtics = (GetTickCount() - starttickcount)/(1000/NEWTICRATE); + + return newtics; +} + +static void I_ShutdownTimer(void) +{ + pfntimeGetTime = NULL; + if (winmm) + { + p_timeEndPeriod pfntimeEndPeriod = (p_timeEndPeriod)GetProcAddress(winmm, "timeEndPeriod"); + if (pfntimeEndPeriod) + pfntimeEndPeriod(1); + FreeLibrary(winmm); + winmm = NULL; + } +} +#else +// +// I_GetTime +// returns time in 1/TICRATE second tics +// +tic_t I_GetTime (void) +{ +#ifdef _arch_dreamcast + static Uint64 basetime = 0; + Uint64 ticks = timer_ms_gettime64(); //using timer_ms_gettime64 instand of SDL_GetTicks for the Dreamcast +#else + static Uint32 basetime = 0; + Uint32 ticks = SDL_GetTicks(); +#endif + + if (!basetime) + basetime = ticks; + + ticks -= basetime; + + ticks = (ticks*TICRATE); + +#if 0 //#ifdef _WIN32_WCE + ticks = (ticks/10); +#else + ticks = (ticks/1000); +#endif + + return (tic_t)ticks; +} +#endif + +// +//I_StartupTimer +// +void I_StartupTimer(void) +{ +#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) + // for win2k time bug + if (M_CheckParm("-gettickcount")) + { + starttickcount = GetTickCount(); + CONS_Printf("%s", M_GetText("Using GetTickCount()\n")); + } + winmm = LoadLibraryA("winmm.dll"); + if (winmm) + { + p_timeEndPeriod pfntimeBeginPeriod = (p_timeEndPeriod)GetProcAddress(winmm, "timeBeginPeriod"); + if (pfntimeBeginPeriod) + pfntimeBeginPeriod(1); + pfntimeGetTime = (p_timeGetTime)GetProcAddress(winmm, "timeGetTime"); + } + I_AddExitFunc(I_ShutdownTimer); +#elif 0 //#elif !defined (_arch_dreamcast) && !defined(GP2X) // the DC have it own timer and GP2X have broken pthreads? + if (SDL_InitSubSystem(SDL_INIT_TIMER) < 0) + I_Error("SRB2: Needs SDL_Timer, Error: %s", SDL_GetError()); +#endif +} + + + +void I_Sleep(void) +{ +#if !(defined (_arch_dreamcast) || defined (_XBOX)) + if (cv_sleep.value != -1) + SDL_Delay(cv_sleep.value); +#endif +} + +INT32 I_StartupSystem(void) +{ + SDL_version SDLcompiled; + const SDL_version *SDLlinked; +#ifdef _XBOX +#ifdef __GNUC__ + char DP[] =" Sonic Robo Blast 2!\n"; + debugPrint(DP); +#endif + unlink("e:/Games/SRB2/stdout.txt"); + freopen("e:/Games/SRB2/stdout.txt", "w+", stdout); + unlink("e:/Games/SRB2/stderr.txt"); + freopen("e:/Games/SRB2/stderr.txt", "w+", stderr); +#endif +#ifdef _arch_dreamcast +#ifdef _DEBUG + //gdb_init(); +#endif + printf(__FILE__":%i\n",__LINE__); +#ifdef _DEBUG + //gdb_breakpoint(); +#endif +#endif + SDL_VERSION(&SDLcompiled) + SDLlinked = SDL_Linked_Version(); + I_StartupConsole(); + I_OutputMsg("Compiled for SDL version: %d.%d.%d\n", + SDLcompiled.major, SDLcompiled.minor, SDLcompiled.patch); + I_OutputMsg("Linked with SDL version: %d.%d.%d\n", + SDLlinked->major, SDLlinked->minor, SDLlinked->patch); +#if 0 //#ifdef GP2X //start up everything + if (SDL_Init(SDL_INIT_NOPARACHUTE|SDL_INIT_EVERYTHING) < 0) +#else + if (SDL_Init(SDL_INIT_NOPARACHUTE) < 0) +#endif + I_Error("SRB2: SDL System Error: %s", SDL_GetError()); //Alam: Oh no.... +#ifndef NOMUMBLE + I_SetupMumble(); +#endif + return 0; +} + + +// +// I_Quit +// +void I_Quit(void) +{ + static SDL_bool quiting = SDL_FALSE; + + /* prevent recursive I_Quit() */ + if (quiting) goto death; + SDLforceUngrabMouse(); + quiting = SDL_FALSE; + I_ShutdownConsole(); + M_SaveConfig(NULL); //save game config, cvars.. +#ifndef NONET + D_SaveBan(); // save the ban list +#endif + G_SaveGameData(); // Tails 12-08-2002 + //added:16-02-98: when recording a demo, should exit using 'q' key, + // but sometimes we forget and use 'F10'.. so save here too. + + if (demorecording) + G_CheckDemoStatus(); + if (metalrecording) + G_StopMetalRecording(); + + D_QuitNetGame(); + I_ShutdownMusic(); + I_ShutdownSound(); + I_ShutdownCD(); + // use this for 1.28 19990220 by Kin + I_ShutdownGraphics(); + I_ShutdownInput(); + I_ShutdownSystem(); +#ifndef _arch_dreamcast + SDL_Quit(); +#endif + /* if option -noendtxt is set, don't print the text */ + if (!M_CheckParm("-noendtxt") && W_CheckNumForName("ENDOOM") != LUMPERROR) + { + printf("\r"); + ShowEndTxt(); + } +death: + W_Shutdown(); +#ifdef GP2X + chdir("/usr/gp2x"); + execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL); +#endif + exit(0); +} + +void I_WaitVBL(INT32 count) +{ + count = 1; + SDL_Delay(count); +} + +void I_BeginRead(void) +{ +} + +void I_EndRead(void) +{ +} + +// +// I_Error +// +/** \brief phuck recursive errors +*/ +static INT32 errorcount = 0; + +/** \brief recursive error detecting +*/ +static boolean shutdowning = false; + +void I_Error(const char *error, ...) +{ + va_list argptr; +#if (defined (MAC_ALERT) || defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__))) && !defined (_XBOX) + char buffer[8192]; +#endif + + // recursive error detecting + if (shutdowning) + { + errorcount++; + if (errorcount == 1) + SDLforceUngrabMouse(); + // try to shutdown each subsystem separately + if (errorcount == 2) + I_ShutdownMusic(); + if (errorcount == 3) + I_ShutdownSound(); + if (errorcount == 4) + I_ShutdownCD(); + if (errorcount == 5) + I_ShutdownGraphics(); + if (errorcount == 6) + I_ShutdownInput(); + if (errorcount == 7) + I_ShutdownSystem(); +#ifndef _arch_dreamcast + if (errorcount == 8) + SDL_Quit(); +#endif + if (errorcount == 9) + { + M_SaveConfig(NULL); + G_SaveGameData(); + } + if (errorcount > 20) + { +#ifdef MAC_ALERT + va_start(argptr, error); + vsprintf(buffer, error, argptr); + va_end(argptr); + // 2004-03-03 AJR Since the Mac user is most likely double clicking to run the game, give them a panel. + MacShowAlert("Recursive Error", buffer, "Quit", NULL, NULL); +#elif (defined (_WIN32) || (defined (_WIN32_WCE)) && !defined (__GNUC__)) && !defined (_XBOX) + va_start(argptr,error); + vsprintf(buffer, error, argptr); + va_end(argptr); +#ifndef _WIN32_WCE + { + HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD bytesWritten; + if (co != INVALID_HANDLE_VALUE) + { + if (GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &bytesWritten)) + WriteConsoleA(co, buffer, (DWORD)strlen(buffer), NULL, NULL); + else + WriteFile(co, buffer, (DWORD)strlen(buffer), &bytesWritten, NULL); + } + } +#endif + OutputDebugStringA(buffer); + MessageBoxA(vid.WndParent, buffer, "SRB2 Recursive Error", MB_OK|MB_ICONERROR); +#else + // Don't print garbage + va_start(argptr, error); + if (!framebuffer) + vfprintf (stderr, error, argptr); + va_end(argptr); +#endif + W_Shutdown(); +#ifdef GP2X + chdir("/usr/gp2x"); + execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL); +#endif + exit(-1); // recursive errors detected + } + } + shutdowning = true; + I_ShutdownConsole(); +#ifndef MAC_ALERT + // Message first. + va_start(argptr,error); + if (!framebuffer) + { + fprintf(stderr, "Error: "); + vfprintf(stderr,error,argptr); + fprintf(stderr, "\n"); + } + va_end(argptr); + + if (!framebuffer) + fflush(stderr); +#endif + M_SaveConfig(NULL); // save game config, cvars.. +#ifndef NONET + D_SaveBan(); // save the ban list +#endif + G_SaveGameData(); // Tails 12-08-2002 + + // Shutdown. Here might be other errors. + if (demorecording) + G_CheckDemoStatus(); + if (metalrecording) + G_StopMetalRecording(); + + D_QuitNetGame(); + I_ShutdownMusic(); + I_ShutdownSound(); + I_ShutdownCD(); + // use this for 1.28 19990220 by Kin + I_ShutdownGraphics(); + I_ShutdownInput(); + I_ShutdownSystem(); +#ifndef _arch_dreamcast + SDL_Quit(); +#endif +#ifdef MAC_ALERT + va_start(argptr, error); + vsprintf(buffer, error, argptr); + va_end(argptr); + // 2004-03-03 AJR Since the Mac user is most likely double clicking to run the game, give them a panel. + MacShowAlert("Critical Error", buffer, "Quit", NULL, NULL); +#endif + W_Shutdown(); +#if defined (PARANOIA) && defined (__CYGWIN__) + *(INT32 *)2 = 4; //Alam: Debug! +#endif +#ifdef GP2X + chdir("/usr/gp2x"); + execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL); +#endif + exit(-1); +} + +/** \brief quit function table +*/ +static quitfuncptr quit_funcs[MAX_QUIT_FUNCS]; /* initialized to all bits 0 */ + +// +// Adds a function to the list that need to be called by I_SystemShutdown(). +// +void I_AddExitFunc(void (*func)()) +{ + INT32 c; + + for (c = 0; c < MAX_QUIT_FUNCS; c++) + { + if (!quit_funcs[c]) + { + quit_funcs[c] = func; + break; + } + } +} + + +// +// Removes a function from the list that need to be called by +// I_SystemShutdown(). +// +void I_RemoveExitFunc(void (*func)()) +{ + INT32 c; + + for (c = 0; c < MAX_QUIT_FUNCS; c++) + { + if (quit_funcs[c] == func) + { + while (c < MAX_QUIT_FUNCS-1) + { + quit_funcs[c] = quit_funcs[c+1]; + c++; + } + quit_funcs[MAX_QUIT_FUNCS-1] = NULL; + break; + } + } +} + +// +// Closes down everything. This includes restoring the initial +// palette and video mode, and removing whatever mouse, keyboard, and +// timer routines have been installed. +// +// NOTE: Shutdown user funcs are effectively called in reverse order. +// +void I_ShutdownSystem(void) +{ + INT32 c; + + for (c = MAX_QUIT_FUNCS-1; c >= 0; c--) + if (quit_funcs[c]) + (*quit_funcs[c])(); +#ifdef LOGMESSAGES + if (logstream) + { + fclose(logstream); + logstream = NULL; + } +#endif + +} + +void I_GetDiskFreeSpace(INT64 *freespace) +{ +#if defined (_arch_dreamcast) || defined (_PSP) + *freespace = 0; +#elif defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#if defined (SOLARIS) || defined (__HAIKU__) || defined (_WII) || defined (_PS3) + *freespace = INT32_MAX; + return; +#else // Both Linux and BSD have this, apparently. + struct statfs stfs; + if (statfs(".", &stfs) == -1) + { + *freespace = INT32_MAX; + return; + } + *freespace = stfs.f_bavail * stfs.f_bsize; +#endif +#elif (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) + static p_GetDiskFreeSpaceExA pfnGetDiskFreeSpaceEx = NULL; + static boolean testwin95 = false; + ULARGE_INTEGER usedbytes, lfreespace; + + if (!testwin95) + { + pfnGetDiskFreeSpaceEx = (p_GetDiskFreeSpaceExA)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetDiskFreeSpaceExA"); + testwin95 = true; + } + if (pfnGetDiskFreeSpaceEx) + { + if (pfnGetDiskFreeSpaceEx(NULL, &lfreespace, &usedbytes, NULL)) + *freespace = lfreespace.QuadPart; + else + *freespace = INT32_MAX; + } + else + { + DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters; + GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector, + &NumberOfFreeClusters, &TotalNumberOfClusters); + *freespace = BytesPerSector*SectorsPerCluster*NumberOfFreeClusters; + } +#else // Dummy for platform independent; 1GB should be enough + *freespace = 1024*1024*1024; +#endif +} + +char *I_GetUserName(void) +{ +#ifdef GP2X + static char username[MAXPLAYERNAME] = "GP2XUSER"; + return username; +#elif defined (PSP) + static char username[MAXPLAYERNAME] = "PSPUSER"; + return username; +#elif !(defined (_WIN32_WCE) || defined (_XBOX)) + static char username[MAXPLAYERNAME]; + char *p; +#ifdef _WIN32 + DWORD i = MAXPLAYERNAME; + + if (!GetUserNameA(username, &i)) +#endif + { + p = I_GetEnv("USER"); + if (!p) + { + p = I_GetEnv("user"); + if (!p) + { + p = I_GetEnv("USERNAME"); + if (!p) + { + p = I_GetEnv("username"); + if (!p) + { + return NULL; + } + } + } + } + strncpy(username, p, MAXPLAYERNAME); + } + + + if (strcmp(username, "") != 0) + return username; +#endif + return NULL; // dummy for platform independent version +} + +INT32 I_mkdir(const char *dirname, INT32 unixright) +{ +//[segabor] +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) || defined (__CYGWIN__) || defined (__OS2__) + return mkdir(dirname, unixright); +#elif (defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__))) && !defined (_XBOX) + UNREFERENCED_PARAMETER(unixright); /// \todo should implement ntright under nt... + return CreateDirectoryA(dirname, NULL); +#else + (void)dirname; + (void)unixright; + return false; +#endif +} + +char *I_GetEnv(const char *name) +{ +#ifdef NEED_SDL_GETENV + return SDL_getenv(name); +#elif defined(_WIN32_WCE) + (void)name; + return NULL; +#else + return getenv(name); +#endif +} + +INT32 I_PutEnv(char *variable) +{ +#ifdef NEED_SDL_GETENV + return SDL_putenv(variable); +#elif defined(_WIN32_WCE) + return ((variable)?-1:0); +#else + return putenv(variable); +#endif +} + +/** \brief The isWadPathOk function + + \param path string path to check + + \return if true, wad file found + + +*/ +static boolean isWadPathOk(const char *path) +{ + char *wad3path = malloc(256); + + if (!wad3path) + return false; + + sprintf(wad3path, pandf, path, WADKEYWORD1); + + if (FIL_ReadFileOK(wad3path)) + { + free(wad3path); + return true; + } + + sprintf(wad3path, pandf, path, WADKEYWORD2); + + if (FIL_ReadFileOK(wad3path)) + { + free(wad3path); + return true; + } + + free(wad3path); + return false; +} + +static void pathonly(char *s) +{ + size_t j; + + for (j = strlen(s); j != (size_t)-1; j--) + if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/')) + { + if (s[j] == ':') s[j+1] = 0; + else s[j] = 0; + return; + } +} + +/** \brief search for srb2.srb in the given path + + \param searchDir starting path + + \return WAD path if not NULL + + +*/ +static const char *searchWad(const char *searchDir) +{ + static char tempsw[256] = ""; + filestatus_t fstemp; + + strcpy(tempsw, WADKEYWORD1); + fstemp = filesearch(tempsw,searchDir,NULL,true,20); + if (fstemp == FS_FOUND) + { + pathonly(tempsw); + return tempsw; + } + + strcpy(tempsw, WADKEYWORD2); + fstemp = filesearch(tempsw, searchDir, NULL, true, 20); + if (fstemp == FS_FOUND) + { + pathonly(tempsw); + return tempsw; + } + return NULL; +} + +/** \brief go through all possible paths and look for srb2.srb + + \return path to srb2.srb if any +*/ +static const char *locateWad(void) +{ + const char *envstr; + const char *WadPath; + + I_OutputMsg("SRB2WADDIR"); + // does SRB2WADDIR exist? + if (((envstr = I_GetEnv("SRB2WADDIR")) != NULL) && isWadPathOk(envstr)) + return envstr; + +#if defined(_WIN32_WCE) || defined(_PS3) || defined(_PSP) + // examine argv[0] + strcpy(returnWadPath, myargv[0]); + pathonly(returnWadPath); + I_PutEnv(va("HOME=%s",returnWadPath)); + if (isWadPathOk(returnWadPath)) + return returnWadPath; +#endif + +#ifndef NOCWD + I_OutputMsg(",."); + // examine current dir + strcpy(returnWadPath, "."); + if (isWadPathOk(returnWadPath)) + return NULL; +#endif + + // examine default dirs +#ifdef DEFAULTWADLOCATION1 + I_OutputMsg(","DEFAULTWADLOCATION1); + strcpy(returnWadPath, DEFAULTWADLOCATION1); + if (isWadPathOk(returnWadPath)) + return returnWadPath; +#endif +#ifdef DEFAULTWADLOCATION2 + I_OutputMsg(","DEFAULTWADLOCATION2); + strcpy(returnWadPath, DEFAULTWADLOCATION2); + if (isWadPathOk(returnWadPath)) + return returnWadPath; +#endif +#ifdef DEFAULTWADLOCATION3 + I_OutputMsg(","DEFAULTWADLOCATION3); + strcpy(returnWadPath, DEFAULTWADLOCATION3); + if (isWadPathOk(returnWadPath)) + return returnWadPath; +#endif +#ifdef DEFAULTWADLOCATION4 + I_OutputMsg(","DEFAULTWADLOCATION4); + strcpy(returnWadPath, DEFAULTWADLOCATION4); + if (isWadPathOk(returnWadPath)) + return returnWadPath; +#endif +#ifdef DEFAULTWADLOCATION5 + I_OutputMsg(","DEFAULTWADLOCATION5); + strcpy(returnWadPath, DEFAULTWADLOCATION5); + if (isWadPathOk(returnWadPath)) + return returnWadPath; +#endif +#ifdef DEFAULTWADLOCATION6 + I_OutputMsg(","DEFAULTWADLOCATION6); + strcpy(returnWadPath, DEFAULTWADLOCATION6); + if (isWadPathOk(returnWadPath)) + return returnWadPath; +#endif +#ifdef DEFAULTWADLOCATION7 + I_OutputMsg(","DEFAULTWADLOCATION7); + strcpy(returnWadPath, DEFAULTWADLOCATION7); + if (isWadPathOk(returnWadPath)) + return returnWadPath; +#endif +#ifndef NOHOME + // find in $HOME + I_OutputMsg(",HOME"); + if ((envstr = I_GetEnv("HOME")) != NULL) + { + WadPath = searchWad(envstr); + if (WadPath) + return WadPath; + } +#endif +#ifdef DEFAULTSEARCHPATH1 + // find in /usr/local + I_OutputMsg(", in:"DEFAULTSEARCHPATH1); + WadPath = searchWad(DEFAULTSEARCHPATH1); + if (WadPath) + return WadPath; +#endif +#ifdef DEFAULTSEARCHPATH2 + // find in /usr/games + I_OutputMsg(", in:"DEFAULTSEARCHPATH2); + WadPath = searchWad(DEFAULTSEARCHPATH2); + if (WadPath) + return WadPath; +#endif +#ifdef DEFAULTSEARCHPATH3 + // find in ??? + I_OutputMsg(", in:"DEFAULTSEARCHPATH3); + WadPath = searchWad(DEFAULTSEARCHPATH3); + if (WadPath) + return WadPath; +#endif + // if nothing was found + return NULL; +} + +const char *I_LocateWad(void) +{ + const char *waddir; + + I_OutputMsg("Looking for WADs in: "); + waddir = locateWad(); + I_OutputMsg("\n"); + + if (waddir) + { + // change to the directory where we found srb2.srb +#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) + SetCurrentDirectoryA(waddir); +#elif !defined (_WIN32_WCE) && !defined (_PS3) + if (chdir(waddir) == -1) + I_OutputMsg("Couldn't change working directory\n"); +#endif + } + return waddir; +} + +#ifdef LINUX +#define MEMINFO_FILE "/proc/meminfo" +#define MEMTOTAL "MemTotal:" +#define MEMFREE "MemFree:" +#endif + +// quick fix for compil +UINT32 I_GetFreeMem(UINT32 *total) +{ +#if defined (_arch_dreamcast) + //Dreamcast! + if (total) + *total = 16<<20; + return 8<<20; +#elif defined (_PSP) + // PSP + if (total) + *total = 32<<20; + return 16<<20; +#elif defined (FREEBSD) + struct vmmeter sum; + kvm_t *kd; + struct nlist namelist[] = + { +#define X_SUM 0 + {"_cnt"}, + {NULL} + }; + if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) + { + *total = 0L; + return 0; + } + if (kvm_nlist(kd, namelist) != 0) + { + kvm_close (kd); + *total = 0L; + return 0; + } + if (kvm_read(kd, namelist[X_SUM].n_value, &sum, + sizeof (sum)) != sizeof (sum)) + { + kvm_close(kd); + *total = 0L; + return 0; + } + kvm_close(kd); + + if (total) + *total = sum.v_page_count * sum.v_page_size; + return sum.v_free_count * sum.v_page_size; +#elif defined (SOLARIS) + /* Just guess */ + if (total) + *total = 32 << 20; + return 32 << 20; +#elif defined (LINUX) + /* Linux */ + char buf[1024]; + char *memTag; + UINT32 freeKBytes; + UINT32 totalKBytes; + INT32 n; + INT32 meminfo_fd = -1; + + meminfo_fd = open(MEMINFO_FILE, O_RDONLY); + n = read(meminfo_fd, buf, 1023); + close(meminfo_fd); + + if (n < 0) + { + // Error + *total = 0L; + return 0; + } + + buf[n] = '\0'; + if (NULL == (memTag = strstr(buf, MEMTOTAL))) + { + // Error + *total = 0L; + return 0; + } + + memTag += sizeof (MEMTOTAL); + totalKBytes = atoi(memTag); + + if (NULL == (memTag = strstr(buf, MEMFREE))) + { + // Error + *total = 0L; + return 0; + } + + memTag += sizeof (MEMFREE); + freeKBytes = atoi(memTag); + + if (total) + *total = totalKBytes << 10; + return freeKBytes << 10; +#elif (defined (_WIN32) || (defined (_WIN32_WCE) && !defined (__GNUC__))) && !defined (_XBOX) + MEMORYSTATUS info; + + info.dwLength = sizeof (MEMORYSTATUS); + GlobalMemoryStatus( &info ); + if (total) + *total = (UINT32)info.dwTotalPhys; + return (UINT32)info.dwAvailPhys; +#elif defined (__OS2__) + UINT32 pr_arena; + + if (total) + DosQuerySysInfo( QSV_TOTPHYSMEM, QSV_TOTPHYSMEM, + (PVOID) total, sizeof (UINT32)); + DosQuerySysInfo( QSV_MAXPRMEM, QSV_MAXPRMEM, + (PVOID) &pr_arena, sizeof (UINT32)); + + return pr_arena; +#else + // Guess 48 MB. + if (total) + *total = 48<<20; + return 48<<20; +#endif /* LINUX */ +} + +const CPUInfoFlags *I_CPUInfo(void) +{ +#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) + static CPUInfoFlags WIN_CPUInfo; + SYSTEM_INFO SI; + p_IsProcessorFeaturePresent pfnCPUID = (p_IsProcessorFeaturePresent)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsProcessorFeaturePresent"); + + ZeroMemory(&WIN_CPUInfo,sizeof (WIN_CPUInfo)); + if (pfnCPUID) + { + WIN_CPUInfo.FPPE = pfnCPUID( 0); //PF_FLOATING_POINT_PRECISION_ERRATA + WIN_CPUInfo.FPE = pfnCPUID( 1); //PF_FLOATING_POINT_EMULATED + WIN_CPUInfo.cmpxchg = pfnCPUID( 2); //PF_COMPARE_EXCHANGE_DOUBLE + WIN_CPUInfo.MMX = pfnCPUID( 3); //PF_MMX_INSTRUCTIONS_AVAILABLE + WIN_CPUInfo.PPCMM64 = pfnCPUID( 4); //PF_PPC_MOVEMEM_64BIT_OK + WIN_CPUInfo.ALPHAbyte = pfnCPUID( 5); //PF_ALPHA_BYTE_INSTRUCTIONS + WIN_CPUInfo.SSE = pfnCPUID( 6); //PF_XMMI_INSTRUCTIONS_AVAILABLE + WIN_CPUInfo.AMD3DNow = pfnCPUID( 7); //PF_3DNOW_INSTRUCTIONS_AVAILABLE + WIN_CPUInfo.RDTSC = pfnCPUID( 8); //PF_RDTSC_INSTRUCTION_AVAILABLE + WIN_CPUInfo.PAE = pfnCPUID( 9); //PF_PAE_ENABLED + WIN_CPUInfo.SSE2 = pfnCPUID(10); //PF_XMMI64_INSTRUCTIONS_AVAILABLE + //WIN_CPUInfo.blank = pfnCPUID(11); //PF_SSE_DAZ_MODE_AVAILABLE + WIN_CPUInfo.DEP = pfnCPUID(12); //PF_NX_ENABLED + WIN_CPUInfo.SSE3 = pfnCPUID(13); //PF_SSE3_INSTRUCTIONS_AVAILABLE + WIN_CPUInfo.cmpxchg16b = pfnCPUID(14); //PF_COMPARE_EXCHANGE128 + WIN_CPUInfo.cmp8xchg16 = pfnCPUID(15); //PF_COMPARE64_EXCHANGE128 + WIN_CPUInfo.PFC = pfnCPUID(16); //PF_CHANNELS_ENABLED + } +#ifdef HAVE_SDLCPUINFO + else + { + WIN_CPUInfo.RDTSC = SDL_HasRDTSC(); + WIN_CPUInfo.MMX = SDL_HasMMX(); + WIN_CPUInfo.AMD3DNow = SDL_Has3DNow(); + WIN_CPUInfo.SSE = SDL_HasSSE(); + WIN_CPUInfo.SSE2 = SDL_HasSSE2(); + WIN_CPUInfo.AltiVec = SDL_HasAltiVec(); + } + WIN_CPUInfo.MMXExt = SDL_HasMMXExt(); + WIN_CPUInfo.AMD3DNowExt = SDL_Has3DNowExt(); +#endif + GetSystemInfo(&SI); + WIN_CPUInfo.CPUs = SI.dwNumberOfProcessors; + WIN_CPUInfo.IA64 = (SI.dwProcessorType == 2200); // PROCESSOR_INTEL_IA64 + WIN_CPUInfo.AMD64 = (SI.dwProcessorType == 8664); // PROCESSOR_AMD_X8664 + return &WIN_CPUInfo; +#elif defined (HAVE_SDLCPUINFO) + static CPUInfoFlags SDL_CPUInfo; + memset(&SDL_CPUInfo,0,sizeof (CPUInfoFlags)); + SDL_CPUInfo.RDTSC = SDL_HasRDTSC(); + SDL_CPUInfo.MMX = SDL_HasMMX(); + SDL_CPUInfo.MMXExt = SDL_HasMMXExt(); + SDL_CPUInfo.AMD3DNow = SDL_Has3DNow(); + SDL_CPUInfo.AMD3DNowExt = SDL_Has3DNowExt(); + SDL_CPUInfo.SSE = SDL_HasSSE(); + SDL_CPUInfo.SSE2 = SDL_HasSSE2(); + SDL_CPUInfo.AltiVec = SDL_HasAltiVec(); + return &SDL_CPUInfo; +#else + return NULL; /// \todo CPUID asm +#endif +} + +#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) +static void CPUAffinity_OnChange(void); +static consvar_t cv_cpuaffinity = {"cpuaffinity", "-1", CV_SAVE | CV_CALL, NULL, CPUAffinity_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +static p_GetCurrentProcess pfnGetCurrentProcess = NULL; +static p_GetProcessAffinityMask pfnGetProcessAffinityMask = NULL; +static p_SetProcessAffinityMask pfnSetProcessAffinityMask = NULL; + +static inline VOID GetAffinityFuncs(VOID) +{ + HMODULE h = GetModuleHandleA("kernel32.dll"); + pfnGetCurrentProcess = (p_GetCurrentProcess)GetProcAddress(h, "GetCurrentProcess"); + pfnGetProcessAffinityMask = (p_GetProcessAffinityMask)GetProcAddress(h, "GetProcessAffinityMask"); + pfnSetProcessAffinityMask = (p_SetProcessAffinityMask)GetProcAddress(h, "SetProcessAffinityMask"); +} + +static void CPUAffinity_OnChange(void) +{ + DWORD_PTR dwProcMask, dwSysMask; + HANDLE selfpid; + + if (!pfnGetCurrentProcess || !pfnGetProcessAffinityMask || !pfnSetProcessAffinityMask) + return; + else + selfpid = pfnGetCurrentProcess(); + + pfnGetProcessAffinityMask(selfpid, &dwProcMask, &dwSysMask); + + /* If resulting mask is zero, don't change anything and fall back to + * actual mask. + */ + if(dwSysMask & cv_cpuaffinity.value) + { + pfnSetProcessAffinityMask(selfpid, dwSysMask & cv_cpuaffinity.value); + CV_StealthSetValue(&cv_cpuaffinity, (INT32)(dwSysMask & cv_cpuaffinity.value)); + } + else + CV_StealthSetValue(&cv_cpuaffinity, (INT32)dwProcMask); +} +#endif + +void I_RegisterSysCommands(void) +{ +#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) + GetAffinityFuncs(); + CV_RegisterVar(&cv_cpuaffinity); +#endif +} +#endif diff --git a/src/sdl12/i_ttf.c b/src/sdl12/i_ttf.c new file mode 100644 index 000000000..770a81d98 --- /dev/null +++ b/src/sdl12/i_ttf.c @@ -0,0 +1,340 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 2011 by Callum Dickinson. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief SDL_ttf interface code. Necessary for platforms with no framebuffer console systems. + +#if defined(SDL) && defined(HAVE_TTF) +#include "SDL.h" +#include "SDL_ttf.h" +#include "../doomdef.h" +#include "../doomstat.h" +#include "../d_netfil.h" +#include "../filesrch.h" +#include "i_ttf.h" + +// Search directories to find aforementioned TTF file. +#ifdef _PS3 +#include +#define FONTSEARCHPATH1 "/dev_hdd0/game/SRB2-PS3_/USRDIR/etc" +#elif defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#define FONTSEARCHPATH1 "/usr/share/fonts" +#define FONTSEARCHPATH2 "/usr/local/share/fonts" +#define FONTSEARCHPATH3 "/usr/games/SRB2" +#define FONTSEARCHPATH4 "/usr/local/games/SRB2" +#define FONTSEARCHPATH5 "/usr/local/share/games/SRB2" +#else +#define FONTSEARCHPATH1 "." +#endif + +#define FONTHANDLE -1 + +// Renduring surfaces. +SDL_Surface *TTFSurface = NULL; +SDL_Surface *TTFRendSurface = NULL; +// Text box. +SDL_Rect TTFRect; +// Temporary storage for the new TTFRect, used to check for +// line wrapping. +SDL_Rect TTFRectCheck; +// Text rendering resolution. +videoResolution res; +// Text storage buffer, the contents get printed to the SDL surface. +char textbuffer[8192]; + +// look for default ttf file in given directory +static char *searchFont(const char *fontsearchDir) +{ + static char tempsw[256] = ""; + filestatus_t fstemp; + + strcpy(tempsw, FONTFILE); + fstemp = filesearch(tempsw, fontsearchDir, NULL, true, 20); + if (fstemp == FS_FOUND) + { + return tempsw; + } + return NULL; +} + +// Load TTF font from file. +INT32 I_TTFLoadFont(const char *file, UINT32 ptsize) +{ + TTF_Font *tmpfont = NULL; + float fontsize; + + // If a font is currently loaded, unload it. + if (currentfont) + { + TTF_CloseFont(currentfont); + } + + // Scale the specified font point size for the current resolution. + fontsize = (ptsize * 0.005f) * (res.width - res.height); + + tmpfont = TTF_OpenFont(file, fontsize); + + if (!tmpfont) + return FONTHANDLE; + + // set pointer for current font + currentfont = tmpfont; + + // set current font point size + currentfontpoint = ptsize; + + // get font properties, and set them + currentfontstyle = TTF_GetFontStyle(currentfont); + TTF_SetFontStyle(currentfont, currentfontstyle); + + // these functions only exist in SDL_ttf 2.0.10 onwards +#if SDL_TTF_VERSION_ATLEAST(2,0,10) + currentfontkerning = TTF_GetFontKerning(currentfont); + TTF_SetFontKerning(currentfont, currentfontkerning); + + currentfonthinting = TTF_GetFontHinting(currentfont); + TTF_SetFontHinting(currentfont, currentfonthinting); + + currentfontoutline = TTF_GetFontOutline(currentfont); + TTF_SetFontOutline(currentfont, currentfontoutline); +#endif + + return 0; +} + +static void I_TTFRendSurface(const char *textmsg, TTF_Font *font, TextQuality quality, SDL_Color fontfgcolor, SDL_Color fontbgcolor) +{ + // Print text in the buffer. + // SDL_ttf has three modes to draw text. + // Solid rendering is quick, but dirty. Use it if you need speed more than quality. + switch (quality) + { + case solid: + TTFRendSurface = TTF_RenderText_Solid(font, textmsg, fontfgcolor); + break; + // Shaded rendering adds a background to the rendered text. Because of this, I_TTFDrawText + // takes an extra color more than the other styles to be a background color. + // Shaded is supposedly as fast as solid rendering and about as good quality as blended. + case shaded: + TTFRendSurface = TTF_RenderText_Shaded(font, textmsg, fontfgcolor, fontbgcolor); + break; + // Blended rendering is the opposite of solid. Good quality, but slow. + case blended: + TTFRendSurface = TTF_RenderText_Blended(font, textmsg, fontfgcolor); + break; + } + + // Get SDL to update the main surface. + SDL_BlitSurface(TTFRendSurface, NULL, TTFSurface, &TTFRect); + SDL_Flip(TTFSurface); +} + +// Draw text to screen. It will accept four colour vales (red, green, blue and alpha) +// with foreground for draw modes Solid and Blended, and an extra four values for background +// colour with draw type Shaded. +void I_TTFDrawText(TTF_Font *font, TextQuality quality, INT32 fgR, INT32 fgG, INT32 fgB, INT32 fgA, INT32 bgR, INT32 bgG, INT32 bgB, INT32 bgA, const char *textmsg) +{ + // Temporary small buffer to store character to process. + // NULL pointer to prevc to kill warning + char c, prevc = 0x0; + // hack to allow TTF_SizeText to work properly. + char linebuffer[2]; + // Don't need h, but TTF_SizeText needs a height parameter + INT32 w, h; + + // Globally declare foreground and background text colours, + // text drawing mode and the font to draw. + SDL_Color fontfgcolor = {fgR, fgG, fgB, fgA}; + SDL_Color fontbgcolor = {bgR, bgG, bgB, bgA}; + + // Keep on processing until the null terminator in the text buffer is reached. + while (*textmsg != '\0') + { + // Copy pointer for current character into the temporary buffer. + c = *textmsg; + // If c is a newline, move to the next available line. + if (c == '\n') + { + TTFRectCheck.x = 0; + TTFRectCheck.y += (currentfontpoint + 1); + } + // Otherwise... + else + { + // If the previous character was a newline, actually move to the next line. + if (prevc == '\n') + { + if (textbuffer != NULL) + { + // Render cached text to the SDL surface. + I_TTFRendSurface(textbuffer, font, quality, fontfgcolor, fontbgcolor); + // Empty text buffer. + memset(textbuffer, '\0', 1); + } + TTFRect.x = TTFRectCheck.x; + TTFRect.y = TTFRectCheck.y; + } + // Copy the character to the text buffer. + sprintf(textbuffer, "%s%c", textbuffer, c); + // Hack to allow TTF_SizeText to work properly. + sprintf(linebuffer, "%c", c); + // If we have reached the end of the screen, move to the next available line. + TTF_SizeText(currentfont, linebuffer, &w, &h); + TTFRectCheck.x += w; + if (TTFRectCheck.x >= res.width) + { + // Render cached text to the SDL surface. + I_TTFRendSurface(textbuffer, font, quality, fontfgcolor, fontbgcolor); + // Empty text buffer. + memset(textbuffer, '\0', 1); + // Move to the next line. + TTFRectCheck.x = 0; + TTFRectCheck.y += (currentfontpoint + 1); + // Set stored co-ordinates for next line. + TTFRect.x = TTFRectCheck.x; + TTFRect.y = TTFRectCheck.y; + } + } + // Add 1 to the pointer reference for the character to process. + textmsg++; + // Copy contents of the now-old buffer to somewhere else, so it can be referenced in next loop. + prevc = c; + } + + // If the buffer was previously emptied by a line wrapping operation and + // no text came after that, don't print anything. Otherwise, print everything + // still in the buffer. + if (textbuffer != NULL) + { + // Render cached text to the SDL surface. + I_TTFRendSurface(textbuffer, font, quality, fontfgcolor, fontbgcolor); + // Empty text buffer. + memset(textbuffer, '\0', 1); + // Set stored co-ordinates for next line. + TTFRect.x = TTFRectCheck.x; + TTFRect.y = TTFRectCheck.y; + } +} + +// Initialise SDL_ttf. +void I_StartupTTF(UINT32 fontpointsize, Uint32 initflags, Uint32 vidmodeflags) +{ + char *fontpath = NULL; + INT32 fontstatus = -1; +#ifdef _PS3 + videoState state; + videoGetState(0, 0, &state); + videoGetResolution(state.displayMode.resolution, &res); + bitsperpixel = 24; +#else + res.width = 320; + res.height = 200; + bitsperpixel = 8; +#endif + + // what's the point of trying to display an error? + // SDL_ttf is not started, can't display anything to screen (presumably)... + if (SDL_InitSubSystem(initflags) < 0) + I_Error("Couldn't initialize SDL: %s\n", SDL_GetError()); + + TTFSurface = SDL_SetVideoMode(res.width, res.height, bitsperpixel, vidmodeflags); + if (!TTFSurface) + I_Error("Couldn't set SDL Video resolution: %s\n", SDL_GetError()); + + if (TTF_Init() < 0) + I_Error("Couldn't start SDL_ttf: %s\n", TTF_GetError()); + + // look for default font in many directories +#ifdef FONTSEARCHPATH1 + fontpath = searchFont(FONTSEARCHPATH1); + if (fontpath) fontstatus = I_TTFLoadFont(fontpath, fontpointsize); +#endif +#ifdef FONTSEARCHPATH2 + if (fontstatus < 0) + { + fontpath = searchFont(FONTSEARCHPATH2); + if (fontpath) fontstatus = I_TTFLoadFont(fontpath, fontpointsize); + } +#endif +#ifdef FONTSEARCHPATH3 + if (fontstatus < 0) + { + fontpath = searchFont(FONTSEARCHPATH3); + if (fontpath) fontstatus = I_TTFLoadFont(fontpath, fontpointsize); + } +#endif +#ifdef FONTSEARCHPATH4 + if (fontstatus < 0) + { + fontpath = searchFont(FONTSEARCHPATH4); + if (fontpath) fontstatus = I_TTFLoadFont(fontpath, fontpointsize); + } +#endif +#ifdef FONTSEARCHPATH5 + if (fontstatus < 0) + { + fontpath = searchFont(FONTSEARCHPATH5); + if (fontpath) fontstatus = I_TTFLoadFont(fontpath, fontpointsize); + } +#endif +#ifdef FONTSEARCHPATH6 + if (fontstatus < 0) + { + fontpath = searchFont(FONTSEARCHPATH6); + if (fontpath) fontstatus = I_TTFLoadFont(fontpath, fontpointsize); + } +#endif +#ifdef FONTSEARCHPATH7 + if (fontstatus < 0) + { + fontpath = searchFont(FONTSEARCHPATH7); + if (fontpath) fontstatus = I_TTFLoadFont(fontpath, fontpointsize); + } +#endif + // argh! no font file found! disable SDL_ttf code + if (fontstatus < 0) + { + I_ShutdownTTF(); + CONS_Printf("Unable to find default font files! Not loading SDL_ttf\n"); + } + else + { + // Get SDL_ttf compiled and linked version + SDL_version TTFcompiled; + const SDL_version *TTFlinked; + + SDL_TTF_VERSION(&TTFcompiled); + TTFlinked = TTF_Linked_Version(); + + // Display it on screen + CONS_Printf("Compiled for SDL_ttf version: %d.%d.%d\n", + TTFcompiled.major, TTFcompiled.minor, TTFcompiled.patch); + CONS_Printf("Linked with SDL_ttf version: %d.%d.%d\n", + TTFlinked->major, TTFlinked->minor, TTFlinked->patch); + } +} + +void I_ShutdownTTF(void) +{ + // close current font + TTF_CloseFont(currentfont); + // shutdown SDL_ttf + TTF_Quit(); + + // Free TTF rendering surfaces. + SDL_FreeSurface(TTFSurface); + SDL_FreeSurface(TTFRendSurface); +} +#endif diff --git a/src/sdl12/i_ttf.h b/src/sdl12/i_ttf.h new file mode 100644 index 000000000..929c8021c --- /dev/null +++ b/src/sdl12/i_ttf.h @@ -0,0 +1,88 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 2011 by Callum Dickinson. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief SDL_ttf interface code. Necessary for platforms with SDL inits that need to run immediately. + +#ifndef __I_TTF__ +#define __I_TTF__ + +#include "../doomdef.h" +#include "SDL_ttf.h" + +// Default name for standard TTF file. +#define FONTFILE "srb2.ttf" +#define FONTPOINTSIZE 12 + +// Default font foreground colours +#define DEFAULTFONTFGR 255 +#define DEFAULTFONTFGG 255 +#define DEFAULTFONTFGB 255 +#define DEFAULTFONTFGA 255 + +// Default font background colours +#define DEFAULTFONTBGR 0 +#define DEFAULTFONTBGG 0 +#define DEFAULTFONTBGB 0 +#define DEFAULTFONTBGA 255 + +#ifndef SDL_TTF_COMPILEDVERSION +#define SDL_TTF_COMPILEDVERSION \ + SDL_VERSIONNUM(TTF_MAJOR_VERSION, TTF_MINOR_VERSION, TTF_PATCHLEVEL) +#endif + +#ifndef SDL_TTF_VERSION_ATLEAST +#define SDL_TTF_VERSION_ATLEAST(X, Y, Z) \ + (SDL_TTF_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) +#endif + +TTF_Font* currentfont; +int currentfontpoint; +int currentfontstyle; +#if SDL_TTF_VERSION_ATLEAST(2,0,10) +int currentfontkerning; +int currentfonthinting; +int currentfontoutline; +#endif + +#ifndef _PS3 +typedef struct +{ + UINT16 width; + UINT16 height; +} VideoResolution; +#endif +UINT8 bitsperpixel; + +typedef enum +{ + solid, + shaded, + blended +} TextQuality; + +// Load TTF font from file. +INT32 I_TTFLoadFont(const char *file, UINT32 ptsize); + +// Draw TTF text to screen. It will accept four colour vales (red, green, blue and alpha) +// with foreground for draw modes Solid and Blended, and an extra four values for background +// colour with draw type Shaded. +void I_TTFDrawText(TTF_Font *font, TextQuality quality, INT32 fgR, INT32 fgG, INT32 fgB, INT32 fgA, INT32 bgR, INT32 bgG, INT32 bgB, INT32 bgA, const char *textmsg); + +// Initialise SDL_ttf. +void I_StartupTTF(UINT32 fontpointsize, Uint32 initflags, Uint32 vidmodeflags); + +void I_ShutdownTTF(void); +#endif diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c new file mode 100644 index 000000000..1a2305fef --- /dev/null +++ b/src/sdl12/i_video.c @@ -0,0 +1,2100 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1993-1996 by id Software, Inc. +// Portions Copyright (C) 1998-2000 by DooM Legacy Team. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief SRB2 graphics stuff for SDL + +#include + +#ifndef _WIN32_WCE +#include +#endif + +#ifdef _MSC_VER +#pragma warning(disable : 4214 4244) +#endif + +#ifdef SDL + +#include "SDL.h" + +#ifdef _MSC_VER +#pragma warning(default : 4214 4244) +#endif + +#if SDL_VERSION_ATLEAST(1,2,9) && defined (_arch_dreamcast) +#define HAVE_DCSDL +#include "SDL_dreamcast.h" +#endif + +#if SDL_VERSION_ATLEAST(1,2,9) && defined (GP2X) +#define HAVE_GP2XSDL +#include "SDL_gp2x.h" +#endif + +#if SDL_VERSION_ATLEAST(1,3,0) +#define SDLK_EQUALS SDLK_KP_EQUALSAS400 +#define SDLK_LMETA SDLK_LGUI +#define SDLK_RMETA SDLK_RGUI +#else +#define HAVE_SDLMETAKEYS +#endif + +#ifdef HAVE_TTF +#include "i_ttf.h" +#endif + +#ifdef HAVE_IMAGE +#include "SDL_image.h" +#elseif !(defined (DC) || defined (_WIN32_WCE) || defined (PSP) || defined(GP2X)) +#define LOAD_XPM //I want XPM! +#include "IMG_xpm.c" //Alam: I don't want to add SDL_Image.dll/so +#define HAVE_IMAGE //I have SDL_Image, sortof +#endif + +#ifdef HAVE_IMAGE +#include "SDL_icon.xpm" +#endif + +#include "../doomdef.h" + +#if defined (_WIN32) && !defined (_XBOX) +#include "SDL_syswm.h" +#endif + +#ifdef _arch_dreamcast +#include +#include +#include +//#include "SRB2DC/VMU.xbm" +//#include +//#define malloc pvr_mem_malloc +//#define free pvr_mem_free +#endif + +#if defined (_XBOX) && defined (__GNUC__) +#include +#endif + +#include "../doomstat.h" +#include "../i_system.h" +#include "../v_video.h" +#include "../m_argv.h" +#include "../m_menu.h" +#include "../d_main.h" +#include "../s_sound.h" +#include "../i_sound.h" // midi pause/unpause +#include "../i_joy.h" +#include "../st_stuff.h" +#include "../g_game.h" +#include "../i_video.h" +#include "../console.h" +#include "../command.h" +#include "sdlmain.h" +#ifdef HWRENDER +#include "../hardware/hw_main.h" +#include "../hardware/hw_drv.h" +// For dynamic referencing of HW rendering functions +#include "hwsym_sdl.h" +#include "ogl_sdl.h" +#endif + +#ifdef REMOTE_DEBUGGING +#ifdef _WII +#include +#endif +#endif + +#ifdef HAVE_FILTER +#define FILTERS +#include "filter/filters.h" +#endif + +// maximum number of windowed modes (see windowedModes[][]) +#if defined (_WIN32_WCE) || defined (DC) || defined (PSP) || defined(GP2X) +#define MAXWINMODES (1) +#elif defined (WII) +#define MAXWINMODES (8) +#elif defined (_PS3) +#define MAXWINMODES (26) +#else +#define MAXWINMODES (27) +#endif + +/** \brief +*/ +static INT32 numVidModes = -1; + +/** \brief +*/ +static char vidModeName[33][32]; // allow 33 different modes + +rendermode_t rendermode=render_soft; + +boolean highcolor = false; + +// synchronize page flipping with screen refresh +#if defined(DC) || (defined(GP2X) && !defined(HAVE_GP2XSDL)) +consvar_t cv_vidwait = {"vid_wait", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +#else +consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +#endif +static consvar_t cv_stretch = {"stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +UINT8 graphics_started = 0; // Is used in console.c and screen.c + +// To disable fullscreen at startup; is set in VID_PrepareModeList +boolean allow_fullscreen = false; +static SDL_bool disable_fullscreen = SDL_FALSE; +#define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value +static SDL_bool disable_mouse = SDL_FALSE; +#define USE_MOUSEINPUT (!disable_mouse && cv_usemouse.value && SDL_GetAppState() & SDL_APPACTIVE) +#define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menuactive && !USE_FULLSCREEN) +#define MOUSEBUTTONS_MAX MOUSEBUTTONS + +// first entry in the modelist which is not bigger than MAXVIDWIDTHxMAXVIDHEIGHT +static INT32 firstEntry = 0; + +// SDL vars +#ifndef HWRENDER //[segabor] !!! I had problem compiling this source with gcc 3.3 +static SDL_Surface *vidSurface = NULL; +#endif +static SDL_Surface *bufSurface = NULL; +static SDL_Surface *icoSurface = NULL; +static SDL_Color localPalette[256]; +static SDL_Rect **modeList = NULL; +#ifdef DC +static Uint8 BitsPerPixel = 15; +#else +static Uint8 BitsPerPixel = 16; +#endif +static Uint16 realwidth = BASEVIDWIDTH; +static Uint16 realheight = BASEVIDHEIGHT; +#ifdef _WIN32_WCE +static const Uint32 surfaceFlagsW = SDL_HWPALETTE; //Can't handle WinCE changing sides +#else +static const Uint32 surfaceFlagsW = SDL_HWPALETTE/*|SDL_RESIZABLE*/; +#endif +#ifdef _PSP +static const Uint32 surfaceFlagsF = SDL_HWSURFACE|SDL_FULLSCREEN; +#else +static const Uint32 surfaceFlagsF = SDL_HWPALETTE|SDL_FULLSCREEN; +#endif +static SDL_bool mousegrabok = SDL_TRUE; +#define HalfWarpMouse(x,y) SDL_WarpMouse((Uint16)(x/2),(Uint16)(y/2)) +#if defined (_WIN32_WCE) || defined (DC) || defined (PSP) || defined(GP2X) +static SDL_bool videoblitok = SDL_TRUE; +#else +static SDL_bool videoblitok = SDL_FALSE; +#endif +static SDL_bool exposevideo = SDL_FALSE; + +// windowed video modes from which to choose from. +static INT32 windowedModes[MAXWINMODES][2] = +{ +#if !(defined (_WIN32_WCE) || defined (DC) || defined (PSP) || defined (GP2X)) +#ifndef WII +#ifndef _PS3 + {1920,1200}, // 1.60,6.00 +#endif + {1680,1050}, // 1.60,5.25 + {1600,1200}, // 1.33,5.00 + {1600,1000}, // 1.60,5.00 + {1536,1152}, // 1.33,4.80 + {1536, 960}, // 1.60,4.80 + {1440, 900}, // 1.60,4.50 + {1400,1050}, // 1.33,4.375 + {1400, 875}, // 1.60,4.375 + {1360, 850}, // 1.60,4.25 + {1280, 960}, // 1.33,4.00 + {1280, 800}, // 1.60,4.00 + {1152, 864}, // 1.33,3.60 + {1120, 700}, // 1.60,3.50 + {1024, 768}, // 1.33,3.20 + { 960, 720}, // 1.33,3.00 + { 960, 600}, // 1.60,3.00 + { 800, 600}, // 1.33,2.50 + { 800, 500}, // 1.60,2.50 +#endif + { 640, 480}, // 1.33,2.00 + { 640, 400}, // 1.60,2.00 + { 576, 432}, // 1.33,1.80 + { 512, 384}, // 1.33,1.60 + { 416, 312}, // 1.33,1.30 + { 400, 300}, // 1.33,1.25 + { 320, 240}, // 1.33,1.00 +#endif + { 320, 200}, // 1.60,1.00 +}; + +static void SDLSetMode(INT32 width, INT32 height, INT32 bpp, Uint32 flags) +{ + const char *SDLVD = I_GetEnv("SDL_VIDEODRIVER"); +#ifdef _WIN32_WCE + if (bpp < 16) + bpp = 16; // 256 mode poo +#endif +#ifdef _WII + bpp = 16; // 8-bit mode poo +#endif +#ifdef DC + if (bpp < 15) + bpp = 15; + height = 240; +#endif +#ifdef PSP + bpp = 16; +#endif +#ifdef GP2X + bpp = 16; +#ifdef HAVE_GP2XSDL + height = 240; +#endif +#endif +#ifdef FILTERS + bpp = Setupf2x(width, height, bpp); +#endif + if (SDLVD && strncasecmp(SDLVD,"glSDL",6) == 0) //for glSDL videodriver + vidSurface = SDL_SetVideoMode(width, height,0,SDL_DOUBLEBUF); +#ifdef _WII // don't want it to use HWSURFACE, so make it first here + else if (SDL_VideoModeOK(width, height, bpp, flags|SDL_SWSURFACE|SDL_DOUBLEBUF) >= bpp) // SDL Wii uses double buffering + vidSurface = SDL_SetVideoMode(width, height, bpp, flags|SDL_SWSURFACE|SDL_DOUBLEBUF); +#endif + else if (cv_vidwait.value && videoblitok && SDL_VideoModeOK(width, height, bpp, flags|SDL_HWSURFACE|SDL_DOUBLEBUF) >= bpp) + vidSurface = SDL_SetVideoMode(width, height, bpp, flags|SDL_HWSURFACE|SDL_DOUBLEBUF); + else if (videoblitok && SDL_VideoModeOK(width, height, bpp, flags|SDL_HWSURFACE) >= bpp) + vidSurface = SDL_SetVideoMode(width, height, bpp, flags|SDL_HWSURFACE); + else if (SDL_VideoModeOK(width, height, bpp, flags|SDL_SWSURFACE) >= bpp) + vidSurface = SDL_SetVideoMode(width, height, bpp, flags|SDL_SWSURFACE); + else return; + realwidth = (Uint16)width; + realheight = (Uint16)height; +#ifdef HAVE_DCSDL + //SDL_DC_SetWindow(320,200); + SDL_DC_EmulateMouse(SDL_FALSE); + SDL_DC_EmulateKeyboard(SDL_TRUE); +#endif +#ifdef HAVE_GP2XSDL + SDL_ShowCursor(SDL_DISABLE); //For GP2X Open2x +#endif +#ifdef FILTERS + if (vidSurface && preSurface && f2xSurface) + { + vid.width = width/2; + vid.height = height/2; + } +#endif +} + +// +// Translates the SDL key into SRB2 key +// + +static INT32 SDLatekey(SDLKey sym) +{ + INT32 rc = sym + 0x80; + +#ifdef _WIN32_WCE + if (sym == SDLK_KP8) + sym = SDLK_UP; + else if (sym == SDLK_KP4) + sym = SDLK_LEFT; + else if (sym == SDLK_KP6) + sym = SDLK_RIGHT; + else if (sym == SDLK_KP2) + sym = SDLK_DOWN; +#endif + + switch (sym) + { + case SDLK_LEFT: + rc = KEY_LEFTARROW; + break; + case SDLK_RIGHT: + rc = KEY_RIGHTARROW; + break; + case SDLK_DOWN: + rc = KEY_DOWNARROW; + break; + case SDLK_UP: + rc = KEY_UPARROW; + break; + + case SDLK_ESCAPE: + rc = KEY_ESCAPE; + break; + case SDLK_SPACE: + rc = KEY_SPACE; + break; + case SDLK_RETURN: + case SDLK_KP_ENTER: + rc = KEY_ENTER; + break; + case SDLK_TAB: + rc = KEY_TAB; + break; + case SDLK_F1: + rc = KEY_F1; + break; + case SDLK_F2: + rc = KEY_F2; + break; + case SDLK_F3: + rc = KEY_F3; + break; + case SDLK_F4: + rc = KEY_F4; + break; + case SDLK_F5: + rc = KEY_F5; + break; + case SDLK_F6: + rc = KEY_F6; + break; + case SDLK_F7: + rc = KEY_F7; + break; + case SDLK_F8: + rc = KEY_F8; + break; + case SDLK_F9: + rc = KEY_F9; + break; + case SDLK_F10: + rc = KEY_F10; + break; + case SDLK_F11: + rc = KEY_F11; + break; + case SDLK_F12: + rc = KEY_F12; + break; + + case SDLK_BACKSPACE: + rc = KEY_BACKSPACE; + break; + case SDLK_DELETE: + rc = KEY_DEL; + break; + + case SDLK_KP_EQUALS: //Alam & Logan: WTF? Mac KB haves one! XD + case SDLK_PAUSE: + rc = KEY_PAUSE; + break; + + case SDLK_EQUALS: + case SDLK_PLUS: + rc = KEY_EQUALS; + break; + + case SDLK_MINUS: + rc = KEY_MINUS; + break; + + case SDLK_LSHIFT: + rc = KEY_LSHIFT; + break; + + case SDLK_RSHIFT: + rc = KEY_RSHIFT; + break; + + case SDLK_CAPSLOCK: + rc = KEY_CAPSLOCK; + break; + + case SDLK_LCTRL: + rc = KEY_LCTRL; + break; + case SDLK_RCTRL: + rc = KEY_RCTRL; + break; + + case SDLK_LALT: + rc = KEY_LALT; + break; + case SDLK_RALT: + rc = KEY_RALT; + break; + + case SDLK_NUMLOCK: + rc = KEY_NUMLOCK; + break; + case SDLK_SCROLLOCK: + rc = KEY_SCROLLLOCK; + break; + + case SDLK_PAGEUP: + rc = KEY_PGUP; + break; + case SDLK_PAGEDOWN: + rc = KEY_PGDN; + break; + case SDLK_END: + rc = KEY_END; + break; + case SDLK_HOME: + rc = KEY_HOME; + break; + case SDLK_INSERT: + rc = KEY_INS; + break; + + case SDLK_KP0: + rc = KEY_KEYPAD0; + break; + case SDLK_KP1: + rc = KEY_KEYPAD1; + break; + case SDLK_KP2: + rc = KEY_KEYPAD2; + break; + case SDLK_KP3: + rc = KEY_KEYPAD3; + break; + case SDLK_KP4: + rc = KEY_KEYPAD4; + break; + case SDLK_KP5: + rc = KEY_KEYPAD5; + break; + case SDLK_KP6: + rc = KEY_KEYPAD6; + break; + case SDLK_KP7: + rc = KEY_KEYPAD7; + break; + case SDLK_KP8: + rc = KEY_KEYPAD8; + break; + case SDLK_KP9: + rc = KEY_KEYPAD9; + break; + + case SDLK_KP_PERIOD: + rc = KEY_KPADDEL; + break; + case SDLK_KP_DIVIDE: + rc = KEY_KPADSLASH; + break; + case SDLK_KP_MULTIPLY: + rc = '*'; + break; + case SDLK_KP_MINUS: + rc = KEY_MINUSPAD; + break; + case SDLK_KP_PLUS: + rc = KEY_PLUSPAD; + break; + +#ifndef _arch_dreamcast + case SDLK_LSUPER: +#ifdef HAVE_SDLMETAKEYS + case SDLK_LMETA: +#endif + rc = KEY_LEFTWIN; + break; + case SDLK_RSUPER: +#ifdef HAVE_SDLMETAKEYS + case SDLK_RMETA: +#endif + rc = KEY_RIGHTWIN; + break; + + case SDLK_MENU: + rc = KEY_MENU; + break; +#endif + + default: + if (sym >= SDLK_SPACE && sym <= SDLK_DELETE) + rc = sym - SDLK_SPACE + ' '; + else if (sym >= 'A' && sym <= 'Z') + rc = sym - 'A' + 'a'; + else if (sym) + { + I_OutputMsg("Unknown Keycode %i, Name: %s\n",sym, SDL_GetKeyName( sym )); + } + else if (!sym) rc = 0; + break; + } + + return rc; +} + +static void SDLdoUngrabMouse(void) +{ + if (SDL_GRAB_ON == SDL_WM_GrabInput(SDL_GRAB_QUERY)) + { + SDL_WM_GrabInput(SDL_GRAB_OFF); + } +} + +void SDLforceUngrabMouse(void) +{ + if (SDL_WasInit(SDL_INIT_VIDEO)==SDL_INIT_VIDEO) + SDL_WM_GrabInput(SDL_GRAB_OFF); +} + +static void VID_Command_NumModes_f (void) +{ + CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), VID_NumModes()); +} + +static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText) +{ + INT32 vfBPP; + const SDL_Surface *VidSur = SDL_GetVideoSurface(); + + if (!infoSurface) + return; + + if (!SurfaceText) + SurfaceText = M_GetText("Unknown Surface"); + + vfBPP = infoSurface->format?infoSurface->format->BitsPerPixel:0; + + CONS_Printf("\x82" "%s\n", SurfaceText); + CONS_Printf(M_GetText(" %ix%i at %i bit color\n"), infoSurface->w, infoSurface->h, vfBPP); + + if (infoSurface->flags&SDL_HWSURFACE) + CONS_Printf("%s", M_GetText(" Stored in video memory\n")); + else if (infoSurface->flags&SDL_OPENGL) + CONS_Printf("%s", M_GetText(" Stored in an OpenGL context\n")); + else if (infoSurface->flags&SDL_PREALLOC) + CONS_Printf("%s", M_GetText(" Uses preallocated memory\n")); + else + CONS_Printf("%s", M_GetText(" Stored in system memory\n")); + + if (infoSurface->flags&SDL_ASYNCBLIT) + CONS_Printf("%s", M_GetText(" Uses asynchronous blits if possible\n")); + else + CONS_Printf("%s", M_GetText(" Uses synchronous blits if possible\n")); + + if (infoSurface->flags&SDL_ANYFORMAT) + CONS_Printf("%s", M_GetText(" Allows any pixel-format\n")); + + if (infoSurface->flags&SDL_HWPALETTE) + CONS_Printf("%s", M_GetText(" Has exclusive palette access\n")); + else if (VidSur == infoSurface) + CONS_Printf("%s", M_GetText(" Has nonexclusive palette access\n")); + + if (infoSurface->flags&SDL_DOUBLEBUF) + CONS_Printf("%s", M_GetText(" Double buffered\n")); + else if (VidSur == infoSurface) + CONS_Printf("%s", M_GetText(" No hardware flipping\n")); + + if (infoSurface->flags&SDL_FULLSCREEN) + CONS_Printf("%s", M_GetText(" Full screen\n")); + else if (infoSurface->flags&SDL_RESIZABLE) + CONS_Printf("%s", M_GetText(" Resizable window\n")); + else if (VidSur == infoSurface) + CONS_Printf("%s", M_GetText(" Nonresizable window\n")); + + if (infoSurface->flags&SDL_HWACCEL) + CONS_Printf("%s", M_GetText(" Uses hardware acceleration blit\n")); + if (infoSurface->flags&SDL_SRCCOLORKEY) + CONS_Printf("%s", M_GetText(" Use colorkey blitting\n")); + if (infoSurface->flags&SDL_RLEACCEL) + CONS_Printf("%s", M_GetText(" Colorkey RLE acceleration blit\n")); + if (infoSurface->flags&SDL_SRCALPHA) + CONS_Printf("%s", M_GetText(" Use alpha blending acceleration blit\n")); + +} + +static void VID_Command_Info_f (void) +{ + const SDL_VideoInfo *videoInfo; + videoInfo = SDL_GetVideoInfo(); //Alam: Double-Check + if (videoInfo) + { + CONS_Printf("%s", M_GetText("Video Interface Capabilities:\n")); + if (videoInfo->hw_available) + CONS_Printf("%s", M_GetText(" Hardware surfaces\n")); + if (videoInfo->wm_available) + CONS_Printf("%s", M_GetText(" Window manager\n")); + //UnusedBits1 :6 + //UnusedBits2 :1 + if (videoInfo->blit_hw) + CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW\n")); + if (videoInfo->blit_hw_CC) + CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW with Colorkey\n")); + if (videoInfo->wm_available) + CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW with Alpha\n")); + if (videoInfo->blit_sw) + { + CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW\n")); + if (!M_CheckParm("-noblit")) videoblitok = SDL_TRUE; + } + if (videoInfo->blit_sw_CC) + CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW with Colorkey\n")); + if (videoInfo->blit_sw_A) + CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW with Alpha\n")); + if (videoInfo->blit_fill) + CONS_Printf("%s", M_GetText(" Accelerated Color filling\n")); + //UnusedBits3 :16 + if (videoInfo->video_mem) + CONS_Printf(M_GetText(" There is %i KB of video memory\n"), videoInfo->video_mem); + else + CONS_Printf("%s", M_GetText(" There no video memory for SDL\n")); + //*vfmt + } + SurfaceInfo(bufSurface, M_GetText("Current Engine Mode")); +#ifdef FILTERS + SurfaceInfo(preSurface, M_GetText("Prebuffer Mode")); + SurfaceInfo(f2xSurface, M_GetText("Postbuffer Mode")); +#endif + SurfaceInfo(vidSurface, M_GetText("Current Video Mode")); +} + +static void VID_Command_ModeList_f(void) +{ +#if !defined (DC) && !defined (_WIN32_WCE) && !defined (_PSP) && !defined(GP2X) + INT32 i; +#ifdef HWRENDER + if (rendermode == render_opengl) + modeList = SDL_ListModes(NULL, SDL_OPENGL|SDL_FULLSCREEN); + else +#endif + modeList = SDL_ListModes(NULL, surfaceFlagsF|SDL_HWSURFACE); //Alam: At least hardware surface + + if (modeList == (SDL_Rect **)0 && cv_fullscreen.value) + { + CONS_Printf("%s", M_GetText("No video modes present\n")); + cv_fullscreen.value = 0; + } + else if (modeList != (SDL_Rect **)0) + { + numVidModes = 0; + if (modeList == (SDL_Rect **)-1) + numVidModes = -1; // should not happen with fullscreen modes + else while (modeList[numVidModes]) + numVidModes++; + } + CONS_Printf(M_GetText("Found %d FullScreen Video Modes:\n"), numVidModes); + for (i=0 ; i= numVidModes) + break; + + CONS_Printf(M_GetText("%dx%d and "), + modeList[modeNum]->w, + modeList[modeNum]->h); + } + CONS_Printf("%s", M_GetText("None\n")); +#endif +} + +static void VID_Command_Mode_f (void) +{ + INT32 modenum; + + if (COM_Argc()!= 2) + { + CONS_Printf(M_GetText("vid_mode : set video mode, current video mode %i\n"), vid.modenum); + return; + } + + modenum = atoi(COM_Argv(1)); + + if (modenum >= VID_NumModes()) + CONS_Printf(M_GetText("Video mode not present\n")); + else + setmodeneeded = modenum+1; // request vid mode change +} + +#if defined(RPC_NO_WINDOWS_H) && !defined(_WIN32_WCE) +static VOID MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + UNREFERENCED_PARAMETER(hWnd); + UNREFERENCED_PARAMETER(message); + UNREFERENCED_PARAMETER(wParam); + switch (message) + { + case WM_SETTEXT: + COM_BufAddText((LPCSTR)lParam); + break; + } +} +#endif + +#if 0 //#ifdef _WIN32 + // Disable Composition in Vista DWM (Desktop Window Manager) ---------------- +static HMODULE DMdll = NULL; +typedef HRESULT (CALLBACK *P_DwmIsCompositionEnabled) (BOOL *pfEnabled); +static P_DwmIsCompositionEnabled pfnDwmIsCompositionEnabled = NULL; +typedef HRESULT (CALLBACK *P_DwmEnableComposition) (BOOL fEnable); +static P_DwmEnableComposition pfnDwmEnableComposition = NULL; +static BOOL AeroWasEnabled = FALSE; + +static inline VOID UnloadDM(VOID) +{ + pfnDwmEnableComposition = NULL; + pfnDwmIsCompositionEnabled = NULL; + if (DMdll) FreeLibrary(DMdll); + DMdll = NULL; +} + +static inline BOOL LoadDM(VOID) +{ + if (DMdll) + return TRUE; + + DMdll = LoadLibraryA("dwmapi.dll"); + if (DMdll) + I_OutputMsg("dmwapi.dll loaded, Vista's Desktop Window Manager API\n"); + else + return FALSE; + + pfnDwmIsCompositionEnabled = (P_DwmIsCompositionEnabled)GetProcAddress(DMdll, "DwmIsCompositionEnabled"); + if (pfnDwmIsCompositionEnabled) + I_OutputMsg("Composition Aero API found, DwmIsCompositionEnabled\n"); + + pfnDwmEnableComposition = (P_DwmEnableComposition)GetProcAddress(DMdll, "DwmEnableComposition"); + if (pfnDwmEnableComposition) + I_OutputMsg("Composition Aero API found, DwmEnableComposition\n"); + + return TRUE; +} + +static inline VOID DisableAero(VOID) +{ + BOOL pfnDwmEnableCompositiond = FALSE; + AeroWasEnabled = FALSE; + + if (!LoadDM()) + return; + + if (pfnDwmIsCompositionEnabled && SUCCEEDED(pfnDwmIsCompositionEnabled(&pfnDwmEnableCompositiond))) + I_OutputMsg("Got the result of DwmIsCompositionEnabled, %i\n", pfnDwmEnableCompositiond); + else + return; + + if ((AeroWasEnabled = pfnDwmEnableCompositiond)) + I_OutputMsg("Disable the Aero rendering\n"); + else + return; + + if (pfnDwmEnableComposition && SUCCEEDED(pfnDwmEnableComposition(FALSE))) + I_OutputMsg("Aero rendering disabled\n"); + else + I_OutputMsg("We failed to disable the Aero rendering\n"); +} + +static inline VOID ResetAero(VOID) +{ + if (pfnDwmEnableComposition && AeroWasEnabled) + { + if (SUCCEEDED(pfnDwmEnableComposition(AeroWasEnabled))) + I_OutputMsg("Aero rendering setting restored\n"); + else + I_OutputMsg("We failed to restore Aero rendering\n"); + } + UnloadDM(); +} +#endif + +static inline void SDLJoyRemap(event_t *event) +{ +#if defined(GP2X) +#define GP2X_BUTTON_UP (0) +#define GP2X_BUTTON_DOWN (4) +#define GP2X_BUTTON_LEFT (2) +#define GP2X_BUTTON_RIGHT (6) +#define GP2X_BUTTON_UPLEFT (1) +#define GP2X_BUTTON_UPRIGHT (7) +#define GP2X_BUTTON_DOWNLEFT (3) +#define GP2X_BUTTON_DOWNRIGHT (5) +#define GP2X_BUTTON_CLICK (18) +#define GP2X_BUTTON_A (12) +#define GP2X_BUTTON_B (13) +#define GP2X_BUTTON_X (14) +#define GP2X_BUTTON_Y (15) +#define GP2X_BUTTON_L (10) +#define GP2X_BUTTON_R (11) +#define GP2X_BUTTON_START (8) +#define GP2X_BUTTON_SELECT (9) +#define GP2X_BUTTON_VOLUP (16) +#define GP2X_BUTTON_VOLDOWN (17) + if ((event->type == ev_keydown || event->type == ev_keyup) && (KEY_JOY1 <= event->data1 && event->data1 <= KEY_JOY1+JOYBUTTONS)) + { + INT32 button = event->data1-KEY_JOY1; + if (button <= 7) + { + static UINT8 DPAD = 0; + if (event->type == ev_keyup) + { + event->type = ev_console; + DPAD &= ~(1<type = ev_joystick; + DPAD |= 1<data2 = event->data3 = INT32_MAX; + if ((DPAD & (1<type = ev_joystick; + event->data2 = event->data3 = 0; + } + else switch (button) + { + case GP2X_BUTTON_UP: + event->data3 = -1; + break; + case GP2X_BUTTON_DOWN: + event->data3 = 1; + break; + case GP2X_BUTTON_LEFT: + event->data2 = -1; + break; + case GP2X_BUTTON_RIGHT: + event->data2 = 1; + break; + case GP2X_BUTTON_UPLEFT: + event->data2 = -1; + event->data3 = -1; + break; + case GP2X_BUTTON_UPRIGHT: + event->data2 = 1; + event->data3 = -1; + break; + case GP2X_BUTTON_DOWNLEFT: + event->data2 = -1; + event->data3 = 1; + break; + case GP2X_BUTTON_DOWNRIGHT: + event->data2 = 1; + event->data3 = 1; + default: + break; + } + event->data1 = 0; + return; + } + else switch (button) + { + case GP2X_BUTTON_CLICK: + event->data1 = KEY_ENTER; + break; + case GP2X_BUTTON_A: + event->data1 = KEY_JOY1+0; + break; + case GP2X_BUTTON_B: + event->data1 = KEY_JOY1+2; + break; + case GP2X_BUTTON_X: + event->data1 = KEY_JOY1+3; + break; + case GP2X_BUTTON_Y: + event->data1 = KEY_JOY1+1; + break; + case GP2X_BUTTON_L: + event->data1 = KEY_JOY1+4; + break; + case GP2X_BUTTON_R: + event->data1 = KEY_JOY1+5; + break; + case GP2X_BUTTON_START: + event->data1 = KEY_ESCAPE; + break; + case GP2X_BUTTON_SELECT: + event->data1 = KEY_JOY1+8; + break; + case GP2X_BUTTON_VOLUP: + event->data1 = KEY_JOY1+6; + break; + case GP2X_BUTTON_VOLDOWN: + event->data1 = KEY_JOY1+7; + break; + default: + break; + } + //I_OutputMsg("Button %i: event key %i and type: %i\n", button, event->data1, event->type); + } +#elif defined(_PSP) + if (event->data1 > KEY_JOY1 + 9 + 2) // All button after D-Pad and Select/Start + event->data1 -= 4; // remap D-pad to Hats, offset of -4 + else if (event->data1 == KEY_JOY1 + 6) // Down + event->data1 = KEY_HAT1+1; + else if (event->data1 == KEY_JOY1 + 7) // Left + event->data1 = KEY_HAT1+2; + else if (event->data1 == KEY_JOY1 + 8) // Up + event->data1 = KEY_HAT1+0; + else if (event->data1 == KEY_JOY1 + 9) // Right + event->data1 = KEY_HAT1+3; + else if (event->data1 == KEY_JOY1 + 10) // Select + event->data1 = KEY_TAB; + else if (event->data1 == KEY_JOY1 + 11) // Start + event->data1 = KEY_ESCAPE; +#else + (void)event; +#endif +} + +static INT32 SDLJoyAxis(const Sint16 axis, evtype_t which) +{ +#ifdef _arch_dreamcast // -128 to 127 SDL for DC have give us a smaller range + INT32 raxis = axis*8; +#else // -32768 to 32767 + INT32 raxis = axis/32; +#endif + if (which == ev_joystick) + { + if (Joystick.bGamepadStyle) + { + // gamepad control type, on or off, live or die + if (raxis < -(JOYAXISRANGE/2)) + raxis = -1; + else if (raxis > (JOYAXISRANGE/2)) + raxis = 1; + else + raxis = 0; + } + else + { + raxis = JoyInfo.scale!=1?((raxis/JoyInfo.scale)*JoyInfo.scale):raxis; + +#ifdef SDL_JDEADZONE + if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE) + raxis = 0; +#endif + } + } + else if (which == ev_joystick2) + { + if (Joystick2.bGamepadStyle) + { + // gamepad control type, on or off, live or die + if (raxis < -(JOYAXISRANGE/2)) + raxis = -1; + else if (raxis > (JOYAXISRANGE/2)) + raxis = 1; + else raxis = 0; + } + else + { + raxis = JoyInfo2.scale!=1?((raxis/JoyInfo2.scale)*JoyInfo2.scale):raxis; + +#ifdef SDL_JDEADZONE + if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE) + raxis = 0; +#endif + } + } + return raxis; +} + +void I_GetEvent(void) +{ + SDL_Event inputEvent; + static SDL_bool sdlquit = SDL_FALSE; //Alam: once, just once + event_t event; + + if (!graphics_started) + return; + + memset(&inputEvent, 0x00, sizeof(inputEvent)); + while (SDL_PollEvent(&inputEvent)) + { + memset(&event,0x00,sizeof (event_t)); + switch (inputEvent.type) + { + case SDL_ACTIVEEVENT: + if (inputEvent.active.state & (SDL_APPACTIVE|SDL_APPINPUTFOCUS)) + { + // pause music when alt-tab + if (inputEvent.active.gain /*&& !paused */) + { + static SDL_bool firsttimeonmouse = SDL_TRUE; + if (!firsttimeonmouse) + { + if (cv_usemouse.value) I_StartupMouse(); + } + else firsttimeonmouse = SDL_FALSE; + //if (!netgame && !con_destlines) paused = false; + if (gamestate == GS_LEVEL) + if (!paused) I_ResumeSong(0); //resume it + } + else /*if (!paused)*/ + { + if (!disable_mouse) + SDLforceUngrabMouse(); + if (!netgame && gamestate == GS_LEVEL) paused = true; + memset(gamekeydown, 0, NUMKEYS); + //S_PauseSound(); + if (gamestate == GS_LEVEL) + I_PauseSong(0); //pause it + } + } + if (MOUSE_MENU) + { + SDLdoUngrabMouse(); + break; + } + if ((SDL_APPMOUSEFOCUS&inputEvent.active.state) && USE_MOUSEINPUT && inputEvent.active.gain) + HalfWarpMouse(realwidth, realheight); + break; + case SDL_KEYDOWN: + case SDL_KEYUP: + /// \todo inputEvent.key.which? + if (inputEvent.type == SDL_KEYUP) + event.type = ev_keyup; + else if (inputEvent.type == SDL_KEYDOWN) + event.type = ev_keydown; + else break; + event.data1 = SDLatekey(inputEvent.key.keysym.sym); + if (event.data1) D_PostEvent(&event); + break; + case SDL_MOUSEMOTION: + /// \todo inputEvent.motion.which + if (MOUSE_MENU) + { + SDLdoUngrabMouse(); + break; + } + if (USE_MOUSEINPUT) + { + // If the event is from warping the pointer back to middle + // of the screen then ignore it. + if ((inputEvent.motion.x == realwidth/2) && + (inputEvent.motion.y == realheight/2)) + { + break; + } + else + { + event.data2 = +inputEvent.motion.xrel; + event.data3 = -inputEvent.motion.yrel; + } + event.type = ev_mouse; + D_PostEvent(&event); + // Warp the pointer back to the middle of the window + // or we cannot move any further if it's at a border. + if ((inputEvent.motion.x < (realwidth/2 )-(realwidth/4 )) || + (inputEvent.motion.y < (realheight/2)-(realheight/4)) || + (inputEvent.motion.x > (realwidth/2 )+(realwidth/4 )) || + (inputEvent.motion.y > (realheight/2)+(realheight/4) ) ) + { + //if (SDL_GRAB_ON == SDL_WM_GrabInput(SDL_GRAB_QUERY) || !mousegrabok) + HalfWarpMouse(realwidth, realheight); + } + } + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + /// \todo inputEvent.button.which + if (USE_MOUSEINPUT) + { + if (inputEvent.type == SDL_MOUSEBUTTONUP) + event.type = ev_keyup; + else if (inputEvent.type == SDL_MOUSEBUTTONDOWN) + event.type = ev_keydown; + else break; + if (inputEvent.button.button==SDL_BUTTON_WHEELUP || inputEvent.button.button==SDL_BUTTON_WHEELDOWN) + { + if (inputEvent.type == SDL_MOUSEBUTTONUP) + event.data1 = 0; //Alam: dumb! this could be a real button with some mice + else + event.data1 = KEY_MOUSEWHEELUP + inputEvent.button.button - SDL_BUTTON_WHEELUP; + } + else if (inputEvent.button.button == SDL_BUTTON_MIDDLE) + event.data1 = KEY_MOUSE1+2; + else if (inputEvent.button.button == SDL_BUTTON_RIGHT) + event.data1 = KEY_MOUSE1+1; + else if (inputEvent.button.button <= MOUSEBUTTONS) + event.data1 = KEY_MOUSE1 + inputEvent.button.button - SDL_BUTTON_LEFT; + if (event.data1) D_PostEvent(&event); + } + break; + case SDL_JOYAXISMOTION: + inputEvent.jaxis.which++; + inputEvent.jaxis.axis++; + event.data1 = event.data2 = event.data3 = INT32_MAX; + if (cv_usejoystick.value == inputEvent.jaxis.which) + { + event.type = ev_joystick; + } + else if (cv_usejoystick.value == inputEvent.jaxis.which) + { + event.type = ev_joystick2; + } + else break; + //axis + if (inputEvent.jaxis.axis > JOYAXISSET*2) + break; + //vaule + if (inputEvent.jaxis.axis%2) + { + event.data1 = inputEvent.jaxis.axis / 2; + event.data2 = SDLJoyAxis(inputEvent.jaxis.value, event.type); + } + else + { + inputEvent.jaxis.axis--; + event.data1 = inputEvent.jaxis.axis / 2; + event.data3 = SDLJoyAxis(inputEvent.jaxis.value, event.type); + } + D_PostEvent(&event); + break; + case SDL_JOYBALLMOTION: + case SDL_JOYHATMOTION: + break; //NONE + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + inputEvent.jbutton.which++; + if (cv_usejoystick.value == inputEvent.jbutton.which) + event.data1 = KEY_JOY1; + else if (cv_usejoystick.value == inputEvent.jbutton.which) + event.data1 = KEY_2JOY1; + else break; + if (inputEvent.type == SDL_JOYBUTTONUP) + event.type = ev_keyup; + else if (inputEvent.type == SDL_JOYBUTTONDOWN) + event.type = ev_keydown; + else break; + if (inputEvent.jbutton.button < JOYBUTTONS) + event.data1 += inputEvent.jbutton.button; + else + break; + SDLJoyRemap(&event); + if (event.type != ev_console) D_PostEvent(&event); + break; +#ifndef _WIN32_WCE + case SDL_QUIT: + if (!sdlquit) + { + sdlquit = SDL_TRUE; + M_QuitResponse('y'); + } + break; +#endif +#if defined(RPC_NO_WINDOWS_H) && !defined(_WIN32_WCE) + case SDL_SYSWMEVENT: + MainWndproc(inputEvent.syswm.msg->hwnd, + inputEvent.syswm.msg->msg, + inputEvent.syswm.msg->wParam, + inputEvent.syswm.msg->lParam); + break; +#endif + case SDL_VIDEORESIZE: + if (gamestate == GS_LEVEL || gamestate == GS_TITLESCREEN || gamestate == GS_EVALUATION) + setmodeneeded = VID_GetModeForSize(inputEvent.resize.w,inputEvent.resize.h)+1; + if (render_soft == rendermode) + { +#ifdef FILTERS + INT32 filtervalue = cv_filter.value; + if (blitfilter) CV_SetValue(&cv_filter,1); +#endif + SDLSetMode(realwidth, realheight, vid.bpp*8, surfaceFlagsW); + if (vidSurface) SDL_SetColors(vidSurface, localPalette, 0, 256); +#ifdef FILTERS + CV_SetValue(&cv_filter,filtervalue); +#endif + } + else + SDLSetMode(realwidth, realheight, vid.bpp*8, surfaceFlagsW); + if (!vidSurface) + I_Error("Could not reset vidmode: %s\n",SDL_GetError()); + break; + case SDL_VIDEOEXPOSE: + exposevideo = SDL_TRUE; + break; + default: + break; + } + } + //reset wheel like in win32, I don't understand it but works + gamekeydown[KEY_MOUSEWHEELDOWN] = gamekeydown[KEY_MOUSEWHEELUP] = 0; +} + +void I_StartupMouse(void) +{ + static SDL_bool firsttimeonmouse = SDL_TRUE; + + if (disable_mouse) + return; + + if (!firsttimeonmouse) + HalfWarpMouse(realwidth, realheight); // warp to center + else + firsttimeonmouse = SDL_FALSE; + if (cv_usemouse.value) + return; + else + SDLdoUngrabMouse(); +} + +// +// I_OsPolling +// +void I_OsPolling(void) +{ + if (consolevent) + I_GetConsoleEvents(); + if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) + { + SDL_JoystickUpdate(); + I_GetJoystickEvents(); + I_GetJoystick2Events(); + } +#ifdef _arch_dreamcast + //vmu_set_icon(VMU_bits); +#endif + + I_GetMouseEvents(); + + I_GetEvent(); +} + +// +// I_UpdateNoBlit +// +void I_UpdateNoBlit(void) +{ + if (!vidSurface) + return; +#ifdef HWRENDER + if (rendermode != render_soft) + OglSdlFinishUpdate(cv_vidwait.value); + else +#endif + if (vidSurface->flags&SDL_DOUBLEBUF) + SDL_Flip(vidSurface); + else if (exposevideo) + SDL_UpdateRect(vidSurface, 0, 0, 0, 0); + exposevideo = SDL_FALSE; +} + +// I_SkipFrame +// +// Returns true if it thinks we can afford to skip this frame +// from PrBoom's src/SDL/i_video.c +static inline boolean I_SkipFrame(void) +{ + static boolean skip = false; + + if (render_soft != rendermode) + return false; + + skip = !skip; + +#if 0 //(defined (GP2X) || defined (PSP) || defined (_arch_dreamcast)) + return skip; +#endif + + switch (gamestate) + { + case GS_LEVEL: + if (!paused) + return false; + case GS_TIMEATTACK: + case GS_WAITINGPLAYERS: + return skip; // Skip odd frames + default: + return false; + } +} + +static inline SDL_bool SDLmatchVideoformat(void) +{ + const SDL_PixelFormat *vidformat = vidSurface->format; + const INT32 vfBPP = vidformat?vidformat->BitsPerPixel:0; + return (((vfBPP == 8 && vid.bpp == 1 && + !vidformat->Rmask && !vidformat->Gmask && !vidformat->Bmask) || + (vfBPP == 15 && vid.bpp == 2 && vidformat->Rmask == 0x7C00 && + vidformat->Gmask == 0x03E0 && vidformat->Bmask == 0x001F )) && + !vidformat->Amask && (vidSurface->flags & SDL_RLEACCEL) == 0); +} + +// +// I_FinishUpdate +// +void I_FinishUpdate(void) +{ + if (!vidSurface) + return; //Alam: No software or OpenGl surface + + if (I_SkipFrame()) + return; + + if (cv_ticrate.value) + SCR_DisplayTicRate(); + + if (render_soft == rendermode && screens[0]) + { + SDL_Rect *dstrect = NULL; + SDL_Rect rect = {0, 0, 0, 0}; + SDL_PixelFormat *vidformat = vidSurface->format; + int lockedsf = 0, blited = 0; + + rect.w = (Sint16)vid.width; + rect.h = (Sint16)vid.height; + + if (vidSurface->h > vid.height) + rect.y = (Sint16)((vidSurface->h-vid.height)/2); + + dstrect = ▭ + + + if (!bufSurface && !vid.direct) //Double-Check + { + if (vid.bpp == 1) bufSurface = SDL_CreateRGBSurfaceFrom(screens[0],vid.width,vid.height,8, + (int)vid.rowbytes,0x00000000,0x00000000,0x00000000,0x00000000); // 256 mode + else if (vid.bpp == 2) bufSurface = SDL_CreateRGBSurfaceFrom(screens[0],vid.width,vid.height,15, + (int)vid.rowbytes,0x00007C00,0x000003E0,0x0000001F,0x00000000); // 555 mode + if (bufSurface) SDL_SetColors(bufSurface, localPalette, 0, 256); + else I_OutputMsg("No system memory for SDL buffer surface\n"); + } + +#ifdef FILTERS + FilterBlit(bufSurface); + if (f2xSurface) //Alam: filter! + { + //I_OutputMsg("2x Filter Code\n"); + blited = SDL_BlitSurface(f2xSurface,NULL,vidSurface,NULL); + } + else +#endif +#if 0 + if (SDLmatchVideoformat() && !vid.direct)//Alam: DOS Way + { + if (SDL_MUSTLOCK(vidSurface)) lockedsf = SDL_LockSurface(vidSurface); + if (lockedsf == 0) + { + if (vidSurface->pixels > vid.height) + { + UINT8 *ptr = vidSurface->pixels; + size_t half_excess = vidSurface->pitch*(vidSurface->height-vid.height)/2; + memset(ptr, 0x1F, half_excess); + ptr += half_excess; + VID_BlitLinearScreen(screens[0], ptr, vid.width*vid.bpp, vid.height, + vid.rowbytes, vidSurface->pitch); + ptr += vid.height*vidSurface->pitch; + memset(ptr, 0x1F, half_excess); + } + else + VID_BlitLinearScreen(screens[0], vidSurface->pixels, vid.width*vid.bpp, + vid.height, vid.rowbytes, vidSurface->pitch ); + if (SDL_MUSTLOCK(vidSurface)) SDL_UnlockSurface(vidSurface); + } + } + else +#endif + if (bufSurface) //Alam: New Way to send video data + { + blited = SDL_BlitSurface(bufSurface,NULL,vidSurface,dstrect); + } + else if (vid.bpp == 1 && !vid.direct) + { + Uint8 *bP,*vP; //Src, Dst + Uint16 bW, vW; // Pitch Remainder + Sint32 pH, pW; //Height, Width + bP = (Uint8 *)screens[0]; + bW = (Uint16)(vid.rowbytes - vid.width); + //I_OutputMsg("Old Copy Code\n"); + if (SDL_MUSTLOCK(vidSurface)) lockedsf = SDL_LockSurface(vidSurface); + vP = (Uint8 *)vidSurface->pixels; + vW = (Uint16)(vidSurface->pitch - vidSurface->w*vidformat->BytesPerPixel); + if (vidSurface->h > vid.height) + vP += vidSurface->pitch*(vidSurface->h-vid.height)/2; + if (lockedsf == 0 && vidSurface->pixels) + { + if (vidformat->BytesPerPixel == 2) + { + for (pH=0;pH < vidSurface->h;pH++) + { + for (pW=0;pW < vidSurface->w;pW++) + { + *((Uint16 *)(void *)vP) = (Uint16)SDL_MapRGB(vidformat, + localPalette[*bP].r,localPalette[*bP].g,localPalette[*bP].b); + bP++; + vP += 2; + } + bP += bW; + vP += vW; + } + } + else if (vidformat->BytesPerPixel == 3) + { + for (pH=0;pH < vidSurface->h;pH++) + { + for (pW=0;pW < vidSurface->w;pW++) + { + *((Uint32 *)(void *)vP) = SDL_MapRGB(vidformat, + localPalette[*bP].r,localPalette[*bP].g,localPalette[*bP].b); + bP++; + vP += 3; + } + bP += bW; + vP += vW; + } + } + else if (vidformat->BytesPerPixel == 4) + { + for (pH=0;pH < vidSurface->h;pH++) + { + for (pW=0;pW < vidSurface->w;pW++) + { + *((Uint32 *)(void *)vP) = SDL_MapRGB(vidformat, + localPalette[*bP].r,localPalette[*bP].g,localPalette[*bP].b); + bP++; + vP += 4; + } + bP += bW; + vP += vW; + } + } + else + { + ;//NOP + } + } + if (SDL_MUSTLOCK(vidSurface)) SDL_UnlockSurface(vidSurface); + } + else /// \todo 15t15,15tN, others? + { + ;//NOP + } + +#ifdef HAVE_GP2XSDL + //if (blited == 0) + SDL_GP2X_WaitForBlitter(); +#endif + + if (lockedsf == 0 && blited == 0 && vidSurface->flags&SDL_DOUBLEBUF) + SDL_Flip(vidSurface); + else if (blited != -2 && lockedsf == 0) //Alam: -2 for Win32 Direct, yea, i know + SDL_UpdateRect(vidSurface, rect.x, rect.y, 0, 0); //Alam: almost always + else + I_OutputMsg("%s\n",SDL_GetError()); + } +#ifdef HWRENDER + else + { + OglSdlFinishUpdate(cv_vidwait.value); + } +#endif + exposevideo = SDL_FALSE; +} + +// +// I_UpdateNoVsync +// +void I_UpdateNoVsync(void) +{ + INT32 real_vidwait = cv_vidwait.value; + cv_vidwait.value = 0; + I_FinishUpdate(); + cv_vidwait.value = real_vidwait; +} + +// +// I_ReadScreen +// +void I_ReadScreen(UINT8 *scr) +{ + if (rendermode != render_soft) + I_Error ("I_ReadScreen: called while in non-software mode"); + else + VID_BlitLinearScreen(screens[0], scr, + vid.width*vid.bpp, vid.height, + vid.rowbytes, vid.rowbytes); +} + +// +// I_SetPalette +// +void I_SetPalette(RGBA_t *palette) +{ + size_t i; + for (i=0; i<256; i++) + { + localPalette[i].r = palette[i].s.red; + localPalette[i].g = palette[i].s.green; + localPalette[i].b = palette[i].s.blue; + } + if (vidSurface) SDL_SetColors(vidSurface, localPalette, 0, 256); + if (bufSurface) SDL_SetColors(bufSurface, localPalette, 0, 256); +} + +// return number of fullscreen + X11 modes +INT32 VID_NumModes(void) +{ + if (USE_FULLSCREEN && numVidModes != -1) + return numVidModes - firstEntry; + else + return MAXWINMODES; +} + +const char *VID_GetModeName(INT32 modeNum) +{ + if (USE_FULLSCREEN && numVidModes != -1) // fullscreen modes + { + modeNum += firstEntry; + if (modeNum >= numVidModes) + return NULL; + + sprintf(&vidModeName[modeNum][0], "%dx%d", + modeList[modeNum]->w, + modeList[modeNum]->h); + } + else // windowed modes + { + if (modeNum > MAXWINMODES) + return NULL; + + sprintf(&vidModeName[modeNum][0], "%dx%d", + windowedModes[modeNum][0], + windowedModes[modeNum][1]); + } + return &vidModeName[modeNum][0]; +} + +INT32 VID_GetModeForSize(INT32 w, INT32 h) +{ + INT32 matchMode = -1, i; + VID_PrepareModeList(); + if (USE_FULLSCREEN && numVidModes != -1) + { + for (i=firstEntry; iw == w && + modeList[i]->h == h) + { + matchMode = i; + break; + } + } + if (-1 == matchMode) // use smaller mode + { + w -= w%BASEVIDWIDTH; + h -= h%BASEVIDHEIGHT; + for (i=firstEntry; iw == w && + modeList[i]->h == h) + { + matchMode = i; + break; + } + } + if (-1 == matchMode) // use smallest mode + matchMode = numVidModes-1; + } + matchMode -= firstEntry; + } + else + { + for (i=0; iw <= MAXVIDWIDTH && + modeList[i]->h <= MAXVIDHEIGHT) + { + firstEntry = i; + break; + } + } + } + } + allow_fullscreen = true; +} + +static inline void SDLESSet(void) +{ +#ifdef HAVE_DCSDL + INT32 j; + SDL_DC_SetVideoDriver(SDL_DC_DIRECT_VIDEO); //SDL_DC_DMA_VIDEO + for (j=0;j<4;j++) + { + SDL_DC_MapKey(j,SDL_DC_START,SDLK_ESCAPE); + SDL_DC_MapKey(j,SDL_DC_A,SDLK_UNKNOWN); + SDL_DC_MapKey(j,SDL_DC_B,SDLK_UNKNOWN); + SDL_DC_MapKey(j,SDL_DC_X,SDLK_UNKNOWN); + SDL_DC_MapKey(j,SDL_DC_Y,SDLK_UNKNOWN); + SDL_DC_MapKey(j,SDL_DC_L,SDLK_UNKNOWN); + SDL_DC_MapKey(j,SDL_DC_R,SDLK_UNKNOWN); + //SDL_DC_MapKey(j,SDL_DC_LEFT,SDLK_UNKNOWN); + //SDL_DC_MapKey(j,SDL_DC_RIGHT,SDLK_UNKNOWN); + //SDL_DC_MapKey(j,SDL_DC_UP,SDLK_UNKNOWN); + //SDL_DC_MapKey(j,SDL_DC_DOWN,SDLK_UNKNOWN); + } + //SDL_DC_MapKey(0,SDL_DC_L,SDLK_LEFTBRACKET); + //SDL_DC_MapKey(0,SDL_DC_R,SDLK_RIGHTBRACKET); + //SDL_DC_MapKey(0,SDL_DC_START,SDLK_UNKNOWN); + //SDL_DC_MapKey(1,SDL_DC_L,SDLK_z); + //SDL_DC_MapKey(1,SDL_DC_R,SDLK_x); +#endif +#ifdef HAVE_GP2XSDL + SDL_GP2X_MiniDisplay(0,0); + //SDL_GP2X_DenyGfxMemory(NULL, 0); + SDL_GP2X_AllowGfxMemory(NULL, 0); +#endif +} + +static void SDLWMSet(void) +{ +#ifdef RPC_NO_WINDOWS_H + SDL_SysWMinfo SDLWM; + memset(&SDLWM,0,sizeof (SDL_SysWMinfo)); + SDL_VERSION(&SDLWM.version) + if (SDL_GetWMInfo(&SDLWM)) + vid.WndParent = SDLWM.window; + else + vid.WndParent = INVALID_HANDLE_VALUE; + if (vid.WndParent != INVALID_HANDLE_VALUE) + { + SetFocus(vid.WndParent); + ShowWindow(vid.WndParent, SW_SHOW); + } +#ifndef _WIN32_WCE + SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); +#endif +#endif + SDL_EventState(SDL_VIDEORESIZE, SDL_IGNORE); +} + +static void* SDLGetDirect(void) +{ +#if 0 //#ifndef __MACH__ // Do not directly access the MacOSX's OpenGL memory + if (!SDL_MUSTLOCK(vidSurface) && SDLmatchVideoformat()) + { + vid.rowbytes = vidSurface->pitch; + return vidSurface->pixels; + } +#endif // you can not use the video memory in pixels member in fullscreen mode + return NULL; +} + +INT32 VID_SetMode(INT32 modeNum) +{ +#ifdef _WIN32_WCE + (void)modeNum; +#else + SDLdoUngrabMouse(); + vid.recalc = true; + BitsPerPixel = (Uint8)cv_scr_depth.value; + //vid.bpp = BitsPerPixel==8?1:2; + // Window title + SDL_WM_SetCaption("SRB2 "VERSIONSTRING, "SRB2"); + + if (render_soft == rendermode) + { + //Alam: SDL_Video system free vidSurface for me + if (vid.buffer) free(vid.buffer); + vid.buffer = NULL; + if (bufSurface) SDL_FreeSurface(bufSurface); + bufSurface = NULL; + } + + if (USE_FULLSCREEN) + { + if (numVidModes != -1) + { + modeNum += firstEntry; + vid.width = modeList[modeNum]->w; + vid.height = modeList[modeNum]->h; + } + else + { + vid.width = windowedModes[modeNum][0]; + vid.height = windowedModes[modeNum][1]; + } + if (render_soft == rendermode) + { + SDLSetMode(vid.width, vid.height, BitsPerPixel, surfaceFlagsF); + + if (!vidSurface) + { + cv_fullscreen.value = 0; + modeNum = VID_GetModeForSize(vid.width,vid.height); + vid.width = windowedModes[modeNum][0]; + vid.height = windowedModes[modeNum][1]; + SDLSetMode(vid.width, vid.height, BitsPerPixel, surfaceFlagsW); + if (!vidSurface) + I_Error("Could not set vidmode: %s\n",SDL_GetError()); + } + } +#ifdef HWRENDER + else // (render_soft != rendermode) + { + if (!OglSdlSurface(vid.width, vid.height, true)) + { + cv_fullscreen.value = 0; + modeNum = VID_GetModeForSize(vid.width,vid.height); + vid.width = windowedModes[modeNum][0]; + vid.height = windowedModes[modeNum][1]; + if (!OglSdlSurface(vid.width, vid.height,false)) + I_Error("Could not set vidmode: %s\n",SDL_GetError()); + } + + realwidth = (Uint16)vid.width; + realheight = (Uint16)vid.height; + } +#endif + } + else //(cv_fullscreen.value) + { + vid.width = windowedModes[modeNum][0]; + vid.height = windowedModes[modeNum][1]; + + if (render_soft == rendermode) + { + SDLSetMode(vid.width, vid.height, BitsPerPixel, surfaceFlagsW); + if (!vidSurface) + I_Error("Could not set vidmode: %s\n",SDL_GetError()); + } +#ifdef HWRENDER + else //(render_soft != rendermode) + { + if (!OglSdlSurface(vid.width, vid.height, false)) + I_Error("Could not set vidmode: %s\n",SDL_GetError()); + realwidth = (Uint16)vid.width; + realheight = (Uint16)vid.height; + } +#endif + } + + vid.modenum = VID_GetModeForSize(vidSurface->w,vidSurface->h); + + if (render_soft == rendermode) + { + vid.rowbytes = vid.width*vid.bpp; + vid.direct = SDLGetDirect(); + vid.buffer = malloc(vid.rowbytes*vid.height*NUMSCREENS); + if (vid.buffer) memset(vid.buffer,0x00,vid.rowbytes*vid.height*NUMSCREENS); + else I_Error ("Not enough memory for video buffer\n"); + } + +#if 0 // broken + if (!cv_stretch.value && (float)vid.width/vid.height != ((float)BASEVIDWIDTH/BASEVIDHEIGHT)) + vid.height = (INT32)(vid.width * ((float)BASEVIDHEIGHT/BASEVIDWIDTH));// Adjust the height to match +#endif +#endif + I_StartupMouse(); + + SDLWMSet(); + + return true; +} + +void I_StartupGraphics(void) +{ + static char SDLNOMOUSE[] = "SDL_NOMOUSE=1"; + static char SDLVIDEOMID[] = "SDL_VIDEO_CENTERED=center"; + + if (dedicated) + { + rendermode = render_none; + return; + } + if (graphics_started) + return; + + COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f); + COM_AddCommand ("vid_info", VID_Command_Info_f); + COM_AddCommand ("vid_modelist", VID_Command_ModeList_f); + COM_AddCommand ("vid_mode", VID_Command_Mode_f); + CV_RegisterVar (&cv_vidwait); + CV_RegisterVar (&cv_stretch); +#ifdef FILTERS + CV_RegisterVar (&cv_filter); +#endif +#ifdef _PSP // pitch is 0, mod of 0 crash + disable_mouse = true; +#else + disable_mouse = M_CheckParm("-nomouse"); +#endif + if (disable_mouse) + I_PutEnv(SDLNOMOUSE); + if (!I_GetEnv("SDL_VIDEO_CENTERED")) + I_PutEnv(SDLVIDEOMID); + disable_fullscreen = M_CheckParm("-win"); + + keyboard_started = true; +#ifdef _arch_dreamcast + conio_shutdown(); +#endif + +#if !defined(HAVE_TTF) +#ifdef _WIN32 // Initialize Audio as well, otherwise Win32's DirectX can not use audio + if (SDL_InitSubSystem(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0) +#else //SDL_OpenAudio will do SDL_InitSubSystem(SDL_INIT_AUDIO) + if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) +#endif + { +#ifdef _WIN32 + if (SDL_WasInit(SDL_INIT_AUDIO)==0) + CONS_Printf(M_GetText("Couldn't initialize SDL's Audio System with Video System: %s\n"), SDL_GetError()); + if (SDL_WasInit(SDL_INIT_VIDEO)==0) +#endif + { + CONS_Printf(M_GetText("Couldn't initialize SDL's Video System: %s\n"), SDL_GetError()); + return; + } + } +#ifdef REMOTE_DEBUGGING +#ifdef _WII + _break(); // break for debugger +#endif +#endif +#endif + { + char vd[100]; //stack space for video name + CONS_Printf(M_GetText("Starting up with video driver : %s\n"), SDL_VideoDriverName(vd,100)); + if (strncasecmp(vd, "gcvideo", 8) == 0 || strncasecmp(vd, "fbcon", 6) == 0 || strncasecmp(vd, "wii", 4) == 0 || strncasecmp(vd, "psl1ght", 8) == 0) + framebuffer = SDL_TRUE; + } + if (M_CheckParm("-software")) + rendermode = render_soft; + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); + SDLESSet(); + VID_Command_ModeList_f(); + vid.buffer = NULL; // For software mode + vid.width = BASEVIDWIDTH; // Default size for startup + vid.height = BASEVIDHEIGHT; // BitsPerPixel is the SDL interface's + vid.recalc = true; // Set up the console stufff + vid.direct = NULL; // Maybe direct access? + vid.bpp = 1; // This is the game engine's Bpp + vid.WndParent = NULL; //For the window? + +#ifdef HAVE_TTF + I_ShutdownTTF(); +#endif + + // Window title +#ifdef _WIN32_WCE + SDL_WM_SetCaption("SRB2 "VERSIONSTRING, "SRB2"); +#else + SDL_WM_SetCaption("SRB2: Starting up", "SRB2"); +#endif + + // Window icon +#ifdef HAVE_IMAGE + icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm); +#endif + SDL_WM_SetIcon(icoSurface, NULL); + +#ifdef _WIN32 + //DisableAero(); //also disable Aero on Vista +#endif + +#ifdef HWRENDER + if (M_CheckParm("-opengl") || rendermode == render_opengl) + { + rendermode = render_opengl; + HWD.pfnInit = hwSym("Init",NULL); + HWD.pfnFinishUpdate = NULL; + HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); + HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); + HWD.pfnSetBlend = hwSym("SetBlend",NULL); + HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); + HWD.pfnSetTexture = hwSym("SetTexture",NULL); + HWD.pfnReadRect = hwSym("ReadRect",NULL); + HWD.pfnGClipRect = hwSym("GClipRect",NULL); + HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); + HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); + HWD.pfnSetPalette = hwSym("SetPalette",NULL); + HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); + HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); + HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); + HWD.pfnSetTransform = hwSym("SetTransform",NULL); + HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); +#ifdef SHUFFLE + HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); +#endif + HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); + HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); + HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); + HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); + HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); + // check gl renderer lib + if (HWD.pfnGetRenderVersion() != VERSION) + I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); +#if 1 //#ifdef _WIN32_WCE + vid.width = BASEVIDWIDTH; + vid.height = BASEVIDHEIGHT; +#else + vid.width = 640; // hack to make voodoo cards work in 640x480 + vid.height = 480; +#endif + if (HWD.pfnInit(I_Error)) // let load the OpenGL library + { + /* + * We want at least 1 bit R, G, and B, + * and at least 16 bpp. Why 1 bit? May be more? + */ + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 1); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 1); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 1); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + if (!OglSdlSurface(vid.width, vid.height, (USE_FULLSCREEN))) + if (!OglSdlSurface(vid.width, vid.height, !(USE_FULLSCREEN))) + rendermode = render_soft; + } + else + rendermode = render_soft; + } +#else + rendermode = render_soft; //force software mode when there no HWRENDER code +#endif + if (render_soft == rendermode) + { +#if defined(_WII) + vid.width = 640; + vid.height = 480; +#elif defined(_PS3) + vid.width = 720; + vid.height = 480; +#else + vid.width = BASEVIDWIDTH; + vid.height = BASEVIDHEIGHT; +#endif + SDLSetMode(vid.width, vid.height, BitsPerPixel, surfaceFlagsW); + if (!vidSurface) + { + CONS_Printf(M_GetText("Could not set vidmode: %s\n") ,SDL_GetError()); + vid.rowbytes = 0; + graphics_started = true; + return; + } + vid.rowbytes = vid.width * vid.bpp; + vid.direct = SDLGetDirect(); + vid.buffer = malloc(vid.rowbytes*vid.height*NUMSCREENS); + if (vid.buffer) memset(vid.buffer,0x00,vid.rowbytes*vid.height*NUMSCREENS); + else CONS_Printf("%s", M_GetText("Not enough memory for video buffer\n")); + } + if (M_CheckParm("-nomousegrab")) + mousegrabok = SDL_FALSE; +#ifdef _DEBUG + else + { + char videodriver[4] = {'S','D','L',0}; + if (!M_CheckParm("-mousegrab") && + SDL_VideoDriverName(videodriver,4) && + strncasecmp("X11",videodriver,4) == 0) + mousegrabok = SDL_FALSE; //X11's XGrabPointer not good + } +#endif + realwidth = (Uint16)vid.width; + realheight = (Uint16)vid.height; + + VID_Command_Info_f(); + if (!disable_mouse) SDL_ShowCursor(SDL_DISABLE); + SDLdoUngrabMouse(); + + SDLWMSet(); + + graphics_started = true; +} + +void I_ShutdownGraphics(void) +{ + const rendermode_t oldrendermode = rendermode; + + rendermode = render_none; + if (icoSurface) SDL_FreeSurface(icoSurface); + icoSurface = NULL; + if (render_soft == oldrendermode) + { + vidSurface = NULL; //Alam: SDL_Video system free vidSurface for me + if (vid.buffer) free(vid.buffer); + vid.buffer = NULL; + if (bufSurface) SDL_FreeSurface(bufSurface); + bufSurface = NULL; +#ifdef FILTERS + if (preSurface) SDL_FreeSurface(preSurface); + preSurface = NULL; + if (f2xSurface) SDL_FreeSurface(f2xSurface); + f2xSurface = NULL; +#endif + } + + // was graphics initialized anyway? + if (!graphics_started) + return; + CONS_Printf("I_ShutdownGraphics: "); +#ifdef _WIN32 + //ResetAero(); +#endif + graphics_started = false; + CONS_Printf("%s", M_GetText("shut down\n")); +#ifdef HWRENDER + if (GLUhandle) + hwClose(GLUhandle); +#endif +#ifndef _arch_dreamcast + SDL_QuitSubSystem(SDL_INIT_VIDEO); +#endif + framebuffer = SDL_FALSE; +} +#endif diff --git a/src/sdl12/macosx/English.lproj/InfoPlist.strings b/src/sdl12/macosx/English.lproj/InfoPlist.strings new file mode 100644 index 000000000..e69de29bb diff --git a/src/sdl12/macosx/Info.plist b/src/sdl12/macosx/Info.plist new file mode 100644 index 000000000..ae0ce24de --- /dev/null +++ b/src/sdl12/macosx/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + Srb2mac.icns + CFBundleIdentifier + com.yourcompany.Srb2mac + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSMainNibFile + SDLMain + NSPrincipalClass + NSApplication + + diff --git a/src/sdl12/macosx/Srb2mac.icns b/src/sdl12/macosx/Srb2mac.icns new file mode 100644 index 0000000000000000000000000000000000000000..4baedc1c5a091a3917d2a33bc3780da5b1b5e996 GIT binary patch literal 79787 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 literal 0 HcmV?d00001 diff --git a/src/sdl12/macosx/Srb2mac.pbproj/project.pbxproj b/src/sdl12/macosx/Srb2mac.pbproj/project.pbxproj new file mode 100644 index 000000000..de12201f5 --- /dev/null +++ b/src/sdl12/macosx/Srb2mac.pbproj/project.pbxproj @@ -0,0 +1,3546 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 38; + objects = { + 6726EB5E10190F860074DCBA = { + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 7; + files = ( + 6755C8D0101802C300A80195, + 6755C8D1101802C300A80195, + 6755C8D2101802C300A80195, + 6755C8D3101802C300A80195, + 6755C8D4101802C300A80195, + 6755C8D5101802C300A80195, + 6755C8D6101802C300A80195, + 6755C8D7101802C300A80195, + 6755C8D8101802C300A80195, + ); + isa = PBXCopyFilesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6726EB5F10190FFC0074DCBA = { + buildActionMask = 2147483647; + files = ( + ); + generatedFileNames = ( + ); + isa = PBXShellScriptBuildPhase; + neededFileNames = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "touch -c $SRCROOT/../../comptime.c"; + }; + 6755C7A91017FE2500A80195 = { + fileEncoding = 30; + isa = PBXFileReference; + name = lzf.c; + path = ../../lzf.c; + refType = 2; + }; + 6755C7AA1017FE2500A80195 = { + fileEncoding = 30; + isa = PBXFileReference; + name = lzf.h; + path = ../../lzf.h; + refType = 2; + }; + 6755C7AB1017FE2500A80195 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_dllist.h; + path = ../../m_dllist.h; + refType = 2; + }; + 6755C7AC1017FE2500A80195 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_queue.c; + path = ../../m_queue.c; + refType = 2; + }; + 6755C7AD1017FE2500A80195 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_queue.h; + path = ../../m_queue.h; + refType = 2; + }; + 6755C7AE1017FE2500A80195 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_polyobj.c; + path = ../../p_polyobj.c; + refType = 2; + }; + 6755C7AF1017FE2500A80195 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_polyobj.h; + path = ../../p_polyobj.h; + refType = 2; + }; + 6755C7B11017FE2500A80195 = { + fileEncoding = 30; + isa = PBXFileReference; + name = string.c; + path = ../../string.c; + refType = 2; + }; + 6755C7B21017FE2500A80195 = { + fileRef = 6755C7A91017FE2500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C7B31017FE2500A80195 = { + fileRef = 6755C7AA1017FE2500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C7B51017FE2500A80195 = { + fileRef = 6755C7AC1017FE2500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C7B71017FE2500A80195 = { + fileRef = 6755C7AE1017FE2500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C7B81017FE2500A80195 = { + fileRef = 6755C7AF1017FE2500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C7BB1017FE2500A80195 = { + fileRef = 6755C7A91017FE2500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C7BC1017FE2500A80195 = { + fileRef = 6755C7AA1017FE2500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C7BD1017FE2500A80195 = { + fileRef = 6755C7AB1017FE2500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C7BE1017FE2500A80195 = { + fileRef = 6755C7AC1017FE2500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C7BF1017FE2500A80195 = { + fileRef = 6755C7AD1017FE2500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C7C01017FE2500A80195 = { + fileRef = 6755C7AE1017FE2500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C7C11017FE2500A80195 = { + fileRef = 6755C7AF1017FE2500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C7C41017FE4400A80195 = { + children = ( + 6755C7FA1017FE4500A80195, + 6755C7FB1017FE4500A80195, + ); + isa = PBXGroup; + name = macosx; + path = ""; + refType = 2; + }; + 6755C7FA1017FE4500A80195 = { + fileEncoding = 30; + isa = PBXFileReference; + path = mac_alert.c; + refType = 2; + }; + 6755C7FB1017FE4500A80195 = { + fileEncoding = 30; + isa = PBXFileReference; + path = mac_alert.h; + refType = 2; + }; + 6755C82A1017FE4500A80195 = { + fileEncoding = 30; + isa = PBXFileReference; + name = sdlmain.h; + path = ../sdlmain.h; + refType = 2; + }; + 6755C84B1017FE4500A80195 = { + fileRef = 6755C7FA1017FE4500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8651017FE4500A80195 = { + fileRef = 6755C82A1017FE4500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8861017FE4500A80195 = { + fileRef = 6755C7FA1017FE4500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8871017FE4500A80195 = { + fileRef = 6755C7FB1017FE4500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8A01017FE4500A80195 = { + fileRef = 6755C82A1017FE4500A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8A41017FE8000A80195 = { + children = ( + 84177748085A1097000C01D8, + 84177749085A1097000C01D8, + 8417774A085A1097000C01D8, + 8417774B085A1097000C01D8, + 8417774C085A1097000C01D8, + 8417774D085A1097000C01D8, + 8417774E085A1097000C01D8, + 8417774F085A1097000C01D8, + 84177750085A1097000C01D8, + 84177751085A1097000C01D8, + 84177752085A1097000C01D8, + 84177753085A1097000C01D8, + 84177754085A1097000C01D8, + 84177755085A10AA000C01D8, + 84177756085A10AA000C01D8, + 6755C82A1017FE4500A80195, + 84177757085A10AA000C01D8, + 6755C7C41017FE4400A80195, + ); + isa = PBXGroup; + name = SDL; + path = ""; + refType = 2; + }; + 6755C8BE101802C300A80195 = { + isa = PBXFileReference; + name = drill.dta; + path = ../../../bin/Resources/drill.dta; + refType = 2; + }; + 6755C8BF101802C300A80195 = { + isa = PBXFileReference; + name = fmod.dll; + path = ../../../bin/Resources/fmod.dll; + refType = 2; + }; + 6755C8C0101802C300A80195 = { + isa = PBXFileReference; + name = knux.plr; + path = ../../../bin/Resources/knux.plr; + refType = 2; + }; + 6755C8C1101802C300A80195 = { + isa = PBXFileReference; + name = music.dta; + path = ../../../bin/Resources/music.dta; + refType = 2; + }; + 6755C8C2101802C300A80195 = { + isa = PBXFileReference; + name = rings.wpn; + path = ../../../bin/Resources/rings.wpn; + refType = 2; + }; + 6755C8C3101802C300A80195 = { + isa = PBXFileReference; + name = soar.dta; + path = ../../../bin/Resources/soar.dta; + refType = 2; + }; + 6755C8C4101802C300A80195 = { + isa = PBXFileReference; + name = sonic.plr; + path = ../../../bin/Resources/sonic.plr; + refType = 2; + }; + 6755C8C5101802C300A80195 = { + isa = PBXFileReference; + name = srb2.wad; + path = ../../../bin/Resources/srb2.wad; + refType = 2; + }; + 6755C8C6101802C300A80195 = { + isa = PBXFileReference; + name = tails.plr; + path = ../../../bin/Resources/tails.plr; + refType = 2; + }; + 6755C8C7101802C300A80195 = { + fileRef = 6755C8BE101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8C8101802C300A80195 = { + fileRef = 6755C8BF101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8C9101802C300A80195 = { + fileRef = 6755C8C0101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8CA101802C300A80195 = { + fileRef = 6755C8C1101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8CB101802C300A80195 = { + fileRef = 6755C8C2101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8CC101802C300A80195 = { + fileRef = 6755C8C3101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8CD101802C300A80195 = { + fileRef = 6755C8C4101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8CE101802C300A80195 = { + fileRef = 6755C8C5101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8CF101802C300A80195 = { + fileRef = 6755C8C6101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8D0101802C300A80195 = { + fileRef = 6755C8BE101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8D1101802C300A80195 = { + fileRef = 6755C8BF101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8D2101802C300A80195 = { + fileRef = 6755C8C0101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8D3101802C300A80195 = { + fileRef = 6755C8C1101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8D4101802C300A80195 = { + fileRef = 6755C8C2101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8D5101802C300A80195 = { + fileRef = 6755C8C3101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8D6101802C300A80195 = { + fileRef = 6755C8C4101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8D7101802C300A80195 = { + fileRef = 6755C8C5101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 6755C8D8101802C300A80195 = { + fileRef = 6755C8C6101802C300A80195; + isa = PBXBuildFile; + settings = { + }; + }; + 677B5EC810180D4E00A80195 = { + fileRef = 84177758085A10D2000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 677B5EC910180D6600A80195 = { + children = ( + 84177758085A10D2000C01D8, + ); + isa = PBXGroup; + name = r_opengl; + refType = 4; + }; + 677B5ECA10180D7100A80195 = { + children = ( + 84F202CA08A92AA0000C01D8, + ); + isa = PBXGroup; + name = s_openal; + refType = 4; + }; + 67B2D0C91018779900A80195 = { + fileRef = 84177748085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 67B2D0CA1018779D00A80195 = { + fileRef = 84177748085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; +//670 +//671 +//672 +//673 +//674 +//840 +//841 +//842 +//843 +//844 + 840CE6B009198AA7000C01D8 = { + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 840CE6B309198ABB000C01D8, + 840CE6B409198ABB000C01D8, + 849BD32D0A7E471D000C01D8, + ); + isa = PBXCopyFilesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 840CE6B309198ABB000C01D8 = { + fileRef = 84C4E04B08620A46000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 840CE6B409198ABB000C01D8 = { + fileRef = 84C4E04C08620A46000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 841776FE085A0C64000C01D8 = { + children = ( + 84C4E00D0862063C000C01D8, + 84177705085A0CDB000C01D8, + 84177706085A0D9D000C01D8, + 84177708085A0DB5000C01D8, + 84177709085A0DD1000C01D8, + 84177712085A0EB5000C01D8, + 8417770B085A0E17000C01D8, + 8417770C085A0E40000C01D8, + 8417770D085A0E4E000C01D8, + 8417770E085A0E5B000C01D8, + 8417770F085A0E66000C01D8, + 84177710085A0E71000C01D8, + 84177711085A0E77000C01D8, + 841779E2085A138F000C01D8, + 84F202C708A92A5D000C01D8, + 84C4E03F0862096F000C01D8, + 84C4E0420862098A000C01D8, + 84C4E045086209D3000C01D8, + 84C4E048086209FF000C01D8, + 84C4E04C08620A46000C01D8, + 84C4E04B08620A46000C01D8, + 849BD31C0A7E45B3000C01D8, + ); + isa = PBXGroup; + refType = 4; + }; + 84177700085A0C64000C01D8 = { + buildRules = ( + ); + buildSettings = { + COPY_PHASE_STRIP = NO; + }; + isa = PBXBuildStyle; + name = Development; + }; + 84177701085A0C64000C01D8 = { + buildRules = ( + ); + buildSettings = { + COPY_PHASE_STRIP = YES; + }; + isa = PBXBuildStyle; + name = Deployment; + }; + 84177702085A0C64000C01D8 = { + buildStyles = ( + 84177700085A0C64000C01D8, + 84177701085A0C64000C01D8, + ); + hasScannedForEncodings = 1; + isa = PBXProject; + mainGroup = 841776FE085A0C64000C01D8; + productRefGroup = 841779E2085A138F000C01D8; + projectDirPath = ""; + targets = ( + 841779E0085A138F000C01D8, + 841779E9085A13B1000C01D8, + ); + }; + 84177705085A0CDB000C01D8 = { + children = ( + 849603A80A791C11000C01D8, + 84177713085A0FCE000C01D8, + 84177714085A0FCE000C01D8, + 84177716085A0FCE000C01D8, + 84177717085A0FCE000C01D8, + 84177718085A0FCE000C01D8, + 84177719085A0FCE000C01D8, + 8417771A085A0FCE000C01D8, + 8417771B085A0FCE000C01D8, + 8417771C085A0FCE000C01D8, + 8417771D085A0FCE000C01D8, + 8417771E085A0FCE000C01D8, + 8417771F085A0FCE000C01D8, + 84177720085A0FCE000C01D8, + 84177721085A0FCE000C01D8, + 84177722085A0FCE000C01D8, + 84177723085A0FCE000C01D8, + 84177724085A0FF2000C01D8, + 84177725085A0FF2000C01D8, + 84177726085A0FF2000C01D8, + 84177727085A0FF2000C01D8, + 6755C7B11017FE2500A80195, + ); + isa = PBXGroup; + name = D_SRB2; + path = ""; + refType = 2; + }; + 84177706085A0D9D000C01D8 = { + children = ( + 8417772A085A100E000C01D8, + 8417772B085A100E000C01D8, + 8417772C085A100E000C01D8, + ); + isa = PBXGroup; + name = F_Frame; + path = ""; + refType = 2; + }; + 84177708085A0DB5000C01D8 = { + children = ( + 841779DA085A1347000C01D8, + 841778C6085A1295000C01D8, + 841778C4085A1295000C01D8, + 841778C5085A1295000C01D8, + 8417772D085A1029000C01D8, + 8417772E085A1029000C01D8, + 8417772F085A1029000C01D8, + 84177730085A1029000C01D8, + 84177731085A1029000C01D8, + 841779D4085A1296000C01D8, + 841779D5085A1296000C01D8, + ); + isa = PBXGroup; + name = G_Game; + path = ""; + refType = 2; + }; + 84177709085A0DD1000C01D8 = { + children = ( + 841778BE085A1295000C01D8, + 841778BF085A1295000C01D8, + 841778C2085A1295000C01D8, + 841778C3085A1295000C01D8, + 841778C0085A1295000C01D8, + 841778C1085A1295000C01D8, + 84177732085A1040000C01D8, + 84177733085A1040000C01D8, + 841779D2085A1296000C01D8, + 841779D3085A1296000C01D8, + 841779D8085A1296000C01D8, + 8490D433085DF537000C01D8, + ); + isa = PBXGroup; + name = H_Hud; + path = ""; + refType = 2; + }; + 8417770B085A0E17000C01D8 = { + children = ( + 6755C8A41017FE8000A80195, + 84177759085A10D2000C01D8, + 841777A4085A1200000C01D8, + 841777A5085A1200000C01D8, + 841777A6085A1200000C01D8, + 841777A8085A1200000C01D8, + 841777A9085A1200000C01D8, + 841777AA085A1200000C01D8, + 841777AB085A1200000C01D8, + 841777AC085A1200000C01D8, + 841777AD085A1200000C01D8, + 841777AE085A1200000C01D8, + ); + isa = PBXGroup; + name = I_Interface; + path = ""; + refType = 2; + }; + 8417770C085A0E40000C01D8 = { + children = ( + 8417775A085A10EB000C01D8, + 8417775B085A10EB000C01D8, + 8417775C085A10EB000C01D8, + 8417775D085A10EB000C01D8, + 8417775E085A10EB000C01D8, + 8417775F085A10EB000C01D8, + 6755C7AB1017FE2500A80195, + 84177760085A10EB000C01D8, + 84177761085A10EB000C01D8, + 84177762085A10EB000C01D8, + 84177763085A10EB000C01D8, + 84177764085A10EB000C01D8, + 84177765085A10EB000C01D8, + 6755C7AC1017FE2500A80195, + 6755C7AD1017FE2500A80195, + 84177766085A10EB000C01D8, + 84177767085A10EB000C01D8, + 84177768085A10EB000C01D8, + ); + isa = PBXGroup; + name = M_Misc; + path = ""; + refType = 2; + }; + 8417770D085A0E4E000C01D8 = { + children = ( + 84177769085A1104000C01D8, + 8417776A085A1104000C01D8, + 8417776B085A1104000C01D8, + 8417776C085A1104000C01D8, + 8417776D085A1104000C01D8, + 8417776E085A1104000C01D8, + 8417776F085A1104000C01D8, + 84177770085A1104000C01D8, + 84177771085A1104000C01D8, + 84177772085A1104000C01D8, + 84177773085A1104000C01D8, + 84177774085A1104000C01D8, + 6755C7AE1017FE2500A80195, + 6755C7AF1017FE2500A80195, + 84177775085A1104000C01D8, + 84177776085A1104000C01D8, + 84177777085A1104000C01D8, + 84177778085A1104000C01D8, + 84177779085A1104000C01D8, + 8417777A085A1104000C01D8, + 8417777B085A1104000C01D8, + 8417777C085A1104000C01D8, + 8417777D085A1104000C01D8, + 8417777E085A1104000C01D8, + 8417777F085A1104000C01D8, + 84177780085A1104000C01D8, + ); + isa = PBXGroup; + name = P_Play; + path = ""; + refType = 2; + }; + 8417770E085A0E5B000C01D8 = { + children = ( + 84177781085A111B000C01D8, + 84177782085A111B000C01D8, + 84177783085A111B000C01D8, + 84177784085A111B000C01D8, + 84177785085A111B000C01D8, + 84177786085A111B000C01D8, + 84177787085A111B000C01D8, + 84177788085A111B000C01D8, + 84177789085A111B000C01D8, + 8417778A085A111B000C01D8, + 8417778B085A111B000C01D8, + 8417778C085A111B000C01D8, + 8417778D085A111B000C01D8, + 8417778E085A111B000C01D8, + 8417778F085A111B000C01D8, + 84177790085A111B000C01D8, + 84177791085A111B000C01D8, + 84177792085A111B000C01D8, + 84177793085A111B000C01D8, + 84177794085A111B000C01D8, + 84177795085A111B000C01D8, + 84177796085A111B000C01D8, + 84177797085A111B000C01D8, + 841777A2085A1197000C01D8, + 841777A3085A1197000C01D8, + 8490D436085DF57B000C01D8, + 841779D7085A1296000C01D8, + ); + isa = PBXGroup; + name = R_Rend; + path = ""; + refType = 2; + }; + 8417770F085A0E66000C01D8 = { + children = ( + 84177798085A1138000C01D8, + 84177799085A1138000C01D8, + 8417779A085A1138000C01D8, + 8417779B085A1138000C01D8, + ); + isa = PBXGroup; + name = S_Sounds; + path = ""; + refType = 2; + }; + 84177710085A0E71000C01D8 = { + children = ( + 8417779C085A114C000C01D8, + 8417779D085A114C000C01D8, + 8417779E085A116B000C01D8, + 8417779F085A116B000C01D8, + ); + isa = PBXGroup; + name = SDL_main; + path = ""; + refType = 2; + }; + 84177711085A0E77000C01D8 = { + children = ( + 6755C7A91017FE2500A80195, + 6755C7AA1017FE2500A80195, + 841777AF085A1228000C01D8, + 841777B0085A1228000C01D8, + 841777A0085A117F000C01D8, + 841777A1085A117F000C01D8, + 841778BC085A122A000C01D8, + 841778BD085A122A000C01D8, + ); + isa = PBXGroup; + name = W_Wad; + path = ""; + refType = 2; + }; + 84177712085A0EB5000C01D8 = { + children = ( + 677B5EC910180D6600A80195, + 677B5ECA10180D7100A80195, + 84177734085A106C000C01D8, + 84177735085A106C000C01D8, + 84177736085A106C000C01D8, + 84177737085A106C000C01D8, + 84177738085A106C000C01D8, + 84177739085A106C000C01D8, + 8417773A085A106C000C01D8, + 8417773B085A106C000C01D8, + 8417773C085A106C000C01D8, + 8417773D085A106C000C01D8, + 8417773E085A106C000C01D8, + 8417773F085A106C000C01D8, + 84177740085A106C000C01D8, + 84177741085A106C000C01D8, + 84177742085A106C000C01D8, + 84177743085A106C000C01D8, + 84177744085A106C000C01D8, + 84177745085A106C000C01D8, + 84177746085A106C000C01D8, + 84177747085A106C000C01D8, + ); + isa = PBXGroup; + name = Hw_Hardware; + path = ""; + refType = 2; + }; + 84177713085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = d_clisrv.c; + path = ../../d_clisrv.c; + refType = 2; + }; + 84177714085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = d_clisrv.h; + path = ../../d_clisrv.h; + refType = 2; + }; + 84177716085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = d_event.h; + path = ../../d_event.h; + refType = 2; + }; + 84177717085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = d_main.c; + path = ../../d_main.c; + refType = 2; + }; + 84177718085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = d_main.h; + path = ../../d_main.h; + refType = 2; + }; + 84177719085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = d_net.c; + path = ../../d_net.c; + refType = 2; + }; + 8417771A085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = d_net.h; + path = ../../d_net.h; + refType = 2; + }; + 8417771B085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = d_netcmd.c; + path = ../../d_netcmd.c; + refType = 2; + }; + 8417771C085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = d_netcmd.h; + path = ../../d_netcmd.h; + refType = 2; + }; + 8417771D085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = d_netfil.c; + path = ../../d_netfil.c; + refType = 2; + }; + 8417771E085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = d_netfil.h; + path = ../../d_netfil.h; + refType = 2; + }; + 8417771F085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = d_player.h; + path = ../../d_player.h; + refType = 2; + }; + 84177720085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = d_think.h; + path = ../../d_think.h; + refType = 2; + }; + 84177721085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = d_ticcmd.h; + path = ../../d_ticcmd.h; + refType = 2; + }; + 84177722085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = dehacked.c; + path = ../../dehacked.c; + refType = 2; + }; + 84177723085A0FCE000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = dehacked.h; + path = ../../dehacked.h; + refType = 2; + }; + 84177724085A0FF2000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = doomdata.h; + path = ../../doomdata.h; + refType = 2; + }; + 84177725085A0FF2000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = doomdef.h; + path = ../../doomdef.h; + refType = 2; + }; + 84177726085A0FF2000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = doomstat.h; + path = ../../doomstat.h; + refType = 2; + }; + 84177727085A0FF2000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = doomtype.h; + path = ../../doomtype.h; + refType = 2; + }; + 8417772A085A100E000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = f_finale.c; + path = ../../f_finale.c; + refType = 2; + }; + 8417772B085A100E000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = f_finale.h; + path = ../../f_finale.h; + refType = 2; + }; + 8417772C085A100E000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = f_wipe.c; + path = ../../f_wipe.c; + refType = 2; + }; + 8417772D085A1029000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = g_game.c; + path = ../../g_game.c; + refType = 2; + }; + 8417772E085A1029000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = g_game.h; + path = ../../g_game.h; + refType = 2; + }; + 8417772F085A1029000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = g_input.c; + path = ../../g_input.c; + refType = 2; + }; + 84177730085A1029000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = g_input.h; + path = ../../g_input.h; + refType = 2; + }; + 84177731085A1029000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = g_state.h; + path = ../../g_state.h; + refType = 2; + }; + 84177732085A1040000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hu_stuff.c; + path = ../../hu_stuff.c; + refType = 2; + }; + 84177733085A1040000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hu_stuff.h; + path = ../../hu_stuff.h; + refType = 2; + }; + 84177734085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_bsp.c; + path = ../../hardware/hw_bsp.c; + refType = 2; + }; + 84177735085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_cache.c; + path = ../../hardware/hw_cache.c; + refType = 2; + }; + 84177736085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_data.h; + path = ../../hardware/hw_data.h; + refType = 2; + }; + 84177737085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_defs.h; + path = ../../hardware/hw_defs.h; + refType = 2; + }; + 84177738085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_dll.h; + path = ../../hardware/hw_dll.h; + refType = 2; + }; + 84177739085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_draw.c; + path = ../../hardware/hw_draw.c; + refType = 2; + }; + 8417773A085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_drv.h; + path = ../../hardware/hw_drv.h; + refType = 2; + }; + 8417773B085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_glide.h; + path = ../../hardware/hw_glide.h; + refType = 2; + }; + 8417773C085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_glob.h; + path = ../../hardware/hw_glob.h; + refType = 2; + }; + 8417773D085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_light.c; + path = ../../hardware/hw_light.c; + refType = 2; + }; + 8417773E085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_light.h; + path = ../../hardware/hw_light.h; + refType = 2; + }; + 8417773F085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_main.c; + path = ../../hardware/hw_main.c; + refType = 2; + }; + 84177740085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_main.h; + path = ../../hardware/hw_main.h; + refType = 2; + }; + 84177741085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_md2.c; + path = ../../hardware/hw_md2.c; + refType = 2; + }; + 84177742085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_md2.h; + path = ../../hardware/hw_md2.h; + refType = 2; + }; + 84177743085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw_trick.c; + path = ../../hardware/hw_trick.c; + refType = 2; + }; + 84177744085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw3dsdrv.h; + path = ../../hardware/hw3dsdrv.h; + refType = 2; + }; + 84177745085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw3sound.c; + path = ../../hardware/hw3sound.c; + refType = 2; + }; + 84177746085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hw3sound.h; + path = ../../hardware/hw3sound.h; + refType = 2; + }; + 84177747085A106C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hws_data.h; + path = ../../hardware/hws_data.h; + refType = 2; + }; + 84177748085A1097000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = dosstr.c; + path = ../dosstr.c; + refType = 2; + }; + 84177749085A1097000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = endtxt.c; + path = ../endtxt.c; + refType = 2; + }; + 8417774A085A1097000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = endtxt.h; + path = ../endtxt.h; + refType = 2; + }; + 8417774B085A1097000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = filesrch.c; + path = ../../filesrch.c; + refType = 2; + }; + 8417774C085A1097000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hwsym_sdl.c; + path = ../hwsym_sdl.c; + refType = 2; + }; + 8417774D085A1097000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = hwsym_sdl.h; + path = ../hwsym_sdl.h; + refType = 2; + }; + 8417774E085A1097000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = i_cdmus.c; + path = ../i_cdmus.c; + refType = 2; + }; + 8417774F085A1097000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = i_main.c; + path = ../i_main.c; + refType = 2; + }; + 84177750085A1097000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = i_net.c; + path = ../i_net.c; + refType = 2; + }; + 84177751085A1097000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = i_sound.c; + path = ../i_sound.c; + refType = 2; + }; + 84177752085A1097000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = i_system.c; + path = ../i_system.c; + refType = 2; + }; + 84177753085A1097000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = i_video.c; + path = ../i_video.c; + refType = 2; + }; + 84177754085A1097000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = IMG_xpm.c; + path = ../IMG_xpm.c; + refType = 2; + }; + 84177755085A10AA000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = ogl_sdl.c; + path = ../ogl_sdl.c; + refType = 2; + }; + 84177756085A10AA000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = ogl_sdl.h; + path = ../ogl_sdl.h; + refType = 2; + }; + 84177757085A10AA000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = SDL_icon.xpm; + path = ../SDL_icon.xpm; + refType = 2; + }; + 84177758085A10D2000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_opengl.c; + path = ../../hardware/r_opengl/r_opengl.c; + refType = 2; + }; + 84177759085A10D2000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_opengl.h; + path = ../../hardware/r_opengl/r_opengl.h; + refType = 2; + }; + 8417775A085A10EB000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_argv.c; + path = ../../m_argv.c; + refType = 2; + }; + 8417775B085A10EB000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_argv.h; + path = ../../m_argv.h; + refType = 2; + }; + 8417775C085A10EB000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_bbox.c; + path = ../../m_bbox.c; + refType = 2; + }; + 8417775D085A10EB000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_bbox.h; + path = ../../m_bbox.h; + refType = 2; + }; + 8417775E085A10EB000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_cheat.c; + path = ../../m_cheat.c; + refType = 2; + }; + 8417775F085A10EB000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_cheat.h; + path = ../../m_cheat.h; + refType = 2; + }; + 84177760085A10EB000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_fixed.c; + path = ../../m_fixed.c; + refType = 2; + }; + 84177761085A10EB000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_fixed.h; + path = ../../m_fixed.h; + refType = 2; + }; + 84177762085A10EB000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_menu.c; + path = ../../m_menu.c; + refType = 2; + }; + 84177763085A10EB000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_menu.h; + path = ../../m_menu.h; + refType = 2; + }; + 84177764085A10EB000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_misc.c; + path = ../../m_misc.c; + refType = 2; + }; + 84177765085A10EB000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_misc.h; + path = ../../m_misc.h; + refType = 2; + }; + 84177766085A10EB000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_random.c; + path = ../../m_random.c; + refType = 2; + }; + 84177767085A10EB000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_random.h; + path = ../../m_random.h; + refType = 2; + }; + 84177768085A10EB000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = m_swap.h; + path = ../../m_swap.h; + refType = 2; + }; + 84177769085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_ceilng.c; + path = ../../p_ceilng.c; + refType = 2; + }; + 8417776A085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_enemy.c; + path = ../../p_enemy.c; + refType = 2; + }; + 8417776B085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_fab.c; + path = ../../p_fab.c; + refType = 2; + }; + 8417776C085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_floor.c; + path = ../../p_floor.c; + refType = 2; + }; + 8417776D085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_inter.c; + path = ../../p_inter.c; + refType = 2; + }; + 8417776E085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_lights.c; + path = ../../p_lights.c; + refType = 2; + }; + 8417776F085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_local.h; + path = ../../p_local.h; + refType = 2; + }; + 84177770085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_map.c; + path = ../../p_map.c; + refType = 2; + }; + 84177771085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_maputl.c; + path = ../../p_maputl.c; + refType = 2; + }; + 84177772085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_maputl.h; + path = ../../p_maputl.h; + refType = 2; + }; + 84177773085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_mobj.c; + path = ../../p_mobj.c; + refType = 2; + }; + 84177774085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_mobj.h; + path = ../../p_mobj.h; + refType = 2; + }; + 84177775085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_pspr.h; + path = ../../p_pspr.h; + refType = 2; + }; + 84177776085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_saveg.c; + path = ../../p_saveg.c; + refType = 2; + }; + 84177777085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_saveg.h; + path = ../../p_saveg.h; + refType = 2; + }; + 84177778085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_setup.c; + path = ../../p_setup.c; + refType = 2; + }; + 84177779085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_setup.h; + path = ../../p_setup.h; + refType = 2; + }; + 8417777A085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_sight.c; + path = ../../p_sight.c; + refType = 2; + }; + 8417777B085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_spec.c; + path = ../../p_spec.c; + refType = 2; + }; + 8417777C085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_spec.h; + path = ../../p_spec.h; + refType = 2; + }; + 8417777D085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_telept.c; + path = ../../p_telept.c; + refType = 2; + }; + 8417777E085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_tick.c; + path = ../../p_tick.c; + refType = 2; + }; + 8417777F085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_tick.h; + path = ../../p_tick.h; + refType = 2; + }; + 84177780085A1104000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = p_user.c; + path = ../../p_user.c; + refType = 2; + }; + 84177781085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_bsp.c; + path = ../../r_bsp.c; + refType = 2; + }; + 84177782085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_bsp.h; + path = ../../r_bsp.h; + refType = 2; + }; + 84177783085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_data.c; + path = ../../r_data.c; + refType = 2; + }; + 84177784085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_data.h; + path = ../../r_data.h; + refType = 2; + }; + 84177785085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_defs.h; + path = ../../r_defs.h; + refType = 2; + }; + 84177786085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_draw.c; + path = ../../r_draw.c; + refType = 2; + }; + 84177787085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_draw.h; + path = ../../r_draw.h; + refType = 2; + }; + 84177788085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_draw8.c; + path = ../../r_draw8.c; + refType = 2; + }; + 84177789085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_draw16.c; + path = ../../r_draw16.c; + refType = 2; + }; + 8417778A085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_local.h; + path = ../../r_local.h; + refType = 2; + }; + 8417778B085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_main.c; + path = ../../r_main.c; + refType = 2; + }; + 8417778C085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_main.h; + path = ../../r_main.h; + refType = 2; + }; + 8417778D085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_plane.c; + path = ../../r_plane.c; + refType = 2; + }; + 8417778E085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_plane.h; + path = ../../r_plane.h; + refType = 2; + }; + 8417778F085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_segs.c; + path = ../../r_segs.c; + refType = 2; + }; + 84177790085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_segs.h; + path = ../../r_segs.h; + refType = 2; + }; + 84177791085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_sky.c; + path = ../../r_sky.c; + refType = 2; + }; + 84177792085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_sky.h; + path = ../../r_sky.h; + refType = 2; + }; + 84177793085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_splats.c; + path = ../../r_splats.c; + refType = 2; + }; + 84177794085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_splats.h; + path = ../../r_splats.h; + refType = 2; + }; + 84177795085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_state.h; + path = ../../r_state.h; + refType = 2; + }; + 84177796085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_things.c; + path = ../../r_things.c; + refType = 2; + }; + 84177797085A111B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = r_things.h; + path = ../../r_things.h; + refType = 2; + }; + 84177798085A1138000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = s_sound.c; + path = ../../s_sound.c; + refType = 2; + }; + 84177799085A1138000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = s_sound.h; + path = ../../s_sound.h; + refType = 2; + }; + 8417779A085A1138000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = sounds.c; + path = ../../sounds.c; + refType = 2; + }; + 8417779B085A1138000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = sounds.h; + path = ../../sounds.h; + refType = 2; + }; + 8417779C085A114C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + path = mac_alert.c; + refType = 2; + }; + 8417779D085A114C000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + path = mac_alert.h; + refType = 2; + }; + 8417779E085A116B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = SDL_macosx_main.h; + path = ../SDL_main/SDL_macosx_main.h; + refType = 2; + }; + 8417779F085A116B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = SDL_macosx_main.m; + path = ../SDL_main/SDL_macosx_main.m; + refType = 2; + }; + 841777A0085A117F000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = w_wad.c; + path = ../../w_wad.c; + refType = 2; + }; + 841777A1085A117F000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = w_wad.h; + path = ../../w_wad.h; + refType = 2; + }; + 841777A2085A1197000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = screen.c; + path = ../../screen.c; + refType = 2; + }; + 841777A3085A1197000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = screen.h; + path = ../../screen.h; + refType = 2; + }; + 841777A4085A1200000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = filesrch.h; + path = ../../filesrch.h; + refType = 2; + }; + 841777A5085A1200000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = i_joy.h; + path = ../../i_joy.h; + refType = 2; + }; + 841777A6085A1200000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = i_net.h; + path = ../../i_net.h; + refType = 2; + }; + 841777A8085A1200000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = i_sound.h; + path = ../../i_sound.h; + refType = 2; + }; + 841777A9085A1200000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = i_system.h; + path = ../../i_system.h; + refType = 2; + }; + 841777AA085A1200000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = i_tcp.c; + path = ../../i_tcp.c; + refType = 2; + }; + 841777AB085A1200000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = i_tcp.h; + path = ../../i_tcp.h; + refType = 2; + }; + 841777AC085A1200000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = i_video.h; + path = ../../i_video.h; + refType = 2; + }; + 841777AD085A1200000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = mserv.c; + path = ../../mserv.c; + refType = 2; + }; + 841777AE085A1200000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = mserv.h; + path = ../../mserv.h; + refType = 2; + }; + 841777AF085A1228000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = md5.c; + path = ../../md5.c; + refType = 2; + }; + 841777B0085A1228000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = md5.h; + path = ../../md5.h; + refType = 2; + }; + 841778BC085A122A000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = z_zone.c; + path = ../../z_zone.c; + refType = 2; + }; + 841778BD085A122A000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = z_zone.h; + path = ../../z_zone.h; + refType = 2; + }; + 841778BE085A1295000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = am_map.c; + path = ../../am_map.c; + refType = 2; + }; + 841778BF085A1295000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = am_map.h; + path = ../../am_map.h; + refType = 2; + }; + 841778C0085A1295000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = command.c; + path = ../../command.c; + refType = 2; + }; + 841778C1085A1295000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = command.h; + path = ../../command.h; + refType = 2; + }; + 841778C2085A1295000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = console.c; + path = ../../console.c; + refType = 2; + }; + 841778C3085A1295000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = console.h; + path = ../../console.h; + refType = 2; + }; + 841778C4085A1295000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = info.c; + path = ../../info.c; + refType = 2; + }; + 841778C5085A1295000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = info.h; + path = ../../info.h; + refType = 2; + }; + 841778C6085A1295000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = keys.h; + path = ../../keys.h; + refType = 2; + }; + 841779D2085A1296000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = st_stuff.c; + path = ../../st_stuff.c; + refType = 2; + }; + 841779D3085A1296000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = st_stuff.h; + path = ../../st_stuff.h; + refType = 2; + }; + 841779D4085A1296000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = tables.c; + path = ../../tables.c; + refType = 2; + }; + 841779D5085A1296000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = tables.h; + path = ../../tables.h; + refType = 2; + }; + 841779D7085A1296000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = v_video.h; + path = ../../v_video.h; + refType = 2; + }; + 841779D8085A1296000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = y_inter.c; + path = ../../y_inter.c; + refType = 2; + }; + 841779DA085A1347000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = byteptr.h; + path = ../../byteptr.h; + refType = 2; + }; + 841779DC085A138F000C01D8 = { + buildActionMask = 2147483647; + files = ( + 6755C8C7101802C300A80195, + 6755C8C8101802C300A80195, + 6755C8C9101802C300A80195, + 6755C8CA101802C300A80195, + 6755C8CB101802C300A80195, + 6755C8CC101802C300A80195, + 6755C8CD101802C300A80195, + 6755C8CE101802C300A80195, + 6755C8CF101802C300A80195, + ); + isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 841779DD085A138F000C01D8 = { + buildActionMask = 2147483647; + files = ( + 84177A2A085A18A8000C01D8, + 84177A2E085A18D2000C01D8, + 84177A30085A18D3000C01D8, + 84177A32085A18D4000C01D8, + 84177A34085A18D5000C01D8, + 84177A39085A18D8000C01D8, + 84177A3F085A18DC000C01D8, + 84177A41085A18E0000C01D8, + 84177A43085A18E1000C01D8, + 84177A46085A18E8000C01D8, + 84177A4A085A18EA000C01D8, + 84177A4E085A18EC000C01D8, + 84177A50085A18F2000C01D8, + 84177A52085A193F000C01D8, + 84177A53085A1940000C01D8, + 84177A54085A1942000C01D8, + 84177A55085A1943000C01D8, + 84177A56085A195A000C01D8, + 84177A57085A195B000C01D8, + 84177A58085A1968000C01D8, + 84177A59085A1969000C01D8, + 84177A5A085A196B000C01D8, + 84177A5B085A197A000C01D8, + 84177A5C085A197C000C01D8, + 84177A5D085A197D000C01D8, + 84177A5E085A197E000C01D8, + 84177A5F085A1980000C01D8, + 84177A61085A1985000C01D8, + 84177A62085A1986000C01D8, + 84177A63085A1988000C01D8, + 84177A64085A1989000C01D8, + 84177A65085A198A000C01D8, + 84177A66085A198A000C01D8, + 84177A67085A198B000C01D8, + 84177A68085A198C000C01D8, + 84177A69085A198E000C01D8, + 84177A6B085A1994000C01D8, + 84177A6C085A1995000C01D8, + 84177A6D085A199D000C01D8, + 84177A6E085A19A0000C01D8, + 84177A6F085A19A1000C01D8, + 84177A70085A19A2000C01D8, + 84177A71085A19A4000C01D8, + 84177A72085A19A5000C01D8, + 84177A73085A19A6000C01D8, + 84177A74085A19A7000C01D8, + 84177A75085A19AC000C01D8, + 84177A76085A19AD000C01D8, + 84177A77085A19AE000C01D8, + 84177A78085A19AE000C01D8, + 84177A79085A19AF000C01D8, + 84177A7A085A19B0000C01D8, + 84177A7B085A19B3000C01D8, + 84177A7C085A19B4000C01D8, + 84177A7D085A19B5000C01D8, + 84177A7E085A19B7000C01D8, + 84177A7F085A19B8000C01D8, + 84177A80085A19B9000C01D8, + 84177A81085A19BA000C01D8, + 84177A82085A19BB000C01D8, + 84177A83085A19BB000C01D8, + 84177A84085A19BC000C01D8, + 84177A85085A19C1000C01D8, + 84177A86085A19C2000C01D8, + 84177A87085A19C3000C01D8, + 84177A88085A19C6000C01D8, + 84177A89085A19C7000C01D8, + 84177A8A085A19C9000C01D8, + 84177A8B085A19CC000C01D8, + 84177A8C085A19CD000C01D8, + 84177A8D085A19CF000C01D8, + 84177A8E085A19D0000C01D8, + 84177A90085A19D8000C01D8, + 84177A91085A19D9000C01D8, + 84177A92085A19DD000C01D8, + 84177A93085A19DF000C01D8, + 84177A94085A19E1000C01D8, + 84177A95085A19E3000C01D8, + 84177A96085A19E6000C01D8, + 8490D438085DF57B000C01D8, + 849603AA0A791C11000C01D8, + 6755C7B21017FE2500A80195, + 6755C7B31017FE2500A80195, + 6755C7B51017FE2500A80195, + 6755C7B71017FE2500A80195, + 6755C7B81017FE2500A80195, + 6755C84B1017FE4500A80195, + 6755C8651017FE4500A80195, + 677B5EC810180D4E00A80195, + 67B2D0C91018779900A80195, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 841779DE085A138F000C01D8 = { + buildActionMask = 2147483647; + files = ( + 84C4E0410862096F000C01D8, + 84C4E0440862098A000C01D8, + 84C4E047086209D3000C01D8, + 84C4E04A086209FF000C01D8, + 84C4E04F08620A46000C01D8, + 84C4E05008620A46000C01D8, + 849BD31E0A7E45B3000C01D8, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 841779E0085A138F000C01D8 = { + buildPhases = ( + 841779DC085A138F000C01D8, + 841779DD085A138F000C01D8, + 841779DE085A138F000C01D8, + ); + buildSettings = { + DEBUGGING_SYMBOLS = NO; + FRAMEWORK_SEARCH_PATHS = "\"$(LOCAL_LIBRARY_DIR)/Frameworks\""; + HEADER_SEARCH_PATHS = "\"$(LOCAL_LIBRARY_DIR)/Frameworks/SDL.framework/Headers\" \"$(LOCAL_LIBRARY_DIR)/Frameworks/SDL_mixer.framework/Headers\" \"$(LOCAL_LIBRARY_DIR)/Frameworks/OpenAL.framework/Headers\" \"$(LOCAL_LIBRARY_DIR)/Frameworks/libpng.framework/Headers\""; + INSTALL_PATH = "$(HOME)/Applications"; + JAVA_COMPILER_DEBUGGING_SYMBOLS = NO; + OPTIMIZATION_CFLAGS = "-O2"; + OTHER_CFLAGS = "-DMAC_ALERT -DUNIXCOMMON -DSDLMAIN -DHAVE_MIXER -DHAVE_PNG -D_BIG_ENDIAN -DSTDC_HEADERS -DSDL -Wall -Winline -fno-strict-aliasing"; + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = Srb2; + SECTORDER_FLAGS = ""; + USE_GCC3_PFE_SUPPORT = NO; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas -Wno-long-double"; + WRAPPER_EXTENSION = app; + }; + dependencies = ( + ); + isa = PBXApplicationTarget; + name = Srb2; + productInstallPath = "$(HOME)/Applications"; + productName = Srb2; + productReference = 841779E1085A138F000C01D8; + productSettingsXML = " + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + Srb2 + CFBundleGetInfoString + + CFBundleIconFile + Srb2mac + CFBundleIdentifier + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Sonic Robo Blast 2 + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.09 + CFBundleSignature + ???? + CFBundleVersion + 1.09 + NSMainNibFile + SDL_Main.nib + NSPrincipalClass + NSApplication + + +"; + }; + 841779E1085A138F000C01D8 = { + isa = PBXApplicationReference; + path = Srb2.app; + refType = 3; + }; + 841779E2085A138F000C01D8 = { + children = ( + 841779E1085A138F000C01D8, + 841779EA085A13B1000C01D8, + ); + isa = PBXGroup; + name = Products; + refType = 4; + }; + 841779E6085A13B1000C01D8 = { + buildActionMask = 2147483647; + files = ( + 84177A98085A1A0B000C01D8, + 84177A99085A1A0E000C01D8, + 84177A9A085A1A0F000C01D8, + 84177A9B085A1A11000C01D8, + 84177A9C085A1A12000C01D8, + 84177A9D085A1A14000C01D8, + 84177A9E085A1A16000C01D8, + 84177A9F085A1A1E000C01D8, + 84177AA0085A1A1F000C01D8, + 84177AA1085A1A24000C01D8, + 84177AA2085A1A25000C01D8, + 84177AA3085A1A27000C01D8, + 84177AA4085A1A28000C01D8, + 84177AA5085A1A2B000C01D8, + 84177AA6085A1A2C000C01D8, + 84177AA7085A1A2D000C01D8, + 84177AA8085A1A2F000C01D8, + 84177AA9085A1A30000C01D8, + 84177AAA085A1A31000C01D8, + 84177AB4085A1A5E000C01D8, + 84177AB5085A1A60000C01D8, + 84177AB8085A1A65000C01D8, + 84177AB9085A1A65000C01D8, + 84177ABA085A1A66000C01D8, + 84177ABB085A1A67000C01D8, + 84177ABC085A1A67000C01D8, + 84177ABD085A1A68000C01D8, + 84177AC1085A1A70000C01D8, + 84177AC2085A1A72000C01D8, + 84177AC3085A1A77000C01D8, + 84177AC4085A1A78000C01D8, + 84177AC5085A1A7A000C01D8, + 84177AC6085A1A7B000C01D8, + 84177AC7085A1A7C000C01D8, + 84177AC8085A1A7D000C01D8, + 84177AC9085A1A7F000C01D8, + 84177ACA085A1A87000C01D8, + 84177ACB085A1A88000C01D8, + 84177ACC085A1A88000C01D8, + 84177ACD085A1A89000C01D8, + 84177ACE085A1A8A000C01D8, + 84177ACF085A1A8B000C01D8, + 84177AD0085A1A8C000C01D8, + 84177AD1085A1A8D000C01D8, + 84177AD2085A1A90000C01D8, + 84177AD4085A1A92000C01D8, + 84177AD5085A1A93000C01D8, + 84177AD6085A1A94000C01D8, + 84177AD7085A1A97000C01D8, + 84177AD8085A1A97000C01D8, + 84177AD9085A1A99000C01D8, + 84177ADA085A1A9F000C01D8, + 84177ADB085A1AA0000C01D8, + 84177ADC085A1AA2000C01D8, + 84177ADF085A1AA4000C01D8, + 84177AE0085A1AA6000C01D8, + 84177AE1085A1AA7000C01D8, + 84177AE2085A1AA8000C01D8, + 84177AE3085A1AA9000C01D8, + 84177AE4085A1AAA000C01D8, + 84177AE5085A1AAE000C01D8, + 84177AE7085A1AB5000C01D8, + 84177AE8085A1AB6000C01D8, + 84177AEB085A1ABD000C01D8, + 84177AEC085A1ABF000C01D8, + 84177AED085A1ABF000C01D8, + 8490D432085DF3D6000C01D8, + 8490D437085DF57B000C01D8, + 8490D43C085E0518000C01D8, + 8490D43D085E05F6000C01D8, + 8490D43E085E05F7000C01D8, + 8490D43F085E05F8000C01D8, + 8490D440085E05FA000C01D8, + 8490D441085E05FB000C01D8, + 8490D442085E05FC000C01D8, + 8490D443085E05FE000C01D8, + 8490D444085E05FF000C01D8, + 8490D445085E0606000C01D8, + 8490D446085E060A000C01D8, + 8490D447085E060B000C01D8, + 8490D448085E067E000C01D8, + 849603A90A791C11000C01D8, + 6755C7BB1017FE2500A80195, + 6755C7BC1017FE2500A80195, + 6755C7BD1017FE2500A80195, + 6755C7BE1017FE2500A80195, + 6755C7BF1017FE2500A80195, + 6755C7C01017FE2500A80195, + 6755C7C11017FE2500A80195, + 6755C8861017FE4500A80195, + 6755C8871017FE4500A80195, + 6755C8A01017FE4500A80195, + 67B2D0CA1018779D00A80195, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 841779E7085A13B1000C01D8 = { + buildActionMask = 2147483647; + files = ( + 84C4E0400862096F000C01D8, + 84C4E0430862098A000C01D8, + 84C4E046086209D3000C01D8, + 84C4E049086209FF000C01D8, + 84C4E04E08620A46000C01D8, + 8494DFE80886EA0D000C01D8, + 849BD31D0A7E45B3000C01D8, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 841779E9085A13B1000C01D8 = { + buildPhases = ( + 840CE6B009198AA7000C01D8, + 6726EB5E10190F860074DCBA, + 6726EB5F10190FFC0074DCBA, + 841779E6085A13B1000C01D8, + 841779E7085A13B1000C01D8, + ); + buildSettings = { + FRAMEWORK_SEARCH_PATHS = "\"$(LOCAL_LIBRARY_DIR)/Frameworks\""; + HEADER_SEARCH_PATHS = "\"$(LOCAL_LIBRARY_DIR)/Frameworks/SDL.framework/Headers\" \"$(LOCAL_LIBRARY_DIR)/Frameworks/SDL_mixer.framework/Headers\" \"$(LOCAL_LIBRARY_DIR)/Frameworks/OpenAL.framework/Headers\" \"$(LOCAL_LIBRARY_DIR)/Frameworks/libpng.framework/Headers\""; + INSTALL_PATH = "$(HOME)/Applications"; + OPTIMIZATION_CFLAGS = "-O0"; + OTHER_CFLAGS = "-DMAC_ALERT -DUNIXCOMMON -DSDLMAIN -DHAVE_MIXER -DHAVE_PNG -D_BIG_ENDIAN -DSTDC_HEADERS -DSDL -Wall -W -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wsign-compare -Waggregate-return -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -fno-strict-aliasing -fno-exceptions -D_DEBUG"; + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = Srb2Debug; + SECTORDER_FLAGS = ""; + USE_GCC3_PFE_SUPPORT = NO; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas -Wno-long-double"; + WRAPPER_EXTENSION = app; + }; + dependencies = ( + ); + isa = PBXApplicationTarget; + name = Srb2Debug; + productInstallPath = "$(HOME)/Applications"; + productName = Srb2Debug; + productReference = 841779EA085A13B1000C01D8; + productSettingsXML = " + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + Srb2Debug + CFBundleGetInfoString + + CFBundleIconFile + srb2mac + CFBundleIdentifier + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Sonic Robo Blast 2 + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.09 + CFBundleSignature + ???? + CFBundleVersion + 1.09 Debug + NSMainNibFile + SDL_Main.nib + NSPrincipalClass + NSApplication + + +"; + }; + 841779EA085A13B1000C01D8 = { + isa = PBXApplicationReference; + path = Srb2Debug.app; + refType = 3; + }; + 84177A2A085A18A8000C01D8 = { + fileRef = 84177713085A0FCE000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A2E085A18D2000C01D8 = { + fileRef = 84177717085A0FCE000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A30085A18D3000C01D8 = { + fileRef = 84177719085A0FCE000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A32085A18D4000C01D8 = { + fileRef = 8417771B085A0FCE000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A34085A18D5000C01D8 = { + fileRef = 8417771D085A0FCE000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A39085A18D8000C01D8 = { + fileRef = 84177722085A0FCE000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A41085A18E0000C01D8 = { + fileRef = 8417772A085A100E000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A43085A18E1000C01D8 = { + fileRef = 8417772C085A100E000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A46085A18E8000C01D8 = { + fileRef = 841778C4085A1295000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A4A085A18EA000C01D8 = { + fileRef = 8417772D085A1029000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A4E085A18EC000C01D8 = { + fileRef = 841779D4085A1296000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A50085A18F2000C01D8 = { + fileRef = 8417772F085A1029000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A52085A193F000C01D8 = { + fileRef = 841778C2085A1295000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A53085A1940000C01D8 = { + fileRef = 841778C0085A1295000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A54085A1942000C01D8 = { + fileRef = 841778BE085A1295000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A55085A1943000C01D8 = { + fileRef = 84177732085A1040000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A56085A195A000C01D8 = { + fileRef = 841779D2085A1296000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A57085A195B000C01D8 = { + fileRef = 841779D8085A1296000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A58085A1968000C01D8 = { + fileRef = 84177734085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A59085A1969000C01D8 = { + fileRef = 84177735085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A5A085A196B000C01D8 = { + fileRef = 84177739085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A5B085A197A000C01D8 = { + fileRef = 8417773D085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A5C085A197C000C01D8 = { + fileRef = 8417773F085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A5D085A197D000C01D8 = { + fileRef = 84177741085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A5E085A197E000C01D8 = { + fileRef = 84177743085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A5F085A1980000C01D8 = { + fileRef = 84177745085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A61085A1985000C01D8 = { + fileRef = 84177749085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A62085A1986000C01D8 = { + fileRef = 8417774B085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A63085A1988000C01D8 = { + fileRef = 8417774E085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A64085A1989000C01D8 = { + fileRef = 8417774F085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A65085A198A000C01D8 = { + fileRef = 84177750085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A66085A198A000C01D8 = { + fileRef = 84177751085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A67085A198B000C01D8 = { + fileRef = 84177752085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A68085A198C000C01D8 = { + fileRef = 84177753085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A69085A198E000C01D8 = { + fileRef = 84177755085A10AA000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A6B085A1994000C01D8 = { + fileRef = 841777AA085A1200000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A6C085A1995000C01D8 = { + fileRef = 841777AD085A1200000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A6D085A199D000C01D8 = { + fileRef = 8417774C085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A6E085A19A0000C01D8 = { + fileRef = 8417775A085A10EB000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A6F085A19A1000C01D8 = { + fileRef = 8417775C085A10EB000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A70085A19A2000C01D8 = { + fileRef = 8417775E085A10EB000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A71085A19A4000C01D8 = { + fileRef = 84177760085A10EB000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A72085A19A5000C01D8 = { + fileRef = 84177762085A10EB000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A73085A19A6000C01D8 = { + fileRef = 84177764085A10EB000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A74085A19A7000C01D8 = { + fileRef = 84177766085A10EB000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A75085A19AC000C01D8 = { + fileRef = 84177769085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A76085A19AD000C01D8 = { + fileRef = 8417776A085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A77085A19AE000C01D8 = { + fileRef = 8417776B085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A78085A19AE000C01D8 = { + fileRef = 8417776C085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A79085A19AF000C01D8 = { + fileRef = 8417776D085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A7A085A19B0000C01D8 = { + fileRef = 8417776E085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A7B085A19B3000C01D8 = { + fileRef = 84177770085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A7C085A19B4000C01D8 = { + fileRef = 84177771085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A7D085A19B5000C01D8 = { + fileRef = 84177773085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A7E085A19B7000C01D8 = { + fileRef = 84177776085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A7F085A19B8000C01D8 = { + fileRef = 84177778085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A80085A19B9000C01D8 = { + fileRef = 8417777A085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A81085A19BA000C01D8 = { + fileRef = 8417777B085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A82085A19BB000C01D8 = { + fileRef = 8417777D085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A83085A19BB000C01D8 = { + fileRef = 8417777E085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A84085A19BC000C01D8 = { + fileRef = 84177780085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A85085A19C1000C01D8 = { + fileRef = 84177781085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A86085A19C2000C01D8 = { + fileRef = 84177783085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A87085A19C3000C01D8 = { + fileRef = 84177786085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A88085A19C6000C01D8 = { + fileRef = 8417778B085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A89085A19C7000C01D8 = { + fileRef = 8417778D085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A8A085A19C9000C01D8 = { + fileRef = 8417778F085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A8B085A19CC000C01D8 = { + fileRef = 84177791085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A8C085A19CD000C01D8 = { + fileRef = 84177793085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A8D085A19CF000C01D8 = { + fileRef = 84177796085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A8E085A19D0000C01D8 = { + fileRef = 841777A2085A1197000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A90085A19D8000C01D8 = { + fileRef = 84177798085A1138000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A91085A19D9000C01D8 = { + fileRef = 8417779A085A1138000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A92085A19DD000C01D8 = { + fileRef = 8417779C085A114C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A93085A19DF000C01D8 = { + fileRef = 8417779F085A116B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A94085A19E1000C01D8 = { + fileRef = 841777A0085A117F000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A95085A19E3000C01D8 = { + fileRef = 841777AF085A1228000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A96085A19E6000C01D8 = { + fileRef = 841778BC085A122A000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A98085A1A0B000C01D8 = { + fileRef = 84177713085A0FCE000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A99085A1A0E000C01D8 = { + fileRef = 84177717085A0FCE000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A9A085A1A0F000C01D8 = { + fileRef = 84177719085A0FCE000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A9B085A1A11000C01D8 = { + fileRef = 8417771B085A0FCE000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A9C085A1A12000C01D8 = { + fileRef = 8417771D085A0FCE000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A9D085A1A14000C01D8 = { + fileRef = 84177722085A0FCE000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177A9F085A1A1E000C01D8 = { + fileRef = 8417772A085A100E000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AA0085A1A1F000C01D8 = { + fileRef = 8417772C085A100E000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AA1085A1A24000C01D8 = { + fileRef = 841778C4085A1295000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AA2085A1A25000C01D8 = { + fileRef = 8417772D085A1029000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AA3085A1A27000C01D8 = { + fileRef = 8417772F085A1029000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AA4085A1A28000C01D8 = { + fileRef = 841779D4085A1296000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AA5085A1A2B000C01D8 = { + fileRef = 841778BE085A1295000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AA6085A1A2C000C01D8 = { + fileRef = 841778C2085A1295000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AA7085A1A2D000C01D8 = { + fileRef = 841778C0085A1295000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AA8085A1A2F000C01D8 = { + fileRef = 84177732085A1040000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AA9085A1A30000C01D8 = { + fileRef = 841779D2085A1296000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AAA085A1A31000C01D8 = { + fileRef = 841779D8085A1296000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AB4085A1A5E000C01D8 = { + fileRef = 84177749085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AB5085A1A60000C01D8 = { + fileRef = 8417774B085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AB8085A1A65000C01D8 = { + fileRef = 8417774E085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AB9085A1A65000C01D8 = { + fileRef = 8417774F085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177ABA085A1A66000C01D8 = { + fileRef = 84177750085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177ABB085A1A67000C01D8 = { + fileRef = 84177751085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177ABC085A1A67000C01D8 = { + fileRef = 84177752085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177ABD085A1A68000C01D8 = { + fileRef = 84177753085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AC1085A1A70000C01D8 = { + fileRef = 841777AA085A1200000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AC2085A1A72000C01D8 = { + fileRef = 841777AD085A1200000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AC3085A1A77000C01D8 = { + fileRef = 8417775A085A10EB000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AC4085A1A78000C01D8 = { + fileRef = 8417775C085A10EB000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AC5085A1A7A000C01D8 = { + fileRef = 8417775E085A10EB000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AC6085A1A7B000C01D8 = { + fileRef = 84177760085A10EB000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AC7085A1A7C000C01D8 = { + fileRef = 84177762085A10EB000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AC8085A1A7D000C01D8 = { + fileRef = 84177764085A10EB000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AC9085A1A7F000C01D8 = { + fileRef = 84177766085A10EB000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177ACA085A1A87000C01D8 = { + fileRef = 84177769085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177ACB085A1A88000C01D8 = { + fileRef = 8417776A085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177ACC085A1A88000C01D8 = { + fileRef = 8417776B085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177ACD085A1A89000C01D8 = { + fileRef = 8417776C085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177ACE085A1A8A000C01D8 = { + fileRef = 8417776D085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177ACF085A1A8B000C01D8 = { + fileRef = 8417776E085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AD0085A1A8C000C01D8 = { + fileRef = 84177770085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AD1085A1A8D000C01D8 = { + fileRef = 84177771085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AD2085A1A90000C01D8 = { + fileRef = 84177773085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AD4085A1A92000C01D8 = { + fileRef = 84177778085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AD5085A1A93000C01D8 = { + fileRef = 8417777A085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AD6085A1A94000C01D8 = { + fileRef = 8417777B085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AD7085A1A97000C01D8 = { + fileRef = 8417777D085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AD8085A1A97000C01D8 = { + fileRef = 8417777E085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AD9085A1A99000C01D8 = { + fileRef = 84177780085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177ADA085A1A9F000C01D8 = { + fileRef = 84177781085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177ADB085A1AA0000C01D8 = { + fileRef = 84177783085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177ADC085A1AA2000C01D8 = { + fileRef = 84177786085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177ADF085A1AA4000C01D8 = { + fileRef = 8417778B085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AE0085A1AA6000C01D8 = { + fileRef = 8417778D085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AE1085A1AA7000C01D8 = { + fileRef = 8417778F085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AE2085A1AA8000C01D8 = { + fileRef = 84177791085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AE3085A1AA9000C01D8 = { + fileRef = 84177793085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AE4085A1AAA000C01D8 = { + fileRef = 84177796085A111B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AE5085A1AAE000C01D8 = { + fileRef = 841777A2085A1197000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AE7085A1AB5000C01D8 = { + fileRef = 84177798085A1138000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AE8085A1AB6000C01D8 = { + fileRef = 8417779A085A1138000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AEB085A1ABD000C01D8 = { + fileRef = 841777AF085A1228000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AEC085A1ABF000C01D8 = { + fileRef = 841777A0085A117F000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84177AED085A1ABF000C01D8 = { + fileRef = 841778BC085A122A000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D432085DF3D6000C01D8 = { + fileRef = 84177776085A1104000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D433085DF537000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = y_inter.h; + path = ../../y_inter.h; + refType = 2; + }; + 8490D436085DF57B000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = v_video.c; + path = ../../v_video.c; + refType = 2; + }; + 8490D437085DF57B000C01D8 = { + fileRef = 8490D436085DF57B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D438085DF57B000C01D8 = { + fileRef = 8490D436085DF57B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D43C085E0518000C01D8 = { + fileRef = 8417779F085A116B000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D43D085E05F6000C01D8 = { + fileRef = 84177734085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D43E085E05F7000C01D8 = { + fileRef = 84177735085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D43F085E05F8000C01D8 = { + fileRef = 84177739085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D440085E05FA000C01D8 = { + fileRef = 8417773D085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D441085E05FB000C01D8 = { + fileRef = 8417773F085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D442085E05FC000C01D8 = { + fileRef = 84177741085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D443085E05FE000C01D8 = { + fileRef = 84177743085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D444085E05FF000C01D8 = { + fileRef = 84177745085A106C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D445085E0606000C01D8 = { + fileRef = 8417774C085A1097000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D446085E060A000C01D8 = { + fileRef = 84177755085A10AA000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D447085E060B000C01D8 = { + fileRef = 84177758085A10D2000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8490D448085E067E000C01D8 = { + fileRef = 8417779C085A114C000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 8494DFE80886EA0D000C01D8 = { + fileRef = 84C4E04B08620A46000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 849603A80A791C11000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = comptime.c; + path = ../../comptime.c; + refType = 2; + }; + 849603A90A791C11000C01D8 = { + fileRef = 849603A80A791C11000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 849603AA0A791C11000C01D8 = { + fileRef = 849603A80A791C11000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 849BD31C0A7E45B3000C01D8 = { + isa = PBXFrameworkReference; + name = libpng.framework; + path = /Library/Frameworks/libpng.framework; + refType = 0; + }; + 849BD31D0A7E45B3000C01D8 = { + fileRef = 849BD31C0A7E45B3000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 849BD31E0A7E45B3000C01D8 = { + fileRef = 849BD31C0A7E45B3000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 849BD32D0A7E471D000C01D8 = { + fileRef = 849BD31C0A7E45B3000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84C4E00D0862063C000C01D8 = { + children = ( + 6755C8BE101802C300A80195, + 6755C8BF101802C300A80195, + 6755C8C0101802C300A80195, + 6755C8C1101802C300A80195, + 6755C8C2101802C300A80195, + 6755C8C3101802C300A80195, + 6755C8C4101802C300A80195, + 6755C8C5101802C300A80195, + 6755C8C6101802C300A80195, + ); + isa = PBXGroup; + name = Data; + refType = 4; + }; + 84C4E03F0862096F000C01D8 = { + isa = PBXFrameworkReference; + name = AppKit.framework; + path = /System/Library/Frameworks/AppKit.framework; + refType = 0; + }; + 84C4E0400862096F000C01D8 = { + fileRef = 84C4E03F0862096F000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84C4E0410862096F000C01D8 = { + fileRef = 84C4E03F0862096F000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84C4E0420862098A000C01D8 = { + isa = PBXFrameworkReference; + name = Foundation.framework; + path = /System/Library/Frameworks/Foundation.framework; + refType = 0; + }; + 84C4E0430862098A000C01D8 = { + fileRef = 84C4E0420862098A000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84C4E0440862098A000C01D8 = { + fileRef = 84C4E0420862098A000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84C4E045086209D3000C01D8 = { + isa = PBXFrameworkReference; + name = CoreFoundation.framework; + path = /System/Library/Frameworks/CoreFoundation.framework; + refType = 0; + }; + 84C4E046086209D3000C01D8 = { + fileRef = 84C4E045086209D3000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84C4E047086209D3000C01D8 = { + fileRef = 84C4E045086209D3000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84C4E048086209FF000C01D8 = { + isa = PBXFrameworkReference; + name = ApplicationServices.framework; + path = /System/Library/Frameworks/ApplicationServices.framework; + refType = 0; + }; + 84C4E049086209FF000C01D8 = { + fileRef = 84C4E048086209FF000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84C4E04A086209FF000C01D8 = { + fileRef = 84C4E048086209FF000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84C4E04B08620A46000C01D8 = { + isa = PBXFrameworkReference; + name = SDL_mixer.framework; + path = /Library/Frameworks/SDL_mixer.framework; + refType = 0; + }; + 84C4E04C08620A46000C01D8 = { + isa = PBXFrameworkReference; + name = SDL.framework; + path = /Library/Frameworks/SDL.framework; + refType = 0; + }; + 84C4E04E08620A46000C01D8 = { + fileRef = 84C4E04C08620A46000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84C4E04F08620A46000C01D8 = { + fileRef = 84C4E04B08620A46000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84C4E05008620A46000C01D8 = { + fileRef = 84C4E04C08620A46000C01D8; + isa = PBXBuildFile; + settings = { + }; + }; + 84F202C708A92A5D000C01D8 = { + isa = PBXFrameworkReference; + name = OpenAL.framework; + path = /Library/Frameworks/OpenAL.framework; + refType = 0; + }; + 84F202CA08A92AA0000C01D8 = { + fileEncoding = 30; + isa = PBXFileReference; + name = s_openal.c; + path = ../../hardware/s_openal/s_openal.c; + refType = 2; + }; + }; + rootObject = 84177702085A0C64000C01D8; +} diff --git a/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj new file mode 100644 index 000000000..1b1a9fdf6 --- /dev/null +++ b/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj @@ -0,0 +1,1510 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 44; + objects = { + +/* Begin PBXBuildFile section */ + 002F39FA09D0881F00EBEB88 /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F39F909D0881F00EBEB88 /* SDL.framework */; }; + 002F3A0009D0884600EBEB88 /* SDL.framework in Copy Frameworks into .app bundle */ = {isa = PBXBuildFile; fileRef = 002F39F909D0881F00EBEB88 /* SDL.framework */; }; + 1E308E720B71172D0015728C /* lzf.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44B2240B67EADE00BAD059 /* lzf.c */; }; + 1E32C4290B6E6D5D0029E058 /* libpng.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E32C4140B6E6D5D0029E058 /* libpng.framework */; }; + 1E32C42B0B6E6D6E0029E058 /* libpng.framework in Copy Frameworks into .app bundle */ = {isa = PBXBuildFile; fileRef = 1E32C4140B6E6D5D0029E058 /* libpng.framework */; }; + 1E44AE750B67CC2B00BAD059 /* hw_bsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE610B67CC2B00BAD059 /* hw_bsp.c */; }; + 1E44AE770B67CC2B00BAD059 /* hw3sound.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE630B67CC2B00BAD059 /* hw3sound.c */; }; + 1E44AE780B67CC2B00BAD059 /* hw_cache.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE640B67CC2B00BAD059 /* hw_cache.c */; }; + 1E44AE7C0B67CC2B00BAD059 /* hw_light.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE680B67CC2B00BAD059 /* hw_light.c */; }; + 1E44AE800B67CC2B00BAD059 /* hw_draw.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE6C0B67CC2B00BAD059 /* hw_draw.c */; }; + 1E44AE820B67CC2B00BAD059 /* hw_main.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE6E0B67CC2B00BAD059 /* hw_main.c */; }; + 1E44AE840B67CC2B00BAD059 /* hw_md2.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE700B67CC2B00BAD059 /* hw_md2.c */; }; + 1E44AE860B67CC2B00BAD059 /* hw_trick.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE720B67CC2B00BAD059 /* hw_trick.c */; }; + 1E44AEA40B67CC8500BAD059 /* d_clisrv.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE8D0B67CC8400BAD059 /* d_clisrv.c */; }; + 1E44AEA70B67CC8500BAD059 /* d_main.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE900B67CC8400BAD059 /* d_main.c */; }; + 1E44AEA80B67CC8500BAD059 /* d_net.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE910B67CC8500BAD059 /* d_net.c */; }; + 1E44AEAB0B67CC8500BAD059 /* d_netfil.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE940B67CC8500BAD059 /* d_netfil.c */; }; + 1E44AEAF0B67CC8500BAD059 /* d_netcmd.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE980B67CC8500BAD059 /* d_netcmd.c */; }; + 1E44AEB30B67CC8500BAD059 /* dehacked.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AE9C0B67CC8500BAD059 /* dehacked.c */; }; + 1E44AEBF0B67CCA900BAD059 /* f_wipe.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEBC0B67CCA900BAD059 /* f_wipe.c */; }; + 1E44AEC00B67CCA900BAD059 /* f_finale.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEBD0B67CCA900BAD059 /* f_finale.c */; }; + 1E44AEC80B67CCC600BAD059 /* g_game.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEC30B67CCC600BAD059 /* g_game.c */; }; + 1E44AECC0B67CCC600BAD059 /* g_input.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEC70B67CCC600BAD059 /* g_input.c */; }; + 1E44AED00B67CCEE00BAD059 /* hu_stuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AECE0B67CCEE00BAD059 /* hu_stuff.c */; }; + 1E44AEDC0B67CD1300BAD059 /* i_tcp.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AED50B67CD1200BAD059 /* i_tcp.c */; }; + 1E44AEE30B67CD2B00BAD059 /* am_map.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEE10B67CD2B00BAD059 /* am_map.c */; }; + 1E44AEE90B67CD3F00BAD059 /* command.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEE70B67CD3F00BAD059 /* command.c */; }; + 1E44AEEC0B67CD4400BAD059 /* comptime.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEEB0B67CD4400BAD059 /* comptime.c */; }; + 1E44AEEF0B67CD5400BAD059 /* console.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEED0B67CD5400BAD059 /* console.c */; }; + 1E44AEF30B67CD7F00BAD059 /* filesrch.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEF10B67CD7F00BAD059 /* filesrch.c */; }; + 1E44AF070B67CDE900BAD059 /* m_argv.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEF80B67CDE900BAD059 /* m_argv.c */; }; + 1E44AF0A0B67CDE900BAD059 /* m_cheat.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEFB0B67CDE900BAD059 /* m_cheat.c */; }; + 1E44AF0B0B67CDE900BAD059 /* m_bbox.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEFC0B67CDE900BAD059 /* m_bbox.c */; }; + 1E44AF0D0B67CDE900BAD059 /* m_fixed.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEFE0B67CDE900BAD059 /* m_fixed.c */; }; + 1E44AF0F0B67CDE900BAD059 /* m_menu.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF000B67CDE900BAD059 /* m_menu.c */; }; + 1E44AF110B67CDE900BAD059 /* m_misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF020B67CDE900BAD059 /* m_misc.c */; }; + 1E44AF130B67CDE900BAD059 /* m_random.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF040B67CDE900BAD059 /* m_random.c */; }; + 1E44AF1A0B67CE2A00BAD059 /* info.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF180B67CE2A00BAD059 /* info.c */; }; + 1E44AF1E0B67CE3600BAD059 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF1C0B67CE3600BAD059 /* md5.c */; }; + 1E44AF220B67CE4100BAD059 /* mserv.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF200B67CE4100BAD059 /* mserv.c */; }; + 1E44AF3C0B67CE5F00BAD059 /* p_enemy.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF240B67CE5F00BAD059 /* p_enemy.c */; }; + 1E44AF3D0B67CE5F00BAD059 /* p_inter.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF250B67CE5F00BAD059 /* p_inter.c */; }; + 1E44AF3E0B67CE5F00BAD059 /* p_fab.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF260B67CE5F00BAD059 /* p_fab.c */; }; + 1E44AF3F0B67CE5F00BAD059 /* p_lights.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF270B67CE5F00BAD059 /* p_lights.c */; }; + 1E44AF400B67CE5F00BAD059 /* p_map.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF280B67CE5F00BAD059 /* p_map.c */; }; + 1E44AF410B67CE5F00BAD059 /* p_maputl.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF290B67CE5F00BAD059 /* p_maputl.c */; }; + 1E44AF430B67CE5F00BAD059 /* p_mobj.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF2B0B67CE5F00BAD059 /* p_mobj.c */; }; + 1E44AF450B67CE5F00BAD059 /* p_floor.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF2D0B67CE5F00BAD059 /* p_floor.c */; }; + 1E44AF480B67CE5F00BAD059 /* p_saveg.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF300B67CE5F00BAD059 /* p_saveg.c */; }; + 1E44AF4A0B67CE5F00BAD059 /* p_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF320B67CE5F00BAD059 /* p_setup.c */; }; + 1E44AF4C0B67CE5F00BAD059 /* p_sight.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF340B67CE5F00BAD059 /* p_sight.c */; }; + 1E44AF4D0B67CE5F00BAD059 /* p_spec.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF350B67CE5F00BAD059 /* p_spec.c */; }; + 1E44AF4F0B67CE5F00BAD059 /* p_telept.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF370B67CE5F00BAD059 /* p_telept.c */; }; + 1E44AF500B67CE5F00BAD059 /* p_tick.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF380B67CE5F00BAD059 /* p_tick.c */; }; + 1E44AF520B67CE5F00BAD059 /* p_user.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF3A0B67CE5F00BAD059 /* p_user.c */; }; + 1E44AF530B67CE5F00BAD059 /* p_ceilng.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF3B0B67CE5F00BAD059 /* p_ceilng.c */; }; + 1E44AF6C0B67CEC200BAD059 /* r_bsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF550B67CEC100BAD059 /* r_bsp.c */; }; + 1E44AF6F0B67CEC200BAD059 /* r_data.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF580B67CEC100BAD059 /* r_data.c */; }; + 1E44AF700B67CEC200BAD059 /* r_draw.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF590B67CEC100BAD059 /* r_draw.c */; }; + 1E44AF730B67CEC200BAD059 /* r_main.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF5C0B67CEC100BAD059 /* r_main.c */; }; + 1E44AF780B67CEC200BAD059 /* r_plane.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF610B67CEC100BAD059 /* r_plane.c */; }; + 1E44AF7A0B67CEC200BAD059 /* r_segs.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF630B67CEC100BAD059 /* r_segs.c */; }; + 1E44AF7C0B67CEC200BAD059 /* r_sky.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF650B67CEC200BAD059 /* r_sky.c */; }; + 1E44AF7E0B67CEC200BAD059 /* r_splats.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF670B67CEC200BAD059 /* r_splats.c */; }; + 1E44AF810B67CEC200BAD059 /* r_things.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF6A0B67CEC200BAD059 /* r_things.c */; }; + 1E44AF870B67CEE000BAD059 /* s_sound.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF850B67CEE000BAD059 /* s_sound.c */; }; + 1E44AF8B0B67CEE900BAD059 /* screen.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF890B67CEE900BAD059 /* screen.c */; }; + 1E44AF8F0B67CEF000BAD059 /* sounds.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF8D0B67CEF000BAD059 /* sounds.c */; }; + 1E44AF930B67CEFF00BAD059 /* st_stuff.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF910B67CEFF00BAD059 /* st_stuff.c */; }; + 1E44AF9B0B67CF2E00BAD059 /* tables.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF990B67CF2E00BAD059 /* tables.c */; }; + 1E44AFA50B67CF5D00BAD059 /* v_video.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFA30B67CF5D00BAD059 /* v_video.c */; }; + 1E44AFA90B67CF6400BAD059 /* w_wad.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFA70B67CF6400BAD059 /* w_wad.c */; }; + 1E44AFAD0B67CF6F00BAD059 /* y_inter.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFAB0B67CF6F00BAD059 /* y_inter.c */; }; + 1E44AFB10B67CF7A00BAD059 /* z_zone.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFAF0B67CF7A00BAD059 /* z_zone.c */; }; + 1E44AFC40B67CFDC00BAD059 /* dosstr.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFB40B67CFDC00BAD059 /* dosstr.c */; }; + 1E44AFC50B67CFDC00BAD059 /* endtxt.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFB50B67CFDC00BAD059 /* endtxt.c */; }; + 1E44AFC70B67CFDC00BAD059 /* hwsym_sdl.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFB70B67CFDC00BAD059 /* hwsym_sdl.c */; }; + 1E44AFC90B67CFDC00BAD059 /* i_cdmus.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFB90B67CFDC00BAD059 /* i_cdmus.c */; }; + 1E44AFCA0B67CFDC00BAD059 /* i_main.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFBA0B67CFDC00BAD059 /* i_main.c */; }; + 1E44AFCB0B67CFDC00BAD059 /* i_net.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFBB0B67CFDC00BAD059 /* i_net.c */; }; + 1E44AFCD0B67CFDC00BAD059 /* i_system.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFBD0B67CFDC00BAD059 /* i_system.c */; }; + 1E44AFCE0B67CFDC00BAD059 /* i_video.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFBE0B67CFDC00BAD059 /* i_video.c */; }; + 1E44AFD00B67CFDC00BAD059 /* ogl_sdl.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFC00B67CFDC00BAD059 /* ogl_sdl.c */; }; + 1E44AFEA0B67D06200BAD059 /* Srb2mac.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1E44AFE70B67D06200BAD059 /* Srb2mac.icns */; }; + 1E44AFEB0B67D06200BAD059 /* mac_alert.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFE80B67D06200BAD059 /* mac_alert.c */; }; + 1E44AFED0B67D0AB00BAD059 /* r_opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AFEC0B67D0AB00BAD059 /* r_opengl.c */; }; + 1E44B0590B67D81E00BAD059 /* SDL_macosx_main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E44B0570B67D81E00BAD059 /* SDL_macosx_main.m */; }; + 1E66921C0B690C5B00B7313A /* SDL_mixer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E66921B0B690C5B00B7313A /* SDL_mixer.framework */; }; + 1E66921D0B690C6B00B7313A /* SDL_mixer.framework in Copy Frameworks into .app bundle */ = {isa = PBXBuildFile; fileRef = 1E66921B0B690C5B00B7313A /* SDL_mixer.framework */; }; + 67259DFD18D2687D00F02971 /* lua_hudlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67259DFB18D2687D00F02971 /* lua_hudlib.c */; }; + 67259DFE18D2687D00F02971 /* lua_skinlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67259DFC18D2687D00F02971 /* lua_skinlib.c */; }; + 67259E0118D268AE00F02971 /* m_anigif.c in Sources */ = {isa = PBXBuildFile; fileRef = 67259DFF18D268AE00F02971 /* m_anigif.c */; }; + 67259E0618D268F700F02971 /* i_ttf.c in Sources */ = {isa = PBXBuildFile; fileRef = 67259E0218D268F600F02971 /* i_ttf.c */; }; + 67259E0718D268F700F02971 /* mixer_sound.c in Sources */ = {isa = PBXBuildFile; fileRef = 67259E0418D268F600F02971 /* mixer_sound.c */; }; + 67259E0818D268F700F02971 /* sdl_sound.c in Sources */ = {isa = PBXBuildFile; fileRef = 67259E0518D268F600F02971 /* sdl_sound.c */; }; + 67259E2E18D26D5700F02971 /* patch.dta in Resources */ = {isa = PBXBuildFile; fileRef = 67259E2B18D26D5700F02971 /* patch.dta */; }; + 67259E2F18D26D5700F02971 /* rings.dta in Resources */ = {isa = PBXBuildFile; fileRef = 67259E2C18D26D5700F02971 /* rings.dta */; }; + 67259E3018D26D5700F02971 /* srb2.srb in Resources */ = {isa = PBXBuildFile; fileRef = 67259E2D18D26D5700F02971 /* srb2.srb */; }; + 67259E3218D26DD200F02971 /* music.dta in Resources */ = {isa = PBXBuildFile; fileRef = 1E44AE440B67CBE800BAD059 /* music.dta */; }; + 67259E3318D26DD300F02971 /* player.dta in Resources */ = {isa = PBXBuildFile; fileRef = 67A1F91813FAD026009FA3E5 /* player.dta */; }; + 67259E3518D26DD500F02971 /* zones.dta in Resources */ = {isa = PBXBuildFile; fileRef = 6766C0AE11B057E50065F389 /* zones.dta */; }; + 676BB5200E0DE06100C95963 /* m_queue.c in Sources */ = {isa = PBXBuildFile; fileRef = 676BB51C0E0DE06100C95963 /* m_queue.c */; }; + 676BB5220E0DE06100C95963 /* p_polyobj.c in Sources */ = {isa = PBXBuildFile; fileRef = 676BB51E0E0DE06100C95963 /* p_polyobj.c */; }; + 67B83BFA14F57EAB00AAAE4E /* lapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BCB14F57EAB00AAAE4E /* lapi.c */; }; + 67B83BFB14F57EAB00AAAE4E /* lauxlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BCD14F57EAB00AAAE4E /* lauxlib.c */; }; + 67B83BFC14F57EAB00AAAE4E /* lbaselib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BCF14F57EAB00AAAE4E /* lbaselib.c */; }; + 67B83BFD14F57EAB00AAAE4E /* lcode.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BD014F57EAB00AAAE4E /* lcode.c */; }; + 67B83BFE14F57EAB00AAAE4E /* ldebug.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BD214F57EAB00AAAE4E /* ldebug.c */; }; + 67B83BFF14F57EAB00AAAE4E /* ldo.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BD414F57EAB00AAAE4E /* ldo.c */; }; + 67B83C0014F57EAB00AAAE4E /* ldump.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BD614F57EAB00AAAE4E /* ldump.c */; }; + 67B83C0114F57EAB00AAAE4E /* lfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BD714F57EAB00AAAE4E /* lfunc.c */; }; + 67B83C0214F57EAB00AAAE4E /* lgc.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BD914F57EAB00AAAE4E /* lgc.c */; }; + 67B83C0314F57EAB00AAAE4E /* linit.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BDB14F57EAB00AAAE4E /* linit.c */; }; + 67B83C0414F57EAB00AAAE4E /* llex.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BDC14F57EAB00AAAE4E /* llex.c */; }; + 67B83C0514F57EAB00AAAE4E /* lmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BDF14F57EAB00AAAE4E /* lmem.c */; }; + 67B83C0614F57EAB00AAAE4E /* lobject.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BE114F57EAB00AAAE4E /* lobject.c */; }; + 67B83C0714F57EAB00AAAE4E /* lopcodes.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BE314F57EAB00AAAE4E /* lopcodes.c */; }; + 67B83C0814F57EAB00AAAE4E /* lparser.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BE514F57EAB00AAAE4E /* lparser.c */; }; + 67B83C0914F57EAB00AAAE4E /* lstate.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BE714F57EAB00AAAE4E /* lstate.c */; }; + 67B83C0A14F57EAB00AAAE4E /* lstring.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BE914F57EAB00AAAE4E /* lstring.c */; }; + 67B83C0B14F57EAB00AAAE4E /* lstrlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BEB14F57EAB00AAAE4E /* lstrlib.c */; }; + 67B83C0C14F57EAB00AAAE4E /* ltable.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BEC14F57EAB00AAAE4E /* ltable.c */; }; + 67B83C0D14F57EAB00AAAE4E /* ltablib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BEE14F57EAB00AAAE4E /* ltablib.c */; }; + 67B83C0E14F57EAB00AAAE4E /* ltm.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BEF14F57EAB00AAAE4E /* ltm.c */; }; + 67B83C0F14F57EAB00AAAE4E /* lundump.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BF414F57EAB00AAAE4E /* lundump.c */; }; + 67B83C1014F57EAB00AAAE4E /* lvm.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BF614F57EAB00AAAE4E /* lvm.c */; }; + 67B83C1114F57EAB00AAAE4E /* lzio.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83BF814F57EAB00AAAE4E /* lzio.c */; }; + 67B83C1414F57ECA00AAAE4E /* b_bot.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1214F57ECA00AAAE4E /* b_bot.c */; }; + 67B83C2214F57EE600AAAE4E /* lua_baselib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1514F57EE600AAAE4E /* lua_baselib.c */; }; + 67B83C2314F57EE600AAAE4E /* lua_consolelib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1614F57EE600AAAE4E /* lua_consolelib.c */; }; + 67B83C2414F57EE600AAAE4E /* lua_hooklib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1814F57EE600AAAE4E /* lua_hooklib.c */; }; + 67B83C2514F57EE600AAAE4E /* lua_infolib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1914F57EE600AAAE4E /* lua_infolib.c */; }; + 67B83C2614F57EE600AAAE4E /* lua_maplib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1B14F57EE600AAAE4E /* lua_maplib.c */; }; + 67B83C2714F57EE600AAAE4E /* lua_mathlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1C14F57EE600AAAE4E /* lua_mathlib.c */; }; + 67B83C2814F57EE600AAAE4E /* lua_mobjlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1D14F57EE600AAAE4E /* lua_mobjlib.c */; }; + 67B83C2914F57EE600AAAE4E /* lua_playerlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1E14F57EE600AAAE4E /* lua_playerlib.c */; }; + 67B83C2A14F57EE600AAAE4E /* lua_script.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C1F14F57EE600AAAE4E /* lua_script.c */; }; + 67B83C2B14F57EE600AAAE4E /* lua_thinkerlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C2114F57EE600AAAE4E /* lua_thinkerlib.c */; }; + 67B83C3314F57F1500AAAE4E /* m_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = 67B83C2F14F57F1500AAAE4E /* m_cond.c */; }; + 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; + 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 002F39FD09D0883400EBEB88 /* Copy Frameworks into .app bundle */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 12; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 1E32C42B0B6E6D6E0029E058 /* libpng.framework in Copy Frameworks into .app bundle */, + 1E66921D0B690C6B00B7313A /* SDL_mixer.framework in Copy Frameworks into .app bundle */, + 002F3A0009D0884600EBEB88 /* SDL.framework in Copy Frameworks into .app bundle */, + ); + name = "Copy Frameworks into .app bundle"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 002F39F909D0881F00EBEB88 /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = ""; }; + 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 1E32C4140B6E6D5D0029E058 /* libpng.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libpng.framework; path = /Library/Frameworks/libpng.framework; sourceTree = ""; }; + 1E44AE440B67CBE800BAD059 /* music.dta */ = {isa = PBXFileReference; lastKnownFileType = text; name = music.dta; path = ../../../bin/Resources/music.dta; sourceTree = SOURCE_ROOT; }; + 1E44AE4B0B67CBE800BAD059 /* srb2.wad */ = {isa = PBXFileReference; lastKnownFileType = text; name = srb2.wad; path = ../../../bin/Resources/srb2.wad; sourceTree = SOURCE_ROOT; }; + 1E44AE600B67CC2B00BAD059 /* hw3dsdrv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw3dsdrv.h; path = ../../hardware/hw3dsdrv.h; sourceTree = SOURCE_ROOT; }; + 1E44AE610B67CC2B00BAD059 /* hw_bsp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_bsp.c; path = ../../hardware/hw_bsp.c; sourceTree = SOURCE_ROOT; }; + 1E44AE620B67CC2B00BAD059 /* hw_defs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_defs.h; path = ../../hardware/hw_defs.h; sourceTree = SOURCE_ROOT; }; + 1E44AE630B67CC2B00BAD059 /* hw3sound.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw3sound.c; path = ../../hardware/hw3sound.c; sourceTree = SOURCE_ROOT; }; + 1E44AE640B67CC2B00BAD059 /* hw_cache.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_cache.c; path = ../../hardware/hw_cache.c; sourceTree = SOURCE_ROOT; }; + 1E44AE650B67CC2B00BAD059 /* hw_dll.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_dll.h; path = ../../hardware/hw_dll.h; sourceTree = SOURCE_ROOT; }; + 1E44AE660B67CC2B00BAD059 /* hw_drv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_drv.h; path = ../../hardware/hw_drv.h; sourceTree = SOURCE_ROOT; }; + 1E44AE670B67CC2B00BAD059 /* hw_glide.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_glide.h; path = ../../hardware/hw_glide.h; sourceTree = SOURCE_ROOT; }; + 1E44AE680B67CC2B00BAD059 /* hw_light.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_light.c; path = ../../hardware/hw_light.c; sourceTree = SOURCE_ROOT; }; + 1E44AE690B67CC2B00BAD059 /* hw_light.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_light.h; path = ../../hardware/hw_light.h; sourceTree = SOURCE_ROOT; }; + 1E44AE6A0B67CC2B00BAD059 /* hw3sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw3sound.h; path = ../../hardware/hw3sound.h; sourceTree = SOURCE_ROOT; }; + 1E44AE6B0B67CC2B00BAD059 /* hw_data.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_data.h; path = ../../hardware/hw_data.h; sourceTree = SOURCE_ROOT; }; + 1E44AE6C0B67CC2B00BAD059 /* hw_draw.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_draw.c; path = ../../hardware/hw_draw.c; sourceTree = SOURCE_ROOT; }; + 1E44AE6D0B67CC2B00BAD059 /* hw_glob.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_glob.h; path = ../../hardware/hw_glob.h; sourceTree = SOURCE_ROOT; }; + 1E44AE6E0B67CC2B00BAD059 /* hw_main.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_main.c; path = ../../hardware/hw_main.c; sourceTree = SOURCE_ROOT; }; + 1E44AE6F0B67CC2B00BAD059 /* hw_main.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_main.h; path = ../../hardware/hw_main.h; sourceTree = SOURCE_ROOT; }; + 1E44AE700B67CC2B00BAD059 /* hw_md2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_md2.c; path = ../../hardware/hw_md2.c; sourceTree = SOURCE_ROOT; }; + 1E44AE710B67CC2B00BAD059 /* hw_md2.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_md2.h; path = ../../hardware/hw_md2.h; sourceTree = SOURCE_ROOT; }; + 1E44AE720B67CC2B00BAD059 /* hw_trick.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_trick.c; path = ../../hardware/hw_trick.c; sourceTree = SOURCE_ROOT; }; + 1E44AE730B67CC2B00BAD059 /* hws_data.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hws_data.h; path = ../../hardware/hws_data.h; sourceTree = SOURCE_ROOT; }; + 1E44AE8A0B67CC6000BAD059 /* asm_defs.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; name = asm_defs.inc; path = ../../asm_defs.inc; sourceTree = SOURCE_ROOT; }; + 1E44AE8D0B67CC8400BAD059 /* d_clisrv.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = d_clisrv.c; path = ../../d_clisrv.c; sourceTree = SOURCE_ROOT; }; + 1E44AE8E0B67CC8400BAD059 /* d_clisrv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_clisrv.h; path = ../../d_clisrv.h; sourceTree = SOURCE_ROOT; }; + 1E44AE8F0B67CC8400BAD059 /* d_event.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_event.h; path = ../../d_event.h; sourceTree = SOURCE_ROOT; }; + 1E44AE900B67CC8400BAD059 /* d_main.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = d_main.c; path = ../../d_main.c; sourceTree = SOURCE_ROOT; }; + 1E44AE910B67CC8500BAD059 /* d_net.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = d_net.c; path = ../../d_net.c; sourceTree = SOURCE_ROOT; }; + 1E44AE920B67CC8500BAD059 /* d_net.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_net.h; path = ../../d_net.h; sourceTree = SOURCE_ROOT; }; + 1E44AE930B67CC8500BAD059 /* d_netcmd.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_netcmd.h; path = ../../d_netcmd.h; sourceTree = SOURCE_ROOT; }; + 1E44AE940B67CC8500BAD059 /* d_netfil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = d_netfil.c; path = ../../d_netfil.c; sourceTree = SOURCE_ROOT; }; + 1E44AE950B67CC8500BAD059 /* d_player.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_player.h; path = ../../d_player.h; sourceTree = SOURCE_ROOT; }; + 1E44AE960B67CC8500BAD059 /* d_think.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_think.h; path = ../../d_think.h; sourceTree = SOURCE_ROOT; }; + 1E44AE980B67CC8500BAD059 /* d_netcmd.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = d_netcmd.c; path = ../../d_netcmd.c; sourceTree = SOURCE_ROOT; }; + 1E44AE990B67CC8500BAD059 /* d_ticcmd.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_ticcmd.h; path = ../../d_ticcmd.h; sourceTree = SOURCE_ROOT; }; + 1E44AE9A0B67CC8500BAD059 /* d_main.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_main.h; path = ../../d_main.h; sourceTree = SOURCE_ROOT; }; + 1E44AE9B0B67CC8500BAD059 /* d_netfil.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = d_netfil.h; path = ../../d_netfil.h; sourceTree = SOURCE_ROOT; }; + 1E44AE9C0B67CC8500BAD059 /* dehacked.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dehacked.c; path = ../../dehacked.c; sourceTree = SOURCE_ROOT; }; + 1E44AE9D0B67CC8500BAD059 /* dehacked.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dehacked.h; path = ../../dehacked.h; sourceTree = SOURCE_ROOT; }; + 1E44AE9E0B67CC8500BAD059 /* doomdata.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = doomdata.h; path = ../../doomdata.h; sourceTree = SOURCE_ROOT; }; + 1E44AE9F0B67CC8500BAD059 /* doomdef.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = doomdef.h; path = ../../doomdef.h; sourceTree = SOURCE_ROOT; }; + 1E44AEA00B67CC8500BAD059 /* doomstat.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = doomstat.h; path = ../../doomstat.h; sourceTree = SOURCE_ROOT; }; + 1E44AEA10B67CC8500BAD059 /* doomtype.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = doomtype.h; path = ../../doomtype.h; sourceTree = SOURCE_ROOT; }; + 1E44AEBC0B67CCA900BAD059 /* f_wipe.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = f_wipe.c; path = ../../f_wipe.c; sourceTree = SOURCE_ROOT; }; + 1E44AEBD0B67CCA900BAD059 /* f_finale.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = f_finale.c; path = ../../f_finale.c; sourceTree = SOURCE_ROOT; }; + 1E44AEBE0B67CCA900BAD059 /* f_finale.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = f_finale.h; path = ../../f_finale.h; sourceTree = SOURCE_ROOT; }; + 1E44AEC30B67CCC600BAD059 /* g_game.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = g_game.c; path = ../../g_game.c; sourceTree = SOURCE_ROOT; }; + 1E44AEC40B67CCC600BAD059 /* g_game.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = g_game.h; path = ../../g_game.h; sourceTree = SOURCE_ROOT; }; + 1E44AEC50B67CCC600BAD059 /* g_input.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = g_input.h; path = ../../g_input.h; sourceTree = SOURCE_ROOT; }; + 1E44AEC60B67CCC600BAD059 /* g_state.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = g_state.h; path = ../../g_state.h; sourceTree = SOURCE_ROOT; }; + 1E44AEC70B67CCC600BAD059 /* g_input.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = g_input.c; path = ../../g_input.c; sourceTree = SOURCE_ROOT; }; + 1E44AECE0B67CCEE00BAD059 /* hu_stuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hu_stuff.c; path = ../../hu_stuff.c; sourceTree = SOURCE_ROOT; }; + 1E44AECF0B67CCEE00BAD059 /* hu_stuff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hu_stuff.h; path = ../../hu_stuff.h; sourceTree = SOURCE_ROOT; }; + 1E44AED30B67CD1200BAD059 /* i_net.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_net.h; path = ../../i_net.h; sourceTree = SOURCE_ROOT; }; + 1E44AED40B67CD1200BAD059 /* i_sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_sound.h; path = ../../i_sound.h; sourceTree = SOURCE_ROOT; }; + 1E44AED50B67CD1200BAD059 /* i_tcp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = i_tcp.c; path = ../../i_tcp.c; sourceTree = SOURCE_ROOT; }; + 1E44AED60B67CD1200BAD059 /* i_tcp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_tcp.h; path = ../../i_tcp.h; sourceTree = SOURCE_ROOT; }; + 1E44AED70B67CD1200BAD059 /* i_system.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_system.h; path = ../../i_system.h; sourceTree = SOURCE_ROOT; }; + 1E44AED80B67CD1200BAD059 /* i_video.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_video.h; path = ../../i_video.h; sourceTree = SOURCE_ROOT; }; + 1E44AED90B67CD1300BAD059 /* i_joy.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i_joy.h; path = ../../i_joy.h; sourceTree = SOURCE_ROOT; }; + 1E44AEE10B67CD2B00BAD059 /* am_map.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = am_map.c; path = ../../am_map.c; sourceTree = SOURCE_ROOT; }; + 1E44AEE20B67CD2B00BAD059 /* am_map.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = am_map.h; path = ../../am_map.h; sourceTree = SOURCE_ROOT; }; + 1E44AEE50B67CD3200BAD059 /* byteptr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = byteptr.h; path = ../../byteptr.h; sourceTree = SOURCE_ROOT; }; + 1E44AEE70B67CD3F00BAD059 /* command.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = command.c; path = ../../command.c; sourceTree = SOURCE_ROOT; }; + 1E44AEE80B67CD3F00BAD059 /* command.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = command.h; path = ../../command.h; sourceTree = SOURCE_ROOT; }; + 1E44AEEB0B67CD4400BAD059 /* comptime.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = comptime.c; path = ../../comptime.c; sourceTree = SOURCE_ROOT; }; + 1E44AEED0B67CD5400BAD059 /* console.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = console.c; path = ../../console.c; sourceTree = SOURCE_ROOT; }; + 1E44AEEE0B67CD5400BAD059 /* console.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = console.h; path = ../../console.h; sourceTree = SOURCE_ROOT; }; + 1E44AEF10B67CD7F00BAD059 /* filesrch.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = filesrch.c; path = ../../filesrch.c; sourceTree = SOURCE_ROOT; }; + 1E44AEF20B67CD7F00BAD059 /* filesrch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = filesrch.h; path = ../../filesrch.h; sourceTree = SOURCE_ROOT; }; + 1E44AEF50B67CD9F00BAD059 /* keys.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = keys.h; path = ../../keys.h; sourceTree = SOURCE_ROOT; }; + 1E44AEF80B67CDE900BAD059 /* m_argv.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_argv.c; path = ../../m_argv.c; sourceTree = SOURCE_ROOT; }; + 1E44AEF90B67CDE900BAD059 /* m_bbox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_bbox.h; path = ../../m_bbox.h; sourceTree = SOURCE_ROOT; }; + 1E44AEFA0B67CDE900BAD059 /* m_argv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_argv.h; path = ../../m_argv.h; sourceTree = SOURCE_ROOT; }; + 1E44AEFB0B67CDE900BAD059 /* m_cheat.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_cheat.c; path = ../../m_cheat.c; sourceTree = SOURCE_ROOT; }; + 1E44AEFC0B67CDE900BAD059 /* m_bbox.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_bbox.c; path = ../../m_bbox.c; sourceTree = SOURCE_ROOT; }; + 1E44AEFD0B67CDE900BAD059 /* m_cheat.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_cheat.h; path = ../../m_cheat.h; sourceTree = SOURCE_ROOT; }; + 1E44AEFE0B67CDE900BAD059 /* m_fixed.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_fixed.c; path = ../../m_fixed.c; sourceTree = SOURCE_ROOT; }; + 1E44AEFF0B67CDE900BAD059 /* m_fixed.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_fixed.h; path = ../../m_fixed.h; sourceTree = SOURCE_ROOT; }; + 1E44AF000B67CDE900BAD059 /* m_menu.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_menu.c; path = ../../m_menu.c; sourceTree = SOURCE_ROOT; }; + 1E44AF010B67CDE900BAD059 /* m_menu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_menu.h; path = ../../m_menu.h; sourceTree = SOURCE_ROOT; }; + 1E44AF020B67CDE900BAD059 /* m_misc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_misc.c; path = ../../m_misc.c; sourceTree = SOURCE_ROOT; }; + 1E44AF030B67CDE900BAD059 /* m_misc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_misc.h; path = ../../m_misc.h; sourceTree = SOURCE_ROOT; }; + 1E44AF040B67CDE900BAD059 /* m_random.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_random.c; path = ../../m_random.c; sourceTree = SOURCE_ROOT; }; + 1E44AF050B67CDE900BAD059 /* m_random.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_random.h; path = ../../m_random.h; sourceTree = SOURCE_ROOT; }; + 1E44AF060B67CDE900BAD059 /* m_swap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_swap.h; path = ../../m_swap.h; sourceTree = SOURCE_ROOT; }; + 1E44AF180B67CE2A00BAD059 /* info.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = info.c; path = ../../info.c; sourceTree = SOURCE_ROOT; }; + 1E44AF190B67CE2A00BAD059 /* info.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = info.h; path = ../../info.h; sourceTree = SOURCE_ROOT; }; + 1E44AF1C0B67CE3600BAD059 /* md5.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = md5.c; path = ../../md5.c; sourceTree = SOURCE_ROOT; }; + 1E44AF1D0B67CE3600BAD059 /* md5.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = md5.h; path = ../../md5.h; sourceTree = SOURCE_ROOT; }; + 1E44AF200B67CE4100BAD059 /* mserv.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = mserv.c; path = ../../mserv.c; sourceTree = SOURCE_ROOT; }; + 1E44AF210B67CE4100BAD059 /* mserv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mserv.h; path = ../../mserv.h; sourceTree = SOURCE_ROOT; }; + 1E44AF240B67CE5F00BAD059 /* p_enemy.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_enemy.c; path = ../../p_enemy.c; sourceTree = SOURCE_ROOT; }; + 1E44AF250B67CE5F00BAD059 /* p_inter.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_inter.c; path = ../../p_inter.c; sourceTree = SOURCE_ROOT; }; + 1E44AF260B67CE5F00BAD059 /* p_fab.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_fab.c; path = ../../p_fab.c; sourceTree = SOURCE_ROOT; }; + 1E44AF270B67CE5F00BAD059 /* p_lights.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_lights.c; path = ../../p_lights.c; sourceTree = SOURCE_ROOT; }; + 1E44AF280B67CE5F00BAD059 /* p_map.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_map.c; path = ../../p_map.c; sourceTree = SOURCE_ROOT; }; + 1E44AF290B67CE5F00BAD059 /* p_maputl.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_maputl.c; path = ../../p_maputl.c; sourceTree = SOURCE_ROOT; }; + 1E44AF2A0B67CE5F00BAD059 /* p_maputl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_maputl.h; path = ../../p_maputl.h; sourceTree = SOURCE_ROOT; }; + 1E44AF2B0B67CE5F00BAD059 /* p_mobj.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_mobj.c; path = ../../p_mobj.c; sourceTree = SOURCE_ROOT; }; + 1E44AF2C0B67CE5F00BAD059 /* p_mobj.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_mobj.h; path = ../../p_mobj.h; sourceTree = SOURCE_ROOT; }; + 1E44AF2D0B67CE5F00BAD059 /* p_floor.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_floor.c; path = ../../p_floor.c; sourceTree = SOURCE_ROOT; }; + 1E44AF2E0B67CE5F00BAD059 /* p_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_local.h; path = ../../p_local.h; sourceTree = SOURCE_ROOT; }; + 1E44AF2F0B67CE5F00BAD059 /* p_pspr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_pspr.h; path = ../../p_pspr.h; sourceTree = SOURCE_ROOT; }; + 1E44AF300B67CE5F00BAD059 /* p_saveg.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_saveg.c; path = ../../p_saveg.c; sourceTree = SOURCE_ROOT; }; + 1E44AF310B67CE5F00BAD059 /* p_saveg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_saveg.h; path = ../../p_saveg.h; sourceTree = SOURCE_ROOT; }; + 1E44AF320B67CE5F00BAD059 /* p_setup.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_setup.c; path = ../../p_setup.c; sourceTree = SOURCE_ROOT; }; + 1E44AF330B67CE5F00BAD059 /* p_setup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_setup.h; path = ../../p_setup.h; sourceTree = SOURCE_ROOT; }; + 1E44AF340B67CE5F00BAD059 /* p_sight.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_sight.c; path = ../../p_sight.c; sourceTree = SOURCE_ROOT; }; + 1E44AF350B67CE5F00BAD059 /* p_spec.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_spec.c; path = ../../p_spec.c; sourceTree = SOURCE_ROOT; }; + 1E44AF360B67CE5F00BAD059 /* p_spec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_spec.h; path = ../../p_spec.h; sourceTree = SOURCE_ROOT; }; + 1E44AF370B67CE5F00BAD059 /* p_telept.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_telept.c; path = ../../p_telept.c; sourceTree = SOURCE_ROOT; }; + 1E44AF380B67CE5F00BAD059 /* p_tick.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_tick.c; path = ../../p_tick.c; sourceTree = SOURCE_ROOT; }; + 1E44AF390B67CE5F00BAD059 /* p_tick.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p_tick.h; path = ../../p_tick.h; sourceTree = SOURCE_ROOT; }; + 1E44AF3A0B67CE5F00BAD059 /* p_user.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_user.c; path = ../../p_user.c; sourceTree = SOURCE_ROOT; }; + 1E44AF3B0B67CE5F00BAD059 /* p_ceilng.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p_ceilng.c; path = ../../p_ceilng.c; sourceTree = SOURCE_ROOT; }; + 1E44AF550B67CEC100BAD059 /* r_bsp.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_bsp.c; path = ../../r_bsp.c; sourceTree = SOURCE_ROOT; }; + 1E44AF560B67CEC100BAD059 /* r_bsp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_bsp.h; path = ../../r_bsp.h; sourceTree = SOURCE_ROOT; }; + 1E44AF570B67CEC100BAD059 /* r_defs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_defs.h; path = ../../r_defs.h; sourceTree = SOURCE_ROOT; }; + 1E44AF580B67CEC100BAD059 /* r_data.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_data.c; path = ../../r_data.c; sourceTree = SOURCE_ROOT; }; + 1E44AF590B67CEC100BAD059 /* r_draw.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_draw.c; path = ../../r_draw.c; sourceTree = SOURCE_ROOT; }; + 1E44AF5A0B67CEC100BAD059 /* r_draw16.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_draw16.c; path = ../../r_draw16.c; sourceTree = SOURCE_ROOT; }; + 1E44AF5B0B67CEC100BAD059 /* r_draw8.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_draw8.c; path = ../../r_draw8.c; sourceTree = SOURCE_ROOT; }; + 1E44AF5C0B67CEC100BAD059 /* r_main.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_main.c; path = ../../r_main.c; sourceTree = SOURCE_ROOT; }; + 1E44AF5D0B67CEC100BAD059 /* r_main.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_main.h; path = ../../r_main.h; sourceTree = SOURCE_ROOT; }; + 1E44AF5E0B67CEC100BAD059 /* r_data.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_data.h; path = ../../r_data.h; sourceTree = SOURCE_ROOT; }; + 1E44AF5F0B67CEC100BAD059 /* r_draw.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_draw.h; path = ../../r_draw.h; sourceTree = SOURCE_ROOT; }; + 1E44AF600B67CEC100BAD059 /* r_local.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_local.h; path = ../../r_local.h; sourceTree = SOURCE_ROOT; }; + 1E44AF610B67CEC100BAD059 /* r_plane.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_plane.c; path = ../../r_plane.c; sourceTree = SOURCE_ROOT; }; + 1E44AF620B67CEC100BAD059 /* r_plane.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_plane.h; path = ../../r_plane.h; sourceTree = SOURCE_ROOT; }; + 1E44AF630B67CEC100BAD059 /* r_segs.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_segs.c; path = ../../r_segs.c; sourceTree = SOURCE_ROOT; }; + 1E44AF640B67CEC100BAD059 /* r_segs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_segs.h; path = ../../r_segs.h; sourceTree = SOURCE_ROOT; }; + 1E44AF650B67CEC200BAD059 /* r_sky.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_sky.c; path = ../../r_sky.c; sourceTree = SOURCE_ROOT; }; + 1E44AF660B67CEC200BAD059 /* r_sky.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_sky.h; path = ../../r_sky.h; sourceTree = SOURCE_ROOT; }; + 1E44AF670B67CEC200BAD059 /* r_splats.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_splats.c; path = ../../r_splats.c; sourceTree = SOURCE_ROOT; }; + 1E44AF680B67CEC200BAD059 /* r_splats.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_splats.h; path = ../../r_splats.h; sourceTree = SOURCE_ROOT; }; + 1E44AF690B67CEC200BAD059 /* r_state.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_state.h; path = ../../r_state.h; sourceTree = SOURCE_ROOT; }; + 1E44AF6A0B67CEC200BAD059 /* r_things.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_things.c; path = ../../r_things.c; sourceTree = SOURCE_ROOT; }; + 1E44AF6B0B67CEC200BAD059 /* r_things.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = r_things.h; path = ../../r_things.h; sourceTree = SOURCE_ROOT; }; + 1E44AF850B67CEE000BAD059 /* s_sound.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = s_sound.c; path = ../../s_sound.c; sourceTree = SOURCE_ROOT; }; + 1E44AF860B67CEE000BAD059 /* s_sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = s_sound.h; path = ../../s_sound.h; sourceTree = SOURCE_ROOT; }; + 1E44AF890B67CEE900BAD059 /* screen.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = screen.c; path = ../../screen.c; sourceTree = SOURCE_ROOT; }; + 1E44AF8A0B67CEE900BAD059 /* screen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = screen.h; path = ../../screen.h; sourceTree = SOURCE_ROOT; }; + 1E44AF8D0B67CEF000BAD059 /* sounds.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = sounds.c; path = ../../sounds.c; sourceTree = SOURCE_ROOT; }; + 1E44AF8E0B67CEF000BAD059 /* sounds.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sounds.h; path = ../../sounds.h; sourceTree = SOURCE_ROOT; }; + 1E44AF910B67CEFF00BAD059 /* st_stuff.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = st_stuff.c; path = ../../st_stuff.c; sourceTree = SOURCE_ROOT; }; + 1E44AF920B67CEFF00BAD059 /* st_stuff.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = st_stuff.h; path = ../../st_stuff.h; sourceTree = SOURCE_ROOT; }; + 1E44AF950B67CF1300BAD059 /* string.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = string.c; path = ../../string.c; sourceTree = SOURCE_ROOT; }; + 1E44AF990B67CF2E00BAD059 /* tables.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = tables.c; path = ../../tables.c; sourceTree = SOURCE_ROOT; }; + 1E44AF9A0B67CF2E00BAD059 /* tables.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tables.h; path = ../../tables.h; sourceTree = SOURCE_ROOT; }; + 1E44AF9D0B67CF3D00BAD059 /* tmap.nas */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = tmap.nas; path = ../../tmap.nas; sourceTree = SOURCE_ROOT; }; + 1E44AF9F0B67CF4900BAD059 /* tmap_mmx.nas */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = tmap_mmx.nas; path = ../../tmap_mmx.nas; sourceTree = SOURCE_ROOT; }; + 1E44AFA00B67CF4900BAD059 /* tmap_vc.nas */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = tmap_vc.nas; path = ../../tmap_vc.nas; sourceTree = SOURCE_ROOT; }; + 1E44AFA30B67CF5D00BAD059 /* v_video.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = v_video.c; path = ../../v_video.c; sourceTree = SOURCE_ROOT; }; + 1E44AFA40B67CF5D00BAD059 /* v_video.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = v_video.h; path = ../../v_video.h; sourceTree = SOURCE_ROOT; }; + 1E44AFA70B67CF6400BAD059 /* w_wad.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = w_wad.c; path = ../../w_wad.c; sourceTree = SOURCE_ROOT; }; + 1E44AFA80B67CF6400BAD059 /* w_wad.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = w_wad.h; path = ../../w_wad.h; sourceTree = SOURCE_ROOT; }; + 1E44AFAB0B67CF6F00BAD059 /* y_inter.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = y_inter.c; path = ../../y_inter.c; sourceTree = SOURCE_ROOT; }; + 1E44AFAC0B67CF6F00BAD059 /* y_inter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = y_inter.h; path = ../../y_inter.h; sourceTree = SOURCE_ROOT; }; + 1E44AFAF0B67CF7A00BAD059 /* z_zone.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = z_zone.c; path = ../../z_zone.c; sourceTree = SOURCE_ROOT; }; + 1E44AFB00B67CF7A00BAD059 /* z_zone.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = z_zone.h; path = ../../z_zone.h; sourceTree = SOURCE_ROOT; }; + 1E44AFB40B67CFDC00BAD059 /* dosstr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dosstr.c; path = ../dosstr.c; sourceTree = SOURCE_ROOT; }; + 1E44AFB50B67CFDC00BAD059 /* endtxt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = endtxt.c; path = ../endtxt.c; sourceTree = SOURCE_ROOT; }; + 1E44AFB60B67CFDC00BAD059 /* endtxt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = endtxt.h; path = ../endtxt.h; sourceTree = SOURCE_ROOT; }; + 1E44AFB70B67CFDC00BAD059 /* hwsym_sdl.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hwsym_sdl.c; path = ../hwsym_sdl.c; sourceTree = SOURCE_ROOT; }; + 1E44AFB80B67CFDC00BAD059 /* hwsym_sdl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hwsym_sdl.h; path = ../hwsym_sdl.h; sourceTree = SOURCE_ROOT; }; + 1E44AFB90B67CFDC00BAD059 /* i_cdmus.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = i_cdmus.c; path = ../i_cdmus.c; sourceTree = SOURCE_ROOT; }; + 1E44AFBA0B67CFDC00BAD059 /* i_main.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = i_main.c; path = ../i_main.c; sourceTree = SOURCE_ROOT; }; + 1E44AFBB0B67CFDC00BAD059 /* i_net.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = i_net.c; path = ../i_net.c; sourceTree = SOURCE_ROOT; }; + 1E44AFBD0B67CFDC00BAD059 /* i_system.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = i_system.c; path = ../i_system.c; sourceTree = SOURCE_ROOT; }; + 1E44AFBE0B67CFDC00BAD059 /* i_video.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = i_video.c; path = ../i_video.c; sourceTree = SOURCE_ROOT; }; + 1E44AFBF0B67CFDC00BAD059 /* IMG_xpm.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = IMG_xpm.c; path = ../IMG_xpm.c; sourceTree = SOURCE_ROOT; }; + 1E44AFC00B67CFDC00BAD059 /* ogl_sdl.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ogl_sdl.c; path = ../ogl_sdl.c; sourceTree = SOURCE_ROOT; }; + 1E44AFC10B67CFDC00BAD059 /* ogl_sdl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ogl_sdl.h; path = ../ogl_sdl.h; sourceTree = SOURCE_ROOT; }; + 1E44AFC20B67CFDC00BAD059 /* SDL_icon.xpm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = SDL_icon.xpm; path = ../SDL_icon.xpm; sourceTree = SOURCE_ROOT; }; + 1E44AFC30B67CFDC00BAD059 /* sdlmain.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sdlmain.h; path = ../sdlmain.h; sourceTree = SOURCE_ROOT; }; + 1E44AFD50B67D03100BAD059 /* filters.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = filters.c; path = ../filter/filters.c; sourceTree = SOURCE_ROOT; }; + 1E44AFD60B67D03100BAD059 /* filters.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = filters.h; path = ../filter/filters.h; sourceTree = SOURCE_ROOT; }; + 1E44AFD70B67D03100BAD059 /* hq2x.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hq2x.c; path = ../filter/hq2x.c; sourceTree = SOURCE_ROOT; }; + 1E44AFD80B67D03100BAD059 /* hq2x.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hq2x.h; path = ../filter/hq2x.h; sourceTree = SOURCE_ROOT; }; + 1E44AFD90B67D03100BAD059 /* interp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = interp.h; path = ../filter/interp.h; sourceTree = SOURCE_ROOT; }; + 1E44AFDA0B67D03100BAD059 /* lq2x.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lq2x.c; path = ../filter/lq2x.c; sourceTree = SOURCE_ROOT; }; + 1E44AFDB0B67D03100BAD059 /* lq2x.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lq2x.h; path = ../filter/lq2x.h; sourceTree = SOURCE_ROOT; }; + 1E44AFDC0B67D03100BAD059 /* main.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = main.c; path = ../filter/main.c; sourceTree = SOURCE_ROOT; }; + 1E44AFE60B67D06200BAD059 /* mac_alert.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mac_alert.h; sourceTree = SOURCE_ROOT; }; + 1E44AFE70B67D06200BAD059 /* Srb2mac.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Srb2mac.icns; sourceTree = SOURCE_ROOT; }; + 1E44AFE80B67D06200BAD059 /* mac_alert.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = mac_alert.c; sourceTree = SOURCE_ROOT; }; + 1E44AFEC0B67D0AB00BAD059 /* r_opengl.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = r_opengl.c; path = ../../hardware/r_opengl/r_opengl.c; sourceTree = SOURCE_ROOT; }; + 1E44B0560B67D81E00BAD059 /* SDL_macosx_main.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SDL_macosx_main.h; path = ../SDL_main/SDL_macosx_main.h; sourceTree = SOURCE_ROOT; }; + 1E44B0570B67D81E00BAD059 /* SDL_macosx_main.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = SDL_macosx_main.m; path = ../SDL_main/SDL_macosx_main.m; sourceTree = SOURCE_ROOT; }; + 1E44B2240B67EADE00BAD059 /* lzf.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lzf.c; path = ../../lzf.c; sourceTree = SOURCE_ROOT; }; + 1E44B2250B67EADE00BAD059 /* lzf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lzf.h; path = ../../lzf.h; sourceTree = SOURCE_ROOT; }; + 1E66921B0B690C5B00B7313A /* SDL_mixer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_mixer.framework; path = /Library/Frameworks/SDL_mixer.framework; sourceTree = ""; }; + 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 67259DFA18D2687D00F02971 /* lua_hud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_hud.h; path = ../../lua_hud.h; sourceTree = SOURCE_ROOT; }; + 67259DFB18D2687D00F02971 /* lua_hudlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_hudlib.c; path = ../../lua_hudlib.c; sourceTree = SOURCE_ROOT; }; + 67259DFC18D2687D00F02971 /* lua_skinlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_skinlib.c; path = ../../lua_skinlib.c; sourceTree = SOURCE_ROOT; }; + 67259DFF18D268AE00F02971 /* m_anigif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = m_anigif.c; path = ../../m_anigif.c; sourceTree = SOURCE_ROOT; }; + 67259E0018D268AE00F02971 /* m_anigif.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m_anigif.h; path = ../../m_anigif.h; sourceTree = SOURCE_ROOT; }; + 67259E0218D268F600F02971 /* i_ttf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = i_ttf.c; path = ../i_ttf.c; sourceTree = SOURCE_ROOT; }; + 67259E0318D268F600F02971 /* i_ttf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = i_ttf.h; path = ../i_ttf.h; sourceTree = SOURCE_ROOT; }; + 67259E0418D268F600F02971 /* mixer_sound.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mixer_sound.c; path = ../mixer_sound.c; sourceTree = SOURCE_ROOT; }; + 67259E0518D268F600F02971 /* sdl_sound.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sdl_sound.c; path = ../sdl_sound.c; sourceTree = SOURCE_ROOT; }; + 67259E2B18D26D5700F02971 /* patch.dta */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = patch.dta; path = ../../../bin/Resources/patch.dta; sourceTree = SOURCE_ROOT; }; + 67259E2C18D26D5700F02971 /* rings.dta */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = rings.dta; path = ../../../bin/Resources/rings.dta; sourceTree = SOURCE_ROOT; }; + 67259E2D18D26D5700F02971 /* srb2.srb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = srb2.srb; path = ../../../bin/Resources/srb2.srb; sourceTree = SOURCE_ROOT; }; + 6766C0AE11B057E50065F389 /* zones.dta */ = {isa = PBXFileReference; lastKnownFileType = text; name = zones.dta; path = ../../../bin/Resources/zones.dta; sourceTree = SOURCE_ROOT; }; + 676BB51C0E0DE06100C95963 /* m_queue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = m_queue.c; path = ../../m_queue.c; sourceTree = SOURCE_ROOT; }; + 676BB51D0E0DE06100C95963 /* m_queue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m_queue.h; path = ../../m_queue.h; sourceTree = SOURCE_ROOT; }; + 676BB51E0E0DE06100C95963 /* p_polyobj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = p_polyobj.c; path = ../../p_polyobj.c; sourceTree = SOURCE_ROOT; }; + 676BB51F0E0DE06100C95963 /* p_polyobj.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = p_polyobj.h; path = ../../p_polyobj.h; sourceTree = SOURCE_ROOT; }; + 67A1F91813FAD026009FA3E5 /* player.dta */ = {isa = PBXFileReference; lastKnownFileType = text; name = player.dta; path = ../../../bin/Resources/player.dta; sourceTree = SOURCE_ROOT; }; + 67B2071C1180FA8200E93654 /* vid_copy.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = vid_copy.s; path = ../../vid_copy.s; sourceTree = SOURCE_ROOT; }; + 67B83BCB14F57EAB00AAAE4E /* lapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lapi.c; path = ../../blua/lapi.c; sourceTree = SOURCE_ROOT; }; + 67B83BCC14F57EAB00AAAE4E /* lapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lapi.h; path = ../../blua/lapi.h; sourceTree = SOURCE_ROOT; }; + 67B83BCD14F57EAB00AAAE4E /* lauxlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lauxlib.c; path = ../../blua/lauxlib.c; sourceTree = SOURCE_ROOT; }; + 67B83BCE14F57EAB00AAAE4E /* lauxlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lauxlib.h; path = ../../blua/lauxlib.h; sourceTree = SOURCE_ROOT; }; + 67B83BCF14F57EAB00AAAE4E /* lbaselib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lbaselib.c; path = ../../blua/lbaselib.c; sourceTree = SOURCE_ROOT; }; + 67B83BD014F57EAB00AAAE4E /* lcode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lcode.c; path = ../../blua/lcode.c; sourceTree = SOURCE_ROOT; }; + 67B83BD114F57EAB00AAAE4E /* lcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lcode.h; path = ../../blua/lcode.h; sourceTree = SOURCE_ROOT; }; + 67B83BD214F57EAB00AAAE4E /* ldebug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ldebug.c; path = ../../blua/ldebug.c; sourceTree = SOURCE_ROOT; }; + 67B83BD314F57EAB00AAAE4E /* ldebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ldebug.h; path = ../../blua/ldebug.h; sourceTree = SOURCE_ROOT; }; + 67B83BD414F57EAB00AAAE4E /* ldo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ldo.c; path = ../../blua/ldo.c; sourceTree = SOURCE_ROOT; }; + 67B83BD514F57EAB00AAAE4E /* ldo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ldo.h; path = ../../blua/ldo.h; sourceTree = SOURCE_ROOT; }; + 67B83BD614F57EAB00AAAE4E /* ldump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ldump.c; path = ../../blua/ldump.c; sourceTree = SOURCE_ROOT; }; + 67B83BD714F57EAB00AAAE4E /* lfunc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lfunc.c; path = ../../blua/lfunc.c; sourceTree = SOURCE_ROOT; }; + 67B83BD814F57EAB00AAAE4E /* lfunc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lfunc.h; path = ../../blua/lfunc.h; sourceTree = SOURCE_ROOT; }; + 67B83BD914F57EAB00AAAE4E /* lgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lgc.c; path = ../../blua/lgc.c; sourceTree = SOURCE_ROOT; }; + 67B83BDA14F57EAB00AAAE4E /* lgc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lgc.h; path = ../../blua/lgc.h; sourceTree = SOURCE_ROOT; }; + 67B83BDB14F57EAB00AAAE4E /* linit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = linit.c; path = ../../blua/linit.c; sourceTree = SOURCE_ROOT; }; + 67B83BDC14F57EAB00AAAE4E /* llex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = llex.c; path = ../../blua/llex.c; sourceTree = SOURCE_ROOT; }; + 67B83BDD14F57EAB00AAAE4E /* llex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = llex.h; path = ../../blua/llex.h; sourceTree = SOURCE_ROOT; }; + 67B83BDE14F57EAB00AAAE4E /* llimits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = llimits.h; path = ../../blua/llimits.h; sourceTree = SOURCE_ROOT; }; + 67B83BDF14F57EAB00AAAE4E /* lmem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lmem.c; path = ../../blua/lmem.c; sourceTree = SOURCE_ROOT; }; + 67B83BE014F57EAB00AAAE4E /* lmem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lmem.h; path = ../../blua/lmem.h; sourceTree = SOURCE_ROOT; }; + 67B83BE114F57EAB00AAAE4E /* lobject.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lobject.c; path = ../../blua/lobject.c; sourceTree = SOURCE_ROOT; }; + 67B83BE214F57EAB00AAAE4E /* lobject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lobject.h; path = ../../blua/lobject.h; sourceTree = SOURCE_ROOT; }; + 67B83BE314F57EAB00AAAE4E /* lopcodes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lopcodes.c; path = ../../blua/lopcodes.c; sourceTree = SOURCE_ROOT; }; + 67B83BE414F57EAB00AAAE4E /* lopcodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lopcodes.h; path = ../../blua/lopcodes.h; sourceTree = SOURCE_ROOT; }; + 67B83BE514F57EAB00AAAE4E /* lparser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lparser.c; path = ../../blua/lparser.c; sourceTree = SOURCE_ROOT; }; + 67B83BE614F57EAB00AAAE4E /* lparser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lparser.h; path = ../../blua/lparser.h; sourceTree = SOURCE_ROOT; }; + 67B83BE714F57EAB00AAAE4E /* lstate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lstate.c; path = ../../blua/lstate.c; sourceTree = SOURCE_ROOT; }; + 67B83BE814F57EAB00AAAE4E /* lstate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lstate.h; path = ../../blua/lstate.h; sourceTree = SOURCE_ROOT; }; + 67B83BE914F57EAB00AAAE4E /* lstring.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lstring.c; path = ../../blua/lstring.c; sourceTree = SOURCE_ROOT; }; + 67B83BEA14F57EAB00AAAE4E /* lstring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lstring.h; path = ../../blua/lstring.h; sourceTree = SOURCE_ROOT; }; + 67B83BEB14F57EAB00AAAE4E /* lstrlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lstrlib.c; path = ../../blua/lstrlib.c; sourceTree = SOURCE_ROOT; }; + 67B83BEC14F57EAB00AAAE4E /* ltable.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ltable.c; path = ../../blua/ltable.c; sourceTree = SOURCE_ROOT; }; + 67B83BED14F57EAB00AAAE4E /* ltable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ltable.h; path = ../../blua/ltable.h; sourceTree = SOURCE_ROOT; }; + 67B83BEE14F57EAB00AAAE4E /* ltablib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ltablib.c; path = ../../blua/ltablib.c; sourceTree = SOURCE_ROOT; }; + 67B83BEF14F57EAB00AAAE4E /* ltm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ltm.c; path = ../../blua/ltm.c; sourceTree = SOURCE_ROOT; }; + 67B83BF014F57EAB00AAAE4E /* ltm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ltm.h; path = ../../blua/ltm.h; sourceTree = SOURCE_ROOT; }; + 67B83BF114F57EAB00AAAE4E /* lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua.h; path = ../../blua/lua.h; sourceTree = SOURCE_ROOT; }; + 67B83BF214F57EAB00AAAE4E /* luaconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = luaconf.h; path = ../../blua/luaconf.h; sourceTree = SOURCE_ROOT; }; + 67B83BF314F57EAB00AAAE4E /* lualib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lualib.h; path = ../../blua/lualib.h; sourceTree = SOURCE_ROOT; }; + 67B83BF414F57EAB00AAAE4E /* lundump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lundump.c; path = ../../blua/lundump.c; sourceTree = SOURCE_ROOT; }; + 67B83BF514F57EAB00AAAE4E /* lundump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lundump.h; path = ../../blua/lundump.h; sourceTree = SOURCE_ROOT; }; + 67B83BF614F57EAB00AAAE4E /* lvm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lvm.c; path = ../../blua/lvm.c; sourceTree = SOURCE_ROOT; }; + 67B83BF714F57EAB00AAAE4E /* lvm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lvm.h; path = ../../blua/lvm.h; sourceTree = SOURCE_ROOT; }; + 67B83BF814F57EAB00AAAE4E /* lzio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lzio.c; path = ../../blua/lzio.c; sourceTree = SOURCE_ROOT; }; + 67B83BF914F57EAB00AAAE4E /* lzio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lzio.h; path = ../../blua/lzio.h; sourceTree = SOURCE_ROOT; }; + 67B83C1214F57ECA00AAAE4E /* b_bot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = b_bot.c; path = ../../b_bot.c; sourceTree = SOURCE_ROOT; }; + 67B83C1314F57ECA00AAAE4E /* b_bot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = b_bot.h; path = ../../b_bot.h; sourceTree = SOURCE_ROOT; }; + 67B83C1514F57EE600AAAE4E /* lua_baselib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_baselib.c; path = ../../lua_baselib.c; sourceTree = SOURCE_ROOT; }; + 67B83C1614F57EE600AAAE4E /* lua_consolelib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_consolelib.c; path = ../../lua_consolelib.c; sourceTree = SOURCE_ROOT; }; + 67B83C1714F57EE600AAAE4E /* lua_hook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_hook.h; path = ../../lua_hook.h; sourceTree = SOURCE_ROOT; }; + 67B83C1814F57EE600AAAE4E /* lua_hooklib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_hooklib.c; path = ../../lua_hooklib.c; sourceTree = SOURCE_ROOT; }; + 67B83C1914F57EE600AAAE4E /* lua_infolib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_infolib.c; path = ../../lua_infolib.c; sourceTree = SOURCE_ROOT; }; + 67B83C1A14F57EE600AAAE4E /* lua_libs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_libs.h; path = ../../lua_libs.h; sourceTree = SOURCE_ROOT; }; + 67B83C1B14F57EE600AAAE4E /* lua_maplib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_maplib.c; path = ../../lua_maplib.c; sourceTree = SOURCE_ROOT; }; + 67B83C1C14F57EE600AAAE4E /* lua_mathlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_mathlib.c; path = ../../lua_mathlib.c; sourceTree = SOURCE_ROOT; }; + 67B83C1D14F57EE600AAAE4E /* lua_mobjlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_mobjlib.c; path = ../../lua_mobjlib.c; sourceTree = SOURCE_ROOT; }; + 67B83C1E14F57EE600AAAE4E /* lua_playerlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_playerlib.c; path = ../../lua_playerlib.c; sourceTree = SOURCE_ROOT; }; + 67B83C1F14F57EE600AAAE4E /* lua_script.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_script.c; path = ../../lua_script.c; sourceTree = SOURCE_ROOT; }; + 67B83C2014F57EE600AAAE4E /* lua_script.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_script.h; path = ../../lua_script.h; sourceTree = SOURCE_ROOT; }; + 67B83C2114F57EE600AAAE4E /* lua_thinkerlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lua_thinkerlib.c; path = ../../lua_thinkerlib.c; sourceTree = SOURCE_ROOT; }; + 67B83C2C14F57F1500AAAE4E /* fastcmp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fastcmp.h; path = ../../fastcmp.h; sourceTree = SOURCE_ROOT; }; + 67B83C2D14F57F1500AAAE4E /* i_addrinfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = i_addrinfo.c; path = ../../i_addrinfo.c; sourceTree = SOURCE_ROOT; }; + 67B83C2E14F57F1500AAAE4E /* i_addrinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = i_addrinfo.h; path = ../../i_addrinfo.h; sourceTree = SOURCE_ROOT; }; + 67B83C2F14F57F1500AAAE4E /* m_cond.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = m_cond.c; path = ../../m_cond.c; sourceTree = SOURCE_ROOT; }; + 67B83C3014F57F1500AAAE4E /* m_cond.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m_cond.h; path = ../../m_cond.h; sourceTree = SOURCE_ROOT; }; + 67B83C3114F57F1500AAAE4E /* m_dllist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m_dllist.h; path = ../../m_dllist.h; sourceTree = SOURCE_ROOT; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 8D1107320486CEB800E47090 /* Srb2mac.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Srb2mac.app; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D11072E0486CEB800E47090 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 002F39FA09D0881F00EBEB88 /* SDL.framework in Frameworks */, + 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, + 1E66921C0B690C5B00B7313A /* SDL_mixer.framework in Frameworks */, + 1E32C4290B6E6D5D0029E058 /* libpng.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1E44AE890B67CC4E00BAD059 /* A_Asm */, + 67B83BCA14F57DD400AAAE4E /* B_Bot */, + 67B83BC914F57D7F00AAAE4E /* BLUA */, + 1E44AE8C0B67CC6500BAD059 /* D_Doom */, + 1E44AEBB0B67CC9800BAD059 /* F_Frame */, + 1E44AEC20B67CCB500BAD059 /* G_Game */, + 1E44AECD0B67CCD200BAD059 /* H_Hud */, + 1E44AE5C0B67CC0F00BAD059 /* Hw_Hardware */, + 1E44AED20B67CCF600BAD059 /* I_Interface */, + 67B83BC814F57D6E00AAAE4E /* LUA */, + 1E44AEF70B67CDA900BAD059 /* M_Misc */, + 1E44AF160B67CDFB00BAD059 /* P_Play */, + 1E44AF540B67CE8C00BAD059 /* R_Render */, + 1E44AF830B67CEC900BAD059 /* S_Sound */, + 1E44AF170B67CE1000BAD059 /* W_Wad */, + ); + name = Classes; + sourceTree = ""; + }; + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1E32C4140B6E6D5D0029E058 /* libpng.framework */, + 1E66921B0B690C5B00B7313A /* SDL_mixer.framework */, + 002F39F909D0881F00EBEB88 /* SDL.framework */, + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 29B97324FDCFA39411CA2CEA /* AppKit.framework */, + 29B97325FDCFA39411CA2CEA /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D1107320486CEB800E47090 /* Srb2mac.app */, + ); + name = Products; + sourceTree = ""; + }; + 1E44AE5C0B67CC0F00BAD059 /* Hw_Hardware */ = { + isa = PBXGroup; + children = ( + 1E44AE600B67CC2B00BAD059 /* hw3dsdrv.h */, + 1E44AE610B67CC2B00BAD059 /* hw_bsp.c */, + 1E44AE620B67CC2B00BAD059 /* hw_defs.h */, + 1E44AE630B67CC2B00BAD059 /* hw3sound.c */, + 1E44AE640B67CC2B00BAD059 /* hw_cache.c */, + 1E44AE650B67CC2B00BAD059 /* hw_dll.h */, + 1E44AE660B67CC2B00BAD059 /* hw_drv.h */, + 1E44AE670B67CC2B00BAD059 /* hw_glide.h */, + 1E44AE680B67CC2B00BAD059 /* hw_light.c */, + 1E44AE690B67CC2B00BAD059 /* hw_light.h */, + 1E44AE6A0B67CC2B00BAD059 /* hw3sound.h */, + 1E44AE6B0B67CC2B00BAD059 /* hw_data.h */, + 1E44AE6C0B67CC2B00BAD059 /* hw_draw.c */, + 1E44AE6D0B67CC2B00BAD059 /* hw_glob.h */, + 1E44AE6E0B67CC2B00BAD059 /* hw_main.c */, + 1E44AE6F0B67CC2B00BAD059 /* hw_main.h */, + 1E44AE700B67CC2B00BAD059 /* hw_md2.c */, + 1E44AE710B67CC2B00BAD059 /* hw_md2.h */, + 1E44AE720B67CC2B00BAD059 /* hw_trick.c */, + 1E44AE730B67CC2B00BAD059 /* hws_data.h */, + ); + name = Hw_Hardware; + sourceTree = ""; + }; + 1E44AE890B67CC4E00BAD059 /* A_Asm */ = { + isa = PBXGroup; + children = ( + 67B2071C1180FA8200E93654 /* vid_copy.s */, + 1E44AE8A0B67CC6000BAD059 /* asm_defs.inc */, + 1E44AF9D0B67CF3D00BAD059 /* tmap.nas */, + 1E44AF9F0B67CF4900BAD059 /* tmap_mmx.nas */, + 1E44AFA00B67CF4900BAD059 /* tmap_vc.nas */, + ); + name = A_Asm; + sourceTree = ""; + }; + 1E44AE8C0B67CC6500BAD059 /* D_Doom */ = { + isa = PBXGroup; + children = ( + 1E44AEEB0B67CD4400BAD059 /* comptime.c */, + 1E44AE8D0B67CC8400BAD059 /* d_clisrv.c */, + 1E44AE8E0B67CC8400BAD059 /* d_clisrv.h */, + 1E44AE8F0B67CC8400BAD059 /* d_event.h */, + 1E44AE900B67CC8400BAD059 /* d_main.c */, + 1E44AE910B67CC8500BAD059 /* d_net.c */, + 1E44AE920B67CC8500BAD059 /* d_net.h */, + 1E44AE930B67CC8500BAD059 /* d_netcmd.h */, + 1E44AE940B67CC8500BAD059 /* d_netfil.c */, + 1E44AE950B67CC8500BAD059 /* d_player.h */, + 1E44AE960B67CC8500BAD059 /* d_think.h */, + 1E44AE980B67CC8500BAD059 /* d_netcmd.c */, + 1E44AE990B67CC8500BAD059 /* d_ticcmd.h */, + 1E44AE9A0B67CC8500BAD059 /* d_main.h */, + 1E44AE9B0B67CC8500BAD059 /* d_netfil.h */, + 1E44AE9C0B67CC8500BAD059 /* dehacked.c */, + 1E44AE9D0B67CC8500BAD059 /* dehacked.h */, + 1E44AE9E0B67CC8500BAD059 /* doomdata.h */, + 1E44AE9F0B67CC8500BAD059 /* doomdef.h */, + 1E44AEA00B67CC8500BAD059 /* doomstat.h */, + 1E44AEA10B67CC8500BAD059 /* doomtype.h */, + 1E44AFAF0B67CF7A00BAD059 /* z_zone.c */, + 1E44AFB00B67CF7A00BAD059 /* z_zone.h */, + ); + name = D_Doom; + sourceTree = ""; + }; + 1E44AEBB0B67CC9800BAD059 /* F_Frame */ = { + isa = PBXGroup; + children = ( + 1E44AEBC0B67CCA900BAD059 /* f_wipe.c */, + 1E44AEBD0B67CCA900BAD059 /* f_finale.c */, + 1E44AEBE0B67CCA900BAD059 /* f_finale.h */, + 1E44AFAB0B67CF6F00BAD059 /* y_inter.c */, + 1E44AFAC0B67CF6F00BAD059 /* y_inter.h */, + ); + name = F_Frame; + sourceTree = ""; + }; + 1E44AEC20B67CCB500BAD059 /* G_Game */ = { + isa = PBXGroup; + children = ( + 1E44AEC30B67CCC600BAD059 /* g_game.c */, + 1E44AEC40B67CCC600BAD059 /* g_game.h */, + 1E44AEC50B67CCC600BAD059 /* g_input.h */, + 1E44AEC60B67CCC600BAD059 /* g_state.h */, + 1E44AEC70B67CCC600BAD059 /* g_input.c */, + ); + name = G_Game; + sourceTree = ""; + }; + 1E44AECD0B67CCD200BAD059 /* H_Hud */ = { + isa = PBXGroup; + children = ( + 1E44AEE10B67CD2B00BAD059 /* am_map.c */, + 1E44AEE20B67CD2B00BAD059 /* am_map.h */, + 1E44AEE70B67CD3F00BAD059 /* command.c */, + 1E44AEE80B67CD3F00BAD059 /* command.h */, + 1E44AEED0B67CD5400BAD059 /* console.c */, + 1E44AEEE0B67CD5400BAD059 /* console.h */, + 1E44AECE0B67CCEE00BAD059 /* hu_stuff.c */, + 1E44AECF0B67CCEE00BAD059 /* hu_stuff.h */, + 1E44AF000B67CDE900BAD059 /* m_menu.c */, + 1E44AF010B67CDE900BAD059 /* m_menu.h */, + 1E44AF910B67CEFF00BAD059 /* st_stuff.c */, + 1E44AF920B67CEFF00BAD059 /* st_stuff.h */, + ); + name = H_Hud; + sourceTree = ""; + }; + 1E44AED20B67CCF600BAD059 /* I_Interface */ = { + isa = PBXGroup; + children = ( + 67259E0218D268F600F02971 /* i_ttf.c */, + 67259E0318D268F600F02971 /* i_ttf.h */, + 67259E0418D268F600F02971 /* mixer_sound.c */, + 67259E0518D268F600F02971 /* sdl_sound.c */, + 1E44AFB30B67CF8500BAD059 /* SDL */, + 67B83C2D14F57F1500AAAE4E /* i_addrinfo.c */, + 67B83C2E14F57F1500AAAE4E /* i_addrinfo.h */, + 1E44AEE50B67CD3200BAD059 /* byteptr.h */, + 1E44AEF10B67CD7F00BAD059 /* filesrch.c */, + 1E44AEF20B67CD7F00BAD059 /* filesrch.h */, + 1E44AED30B67CD1200BAD059 /* i_net.h */, + 1E44AED40B67CD1200BAD059 /* i_sound.h */, + 1E44AED50B67CD1200BAD059 /* i_tcp.c */, + 1E44AED60B67CD1200BAD059 /* i_tcp.h */, + 1E44AED70B67CD1200BAD059 /* i_system.h */, + 1E44AED80B67CD1200BAD059 /* i_video.h */, + 1E44AED90B67CD1300BAD059 /* i_joy.h */, + 1E44AEF50B67CD9F00BAD059 /* keys.h */, + 1E44AF200B67CE4100BAD059 /* mserv.c */, + 1E44AF210B67CE4100BAD059 /* mserv.h */, + ); + name = I_Interface; + sourceTree = ""; + }; + 1E44AEF70B67CDA900BAD059 /* M_Misc */ = { + isa = PBXGroup; + children = ( + 67259DFF18D268AE00F02971 /* m_anigif.c */, + 67259E0018D268AE00F02971 /* m_anigif.h */, + 1E44AEF80B67CDE900BAD059 /* m_argv.c */, + 1E44AEFA0B67CDE900BAD059 /* m_argv.h */, + 1E44AEFC0B67CDE900BAD059 /* m_bbox.c */, + 1E44AEF90B67CDE900BAD059 /* m_bbox.h */, + 1E44AEFB0B67CDE900BAD059 /* m_cheat.c */, + 1E44AEFD0B67CDE900BAD059 /* m_cheat.h */, + 67B83C2F14F57F1500AAAE4E /* m_cond.c */, + 67B83C3014F57F1500AAAE4E /* m_cond.h */, + 67B83C3114F57F1500AAAE4E /* m_dllist.h */, + 1E44AEFE0B67CDE900BAD059 /* m_fixed.c */, + 1E44AEFF0B67CDE900BAD059 /* m_fixed.h */, + 1E44AF020B67CDE900BAD059 /* m_misc.c */, + 1E44AF030B67CDE900BAD059 /* m_misc.h */, + 676BB51C0E0DE06100C95963 /* m_queue.c */, + 676BB51D0E0DE06100C95963 /* m_queue.h */, + 1E44AF040B67CDE900BAD059 /* m_random.c */, + 1E44AF050B67CDE900BAD059 /* m_random.h */, + 1E44AF060B67CDE900BAD059 /* m_swap.h */, + 1E44AF950B67CF1300BAD059 /* string.c */, + ); + name = M_Misc; + sourceTree = ""; + }; + 1E44AF160B67CDFB00BAD059 /* P_Play */ = { + isa = PBXGroup; + children = ( + 1E44AF180B67CE2A00BAD059 /* info.c */, + 1E44AF190B67CE2A00BAD059 /* info.h */, + 1E44AF3B0B67CE5F00BAD059 /* p_ceilng.c */, + 1E44AF240B67CE5F00BAD059 /* p_enemy.c */, + 1E44AF250B67CE5F00BAD059 /* p_inter.c */, + 1E44AF260B67CE5F00BAD059 /* p_fab.c */, + 1E44AF270B67CE5F00BAD059 /* p_lights.c */, + 1E44AF280B67CE5F00BAD059 /* p_map.c */, + 1E44AF290B67CE5F00BAD059 /* p_maputl.c */, + 1E44AF2A0B67CE5F00BAD059 /* p_maputl.h */, + 1E44AF2B0B67CE5F00BAD059 /* p_mobj.c */, + 1E44AF2C0B67CE5F00BAD059 /* p_mobj.h */, + 1E44AF2D0B67CE5F00BAD059 /* p_floor.c */, + 1E44AF2E0B67CE5F00BAD059 /* p_local.h */, + 676BB51E0E0DE06100C95963 /* p_polyobj.c */, + 676BB51F0E0DE06100C95963 /* p_polyobj.h */, + 1E44AF2F0B67CE5F00BAD059 /* p_pspr.h */, + 1E44AF300B67CE5F00BAD059 /* p_saveg.c */, + 1E44AF310B67CE5F00BAD059 /* p_saveg.h */, + 1E44AF320B67CE5F00BAD059 /* p_setup.c */, + 1E44AF330B67CE5F00BAD059 /* p_setup.h */, + 1E44AF340B67CE5F00BAD059 /* p_sight.c */, + 1E44AF350B67CE5F00BAD059 /* p_spec.c */, + 1E44AF360B67CE5F00BAD059 /* p_spec.h */, + 1E44AF370B67CE5F00BAD059 /* p_telept.c */, + 1E44AF380B67CE5F00BAD059 /* p_tick.c */, + 1E44AF390B67CE5F00BAD059 /* p_tick.h */, + 1E44AF3A0B67CE5F00BAD059 /* p_user.c */, + 1E44AF990B67CF2E00BAD059 /* tables.c */, + 1E44AF9A0B67CF2E00BAD059 /* tables.h */, + ); + name = P_Play; + sourceTree = ""; + }; + 1E44AF170B67CE1000BAD059 /* W_Wad */ = { + isa = PBXGroup; + children = ( + 1E44B2240B67EADE00BAD059 /* lzf.c */, + 1E44B2250B67EADE00BAD059 /* lzf.h */, + 1E44AF1C0B67CE3600BAD059 /* md5.c */, + 1E44AF1D0B67CE3600BAD059 /* md5.h */, + 1E44AFA70B67CF6400BAD059 /* w_wad.c */, + 1E44AFA80B67CF6400BAD059 /* w_wad.h */, + ); + name = W_Wad; + sourceTree = ""; + }; + 1E44AF540B67CE8C00BAD059 /* R_Render */ = { + isa = PBXGroup; + children = ( + 1E44AF550B67CEC100BAD059 /* r_bsp.c */, + 1E44AF560B67CEC100BAD059 /* r_bsp.h */, + 1E44AF570B67CEC100BAD059 /* r_defs.h */, + 1E44AF580B67CEC100BAD059 /* r_data.c */, + 1E44AF590B67CEC100BAD059 /* r_draw.c */, + 1E44AF5A0B67CEC100BAD059 /* r_draw16.c */, + 1E44AF5B0B67CEC100BAD059 /* r_draw8.c */, + 1E44AF5C0B67CEC100BAD059 /* r_main.c */, + 1E44AF5D0B67CEC100BAD059 /* r_main.h */, + 1E44AF5E0B67CEC100BAD059 /* r_data.h */, + 1E44AF5F0B67CEC100BAD059 /* r_draw.h */, + 1E44AF600B67CEC100BAD059 /* r_local.h */, + 1E44AF610B67CEC100BAD059 /* r_plane.c */, + 1E44AF620B67CEC100BAD059 /* r_plane.h */, + 1E44AF630B67CEC100BAD059 /* r_segs.c */, + 1E44AF640B67CEC100BAD059 /* r_segs.h */, + 1E44AF650B67CEC200BAD059 /* r_sky.c */, + 1E44AF660B67CEC200BAD059 /* r_sky.h */, + 1E44AF670B67CEC200BAD059 /* r_splats.c */, + 1E44AF680B67CEC200BAD059 /* r_splats.h */, + 1E44AF690B67CEC200BAD059 /* r_state.h */, + 1E44AF6A0B67CEC200BAD059 /* r_things.c */, + 1E44AF6B0B67CEC200BAD059 /* r_things.h */, + 1E44AF890B67CEE900BAD059 /* screen.c */, + 1E44AF8A0B67CEE900BAD059 /* screen.h */, + 1E44AFA30B67CF5D00BAD059 /* v_video.c */, + 1E44AFA40B67CF5D00BAD059 /* v_video.h */, + ); + name = R_Render; + sourceTree = ""; + }; + 1E44AF830B67CEC900BAD059 /* S_Sound */ = { + isa = PBXGroup; + children = ( + 1E44AF850B67CEE000BAD059 /* s_sound.c */, + 1E44AF860B67CEE000BAD059 /* s_sound.h */, + 1E44AF8D0B67CEF000BAD059 /* sounds.c */, + 1E44AF8E0B67CEF000BAD059 /* sounds.h */, + ); + name = S_Sound; + sourceTree = ""; + }; + 1E44AFB30B67CF8500BAD059 /* SDL */ = { + isa = PBXGroup; + children = ( + 1E44AFE50B67D04900BAD059 /* macosx */, + 1E44AFD40B67D03100BAD059 /* filter */, + 1E44AFB40B67CFDC00BAD059 /* dosstr.c */, + 1E44AFB50B67CFDC00BAD059 /* endtxt.c */, + 1E44AFB60B67CFDC00BAD059 /* endtxt.h */, + 1E44AFB70B67CFDC00BAD059 /* hwsym_sdl.c */, + 1E44AFB80B67CFDC00BAD059 /* hwsym_sdl.h */, + 1E44AFB90B67CFDC00BAD059 /* i_cdmus.c */, + 1E44AFBA0B67CFDC00BAD059 /* i_main.c */, + 1E44AFBB0B67CFDC00BAD059 /* i_net.c */, + 1E44AFBD0B67CFDC00BAD059 /* i_system.c */, + 1E44AFBE0B67CFDC00BAD059 /* i_video.c */, + 1E44AFBF0B67CFDC00BAD059 /* IMG_xpm.c */, + 1E44AFEC0B67D0AB00BAD059 /* r_opengl.c */, + 1E44AFC00B67CFDC00BAD059 /* ogl_sdl.c */, + 1E44AFC10B67CFDC00BAD059 /* ogl_sdl.h */, + 1E44AFC20B67CFDC00BAD059 /* SDL_icon.xpm */, + 1E44AFC30B67CFDC00BAD059 /* sdlmain.h */, + ); + name = SDL; + sourceTree = ""; + }; + 1E44AFD40B67D03100BAD059 /* filter */ = { + isa = PBXGroup; + children = ( + 1E44AFD50B67D03100BAD059 /* filters.c */, + 1E44AFD60B67D03100BAD059 /* filters.h */, + 1E44AFD70B67D03100BAD059 /* hq2x.c */, + 1E44AFD80B67D03100BAD059 /* hq2x.h */, + 1E44AFD90B67D03100BAD059 /* interp.h */, + 1E44AFDA0B67D03100BAD059 /* lq2x.c */, + 1E44AFDB0B67D03100BAD059 /* lq2x.h */, + 1E44AFDC0B67D03100BAD059 /* main.c */, + ); + name = filter; + path = ../filter; + sourceTree = SOURCE_ROOT; + }; + 1E44AFE50B67D04900BAD059 /* macosx */ = { + isa = PBXGroup; + children = ( + 1E44AFE60B67D06200BAD059 /* mac_alert.h */, + 1E44AFE70B67D06200BAD059 /* Srb2mac.icns */, + 1E44AFE80B67D06200BAD059 /* mac_alert.c */, + 1E44B0560B67D81E00BAD059 /* SDL_macosx_main.h */, + 1E44B0570B67D81E00BAD059 /* SDL_macosx_main.m */, + ); + name = macosx; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* Srb2mac */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = Srb2mac; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 67259E2B18D26D5700F02971 /* patch.dta */, + 67259E2C18D26D5700F02971 /* rings.dta */, + 67259E2D18D26D5700F02971 /* srb2.srb */, + 67A1F91813FAD026009FA3E5 /* player.dta */, + 6766C0AE11B057E50065F389 /* zones.dta */, + 1E44AE440B67CBE800BAD059 /* music.dta */, + 1E44AE4B0B67CBE800BAD059 /* srb2.wad */, + 8D1107310486CEB800E47090 /* Info.plist */, + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; + 67B83BC814F57D6E00AAAE4E /* LUA */ = { + isa = PBXGroup; + children = ( + 67259DFA18D2687D00F02971 /* lua_hud.h */, + 67259DFB18D2687D00F02971 /* lua_hudlib.c */, + 67259DFC18D2687D00F02971 /* lua_skinlib.c */, + 67B83C2C14F57F1500AAAE4E /* fastcmp.h */, + 67B83C1514F57EE600AAAE4E /* lua_baselib.c */, + 67B83C1614F57EE600AAAE4E /* lua_consolelib.c */, + 67B83C1714F57EE600AAAE4E /* lua_hook.h */, + 67B83C1814F57EE600AAAE4E /* lua_hooklib.c */, + 67B83C1914F57EE600AAAE4E /* lua_infolib.c */, + 67B83C1A14F57EE600AAAE4E /* lua_libs.h */, + 67B83C1B14F57EE600AAAE4E /* lua_maplib.c */, + 67B83C1C14F57EE600AAAE4E /* lua_mathlib.c */, + 67B83C1D14F57EE600AAAE4E /* lua_mobjlib.c */, + 67B83C1E14F57EE600AAAE4E /* lua_playerlib.c */, + 67B83C1F14F57EE600AAAE4E /* lua_script.c */, + 67B83C2014F57EE600AAAE4E /* lua_script.h */, + 67B83C2114F57EE600AAAE4E /* lua_thinkerlib.c */, + ); + name = LUA; + sourceTree = ""; + }; + 67B83BC914F57D7F00AAAE4E /* BLUA */ = { + isa = PBXGroup; + children = ( + 67B83BCB14F57EAB00AAAE4E /* lapi.c */, + 67B83BCC14F57EAB00AAAE4E /* lapi.h */, + 67B83BCD14F57EAB00AAAE4E /* lauxlib.c */, + 67B83BCE14F57EAB00AAAE4E /* lauxlib.h */, + 67B83BCF14F57EAB00AAAE4E /* lbaselib.c */, + 67B83BD014F57EAB00AAAE4E /* lcode.c */, + 67B83BD114F57EAB00AAAE4E /* lcode.h */, + 67B83BD214F57EAB00AAAE4E /* ldebug.c */, + 67B83BD314F57EAB00AAAE4E /* ldebug.h */, + 67B83BD414F57EAB00AAAE4E /* ldo.c */, + 67B83BD514F57EAB00AAAE4E /* ldo.h */, + 67B83BD614F57EAB00AAAE4E /* ldump.c */, + 67B83BD714F57EAB00AAAE4E /* lfunc.c */, + 67B83BD814F57EAB00AAAE4E /* lfunc.h */, + 67B83BD914F57EAB00AAAE4E /* lgc.c */, + 67B83BDA14F57EAB00AAAE4E /* lgc.h */, + 67B83BDB14F57EAB00AAAE4E /* linit.c */, + 67B83BDC14F57EAB00AAAE4E /* llex.c */, + 67B83BDD14F57EAB00AAAE4E /* llex.h */, + 67B83BDE14F57EAB00AAAE4E /* llimits.h */, + 67B83BDF14F57EAB00AAAE4E /* lmem.c */, + 67B83BE014F57EAB00AAAE4E /* lmem.h */, + 67B83BE114F57EAB00AAAE4E /* lobject.c */, + 67B83BE214F57EAB00AAAE4E /* lobject.h */, + 67B83BE314F57EAB00AAAE4E /* lopcodes.c */, + 67B83BE414F57EAB00AAAE4E /* lopcodes.h */, + 67B83BE514F57EAB00AAAE4E /* lparser.c */, + 67B83BE614F57EAB00AAAE4E /* lparser.h */, + 67B83BE714F57EAB00AAAE4E /* lstate.c */, + 67B83BE814F57EAB00AAAE4E /* lstate.h */, + 67B83BE914F57EAB00AAAE4E /* lstring.c */, + 67B83BEA14F57EAB00AAAE4E /* lstring.h */, + 67B83BEB14F57EAB00AAAE4E /* lstrlib.c */, + 67B83BEC14F57EAB00AAAE4E /* ltable.c */, + 67B83BED14F57EAB00AAAE4E /* ltable.h */, + 67B83BEE14F57EAB00AAAE4E /* ltablib.c */, + 67B83BEF14F57EAB00AAAE4E /* ltm.c */, + 67B83BF014F57EAB00AAAE4E /* ltm.h */, + 67B83BF114F57EAB00AAAE4E /* lua.h */, + 67B83BF214F57EAB00AAAE4E /* luaconf.h */, + 67B83BF314F57EAB00AAAE4E /* lualib.h */, + 67B83BF414F57EAB00AAAE4E /* lundump.c */, + 67B83BF514F57EAB00AAAE4E /* lundump.h */, + 67B83BF614F57EAB00AAAE4E /* lvm.c */, + 67B83BF714F57EAB00AAAE4E /* lvm.h */, + 67B83BF814F57EAB00AAAE4E /* lzio.c */, + 67B83BF914F57EAB00AAAE4E /* lzio.h */, + ); + name = BLUA; + sourceTree = ""; + }; + 67B83BCA14F57DD400AAAE4E /* B_Bot */ = { + isa = PBXGroup; + children = ( + 67B83C1214F57ECA00AAAE4E /* b_bot.c */, + 67B83C1314F57ECA00AAAE4E /* b_bot.h */, + ); + name = B_Bot; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D1107260486CEB800E47090 /* Srb2mac */ = { + isa = PBXNativeTarget; + buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Srb2mac" */; + buildPhases = ( + 8D1107290486CEB800E47090 /* Resources */, + 677E4CB30E1765500034519D /* Get SCM Info */, + 8D11072C0486CEB800E47090 /* Sources */, + 8D11072E0486CEB800E47090 /* Frameworks */, + 002F39FD09D0883400EBEB88 /* Copy Frameworks into .app bundle */, + 679B708A102B872300AA9E4C /* Make DMG */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Srb2mac; + productInstallPath = "$(HOME)/Applications"; + productName = Srb2mac; + productReference = 8D1107320486CEB800E47090 /* Srb2mac.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Srb2mac" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* Srb2mac */; + projectDirPath = ""; + projectRoot = ../../..; + targets = ( + 8D1107260486CEB800E47090 /* Srb2mac */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D1107290486CEB800E47090 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, + 1E44AFEA0B67D06200BAD059 /* Srb2mac.icns in Resources */, + 67259E2E18D26D5700F02971 /* patch.dta in Resources */, + 67259E2F18D26D5700F02971 /* rings.dta in Resources */, + 67259E3018D26D5700F02971 /* srb2.srb in Resources */, + 67259E3218D26DD200F02971 /* music.dta in Resources */, + 67259E3318D26DD300F02971 /* player.dta in Resources */, + 67259E3518D26DD500F02971 /* zones.dta in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 677E4CB30E1765500034519D /* Get SCM Info */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + comments = "update the time and date stamps in src/comptime.c"; + files = ( + ); + inputPaths = ( + ); + name = "Get SCM Info"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "PATH=\"/usr/local/bin:$PATH\" $SRCROOT/../../../comptime.sh $SRCROOT/../../"; + }; + 679B708A102B872300AA9E4C /* Make DMG */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + comments = "make DMG file for Release builds"; + files = ( + ); + inputPaths = ( + $BUILT_PRODUCTS_DIR/$WRAPPER_NAME, + ); + name = "Make DMG"; + outputPaths = ( + $BUILT_PRODUCTS_DIR/$TARGET_NAME.nodata.dmg, + $BUILT_PRODUCTS_DIR/$TARGET_NAME.dmg, + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "set -ex\n\n[ \"$ACTION\" = build ] || exit 0\n[ \"$CURRENT_VARIANT\" = \"normal\" ] || exit 0\n[ \"$BUILD_STYLE\" = \"Release\" ] || exit 0\n\ndir=\"$TEMP_FILES_DIR/$TARGET_NAME.disk\"\ndmg=\"$BUILT_PRODUCTS_DIR/$TARGET_NAME.dmg\"\ndmg_nodata=\"$BUILT_PRODUCTS_DIR/$TARGET_NAME.nodata.dmg\"\n\nrm -rf -- \"$dir\"\nmkdir \"$dir\"\ncp -R \"$BUILT_PRODUCTS_DIR/$WRAPPER_NAME\" \"$dir\"\nrm -f -- \"$dmg\"\nhdiutil create -ov -fs HFS+ -srcfolder \"$dir\" -volname \"$TARGET_NAME\" \"$dmg\"\nhdiutil internet-enable -yes \"$dmg\"\ncd \"$dir/$WRAPPER_NAME/Contents/Resources\"\nrm -f -- *.wad\nrm -f -- *.dta\nrm -f -- *.plr\nrm -f -- *.wpn\nrm -f -- *.srb2\ncd \"$OLDPWD\"\nrm -f -- \"$dmg_nodata\"\nhdiutil create -ov -fs HFS+ -srcfolder \"$dir\" -volname \"$TARGET_NAME Lite\" \"$dmg_nodata\"\nhdiutil internet-enable -yes \"$dmg_nodata\"\nrm -rf -- \"$dir\""; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D11072C0486CEB800E47090 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1E44AE750B67CC2B00BAD059 /* hw_bsp.c in Sources */, + 1E44AE770B67CC2B00BAD059 /* hw3sound.c in Sources */, + 1E44AE780B67CC2B00BAD059 /* hw_cache.c in Sources */, + 1E44AE7C0B67CC2B00BAD059 /* hw_light.c in Sources */, + 1E44AE800B67CC2B00BAD059 /* hw_draw.c in Sources */, + 1E44AE820B67CC2B00BAD059 /* hw_main.c in Sources */, + 1E44AE840B67CC2B00BAD059 /* hw_md2.c in Sources */, + 1E44AE860B67CC2B00BAD059 /* hw_trick.c in Sources */, + 1E44AEA40B67CC8500BAD059 /* d_clisrv.c in Sources */, + 1E44AEA70B67CC8500BAD059 /* d_main.c in Sources */, + 1E44AEA80B67CC8500BAD059 /* d_net.c in Sources */, + 1E44AEAB0B67CC8500BAD059 /* d_netfil.c in Sources */, + 1E44AEAF0B67CC8500BAD059 /* d_netcmd.c in Sources */, + 1E44AEB30B67CC8500BAD059 /* dehacked.c in Sources */, + 1E44AEBF0B67CCA900BAD059 /* f_wipe.c in Sources */, + 1E44AEC00B67CCA900BAD059 /* f_finale.c in Sources */, + 1E44AEC80B67CCC600BAD059 /* g_game.c in Sources */, + 1E44AECC0B67CCC600BAD059 /* g_input.c in Sources */, + 1E44AED00B67CCEE00BAD059 /* hu_stuff.c in Sources */, + 1E44AEDC0B67CD1300BAD059 /* i_tcp.c in Sources */, + 1E44AEE30B67CD2B00BAD059 /* am_map.c in Sources */, + 1E44AEE90B67CD3F00BAD059 /* command.c in Sources */, + 1E44AEEC0B67CD4400BAD059 /* comptime.c in Sources */, + 1E44AEEF0B67CD5400BAD059 /* console.c in Sources */, + 1E44AEF30B67CD7F00BAD059 /* filesrch.c in Sources */, + 1E44AF070B67CDE900BAD059 /* m_argv.c in Sources */, + 1E44AF0A0B67CDE900BAD059 /* m_cheat.c in Sources */, + 1E44AF0B0B67CDE900BAD059 /* m_bbox.c in Sources */, + 1E44AF0D0B67CDE900BAD059 /* m_fixed.c in Sources */, + 1E44AF0F0B67CDE900BAD059 /* m_menu.c in Sources */, + 1E44AF110B67CDE900BAD059 /* m_misc.c in Sources */, + 1E44AF130B67CDE900BAD059 /* m_random.c in Sources */, + 1E44AF1A0B67CE2A00BAD059 /* info.c in Sources */, + 1E44AF1E0B67CE3600BAD059 /* md5.c in Sources */, + 1E44AF220B67CE4100BAD059 /* mserv.c in Sources */, + 1E44AF3C0B67CE5F00BAD059 /* p_enemy.c in Sources */, + 1E44AF3D0B67CE5F00BAD059 /* p_inter.c in Sources */, + 1E44AF3E0B67CE5F00BAD059 /* p_fab.c in Sources */, + 1E44AF3F0B67CE5F00BAD059 /* p_lights.c in Sources */, + 1E44AF400B67CE5F00BAD059 /* p_map.c in Sources */, + 1E44AF410B67CE5F00BAD059 /* p_maputl.c in Sources */, + 1E44AF430B67CE5F00BAD059 /* p_mobj.c in Sources */, + 1E44AF450B67CE5F00BAD059 /* p_floor.c in Sources */, + 1E44AF480B67CE5F00BAD059 /* p_saveg.c in Sources */, + 1E44AF4A0B67CE5F00BAD059 /* p_setup.c in Sources */, + 1E44AF4C0B67CE5F00BAD059 /* p_sight.c in Sources */, + 1E44AF4D0B67CE5F00BAD059 /* p_spec.c in Sources */, + 1E44AF4F0B67CE5F00BAD059 /* p_telept.c in Sources */, + 1E44AF500B67CE5F00BAD059 /* p_tick.c in Sources */, + 1E44AF520B67CE5F00BAD059 /* p_user.c in Sources */, + 1E44AF530B67CE5F00BAD059 /* p_ceilng.c in Sources */, + 1E44AF6C0B67CEC200BAD059 /* r_bsp.c in Sources */, + 1E44AF6F0B67CEC200BAD059 /* r_data.c in Sources */, + 1E44AF700B67CEC200BAD059 /* r_draw.c in Sources */, + 1E44AF730B67CEC200BAD059 /* r_main.c in Sources */, + 1E44AF780B67CEC200BAD059 /* r_plane.c in Sources */, + 1E44AF7A0B67CEC200BAD059 /* r_segs.c in Sources */, + 1E44AF7C0B67CEC200BAD059 /* r_sky.c in Sources */, + 1E44AF7E0B67CEC200BAD059 /* r_splats.c in Sources */, + 1E44AF810B67CEC200BAD059 /* r_things.c in Sources */, + 1E44AF870B67CEE000BAD059 /* s_sound.c in Sources */, + 1E44AF8B0B67CEE900BAD059 /* screen.c in Sources */, + 1E44AF8F0B67CEF000BAD059 /* sounds.c in Sources */, + 1E44AF930B67CEFF00BAD059 /* st_stuff.c in Sources */, + 1E44AF9B0B67CF2E00BAD059 /* tables.c in Sources */, + 1E44AFA50B67CF5D00BAD059 /* v_video.c in Sources */, + 1E44AFA90B67CF6400BAD059 /* w_wad.c in Sources */, + 1E44AFAD0B67CF6F00BAD059 /* y_inter.c in Sources */, + 1E44AFB10B67CF7A00BAD059 /* z_zone.c in Sources */, + 1E44AFC40B67CFDC00BAD059 /* dosstr.c in Sources */, + 1E44AFC50B67CFDC00BAD059 /* endtxt.c in Sources */, + 1E44AFC70B67CFDC00BAD059 /* hwsym_sdl.c in Sources */, + 1E44AFC90B67CFDC00BAD059 /* i_cdmus.c in Sources */, + 1E44AFCA0B67CFDC00BAD059 /* i_main.c in Sources */, + 1E44AFCB0B67CFDC00BAD059 /* i_net.c in Sources */, + 1E44AFCD0B67CFDC00BAD059 /* i_system.c in Sources */, + 1E44AFCE0B67CFDC00BAD059 /* i_video.c in Sources */, + 1E44AFD00B67CFDC00BAD059 /* ogl_sdl.c in Sources */, + 1E44AFEB0B67D06200BAD059 /* mac_alert.c in Sources */, + 1E44AFED0B67D0AB00BAD059 /* r_opengl.c in Sources */, + 1E44B0590B67D81E00BAD059 /* SDL_macosx_main.m in Sources */, + 1E308E720B71172D0015728C /* lzf.c in Sources */, + 676BB5200E0DE06100C95963 /* m_queue.c in Sources */, + 676BB5220E0DE06100C95963 /* p_polyobj.c in Sources */, + 67B83BFA14F57EAB00AAAE4E /* lapi.c in Sources */, + 67B83BFB14F57EAB00AAAE4E /* lauxlib.c in Sources */, + 67B83BFC14F57EAB00AAAE4E /* lbaselib.c in Sources */, + 67B83BFD14F57EAB00AAAE4E /* lcode.c in Sources */, + 67B83BFE14F57EAB00AAAE4E /* ldebug.c in Sources */, + 67B83BFF14F57EAB00AAAE4E /* ldo.c in Sources */, + 67B83C0014F57EAB00AAAE4E /* ldump.c in Sources */, + 67B83C0114F57EAB00AAAE4E /* lfunc.c in Sources */, + 67B83C0214F57EAB00AAAE4E /* lgc.c in Sources */, + 67B83C0314F57EAB00AAAE4E /* linit.c in Sources */, + 67B83C0414F57EAB00AAAE4E /* llex.c in Sources */, + 67B83C0514F57EAB00AAAE4E /* lmem.c in Sources */, + 67B83C0614F57EAB00AAAE4E /* lobject.c in Sources */, + 67B83C0714F57EAB00AAAE4E /* lopcodes.c in Sources */, + 67B83C0814F57EAB00AAAE4E /* lparser.c in Sources */, + 67B83C0914F57EAB00AAAE4E /* lstate.c in Sources */, + 67B83C0A14F57EAB00AAAE4E /* lstring.c in Sources */, + 67B83C0B14F57EAB00AAAE4E /* lstrlib.c in Sources */, + 67B83C0C14F57EAB00AAAE4E /* ltable.c in Sources */, + 67B83C0D14F57EAB00AAAE4E /* ltablib.c in Sources */, + 67B83C0E14F57EAB00AAAE4E /* ltm.c in Sources */, + 67B83C0F14F57EAB00AAAE4E /* lundump.c in Sources */, + 67B83C1014F57EAB00AAAE4E /* lvm.c in Sources */, + 67B83C1114F57EAB00AAAE4E /* lzio.c in Sources */, + 67B83C1414F57ECA00AAAE4E /* b_bot.c in Sources */, + 67B83C2214F57EE600AAAE4E /* lua_baselib.c in Sources */, + 67B83C2314F57EE600AAAE4E /* lua_consolelib.c in Sources */, + 67B83C2414F57EE600AAAE4E /* lua_hooklib.c in Sources */, + 67B83C2514F57EE600AAAE4E /* lua_infolib.c in Sources */, + 67B83C2614F57EE600AAAE4E /* lua_maplib.c in Sources */, + 67B83C2714F57EE600AAAE4E /* lua_mathlib.c in Sources */, + 67B83C2814F57EE600AAAE4E /* lua_mobjlib.c in Sources */, + 67B83C2914F57EE600AAAE4E /* lua_playerlib.c in Sources */, + 67B83C2A14F57EE600AAAE4E /* lua_script.c in Sources */, + 67B83C2B14F57EE600AAAE4E /* lua_thinkerlib.c in Sources */, + 67B83C3314F57F1500AAAE4E /* m_cond.c in Sources */, + 67259DFD18D2687D00F02971 /* lua_hudlib.c in Sources */, + 67259DFE18D2687D00F02971 /* lua_skinlib.c in Sources */, + 67259E0118D268AE00F02971 /* m_anigif.c in Sources */, + 67259E0618D268F700F02971 /* i_ttf.c in Sources */, + 67259E0718D268F700F02971 /* mixer_sound.c in Sources */, + 67259E0818D268F700F02971 /* sdl_sound.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C165DFE840E0CC02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + C01FCF4B08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CURRENT_PROJECT_VERSION = 2.1.8; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + NORMALSRB2, + ); + PRODUCT_NAME = Srb2mac; + }; + name = Debug; + }; + C01FCF4C08A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CURRENT_PROJECT_VERSION = 2.1.8; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + NORMALSRB2, + ); + PRODUCT_NAME = Srb2mac; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 0.0.0; + DEBUG_INFORMATION_FORMAT = dwarf; + DSTROOT = "$(HOME)/Applications"; + FRAMEWORK_SEARCH_PATHS = ( + "$(HOME)/Library/Frameworks", + /Library/Frameworks, + "$(FRAMEWORK_SEARCH_PATHS)", + ); + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_ENABLE_OBJC_EXCEPTIONS = NO; + GCC_ENABLE_PASCAL_STRINGS = NO; + GCC_FAST_OBJC_DISPATCH = NO; + "GCC_MODEL_TUNING[arch=ppc]" = G3; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + MAC_ALERT, + SDLMAIN, + SDL, + HAVE_MIXER, + HAVE_PNG, + HAVE_BLUA, + LUA_USE_POSIX, + COMPVERSION, + ); + GCC_THREADSAFE_STATICS = NO; + GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; + GCC_TREAT_NONCONFORMANT_CODE_ERRORS_AS_WARNINGS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_VERSION_i386 = 4.0; + GCC_VERSION_ppc0 = 3.3; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_GLOBAL_CONSTRUCTORS = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = YES; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + GCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; + GCC_WARN_INHIBIT_ALL_WARNINGS = NO; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_MISSING_PARENTHESES = YES; + GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = NO; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_PEDANTIC = NO; + GCC_WARN_PROTOTYPE_CONVERSION = NO; + GCC_WARN_SHADOW = NO; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_STRICT_SELECTOR_MATCH = YES; + GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VALUE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GGG_MODEL_TUNING_ppc = G3; + HEADER_SEARCH_PATHS = ( + "$(HOME)/Library/Frameworks/SDL.framework/Headers", + /Library/Frameworks/SDL.framework/Headers, + "$(HOME)/Library/Frameworks/SDL_mixer.framework/Headers", + /Library/Frameworks/SDL_mixer.framework/Headers, + "$(HOME)/Library/Frameworks/libz.framework/Headers", + /Library/Frameworks/libz.framework/Headers, + "$(HOME)/Library/Frameworks/libpng.framework/Headers", + /Library/Frameworks/libpng.framework/Headers, + "$(HEADER_SEARCH_PATHS)", + ); + INFOPLIST_FILE = Info.plist; + MACH_O_TYPE = mh_execute; + MACOSX_DEPLOYMENT_TARGET = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=i386]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc64]" = 10.5; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc]" = 10.2; + "MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5; + MACOSX_DEPLOYMENT_TARGET_i386 = 10.4; + MACOSX_DEPLOYMENT_TARGET_ppc = 10.2; + OBJROOT = "$(inherited)/$(PRODUCT_NAME)/$(CURRENT_PROJECT_VERSION)"; + OTHER_CFLAGS_normal = "-D_DEBUG -DPARANOIA -DRANGECHECK"; + PREBINDING = NO; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; + PRODUCT_NAME = SRB2dummy; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + "SDKROOT[arch=i386]" = macosx10.4; + "SDKROOT[arch=ppc]" = macosx10.3.9; + SDKROOT_i386 = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + SDKROOT_ppc = "$(DEVELOPER_SDK_DIR)/MacOSX10.3.9.sdk"; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "$(inherited)/$(PRODUCT_NAME)/$(CURRENT_PROJECT_VERSION)"; + WARNING_CFLAGS = ( + "-Wall", + "-W", + "-Wno-undef", + "-Wpointer-arith", + "-Wbad-function-cast", + "-Wno-cast-qual", + "-Wcast-align", + "-Wwrite-strings", + "-Waggregate-return", + "-Wmissing-prototypes", + "-Wmissing-declarations", + "-Wno-missing-noreturn", + "-Wnested-externs", + "-Winline", + ); + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 0.0.0; + DSTROOT = "$(HOME)/Applications"; + FRAMEWORK_SEARCH_PATHS = ( + "$(HOME)/Library/Frameworks", + /Library/Frameworks, + "$(FRAMEWORK_SEARCH_PATHS)", + ); + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = NO; + GCC_ENABLE_PASCAL_STRINGS = NO; + GCC_FAST_OBJC_DISPATCH = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + "GCC_MODEL_TUNING[arch=ppc]" = G3; + GCC_OPTIMIZATION_LEVEL = 2; + GCC_PREPROCESSOR_DEFINITIONS = ( + MAC_ALERT, + SDLMAIN, + SDL, + HAVE_MIXER, + HAVE_PNG, + HAVE_BLUA, + LUA_USE_POSIX, + COMPVERSION, + ); + GCC_THREADSAFE_STATICS = NO; + GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; + GCC_TREAT_NONCONFORMANT_CODE_ERRORS_AS_WARNINGS = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_VERSION_i386 = 4.0; + GCC_VERSION_ppc0 = 3.3; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_GLOBAL_CONSTRUCTORS = YES; + GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = YES; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + GCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; + GCC_WARN_INHIBIT_ALL_WARNINGS = NO; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_MISSING_PARENTHESES = YES; + GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = NO; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_PEDANTIC = NO; + GCC_WARN_PROTOTYPE_CONVERSION = NO; + GCC_WARN_SHADOW = NO; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_STRICT_SELECTOR_MATCH = YES; + GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VALUE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GGG_MODEL_TUNING_ppc = G3; + HEADER_SEARCH_PATHS = ( + "$(HOME)/Library/Frameworks/SDL.framework/Headers", + /Library/Frameworks/SDL.framework/Headers, + "$(HOME)/Library/Frameworks/SDL_mixer.framework/Headers", + /Library/Frameworks/SDL_mixer.framework/Headers, + "$(HOME)/Library/Frameworks/libz.framework/Headers", + /Library/Frameworks/libz.framework/Headers, + "$(HOME)/Library/Frameworks/libpng.framework/Headers", + /Library/Frameworks/libpng.framework/Headers, + "$(HEADER_SEARCH_PATHS)", + ); + INFOPLIST_FILE = Info.plist; + MACH_O_TYPE = mh_execute; + MACOSX_DEPLOYMENT_TARGET = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=i386]" = 10.4; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc64]" = 10.5; + "MACOSX_DEPLOYMENT_TARGET[arch=ppc]" = 10.2; + "MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5; + MACOSX_DEPLOYMENT_TARGET_i386 = 10.4; + MACOSX_DEPLOYMENT_TARGET_ppc = 10.2; + OBJROOT = "$(inherited)/$(PRODUCT_NAME)/$(CURRENT_PROJECT_VERSION)"; + OTHER_CFLAGS_normal = "-DNDEBUG"; + PREBINDING = NO; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO; + PRODUCT_NAME = SRB2dummy; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + "SDKROOT[arch=i386]" = macosx10.4; + "SDKROOT[arch=ppc]" = macosx10.3.9; + SDKROOT_i386 = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; + SDKROOT_ppc = "$(DEVELOPER_SDK_DIR)/MacOSX10.3.9.sdk"; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "$(inherited)/$(PRODUCT_NAME)/$(CURRENT_PROJECT_VERSION)"; + WARNING_CFLAGS = ( + "-Wall", + "-W", + "-Wno-undef", + "-Wpointer-arith", + "-Wbad-function-cast", + "-Wno-cast-qual", + "-Wcast-align", + "-Wwrite-strings", + "-Waggregate-return", + "-Wmissing-prototypes", + "-Wmissing-declarations", + "-Wno-missing-noreturn", + "-Wnested-externs", + "-Winline", + "-Wno-aggregate-return", + ); + WRAPPER_EXTENSION = app; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Srb2mac" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4B08A954540054247B /* Debug */, + C01FCF4C08A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Srb2mac" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/src/sdl12/macosx/mac_alert.c b/src/sdl12/macosx/mac_alert.c new file mode 100644 index 000000000..455e36509 --- /dev/null +++ b/src/sdl12/macosx/mac_alert.c @@ -0,0 +1,45 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1993-1996 by id Software, Inc. +// Portions Copyright (C) 1998-2000 by DooM Legacy Team. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief Graphical Alerts for MacOSX +/// +/// Shows alerts, since we can't just print these to the screen when +/// launched graphically on a mac. + +#ifdef __APPLE_CC__ + +#include "mac_alert.h" +#include + +int MacShowAlert(const char *title, const char *message, const char *button1, const char *button2, const char *button3) +{ + CFOptionFlags results; + + CFUserNotificationDisplayAlert(0, + kCFUserNotificationStopAlertLevel | kCFUserNotificationNoDefaultButtonFlag, + NULL, NULL, NULL, + CFStringCreateWithCString(NULL, title, kCFStringEncodingASCII), + CFStringCreateWithCString(NULL, message, kCFStringEncodingASCII), + button1 != NULL ? CFStringCreateWithCString(NULL, button1, kCFStringEncodingASCII) : NULL, + button2 != NULL ? CFStringCreateWithCString(NULL, button2, kCFStringEncodingASCII) : NULL, + button3 != NULL ? CFStringCreateWithCString(NULL, button3, kCFStringEncodingASCII) : NULL, + &results); + + return (int)results; +} + +#endif diff --git a/src/sdl12/macosx/mac_alert.h b/src/sdl12/macosx/mac_alert.h new file mode 100644 index 000000000..82a28d120 --- /dev/null +++ b/src/sdl12/macosx/mac_alert.h @@ -0,0 +1,27 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1993-1996 by id Software, Inc. +// Portions Copyright (C) 1998-2000 by DooM Legacy Team. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief Graphical Alerts for MacOSX +/// +/// Shows alerts, since we can't just print these to the screen when +/// launched graphically on a mac. + +#ifdef __APPLE_CC__ + +extern int MacShowAlert(const char *title, const char *message, const char *button1, const char *button2, const char *button3); + +#endif diff --git a/src/sdl12/mixer_sound.c b/src/sdl12/mixer_sound.c new file mode 100644 index 000000000..98159b473 --- /dev/null +++ b/src/sdl12/mixer_sound.c @@ -0,0 +1,824 @@ +/// \file +/// \brief SDL Mixer interface for sound + +#include "../doomdef.h" + +#if defined(SDL) && defined(HAVE_MIXER) && SOUND==SOUND_MIXER + +#include "../sounds.h" +#include "../s_sound.h" +#include "../i_sound.h" +#include "../w_wad.h" +#include "../z_zone.h" +#include "../byteptr.h" + +#ifdef _MSC_VER +#pragma warning(disable : 4214 4244) +#endif +#include "SDL.h" +#ifdef _MSC_VER +#pragma warning(default : 4214 4244) +#endif + +#include "SDL_mixer.h" + +/* This is the version number macro for the current SDL_mixer version: */ +#ifndef SDL_MIXER_COMPILEDVERSION +#define SDL_MIXER_COMPILEDVERSION \ + SDL_VERSIONNUM(MIX_MAJOR_VERSION, MIX_MINOR_VERSION, MIX_PATCHLEVEL) +#endif + +/* This macro will evaluate to true if compiled with SDL_mixer at least X.Y.Z */ +#ifndef SDL_MIXER_VERSION_ATLEAST +#define SDL_MIXER_VERSION_ATLEAST(X, Y, Z) \ + (SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) +#endif + +#ifdef HAVE_LIBGME +#include "gme/gme.h" +#define GME_TREBLE 5.0 +#define GME_BASS 1.0 +#ifdef HAVE_PNG /// TODO: compile with zlib support without libpng + +#define HAVE_ZLIB + +#ifndef _MSC_VER +#ifndef _WII +#ifndef _LARGEFILE64_SOURCE +#define _LARGEFILE64_SOURCE +#endif +#endif +#endif + +#ifndef _LFS64_LARGEFILE +#define _LFS64_LARGEFILE +#endif + +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 0 +#endif + +#include "zlib.h" +#endif +#endif + +UINT8 sound_started = false; + +static boolean midimode; +static Mix_Music *music; +static UINT8 music_volume, midi_volume, sfx_volume; +static float loop_point; + +#ifdef HAVE_LIBGME +static Music_Emu *gme; +static INT32 current_track; +#endif + +void I_StartupSound(void) +{ + I_Assert(!sound_started); + sound_started = true; + + midimode = false; + music = NULL; + music_volume = midi_volume = sfx_volume = 0; + +#if SDL_MIXER_VERSION_ATLEAST(1,2,11) + Mix_Init(MIX_INIT_FLAC|MIX_INIT_MOD|MIX_INIT_MP3|MIX_INIT_OGG); +#endif + Mix_OpenAudio(44100, AUDIO_S16LSB, 2, 2048); + Mix_AllocateChannels(256); +} + +void I_ShutdownSound(void) +{ + I_Assert(sound_started); + sound_started = false; + + Mix_CloseAudio(); +#if SDL_MIXER_VERSION_ATLEAST(1,2,11) + Mix_Quit(); +#endif +#ifdef HAVE_LIBGME + if (gme) + gme_delete(gme); +#endif +} + +void I_UpdateSound(void) +{ +} + +// this is as fast as I can possibly make it. +// sorry. more asm needed. +static Mix_Chunk *ds2chunk(void *stream) +{ + UINT16 ver,freq; + UINT32 samples, i, newsamples; + UINT8 *sound; + + SINT8 *s; + INT16 *d; + INT16 o; + fixed_t step, frac; + + // lump header + ver = READUINT16(stream); // sound version format? + if (ver != 3) // It should be 3 if it's a doomsound... + return NULL; // onos! it's not a doomsound! + freq = READUINT16(stream); + samples = READUINT32(stream); + + // convert from signed 8bit ???hz to signed 16bit 44100hz. + switch(freq) + { + case 44100: + if (samples >= UINT32_MAX>>2) + return NULL; // would wrap, can't store. + newsamples = samples; + break; + case 22050: + if (samples >= UINT32_MAX>>3) + return NULL; // would wrap, can't store. + newsamples = samples<<1; + break; + case 11025: + if (samples >= UINT32_MAX>>4) + return NULL; // would wrap, can't store. + newsamples = samples<<2; + break; + default: + frac = (44100 << FRACBITS) / (UINT32)freq; + if (!(frac & 0xFFFF)) // other solid multiples (change if FRACBITS != 16) + newsamples = samples * (frac >> FRACBITS); + else // strange and unusual fractional frequency steps, plus anything higher than 44100hz. + newsamples = FixedMul(FixedDiv(samples, freq), 44100) + 1; // add 1 to counter truncation. + if (newsamples >= UINT32_MAX>>2) + return NULL; // would and/or did wrap, can't store. + break; + } + sound = Z_Malloc(newsamples<<2, PU_SOUND, NULL); // samples * frequency shift * bytes per sample * channels + + s = (SINT8 *)stream; + d = (INT16 *)sound; + + i = 0; + switch(freq) + { + case 44100: // already at the same rate? well that makes it simple. + while(i++ < samples) + { + o = ((INT16)(*s++)+0x80)<<8; // changed signedness and shift up to 16 bits + *d++ = o; // left channel + *d++ = o; // right channel + } + break; + case 22050: // unwrap 2x + while(i++ < samples) + { + o = ((INT16)(*s++)+0x80)<<8; // changed signedness and shift up to 16 bits + *d++ = o; // left channel + *d++ = o; // right channel + *d++ = o; // left channel + *d++ = o; // right channel + } + break; + case 11025: // unwrap 4x + while(i++ < samples) + { + o = ((INT16)(*s++)+0x80)<<8; // changed signedness and shift up to 16 bits + *d++ = o; // left channel + *d++ = o; // right channel + *d++ = o; // left channel + *d++ = o; // right channel + *d++ = o; // left channel + *d++ = o; // right channel + *d++ = o; // left channel + *d++ = o; // right channel + } + break; + default: // convert arbitrary hz to 44100. + step = 0; + frac = ((UINT32)freq << FRACBITS) / 44100; + while (i < samples) + { + o = (INT16)(*s+0x80)<<8; // changed signedness and shift up to 16 bits + while (step < FRACUNIT) // this is as fast as I can make it. + { + *d++ = o; // left channel + *d++ = o; // right channel + step += frac; + } + do { + i++; s++; + step -= FRACUNIT; + } while (step >= FRACUNIT); + } + break; + } + + // return Mixer Chunk. + return Mix_QuickLoad_RAW(sound, (UINT8*)d-sound); +} + +void *I_GetSfx(sfxinfo_t *sfx) +{ + void *lump; + Mix_Chunk *chunk; +#ifdef HAVE_LIBGME + Music_Emu *emu; + gme_info_t *info; +#endif + + if (sfx->lumpnum == LUMPERROR) + sfx->lumpnum = S_GetSfxLumpNum(sfx); + sfx->length = W_LumpLength(sfx->lumpnum); + + lump = W_CacheLumpNum(sfx->lumpnum, PU_SOUND); + + // convert from standard DoomSound format. + chunk = ds2chunk(lump); + if (chunk) + { + Z_Free(lump); + return chunk; + } + + // Not a doom sound? Try something else. +#ifdef HAVE_LIBGME + // VGZ format + if (((UINT8 *)lump)[0] == 0x1F + && ((UINT8 *)lump)[1] == 0x8B) + { +#ifdef HAVE_ZLIB + UINT8 *inflatedData; + size_t inflatedLen; + z_stream stream; + int zErr; // Somewhere to handle any error messages zlib tosses out + + memset(&stream, 0x00, sizeof (z_stream)); // Init zlib stream + // Begin the inflation process + inflatedLen = *(UINT32 *)lump + (sfx->length-4); // Last 4 bytes are the decompressed size, typically + inflatedData = (UINT8 *)Z_Malloc(inflatedLen, PU_SOUND, NULL); // Make room for the decompressed data + stream.total_in = stream.avail_in = sfx->length; + stream.total_out = stream.avail_out = inflatedLen; + stream.next_in = (UINT8 *)lump; + stream.next_out = inflatedData; + + zErr = inflateInit2(&stream, 32 + MAX_WBITS); + if (zErr == Z_OK) // We're good to go + { + zErr = inflate(&stream, Z_FINISH); + if (zErr == Z_STREAM_END) { + // Run GME on new data + if (!gme_open_data(inflatedData, inflatedLen, &emu, 44100)) + { + short *mem; + UINT32 len; + gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; + + Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around + Z_Free(lump); // We're done with the uninflated lump now, too. + + gme_start_track(emu, 0); + gme_set_equalizer(emu, &eq); + gme_track_info(emu, &info, 0); + + len = (info->play_length * 441 / 10) << 2; + mem = Z_Malloc(len, PU_SOUND, NULL); + gme_play(emu, len >> 1, mem); + gme_delete(emu); + + return Mix_QuickLoad_RAW((Uint8 *)mem, len); + } + } + else + { + const char *errorType; + switch (zErr) + { + case Z_ERRNO: + errorType = "Z_ERRNO"; break; + case Z_STREAM_ERROR: + errorType = "Z_STREAM_ERROR"; break; + case Z_DATA_ERROR: + errorType = "Z_DATA_ERROR"; break; + case Z_MEM_ERROR: + errorType = "Z_MEM_ERROR"; break; + case Z_BUF_ERROR: + errorType = "Z_BUF_ERROR"; break; + case Z_VERSION_ERROR: + errorType = "Z_VERSION_ERROR"; break; + default: + errorType = "unknown error"; + } + CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", errorType, stream.msg); + } + (void)inflateEnd(&stream); + } + else // Hold up, zlib's got a problem + { + const char *errorType; + switch (zErr) + { + case Z_ERRNO: + errorType = "Z_ERRNO"; break; + case Z_STREAM_ERROR: + errorType = "Z_STREAM_ERROR"; break; + case Z_DATA_ERROR: + errorType = "Z_DATA_ERROR"; break; + case Z_MEM_ERROR: + errorType = "Z_MEM_ERROR"; break; + case Z_BUF_ERROR: + errorType = "Z_BUF_ERROR"; break; + case Z_VERSION_ERROR: + errorType = "Z_VERSION_ERROR"; break; + default: + errorType = "unknown error"; + } + CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", errorType, stream.msg); + } + Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up +#else + //CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n"); +#endif + } + // Try to read it as a GME sound + else if (!gme_open_data(lump, sfx->length, &emu, 44100)) + { + short *mem; + UINT32 len; + gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; + + Z_Free(lump); + + gme_start_track(emu, 0); + gme_set_equalizer(emu, &eq); + gme_track_info(emu, &info, 0); + + len = (info->play_length * 441 / 10) << 2; + mem = Z_Malloc(len, PU_SOUND, NULL); + gme_play(emu, len >> 1, mem); + gme_delete(emu); + + return Mix_QuickLoad_RAW((Uint8 *)mem, len); + } +#endif + + // Try to load it as a WAVE or OGG using Mixer. + return Mix_LoadWAV_RW(SDL_RWFromMem(lump, sfx->length), 1); +} + +void I_FreeSfx(sfxinfo_t *sfx) +{ + if (sfx->data) + Mix_FreeChunk(sfx->data); + sfx->data = NULL; +} + +INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) +{ + UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127 + INT32 handle = Mix_PlayChannel(-1, S_sfx[id].data, 0); + Mix_Volume(handle, volume); + Mix_SetPanning(handle, min((UINT16)sep<<1, 0xff), min((UINT16)(0xff-sep)<<1, 0xff)); + (void)pitch; // Mixer can't handle pitch + (void)priority; // priority and channel management is handled by SRB2... + return handle; +} + +void I_StopSound(INT32 handle) +{ + Mix_HaltChannel(handle); +} + +boolean I_SoundIsPlaying(INT32 handle) +{ + return Mix_Playing(handle); +} + +void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch) +{ + UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127 + Mix_Volume(handle, volume); + Mix_SetPanning(handle, min((UINT16)sep<<1, 0xff), min((UINT16)(0xff-sep)<<1, 0xff)); + (void)pitch; +} + +void I_SetSfxVolume(UINT8 volume) +{ + sfx_volume = volume; +} + +// +// Music +// + +// Music hooks +static void music_loop(void) +{ + Mix_PlayMusic(music, 0); + Mix_SetMusicPosition(loop_point); +} + +#ifdef HAVE_LIBGME +static void mix_gme(void *udata, Uint8 *stream, int len) +{ + int i; + short *p; + + (void)udata; + + // no gme? no music. + if (!gme || gme_track_ended(gme)) + return; + + // play gme into stream + gme_play(gme, len/2, (short *)stream); + + // apply volume to stream + for (i = 0, p = (short *)stream; i < len/2; i++, p++) + *p = ((INT32)*p) * music_volume / 31; +} +#endif + +void I_InitMusic(void) +{ +} + +void I_ShutdownMusic(void) +{ + I_ShutdownDigMusic(); + I_ShutdownMIDIMusic(); +} + +void I_PauseSong(INT32 handle) +{ + (void)handle; + Mix_PauseMusic(); +} + +void I_ResumeSong(INT32 handle) +{ + (void)handle; + Mix_ResumeMusic(); +} + +// +// Digital Music +// + +void I_InitDigMusic(void) +{ +#ifdef HAVE_LIBGME + gme = NULL; + current_track = -1; +#endif +} + +void I_ShutdownDigMusic(void) +{ + if (midimode) + return; +#ifdef HAVE_LIBGME + if (gme) + { + Mix_HookMusic(NULL, NULL); + gme_delete(gme); + gme = NULL; + } +#endif + if (!music) + return; + Mix_HookMusicFinished(NULL); + Mix_FreeMusic(music); + music = NULL; +} + +boolean I_StartDigSong(const char *musicname, boolean looping) +{ + char *data; + size_t len; + lumpnum_t lumpnum = W_CheckNumForName(va("O_%s",musicname)); + + I_Assert(!music); +#ifdef HAVE_LIBGME + I_Assert(!gme); +#endif + + if (lumpnum == LUMPERROR) + { + lumpnum = W_CheckNumForName(va("D_%s",musicname)); + if (lumpnum == LUMPERROR) + return false; + midimode = true; + } + else + midimode = false; + + data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC); + len = W_LumpLength(lumpnum); + +#ifdef HAVE_LIBGME + if ((UINT8)data[0] == 0x1F + && (UINT8)data[1] == 0x8B) + { +#ifdef HAVE_ZLIB + UINT8 *inflatedData; + size_t inflatedLen; + z_stream stream; + int zErr; // Somewhere to handle any error messages zlib tosses out + + memset(&stream, 0x00, sizeof (z_stream)); // Init zlib stream + // Begin the inflation process + inflatedLen = *(UINT32 *)(data + (len-4)); // Last 4 bytes are the decompressed size, typically + inflatedData = (UINT8 *)Z_Calloc(inflatedLen, PU_MUSIC, NULL); // Make room for the decompressed data + stream.total_in = stream.avail_in = len; + stream.total_out = stream.avail_out = inflatedLen; + stream.next_in = (UINT8 *)data; + stream.next_out = inflatedData; + + zErr = inflateInit2(&stream, 32 + MAX_WBITS); + if (zErr == Z_OK) // We're good to go + { + zErr = inflate(&stream, Z_FINISH); + if (zErr == Z_STREAM_END) { + // Run GME on new data + if (!gme_open_data(inflatedData, inflatedLen, &gme, 44100)) + { + gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; + gme_start_track(gme, 0); + current_track = 0; + gme_set_equalizer(gme, &eq); + Mix_HookMusic(mix_gme, gme); + Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around + return true; + } + } + else + { + const char *errorType; + switch (zErr) + { + case Z_ERRNO: + errorType = "Z_ERRNO"; break; + case Z_STREAM_ERROR: + errorType = "Z_STREAM_ERROR"; break; + case Z_DATA_ERROR: + errorType = "Z_DATA_ERROR"; break; + case Z_MEM_ERROR: + errorType = "Z_MEM_ERROR"; break; + case Z_BUF_ERROR: + errorType = "Z_BUF_ERROR"; break; + case Z_VERSION_ERROR: + errorType = "Z_VERSION_ERROR"; break; + default: + errorType = "unknown error"; + } + CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", errorType, stream.msg); + } + (void)inflateEnd(&stream); + } + else // Hold up, zlib's got a problem + { + const char *errorType; + switch (zErr) + { + case Z_ERRNO: + errorType = "Z_ERRNO"; break; + case Z_STREAM_ERROR: + errorType = "Z_STREAM_ERROR"; break; + case Z_DATA_ERROR: + errorType = "Z_DATA_ERROR"; break; + case Z_MEM_ERROR: + errorType = "Z_MEM_ERROR"; break; + case Z_BUF_ERROR: + errorType = "Z_BUF_ERROR"; break; + case Z_VERSION_ERROR: + errorType = "Z_VERSION_ERROR"; break; + default: + errorType = "unknown error"; + } + CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", errorType, stream.msg); + } + Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up +#else + //CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n"); +#endif + } + else if (!gme_open_data(data, len, &gme, 44100)) + { + gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; + gme_start_track(gme, 0); + current_track = 0; + gme_set_equalizer(gme, &eq); + Mix_HookMusic(mix_gme, gme); + return true; + } +#endif + + music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len)); + if (!music) + { + CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError()); + return true; + } + + // Find the OGG loop point. + loop_point = 0.0f; + if (looping) + { + const char *key1 = "LOOP"; + const char *key2 = "POINT="; + const char *key3 = "MS="; + const UINT8 key1len = strlen(key1); + const UINT8 key2len = strlen(key2); + const UINT8 key3len = strlen(key3); + char *p = data; + while ((UINT32)(p - data) < len) + { + if (strncmp(p++, key1, key1len)) + continue; + p += key1len-1; // skip OOP (the L was skipped in strncmp) + if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=? + { + p += key2len; // skip POINT= + loop_point = (float)((44.1L+atoi(p)) / 44100.0L); // LOOPPOINT works by sample count. + // because SDL_Mixer is USELESS and can't even tell us + // something simple like the frequency of the streaming music, + // we are unfortunately forced to assume that ALL MUSIC is 44100hz. + // This means a lot of tracks that are only 22050hz for a reasonable downloadable file size will loop VERY badly. + } + else if (!strncmp(p, key3, key3len)) // is it LOOPMS=? + { + p += key3len; // skip MS= + loop_point = atoi(p) / 1000.0L; // LOOPMS works by real time, as miliseconds. + // Everything that uses LOOPMS will work perfectly with SDL_Mixer. + } + // Neither?! Continue searching. + } + } + + if (Mix_PlayMusic(music, looping && loop_point == 0.0f ? -1 : 0) == -1) + { + CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError()); + return true; + } + if (midimode) + Mix_VolumeMusic((UINT32)midi_volume*128/31); + else + Mix_VolumeMusic((UINT32)music_volume*128/31); + + if (loop_point != 0.0f) + Mix_HookMusicFinished(music_loop); + return true; +} + +void I_StopDigSong(void) +{ + if (midimode) + return; +#ifdef HAVE_LIBGME + if (gme) + { + Mix_HookMusic(NULL, NULL); + gme_delete(gme); + gme = NULL; + current_track = -1; + return; + } +#endif + if (!music) + return; + Mix_HookMusicFinished(NULL); + Mix_FreeMusic(music); + music = NULL; +} + +void I_SetDigMusicVolume(UINT8 volume) +{ + music_volume = volume; + if (midimode || !music) + return; + Mix_VolumeMusic((UINT32)volume*128/31); +} + +boolean I_SetSongSpeed(float speed) +{ + if (speed > 250.0f) + speed = 250.0f; //limit speed up to 250x +#ifdef HAVE_LIBGME + if (gme) + { + SDL_LockAudio(); + gme_set_tempo(gme, speed); + SDL_UnlockAudio(); + return true; + } +#else + (void)speed; +#endif + return false; +} + +boolean I_SetSongTrack(int track) +{ +#ifdef HAVE_LIBGME + if (current_track == track) + return false; + + // If the specified track is within the number of tracks playing, then change it + if (gme) + { + SDL_LockAudio(); + if (track >= 0 + && track < gme_track_count(gme)) + { + gme_err_t gme_e = gme_start_track(gme, track); + if (gme_e != NULL) + { + CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e); + return false; + } + current_track = track; + SDL_UnlockAudio(); + return true; + } + SDL_UnlockAudio(); + return false; + } +#endif + (void)track; + return false; +} + +// +// MIDI Music +// + +void I_InitMIDIMusic(void) +{ +} + +void I_ShutdownMIDIMusic(void) +{ + if (!midimode || !music) + return; + Mix_FreeMusic(music); + music = NULL; +} + +void I_SetMIDIMusicVolume(UINT8 volume) +{ + midi_volume = volume; + if (!midimode || !music) + return; + Mix_VolumeMusic((UINT32)volume*128/31); +} + +INT32 I_RegisterSong(void *data, size_t len) +{ + music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len)); + if (!music) + { + CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError()); + return -1; + } + return 1337; +} + +boolean I_PlaySong(INT32 handle, boolean looping) +{ + (void)handle; + + midimode = true; + + if (Mix_PlayMusic(music, looping ? -1 : 0) == -1) + { + CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError()); + return false; + } + Mix_VolumeMusic((UINT32)music_volume*128/31); + return true; +} + +void I_StopSong(INT32 handle) +{ + if (!midimode || !music) + return; + + (void)handle; + Mix_HaltMusic(); +} + +void I_UnRegisterSong(INT32 handle) +{ + if (!midimode || !music) + return; + + (void)handle; + Mix_FreeMusic(music); + music = NULL; +} + +#endif diff --git a/src/sdl12/ogl_sdl.c b/src/sdl12/ogl_sdl.c new file mode 100644 index 000000000..9427d3317 --- /dev/null +++ b/src/sdl12/ogl_sdl.c @@ -0,0 +1,315 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1998-2000 by DooM Legacy Team. +// +// 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. +// +//----------------------------------------------------------------------------- +/// \file +/// \brief SDL specific part of the OpenGL API for SRB2 + +#ifdef _MSC_VER +#pragma warning(disable : 4214 4244) +#endif + +#ifdef SDL + +#include "SDL.h" + +#ifdef _MSC_VER +#pragma warning(default : 4214 4244) +#endif + +#include "../doomdef.h" + +#ifdef HWRENDER +#include "../hardware/r_opengl/r_opengl.h" +#include "ogl_sdl.h" +#include "../i_system.h" +#include "hwsym_sdl.h" +#include "../m_argv.h" + +#ifdef DEBUG_TO_FILE +#include +#if defined (_WIN32) && !defined (__CYGWIN__) +#include +#else +#include +#endif +#include +#include +#endif + +#ifdef USE_WGL_SWAP +PFNWGLEXTSWAPCONTROLPROC wglSwapIntervalEXT = NULL; +#else +typedef int (*PFNGLXSWAPINTERVALPROC) (int); +PFNGLXSWAPINTERVALPROC glXSwapIntervalSGIEXT = NULL; +#endif + +#ifndef STATIC_OPENGL +PFNglClear pglClear; +PFNglGetIntegerv pglGetIntegerv; +PFNglGetString pglGetString; +#endif + +#ifdef _PSP +static const Uint32 WOGLFlags = SDL_HWSURFACE|SDL_OPENGL/*|SDL_RESIZABLE*/; +static const Uint32 FOGLFlags = SDL_HWSURFACE|SDL_OPENGL|SDL_FULLSCREEN; +#else +static const Uint32 WOGLFlags = SDL_OPENGL/*|SDL_RESIZABLE*/; +static const Uint32 FOGLFlags = SDL_OPENGL|SDL_FULLSCREEN; +#endif + +/** \brief SDL video display surface +*/ +SDL_Surface *vidSurface = NULL; +INT32 oglflags = 0; +void *GLUhandle = NULL; + +#ifndef STATIC_OPENGL +void *GetGLFunc(const char *proc) +{ + if (strncmp(proc, "glu", 3) == 0) + { + if (GLUhandle) + return hwSym(proc, GLUhandle); + else + return NULL; + } + return SDL_GL_GetProcAddress(proc); +} +#endif + +boolean LoadGL(void) +{ +#ifndef STATIC_OPENGL + const char *OGLLibname = NULL; + const char *GLULibname = NULL; + + if (M_CheckParm ("-OGLlib") && M_IsNextParm()) + OGLLibname = M_GetNextParm(); + + if (SDL_GL_LoadLibrary(OGLLibname) != 0) + { + I_OutputMsg("Could not load OpenGL Library: %s\n" + "Falling back to Software mode.\n", SDL_GetError()); + if (!M_CheckParm ("-OGLlib")) + I_OutputMsg("If you know what is the OpenGL library's name, use -OGLlib\n"); + return 0; + } + +#if 0 + GLULibname = "/proc/self/exe"; +#elif defined (_WIN32) + GLULibname = "GLU32.DLL"; +#elif defined (__MACH__) + GLULibname = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib"; +#elif defined (macintos) + GLULibname = "OpenGLLibrary"; +#elif defined (__unix__) + GLULibname = "libGLU.so.1"; +#elif defined (__HAIKU__) + GLULibname = "libGLU.so"; +#else + GLULibname = NULL; +#endif + + if (M_CheckParm ("-GLUlib") && M_IsNextParm()) + GLULibname = M_GetNextParm(); + + if (GLULibname) + { + GLUhandle = hwOpen(GLULibname); + if (GLUhandle) + return SetupGLfunc(); + else + { + I_OutputMsg("Could not load GLU Library: %s\n", GLULibname); + if (!M_CheckParm ("-GLUlib")) + I_OutputMsg("If you know what is the GLU library's name, use -GLUlib\n"); + } + } + else + { + I_OutputMsg("Could not load GLU Library\n"); + I_OutputMsg("If you know what is the GLU library's name, use -GLUlib\n"); + } +#endif + return SetupGLfunc(); +} + +/** \brief The OglSdlSurface function + + \param w width + \param h height + \param isFullscreen if true, go fullscreen + + \return if true, changed video mode +*/ +boolean OglSdlSurface(INT32 w, INT32 h, boolean isFullscreen) +{ + INT32 cbpp; + Uint32 OGLFlags; + const GLvoid *glvendor = NULL, *glrenderer = NULL, *glversion = NULL; + + cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value; + + if (vidSurface) + { + //Alam: SDL_Video system free vidSurface for me +#ifdef VOODOOSAFESWITCHING + SDL_QuitSubSystem(SDL_INIT_VIDEO); + SDL_InitSubSystem(SDL_INIT_VIDEO); +#endif + } + + if (isFullscreen) + OGLFlags = FOGLFlags; + else + OGLFlags = WOGLFlags; + + cbpp = SDL_VideoModeOK(w, h, cbpp, OGLFlags); + if (cbpp < 16) + return true; //Alam: Let just say we did, ok? + + vidSurface = SDL_SetVideoMode(w, h, cbpp, OGLFlags); + if (!vidSurface) + return false; + + glvendor = pglGetString(GL_VENDOR); + // Get info and extensions. + //BP: why don't we make it earlier ? + //Hurdler: we cannot do that before intialising gl context + glrenderer = pglGetString(GL_RENDERER); + glversion = pglGetString(GL_VERSION); + gl_extensions = pglGetString(GL_EXTENSIONS); + + DBG_Printf("Vendor : %s\n", glvendor); + DBG_Printf("Renderer : %s\n", glrenderer); + DBG_Printf("Version : %s\n", glversion); + DBG_Printf("Extensions : %s\n", gl_extensions); + oglflags = 0; + +#ifdef _WIN32 + // BP: disable advenced feature that don't work on somes hardware + // Hurdler: Now works on G400 with bios 1.6 and certified drivers 6.04 + if (strstr(glrenderer, "810")) oglflags |= GLF_NOZBUFREAD; +#elif defined (unix) || defined (UNIXCOMMON) + // disable advanced features not working on somes hardware + if (strstr(glrenderer, "G200")) oglflags |= GLF_NOTEXENV; + if (strstr(glrenderer, "G400")) oglflags |= GLF_NOTEXENV; +#endif + DBG_Printf("oglflags : 0x%X\n", oglflags ); + +#ifdef USE_PALETTED_TEXTURE + if (isExtAvailable("GL_EXT_paletted_texture", gl_extensions)) + glColorTableEXT = SDL_GL_GetProcAddress("glColorTableEXT"); + else + glColorTableEXT = NULL; +#endif + +#ifdef USE_WGL_SWAP + if (isExtAvailable("WGL_EXT_swap_control", gl_extensions)) + wglSwapIntervalEXT = SDL_GL_GetProcAddress("wglSwapIntervalEXT"); + else + wglSwapIntervalEXT = NULL; +#else + if (isExtAvailable("GLX_SGI_swap_control", gl_extensions)) + glXSwapIntervalSGIEXT = SDL_GL_GetProcAddress("glXSwapIntervalSGI"); + else + glXSwapIntervalSGIEXT = NULL; +#endif + +#ifndef KOS_GL_COMPATIBILITY + if (isExtAvailable("GL_EXT_texture_filter_anisotropic", gl_extensions)) + pglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnisotropy); + else +#endif + maximumAnisotropy = 0; + + granisotropicmode_cons_t[1].value = maximumAnisotropy; + + SetModelView(w, h); + SetStates(); + pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + HWR_Startup(); +#ifdef KOS_GL_COMPATIBILITY + textureformatGL = GL_ARGB4444; +#else + textureformatGL = cbpp > 16 ? GL_RGBA : GL_RGB5_A1; +#endif + + return true; +} + +/** \brief The OglSdlFinishUpdate function + + \param vidwait wait for video sync + + \return void +*/ +void OglSdlFinishUpdate(boolean waitvbl) +{ + static boolean oldwaitvbl = false; + if (oldwaitvbl != waitvbl) + { +#ifdef USE_WGL_SWAP + if (wglSwapIntervalEXT) + wglSwapIntervalEXT(waitvbl); +#else + if (glXSwapIntervalSGIEXT) + glXSwapIntervalSGIEXT(waitvbl); +#endif + } + oldwaitvbl = waitvbl; + + SDL_GL_SwapBuffers(); +} + +EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma) +{ + INT32 i = -1; + UINT32 redgamma = pgamma->s.red, greengamma = pgamma->s.green, + bluegamma = pgamma->s.blue; + +#if 0 // changing the gamma to 127 is a bad idea + i = SDL_SetGamma(byteasfloat(redgamma), byteasfloat(greengamma), byteasfloat(bluegamma)); +#endif + if (i == 0) redgamma = greengamma = bluegamma = 0x7F; //Alam: cool + for (i = 0; i < 256; i++) + { + myPaletteData[i].s.red = (UINT8)MIN((palette[i].s.red * redgamma) /127, 255); + myPaletteData[i].s.green = (UINT8)MIN((palette[i].s.green * greengamma)/127, 255); + myPaletteData[i].s.blue = (UINT8)MIN((palette[i].s.blue * bluegamma) /127, 255); + myPaletteData[i].s.alpha = palette[i].s.alpha; + } +#ifdef USE_PALETTED_TEXTURE + if (glColorTableEXT) + { + for (i = 0; i < 256; i++) + { + palette_tex[(3*i)+0] = palette[i].s.red; + palette_tex[(3*i)+1] = palette[i].s.green; + palette_tex[(3*i)+2] = palette[i].s.blue; + } + glColorTableEXT(GL_TEXTURE_2D, GL_RGB8, 256, GL_RGB, GL_UNSIGNED_BYTE, palette_tex); + } +#endif + // on a chang�de palette, il faut recharger toutes les textures + // jaja, und noch viel mehr ;-) + Flush(); +} + +#endif //HWRENDER +#endif //SDL diff --git a/src/sdl12/ogl_sdl.h b/src/sdl12/ogl_sdl.h new file mode 100644 index 000000000..43c28fa42 --- /dev/null +++ b/src/sdl12/ogl_sdl.h @@ -0,0 +1,30 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1998-2000 by DooM Legacy Team. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief SDL specific part of the OpenGL API for SRB2 + +#include "../v_video.h" + +extern SDL_Surface *vidSurface; +extern void *GLUhandle; + +boolean OglSdlSurface(INT32 w, INT32 h, boolean isFullscreen); + +void OglSdlFinishUpdate(boolean vidwait); + +#ifdef _CREATE_DLL_ +EXPORT void HWRAPI( OglSdlSetPalette ) (RGBA_t *palette, RGBA_t *pgamma); +#endif diff --git a/src/sdl12/sdl_sound.c b/src/sdl12/sdl_sound.c new file mode 100644 index 000000000..3750e6778 --- /dev/null +++ b/src/sdl12/sdl_sound.c @@ -0,0 +1,2030 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 1993-1996 by 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. +// +// The source 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief SDL interface for sound + +#include +#include "../doomdef.h" + +#ifdef _MSC_VER +#pragma warning(disable : 4214 4244) +#endif + +#if defined(SDL) && SOUND==SOUND_SDL + +#include "SDL.h" + +#ifdef _MSC_VER +#pragma warning(default : 4214 4244) +#endif + +#ifdef HAVE_MIXER +#include "SDL_mixer.h" +/* This is the version number macro for the current SDL_mixer version: */ +#ifndef SDL_MIXER_COMPILEDVERSION +#define SDL_MIXER_COMPILEDVERSION \ + SDL_VERSIONNUM(MIX_MAJOR_VERSION, MIX_MINOR_VERSION, MIX_PATCHLEVEL) +#endif + +/* This macro will evaluate to true if compiled with SDL_mixer at least X.Y.Z */ +#ifndef SDL_MIXER_VERSION_ATLEAST +#define SDL_MIXER_VERSION_ATLEAST(X, Y, Z) \ + (SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) +#endif + +#else +#define MIX_CHANNELS 8 +#endif + +#if defined (_WIN32) && !defined (_WIN32_WCE) && !defined (_XBOX) +#include +#elif defined (__GNUC__) +#include +#endif +#include "../z_zone.h" + +#include "../m_swap.h" +#include "../i_system.h" +#include "../i_sound.h" +#include "../m_argv.h" +#include "../m_misc.h" +#include "../w_wad.h" +#include "../screen.h" //vid.WndParent +#include "../doomdef.h" +#include "../doomstat.h" +#include "../s_sound.h" + +#include "../d_main.h" + +#ifdef HW3SOUND +#include "../hardware/hw3dsdrv.h" +#include "../hardware/hw3sound.h" +#include "hwsym_sdl.h" +#endif + +#ifdef HAVE_LIBGME +#include "gme/gme.h" +#endif + +// The number of internal mixing channels, +// the samples calculated for each mixing step, +// the size of the 16bit, 2 hardware channel (stereo) +// mixing buffer, and the samplerate of the raw data. + +// Needed for calling the actual sound output. +#if defined (_WIN32_WCE) || defined (DC) || defined (PSP) || defined(GP2X) +#define NUM_CHANNELS MIX_CHANNELS +#else +#define NUM_CHANNELS MIX_CHANNELS*4 +#endif + +#define INDEXOFSFX(x) ((sfxinfo_t *)x - S_sfx) + +#if defined (_WIN32_WCE) || defined (DC) || defined (PSP) +static Uint16 samplecount = 512; //Alam: .5KB samplecount at 11025hz is 46.439909297052154195011337868481ms of buffer +#elif defined(GP2X) +static Uint16 samplecount = 128; +#else +static Uint16 samplecount = 1024; //Alam: 1KB samplecount at 22050hz is 46.439909297052154195011337868481ms of buffer +#endif + +typedef struct chan_struct +{ + // The channel data pointers, start and end. + Uint8 *data; //static unsigned char *channels[NUM_CHANNELS]; + Uint8 *end; //static unsigned char *channelsend[NUM_CHANNELS]; + + // pitch + Uint32 realstep; // The channel step amount... + Uint32 step; //static UINT32 channelstep[NUM_CHANNELS]; + Uint32 stepremainder; //static UINT32 channelstepremainder[NUM_CHANNELS]; + Uint32 samplerate; // ... and a 0.16 bit remainder of last step. + + // Time/gametic that the channel started playing, + // used to determine oldest, which automatically + // has lowest priority. + tic_t starttic; //static INT32 channelstart[NUM_CHANNELS]; + + // The sound handle, determined on registration, + // used to unregister/stop/modify, + INT32 handle; //static INT32 channelhandles[NUM_CHANNELS]; + + // SFX id of the playing sound effect. + void *id; // Used to catch duplicates (like chainsaw). + sfxenum_t sfxid; //static INT32 channelids[NUM_CHANNELS]; + INT32 vol; //the channel volume + INT32 sep; //the channel pan + + // Hardware left and right channel volume lookup. + Sint16* leftvol_lookup; //static INT32 *channelleftvol_lookup[NUM_CHANNELS]; + Sint16* rightvol_lookup; //static INT32 *channelrightvol_lookup[NUM_CHANNELS]; +} chan_t; + +static chan_t channels[NUM_CHANNELS]; + +// Pitch to stepping lookup +static INT32 steptable[256]; + +// Volume lookups. +static Sint16 vol_lookup[128 * 256]; + +UINT8 sound_started = false; +static SDL_mutex *Snd_Mutex = NULL; + +//SDL's Audio +static SDL_AudioSpec audio; + +static SDL_bool musicStarted = SDL_FALSE; +#ifdef HAVE_MIXER +static SDL_mutex *Msc_Mutex = NULL; +/* FIXME: Make this file instance-specific */ +#ifdef _arch_dreamcast +#define MIDI_PATH "/ram" +#elif defined(GP2X) +#define MIDI_PATH "/mnt/sd/srb2" +#define MIDI_PATH2 "/tmp/mnt/sd/srb2" +#else +#define MIDI_PATH srb2home +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#define MIDI_PATH2 "/tmp" +#endif +#endif +#define MIDI_TMPFILE "srb2music" +#define MIDI_TMPFILE2 "srb2wav" +static INT32 musicvol = 62; + +#if SDL_MIXER_VERSION_ATLEAST(1,2,2) +#define MIXER_POS //Mix_FadeInMusicPos in 1.2.2+ +static void SDLCALL I_FinishMusic(void); +static double loopstartDig = 0.0l; +static SDL_bool loopingDig = SDL_FALSE; +static SDL_bool canlooping = SDL_TRUE; +#endif + +#if SDL_MIXER_VERSION_ATLEAST(1,2,7) +#define USE_RWOPS // ok, USE_RWOPS is in here +#if defined (DC) || defined (_WIN32_WCE) || defined (_XBOX) //|| defined(_WIN32) || defined(GP2X) +#undef USE_RWOPS +#endif +#endif + +#if SDL_MIXER_VERSION_ATLEAST(1,2,10) +//#define MIXER_INIT +#endif + +#ifdef USE_RWOPS +static void * Smidi[2] = { NULL, NULL }; +static SDL_bool canuseRW = SDL_TRUE; +#endif +static const char *fmidi[2] = { MIDI_TMPFILE, MIDI_TMPFILE2}; + +static const INT32 MIDIfade = 500; +static const INT32 Digfade = 0; + +static Mix_Music *music[2] = { NULL, NULL }; +#endif + +typedef struct srb2audio_s { + void *userdata; +#ifdef HAVE_LIBGME + Music_Emu *gme_emu; + UINT8 gme_pause; + UINT8 gme_loop; +#endif +} srb2audio_t; + +static srb2audio_t localdata; + +static void Snd_LockAudio(void) //Alam: Lock audio data and uninstall audio callback +{ + if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); + else if (nosound) return; + else if (nomidimusic && nodigimusic +#ifdef HW3SOUND + && hws_mode == HWS_DEFAULT_MODE +#endif + ) SDL_LockAudio(); +#ifdef HAVE_MIXER + else if (musicStarted) Mix_SetPostMix(NULL, NULL); +#endif +} + +static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio callback +{ + if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); + else if (nosound) return; + else if (nomidimusic && nodigimusic +#ifdef HW3SOUND + && hws_mode == HWS_DEFAULT_MODE +#endif + ) SDL_UnlockAudio(); +#ifdef HAVE_MIXER + else if (musicStarted) Mix_SetPostMix(audio.callback, audio.userdata); +#endif +} + +FUNCMATH static inline Uint16 Snd_LowerRate(Uint16 sr) +{ + if (sr <= audio.freq) // already lowered rate? + return sr; // good then + for (;sr > audio.freq;) // not good? + { // then let see... + if (sr % 2) // can we div by half? + return sr; // no, just use the currect rate + sr /= 2; // we can? wonderful + } // let start over again + if (sr == audio.freq) // did we drop to the desired rate? + return sr; // perfect! but if not + return sr*2; // just keep it just above the output sample rate +} + +#ifdef _MSC_VER +#pragma warning(disable : 4200) +#pragma pack(1) +#endif + +typedef struct +{ + Uint16 header; // 3? + Uint16 samplerate; // 11025+ + Uint16 samples; // number of samples + Uint16 dummy; // 0 + Uint8 data[0]; // data; +} ATTRPACK dssfx_t; + +#ifdef _MSC_VER +#pragma pack() +#pragma warning(default : 4200) +#endif + +// +// This function loads the sound data from the WAD lump, +// for single sound. +// +static void *getsfx(lumpnum_t sfxlump, size_t *len) +{ + dssfx_t *sfx, *paddedsfx; + Uint16 sr , csr; + size_t size = *len; + SDL_AudioCVT sfxcvt; + + sfx = (dssfx_t *)malloc(size); + if (sfx) W_ReadLump(sfxlump, (void *)sfx); + else return NULL; + sr = SHORT(sfx->samplerate); + csr = Snd_LowerRate(sr); + + if (sr > csr && SDL_BuildAudioCVT(&sfxcvt, AUDIO_U8, 1, sr, AUDIO_U8, 1, csr)) + {//Alam: Setup the AudioCVT for the SFX + + sfxcvt.len = (INT32)size-8; //Alam: Chop off the header + sfxcvt.buf = malloc(sfxcvt.len * sfxcvt.len_mult); //Alam: make room + if (sfxcvt.buf) M_Memcpy(sfxcvt.buf, &(sfx->data), sfxcvt.len); //Alam: copy the sfx sample + + if (sfxcvt.buf && SDL_ConvertAudio(&sfxcvt) == 0) //Alam: let convert it! + { + size = sfxcvt.len_cvt + 8; + *len = sfxcvt.len_cvt; + + // Allocate from zone memory. + paddedsfx = (dssfx_t *) Z_Malloc(size, PU_SOUND, NULL); + + // Now copy and pad. + M_Memcpy(paddedsfx->data, sfxcvt.buf, sfxcvt.len_cvt); + free(sfxcvt.buf); + M_Memcpy(paddedsfx,sfx,8); + paddedsfx->samplerate = SHORT(csr); // new freq + } + else //Alam: the convert failed, not needed or I couldn't malloc the buf + { + if (sfxcvt.buf) free(sfxcvt.buf); + *len = size - 8; + + // Allocate from zone memory then copy and pad + paddedsfx = (dssfx_t *)M_Memcpy(Z_Malloc(size, PU_SOUND, NULL), sfx, size); + } + } + else + { + // Pads the sound effect out to the mixing buffer size. + // The original realloc would interfere with zone memory. + *len = size - 8; + + // Allocate from zone memory then copy and pad + paddedsfx = (dssfx_t *)M_Memcpy(Z_Malloc(size, PU_SOUND, NULL), sfx, size); + } + + // Remove the cached lump. + free(sfx); + + // Return allocated padded data. + return paddedsfx; +} + +// used to (re)calculate channel params based on vol, sep, pitch +static void I_SetChannelParams(chan_t *c, INT32 vol, INT32 sep, INT32 step) +{ + INT32 leftvol; + INT32 rightvol; + c->vol = vol; + c->sep = sep; + c->step = c->realstep = step; + + if (step != steptable[128]) + c->step += (((c->samplerate<<16)/audio.freq)-65536); + else if (c->samplerate != (unsigned)audio.freq) + c->step = ((c->samplerate<<16)/audio.freq); + // x^2 separation, that is, orientation/stereo. + // range is: 0 (left) - 255 (right) + + // Volume arrives in range 0..255 and it must be in 0..cv_soundvolume... + vol = (vol * cv_soundvolume.value) >> 7; + // note: >> 6 would use almost the entire dynamical range, but + // then there would be no "dynamical room" for other sounds :-/ + + leftvol = vol - ((vol*sep*sep) >> 16); ///(256*256); + sep = 255 - sep; + rightvol = vol - ((vol*sep*sep) >> 16); + + // Sanity check, clamp volume. + if (rightvol < 0) + rightvol = 0; + else if (rightvol > 127) + rightvol = 127; + if (leftvol < 0) + leftvol = 0; + else if (leftvol > 127) + leftvol = 127; + + // Get the proper lookup table piece + // for this volume level + c->leftvol_lookup = &vol_lookup[leftvol*256]; + c->rightvol_lookup = &vol_lookup[rightvol*256]; +} + +static INT32 FindChannel(INT32 handle) +{ + INT32 i; + + for (i = 0; i < NUM_CHANNELS; i++) + if (channels[i].handle == handle) + return i; + + // not found + return -1; +} + +// +// This function adds a sound to the +// list of currently active sounds, +// which is maintained as a given number +// (eight, usually) of internal channels. +// Returns a handle. +// +static INT32 addsfx(sfxenum_t sfxid, INT32 volume, INT32 step, INT32 seperation) +{ + static UINT16 handlenums = 0; + INT32 i, slot, oldestnum = 0; + tic_t oldest = gametic; + + // Play these sound effects only one at a time. +#if 1 + if ( +#if 0 + sfxid == sfx_stnmov || sfxid == sfx_sawup || sfxid == sfx_sawidl || sfxid == sfx_sawful || sfxid == sfx_sawhit || sfxid == sfx_pistol +#else + ( sfx_litng1 <= sfxid && sfxid >= sfx_litng4 ) + || sfxid == sfx_trfire || sfxid == sfx_alarm || sfxid == sfx_spin + || sfxid == sfx_athun1 || sfxid == sfx_athun2 || sfxid == sfx_rainin +#endif + ) + { + // Loop all channels, check. + for (i = 0; i < NUM_CHANNELS; i++) + { + // Active, and using the same SFX? + if ((channels[i].end) && (channels[i].sfxid == sfxid)) + { + // Reset. + channels[i].end = NULL; + // We are sure that iff, + // there will only be one. + break; + } + } + } +#endif + + // Loop all channels to find oldest SFX. + for (i = 0; (i < NUM_CHANNELS) && (channels[i].end); i++) + { + if (channels[i].starttic < oldest) + { + oldestnum = i; + oldest = channels[i].starttic; + } + } + + // Tales from the cryptic. + // If we found a channel, fine. + // If not, we simply overwrite the first one, 0. + // Probably only happens at startup. + if (i == NUM_CHANNELS) + slot = oldestnum; + else + slot = i; + + channels[slot].end = NULL; + // Okay, in the less recent channel, + // we will handle the new SFX. + // Set pointer to raw data. + channels[slot].data = (Uint8 *)S_sfx[sfxid].data; + channels[slot].samplerate = (channels[slot].data[3]<<8)+channels[slot].data[2]; + channels[slot].data += 8; //Alam: offset of the sound header + + while (FindChannel(handlenums)!=-1) + { + handlenums++; + // Reset current handle number, limited to 0..65535. + if (handlenums == UINT16_MAX) + handlenums = 0; + } + + // Assign current handle number. + // Preserved so sounds could be stopped. + channels[slot].handle = handlenums; + + // Restart steper + channels[slot].stepremainder = 0; + // Should be gametic, I presume. + channels[slot].starttic = gametic; + + I_SetChannelParams(&channels[slot], volume, seperation, step); + + // Preserve sound SFX id, + // e.g. for avoiding duplicates of chainsaw. + channels[slot].id = S_sfx[sfxid].data; + + channels[slot].sfxid = sfxid; + + // Set pointer to end of raw data. + channels[slot].end = channels[slot].data + S_sfx[sfxid].length; + + + // You tell me. + return handlenums; +} + +// +// SFX API +// Note: this was called by S_Init. +// However, whatever they did in the +// old DPMS based DOS version, this +// were simply dummies in the Linux +// version. +// See soundserver initdata(). +// +// Well... To keep compatibility with legacy doom, I have to call this in +// I_InitSound since it is not called in S_Init... (emanne@absysteme.fr) + +static inline void I_SetChannels(void) +{ + // Init internal lookups (raw data, mixing buffer, channels). + // This function sets up internal lookups used during + // the mixing process. + INT32 i; + INT32 j; + + INT32 *steptablemid = steptable + 128; + + if (nosound) + return; + + // This table provides step widths for pitch parameters. + for (i = -128; i < 128; i++) + { + const double po = pow((double)(2.0l), (double)(i / 64.0l)); + steptablemid[i] = (INT32)(po * 65536.0l); + } + + // Generates volume lookup tables + // which also turn the unsigned samples + // into signed samples. + for (i = 0; i < 128; i++) + for (j = 0; j < 256; j++) + { + //From PrDoom + // proff - made this a little bit softer, because with + // full volume the sound clipped badly + vol_lookup[i * 256 + j] = (Sint16)((i * (j - 128) * 256) / 127); + } +} + +void I_SetSfxVolume(UINT8 volume) +{ + INT32 i; + + (void)volume; + //Snd_LockAudio(); + + for (i = 0; i < NUM_CHANNELS; i++) + if (channels[i].end) I_SetChannelParams(&channels[i], channels[i].vol, channels[i].sep, channels[i].realstep); + + //Snd_UnlockAudio(); +} + +void *I_GetSfx(sfxinfo_t *sfx) +{ + if (sfx->lumpnum == LUMPERROR) + sfx->lumpnum = S_GetSfxLumpNum(sfx); +// else if (sfx->lumpnum != S_GetSfxLumpNum(sfx)) +// I_FreeSfx(sfx); + +#ifdef HW3SOUND + if (hws_mode != HWS_DEFAULT_MODE) + return HW3S_GetSfx(sfx); +#endif + + if (sfx->data) + return sfx->data; //Alam: I have it done! + + sfx->length = W_LumpLength(sfx->lumpnum); + + return getsfx(sfx->lumpnum, &sfx->length); + +} + +void I_FreeSfx(sfxinfo_t * sfx) +{ +// if (sfx->lumpnum<0) +// return; + +#ifdef HW3SOUND + if (hws_mode != HWS_DEFAULT_MODE) + { + HW3S_FreeSfx(sfx); + } + else +#endif + { + size_t i; + + for (i = 1; i < NUMSFX; i++) + { + // Alias? Example is the chaingun sound linked to pistol. + if (S_sfx[i].data == sfx->data) + { + if (S_sfx+i != sfx) S_sfx[i].data = NULL; + S_sfx[i].lumpnum = LUMPERROR; + S_sfx[i].length = 0; + } + } + //Snd_LockAudio(); //Alam: too much? + // Loop all channels, check. + for (i = 0; i < NUM_CHANNELS; i++) + { + // Active, and using the same SFX? + if (channels[i].end && channels[i].id == sfx->data) + { + channels[i].end = NULL; // Reset. + } + } + //Snd_UnlockAudio(); //Alam: too much? + Z_Free(sfx->data); + } + sfx->data = NULL; + sfx->lumpnum = LUMPERROR; +} + +// +// Starting a sound means adding it +// to the current list of active sounds +// in the internal channels. +// As the SFX info struct contains +// e.g. a pointer to the raw data, +// it is ignored. +// As our sound handling does not handle +// priority, it is ignored. +// Pitching (that is, increased speed of playback) +// is set, but currently not used by mixing. +// +INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) +{ + (void)priority; + (void)pitch; + + if (nosound) + return 0; + + if (S_sfx[id].data == NULL) return -1; + + Snd_LockAudio(); + id = addsfx(id, vol, steptable[pitch], sep); + Snd_UnlockAudio(); + + return id; // Returns a handle (not used). +} + +void I_StopSound(INT32 handle) +{ + // You need the handle returned by StartSound. + // Would be looping all channels, + // tracking down the handle, + // an setting the channel to zero. + INT32 i; + + i = FindChannel(handle); + + if (i != -1) + { + //Snd_LockAudio(); //Alam: too much? + channels[i].end = NULL; + //Snd_UnlockAudio(); //Alam: too much? + channels[i].handle = -1; + channels[i].starttic = 0; + } + +} + +boolean I_SoundIsPlaying(INT32 handle) +{ + boolean isplaying = false; + int chan = FindChannel(handle); + if (chan != -1) + isplaying = (channels[chan].end != NULL); + return isplaying; +} + +FUNCINLINE static ATTRINLINE void I_UpdateStream8S(Uint8 *stream, int len) +{ + // Mix current sound data. + // Data, from raw sound + register Sint16 dr; // Right 8bit stream + register Uint8 sample; // Center 8bit sfx + register Sint16 dl; // Left 8bit stream + + // Pointers in audio stream + Sint8 *rightout = (Sint8 *)stream; // currect right + Sint8 *leftout = rightout + 1;// currect left + const Uint8 step = 2; // Step in stream, left and right, thus two. + + INT32 chan; // Mixing channel index. + + // Determine end of the stream + len /= 2; // not 8bit mono samples, 8bit stereo ones + + if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); + + // Mix sounds into the mixing buffer. + // Loop over len + while (len--) + { + // Reset left/right value. + dl = *leftout; + dr = *rightout; + + // Love thy L2 cache - made this a loop. + // Now more channels could be set at compile time + // as well. Thus loop those channels. + for (chan = 0; chan < NUM_CHANNELS; chan++) + { + // Check channel, if active. + if (channels[chan].end) + { +#if 1 + // Get the raw data from the channel. + sample = channels[chan].data[0]; +#else + // linear filtering from PrDoom + sample = (((Uint32)channels[chan].data[0] *(0x10000 - channels[chan].stepremainder)) + + ((Uint32)channels[chan].data[1]) * (channels[chan].stepremainder))) >> 16; +#endif + // Add left and right part + // for this channel (sound) + // to the current data. + // Adjust volume accordingly. + dl = (Sint16)(dl+(channels[chan].leftvol_lookup[sample]>>8)); + dr = (Sint16)(dr+(channels[chan].rightvol_lookup[sample]>>8)); + // Increment stepage + channels[chan].stepremainder += channels[chan].step; + // Check whether we are done. + if (channels[chan].data + (channels[chan].stepremainder >> 16) >= channels[chan].end) + channels[chan].end = NULL; + else + { + // step to next sample + channels[chan].data += (channels[chan].stepremainder >> 16); + // Limit to LSB??? + channels[chan].stepremainder &= 0xffff; + } + } + } + + // Clamp to range. Left hardware channel. + // Has been char instead of short. + + if (dl > 0x7f) + *leftout = 0x7f; + else if (dl < -0x80) + *leftout = -0x80; + else + *leftout = (Sint8)dl; + + // Same for right hardware channel. + if (dr > 0x7f) + *rightout = 0x7f; + else if (dr < -0x80) + *rightout = -0x80; + else + *rightout = (Sint8)dr; + + // Increment current pointers in stream + leftout += step; + rightout += step; + + } + if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); +} + +FUNCINLINE static ATTRINLINE void I_UpdateStream8M(Uint8 *stream, int len) +{ + // Mix current sound data. + // Data, from raw sound + register Sint16 d; // Mono 8bit stream + register Uint8 sample; // Center 8bit sfx + + // Pointers in audio stream + Sint8 *monoout = (Sint8 *)stream; // currect mono + const Uint8 step = 1; // Step in stream, left and right, thus two. + + INT32 chan; // Mixing channel index. + + // Determine end of the stream + //len /= 1; // not 8bit mono samples, 8bit mono ones? + + if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); + + // Mix sounds into the mixing buffer. + // Loop over len + while (len--) + { + // Reset left/right value. + d = *monoout; + + // Love thy L2 cache - made this a loop. + // Now more channels could be set at compile time + // as well. Thus loop those channels. + for (chan = 0; chan < NUM_CHANNELS; chan++) + { + // Check channel, if active. + if (channels[chan].end) + { +#if 1 + // Get the raw data from the channel. + sample = channels[chan].data[0]; +#else + // linear filtering from PrDoom + sample = (((Uint32)channels[chan].data[0] *(0x10000 - channels[chan].stepremainder)) + + ((Uint32)channels[chan].data[1]) * (channels[chan].stepremainder))) >> 16; +#endif + // Add left and right part + // for this channel (sound) + // to the current data. + // Adjust volume accordingly. + d = (Sint16)(d+((channels[chan].leftvol_lookup[sample] + channels[chan].rightvol_lookup[sample])>>9)); + // Increment stepage + channels[chan].stepremainder += channels[chan].step; + // Check whether we are done. + if (channels[chan].data + (channels[chan].stepremainder >> 16) >= channels[chan].end) + channels[chan].end = NULL; + else + { + // step to next sample + channels[chan].data += (channels[chan].stepremainder >> 16); + // Limit to LSB??? + channels[chan].stepremainder &= 0xffff; + } + } + } + + // Clamp to range. Left hardware channel. + // Has been char instead of short. + + if (d > 0x7f) + *monoout = 0x7f; + else if (d < -0x80) + *monoout = -0x80; + else + *monoout = (Sint8)d; + + // Increment current pointers in stream + monoout += step; + } + if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); +} + +FUNCINLINE static ATTRINLINE void I_UpdateStream16S(Uint8 *stream, int len) +{ + // Mix current sound data. + // Data, from raw sound + register Sint32 dr; // Right 16bit stream + register Uint8 sample; // Center 8bit sfx + register Sint32 dl; // Left 16bit stream + + // Pointers in audio stream + Sint16 *rightout = (Sint16 *)(void *)stream; // currect right + Sint16 *leftout = rightout + 1;// currect left + const Uint8 step = 2; // Step in stream, left and right, thus two. + + INT32 chan; // Mixing channel index. + + // Determine end of the stream + len /= 4; // not 8bit mono samples, 16bit stereo ones + + if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); + + // Mix sounds into the mixing buffer. + // Loop over len + while (len--) + { + // Reset left/right value. + dl = *leftout; + dr = *rightout; + + // Love thy L2 cache - made this a loop. + // Now more channels could be set at compile time + // as well. Thus loop those channels. + for (chan = 0; chan < NUM_CHANNELS; chan++) + { + // Check channel, if active. + if (channels[chan].end) + { +#if 1 + // Get the raw data from the channel. + sample = channels[chan].data[0]; +#else + // linear filtering from PrDoom + sample = (((Uint32)channels[chan].data[0] *(0x10000 - channels[chan].stepremainder)) + + ((Uint32)channels[chan].data[1]) * (channels[chan].stepremainder))) >> 16; +#endif + // Add left and right part + // for this channel (sound) + // to the current data. + // Adjust volume accordingly. + dl += channels[chan].leftvol_lookup[sample]; + dr += channels[chan].rightvol_lookup[sample]; + // Increment stepage + channels[chan].stepremainder += channels[chan].step; + // Check whether we are done. + if (channels[chan].data + (channels[chan].stepremainder >> 16) >= channels[chan].end) + channels[chan].end = NULL; + else + { + // step to next sample + channels[chan].data += (channels[chan].stepremainder >> 16); + // Limit to LSB??? + channels[chan].stepremainder &= 0xffff; + } + } + } + + // Clamp to range. Left hardware channel. + // Has been char instead of short. + + if (dl > 0x7fff) + *leftout = 0x7fff; + else if (dl < -0x8000) + *leftout = -0x8000; + else + *leftout = (Sint16)dl; + + // Same for right hardware channel. + if (dr > 0x7fff) + *rightout = 0x7fff; + else if (dr < -0x8000) + *rightout = -0x8000; + else + *rightout = (Sint16)dr; + + // Increment current pointers in stream + leftout += step; + rightout += step; + + } + if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); +} + +FUNCINLINE static ATTRINLINE void I_UpdateStream16M(Uint8 *stream, int len) +{ + // Mix current sound data. + // Data, from raw sound + register Sint32 d; // Mono 16bit stream + register Uint8 sample; // Center 8bit sfx + + // Pointers in audio stream + Sint16 *monoout = (Sint16 *)(void *)stream; // currect mono + const Uint8 step = 1; // Step in stream, left and right, thus two. + + INT32 chan; // Mixing channel index. + + // Determine end of the stream + len /= 2; // not 8bit mono samples, 16bit mono ones + + if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); + + // Mix sounds into the mixing buffer. + // Loop over len + while (len--) + { + // Reset left/right value. + d = *monoout; + + // Love thy L2 cache - made this a loop. + // Now more channels could be set at compile time + // as well. Thus loop those channels. + for (chan = 0; chan < NUM_CHANNELS; chan++) + { + // Check channel, if active. + if (channels[chan].end) + { +#if 1 + // Get the raw data from the channel. + sample = channels[chan].data[0]; +#else + // linear filtering from PrDoom + sample = (((Uint32)channels[chan].data[0] *(0x10000 - channels[chan].stepremainder)) + + ((Uint32)channels[chan].data[1]) * (channels[chan].stepremainder))) >> 16; +#endif + // Add left and right part + // for this channel (sound) + // to the current data. + // Adjust volume accordingly. + d += (channels[chan].leftvol_lookup[sample] + channels[chan].rightvol_lookup[sample])>>1; + // Increment stepage + channels[chan].stepremainder += channels[chan].step; + // Check whether we are done. + if (channels[chan].data + (channels[chan].stepremainder >> 16) >= channels[chan].end) + channels[chan].end = NULL; + else + { + // step to next sample + channels[chan].data += (channels[chan].stepremainder >> 16); + // Limit to LSB??? + channels[chan].stepremainder &= 0xffff; + } + } + } + + // Clamp to range. Left hardware channel. + // Has been char instead of short. + + if (d > 0x7fff) + *monoout = 0x7fff; + else if (d < -0x8000) + *monoout = -0x8000; + else + *monoout = (Sint16)d; + + // Increment current pointers in stream + monoout += step; + } + if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); +} + +#ifdef HAVE_LIBGME +static void I_UpdateSteamGME(Music_Emu *emu, INT16 *stream, int len, UINT8 looping) +{ + #define GME_BUFFER_LEN 44100*2048 + // Mix current sound data. + // Data, from raw sound + register Sint32 da; + + static short gme_buffer[GME_BUFFER_LEN]; // a large buffer for gme + Sint16 *in = gme_buffer; + + do + { + int out = min(GME_BUFFER_LEN, len); + if ( gme_play( emu, len, gme_buffer ) ) { } // ignore error + len -= out; + while (out--) + { + //Left + da = *in; + in++; + da += *stream; + stream++; + //Right + da = *in; + in++; + da += *stream; + stream++; + } + if (gme_track_ended( emu )) + { + if (looping) + gme_seek( emu, 0); + else + break; + } + } while ( len ); + #undef GME_BUFFER_LEN +} +#endif + +static void SDLCALL I_UpdateStream(void *userdata, Uint8 *stream, int len) +{ + if (!sound_started || !userdata) + return; + +#if SDL_VERSION_ATLEAST(1,3,0) + if (musicStarted) + memset(stream, 0x00, len); // only work in !AUDIO_U8, that needs 0x80 +#endif + + if ((audio.channels != 1 && audio.channels != 2) || + (audio.format != AUDIO_S8 && audio.format != AUDIO_S16SYS)) + ; // no function to encode this type of stream + else if (audio.channels == 1 && audio.format == AUDIO_S8) + I_UpdateStream8M(stream, len); + else if (audio.channels == 2 && audio.format == AUDIO_S8) + I_UpdateStream8S(stream, len); + else if (audio.channels == 1 && audio.format == AUDIO_S16SYS) + I_UpdateStream16M(stream, len); + else if (audio.channels == 2 && audio.format == AUDIO_S16SYS) + { + I_UpdateStream16S(stream, len); +#ifdef HAVE_LIBGME + if (userdata) + { + srb2audio_t *sa_userdata = userdata; + if (!sa_userdata->gme_pause) + I_UpdateSteamGME(sa_userdata->gme_emu, (INT16 *)stream, len/4, sa_userdata->gme_loop); + } +#endif + + } +} + +void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch) +{ + // Would be using the handle to identify + // on which channel the sound might be active, + // and resetting the channel parameters. + + INT32 i = FindChannel(handle); + + if (i != -1 && channels[i].end) + { + //Snd_LockAudio(); //Alam: too much? + I_SetChannelParams(&channels[i], vol, sep, steptable[pitch]); + //Snd_UnlockAudio(); //Alam: too much? + } + +} + +#ifdef HW3SOUND + +static void *soundso = NULL; + +static INT32 Init3DSDriver(const char *soName) +{ + if (soName) soundso = hwOpen(soName); +#if defined (_WIN32) && defined (_X86_) && !defined (STATIC3DS) + HW3DS.pfnStartup = hwSym("Startup@8",soundso); + HW3DS.pfnShutdown = hwSym("Shutdown@0",soundso); + HW3DS.pfnAddSfx = hwSym("AddSfx@4",soundso); + HW3DS.pfnAddSource = hwSym("AddSource@8",soundso); + HW3DS.pfnStartSource = hwSym("StartSource@4",soundso); + HW3DS.pfnStopSource = hwSym("StopSource@4",soundso); + HW3DS.pfnGetHW3DSVersion = hwSym("GetHW3DSVersion@0",soundso); + HW3DS.pfnBeginFrameUpdate = hwSym("BeginFrameUpdate@0",soundso); + HW3DS.pfnEndFrameUpdate = hwSym("EndFrameUpdate@0",soundso); + HW3DS.pfnIsPlaying = hwSym("IsPlaying@4",soundso); + HW3DS.pfnUpdateListener = hwSym("UpdateListener@8",soundso); + HW3DS.pfnUpdateSourceParms = hwSym("UpdateSourceParms@12",soundso); + HW3DS.pfnSetCone = hwSym("SetCone@8",soundso); + HW3DS.pfnSetGlobalSfxVolume = hwSym("SetGlobalSfxVolume@4",soundso); + HW3DS.pfnUpdate3DSource = hwSym("Update3DSource@8",soundso); + HW3DS.pfnReloadSource = hwSym("ReloadSource@8",soundso); + HW3DS.pfnKillSource = hwSym("KillSource@4",soundso); + HW3DS.pfnKillSfx = hwSym("KillSfx@4",soundso); + HW3DS.pfnGetHW3DSTitle = hwSym("GetHW3DSTitle@8",soundso); +#else + HW3DS.pfnStartup = hwSym("Startup",soundso); + HW3DS.pfnShutdown = hwSym("Shutdown",soundso); + HW3DS.pfnAddSfx = hwSym("AddSfx",soundso); + HW3DS.pfnAddSource = hwSym("AddSource",soundso); + HW3DS.pfnStartSource = hwSym("StartSource",soundso); + HW3DS.pfnStopSource = hwSym("StopSource",soundso); + HW3DS.pfnGetHW3DSVersion = hwSym("GetHW3DSVersion",soundso); + HW3DS.pfnBeginFrameUpdate = hwSym("BeginFrameUpdate",soundso); + HW3DS.pfnEndFrameUpdate = hwSym("EndFrameUpdate",soundso); + HW3DS.pfnIsPlaying = hwSym("IsPlaying",soundso); + HW3DS.pfnUpdateListener = hwSym("UpdateListener",soundso); + HW3DS.pfnUpdateSourceParms = hwSym("UpdateSourceParms",soundso); + HW3DS.pfnSetCone = hwSym("SetCone",soundso); + HW3DS.pfnSetGlobalSfxVolume = hwSym("SetGlobalSfxVolume",soundso); + HW3DS.pfnUpdate3DSource = hwSym("Update3DSource",soundso); + HW3DS.pfnReloadSource = hwSym("ReloadSource",soundso); + HW3DS.pfnKillSource = hwSym("KillSource",soundso); + HW3DS.pfnKillSfx = hwSym("KillSfx",soundso); + HW3DS.pfnGetHW3DSTitle = hwSym("GetHW3DSTitle",soundso); +#endif + +// if (HW3DS.pfnUpdateListener2 && HW3DS.pfnUpdateListener2 != soundso) + return true; +// else +// return false; +} +#endif + +void I_ShutdownSound(void) +{ + if (nosound || !sound_started) + return; + + CONS_Printf("I_ShutdownSound: "); + +#ifdef HW3SOUND + if (hws_mode != HWS_DEFAULT_MODE) + { + HW3S_Shutdown(); + hwClose(soundso); + return; + } +#endif + + if (nomidimusic && nodigimusic) + SDL_CloseAudio(); + CONS_Printf("%s", M_GetText("shut down\n")); + sound_started = false; + SDL_QuitSubSystem(SDL_INIT_AUDIO); + if (Snd_Mutex) + SDL_DestroyMutex(Snd_Mutex); + Snd_Mutex = NULL; +} + +void I_UpdateSound(void) +{ +} + +void I_StartupSound(void) +{ +#ifdef HW3SOUND + const char *sdrv_name = NULL; +#endif +#ifndef HAVE_MIXER + nomidimusic = nodigimusic = true; +#endif +#ifdef DC + //nosound = true; +#ifdef HAVE_MIXER + nomidimusic = true; + nodigimusic = true; +#endif +#endif + + memset(channels, 0, sizeof (channels)); //Alam: Clean it + + audio.format = AUDIO_S16SYS; + audio.channels = 2; + audio.callback = I_UpdateStream; + audio.userdata = &localdata; + + if (dedicated) + { + nosound = nomidimusic = nodigimusic = true; + return; + } + + // Configure sound device + CONS_Printf("I_StartupSound:\n"); + + // Open the audio device + if (M_CheckParm ("-freq") && M_IsNextParm()) + { + audio.freq = atoi(M_GetNextParm()); + if (!audio.freq) audio.freq = cv_samplerate.value; + audio.samples = (Uint16)((samplecount/2)*(INT32)(audio.freq/11025)); //Alam: to keep it around the same XX ms + CONS_Printf (M_GetText(" requested frequency of %d hz\n"), audio.freq); + } + else + { + audio.samples = samplecount; + audio.freq = cv_samplerate.value; + } + + if (M_CheckParm ("-mono")) + { + audio.channels = 1; + audio.samples /= 2; + } + +#if defined (_PSP) && defined (HAVE_MIXER) // Bug in PSP's SDL_OpenAudio, can not open twice + I_SetChannels(); + sound_started = true; + Snd_Mutex = SDL_CreateMutex(); +#else + if (nosound) +#endif + return; + +#ifdef HW3SOUND +#ifdef STATIC3DS + if (M_CheckParm("-3dsound") || M_CheckParm("-ds3d")) + { + hws_mode = HWS_OPENAL; + } +#elif defined (_WIN32) + if (M_CheckParm("-ds3d")) + { + hws_mode = HWS_DS3D; + sdrv_name = "s_ds3d.dll"; + } + else if (M_CheckParm("-fmod3d")) + { + hws_mode = HWS_FMOD3D; + sdrv_name = "s_fmod.dll"; + } + else if (M_CheckParm("-openal")) + { + hws_mode = HWS_OPENAL; + sdrv_name = "s_openal.dll"; + } +#else + if (M_CheckParm("-fmod3d")) + { + hws_mode = HWS_FMOD3D; + sdrv_name = "./s_fmod.so"; + } + else if (M_CheckParm("-openal")) + { + hws_mode = HWS_OPENAL; + sdrv_name = "./s_openal.so"; + } +#endif + else if (M_CheckParm("-sounddriver") && M_IsNextParm()) + { + hws_mode = HWS_OTHER; + sdrv_name = M_GetNextParm(); + } + if (hws_mode != HWS_DEFAULT_MODE) + { + if (Init3DSDriver(sdrv_name)) + { + snddev_t snddev; + + //nosound = true; + //I_AddExitFunc(I_ShutdownSound); + snddev.bps = 16; + snddev.sample_rate = audio.freq; + snddev.numsfxs = NUMSFX; +#if defined (_WIN32) && !defined (_XBOX) + snddev.cooplevel = 0x00000002; + snddev.hWnd = vid.WndParent; +#endif + if (HW3S_Init(I_Error, &snddev)) + { + audio.userdata = NULL; + CONS_Printf("%s", M_GetText(" Using 3D sound driver\n")); + return; + } + CONS_Printf("%s", M_GetText(" Failed loading 3D sound driver\n")); + // Falls back to default sound system + HW3S_Shutdown(); + hwClose(soundso); + } + CONS_Printf("%s", M_GetText(" Failed loading 3D sound driver\n")); + hws_mode = HWS_DEFAULT_MODE; + } +#endif + if (!musicStarted && SDL_OpenAudio(&audio, &audio) < 0) + { + CONS_Printf("%s", M_GetText(" couldn't open audio with desired format\n")); + nosound = true; + return; + } + else + { + char ad[100]; + CONS_Printf(M_GetText(" Starting up with audio driver : %s\n"), SDL_AudioDriverName(ad, (int)sizeof ad)); + } + samplecount = audio.samples; + CV_SetValue(&cv_samplerate, audio.freq); + CONS_Printf(M_GetText(" configured audio device with %d samples/slice at %ikhz(%dms buffer)\n"), samplecount, audio.freq/1000, (INT32) (((float)audio.samples * 1000.0f) / audio.freq)); + // Finished initialization. + CONS_Printf("%s", M_GetText(" Sound module ready\n")); + //[segabor] + if (!musicStarted) SDL_PauseAudio(0); + //Mix_Pause(0); + I_SetChannels(); + sound_started = true; + Snd_Mutex = SDL_CreateMutex(); +} + +// +// MUSIC API. +// + +void I_ShutdownMIDIMusic(void) +{ + nomidimusic = false; + if (nodigimusic) I_ShutdownMusic(); +} + +#ifdef HAVE_LIBGME +static void I_ShutdownGMEMusic(void) +{ + Snd_LockAudio(); + if (localdata.gme_emu) + gme_delete(localdata.gme_emu); + localdata.gme_emu = NULL; + Snd_UnlockAudio(); +} +#endif + +void I_ShutdownDigMusic(void) +{ + nodigimusic = false; + if (nomidimusic) I_ShutdownMusic(); +} + +#ifdef HAVE_MIXER +static boolean LoadSong(void *data, size_t lumplength, size_t selectpos) +{ + FILE *midfile; + const char *tempname; +#ifdef USE_RWOPS + if (canuseRW) + { + SDL_RWops *SDLRW; + void *olddata = Smidi[selectpos]; //quick shortcut to set + + Z_Free(olddata); //free old memory + Smidi[selectpos] = NULL; + + if (!data) + return olddata != NULL; //was there old data? + + SDLRW = SDL_RWFromConstMem(data, (int)lumplength); //new RWops from Z_zone + if (!SDLRW) //ERROR while making RWops! + { + CONS_Printf(M_GetText("Couldn't load music lump: %s\n"), SDL_GetError()); + Z_Free(data); + return false; + } + + music[selectpos] = Mix_LoadMUS_RW(SDLRW); // new Mix_Chuck from RWops + if (music[selectpos]) + Smidi[selectpos] = data; //all done + else //ERROR while making Mix_Chuck + { + CONS_Printf(M_GetText("Couldn't load music data: %s\n"), Mix_GetError()); + Z_Free(data); + SDL_RWclose(SDLRW); + Smidi[selectpos] = NULL; + } + return true; + } +#endif + tempname = va("%s/%s", MIDI_PATH, fmidi[selectpos]); + + if (!data) + { + if (FIL_FileExists(tempname)) + return unlink(tempname)+1; +#ifdef MIDI_PATH2 + else if (FIL_FileExists(tempname = va("%s/%s", MIDI_PATH2, fmidi[selectpos]))) + return unlink(tempname)+1; +#endif + else + return false; + } + + midfile = fopen(tempname, "wb"); + +#ifdef MIDI_PATH2 + if (!midfile) + { + tempname = va("%s/%s", MIDI_PATH2, fmidi[selectpos]); + midfile = fopen(tempname, "wb"); + } +#endif + + if (!midfile) + { + CONS_Printf(M_GetText("Couldn't open file %s to write music in\n"), tempname); + Z_Free(data); + return false; + } + + if (fwrite(data, lumplength, 1, midfile) == 0) + { + CONS_Printf(M_GetText("Couldn't write music into file %s because %s\n"), tempname, strerror(ferror(midfile))); + Z_Free(data); + fclose(midfile); + return false; + } + + fclose(midfile); + + Z_Free(data); + + music[selectpos] = Mix_LoadMUS(tempname); + if (!music[selectpos]) //ERROR while making Mix_Chuck + { + CONS_Printf(M_GetText("Couldn't load music file %s: %s\n"), tempname, Mix_GetError()); + return false; + } + return true; +} +#endif + + +void I_ShutdownMusic(void) +{ +#ifdef HAVE_MIXER + if ((nomidimusic && nodigimusic) || !musicStarted) + return; + + CONS_Printf("%s", M_GetText("I_ShutdownMusic: ")); + + I_UnRegisterSong(0); + I_StopDigSong(); + Mix_CloseAudio(); +#ifdef MIX_INIT + Mix_Quit(); +#endif + CONS_Printf("%s", M_GetText("shut down\n")); + musicStarted = SDL_FALSE; + if (Msc_Mutex) + SDL_DestroyMutex(Msc_Mutex); + Msc_Mutex = NULL; +#endif +} + +void I_InitMIDIMusic(void) +{ + if (nodigimusic) I_InitMusic(); +} + +void I_InitDigMusic(void) +{ + if (nomidimusic) I_InitMusic(); +} + +void I_InitMusic(void) +{ +#ifdef HAVE_MIXER + char ad[100]; + SDL_version MIXcompiled; + const SDL_version *MIXlinked; +#ifdef MIXER_INIT + const int mixstart = MIX_INIT_OGG; + int mixflags; +#endif +#endif +#ifdef HAVE_LIBGME + I_AddExitFunc(I_ShutdownGMEMusic); +#endif + + if ((nomidimusic && nodigimusic) || dedicated) + return; + +#ifdef HAVE_MIXER + MIX_VERSION(&MIXcompiled) + MIXlinked = Mix_Linked_Version(); + I_OutputMsg("Compiled for SDL_mixer version: %d.%d.%d\n", + MIXcompiled.major, MIXcompiled.minor, MIXcompiled.patch); +#ifdef MIXER_POS +#ifndef _WII + if (MIXlinked->major == 1 && MIXlinked->minor == 2 && MIXlinked->patch < 7) +#endif + canlooping = SDL_FALSE; +#endif +#ifdef USE_RWOPS + if (M_CheckParm("-noRW")) + canuseRW = SDL_FALSE; +#endif + I_OutputMsg("Linked with SDL_mixer version: %d.%d.%d\n", + MIXlinked->major, MIXlinked->minor, MIXlinked->patch); +#if !(defined (DC) || defined (PSP) || defined(GP2X) || defined (WII)) + if (audio.freq < 44100 && !M_CheckParm ("-freq")) //I want atleast 44Khz + { + audio.samples = (Uint16)(audio.samples*(INT32)(44100/audio.freq)); + audio.freq = 44100; //Alam: to keep it around the same XX ms + } +#endif + + if (sound_started +#ifdef HW3SOUND + && hws_mode == HWS_DEFAULT_MODE +#endif + ) + { + I_OutputMsg("Temp Shutdown of SDL Audio System"); + SDL_CloseAudio(); + I_OutputMsg(" Done\n"); + } + + CONS_Printf("%s", M_GetText("I_InitMusic:")); + +#ifdef MIXER_INIT + mixflags = Mix_Init(mixstart); + if ((mixstart & MIX_INIT_FLAC) != (mixflags & MIX_INIT_FLAC)) + { + CONS_Printf("%s", M_GetText(" Unable to load FLAC support\n")); + } + if ((mixstart & MIX_INIT_MOD ) != (mixflags & MIX_INIT_MOD )) + { + CONS_Printf("%s", M_GetText(" Unable to load MOD support\n")); + } + if ((mixstart & MIX_INIT_MP3 ) != (mixflags & MIX_INIT_MP3 )) + { + CONS_Printf("%s", M_GetText(" Unable to load MP3 support\n")); + } + if ((mixstart & MIX_INIT_OGG ) != (mixflags & MIX_INIT_OGG )) + { + CONS_Printf("%s", M_GetText(" Unable to load OGG support\n")); + } +#endif + + if (Mix_OpenAudio(audio.freq, audio.format, audio.channels, audio.samples) < 0) //open_music(&audio) + { + CONS_Printf(M_GetText(" Unable to open music: %s\n"), Mix_GetError()); + nomidimusic = nodigimusic = true; + if (sound_started +#ifdef HW3SOUND + && hws_mode == HWS_DEFAULT_MODE +#endif + ) + { + if (SDL_OpenAudio(&audio, NULL) < 0) //retry + { + CONS_Printf("%s", M_GetText(" couldn't open audio with desired format\n")); + nosound = true; + sound_started = false; + } + else + { + CONS_Printf(M_GetText(" Starting with audio driver : %s\n"), SDL_AudioDriverName(ad, (int)sizeof ad)); + } + } + return; + } + else + CONS_Printf(M_GetText(" Starting up with audio driver : %s with SDL_Mixer\n"), SDL_AudioDriverName(ad, (int)sizeof ad)); + + samplecount = audio.samples; + CV_SetValue(&cv_samplerate, audio.freq); + if (sound_started +#ifdef HW3SOUND + && hws_mode == HWS_DEFAULT_MODE +#endif + ) + I_OutputMsg(" Reconfigured SDL Audio System"); + else I_OutputMsg(" Configured SDL_Mixer System"); + I_OutputMsg(" with %d samples/slice at %ikhz(%dms buffer)\n", samplecount, audio.freq/1000, (INT32) ((audio.samples * 1000.0f) / audio.freq)); + Mix_SetPostMix(audio.callback, audio.userdata); // after mixing music, add sound effects + Mix_Resume(-1); + CONS_Printf("%s", M_GetText("Music initialized\n")); + musicStarted = SDL_TRUE; + Msc_Mutex = SDL_CreateMutex(); +#endif +} + +boolean I_PlaySong(INT32 handle, boolean looping) +{ + (void)handle; +#ifdef HAVE_MIXER + if (nomidimusic || !musicStarted || !music[handle]) + return false; + +#ifdef MIXER_POS + if (canlooping) + Mix_HookMusicFinished(NULL); +#endif + + if (Mix_FadeInMusic(music[handle], looping ? -1 : 0, MIDIfade) == -1) + CONS_Printf(M_GetText("Couldn't play song because %s\n"), Mix_GetError()); + else + { + Mix_VolumeMusic(musicvol); + return true; + } +#else + (void)looping; +#endif + return false; +} + +static void I_PauseGME(void) +{ +#ifdef HAVE_LIBGME + localdata.gme_pause = true; +#endif +} + +void I_PauseSong(INT32 handle) +{ + (void)handle; + I_PauseGME(); +#ifdef HAVE_MIXER + if ((nomidimusic && nodigimusic) || !musicStarted) + return; + + Mix_PauseMusic(); + //I_StopSong(handle); +#endif +} + +static void I_ResumeGME(void) +{ +#ifdef HAVE_LIBGME + localdata.gme_pause = false; +#endif +} + +void I_ResumeSong(INT32 handle) +{ + (void)handle; + I_ResumeGME(); +#ifdef HAVE_MIXER + if ((nomidimusic && nodigimusic) || !musicStarted) + return; + + Mix_VolumeMusic(musicvol); + Mix_ResumeMusic(); + //I_PlaySong(handle, true); +#endif +} + +void I_StopSong(INT32 handle) +{ + (void)handle; +#ifdef HAVE_MIXER + if (nomidimusic || !musicStarted) + return; + Mix_FadeOutMusic(MIDIfade); +#endif +} + +void I_UnRegisterSong(INT32 handle) +{ +#ifdef HAVE_MIXER + + if (nomidimusic || !musicStarted) + return; + + Mix_HaltMusic(); + while (Mix_PlayingMusic()) + ; + + if (music[handle]) + Mix_FreeMusic(music[handle]); + music[handle] = NULL; + LoadSong(NULL, 0, handle); +#else + (void)handle; +#endif +} + +INT32 I_RegisterSong(void *data, size_t len) +{ +#ifdef HAVE_MIXER + if (nomidimusic || !musicStarted) + return false; + + if (!LoadSong(data, len, 0)) + return false; + + if (music[0]) + return true; + + CONS_Printf(M_GetText("Couldn't load MIDI: %s\n"), Mix_GetError()); +#else + (void)len; + (void)data; +#endif + return false; +} + +void I_SetMIDIMusicVolume(UINT8 volume) +{ +#ifdef HAVE_MIXER + if ((nomidimusic && nodigimusic) || !musicStarted) + return; + + if (Msc_Mutex) SDL_LockMutex(Msc_Mutex); + musicvol = volume * 2; + if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); + Mix_VolumeMusic(musicvol); +#else + (void)volume; +#endif +} + +#ifdef HAVE_LIBGME +static void I_CleanupGME(void *userdata) +{ + Z_Free(userdata); +} +#endif + +static boolean I_StartGMESong(const char *musicname, boolean looping) +{ +#ifdef HAVE_LIBGME + XBOXSTATIC char filename[9]; + void *data; + lumpnum_t lumpnum; + size_t lumplength; + Music_Emu *emu; + const char* gme_err; + + Snd_LockAudio(); + if (localdata.gme_emu) + gme_delete(localdata.gme_emu); + localdata.gme_emu = NULL; + Snd_UnlockAudio(); + + snprintf(filename, sizeof filename, "o_%s", musicname); + + lumpnum = W_CheckNumForName(filename); + + if (lumpnum == LUMPERROR) + { + return false; // No music found. Oh well! + } + else + lumplength = W_LumpLength(lumpnum); + + data = W_CacheLumpNum(lumpnum, PU_MUSIC); + + gme_err = gme_open_data(data, (long)lumplength, &emu, audio.freq); + if (gme_err != NULL) { + //I_OutputMsg("I_StartGMESong: error %s\n",gme_err); + return false; + } + gme_set_user_data(emu, data); + gme_set_user_cleanup(emu, I_CleanupGME); + gme_start_track(emu, 0); + gme_set_fade(emu, Digfade); + + Snd_LockAudio(); + localdata.gme_emu = emu; + localdata.gme_pause = false; + localdata.gme_loop = (UINT8)looping; + Snd_UnlockAudio(); + + return true; +#else + (void)musicname; + (void)looping; +#endif + return false; +} + +boolean I_StartDigSong(const char *musicname, boolean looping) +{ +#ifdef HAVE_MIXER + XBOXSTATIC char filename[9]; + void *data; + lumpnum_t lumpnum; + size_t lumplength; +#endif + + if(I_StartGMESong(musicname, looping)) + return true; + +#ifdef HAVE_MIXER + if (nodigimusic) + return false; + + snprintf(filename, sizeof filename, "o_%s", musicname); + + lumpnum = W_CheckNumForName(filename); + + I_StopDigSong(); + + if (lumpnum == LUMPERROR) + { + // Alam_GBC: like in win32/win_snd.c: Graue 02-29-2004: don't worry about missing music, there might still be a MIDI + //I_OutputMsg("Music lump %s not found!\n", filename); + return false; // No music found. Oh well! + } + else + lumplength = W_LumpLength(lumpnum); + + data = W_CacheLumpNum(lumpnum, PU_MUSIC); + + if (Msc_Mutex) SDL_LockMutex(Msc_Mutex); + +#ifdef MIXER_POS + if (canlooping && (loopingDig = looping) == SDL_TRUE && strcmp(data, "OggS") == 0) + looping = false; // Only on looping Ogg files, will we will do our own looping + + // Scan the Ogg Vorbis file for the COMMENT= field for a custom + // loop point + if (!looping && loopingDig) + { + size_t scan; + const char *dataum = data; + XBOXSTATIC char looplength[64]; + UINT32 loopstart = 0; + UINT8 newcount = 0; + + Mix_HookMusicFinished(I_FinishMusic); + + for (scan = 0; scan < lumplength; scan++) + { + if (*dataum++ == 'C'){ + if (*dataum++ == 'O'){ + if (*dataum++ == 'M'){ + if (*dataum++ == 'M'){ + if (*dataum++ == 'E'){ + if (*dataum++ == 'N'){ + if (*dataum++ == 'T'){ + if (*dataum++ == '='){ + if (*dataum++ == 'L'){ + if (*dataum++ == 'O'){ + if (*dataum++ == 'O'){ + if (*dataum++ == 'P'){ + if (*dataum++ == 'P'){ + if (*dataum++ == 'O'){ + if (*dataum++ == 'I'){ + if (*dataum++ == 'N'){ + if (*dataum++ == 'T'){ + if (*dataum++ == '=') + { + + while (*dataum != 1 && newcount != 63) + looplength[newcount++] = *dataum++; + + looplength[newcount] = '\0'; + + loopstart = atoi(looplength); + + } + else + dataum--;} + else + dataum--;} + else + dataum--;} + else + dataum--;} + else + dataum--;} + else + dataum--;} + else + dataum--;} + else + dataum--;} + else + dataum--;} + else + dataum--;} + else + dataum--;} + else + dataum--;} + else + dataum--;} + else + dataum--;} + else + dataum--;} + else + dataum--;} + else + dataum--;} + } + + if (loopstart > 0) + { + loopstartDig = (double)((44.1l+loopstart) / 44100.0l); //8 PCM chucks off and PCM to secs +//#ifdef GP2X//#ifdef PARANOIA + //I_OutputMsg("I_StartDigSong: setting looping point to %ul PCMs(%f seconds)\n", loopstart, loopstartDig); +//#endif + } + else + { + looping = true; // loopingDig true, but couldn't find start loop point + } + } + else + loopstartDig = 0.0l; +#else + if (looping && strcmp(data, "OggS") == 0) + I_OutputMsg("I_StartDigSong: SRB2 was not compiled with looping music support(no Mix_FadeInMusicPos)\n"); +#endif + + if (!LoadSong(data, lumplength, 1)) + { + if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); + return false; + } + + // Note: LoadSong() frees the data. Let's make sure + // we don't try to use the data again. + data = NULL; + + if (Mix_FadeInMusic(music[1], looping ? -1 : 0, Digfade) == -1) + { + if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); + I_OutputMsg("I_StartDigSong: Couldn't play song %s because %s\n", musicname, Mix_GetError()); + return false; + } + Mix_VolumeMusic(musicvol); + + if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); + return true; +#else + (void)looping; + (void)musicname; + return false; +#endif +} + +static void I_StopGME(void) +{ +#ifdef HAVE_LIBGME + Snd_LockAudio(); + gme_seek(localdata.gme_emu, 0); + Snd_UnlockAudio(); +#endif +} + +void I_StopDigSong(void) +{ + I_StopGME(); +#ifdef HAVE_MIXER + if (nodigimusic) + return; + +#ifdef MIXER_POS + if (canlooping) + Mix_HookMusicFinished(NULL); +#endif + + Mix_HaltMusic(); + while (Mix_PlayingMusic()) + ; + + if (music[1]) + Mix_FreeMusic(music[1]); + music[1] = NULL; + LoadSong(NULL, 0, 1); +#endif +} + +void I_SetDigMusicVolume(UINT8 volume) +{ + I_SetMIDIMusicVolume(volume); +} + +boolean I_SetSongSpeed(float speed) +{ + + (void)speed; + return false; +} + +boolean I_SetSongTrack(int track) +{ + (void)track; + return false; +} + +#ifdef MIXER_POS +static void SDLCALL I_FinishMusic(void) +{ + if (!music[1]) + return; + else if (Msc_Mutex) SDL_LockMutex(Msc_Mutex); +// I_OutputMsg("I_FinishMusic: Loopping song to %g seconds\n", loopstartDig); + + if (Mix_FadeInMusicPos(music[1], loopstartDig ? 0 : -1, Digfade, loopstartDig) == 0) + Mix_VolumeMusic(musicvol); + else + I_OutputMsg("I_FinishMusic: Couldn't loop song because %s\n", Mix_GetError()); + + if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex); +} +#endif +#endif //SDL diff --git a/src/sdl12/sdlmain.h b/src/sdl12/sdlmain.h new file mode 100644 index 000000000..1e497b10d --- /dev/null +++ b/src/sdl12/sdlmain.h @@ -0,0 +1,65 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright (C) 2006 by Sonic Team Jr. +// +// 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. +//----------------------------------------------------------------------------- +/// \file +/// \brief System specific interface stuff. + +#ifndef __sdlmain__ +#define __sdlmain__ + +extern SDL_bool consolevent; +extern SDL_bool framebuffer; + +/** \brief The JoyInfo_s struct + + info about joystick +*/ +typedef struct SDLJoyInfo_s +{ + /// Joystick handle + SDL_Joystick *dev; + /// number of old joystick + int oldjoy; + /// number of axies + int axises; + /// scale of axises + INT32 scale; + /// number of buttons + int buttons; + /// number of hats + int hats; + /// number of balls + int balls; + +} SDLJoyInfo_t; + +/** \brief SDL info about joystick 1 +*/ +extern SDLJoyInfo_t JoyInfo; + +/** \brief joystick axis deadzone +*/ +#define SDL_JDEADZONE 153 +#undef SDL_JDEADZONE + +/** \brief SDL inof about joystick 2 +*/ +extern SDLJoyInfo_t JoyInfo2; + +void I_GetConsoleEvents(void); + +void SDLforceUngrabMouse(void); + +#endif diff --git a/src/sdl12/srb2.ttf b/src/sdl12/srb2.ttf new file mode 100644 index 0000000000000000000000000000000000000000..53f4c6a28a2adc0c97df4a7570ace24cf4949580 GIT binary patch literal 318280 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 z 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