...
|
...
|
@@ -33,10 +33,86 @@ |
33
|
33
|
#include "mzip.h"
|
34
|
34
|
#include "zlib.h"
|
35
|
35
|
#include "main.h"
|
|
36
|
+#include "utf8proc.h"
|
36
|
37
|
#include "useshader.h"
|
37
|
38
|
#include <math.h>
|
38
|
39
|
#include <time.h>
|
39
|
40
|
|
|
41
|
+
|
|
42
|
+/***** Helpers *****/
|
|
43
|
+static GLenum sdl_gl_texture_format(SDL_Surface *s) {
|
|
44
|
+ // get the number of channels in the SDL surface
|
|
45
|
+ GLint nOfColors = s->format->BytesPerPixel;
|
|
46
|
+ GLenum texture_format;
|
|
47
|
+ if (nOfColors == 4) // contains an alpha channel
|
|
48
|
+ {
|
|
49
|
+ if (s->format->Rmask == 0x000000ff)
|
|
50
|
+ texture_format = GL_RGBA;
|
|
51
|
+ else
|
|
52
|
+ texture_format = GL_BGRA;
|
|
53
|
+ } else if (nOfColors == 3) // no alpha channel
|
|
54
|
+ {
|
|
55
|
+ if (s->format->Rmask == 0x000000ff)
|
|
56
|
+ texture_format = GL_RGB;
|
|
57
|
+ else
|
|
58
|
+ texture_format = GL_BGR;
|
|
59
|
+ } else {
|
|
60
|
+ printf("warning: the image is not truecolor.. this will probably break %d\n", nOfColors);
|
|
61
|
+ // this error should not go unhandled
|
|
62
|
+ }
|
|
63
|
+
|
|
64
|
+ return texture_format;
|
|
65
|
+}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+// allocate memory for a texture without copying pixels in
|
|
69
|
+// caller binds texture
|
|
70
|
+void make_texture_for_surface(SDL_Surface *s, int *fw, int *fh) {
|
|
71
|
+ // Paramétrage de la texture.
|
|
72
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
73
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
74
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
75
|
+
|
|
76
|
+ // get the number of channels in the SDL surface
|
|
77
|
+ GLint nOfColors = s->format->BytesPerPixel;
|
|
78
|
+ GLenum texture_format = sdl_gl_texture_format(s);
|
|
79
|
+
|
|
80
|
+ // In case we can't support NPOT textures round up to nearest POT
|
|
81
|
+ int realw=1;
|
|
82
|
+ int realh=1;
|
|
83
|
+
|
|
84
|
+ while (realw < s->w) realw *= 2;
|
|
85
|
+ while (realh < s->h) realh *= 2;
|
|
86
|
+
|
|
87
|
+ if (fw) *fw = realw;
|
|
88
|
+ if (fh) *fh = realh;
|
|
89
|
+ //printf("request size (%d,%d), producing size (%d,%d)\n",s->w,s->h,realw,realh);
|
|
90
|
+
|
|
91
|
+ glTexImage2D(GL_TEXTURE_2D, 0, nOfColors, realw, realh, 0, texture_format, GL_UNSIGNED_BYTE, NULL);
|
|
92
|
+
|
|
93
|
+#ifdef _DEBUG
|
|
94
|
+ GLenum err = glGetError();
|
|
95
|
+ if (err != GL_NO_ERROR) {
|
|
96
|
+ printf("make_texture_for_surface: glTexImage2D : %s\n",gluErrorString(err));
|
|
97
|
+ }
|
|
98
|
+#endif
|
|
99
|
+}
|
|
100
|
+
|
|
101
|
+// copy pixels into previous allocated surface
|
|
102
|
+void copy_surface_to_texture(SDL_Surface *s) {
|
|
103
|
+ GLenum texture_format = sdl_gl_texture_format(s);
|
|
104
|
+
|
|
105
|
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, s->w, s->h, texture_format, GL_UNSIGNED_BYTE, s->pixels);
|
|
106
|
+
|
|
107
|
+#ifdef _DEBUG
|
|
108
|
+ GLenum err = glGetError();
|
|
109
|
+ if (err != GL_NO_ERROR) {
|
|
110
|
+ printf("copy_surface_to_texture : glTexSubImage2D : %s\n",gluErrorString(err));
|
|
111
|
+ }
|
|
112
|
+#endif
|
|
113
|
+}
|
|
114
|
+
|
|
115
|
+
|
40
|
116
|
/******************************************************************
|
41
|
117
|
******************************************************************
|
42
|
118
|
* Mouse *
|
...
|
...
|
@@ -410,6 +486,234 @@ static int sdl_surface_drawstring_newsurface_aa(lua_State *L) |
410
|
486
|
return 1;
|
411
|
487
|
}
|
412
|
488
|
|
|
489
|
+static font_make_texture_line(lua_State *L, SDL_Surface *s, int id)
|
|
490
|
+{
|
|
491
|
+ lua_newtable(L);
|
|
492
|
+
|
|
493
|
+ lua_pushstring(L, "_tex");
|
|
494
|
+ GLuint *t = (GLuint*)lua_newuserdata(L, sizeof(GLuint));
|
|
495
|
+ auxiliar_setclass(L, "gl{texture}", -1);
|
|
496
|
+ lua_rawset(L, -3);
|
|
497
|
+
|
|
498
|
+ glGenTextures(1, t);
|
|
499
|
+ tglBindTexture(GL_TEXTURE_2D, *t);
|
|
500
|
+ int fw, fh;
|
|
501
|
+ make_texture_for_surface(s, &fw, &fh);
|
|
502
|
+ copy_surface_to_texture(s);
|
|
503
|
+
|
|
504
|
+ lua_pushstring(L, "_tex_w");
|
|
505
|
+ lua_pushnumber(L, fw);
|
|
506
|
+ lua_rawset(L, -3);
|
|
507
|
+ lua_pushstring(L, "_tex_h");
|
|
508
|
+ lua_pushnumber(L, fh);
|
|
509
|
+ lua_rawset(L, -3);
|
|
510
|
+
|
|
511
|
+ lua_pushstring(L, "w");
|
|
512
|
+ lua_pushnumber(L, s->w);
|
|
513
|
+ lua_rawset(L, -3);
|
|
514
|
+ lua_pushstring(L, "h");
|
|
515
|
+ lua_pushnumber(L, s->h);
|
|
516
|
+ lua_rawset(L, -3);
|
|
517
|
+
|
|
518
|
+ lua_rawseti(L, -2, id);
|
|
519
|
+}
|
|
520
|
+
|
|
521
|
+static int sdl_font_draw(lua_State *L)
|
|
522
|
+{
|
|
523
|
+// if (no_text_aa) return sdl_surface_drawstring(L);
|
|
524
|
+ TTF_Font **f = (TTF_Font**)auxiliar_checkclass(L, "sdl{font}", 1);
|
|
525
|
+ const char *str = luaL_checkstring(L, 2);
|
|
526
|
+ int max_width = luaL_checknumber(L, 3);
|
|
527
|
+ int r = luaL_checknumber(L, 4);
|
|
528
|
+ int g = luaL_checknumber(L, 5);
|
|
529
|
+ int b = luaL_checknumber(L, 6);
|
|
530
|
+ int h = TTF_FontLineSkip(*f);
|
|
531
|
+
|
|
532
|
+ int space_w = 0, space_h = 0;
|
|
533
|
+ TTF_SizeUTF8(*f, " ", &space_w, &space_h);
|
|
534
|
+
|
|
535
|
+ Uint32 rmask, gmask, bmask, amask;
|
|
536
|
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
|
537
|
+ rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff;
|
|
538
|
+#else
|
|
539
|
+ rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000;
|
|
540
|
+#endif
|
|
541
|
+ SDL_Surface *s = SDL_CreateRGBSurface(
|
|
542
|
+ SDL_SWSURFACE | SDL_SRCALPHA,
|
|
543
|
+ max_width,
|
|
544
|
+ h,
|
|
545
|
+ 32,
|
|
546
|
+ rmask, gmask, bmask, amask
|
|
547
|
+ );
|
|
548
|
+ SDL_FillRect(s, NULL, SDL_MapRGBA(s->format, 0, 0, 0, 0));
|
|
549
|
+
|
|
550
|
+ SDL_Color color = {r,g,b};
|
|
551
|
+
|
|
552
|
+ lua_newtable(L);
|
|
553
|
+
|
|
554
|
+ int nb_lines = 1;
|
|
555
|
+ char *start = (char*)str, *stop = (char*)str, *next = (char*)str;
|
|
556
|
+ int max_size = 0;
|
|
557
|
+ int size = 0;
|
|
558
|
+ int i;
|
|
559
|
+ bool force_nl = FALSE;
|
|
560
|
+ SDL_Surface *txt = NULL;
|
|
561
|
+ while (TRUE)
|
|
562
|
+ {
|
|
563
|
+ if ((*next == '\n') || (*next == ' ') || (*next == '\0') || (*next == '#'))
|
|
564
|
+ {
|
|
565
|
+ stop = next - 1;
|
|
566
|
+
|
|
567
|
+ // Make a surface for the word
|
|
568
|
+ char old = *next;
|
|
569
|
+ *next = '\0';
|
|
570
|
+ if (txt) SDL_FreeSurface(txt);
|
|
571
|
+ txt = TTF_RenderUTF8_Blended(*f, start, color);
|
|
572
|
+
|
|
573
|
+ // If we must do a newline, flush the previous word and the start the new line
|
|
574
|
+ if (force_nl || (txt && (size + txt->w + space_w > max_width)))
|
|
575
|
+ {
|
|
576
|
+ // Push it & reset the surface
|
|
577
|
+ font_make_texture_line(L, s, nb_lines);
|
|
578
|
+ SDL_FillRect(s, NULL, SDL_MapRGBA(s->format, 0, 0, 0, 0));
|
|
579
|
+// printf("Ending previous line at size %d\n", size);
|
|
580
|
+ if (size > max_size) max_size = size;
|
|
581
|
+ size = 0;
|
|
582
|
+ nb_lines++;
|
|
583
|
+ force_nl = FALSE;
|
|
584
|
+ }
|
|
585
|
+
|
|
586
|
+ if (txt)
|
|
587
|
+ {
|
|
588
|
+// printf("Drawing word '%s'\n", start);
|
|
589
|
+ SDL_SetAlpha(txt, 0, 0);
|
|
590
|
+ sdlDrawImage(s, txt, size, 0);
|
|
591
|
+ size += txt->w + space_w;
|
|
592
|
+ }
|
|
593
|
+ *next = old;
|
|
594
|
+ start = next + 1;
|
|
595
|
+
|
|
596
|
+ // Force a linefeed
|
|
597
|
+ if (*next == '\n') force_nl = TRUE;
|
|
598
|
+
|
|
599
|
+ // Handle special codes
|
|
600
|
+ else if (*next == '#')
|
|
601
|
+ {
|
|
602
|
+ char *codestop = next + 1;
|
|
603
|
+ while (*codestop && *codestop != '#') codestop++;
|
|
604
|
+ // Font style
|
|
605
|
+ if (*(next+1) == '{') {
|
|
606
|
+ if (*(next+2) == 'n') TTF_SetFontStyle(*f, 0);
|
|
607
|
+ else if (*(next+2) == 'b') TTF_SetFontStyle(*f, TTF_STYLE_BOLD);
|
|
608
|
+ else if (*(next+2) == 'i') TTF_SetFontStyle(*f, TTF_STYLE_ITALIC);
|
|
609
|
+ else if (*(next+2) == 'u') TTF_SetFontStyle(*f, TTF_STYLE_UNDERLINE);
|
|
610
|
+ }
|
|
611
|
+ // Entity UID
|
|
612
|
+ else if ((codestop - (next+1) > 4) && (*(next+1) == 'U') && (*(next+2) == 'I') && (*(next+3) == 'D') && (*(next+4) == ':')) {
|
|
613
|
+ lua_getglobal(L, "__get_uid_surface");
|
|
614
|
+ char *colon = next + 5;
|
|
615
|
+ while (*colon && *colon != ':') colon++;
|
|
616
|
+ lua_pushlstring(L, next+5, colon - (next+5));
|
|
617
|
+// printf("Drawing UID %s\n", lua_tostring(L,-1));
|
|
618
|
+ lua_pushnumber(L, h);
|
|
619
|
+ lua_pushnumber(L, h);
|
|
620
|
+ lua_call(L, 3, 1);
|
|
621
|
+ if (lua_isuserdata(L, -1))
|
|
622
|
+ {
|
|
623
|
+ SDL_Surface **img = (SDL_Surface**)auxiliar_checkclass(L, "sdl{surface}", -1);
|
|
624
|
+ sdlDrawImage(s, *img, size, 0);
|
|
625
|
+ size += (*img)->w;
|
|
626
|
+ }
|
|
627
|
+ lua_pop(L, 1);
|
|
628
|
+ }
|
|
629
|
+ // Color
|
|
630
|
+ else {
|
|
631
|
+ if ((codestop - (next+1) == 4) && (*(next+1) == 'L') && (*(next+2) == 'A') && (*(next+3) == 'S') && (*(next+4) == 'T'))
|
|
632
|
+ {
|
|
633
|
+ color.r = r;
|
|
634
|
+ color.g = g;
|
|
635
|
+ color.b = b;
|
|
636
|
+ }
|
|
637
|
+
|
|
638
|
+ lua_getglobal(L, "colors");
|
|
639
|
+ lua_pushlstring(L, next+1, codestop - (next+1));
|
|
640
|
+ lua_rawget(L, -2);
|
|
641
|
+ if (lua_istable(L, -1)) {
|
|
642
|
+ r = color.r;
|
|
643
|
+ g = color.g;
|
|
644
|
+ b = color.b;
|
|
645
|
+
|
|
646
|
+ lua_pushstring(L, "r");
|
|
647
|
+ lua_rawget(L, -2);
|
|
648
|
+ color.r = lua_tonumber(L, -1);
|
|
649
|
+ lua_pushstring(L, "g");
|
|
650
|
+ lua_rawget(L, -3);
|
|
651
|
+ color.g = lua_tonumber(L, -1);
|
|
652
|
+ lua_pushstring(L, "b");
|
|
653
|
+ lua_rawget(L, -4);
|
|
654
|
+ color.b = lua_tonumber(L, -1);
|
|
655
|
+ lua_pop(L, 3);
|
|
656
|
+ }
|
|
657
|
+ // Hexacolor
|
|
658
|
+ else if (codestop - (next+1) == 6)
|
|
659
|
+ {
|
|
660
|
+ r = color.r;
|
|
661
|
+ g = color.g;
|
|
662
|
+ b = color.b;
|
|
663
|
+
|
|
664
|
+ int rh = 0, gh = 0, bh = 0;
|
|
665
|
+
|
|
666
|
+ if ((*(next+1) >= '0') && (*(next+1) <= '9')) rh += 16 * (*(next+1) - '0');
|
|
667
|
+ else if ((*(next+1) >= 'a') && (*(next+1) <= 'f')) rh += 16 * (10 + *(next+1) - 'a');
|
|
668
|
+ else if ((*(next+1) >= 'A') && (*(next+1) <= 'F')) rh += 16 * (10 + *(next+1) - 'A');
|
|
669
|
+ if ((*(next+2) >= '0') && (*(next+2) <= '9')) rh += (*(next+2) - '0');
|
|
670
|
+ else if ((*(next+2) >= 'a') && (*(next+2) <= 'f')) rh += (10 + *(next+2) - 'a');
|
|
671
|
+ else if ((*(next+2) >= 'A') && (*(next+2) <= 'F')) rh += (10 + *(next+2) - 'A');
|
|
672
|
+
|
|
673
|
+ if ((*(next+3) >= '0') && (*(next+3) <= '9')) gh += 16 * (*(next+3) - '0');
|
|
674
|
+ else if ((*(next+3) >= 'a') && (*(next+3) <= 'f')) gh += 16 * (10 + *(next+3) - 'a');
|
|
675
|
+ else if ((*(next+3) >= 'A') && (*(next+3) <= 'F')) gh += 16 * (10 + *(next+3) - 'A');
|
|
676
|
+ if ((*(next+4) >= '0') && (*(next+4) <= '9')) gh += (*(next+4) - '0');
|
|
677
|
+ else if ((*(next+4) >= 'a') && (*(next+4) <= 'f')) gh += (10 + *(next+4) - 'a');
|
|
678
|
+ else if ((*(next+4) >= 'A') && (*(next+4) <= 'F')) gh += (10 + *(next+4) - 'A');
|
|
679
|
+
|
|
680
|
+ if ((*(next+5) >= '0') && (*(next+5) <= '9')) bh += 16 * (*(next+5) - '0');
|
|
681
|
+ else if ((*(next+5) >= 'a') && (*(next+5) <= 'f')) bh += 16 * (10 + *(next+5) - 'a');
|
|
682
|
+ else if ((*(next+5) >= 'A') && (*(next+5) <= 'F')) bh += 16 * (10 + *(next+5) - 'A');
|
|
683
|
+ if ((*(next+6) >= '0') && (*(next+6) <= '9')) bh += (*(next+6) - '0');
|
|
684
|
+ else if ((*(next+6) >= 'a') && (*(next+6) <= 'f')) bh += (10 + *(next+6) - 'a');
|
|
685
|
+ else if ((*(next+6) >= 'A') && (*(next+6) <= 'F')) bh += (10 + *(next+6) - 'A');
|
|
686
|
+
|
|
687
|
+ color.r = rh;
|
|
688
|
+ color.g = gh;
|
|
689
|
+ color.b = bh;
|
|
690
|
+ }
|
|
691
|
+ lua_pop(L, 1);
|
|
692
|
+ }
|
|
693
|
+
|
|
694
|
+ char old = *codestop;
|
|
695
|
+ *codestop = '\0';
|
|
696
|
+// printf("Found code: %s\n", next+1);
|
|
697
|
+ *codestop = old;
|
|
698
|
+
|
|
699
|
+ start = codestop + 1;
|
|
700
|
+ next = codestop; // The while will increment it, so we dont so it here
|
|
701
|
+ }
|
|
702
|
+ }
|
|
703
|
+ if (*next == '\0') break;
|
|
704
|
+ next++;
|
|
705
|
+ }
|
|
706
|
+
|
|
707
|
+ font_make_texture_line(L, s, nb_lines);
|
|
708
|
+
|
|
709
|
+ if (txt) SDL_FreeSurface(txt);
|
|
710
|
+ SDL_FreeSurface(s);
|
|
711
|
+
|
|
712
|
+ lua_pushnumber(L, nb_lines);
|
|
713
|
+ lua_pushnumber(L, max_size);
|
|
714
|
+
|
|
715
|
+ return 3;
|
|
716
|
+}
|
413
|
717
|
|
414
|
718
|
|
415
|
719
|
static int sdl_new_tile(lua_State *L)
|
...
|
...
|
@@ -681,77 +985,6 @@ static void draw_textured_quad(int x, int y, int w, int h) { |
681
|
985
|
glDrawArrays(GL_QUADS, 0, 4);
|
682
|
986
|
}
|
683
|
987
|
|
684
|
|
-static GLenum sdl_gl_texture_format(SDL_Surface *s) {
|
685
|
|
- // get the number of channels in the SDL surface
|
686
|
|
- GLint nOfColors = s->format->BytesPerPixel;
|
687
|
|
- GLenum texture_format;
|
688
|
|
- if (nOfColors == 4) // contains an alpha channel
|
689
|
|
- {
|
690
|
|
- if (s->format->Rmask == 0x000000ff)
|
691
|
|
- texture_format = GL_RGBA;
|
692
|
|
- else
|
693
|
|
- texture_format = GL_BGRA;
|
694
|
|
- } else if (nOfColors == 3) // no alpha channel
|
695
|
|
- {
|
696
|
|
- if (s->format->Rmask == 0x000000ff)
|
697
|
|
- texture_format = GL_RGB;
|
698
|
|
- else
|
699
|
|
- texture_format = GL_BGR;
|
700
|
|
- } else {
|
701
|
|
- printf("warning: the image is not truecolor.. this will probably break %d\n", nOfColors);
|
702
|
|
- // this error should not go unhandled
|
703
|
|
- }
|
704
|
|
-
|
705
|
|
- return texture_format;
|
706
|
|
-}
|
707
|
|
-
|
708
|
|
-// allocate memory for a texture without copying pixels in
|
709
|
|
-// caller binds texture
|
710
|
|
-void make_texture_for_surface(SDL_Surface *s, int *fw, int *fh) {
|
711
|
|
- // Paramétrage de la texture.
|
712
|
|
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
713
|
|
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
714
|
|
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
715
|
|
-
|
716
|
|
- // get the number of channels in the SDL surface
|
717
|
|
- GLint nOfColors = s->format->BytesPerPixel;
|
718
|
|
- GLenum texture_format = sdl_gl_texture_format(s);
|
719
|
|
-
|
720
|
|
- // In case we can't support NPOT textures round up to nearest POT
|
721
|
|
- int realw=1;
|
722
|
|
- int realh=1;
|
723
|
|
-
|
724
|
|
- while (realw < s->w) realw *= 2;
|
725
|
|
- while (realh < s->h) realh *= 2;
|
726
|
|
-
|
727
|
|
- if (fw) *fw = realw;
|
728
|
|
- if (fh) *fh = realh;
|
729
|
|
- //printf("request size (%d,%d), producing size (%d,%d)\n",s->w,s->h,realw,realh);
|
730
|
|
-
|
731
|
|
- glTexImage2D(GL_TEXTURE_2D, 0, nOfColors, realw, realh, 0, texture_format, GL_UNSIGNED_BYTE, NULL);
|
732
|
|
-
|
733
|
|
-#ifdef _DEBUG
|
734
|
|
- GLenum err = glGetError();
|
735
|
|
- if (err != GL_NO_ERROR) {
|
736
|
|
- printf("make_texture_for_surface: glTexImage2D : %s\n",gluErrorString(err));
|
737
|
|
- }
|
738
|
|
-#endif
|
739
|
|
-}
|
740
|
|
-
|
741
|
|
-// copy pixels into previous allocated surface
|
742
|
|
-void copy_surface_to_texture(SDL_Surface *s) {
|
743
|
|
- GLenum texture_format = sdl_gl_texture_format(s);
|
744
|
|
-
|
745
|
|
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, s->w, s->h, texture_format, GL_UNSIGNED_BYTE, s->pixels);
|
746
|
|
-
|
747
|
|
-#ifdef _DEBUG
|
748
|
|
- GLenum err = glGetError();
|
749
|
|
- if (err != GL_NO_ERROR) {
|
750
|
|
- printf("copy_surface_to_texture : glTexSubImage2D : %s\n",gluErrorString(err));
|
751
|
|
- }
|
752
|
|
-#endif
|
753
|
|
-}
|
754
|
|
-
|
755
|
988
|
static int sdl_surface_toscreen(lua_State *L)
|
756
|
989
|
{
|
757
|
990
|
SDL_Surface **s = (SDL_Surface**)auxiliar_checkclass(L, "sdl{surface}", 1);
|
...
|
...
|
@@ -1576,6 +1809,7 @@ static const struct luaL_reg sdl_font_reg[] = |
1576
|
1809
|
{"lineSkip", sdl_font_lineskip},
|
1577
|
1810
|
{"setStyle", sdl_font_style},
|
1578
|
1811
|
{"getStyle", sdl_font_style_get},
|
|
1812
|
+ {"draw", sdl_font_draw},
|
1579
|
1813
|
{NULL, NULL},
|
1580
|
1814
|
};
|
1581
|
1815
|
|
...
|
...
|
|