--- deliantra/Deliantra-Client/Client.xs 2006/04/20 08:11:56 1.55 +++ deliantra/Deliantra-Client/Client.xs 2006/05/06 20:14:57 1.74 @@ -35,22 +35,45 @@ typedef signed int int32_t; #endif +#include "glext.h" + #define FOW_DARKNESS 32 #define MAP_EXTEND_X 32 #define MAP_EXTEND_Y 512 +#define MIN_FONT_HEIGHT 10 + +#define GL_CALL(type,func,args) \ + { \ + static int init_; \ + static type fptr_; \ + \ + if (!init_) \ + { \ + init_ = 1; \ + fptr_ = (type)SDL_GL_GetProcAddress (# func); \ + } \ + \ + if (fptr_) \ + fptr_ args; \ + } + typedef Mix_Chunk *CFClient__MixChunk; typedef Mix_Music *CFClient__MixMusic; -static PangoContext *context; -static PangoFontMap *fontmap; +typedef PangoFontDescription *CFClient__Font; typedef struct cf_layout { PangoLayout *pl; int base_height; + CFClient__Font font; } *CFClient__Layout; +static CFClient__Font default_font; +static PangoContext *context; +static PangoFontMap *fontmap; + static void substitute_func (FcPattern *pattern, gpointer data) { @@ -59,27 +82,22 @@ } static void -layout_update (CFClient__Layout self) +layout_update_font (CFClient__Layout self) { /* use a random scale factor to account for unknown descenders, 0.8 works * reasonably well with bitstream vera */ - PangoFontDescription *font = pango_context_get_font_description (context); + PangoFontDescription *font = self->font ? self->font : default_font; - int height = self->base_height * (PANGO_SCALE * 8 / 10); + pango_font_description_set_absolute_size (font, + MAX (MIN_FONT_HEIGHT, self->base_height) * (PANGO_SCALE * 8 / 10)); - if (pango_font_description_get_size (font) != height) - { - pango_font_description_set_absolute_size (font, height); - pango_layout_context_changed (self->pl); - } + pango_layout_set_font_description (self->pl, font); } static void layout_get_pixel_size (CFClient__Layout self, int *w, int *h) { - layout_update (self); - pango_layout_get_pixel_size (self->pl, w, h); *w = (*w + 3) & ~3; @@ -241,6 +259,32 @@ } } +static void +music_finished () +{ + SDL_UserEvent ev; + + ev.type = SDL_USEREVENT; + ev.code = 0; + ev.data1 = 0; + ev.data2 = 0; + + SDL_PushEvent ((SDL_Event *)&ev); +} + +static void +channel_finished (int channel) +{ + SDL_UserEvent ev; + + ev.type = SDL_USEREVENT; + ev.code = 1; + ev.data1 = (void *)(long)channel; + ev.data2 = 0; + + SDL_PushEvent ((SDL_Event *)&ev); +} + MODULE = CFClient PACKAGE = CFClient PROTOTYPES: ENABLE @@ -428,6 +472,7 @@ { HV *hv = newHV (); hv_store (hv, "type", 4, newSViv (ev.type), 0); + switch (ev.type) { case SDL_KEYDOWN: @@ -457,6 +502,13 @@ hv_store (hv, "state", 5, newSViv (ev.button.state), 0); hv_store (hv, "x", 1, newSViv (ev.button.x), 0); hv_store (hv, "y", 1, newSViv (ev.button.y), 0); + break; + + case SDL_USEREVENT: + hv_store (hv, "code", 4, newSViv (ev.user.code), 0); + hv_store (hv, "data1", 5, newSViv ((IV)ev.user.data1), 0); + hv_store (hv, "data2", 5, newSViv ((IV)ev.user.data2), 0); + break; } XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); @@ -464,7 +516,10 @@ } int -Mix_OpenAudio (int frequency = 22050, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 512) +Mix_OpenAudio (int frequency = 48000, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 2048) + POSTCALL: + Mix_HookMusicFinished (music_finished); + Mix_ChannelFinished (channel_finished); void Mix_CloseAudio () @@ -499,17 +554,6 @@ FcConfigAppFontAddFile (0, (const FcChar8 *)file); /* no idea wether this is required */ void -set_font (char *file) - CODE: -{ - int count; - FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)file, 0, 0, &count); - PangoFontDescription *font = pango_fc_font_description_from_pattern (pattern, 0); - FcPatternDestroy (pattern); - pango_context_set_font_description (context, font); -} - -void load_image_inline (SV *image_) ALIAS: load_image_file = 1 @@ -599,6 +643,15 @@ } void +error (char *message) + CODE: +#ifdef _WIN32 + MessageBox (0, message, "Crossfire+ Error", MB_OK | MB_ICONERROR | MB_SETFOREGROUND); +#else + fprintf (stderr, "ERROR: %s\n", message); +#endif + +void fatal (char *message) CODE: #ifdef _WIN32 @@ -608,15 +661,41 @@ #endif exit (1); +MODULE = CFClient PACKAGE = CFClient::Font + +CFClient::Font +new_from_file (SV *class, char *path, int id = 0) + CODE: +{ + int count; + FcPattern *pattern = FcFreeTypeQuery ((const FcChar8 *)path, id, 0, &count); + RETVAL = pango_fc_font_description_from_pattern (pattern, 0); + FcPatternDestroy (pattern); +} + OUTPUT: + RETVAL + +void +DESTROY (CFClient::Font self) + CODE: + pango_font_description_free (self); + +void +make_default (CFClient::Font self) + CODE: + default_font = self; + MODULE = CFClient PACKAGE = CFClient::Layout CFClient::Layout -new (SV *class, int base_height = 10) +new (SV *class, int base_height = MIN_FONT_HEIGHT) CODE: New (0, RETVAL, 1, struct cf_layout); - RETVAL->base_height = base_height; RETVAL->pl = pango_layout_new (context); + RETVAL->base_height = base_height; + RETVAL->font = 0; pango_layout_set_wrap (RETVAL->pl, PANGO_WRAP_WORD_CHAR); + pango_layout_set_font_description (RETVAL->pl, default_font); OUTPUT: RETVAL @@ -655,9 +734,22 @@ RETVAL void +set_font (CFClient::Layout self, CFClient::Font font = 0) + CODE: + if (self->font != font) + { + self->font = font; + layout_update_font (self); + } + +void set_height (CFClient::Layout self, int base_height) CODE: - self->base_height = base_height; + if (self->base_height != base_height) + { + self->base_height = base_height; + layout_update_font (self); + } void set_width (CFClient::Layout self, int max_width = -1) @@ -670,7 +762,6 @@ { int w, h; - layout_update (self); layout_get_pixel_size (self, &w, &h); EXTEND (SP, 2); @@ -683,10 +774,7 @@ CODE: { int index, trailing; - - layout_update (self); pango_layout_xy_to_index (self->pl, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing); - RETVAL = index; } OUTPUT: @@ -697,7 +785,6 @@ PPCODE: { PangoRectangle strong_pos; - layout_update (self); pango_layout_get_cursor_pos (self->pl, index, &strong_pos, 0); EXTEND (SP, 3); @@ -714,7 +801,6 @@ int w, h; FT_Bitmap bitmap; - layout_update (self); layout_get_pixel_size (self, &w, &h); retval = newSV (w * h); @@ -1286,14 +1372,19 @@ const_iv (GL_COLOR_MATERIAL), const_iv (GL_SMOOTH), const_iv (GL_FLAT), + const_iv (GL_DITHER), const_iv (GL_BLEND), + const_iv (GL_SCISSOR_TEST), const_iv (GL_AND), + const_iv (GL_ONE), + const_iv (GL_ZERO), const_iv (GL_SRC_ALPHA), + const_iv (GL_SRC_ALPHA_SATURATE), const_iv (GL_ONE_MINUS_SRC_ALPHA), + const_iv (GL_ONE_MINUS_DST_ALPHA), const_iv (GL_RGB), const_iv (GL_RGBA), const_iv (GL_UNSIGNED_BYTE), - const_iv (GL_ALPHA4), const_iv (GL_ALPHA), const_iv (GL_FLOAT), const_iv (GL_UNSIGNED_INT_8_8_8_8_REV), @@ -1310,12 +1401,19 @@ const_iv (GL_REPEAT), const_iv (GL_NEAREST), const_iv (GL_LINEAR), + const_iv (GL_NEAREST_MIPMAP_NEAREST), + const_iv (GL_LINEAR_MIPMAP_NEAREST), + const_iv (GL_NEAREST_MIPMAP_LINEAR), + const_iv (GL_LINEAR_MIPMAP_LINEAR), + const_iv (GL_GENERATE_MIPMAP), const_iv (GL_MODULATE), + const_iv (GL_DECAL), const_iv (GL_REPLACE), const_iv (GL_COLOR_BUFFER_BIT), const_iv (GL_PROJECTION), const_iv (GL_MODELVIEW), const_iv (GL_COLOR_LOGIC_OP), + const_iv (GL_SEPARABLE_2D), const_iv (GL_CONVOLUTION_2D), const_iv (GL_CONVOLUTION_BORDER_MODE), const_iv (GL_CONSTANT_BORDER), @@ -1350,6 +1448,8 @@ void glLogicOp (int opcode) +void glColorMask (int red, int green, int blue, int alpha) + void glMatrixMode (int mode) void glPushMatrix () @@ -1358,15 +1458,18 @@ void glLoadIdentity () -void glOrtho (double left, double right, double bottom, double top, double near, double far) +# near and far are due to microsofts buggy c compiler +void glOrtho (double left, double right, double bottom, double top, double near_, double far_) void glViewport (int x, int y, int width, int height) +void glScissor (int x, int y, int width, int height) + void glTranslate (float x, float y, float z = 0.) CODE: glTranslatef (x, y, z); -void glScale (float x, float y, float z) +void glScale (float x, float y, float z = 1.) CODE: glScalef (x, y, z); @@ -1381,7 +1484,7 @@ void glColor (float r, float g, float b, float a = 1.0) PROTOTYPE: @ CODE: - glColor4f (r, g, b, a); + glColor4ub (r * 255., g * 255., b * 255., a * 255.); void glVertex (float x, float y, float z = 0.) CODE: @@ -1403,14 +1506,28 @@ void glConvolutionParameter (int target, int pname, float params) CODE: - glConvolutionParameterf (target, pname, params); + GL_CALL (PFNGLCONVOLUTIONPARAMETERFEXTPROC, glConvolutionParameterf, (target, pname, params)); void glConvolutionFilter2D (int target, int internalformat, int width, int height, int format, int type, char *data) + CODE: + GL_CALL (PFNGLCONVOLUTIONFILTER2DEXTPROC, glConvolutionFilter2D, + (target, internalformat, width, height, format, type, data)); + +void glSeparableFilter2D (int target, int internalformat, int width, int height, int format, int type, char *row, char *column) + CODE: + GL_CALL (PFNGLSEPARABLEFILTER2DEXTPROC, glSeparableFilter2D, + (target, internalformat, width, height, format, type, row, column)); void glTexImage2D (int target, int level, int internalformat, int width, int height, int border, int format, int type, char *data) void glCopyTexImage2D (int target, int level, int internalformat, int x, int y, int width, int height, int border) +void glRasterPos (int x, int y) + CODE: + glRasterPos2i (x, y); + +void glCopyPixels (int x, int y, int width, int height, int type = GL_COLOR) + int glGenTexture () CODE: {