Initial SDL2 renderer impmlementation work.

This commit is contained in:
Ronald Kinard 2014-03-19 02:31:50 -05:00
parent 2fed5d1270
commit 2a827a98bb
87 changed files with 34394 additions and 4 deletions

View file

@ -5,7 +5,8 @@ if [ x"$1" != x ]; then
fi
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
// Do not edit! This file was autogenerated

View file

@ -202,7 +202,7 @@ LIBS+=-lm
endif
ifdef SDL
include sdl/Makefile.cfg
include sdl2/Makefile.cfg
endif #ifdef SDL
ifdef DISTCC

View file

@ -230,7 +230,6 @@ ifdef DUMMY
BIN:=$(BIN)/dummy
else
ifdef LINUX
INTERFACE=sdl
NASMFORMAT=elf -DLINUX
SDL=1
ifndef NOGETTEXT
@ -387,7 +386,7 @@ OBJDUMP_OPTS?=--wide --source --line-numbers
LD=$(CC)
ifdef SDL
INTERFACE=sdl
INTERFACE=sdl2
OBJDIR:=$(OBJDIR)/SDL
endif

View file

@ -49,6 +49,7 @@
#ifdef SDL
#include "sdl/hwsym_sdl.h"
typedef off_t off64_t;
#endif
#if defined (_WIN32)

506
src/sdl2/IMG_xpm.c Normal file
View 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
View 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
View 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
View 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
View 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 ",
" { ",
" ",
" ",
" "};

View 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

View 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

View 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;
}

View file

@ -0,0 +1,7 @@
/* Include the SDL main definition header */
#include "SDL_main.h"
void XBoxStartup()
{
SDL_main(0, NULL); /// \todo ?
}

View 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;
}

View 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

Binary file not shown.

447
src/sdl2/SRB2CE/cehelp.c Normal file
View 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
View 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
View file

@ -0,0 +1 @@
/scramble

BIN
src/sdl2/SRB2DC/IP.BIN Normal file

Binary file not shown.

View 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

Binary file not shown.

19
src/sdl2/SRB2DC/VMU.xbm Normal file
View 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
View 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
View 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
View 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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View 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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View file

@ -0,0 +1,2 @@
/psp-prxsign
/psp-prxsign.exe

View 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)

View 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];
}
}

View 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

View 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

View 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;
}

View 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

View 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)

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

18
src/sdl2/SRB2WII/meta.xml Normal file
View 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>

View 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

View 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

View 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

File diff suppressed because it is too large Load diff

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

File diff suppressed because it is too large Load diff

74
src/sdl2/Srb2SDL.dsw Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

38
src/sdl2/dosstr.c Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

212
src/sdl2/filter/filters.h Normal file
View 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

File diff suppressed because it is too large Load diff

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
View 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
View 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

File diff suppressed because it is too large Load diff

15
src/sdl2/filter/main.c Normal file
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

340
src/sdl2/i_ttf.c Normal file
View 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
View 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
View 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){}

View 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>

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View 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

View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

65
src/sdl2/sdlmain.h Normal file
View 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

Binary file not shown.