--- deliantra/Deliantra-Client/Client.xs 2006/04/19 00:47:34 1.50 +++ deliantra/Deliantra-Client/Client.xs 2006/04/20 09:13:31 1.56 @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -39,6 +40,9 @@ #define MAP_EXTEND_X 32 #define MAP_EXTEND_Y 512 +typedef Mix_Chunk *CFClient__MixChunk; +typedef Mix_Music *CFClient__MixMusic; + static PangoContext *context; static PangoFontMap *fontmap; @@ -237,17 +241,252 @@ } } +static void +music_finished () +{ + SDL_UserEvent ev; + + ev.type = SDL_USEREVENT; + ev.code = 0; + ev.data1 = 0; + ev.data2 = 0; + + SDL_PushEvent (&ev); +} + MODULE = CFClient PACKAGE = CFClient PROTOTYPES: ENABLE BOOT: { - fontmap = pango_ft2_font_map_new (); - pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)fontmap, substitute_func, 0, 0); - context = pango_ft2_font_map_create_context ((PangoFT2FontMap *)fontmap); + HV *stash = gv_stashpv ("CFClient", 1); + static const struct { + const char *name; + IV iv; + } *civ, const_iv[] = { +# define const_iv(name) { # name, (IV)name } + const_iv (SDL_ACTIVEEVENT), + const_iv (SDL_KEYDOWN), + const_iv (SDL_KEYUP), + const_iv (SDL_MOUSEMOTION), + const_iv (SDL_MOUSEBUTTONDOWN), + const_iv (SDL_MOUSEBUTTONUP), + const_iv (SDL_JOYAXISMOTION), + const_iv (SDL_JOYBALLMOTION), + const_iv (SDL_JOYHATMOTION), + const_iv (SDL_JOYBUTTONDOWN), + const_iv (SDL_JOYBUTTONUP), + const_iv (SDL_QUIT), + const_iv (SDL_SYSWMEVENT), + const_iv (SDL_EVENT_RESERVEDA), + const_iv (SDL_EVENT_RESERVEDB), + const_iv (SDL_VIDEORESIZE), + const_iv (SDL_VIDEOEXPOSE), + const_iv (SDL_USEREVENT), + const_iv (SDLK_KP0), + const_iv (SDLK_KP1), + const_iv (SDLK_KP2), + const_iv (SDLK_KP3), + const_iv (SDLK_KP4), + const_iv (SDLK_KP5), + const_iv (SDLK_KP6), + const_iv (SDLK_KP7), + const_iv (SDLK_KP8), + const_iv (SDLK_KP9), + const_iv (SDLK_KP_PERIOD), + const_iv (SDLK_KP_DIVIDE), + const_iv (SDLK_KP_MULTIPLY), + const_iv (SDLK_KP_MINUS), + const_iv (SDLK_KP_PLUS), + const_iv (SDLK_KP_ENTER), + const_iv (SDLK_KP_EQUALS), + const_iv (SDLK_UP), + const_iv (SDLK_DOWN), + const_iv (SDLK_RIGHT), + const_iv (SDLK_LEFT), + const_iv (SDLK_INSERT), + const_iv (SDLK_HOME), + const_iv (SDLK_END), + const_iv (SDLK_PAGEUP), + const_iv (SDLK_PAGEDOWN), + const_iv (SDLK_F1), + const_iv (SDLK_F2), + const_iv (SDLK_F3), + const_iv (SDLK_F4), + const_iv (SDLK_F5), + const_iv (SDLK_F6), + const_iv (SDLK_F7), + const_iv (SDLK_F8), + const_iv (SDLK_F9), + const_iv (SDLK_F10), + const_iv (SDLK_F11), + const_iv (SDLK_F12), + const_iv (SDLK_F13), + const_iv (SDLK_F14), + const_iv (SDLK_F15), + const_iv (SDLK_NUMLOCK), + const_iv (SDLK_CAPSLOCK), + const_iv (SDLK_SCROLLOCK), + const_iv (SDLK_RSHIFT), + const_iv (SDLK_LSHIFT), + const_iv (SDLK_RCTRL), + const_iv (SDLK_LCTRL), + const_iv (SDLK_RALT), + const_iv (SDLK_LALT), + const_iv (SDLK_RMETA), + const_iv (SDLK_LMETA), + const_iv (SDLK_LSUPER), + const_iv (SDLK_RSUPER), + const_iv (SDLK_MODE), + const_iv (SDLK_COMPOSE), + const_iv (SDLK_HELP), + const_iv (SDLK_PRINT), + const_iv (SDLK_SYSREQ), + const_iv (SDLK_BREAK), + const_iv (SDLK_MENU), + const_iv (SDLK_POWER), + const_iv (SDLK_EURO), + const_iv (SDLK_UNDO), + const_iv (KMOD_NONE), + const_iv (KMOD_LSHIFT), + const_iv (KMOD_RSHIFT), + const_iv (KMOD_LCTRL), + const_iv (KMOD_RCTRL), + const_iv (KMOD_LALT), + const_iv (KMOD_RALT), + const_iv (KMOD_LMETA), + const_iv (KMOD_RMETA), + const_iv (KMOD_NUM), + const_iv (KMOD_CAPS), + const_iv (KMOD_MODE), + const_iv (KMOD_CTRL), + const_iv (KMOD_SHIFT), + const_iv (KMOD_ALT), + const_iv (KMOD_META) +# undef const_iv + }; + + for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) + newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); + + fontmap = pango_ft2_font_map_new (); + pango_ft2_font_map_set_default_substitute ((PangoFT2FontMap *)fontmap, substitute_func, 0, 0); + context = pango_ft2_font_map_create_context ((PangoFT2FontMap *)fontmap); +} + +int +SDL_Init (U32 flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO) + +void +SDL_Quit () + +void +SDL_ListModes () + 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_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_ALPHA_SIZE, 0); + + SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute (SDL_GL_BUFFER_SIZE, 15); + SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 0); + + 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))); + + ++m; + } +} + +int +SDL_SetVideoMode (int w, int h, int fullscreen) + CODE: + RETVAL = !!SDL_SetVideoMode ( + w, h, 0, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0) + ); + SDL_WM_SetCaption ("Crossfire+ Client " VERSION, "Crossfire+"); + OUTPUT: + RETVAL + +void +SDL_GL_SwapBuffers () + +void +SDL_PollEvent () + PPCODE: +{ + SDL_Event ev; + + while (SDL_PollEvent (&ev)) + { + HV *hv = newHV (); + hv_store (hv, "type", 4, newSViv (ev.type), 0); + switch (ev.type) + { + case SDL_KEYDOWN: + case SDL_KEYUP: + hv_store (hv, "state", 5, newSViv (ev.key.state), 0); + hv_store (hv, "sym", 3, newSViv (ev.key.keysym.sym), 0); + hv_store (hv, "mod", 3, newSViv (ev.key.keysym.mod), 0); + hv_store (hv, "unicode", 7, newSViv (ev.key.keysym.unicode), 0); + break; + + case SDL_ACTIVEEVENT: + hv_store (hv, "gain", 4, newSViv (ev.active.gain), 0); + hv_store (hv, "state", 5, newSViv (ev.active.state), 0); + break; + + case 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); + break; + + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + hv_store (hv, "button", 6, newSViv (ev.button.button), 0); + 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); + } + + XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); + } } +int +Mix_OpenAudio (int frequency = 22050, int format = MIX_DEFAULT_FORMAT, int channels = 1, int chunksize = 512) + POSTCALL: + Mix_HookMusicFinished (music_finished); + +void +Mix_CloseAudio () + +int +Mix_AllocateChannels (int numchans = -1) + void lowdelay (int fd, int val = 1) CODE: @@ -711,11 +950,11 @@ } SV * -mapmap (CFClient::Map self, int w, int h) +mapmap (CFClient::Map self, int x0, int y0, int w, int h) CODE: { - int x0, x1, x; - int y0, y1, y; + int x1, x; + int y1, y; int z; SV *map_sv = newSV (w * h * sizeof (uint32_t)); uint32_t *map = (uint32_t *)SvPVX (map_sv); @@ -723,8 +962,8 @@ SvPOK_only (map_sv); SvCUR_set (map_sv, w * h * sizeof (uint32_t)); - x0 = self->x - w / 2; x1 = x0 + w; - y0 = self->y - h / 2; y1 = y0 + h; + x0 += self->x; x1 = x0 + w; + y0 += self->y; y1 = y0 + h; for (y = y0; y < y1; y++) { @@ -874,7 +1113,7 @@ *data++ = h >> 8; *data++ = h; // we need to do this 'cause we don't keep an absolute coord system for rows - // TODO: treat rows as we treat + // TODO: treat rows as we treat columns map_get_row (self, y0 + self->y - self->oy);//D map_get_row (self, y0 + self->y - self->oy + h - 1);//D @@ -948,7 +1187,7 @@ h = *data++ << 8; h |= *data++; // we need to do this 'cause we don't keep an absolute coord system for rows - // TODO: treat rows as we treat + // TODO: treat rows as we treat columns map_get_row (self, y0 + self->y - self->oy);//D map_get_row (self, y0 + self->y - self->oy + h - 1);//D @@ -993,3 +1232,230 @@ } } +MODULE = CFClient PACKAGE = CFClient::MixChunk + +CFClient::MixChunk +new_from_file (SV *class, char *path) + CODE: + RETVAL = Mix_LoadWAV (path); + OUTPUT: + RETVAL + +void +DESTROY (CFClient::MixChunk self) + CODE: + Mix_FreeChunk (self); + +int +volume (CFClient::MixChunk self, int volume = -1) + CODE: + RETVAL = Mix_VolumeChunk (self, volume); + OUTPUT: + RETVAL + +int +play (CFClient::MixChunk self, int channel = -1, int loops = 0, int ticks = -1) + CODE: + RETVAL = Mix_PlayChannelTimed (channel, self, loops, ticks); + OUTPUT: + RETVAL + +MODULE = CFClient PACKAGE = CFClient::MixMusic + +int +volume (int volume = -1) + CODE: + RETVAL = Mix_VolumeMusic (volume); + OUTPUT: + RETVAL + +CFClient::MixMusic +new_from_file (SV *class, char *path) + CODE: + RETVAL = Mix_LoadMUS (path); + OUTPUT: + RETVAL + +void +DESTROY (CFClient::MixMusic self) + CODE: + Mix_FreeMusic (self); + +int +play (CFClient::MixMusic self, int loops = -1) + CODE: + RETVAL = Mix_PlayMusic (self, loops); + OUTPUT: + RETVAL + +MODULE = CFClient PACKAGE = CFClient::OpenGL + +BOOT: +{ + HV *stash = gv_stashpv ("CFClient::OpenGL", 1); + static const struct { + const char *name; + IV iv; + } *civ, const_iv[] = { +# define const_iv(name) { # name, (IV)name } + const_iv (GL_COLOR_MATERIAL), + const_iv (GL_SMOOTH), + const_iv (GL_FLAT), + const_iv (GL_BLEND), + const_iv (GL_AND), + const_iv (GL_SRC_ALPHA), + const_iv (GL_ONE_MINUS_SRC_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), + const_iv (GL_COMPILE), + const_iv (GL_TEXTURE_1D), + const_iv (GL_TEXTURE_2D), + const_iv (GL_TEXTURE_ENV), + const_iv (GL_TEXTURE_MAG_FILTER), + const_iv (GL_TEXTURE_MIN_FILTER), + const_iv (GL_TEXTURE_ENV_MODE), + const_iv (GL_TEXTURE_WRAP_S), + const_iv (GL_TEXTURE_WRAP_T), + const_iv (GL_CLAMP), + const_iv (GL_REPEAT), + const_iv (GL_NEAREST), + const_iv (GL_LINEAR), + const_iv (GL_MODULATE), + 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_CONVOLUTION_2D), + const_iv (GL_CONVOLUTION_BORDER_MODE), + const_iv (GL_CONSTANT_BORDER), + const_iv (GL_LINES), + const_iv (GL_QUADS), + const_iv (GL_LINE_LOOP), + const_iv (GL_PERSPECTIVE_CORRECTION_HINT), + const_iv (GL_FASTEST), +# undef const_iv + }; + + for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) + newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); +} + +int glGetError () + +void glClear (int mask) + +void glClearColor (float r, float g, float b, float a = 1.0) + PROTOTYPE: @ + +void glEnable (int cap) + +void glDisable (int cap) + +void glShadeModel (int mode) + +void glHint (int target, int mode) + +void glBlendFunc (int sfactor, int dfactor) + +void glLogicOp (int opcode) + +void glMatrixMode (int mode) + +void glPushMatrix () + +void glPopMatrix () + +void glLoadIdentity () + +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 glTranslate (float x, float y, float z = 0.) + CODE: + glTranslatef (x, y, z); + +void glScale (float x, float y, float z) + CODE: + glScalef (x, y, z); + +void glRotate (float angle, float x, float y, float z) + CODE: + glRotatef (angle, x, y, z); + +void glBegin (int mode) + +void glEnd () + +void glColor (float r, float g, float b, float a = 1.0) + PROTOTYPE: @ + CODE: + glColor4f (r, g, b, a); + +void glVertex (float x, float y, float z = 0.) + CODE: + glVertex3f (x, y, z); + +void glTexCoord (float s, float t) + CODE: + glTexCoord2f (s, t); + +void glTexEnv (int target, int pname, float param) + CODE: + glTexEnvf (target, pname, param); + +void glTexParameter (int target, int pname, float param) + CODE: + glTexParameterf (target, pname, param); + +void glBindTexture (int target, int name) + +void glConvolutionParameter (int target, int pname, float params) + CODE: + glConvolutionParameterf (target, pname, params); + +void glConvolutionFilter2D (int target, int internalformat, int width, int height, int format, int type, char *data) + +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) + +int glGenTexture () + CODE: +{ + GLuint name; + glGenTextures (1, &name); + RETVAL = name; +} + OUTPUT: + RETVAL + +void glDeleteTexture (int name) + CODE: +{ + GLuint name_ = name; + glDeleteTextures (1, &name_); +} + +int glGenList () + CODE: + RETVAL = glGenLists (1); + OUTPUT: + RETVAL + +void glDeleteList (int list) + CODE: + glDeleteLists (list, 1); + +void glNewList (int list, int mode = GL_COMPILE) + +void glEndList () + +void glCallList (int list) +