--- deliantra/Deliantra-Client/Client.xs 2007/04/20 17:25:41 1.184 +++ deliantra/Deliantra-Client/Client.xs 2007/07/17 17:39:06 1.201 @@ -8,6 +8,11 @@ # pragma warning(disable:4761) #endif +//#define DEBUG 1 +#if DEBUG +# include +#endif + #include "EXTERN.h" #include "perl.h" #include "XSUB.h" @@ -58,6 +63,8 @@ # define PARACHUTE 0 #endif +static AV *texture_av; + static struct { #define GL_FUNC(ptr,name) ptr name; @@ -65,7 +72,8 @@ #undef GL_FUNC } gl; -static void gl_BlendFuncSeparate (GLenum sa, GLenum da, GLenum saa, GLenum daa) +static void +gl_BlendFuncSeparate (GLenum sa, GLenum da, GLenum saa, GLenum daa) { if (gl.BlendFuncSeparate) gl.BlendFuncSeparate (sa, da, saa, daa); @@ -75,6 +83,30 @@ glBlendFunc (sa, da); } +static GLuint +gen_texture () +{ + GLuint name; + + if (AvFILL (texture_av) >= 0) + name = (GLuint)(size_t)av_pop (texture_av); + else + glGenTextures (1, &name); + + return name; +} + +static void +del_texture (GLuint name) +{ + /* make a half-assed attempt at returning the memory used by the texture */ + /* textures are frequently being reused by cfplus anyway */ + /*glBindTexture (GL_TEXTURE_2D, name);*/ + /*glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, 0, 0, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0);*/ + av_push (texture_av, (SV *)(size_t)name); + glDeleteTextures (1, &name); +} + #include "texcache.c" #include "pango-font.c" @@ -402,17 +434,12 @@ #define SDLK_MODIFIER_MIN 300 #define SDLK_MODIFIER_MAX 314 -static AV *texture_av; - MODULE = CFPlus PACKAGE = CFPlus PROTOTYPES: ENABLE BOOT: { - texture_av = newAV (); - AvREAL_off (texture_av); - HV *stash = gv_stashpv ("CFPlus", 1); static const struct { const char *name; @@ -562,6 +589,9 @@ opengl_context = pango_opengl_font_map_create_context ((PangoOpenGLFontMap *)opengl_fontmap); } +char * +SDL_GetError () + int SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | PARACHUTE) @@ -569,22 +599,22 @@ SDL_Quit () void -SDL_ListModes () +SDL_ListModes (int rgb, int alpha) PPCODE: { SDL_Rect **m; - SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5); - SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5); - SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5); - SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 1); + SDL_GL_SetAttribute (SDL_GL_RED_SIZE , rgb); + SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, rgb); + SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE , rgb); + SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, alpha); SDL_GL_SetAttribute (SDL_GL_BUFFER_SIZE, 15); - SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 0); + SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE , 0); - SDL_GL_SetAttribute (SDL_GL_ACCUM_RED_SIZE, 0); + SDL_GL_SetAttribute (SDL_GL_ACCUM_RED_SIZE , 0); SDL_GL_SetAttribute (SDL_GL_ACCUM_GREEN_SIZE, 0); - SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE, 0); + SDL_GL_SetAttribute (SDL_GL_ACCUM_BLUE_SIZE , 0); SDL_GL_SetAttribute (SDL_GL_ACCUM_ALPHA_SIZE, 0); SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); @@ -593,39 +623,51 @@ SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 1); #endif - SDL_EnableUNICODE (1); - SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); - m = SDL_ListModes (0, SDL_FULLSCREEN | SDL_OPENGL); if (m && m != (SDL_Rect **)-1) while (*m) { - AV *av = newAV (); - av_push (av, newSViv ((*m)->w)); - av_push (av, newSViv ((*m)->h)); - XPUSHs (sv_2mortal (newRV_noinc ((SV *)av))); + if ((*m)->w >= 640 && (*m)->h >= 480) + { + AV *av = newAV (); + av_push (av, newSViv ((*m)->w)); + av_push (av, newSViv ((*m)->h)); + av_push (av, newSViv (rgb)); + av_push (av, newSViv (alpha)); + XPUSHs (sv_2mortal (newRV_noinc ((SV *)av))); + } ++m; } } -char * -SDL_GetError () - int -SDL_SetVideoMode (int w, int h, int fullscreen) +SDL_SetVideoMode (int w, int h, int rgb, int alpha, int fullscreen) CODE: +{ + SDL_EnableUNICODE (1); + SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + + SDL_GL_SetAttribute (SDL_GL_RED_SIZE , rgb); + SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, rgb); + SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE , rgb); + SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, alpha); + RETVAL = !!SDL_SetVideoMode ( w, h, 0, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0) ); + if (RETVAL) { + av_clear (texture_av); + SDL_WM_SetCaption ("Crossfire+ Client " VERSION, "Crossfire+"); -# define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name); -# include "glfunc.h" -# undef GL_FUNC +#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name); +#include "glfunc.h" +#undef GL_FUNC } +} OUTPUT: RETVAL @@ -635,13 +677,17 @@ char * SDL_GetKeyName (int sym) +int +SDL_GetAppState () + void -SDL_PollEvent () +poll_events () PPCODE: { SDL_Event ev; - while (SDL_PollEvent (&ev)) + SDL_PumpEvents (); + while (SDL_PeepEvents (&ev, 1, SDL_GETEVENT, SDL_ALLEVENTS) > 0) { HV *hv = newHV (); hv_store (hv, "type", 4, newSViv (ev.type), 0); @@ -663,13 +709,31 @@ break; case SDL_MOUSEMOTION: - hv_store (hv, "mod", 3, newSViv (SDL_GetModState ()), 0); + { + int state = ev.motion.state; + int x = ev.motion.x; + int y = ev.motion.y; + int xrel = ev.motion.xrel; + int yrel = ev.motion.yrel; + + /* do simplistic event compression */ + while (SDL_PeepEvents (&ev, 1, SDL_PEEKEVENT, SDL_EVENTMASK (SDL_MOUSEMOTION)) > 0 + && state == ev.motion.state) + { + xrel += ev.motion.xrel; + yrel += ev.motion.yrel; + x = ev.motion.x; + y = ev.motion.y; + SDL_PeepEvents (&ev, 1, SDL_GETEVENT, SDL_EVENTMASK (SDL_MOUSEMOTION)); + } - hv_store (hv, "state", 5, newSViv (ev.motion.state), 0); - hv_store (hv, "x", 1, newSViv (ev.motion.x), 0); - hv_store (hv, "y", 1, newSViv (ev.motion.y), 0); - hv_store (hv, "xrel", 4, newSViv (ev.motion.xrel), 0); - hv_store (hv, "yrel", 4, newSViv (ev.motion.yrel), 0); + hv_store (hv, "mod", 3, newSViv (SDL_GetModState ()), 0); + hv_store (hv, "state", 5, newSViv (state), 0); + hv_store (hv, "x", 1, newSViv (x), 0); + hv_store (hv, "y", 1, newSViv (y), 0); + hv_store (hv, "xrel", 4, newSViv (xrel), 0); + hv_store (hv, "yrel", 4, newSViv (yrel), 0); + } break; case SDL_MOUSEBUTTONDOWN: @@ -859,6 +923,15 @@ _exit (retval); #endif +void +debug () + CODE: +{ +#if DEBUG + VALGRIND_DO_LEAK_CHECK; +#endif +} + MODULE = CFPlus PACKAGE = CFPlus::Font CFPlus::Font @@ -1183,6 +1256,8 @@ MODULE = CFPlus PACKAGE = CFPlus::Texture +int minpot (int n) + void pad2pot (SV *data_, SV *w_, SV *h_) CODE: @@ -1269,6 +1344,17 @@ } } +IV texture_valid_2d (GLint internalformat, GLsizei w, GLsizei h, GLenum format, GLenum type) + CODE: +{ + GLint width; + glTexImage2D (GL_PROXY_TEXTURE_2D, 0, internalformat, w, h, 0, format, type, 0); + glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); + RETVAL = width > 0; +} + OUTPUT: + RETVAL + MODULE = CFPlus PACKAGE = CFPlus::Map CFPlus::Map @@ -1398,12 +1484,12 @@ if (dx > 0) map_blank (self, self->x, self->y, dx, self->h); else if (dx < 0) - map_blank (self, self->x + self->w + dx + 1, self->y, -dx, self->h); + map_blank (self, self->x + self->w + dx, self->y, -dx, self->h); if (dy > 0) map_blank (self, self->x, self->y, self->w, dy); else if (dy < 0) - map_blank (self, self->x, self->y + self->h + dy + 1, self->w, -dy); + map_blank (self, self->x, self->y + self->h + dy, self->w, -dy); self->ox += dx; self->x += dx; self->oy += dy; self->y += dy; @@ -1742,7 +1828,7 @@ if (!(bits & 0x1000) && skey->level == level - && level >= smooth_max [skey->x][skey->y]) + && level > smooth_max [skey->x][skey->y]) { maptex tex = self->tex [skey->tile]; int px = (((int)skey->x) - 1) * T; @@ -1890,7 +1976,7 @@ } void -fow_texture (CFPlus::Map self, int mx, int my, int sw, int sh) +fow_texture (CFPlus::Map self, int mx, int my, int sw, int sh, int smoothing, const char *matrix) PPCODE: { int x, y; @@ -1921,6 +2007,36 @@ } } + if (smoothing) + { + SV *darkness2_sv = sv_2mortal (newSV (sw4 * sh)); + uint8_t *darkness2 = (uint8_t *)SvPVX (darkness2_sv); + + SvPOK_only (darkness2_sv); + SvCUR_set (darkness2_sv, sw4 * sh); + + for (y = 0; y < sh; ++y) + for (x = 0; x < sw4; ++x) + { + float *f = (float *)matrix; + int dx, dy; + float sum = 0.f; + + for (dy = -1; dy <= 1; ++dy) + for (dx = -1; dx <= 1; ++dx) + { + unsigned int x2 = x + dx; + unsigned int y2 = y + dy; + + sum += (x2 < sw && y2 < sh ? darkness [y2 * sw4 + x2] : 255) * *f++; + } + + darkness2 [y * sw4 + x] = sum > 255. ? 255. : sum; + } + + darkness_sv = darkness2_sv; + } + EXTEND (SP, 3); PUSHs (sv_2mortal (newSViv (sw4))); PUSHs (sv_2mortal (newSViv (sh))); @@ -2103,6 +2219,13 @@ OUTPUT: RETVAL +int +fade_out (int ms) + CODE: + RETVAL = Mix_FadeOutMusic (ms); + OUTPUT: + RETVAL + CFPlus::MixMusic new_from_file (SV *class, char *path) CODE: @@ -2122,6 +2245,13 @@ OUTPUT: RETVAL +int +fade_in_pos (CFPlus::MixMusic self, int loops, int ms, double position) + CODE: + RETVAL = Mix_FadeInMusicPos (self, loops, ms, position); + OUTPUT: + RETVAL + MODULE = CFPlus PACKAGE = CFPlus::OpenGL BOOT: @@ -2132,6 +2262,9 @@ IV iv; } *civ, const_iv[] = { # define const_iv(name) { # name, (IV)name } + const_iv (GL_VENDOR), + const_iv (GL_VERSION), + const_iv (GL_EXTENSIONS), const_iv (GL_COLOR_MATERIAL), const_iv (GL_SMOOTH), const_iv (GL_FLAT), @@ -2168,6 +2301,8 @@ const_iv (GL_FLOAT), const_iv (GL_UNSIGNED_INT_8_8_8_8_REV), const_iv (GL_COMPILE), + const_iv (GL_PROXY_TEXTURE_1D), + const_iv (GL_PROXY_TEXTURE_2D), const_iv (GL_TEXTURE_1D), const_iv (GL_TEXTURE_2D), const_iv (GL_TEXTURE_ENV), @@ -2217,6 +2352,9 @@ for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); + + texture_av = newAV (); + AvREAL_off (texture_av); } char * @@ -2240,6 +2378,20 @@ OUTPUT: RETVAL +const char *glGetString (GLenum pname) + +GLint glGetInteger (GLenum pname) + CODE: + glGetIntegerv (pname, &RETVAL); + OUTPUT: + RETVAL + +GLdouble glGetDouble (GLenum pname) + CODE: + glGetDoublev (pname, &RETVAL); + OUTPUT: + RETVAL + int glGetError () void glFinish () @@ -2371,32 +2523,20 @@ void glDrawPixels (int width, int height, int format, int type, char *pixels) +void glPixelZoom (float x, float y) + void glCopyPixels (int x, int y, int width, int height, int type = GL_COLOR) int glGenTexture () CODE: -{ - GLuint name; - if (AvFILL (texture_av) >= 0) - name = (GLuint)av_pop (texture_av); - else - glGenTextures (1, &name); - RETVAL = name; -} + RETVAL = gen_texture (); OUTPUT: RETVAL void glDeleteTexture (int name) CODE: -{ - /* make a half-assed attempt at returning the memory used by the texture */ - /* textures are frequently being reused by cfplus anyway */ - glBindTexture (GL_TEXTURE_2D, name); - glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, 0, 0, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0); - av_push (texture_av, (SV *)name); - /*glDeleteTextures (1, &name_);*/ -} - + del_texture (name); + int glGenList () CODE: RETVAL = glGenLists (1);