mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-26 04:11:18 +00:00
Initial SDL2 renderer impmlementation work.
This commit is contained in:
parent
2fed5d1270
commit
2a827a98bb
87 changed files with 34394 additions and 4 deletions
|
@ -5,7 +5,8 @@ if [ x"$1" != x ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
versiongit() {
|
versiongit() {
|
||||||
gitversion=`git svn log HEAD --limit=1 --oneline | cut -f 1 -d " "`
|
#gitversion=`git svn log HEAD --limit=1 --oneline | cut -f 1 -d " "`
|
||||||
|
gitversion=`git log HEAD -n1 --oneline | cut -f 1 -d " "`
|
||||||
cat <<EOF > $path/comptime.h
|
cat <<EOF > $path/comptime.h
|
||||||
|
|
||||||
// Do not edit! This file was autogenerated
|
// Do not edit! This file was autogenerated
|
||||||
|
|
|
@ -202,7 +202,7 @@ LIBS+=-lm
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef SDL
|
ifdef SDL
|
||||||
include sdl/Makefile.cfg
|
include sdl2/Makefile.cfg
|
||||||
endif #ifdef SDL
|
endif #ifdef SDL
|
||||||
|
|
||||||
ifdef DISTCC
|
ifdef DISTCC
|
||||||
|
|
|
@ -230,7 +230,6 @@ ifdef DUMMY
|
||||||
BIN:=$(BIN)/dummy
|
BIN:=$(BIN)/dummy
|
||||||
else
|
else
|
||||||
ifdef LINUX
|
ifdef LINUX
|
||||||
INTERFACE=sdl
|
|
||||||
NASMFORMAT=elf -DLINUX
|
NASMFORMAT=elf -DLINUX
|
||||||
SDL=1
|
SDL=1
|
||||||
ifndef NOGETTEXT
|
ifndef NOGETTEXT
|
||||||
|
@ -387,7 +386,7 @@ OBJDUMP_OPTS?=--wide --source --line-numbers
|
||||||
LD=$(CC)
|
LD=$(CC)
|
||||||
|
|
||||||
ifdef SDL
|
ifdef SDL
|
||||||
INTERFACE=sdl
|
INTERFACE=sdl2
|
||||||
OBJDIR:=$(OBJDIR)/SDL
|
OBJDIR:=$(OBJDIR)/SDL
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
|
|
||||||
#ifdef SDL
|
#ifdef SDL
|
||||||
#include "sdl/hwsym_sdl.h"
|
#include "sdl/hwsym_sdl.h"
|
||||||
|
typedef off_t off64_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (_WIN32)
|
#if defined (_WIN32)
|
||||||
|
|
506
src/sdl2/IMG_xpm.c
Normal file
506
src/sdl2/IMG_xpm.c
Normal file
|
@ -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 <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
//#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
|
||||||
|
*
|
||||||
|
* <width> <height> <ncolors> <cpp> [ <hotspot_x> <hotspot_y> ]
|
||||||
|
*
|
||||||
|
* 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 */
|
17
src/sdl2/MakeCYG.cfg
Normal file
17
src/sdl2/MakeCYG.cfg
Normal file
|
@ -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
|
92
src/sdl2/MakeNIX.cfg
Normal file
92
src/sdl2/MakeNIX.cfg
Normal file
|
@ -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?=lsdl2srb2
|
163
src/sdl2/Makefile.cfg
Normal file
163
src/sdl2/Makefile.cfg
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
#
|
||||||
|
# sdl/makefile.cfg for SRB2/SDL
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
#SDL...., *looks at Alam*, THIS IS A MESS!
|
||||||
|
#
|
||||||
|
|
||||||
|
ifdef UNIXCOMMON
|
||||||
|
include sdl2/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 sdl2/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)-sdl2-config
|
||||||
|
else
|
||||||
|
SDL_CONFIG?=sdl2-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
|
80
src/sdl2/SDL_icon.xpm
Normal file
80
src/sdl2/SDL_icon.xpm
Normal file
|
@ -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 ",
|
||||||
|
" { ",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" "};
|
12
src/sdl2/SDL_main/SDL_dummy_main.c
Normal file
12
src/sdl2/SDL_main/SDL_dummy_main.c
Normal file
|
@ -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
|
11
src/sdl2/SDL_main/SDL_macosx_main.h
Normal file
11
src/sdl2/SDL_main/SDL_macosx_main.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
|
||||||
|
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
|
||||||
|
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
|
||||||
|
|
||||||
|
Feel free to customize this file to suit your needs
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface SDLMain : NSObject
|
||||||
|
@end
|
374
src/sdl2/SDL_main/SDL_macosx_main.m
Normal file
374
src/sdl2/SDL_main/SDL_macosx_main.m
Normal file
|
@ -0,0 +1,374 @@
|
||||||
|
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
|
||||||
|
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
|
||||||
|
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
|
||||||
|
|
||||||
|
Feel free to customize this file to suit your needs
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "SDL.h"
|
||||||
|
#import "SDL_macosx_main.h"
|
||||||
|
#import <sys/param.h> /* for MAXPATHLEN */
|
||||||
|
#import <unistd.h>
|
||||||
|
|
||||||
|
/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
|
||||||
|
but the method still is there and works. To avoid warnings, we declare
|
||||||
|
it ourselves here. */
|
||||||
|
@interface NSApplication(SDL_Missing_Methods)
|
||||||
|
- (void)setAppleMenu:(NSMenu *)menu;
|
||||||
|
@end
|
||||||
|
|
||||||
|
/* Use this flag to determine whether we use SDLMain.nib or not */
|
||||||
|
#define SDL_USE_NIB_FILE 0
|
||||||
|
|
||||||
|
/* Use this flag to determine whether we use CPS (docking) or not */
|
||||||
|
#define SDL_USE_CPS 1
|
||||||
|
#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;
|
||||||
|
}
|
7
src/sdl2/SDL_main/SDL_openxdk_main.c
Normal file
7
src/sdl2/SDL_main/SDL_openxdk_main.c
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
/* Include the SDL main definition header */
|
||||||
|
#include "SDL_main.h"
|
||||||
|
|
||||||
|
void XBoxStartup()
|
||||||
|
{
|
||||||
|
SDL_main(0, NULL); /// \todo ?
|
||||||
|
}
|
406
src/sdl2/SDL_main/SDL_win32_main.c
Normal file
406
src/sdl2/SDL_main/SDL_win32_main.c
Normal file
|
@ -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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#define RPC_NO_WINDOWS_H
|
||||||
|
#include <windows.h>
|
||||||
|
#include <malloc.h> /* For _alloca() */
|
||||||
|
|
||||||
|
#include <tchar.h>
|
||||||
|
|
||||||
|
#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 <direct.h>
|
||||||
|
#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;
|
||||||
|
}
|
12
src/sdl2/SRB2CE/Makefile.cfg
Normal file
12
src/sdl2/SRB2CE/Makefile.cfg
Normal file
|
@ -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
|
BIN
src/sdl2/SRB2CE/SRB2CE.zip
Normal file
BIN
src/sdl2/SRB2CE/SRB2CE.zip
Normal file
Binary file not shown.
447
src/sdl2/SRB2CE/cehelp.c
Normal file
447
src/sdl2/SRB2CE/cehelp.c
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
|
63
src/sdl2/SRB2CE/cehelp.h
Normal file
63
src/sdl2/SRB2CE/cehelp.h
Normal file
|
@ -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
|
1
src/sdl2/SRB2DC/.gitignore
vendored
Normal file
1
src/sdl2/SRB2DC/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/scramble
|
BIN
src/sdl2/SRB2DC/IP.BIN
Normal file
BIN
src/sdl2/SRB2DC/IP.BIN
Normal file
Binary file not shown.
53
src/sdl2/SRB2DC/Makefile.cfg
Normal file
53
src/sdl2/SRB2DC/Makefile.cfg
Normal file
|
@ -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
|
BIN
src/sdl2/SRB2DC/SELFBOOT.BIN
Normal file
BIN
src/sdl2/SRB2DC/SELFBOOT.BIN
Normal file
Binary file not shown.
19
src/sdl2/SRB2DC/VMU.xbm
Normal file
19
src/sdl2/SRB2DC/VMU.xbm
Normal file
|
@ -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 };
|
134
src/sdl2/SRB2DC/dchelp.c
Normal file
134
src/sdl2/SRB2DC/dchelp.c
Normal file
|
@ -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 <kos/fs.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#ifndef HAVE_LWIP
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#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 <lwip/lwip.h>
|
||||||
|
|
||||||
|
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
|
51
src/sdl2/SRB2DC/dchelp.h
Normal file
51
src/sdl2/SRB2DC/dchelp.h
Normal file
|
@ -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
|
455
src/sdl2/SRB2DC/i_udp.c
Normal file
455
src/sdl2/SRB2DC/i_udp.c
Normal file
|
@ -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 <kos/net.h>
|
||||||
|
//#include <net/net_ipv4.h>
|
||||||
|
#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>");
|
||||||
|
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;
|
||||||
|
}
|
259
src/sdl2/SRB2DC/scramble.c
Normal file
259
src/sdl2/SRB2DC/scramble.c
Normal file
|
@ -0,0 +1,259 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
BIN
src/sdl2/SRB2PS3/ICON0.png
Normal file
BIN
src/sdl2/SRB2PS3/ICON0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
139
src/sdl2/SRB2PS3/Makefile.cfg
Normal file
139
src/sdl2/SRB2PS3/Makefile.cfg
Normal file
|
@ -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=<path to>ps3dev-toolchain")
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(PSL1GHT)),)
|
||||||
|
$(error "Please set PSL1GHT in your environment. export PSL1GHT=<path to>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
|
39
src/sdl2/SRB2PS3/sfo.xml
Normal file
39
src/sdl2/SRB2PS3/sfo.xml
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<?xml version="1.0" ?>
|
||||||
|
<sfo>
|
||||||
|
<value name="APP_VER" type="string">
|
||||||
|
02.06
|
||||||
|
</value>
|
||||||
|
<value name="ATTRIBUTE" type="integer">
|
||||||
|
0
|
||||||
|
</value>
|
||||||
|
<value name="BOOTABLE" type="integer">
|
||||||
|
1
|
||||||
|
</value>
|
||||||
|
<value name="CATEGORY" type="string">
|
||||||
|
HG
|
||||||
|
</value>
|
||||||
|
<value name="LICENSE" type="string">
|
||||||
|
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.
|
||||||
|
</value>
|
||||||
|
<value name="PARENTAL_LEVEL" type="integer">
|
||||||
|
0
|
||||||
|
</value>
|
||||||
|
<value name="PS3_SYSTEM_VER" type="string">
|
||||||
|
0@@PS3_SYSTEM_VER@@00
|
||||||
|
</value>
|
||||||
|
<value name="RESOLUTION" type="integer">
|
||||||
|
63
|
||||||
|
</value>
|
||||||
|
<value name="SOUND_FORMAT" type="integer">
|
||||||
|
279
|
||||||
|
</value>
|
||||||
|
<value name="TITLE" type="string">
|
||||||
|
Sonic Robo Blast 2
|
||||||
|
</value>
|
||||||
|
<value name="TITLE_ID" type="string">
|
||||||
|
SRB200000
|
||||||
|
</value>
|
||||||
|
<value name="VERSION" type="string">
|
||||||
|
02.06
|
||||||
|
</value>
|
||||||
|
</sfo>
|
BIN
src/sdl2/SRB2PSP/ICON0.png
Normal file
BIN
src/sdl2/SRB2PSP/ICON0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
126
src/sdl2/SRB2PSP/Makefile.cfg
Normal file
126
src/sdl2/SRB2PSP/Makefile.cfg
Normal file
|
@ -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
|
BIN
src/sdl2/SRB2PSP/PIC1.png
Normal file
BIN
src/sdl2/SRB2PSP/PIC1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
2
src/sdl2/SRB2PSP/psp-prxsign/.gitignore
vendored
Normal file
2
src/sdl2/SRB2PSP/psp-prxsign/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/psp-prxsign
|
||||||
|
/psp-prxsign.exe
|
22
src/sdl2/SRB2PSP/psp-prxsign/Makefile
Normal file
22
src/sdl2/SRB2PSP/psp-prxsign/Makefile
Normal file
|
@ -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)
|
130
src/sdl2/SRB2PSP/psp-prxsign/cmac.c
Normal file
130
src/sdl2/SRB2PSP/psp-prxsign/cmac.c
Normal file
|
@ -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<n-1; i++ )
|
||||||
|
{
|
||||||
|
xor_128(X,&input[16*i],Y); /* Y := Mi (+) X */
|
||||||
|
AES_encrypt(Y, X, &aes); /* X := AES-128(KEY, Y); */
|
||||||
|
}
|
||||||
|
|
||||||
|
xor_128(X,M_last,Y);
|
||||||
|
AES_encrypt(Y, X, &aes);
|
||||||
|
|
||||||
|
for ( i=0; i<16; i++ ) {
|
||||||
|
mac[i] = X[i];
|
||||||
|
}
|
||||||
|
}
|
38
src/sdl2/SRB2PSP/psp-prxsign/cmac.h
Normal file
38
src/sdl2/SRB2PSP/psp-prxsign/cmac.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
LICENSE TERMS
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
1. source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
2. binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation;
|
||||||
|
|
||||||
|
3. the name of the copyright holder is not used to endorse products
|
||||||
|
built using this software without specific written permission.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its properties, including, but not limited to, correctness
|
||||||
|
and/or fitness for purpose.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Issue Date: 6/10/2008
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CMAC_AES_H
|
||||||
|
#define CMAC_AES_H
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <openssl/aes.h>
|
||||||
|
|
||||||
|
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
|
25
src/sdl2/SRB2PSP/psp-prxsign/kirk_header.h
Normal file
25
src/sdl2/SRB2PSP/psp-prxsign/kirk_header.h
Normal file
|
@ -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
|
190
src/sdl2/SRB2PSP/psp-prxsign/main.c
Normal file
190
src/sdl2/SRB2PSP/psp-prxsign/main.c
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <openssl/aes.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
#include <elf.h>
|
||||||
|
#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;
|
||||||
|
}
|
29
src/sdl2/SRB2PSP/psp-prxsign/psp_header.h
Normal file
29
src/sdl2/SRB2PSP/psp-prxsign/psp_header.h
Normal file
|
@ -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
|
39
src/sdl2/SRB2Pandora/Makefile.cfg
Normal file
39
src/sdl2/SRB2Pandora/Makefile.cfg
Normal file
|
@ -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)
|
17
src/sdl2/SRB2Pandora/PXML.xml
Normal file
17
src/sdl2/SRB2Pandora/PXML.xml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<PXML xmlns="http://openpandora.org/namespaces/PXML">
|
||||||
|
<application id="srb2.pandora.v20" appdata="srb2">
|
||||||
|
<title lang="en_US">Sonic Robo Blast 2</title>
|
||||||
|
<title lang="ja_JA">ソニック・ロボ・ブラスト・2</title>
|
||||||
|
<description lang="en_US">A 3D Sonic fangame with a huge fanbase developing custom content, including characters, levels, and even large-scale modifications</description>
|
||||||
|
<version major="2" minor="0" release="6" build="1" />
|
||||||
|
<exec command="lsdlsrb2" background="true" standalone="true" x11="ignore"/>
|
||||||
|
<author name="Sonic Team Junior" website="http://www.srb2.org/" email="stjr@srb2.org"/>
|
||||||
|
<icon src="icon.png"/>
|
||||||
|
<categories>
|
||||||
|
<category name="Game">
|
||||||
|
<subcategory name="ActionGame" />
|
||||||
|
</category>
|
||||||
|
</categories>
|
||||||
|
</application>
|
||||||
|
</PXML>
|
BIN
src/sdl2/SRB2Pandora/icon.png
Normal file
BIN
src/sdl2/SRB2Pandora/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
124
src/sdl2/SRB2WII/Makefile.cfg
Normal file
124
src/sdl2/SRB2WII/Makefile.cfg
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
#
|
||||||
|
# Makefile.cfg for SRB2Wii native using libogc
|
||||||
|
#
|
||||||
|
|
||||||
|
# Check if DEVKITPPC is set in the environment. If so, continue with compilation.
|
||||||
|
.SUFFIXES:
|
||||||
|
|
||||||
|
ifeq ($(strip $(DEVKITPPC)),)
|
||||||
|
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
|
||||||
|
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)
|
BIN
src/sdl2/SRB2WII/icon.png
Normal file
BIN
src/sdl2/SRB2WII/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
18
src/sdl2/SRB2WII/meta.xml
Normal file
18
src/sdl2/SRB2WII/meta.xml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<app version="1">
|
||||||
|
<name>SRB2Wii</name>
|
||||||
|
<coder>Callum</coder>
|
||||||
|
<version>2.0.6</version>
|
||||||
|
<release_date>20101207</release_date>
|
||||||
|
<short_description>A 3D Sonic fangame</short_description>
|
||||||
|
<long_description>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.</long_description>
|
||||||
|
</app>
|
44
src/sdl2/SRB2XBOX/Makefile.cfg
Normal file
44
src/sdl2/SRB2XBOX/Makefile.cfg
Normal file
|
@ -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
|
91
src/sdl2/SRB2XBOX/xboxhelp.c
Normal file
91
src/sdl2/SRB2XBOX/xboxhelp.c
Normal file
|
@ -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 <unistd.h>
|
||||||
|
#else
|
||||||
|
#include <stdlib.h>
|
||||||
|
#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 <RtcApi.h>
|
||||||
|
void __cdecl _RTC_Initialize(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
char *getenv(const char *__env)
|
||||||
|
{
|
||||||
|
__env = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int putenv(const char *__env)
|
||||||
|
{
|
||||||
|
__env = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
6
src/sdl2/SRB2XBOX/xboxhelp.h
Normal file
6
src/sdl2/SRB2XBOX/xboxhelp.h
Normal file
|
@ -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
|
1464
src/sdl2/Srb2SDL-vc10.vcxproj
Normal file
1464
src/sdl2/Srb2SDL-vc10.vcxproj
Normal file
File diff suppressed because it is too large
Load diff
5845
src/sdl2/Srb2SDL-vc9.vcproj
Normal file
5845
src/sdl2/Srb2SDL-vc9.vcproj
Normal file
File diff suppressed because it is too large
Load diff
1057
src/sdl2/Srb2SDL.dsp
Normal file
1057
src/sdl2/Srb2SDL.dsp
Normal file
File diff suppressed because it is too large
Load diff
74
src/sdl2/Srb2SDL.dsw
Normal file
74
src/sdl2/Srb2SDL.dsw
Normal file
|
@ -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>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
BIN
src/sdl2/Srb2SDL.ico
Normal file
BIN
src/sdl2/Srb2SDL.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
38
src/sdl2/dosstr.c
Normal file
38
src/sdl2/dosstr.c
Normal file
|
@ -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 <ctype.h>
|
||||||
|
|
||||||
|
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
|
236
src/sdl2/endtxt.c
Normal file
236
src/sdl2/endtxt.c
Normal file
|
@ -0,0 +1,236 @@
|
||||||
|
/*
|
||||||
|
* Function to write the SRB2 end message text
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 by Udo Munk <udo@umserver.umnet.de>
|
||||||
|
*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
24
src/sdl2/endtxt.h
Normal file
24
src/sdl2/endtxt.h
Normal file
|
@ -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
|
1000
src/sdl2/filter/filters.c
Normal file
1000
src/sdl2/filter/filters.c
Normal file
File diff suppressed because it is too large
Load diff
212
src/sdl2/filter/filters.h
Normal file
212
src/sdl2/filter/filters.h
Normal file
|
@ -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
|
3125
src/sdl2/filter/hq2x.c
Normal file
3125
src/sdl2/filter/hq2x.c
Normal file
File diff suppressed because it is too large
Load diff
1824
src/sdl2/filter/hq2x.h
Normal file
1824
src/sdl2/filter/hq2x.h
Normal file
File diff suppressed because it is too large
Load diff
306
src/sdl2/filter/interp.h
Normal file
306
src/sdl2/filter/interp.h
Normal file
|
@ -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
|
564
src/sdl2/filter/lq2x.c
Normal file
564
src/sdl2/filter/lq2x.c
Normal file
|
@ -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;i<count;++i) {
|
||||||
|
Uint8 mask;
|
||||||
|
|
||||||
|
Uint16 c[9];
|
||||||
|
|
||||||
|
c[1] = src0[0];
|
||||||
|
c[4] = src1[0];
|
||||||
|
c[7] = src2[0];
|
||||||
|
|
||||||
|
if (i>0) {
|
||||||
|
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<count-1) {
|
||||||
|
c[2] = src0[1];
|
||||||
|
c[5] = src1[1];
|
||||||
|
c[8] = src2[1];
|
||||||
|
} else {
|
||||||
|
c[2] = c[1];
|
||||||
|
c[5] = c[4];
|
||||||
|
c[8] = c[7];
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = 0;
|
||||||
|
|
||||||
|
if (interp_16_diff(c[0], c[4]))
|
||||||
|
mask |= 1 << 0;
|
||||||
|
if (interp_16_diff(c[1], c[4]))
|
||||||
|
mask |= 1 << 1;
|
||||||
|
if (interp_16_diff(c[2], c[4]))
|
||||||
|
mask |= 1 << 2;
|
||||||
|
if (interp_16_diff(c[3], c[4]))
|
||||||
|
mask |= 1 << 3;
|
||||||
|
if (interp_16_diff(c[5], c[4]))
|
||||||
|
mask |= 1 << 4;
|
||||||
|
if (interp_16_diff(c[6], c[4]))
|
||||||
|
mask |= 1 << 5;
|
||||||
|
if (interp_16_diff(c[7], c[4]))
|
||||||
|
mask |= 1 << 6;
|
||||||
|
if (interp_16_diff(c[8], c[4]))
|
||||||
|
mask |= 1 << 7;
|
||||||
|
|
||||||
|
#define P0 dst0[0]
|
||||||
|
#define P1 dst0[1]
|
||||||
|
#define P2 dst1[0]
|
||||||
|
#define P3 dst1[1]
|
||||||
|
#define MUR interp_16_diff(c[1], c[5])
|
||||||
|
#define MDR interp_16_diff(c[5], c[7])
|
||||||
|
#define MDL interp_16_diff(c[7], c[3])
|
||||||
|
#define MUL interp_16_diff(c[3], c[1])
|
||||||
|
#define IC(p0) c[p0]
|
||||||
|
#define I11(p0,p1) interp_16_11(c[p0], c[p1])
|
||||||
|
#define I211(p0,p1,p2) interp_16_211(c[p0], c[p1], c[p2])
|
||||||
|
#define I31(p0,p1) interp_16_31(c[p0], c[p1])
|
||||||
|
#define I332(p0,p1,p2) interp_16_332(c[p0], c[p1], c[p2])
|
||||||
|
#define I431(p0,p1,p2) interp_16_431(c[p0], c[p1], c[p2])
|
||||||
|
#define I521(p0,p1,p2) interp_16_521(c[p0], c[p1], c[p2])
|
||||||
|
#define I53(p0,p1) interp_16_53(c[p0], c[p1])
|
||||||
|
#define I611(p0,p1,p2) interp_16_611(c[p0], c[p1], c[p2])
|
||||||
|
#define I71(p0,p1) interp_16_71(c[p0], c[p1])
|
||||||
|
#define I772(p0,p1,p2) interp_16_772(c[p0], c[p1], c[p2])
|
||||||
|
#define I97(p0,p1) interp_16_97(c[p0], c[p1])
|
||||||
|
#define I1411(p0,p1,p2) interp_16_1411(c[p0], c[p1], c[p2])
|
||||||
|
#define I151(p0,p1) interp_16_151(c[p0], c[p1])
|
||||||
|
|
||||||
|
switch (mask) {
|
||||||
|
#include "hq2x.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef P0
|
||||||
|
#undef P1
|
||||||
|
#undef P2
|
||||||
|
#undef P3
|
||||||
|
#undef MUR
|
||||||
|
#undef MDR
|
||||||
|
#undef MDL
|
||||||
|
#undef MUL
|
||||||
|
#undef IC
|
||||||
|
#undef I11
|
||||||
|
#undef I211
|
||||||
|
#undef I31
|
||||||
|
#undef I332
|
||||||
|
#undef I431
|
||||||
|
#undef I521
|
||||||
|
#undef I53
|
||||||
|
#undef I611
|
||||||
|
#undef I71
|
||||||
|
#undef I772
|
||||||
|
#undef I97
|
||||||
|
#undef I1411
|
||||||
|
#undef I151
|
||||||
|
|
||||||
|
src0 += 1;
|
||||||
|
src1 += 1;
|
||||||
|
src2 += 1;
|
||||||
|
dst0 += 2;
|
||||||
|
dst1 += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hq2x_32_def(Uint32* dst0, Uint32* dst1, const Uint32* src0, const Uint32* src1, const Uint32* src2, Uint32 count)
|
||||||
|
{
|
||||||
|
Uint32 i;
|
||||||
|
|
||||||
|
for(i=0;i<count;++i) {
|
||||||
|
Uint8 mask;
|
||||||
|
|
||||||
|
Uint32 c[9];
|
||||||
|
|
||||||
|
c[1] = src0[0];
|
||||||
|
c[4] = src1[0];
|
||||||
|
c[7] = src2[0];
|
||||||
|
|
||||||
|
if (i>0) {
|
||||||
|
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<count-1) {
|
||||||
|
c[2] = src0[1];
|
||||||
|
c[5] = src1[1];
|
||||||
|
c[8] = src2[1];
|
||||||
|
} else {
|
||||||
|
c[2] = c[1];
|
||||||
|
c[5] = c[4];
|
||||||
|
c[8] = c[7];
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = 0;
|
||||||
|
|
||||||
|
if (interp_32_diff(c[0], c[4]))
|
||||||
|
mask |= 1 << 0;
|
||||||
|
if (interp_32_diff(c[1], c[4]))
|
||||||
|
mask |= 1 << 1;
|
||||||
|
if (interp_32_diff(c[2], c[4]))
|
||||||
|
mask |= 1 << 2;
|
||||||
|
if (interp_32_diff(c[3], c[4]))
|
||||||
|
mask |= 1 << 3;
|
||||||
|
if (interp_32_diff(c[5], c[4]))
|
||||||
|
mask |= 1 << 4;
|
||||||
|
if (interp_32_diff(c[6], c[4]))
|
||||||
|
mask |= 1 << 5;
|
||||||
|
if (interp_32_diff(c[7], c[4]))
|
||||||
|
mask |= 1 << 6;
|
||||||
|
if (interp_32_diff(c[8], c[4]))
|
||||||
|
mask |= 1 << 7;
|
||||||
|
|
||||||
|
#define P0 dst0[0]
|
||||||
|
#define P1 dst0[1]
|
||||||
|
#define P2 dst1[0]
|
||||||
|
#define P3 dst1[1]
|
||||||
|
#define MUR interp_32_diff(c[1], c[5])
|
||||||
|
#define MDR interp_32_diff(c[5], c[7])
|
||||||
|
#define MDL interp_32_diff(c[7], c[3])
|
||||||
|
#define MUL interp_32_diff(c[3], c[1])
|
||||||
|
#define IC(p0) c[p0]
|
||||||
|
#define I11(p0,p1) interp_32_11(c[p0], c[p1])
|
||||||
|
#define I211(p0,p1,p2) interp_32_211(c[p0], c[p1], c[p2])
|
||||||
|
#define I31(p0,p1) interp_32_31(c[p0], c[p1])
|
||||||
|
#define I332(p0,p1,p2) interp_32_332(c[p0], c[p1], c[p2])
|
||||||
|
#define I431(p0,p1,p2) interp_32_431(c[p0], c[p1], c[p2])
|
||||||
|
#define I521(p0,p1,p2) interp_32_521(c[p0], c[p1], c[p2])
|
||||||
|
#define I53(p0,p1) interp_32_53(c[p0], c[p1])
|
||||||
|
#define I611(p0,p1,p2) interp_32_611(c[p0], c[p1], c[p2])
|
||||||
|
#define I71(p0,p1) interp_32_71(c[p0], c[p1])
|
||||||
|
#define I772(p0,p1,p2) interp_32_772(c[p0], c[p1], c[p2])
|
||||||
|
#define I97(p0,p1) interp_32_97(c[p0], c[p1])
|
||||||
|
#define I1411(p0,p1,p2) interp_32_1411(c[p0], c[p1], c[p2])
|
||||||
|
#define I151(p0,p1) interp_32_151(c[p0], c[p1])
|
||||||
|
|
||||||
|
switch (mask) {
|
||||||
|
#include "hq2x.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef P0
|
||||||
|
#undef P1
|
||||||
|
#undef P2
|
||||||
|
#undef P3
|
||||||
|
#undef MUR
|
||||||
|
#undef MDR
|
||||||
|
#undef MDL
|
||||||
|
#undef MUL
|
||||||
|
#undef IC
|
||||||
|
#undef I11
|
||||||
|
#undef I211
|
||||||
|
#undef I31
|
||||||
|
#undef I332
|
||||||
|
#undef I431
|
||||||
|
#undef I521
|
||||||
|
#undef I53
|
||||||
|
#undef I611
|
||||||
|
#undef I71
|
||||||
|
#undef I772
|
||||||
|
#undef I97
|
||||||
|
#undef I1411
|
||||||
|
#undef I151
|
||||||
|
|
||||||
|
src0 += 1;
|
||||||
|
src1 += 1;
|
||||||
|
src2 += 1;
|
||||||
|
dst0 += 2;
|
||||||
|
dst1 += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/* LQ2x C implementation */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This effect is derived from the hq2x effect made by Maxim Stepin
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void lq2x_16_def(Uint16* dst0, Uint16* dst1, const Uint16* src0, const Uint16* src1, const Uint16* src2, Uint32 count)
|
||||||
|
{
|
||||||
|
Uint32 i;
|
||||||
|
|
||||||
|
for(i=0;i<count;++i) {
|
||||||
|
Uint8 mask;
|
||||||
|
|
||||||
|
Uint16 c[9];
|
||||||
|
|
||||||
|
c[1] = src0[0];
|
||||||
|
c[4] = src1[0];
|
||||||
|
c[7] = src2[0];
|
||||||
|
|
||||||
|
if (i>0) {
|
||||||
|
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<count-1) {
|
||||||
|
c[2] = src0[1];
|
||||||
|
c[5] = src1[1];
|
||||||
|
c[8] = src2[1];
|
||||||
|
} else {
|
||||||
|
c[2] = c[1];
|
||||||
|
c[5] = c[4];
|
||||||
|
c[8] = c[7];
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = 0;
|
||||||
|
|
||||||
|
if (c[0] != c[4])
|
||||||
|
mask |= 1 << 0;
|
||||||
|
if (c[1] != c[4])
|
||||||
|
mask |= 1 << 1;
|
||||||
|
if (c[2] != c[4])
|
||||||
|
mask |= 1 << 2;
|
||||||
|
if (c[3] != c[4])
|
||||||
|
mask |= 1 << 3;
|
||||||
|
if (c[5] != c[4])
|
||||||
|
mask |= 1 << 4;
|
||||||
|
if (c[6] != c[4])
|
||||||
|
mask |= 1 << 5;
|
||||||
|
if (c[7] != c[4])
|
||||||
|
mask |= 1 << 6;
|
||||||
|
if (c[8] != c[4])
|
||||||
|
mask |= 1 << 7;
|
||||||
|
|
||||||
|
#define P0 dst0[0]
|
||||||
|
#define P1 dst0[1]
|
||||||
|
#define P2 dst1[0]
|
||||||
|
#define P3 dst1[1]
|
||||||
|
#define MUR (c[1] != c[5])
|
||||||
|
#define MDR (c[5] != c[7])
|
||||||
|
#define MDL (c[7] != c[3])
|
||||||
|
#define MUL (c[3] != c[1])
|
||||||
|
#define IC(p0) c[p0]
|
||||||
|
#define I11(p0,p1) interp_16_11(c[p0], c[p1])
|
||||||
|
#define I211(p0,p1,p2) interp_16_211(c[p0], c[p1], c[p2])
|
||||||
|
#define I31(p0,p1) interp_16_31(c[p0], c[p1])
|
||||||
|
#define I332(p0,p1,p2) interp_16_332(c[p0], c[p1], c[p2])
|
||||||
|
#define I431(p0,p1,p2) interp_16_431(c[p0], c[p1], c[p2])
|
||||||
|
#define I521(p0,p1,p2) interp_16_521(c[p0], c[p1], c[p2])
|
||||||
|
#define I53(p0,p1) interp_16_53(c[p0], c[p1])
|
||||||
|
#define I611(p0,p1,p2) interp_16_611(c[p0], c[p1], c[p2])
|
||||||
|
#define I71(p0,p1) interp_16_71(c[p0], c[p1])
|
||||||
|
#define I772(p0,p1,p2) interp_16_772(c[p0], c[p1], c[p2])
|
||||||
|
#define I97(p0,p1) interp_16_97(c[p0], c[p1])
|
||||||
|
#define I1411(p0,p1,p2) interp_16_1411(c[p0], c[p1], c[p2])
|
||||||
|
#define I151(p0,p1) interp_16_151(c[p0], c[p1])
|
||||||
|
|
||||||
|
switch (mask) {
|
||||||
|
#include "lq2x.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef P0
|
||||||
|
#undef P1
|
||||||
|
#undef P2
|
||||||
|
#undef P3
|
||||||
|
#undef MUR
|
||||||
|
#undef MDR
|
||||||
|
#undef MDL
|
||||||
|
#undef MUL
|
||||||
|
#undef IC
|
||||||
|
#undef I11
|
||||||
|
#undef I211
|
||||||
|
#undef I31
|
||||||
|
#undef I332
|
||||||
|
#undef I431
|
||||||
|
#undef I521
|
||||||
|
#undef I53
|
||||||
|
#undef I611
|
||||||
|
#undef I71
|
||||||
|
#undef I772
|
||||||
|
#undef I97
|
||||||
|
#undef I1411
|
||||||
|
#undef I151
|
||||||
|
|
||||||
|
src0 += 1;
|
||||||
|
src1 += 1;
|
||||||
|
src2 += 1;
|
||||||
|
dst0 += 2;
|
||||||
|
dst1 += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lq2x_32_def(Uint32* dst0, Uint32* dst1, const Uint32* src0, const Uint32* src1, const Uint32* src2, Uint32 count)
|
||||||
|
{
|
||||||
|
Uint32 i;
|
||||||
|
|
||||||
|
for(i=0;i<count;++i) {
|
||||||
|
Uint8 mask;
|
||||||
|
|
||||||
|
Uint32 c[9];
|
||||||
|
|
||||||
|
c[1] = src0[0];
|
||||||
|
c[4] = src1[0];
|
||||||
|
c[7] = src2[0];
|
||||||
|
|
||||||
|
if (i>0) {
|
||||||
|
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<count-1) {
|
||||||
|
c[2] = src0[1];
|
||||||
|
c[5] = src1[1];
|
||||||
|
c[8] = src2[1];
|
||||||
|
} else {
|
||||||
|
c[2] = c[1];
|
||||||
|
c[5] = c[4];
|
||||||
|
c[8] = c[7];
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = 0;
|
||||||
|
|
||||||
|
if (c[0] != c[4])
|
||||||
|
mask |= 1 << 0;
|
||||||
|
if (c[1] != c[4])
|
||||||
|
mask |= 1 << 1;
|
||||||
|
if (c[2] != c[4])
|
||||||
|
mask |= 1 << 2;
|
||||||
|
if (c[3] != c[4])
|
||||||
|
mask |= 1 << 3;
|
||||||
|
if (c[5] != c[4])
|
||||||
|
mask |= 1 << 4;
|
||||||
|
if (c[6] != c[4])
|
||||||
|
mask |= 1 << 5;
|
||||||
|
if (c[7] != c[4])
|
||||||
|
mask |= 1 << 6;
|
||||||
|
if (c[8] != c[4])
|
||||||
|
mask |= 1 << 7;
|
||||||
|
|
||||||
|
#define P0 dst0[0]
|
||||||
|
#define P1 dst0[1]
|
||||||
|
#define P2 dst1[0]
|
||||||
|
#define P3 dst1[1]
|
||||||
|
#define MUR (c[1] != c[5])
|
||||||
|
#define MDR (c[5] != c[7])
|
||||||
|
#define MDL (c[7] != c[3])
|
||||||
|
#define MUL (c[3] != c[1])
|
||||||
|
#define IC(p0) c[p0]
|
||||||
|
#define I11(p0,p1) interp_32_11(c[p0], c[p1])
|
||||||
|
#define I211(p0,p1,p2) interp_32_211(c[p0], c[p1], c[p2])
|
||||||
|
#define I31(p0,p1) interp_32_31(c[p0], c[p1])
|
||||||
|
#define I332(p0,p1,p2) interp_32_332(c[p0], c[p1], c[p2])
|
||||||
|
#define I431(p0,p1,p2) interp_32_431(c[p0], c[p1], c[p2])
|
||||||
|
#define I521(p0,p1,p2) interp_32_521(c[p0], c[p1], c[p2])
|
||||||
|
#define I53(p0,p1) interp_32_53(c[p0], c[p1])
|
||||||
|
#define I611(p0,p1,p2) interp_32_611(c[p0], c[p1], c[p2])
|
||||||
|
#define I71(p0,p1) interp_32_71(c[p0], c[p1])
|
||||||
|
#define I772(p0,p1,p2) interp_32_772(c[p0], c[p1], c[p2])
|
||||||
|
#define I97(p0,p1) interp_32_97(c[p0], c[p1])
|
||||||
|
#define I1411(p0,p1,p2) interp_32_1411(c[p0], c[p1], c[p2])
|
||||||
|
#define I151(p0,p1) interp_32_151(c[p0], c[p1])
|
||||||
|
|
||||||
|
switch (mask) {
|
||||||
|
#include "lq2x.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef P0
|
||||||
|
#undef P1
|
||||||
|
#undef P2
|
||||||
|
#undef P3
|
||||||
|
#undef MUR
|
||||||
|
#undef MDR
|
||||||
|
#undef MDL
|
||||||
|
#undef MUL
|
||||||
|
#undef IC
|
||||||
|
#undef I11
|
||||||
|
#undef I211
|
||||||
|
#undef I31
|
||||||
|
#undef I332
|
||||||
|
#undef I431
|
||||||
|
#undef I521
|
||||||
|
#undef I53
|
||||||
|
#undef I611
|
||||||
|
#undef I71
|
||||||
|
#undef I772
|
||||||
|
#undef I97
|
||||||
|
#undef I1411
|
||||||
|
#undef I151
|
||||||
|
|
||||||
|
src0 += 1;
|
||||||
|
src1 += 1;
|
||||||
|
src2 += 1;
|
||||||
|
dst0 += 2;
|
||||||
|
dst1 += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hq2x16(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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
*/
|
1284
src/sdl2/filter/lq2x.h
Normal file
1284
src/sdl2/filter/lq2x.h
Normal file
File diff suppressed because it is too large
Load diff
15
src/sdl2/filter/main.c
Normal file
15
src/sdl2/filter/main.c
Normal file
|
@ -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
|
||||||
|
}
|
183
src/sdl2/hwsym_sdl.c
Normal file
183
src/sdl2/hwsym_sdl.c
Normal file
|
@ -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
|
23
src/sdl2/hwsym_sdl.h
Normal file
23
src/sdl2/hwsym_sdl.h
Normal file
|
@ -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);
|
38
src/sdl2/i_cdmus.c
Normal file
38
src/sdl2/i_cdmus.c
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#include "../command.h"
|
||||||
|
#include "../s_sound.h"
|
||||||
|
#include "../i_sound.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// CD MUSIC I/O
|
||||||
|
//
|
||||||
|
|
||||||
|
UINT8 cdaudio_started = 0;
|
||||||
|
|
||||||
|
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};
|
||||||
|
|
||||||
|
|
||||||
|
void I_InitCD(void){}
|
||||||
|
|
||||||
|
void I_StopCD(void){}
|
||||||
|
|
||||||
|
void I_PauseCD(void){}
|
||||||
|
|
||||||
|
void I_ResumeCD(void){}
|
||||||
|
|
||||||
|
void I_ShutdownCD(void){}
|
||||||
|
|
||||||
|
void I_UpdateCD(void){}
|
||||||
|
|
||||||
|
void I_PlayCD(UINT8 track, UINT8 looping)
|
||||||
|
{
|
||||||
|
(void)track;
|
||||||
|
(void)looping;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SetVolumeCD(int volume)
|
||||||
|
{
|
||||||
|
(void)volume;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
247
src/sdl2/i_main.c
Normal file
247
src/sdl2/i_main.c
Normal file
|
@ -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 <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WII
|
||||||
|
#include <limits.h>
|
||||||
|
#include <network.h>
|
||||||
|
#include <fat.h>
|
||||||
|
#ifdef REMOTE_DEBUGGING
|
||||||
|
#include <debug.h>
|
||||||
|
#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 <pspmoduleinfo.h>
|
||||||
|
#include <pspthreadman.h>
|
||||||
|
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 <arch/arch.h>
|
||||||
|
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
|
442
src/sdl2/i_net.c
Normal file
442
src/sdl2/i_net.c
Normal file
|
@ -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>");
|
||||||
|
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
|
3115
src/sdl2/i_system.c
Normal file
3115
src/sdl2/i_system.c
Normal file
File diff suppressed because it is too large
Load diff
340
src/sdl2/i_ttf.c
Normal file
340
src/sdl2/i_ttf.c
Normal file
|
@ -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 <sysutil/video.h>
|
||||||
|
#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
|
88
src/sdl2/i_ttf.h
Normal file
88
src/sdl2/i_ttf.h
Normal file
|
@ -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
|
186
src/sdl2/i_video.c
Normal file
186
src/sdl2/i_video.c
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
#include "../doomdef.h"
|
||||||
|
#include "../command.h"
|
||||||
|
#include "../i_video.h"
|
||||||
|
#include "../d_clisrv.h"
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
typedef struct sdlmode_s
|
||||||
|
{
|
||||||
|
Uint16 w;
|
||||||
|
Uint16 h;
|
||||||
|
} sdlmode_t;
|
||||||
|
|
||||||
|
rendermode_t rendermode = render_soft;
|
||||||
|
|
||||||
|
boolean highcolor = true;
|
||||||
|
|
||||||
|
boolean allow_fullscreen = true;
|
||||||
|
|
||||||
|
consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
static SDL_bool graphicsInitialized = SDL_FALSE;
|
||||||
|
|
||||||
|
// SDL2 vars
|
||||||
|
static SDL_Window *window;
|
||||||
|
static SDL_Renderer *renderer;
|
||||||
|
static Uint16 logicalWidth; // real for windowed
|
||||||
|
static Uint16 logicalHeight; // real for windowed
|
||||||
|
|
||||||
|
#define SDLI_MAX_MODES 32
|
||||||
|
static int numVidModes = 0;
|
||||||
|
static sdlmode_t sdlmodes[SDLI_MAX_MODES];
|
||||||
|
|
||||||
|
static SDL_bool Impl_CreateWindow()
|
||||||
|
{
|
||||||
|
window = SDL_CreateWindow("Sonic Robo Blast 2", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 200, 0);
|
||||||
|
renderer = SDL_CreateRenderer(window, -1, 0);
|
||||||
|
if (window == NULL || renderer == NULL)
|
||||||
|
{
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static SDL_bool Impl_DestroyWindow()
|
||||||
|
{
|
||||||
|
if (window != NULL)
|
||||||
|
{
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
}
|
||||||
|
window = NULL;
|
||||||
|
if (renderer != NULL)
|
||||||
|
{
|
||||||
|
SDL_DestroyRenderer(renderer);
|
||||||
|
}
|
||||||
|
renderer = NULL;
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SDL_bool Impl_SetMode(Uint16 width, Uint16 height, SDL_bool fullscreen)
|
||||||
|
{
|
||||||
|
logicalWidth = width;
|
||||||
|
logicalHeight = height;
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SDL_bool Impl_AddSDLMode(Uint16 width, Uint16 height)
|
||||||
|
{
|
||||||
|
if (numVidModes >= SDLI_MAX_MODES)
|
||||||
|
{
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
numVidModes += 1;
|
||||||
|
sdlmodes[numVidModes].w = width;
|
||||||
|
sdlmodes[numVidModes].h = height;
|
||||||
|
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_StartupGraphics(void)
|
||||||
|
{
|
||||||
|
if (graphicsInitialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dedicated)
|
||||||
|
{
|
||||||
|
rendermode = render_none;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
|
||||||
|
{
|
||||||
|
if (!SDL_WasInit(SDL_INIT_VIDEO))
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("Failed to initialize SDL video: %s\n"), SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add 'supported' modes
|
||||||
|
#ifdef ANDROID
|
||||||
|
Impl_AddSDLMode(640, 400);
|
||||||
|
#else
|
||||||
|
Impl_AddSDLMode(320, 200);
|
||||||
|
Impl_AddSDLMode(640, 400);
|
||||||
|
Impl_AddSDLMode(1280, 800);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!Impl_CreateWindow() || !Impl_SetMode(640, 400, SDL_FALSE))
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("SDL: Could not create window and set initial mode: %s\n"), SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphicsInitialized = SDL_TRUE;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_ShutdownGraphics(void)
|
||||||
|
{
|
||||||
|
if (!graphicsInitialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Impl_DestroyWindow();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_SetPalette(RGBA_t *palette)
|
||||||
|
{
|
||||||
|
(void)palette;
|
||||||
|
}
|
||||||
|
|
||||||
|
INT32 VID_NumModes(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
INT32 VID_GetModeForSize(INT32 w, INT32 h)
|
||||||
|
{
|
||||||
|
(void)w;
|
||||||
|
(void)h;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VID_PrepareModeList(void){}
|
||||||
|
|
||||||
|
INT32 VID_SetMode(INT32 modenum)
|
||||||
|
{
|
||||||
|
(void)modenum;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *VID_GetModeName(INT32 modenum)
|
||||||
|
{
|
||||||
|
(void)modenum;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_UpdateNoBlit(void){}
|
||||||
|
|
||||||
|
void I_FinishUpdate(void){}
|
||||||
|
|
||||||
|
void I_UpdateNoVsync(void) {}
|
||||||
|
|
||||||
|
void I_WaitVBL(INT32 count)
|
||||||
|
{
|
||||||
|
(void)count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_ReadScreen(UINT8 *scr)
|
||||||
|
{
|
||||||
|
(void)scr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_BeginRead(void){}
|
||||||
|
|
||||||
|
void I_EndRead(void){}
|
||||||
|
|
0
src/sdl2/macosx/English.lproj/InfoPlist.strings
Normal file
0
src/sdl2/macosx/English.lproj/InfoPlist.strings
Normal file
28
src/sdl2/macosx/Info.plist
Normal file
28
src/sdl2/macosx/Info.plist
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>English</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${EXECUTABLE_NAME}</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>Srb2mac.icns</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>com.yourcompany.Srb2mac</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${PRODUCT_NAME}</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>NSMainNibFile</key>
|
||||||
|
<string>SDLMain</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string>NSApplication</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
BIN
src/sdl2/macosx/Srb2mac.icns
Normal file
BIN
src/sdl2/macosx/Srb2mac.icns
Normal file
Binary file not shown.
3546
src/sdl2/macosx/Srb2mac.pbproj/project.pbxproj
Normal file
3546
src/sdl2/macosx/Srb2mac.pbproj/project.pbxproj
Normal file
File diff suppressed because it is too large
Load diff
1508
src/sdl2/macosx/Srb2mac.xcodeproj/project.pbxproj
Normal file
1508
src/sdl2/macosx/Srb2mac.xcodeproj/project.pbxproj
Normal file
File diff suppressed because it is too large
Load diff
45
src/sdl2/macosx/mac_alert.c
Normal file
45
src/sdl2/macosx/mac_alert.c
Normal file
|
@ -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 <CoreFoundation/CoreFoundation.h>
|
||||||
|
|
||||||
|
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
|
27
src/sdl2/macosx/mac_alert.h
Normal file
27
src/sdl2/macosx/mac_alert.h
Normal file
|
@ -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
|
824
src/sdl2/mixer_sound.c
Normal file
824
src/sdl2/mixer_sound.c
Normal file
|
@ -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(frac, samples) + 1; // add 1 sample for security! the code below rounds up.
|
||||||
|
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
|
315
src/sdl2/ogl_sdl.c
Normal file
315
src/sdl2/ogl_sdl.c
Normal file
|
@ -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 <stdarg.h>
|
||||||
|
#if defined (_WIN32) && !defined (__CYGWIN__)
|
||||||
|
#include <direct.h>
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#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<6E>de palette, il faut recharger toutes les textures
|
||||||
|
// jaja, und noch viel mehr ;-)
|
||||||
|
Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //HWRENDER
|
||||||
|
#endif //SDL
|
30
src/sdl2/ogl_sdl.h
Normal file
30
src/sdl2/ogl_sdl.h
Normal file
|
@ -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
|
2030
src/sdl2/sdl_sound.c
Normal file
2030
src/sdl2/sdl_sound.c
Normal file
File diff suppressed because it is too large
Load diff
65
src/sdl2/sdlmain.h
Normal file
65
src/sdl2/sdlmain.h
Normal file
|
@ -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
|
BIN
src/sdl2/srb2.ttf
Normal file
BIN
src/sdl2/srb2.ttf
Normal file
Binary file not shown.
Loading…
Reference in a new issue