ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/Client.xs
(Generate patch)

Comparing deliantra/Deliantra-Client/Client.xs (file contents):
Revision 1.303 by root, Thu Apr 22 11:18:04 2010 UTC vs.
Revision 1.316 by root, Sun Nov 4 02:13:53 2012 UTC

99 99
100#define KMOD_LRAM 0x10000 // our extension 100#define KMOD_LRAM 0x10000 // our extension
101 101
102#define TEXID_SPEECH 1 102#define TEXID_SPEECH 1
103#define TEXID_NOFACE 2 103#define TEXID_NOFACE 2
104
105static char *
106fast_sv_grow (SV *sv, STRLEN need)
107{
108 STRLEN len = SvLEN (sv);
109 STRLEN want = SvCUR (sv) + need;
110
111 if (expect_false (len < want))
112 {
113 do
114 len *= 2;
115 while (len < want);
116
117 sv_grow (sv, len);
118 }
119
120 SvCUR_set (sv, want);
121 return SvEND (sv) - need;
122}
104 123
105static AV *texture_av; 124static AV *texture_av;
106 125
107static struct 126static struct
108{ 127{
463 482
464 SDL_PushEvent ((SDL_Event *)&ev); 483 SDL_PushEvent ((SDL_Event *)&ev);
465} 484}
466 485
467static unsigned int 486static unsigned int
487div255 (unsigned int n)
488{
489 return (n + (n >> 8)) >> 8;
490}
491
492static unsigned int
468minpot (unsigned int n) 493minpot (unsigned int n)
469{ 494{
470 if (!n) 495 if (!n)
471 return 0; 496 return 0;
472 497
552 577
553 return mod; 578 return mod;
554} 579}
555 580
556static void 581static void
557deliantra_main () 582deliantra_main (SV *real_main)
558{ 583{
559 char *argv[] = { 0 }; 584 dSP;
560 call_argv ("::main", G_DISCARD | G_VOID, argv); 585
586 PUSHMARK (SP);
587 call_sv (real_main, G_DISCARD | G_VOID);
561} 588}
562 589
563#ifdef __MACOSX__ 590#ifdef __MACOSX__
591 static SV *real_main;
592
564 /* to due surprising braindamage on the side of SDL design, we 593 /* to due surprising braindamage on the side of SDL design, we
565 * do some mind-boggling hack here: SDL requires a custom main() 594 * do some mind-boggling hack here: SDL requires a custom main()
566 * on OS X, so... we provide one and call the original main(), which, 595 * on OS X, so... we provide one and call the original main(), which,
567 * due to share dlibrary magic, calls -lSDLmain's main, not perl's main, 596 * due to shared library magic, calls -lSDLmain's main, not perl's main,
568 * and which calls our main (== SDL_main) back. 597 * and which calls our main (== SDL_main) back.
569 */ 598 */
570 extern C_LINKAGE int 599 extern C_LINKAGE int
571 main (int argc, char *argv[]) 600 main (int argc, char *argv[])
572 { 601 {
573 deliantra_main (); 602 deliantra_main (real_main);
574 } 603 }
575 604
576 #undef main 605 #undef main
577 606
578 extern C_LINKAGE int main (int argc, char *argv[]); 607 extern C_LINKAGE int main (int argc, char *argv[]);
579 608
580 static void 609 static void
581 SDL_braino (void) 610 SDL_main_hack (SV *real_main_)
582 { 611 {
612 real_main = real_main_;
613
583 char *argv[] = { "deliantra client", 0 }; 614 char *argv[] = { "deliantra client", 0 };
584 (main) (1, argv); 615 (main) (1, argv);
585 } 616 }
586#else 617#else
587 static void 618 static void
588 SDL_braino (void) 619 SDL_main_hack (SV *real_main)
589 { 620 {
590 deliantra_main (); 621 deliantra_main (real_main);
591 } 622 }
592#endif 623#endif
593 624
594MODULE = Deliantra::Client PACKAGE = DC 625MODULE = Deliantra::Client PACKAGE = DC
595 626
796 827
797 const_iv (FOW_DARKNESS) 828 const_iv (FOW_DARKNESS)
798# undef const_iv 829# undef const_iv
799 }; 830 };
800 831
801 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 832 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
802 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 833 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
803 834
804 assert (SDLK_MODIFIER_MIN == SDLK_NUMLOCK); 835 assert (SDLK_MODIFIER_MIN == SDLK_NUMLOCK);
805 assert (SDLK_MODIFIER_MAX == SDLK_COMPOSE); 836 assert (SDLK_MODIFIER_MAX == SDLK_COMPOSE);
806} 837}
807 838
846#endif 877#endif
847} 878}
848 879
849char *SDL_GetError () 880char *SDL_GetError ()
850 881
851void SDL_braino () 882void SDL_main_hack (SV *real_main)
883 PROTOTYPE: &
852 884
853int SDL_Init (U32 flags) 885int SDL_Init (U32 flags)
854 886
855int SDL_InitSubSystem (U32 flags) 887int SDL_InitSubSystem (U32 flags)
856 888
925 ); 957 );
926 958
927 if (RETVAL) 959 if (RETVAL)
928 { 960 {
929 av_clear (texture_av); 961 av_clear (texture_av);
930
931 SDL_WM_SetCaption ("Deliantra MORPG Client " VERSION, "Deliantra");
932#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name); 962#define GL_FUNC(ptr,name) gl.name = (ptr)SDL_GL_GetProcAddress ("gl" # name);
933#include "glfunc.h" 963#include "glfunc.h"
934#undef GL_FUNC 964#undef GL_FUNC
935
936 if (!gl.ActiveTexture ) gl.ActiveTexture = gl.ActiveTextureARB; 965 if (!gl.ActiveTexture ) gl.ActiveTexture = gl.ActiveTextureARB;
937 if (!gl.MultiTexCoord2f) gl.MultiTexCoord2f = gl.MultiTexCoord2fARB; 966 if (!gl.MultiTexCoord2f) gl.MultiTexCoord2f = gl.MultiTexCoord2fARB;
938 } 967 }
939} 968}
940 OUTPUT: 969 OUTPUT:
941 RETVAL 970 RETVAL
942 971
943void 972void
973SDL_WM_SetCaption (const char *title, const char *icon)
974
975void
944SDL_GL_SwapBuffers () 976SDL_GL_SwapBuffers ()
945 977
946char * 978char *
947SDL_GetKeyName (int sym) 979SDL_GetKeyName (int sym)
948 980
950SDL_GetAppState () 982SDL_GetAppState ()
951 983
952int 984int
953SDL_GetModState () 985SDL_GetModState ()
954 986
987int
988SDL_WaitEvent ()
989 C_ARGS: 0
990
955void 991void
992SDL_PumpEvents ()
993
994void
956poll_events () 995peep_events ()
957 PPCODE: 996 PPCODE:
958{ 997{
959 SDL_Event ev; 998 SDL_Event ev;
960 999
961 SDL_PumpEvents (); 1000 SDL_PumpEvents ();
1111add_font (char *file) 1150add_font (char *file)
1112 CODE: 1151 CODE:
1113 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file); 1152 RETVAL = FcConfigAppFontAddFile (0, (const FcChar8 *)file);
1114 OUTPUT: 1153 OUTPUT:
1115 RETVAL 1154 RETVAL
1155
1156void
1157IMG_Init (int flags = IMG_INIT_JPG | IMG_INIT_PNG)
1158
1159# MIX_INIT_MP3 gives smpeg + libstdc++ + libgcc_s
1160void
1161Mix_Init (int flags = MIX_INIT_MOD | MIX_INIT_OGG)
1116 1162
1117void 1163void
1118load_image_inline (SV *image_) 1164load_image_inline (SV *image_)
1119 ALIAS: 1165 ALIAS:
1120 load_image_file = 1 1166 load_image_file = 1
1986 self->y += MAP_EXTEND_Y; 2032 self->y += MAP_EXTEND_Y;
1987 } 2033 }
1988} 2034}
1989 2035
1990SV * 2036SV *
1991map1a_update (DC::Map self, SV *data_, int extmap) 2037map1a_update (DC::Map self, SV *data_)
1992 CODE: 2038 CODE:
1993{ 2039{
1994 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_); 2040 uint8_t *data = (uint8_t *)SvPVbyte_nolen (data_);
1995 uint8_t *data_end = (uint8_t *)SvEND (data_); 2041 uint8_t *data_end = (uint8_t *)SvEND (data_);
1996 mapcell *cell; 2042 mapcell *cell;
2017 2063
2018 //TODO: don't trust server data to be in-range(!) 2064 //TODO: don't trust server data to be in-range(!)
2019 2065
2020 if (flags & 8) 2066 if (flags & 8)
2021 { 2067 {
2068 uint8_t ext, cmd;
2069
2022 if (extmap) 2070 do
2023 { 2071 {
2024 uint8_t ext, cmd; 2072 ext = *data++;
2073 cmd = ext & 0x7f;
2025 2074
2026 do 2075 if (cmd < 4)
2076 cell->darkness = 255 - ext * 64 + 1; /* make sure this doesn't collide with FOW_DARKNESS */
2077 else if (cmd == 5) // health
2027 { 2078 {
2028 ext = *data++;
2029 cmd = ext & 0x7f;
2030
2031 if (cmd < 4)
2032 cell->darkness = 255 - ext * 64 + 1; /* make sure this doesn't collide with FOW_DARKNESS */
2033 else if (cmd == 5) // health
2034 {
2035 cell->stat_width = 1; 2079 cell->stat_width = 1;
2036 cell->stat_hp = *data++; 2080 cell->stat_hp = *data++;
2037 }
2038 else if (cmd == 6) // monster width
2039 cell->stat_width = *data++ + 1;
2040 else if (cmd == 0x47)
2041 {
2042 if (*data == 1) cell->player = data [1];
2043 else if (*data == 2) cell->player = data [2] + (data [1] << 8);
2044 else if (*data == 3) cell->player = data [3] + (data [2] << 8) + (data [1] << 16);
2045 else if (*data == 4) cell->player = data [4] + (data [3] << 8) + (data [2] << 16) + (data [1] << 24);
2046
2047 data += *data + 1;
2048 }
2049 else if (cmd == 8) // cell flags
2050 cell->flags = *data++;
2051 else if (ext & 0x40) // unknown, multibyte => skip
2052 data += *data + 1;
2053 else
2054 data++;
2055 } 2081 }
2056 while (ext & 0x80); 2082 else if (cmd == 6) // monster width
2083 cell->stat_width = *data++ + 1;
2084 else if (cmd == 0x47)
2085 {
2086 if (*data == 1) cell->player = data [1];
2087 else if (*data == 2) cell->player = data [2] + (data [1] << 8);
2088 else if (*data == 3) cell->player = data [3] + (data [2] << 8) + (data [1] << 16);
2089 else if (*data == 4) cell->player = data [4] + (data [3] << 8) + (data [2] << 16) + (data [1] << 24);
2090
2091 data += *data + 1;
2092 }
2093 else if (cmd == 8) // cell flags
2094 cell->flags = *data++;
2095 else if (ext & 0x40) // unknown, multibyte => skip
2096 data += *data + 1;
2097 else
2098 data++;
2057 } 2099 }
2058 else 2100 while (ext & 0x80);
2059 cell->darkness = *data++ + 1;
2060 } 2101 }
2061 2102
2062 for (z = 0; z <= 2; ++z) 2103 for (z = 0; z <= 2; ++z)
2063 if (flags & (4 >> z)) 2104 if (flags & (4 >> z))
2064 { 2105 {
2112 ? self->row + y 2153 ? self->row + y
2113 : 0; 2154 : 0;
2114 2155
2115 for (x = x0; x < x1; x++) 2156 for (x = x0; x < x1; x++)
2116 { 2157 {
2117 int r = 32, g = 32, b = 32, a = 192; 2158 unsigned int r = 32, g = 32, b = 32, a = 192;
2118 2159
2119 if (row && row->c0 <= x && x < row->c1) 2160 if (row && row->c0 <= x && x < row->c1)
2120 { 2161 {
2121 mapcell *cell = row->col + (x - row->c0); 2162 mapcell *cell = row->col + (x - row->c0);
2122 2163
2124 { 2165 {
2125 maptex tex = self->tex [cell->tile [z]]; 2166 maptex tex = self->tex [cell->tile [z]];
2126 int a0 = 255 - tex.a; 2167 int a0 = 255 - tex.a;
2127 int a1 = tex.a; 2168 int a1 = tex.a;
2128 2169
2129 r = (r * a0 + tex.r * a1) / 255; 2170 r = div255 (r * a0 + tex.r * a1);
2130 g = (g * a0 + tex.g * a1) / 255; 2171 g = div255 (g * a0 + tex.g * a1);
2131 b = (b * a0 + tex.b * a1) / 255; 2172 b = div255 (b * a0 + tex.b * a1);
2132 a = (a * a0 + tex.a * a1) / 255; 2173 a = div255 (a * a0 + tex.a * a1);
2133 } 2174 }
2134 } 2175 }
2135 2176
2136 *map++ = (r ) 2177 *map++ = (r )
2137 | (g << 8) 2178 | (g << 8)
2144} 2185}
2145 OUTPUT: 2186 OUTPUT:
2146 RETVAL 2187 RETVAL
2147 2188
2148void 2189void
2149draw (DC::Map self, int mx, int my, int sw, int sh, int T, U32 player = 0xffffffff, int sdx = 0, int sdy = 0) 2190draw (DC::Map self, int mx, int my, int sw, int sh, int Tw, int Th, U32 player = 0xffffffff, int sdx = 0, int sdy = 0)
2150 CODE: 2191 CODE:
2151{ 2192{
2152 int x, y, z; 2193 int x, y, z;
2153 2194
2154 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ()); 2195 HV *smooth = (HV *)sv_2mortal ((SV *)newHV ());
2238 2279
2239 key.texname = tex.name; 2280 key.texname = tex.name;
2240 arr = rc_array (rc, &key); 2281 arr = rc_array (rc, &key);
2241 } 2282 }
2242 2283
2243 px = (x + 1) * T - tex.w; 2284 px = (x + 1) * Th - tex.w;
2244 py = (y + 1) * T - tex.h; 2285 py = (y + 1) * Tw - tex.h;
2245 2286
2246 if (expect_false (cell->player == player) && expect_false (z == 2)) 2287 if (expect_false (cell->player == player) && expect_false (z == 2))
2247 { 2288 {
2248 pl_x = px; 2289 pl_x = px;
2249 pl_y = py; 2290 pl_y = py;
2302 if (cell->flags & 1) 2343 if (cell->flags & 1)
2303 { 2344 {
2304 rc_key_t key_ov = key; 2345 rc_key_t key_ov = key;
2305 maptex tex = self->tex [TEXID_SPEECH]; 2346 maptex tex = self->tex [TEXID_SPEECH];
2306 rc_array_t *arr; 2347 rc_array_t *arr;
2307 int px = x * T + T * 2 / 32; 2348 int px = x * Tw + Tw * 2 / 32;
2308 int py = y * T - T * 6 / 32; 2349 int py = y * Th - Th * 6 / 32;
2309 2350
2310 key_ov.texname = tex.name; 2351 key_ov.texname = tex.name;
2311 arr = rc_array (rc_ov, &key_ov); 2352 arr = rc_array (rc_ov, &key_ov);
2312 2353
2313 rc_t2f_v3f (arr, 0 , 0 , px , py , 0); 2354 rc_t2f_v3f (arr, 0 , 0 , px , py , 0);
2314 rc_t2f_v3f (arr, 0 , tex.t, px , py + T, 0); 2355 rc_t2f_v3f (arr, 0 , tex.t, px , py + Th, 0);
2315 rc_t2f_v3f (arr, tex.s, tex.t, px + T, py + T, 0); 2356 rc_t2f_v3f (arr, tex.s, tex.t, px + Tw, py + Th, 0);
2316 rc_t2f_v3f (arr, tex.s, 0 , px + T, py , 0); 2357 rc_t2f_v3f (arr, tex.s, 0 , px + Tw, py , 0);
2317 } 2358 }
2318 } 2359 }
2319 } 2360 }
2320 } 2361 }
2321 2362
2348 if (!(bits & 0x1000) 2389 if (!(bits & 0x1000)
2349 && skey->level == level 2390 && skey->level == level
2350 && level > smooth_max [skey->x][skey->y]) 2391 && level > smooth_max [skey->x][skey->y])
2351 { 2392 {
2352 maptex tex = self->tex [skey->tile]; 2393 maptex tex = self->tex [skey->tile];
2353 int px = (((int)skey->x) - 1) * T; 2394 int px = (((int)skey->x) - 1) * Tw;
2354 int py = (((int)skey->y) - 1) * T; 2395 int py = (((int)skey->y) - 1) * Th;
2355 int border = bits & 15; 2396 int border = bits & 15;
2356 int corner = (bits >> 8) & ~(bits >> 4) & 15; 2397 int corner = (bits >> 8) & ~(bits >> 4) & 15;
2357 float dx = tex.s * .0625f; // 16 images/row 2398 float dx = tex.s * .0625f; // 16 images/row
2358 float dy = tex.t * .5f ; // 2 images/column 2399 float dy = tex.t * .5f ; // 2 images/column
2359 2400
2372 2413
2373 if (border) 2414 if (border)
2374 { 2415 {
2375 float ox = border * dx; 2416 float ox = border * dx;
2376 2417
2377 glTexCoord2f (ox , 0.f ); glVertex2i (px , py ); 2418 glTexCoord2f (ox , 0.f ); glVertex2i (px , py );
2378 glTexCoord2f (ox , dy ); glVertex2i (px , py + T); 2419 glTexCoord2f (ox , dy ); glVertex2i (px , py + Th);
2379 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py + T); 2420 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py + Th);
2380 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + T, py ); 2421 glTexCoord2f (ox + dx, 0.f ); glVertex2i (px + Tw, py );
2381 } 2422 }
2382 2423
2383 if (corner) 2424 if (corner)
2384 { 2425 {
2385 float ox = corner * dx; 2426 float ox = corner * dx;
2386 2427
2387 glTexCoord2f (ox , dy ); glVertex2i (px , py ); 2428 glTexCoord2f (ox , dy ); glVertex2i (px , py );
2388 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + T); 2429 glTexCoord2f (ox , dy * 2.f); glVertex2i (px , py + Th);
2389 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + T, py + T); 2430 glTexCoord2f (ox + dx, dy * 2.f); glVertex2i (px + Tw, py + Th);
2390 glTexCoord2f (ox + dx, dy ); glVertex2i (px + T, py ); 2431 glTexCoord2f (ox + dx, dy ); glVertex2i (px + Tw, py );
2391 } 2432 }
2392 } 2433 }
2393 } 2434 }
2394 } 2435 }
2395 } 2436 }
2436 for (x = 0; x < sw; x++) 2477 for (x = 0; x < sw; x++)
2437 if (row->c0 <= x + mx && x + mx < row->c1) 2478 if (row->c0 <= x + mx && x + mx < row->c1)
2438 { 2479 {
2439 mapcell *cell = row->col + (x + mx - row->c0); 2480 mapcell *cell = row->col + (x + mx - row->c0);
2440 2481
2441 int px = x * T; 2482 int px = x * Tw;
2442 int py = y * T; 2483 int py = y * Th;
2443 2484
2444 if (expect_false (cell->player == player)) 2485 if (expect_false (cell->player == player))
2445 { 2486 {
2446 px += sdx; 2487 px += sdx;
2447 py += sdy; 2488 py += sdy;
2448 } 2489 }
2449 2490
2450 if (cell->stat_hp) 2491 if (cell->stat_hp)
2451 { 2492 {
2452 int width = cell->stat_width * T; 2493 int width = cell->stat_width * Tw;
2453 int thick = (sh * T / 32 + 27) / 28 + 1 + cell->stat_width; 2494 int thick = (sh * Th / 32 + 27) / 28 + 1 + cell->stat_width;
2454 2495
2455 glColor3ub (0, 0, 0); 2496 glColor3ub (0, 0, 0);
2456 glRectf (px + 1, py - thick - 2, 2497 glRectf (px + 1, py - thick - 2,
2457 px + width - 1, py); 2498 px + width - 1, py);
2458 2499
2538 int x, y; 2579 int x, y;
2539 int sw1 = sw + 2; 2580 int sw1 = sw + 2;
2540 int sh1 = sh + 2; 2581 int sh1 = sh + 2;
2541 int sh3 = sh * 3; 2582 int sh3 = sh * 3;
2542 int sw3 = sw * 3; 2583 int sw3 = sw * 3;
2543 uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1);
2544 SV *darkness3_sv = sv_2mortal (newSV (sw3 * sh3)); 2584 SV *darkness3_sv = sv_2mortal (newSV (sw3 * sh3));
2545 uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv); 2585 uint8_t *darkness3 = (uint8_t *)SvPVX (darkness3_sv);
2586 uint8_t *darkness1 = (uint8_t *)malloc (sw1 * sh1);
2587 memset (darkness1, 0, sw1*sh1);
2546 2588
2547 SvPOK_only (darkness3_sv); 2589 SvPOK_only (darkness3_sv);
2548 SvCUR_set (darkness3_sv, sw3 * sh3); 2590 SvCUR_set (darkness3_sv, sw3 * sh3);
2549 2591
2550 mx += self->x - 1; 2592 mx += self->x - 1;
3129 const_iv (GL_FUNC_SUBTRACT), 3171 const_iv (GL_FUNC_SUBTRACT),
3130 const_iv (GL_FUNC_REVERSE_SUBTRACT), 3172 const_iv (GL_FUNC_REVERSE_SUBTRACT),
3131# undef const_iv 3173# undef const_iv
3132 }; 3174 };
3133 3175
3134 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 3176 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
3135 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 3177 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
3136 3178
3137 texture_av = newAV (); 3179 texture_av = newAV ();
3138 AvREAL_off (texture_av); 3180 AvREAL_off (texture_av);
3139} 3181}
3140 3182
3183 RETVAL 3225 RETVAL
3184 3226
3185int glGetError () 3227int glGetError ()
3186 3228
3187void glFinish () 3229void glFinish ()
3230
3231void glFlush ()
3188 3232
3189void glClear (int mask) 3233void glClear (int mask)
3190 3234
3191void glClearColor (float r, float g, float b, float a = 1.0) 3235void glClearColor (float r, float g, float b, float a = 1.0)
3192 PROTOTYPE: @ 3236 PROTOTYPE: @

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines