3 * libneuro, a light weight abstraction of high or lower libraries
4 * and toolkit for applications.
5 * Copyright (C) 2005-2006 Nicholas Niro, Robert Lemay
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 * contains miscellaneous functions
24 * useful not directly associated with
25 * xml handling but most of the time useful.
26 * Especially when you want to have more than 1 data per nodes
34 #define WIN32_LEAN_AND_MEAN
39 #endif /* NOT WIN32 */
48 #include "../video/video.h" /* for Graphics_FreeVObject() */
51 Chk_bound(Rectan
*rec
, i16 x
, i16 y
, i16 w
, i16 h
)
53 if (rec
->x
<= x
&& (rec
->x
+ rec
->w
) >= x
)
55 if (rec
->y
<= y
&& (rec
->y
+ rec
->h
) >= y
)
57 /* Debug_Print("condition 1"); */
64 if ((rec
->y
+ rec
->h
) < (y
+ h
))
66 /* Debug_Print("condition 2"); */
71 if ((rec
->y
+ rec
->h
) < y
)
75 /* Debug_Print("condition 5"); */
80 /* Debug_Print("ret condition 1"); */
83 if (rec
->y
<= y
&& (rec
->y
+ rec
->h
) >= y
)
87 if ((rec
->x
+ rec
->w
) < (x
+ w
))
89 /* Debug_Print("condition 3"); */
94 if ((rec
->x
+ rec
->w
) < x
)
98 /* Debug_Print("condition 4"); */
101 /* Debug_Print("sub ret condition 2"); */
103 /* Debug_Print("ret condition 2"); */
106 /* Debug_Print("condition 0"); */
114 /* Sleep is in milli seconds */
116 #else /* NOT WIN32 */
117 /* usleep is in nano seconds */
119 #endif /* NOT WIN32 */
126 if (IsLittleEndian())
127 return (GetTickCount() / 10) & 0x7fffffff;
129 return (GetTickCount() / 10) & 0xfffffff7;
130 #else /* NOT WIN32 */
132 gettimeofday(&tv
, NULL
);
133 if (IsLittleEndian())
134 return (tv
.tv_sec
* 100 + tv
.tv_usec
/ 10000) & 0x7fffffff;
136 return (tv
.tv_sec
* 100 + tv
.tv_usec
/ 10000) & 0xfffffff7;
137 #endif /* NOT WIN32 */
141 /* this functions was made to separate a given character,
142 * like the character ':' of a string,
143 * example : foo:bar:test:test2
144 * the functions will have the pointers to each words in the string so
145 * foo bar test and test2 will be accessable independently.
148 Neuro_SepChr(const unsigned char chr
, char *source
, int *items
)
149 {/* separate characters of words */
150 char **ending
= NULL
;
151 u32 slen
= strlen(source
);
160 while ((last_ptr
+ o_ptr
) < slen
)
165 last_ptr
+= o_ptr
+ 1;
166 if ((object
= memchr(&source
[o_ptr
], chr
, slen
)) != NULL
)
167 object
[0] = '\0'; /* reset the ':' to \0 so we can point to it */
168 o_ptr
= strlen(&source
[last_ptr
]);
170 ending
= (char**)calloc(1, sizeof(char*));
173 ending
= (char **)realloc((char*)ending
, (sizeof(char*) * (o_total
+ 1)));
174 ending
[o_total
] = (char*)calloc(1, sizeof(char*));
176 ending
[o_total
] = (char*)&source
[last_ptr
];
184 clean_sepchr_ebuf(void *src
)
188 tmp
= (SepChr_Data
*)src
;
194 /* new separate character function using the EBUF tech */
196 Neuro_SepChr2(const unsigned char chr
, char *source
)
206 total
= strlen(source
);
213 Neuro_CreateEBuf(&temp
);
214 Neuro_SetcallbEBuf(temp
, clean_sepchr_ebuf
);
216 buf
= calloc(1, total
);
220 if (source
[i
] == chr
)
222 Neuro_AllocEBuf(temp
, sizeof(SepChr_Data
*), sizeof(SepChr_Data
));
223 tmp
= Neuro_GiveCurEBuf(temp
);
225 tmp
->string
= calloc(1, i2
+ 1);
226 strncpy(tmp
->string
, buf
, i2
);
227 tmp
->string
[i2
] = '\0';
241 Neuro_AllocEBuf(temp
, sizeof(SepChr_Data
*), sizeof(SepChr_Data
));
242 tmp
= Neuro_GiveCurEBuf(temp
);
244 tmp
->string
= calloc(1, i2
+ 1);
245 strncpy(tmp
->string
, buf
, i2
);
246 tmp
->string
[i2
] = '\0';
255 Neuro_GiveRGB8(u8 R
, u8 G
, u8 B
)
257 /* if the 2 not used bits are at the end
262 * if the 2 not used bits are at the beginning
271 Neuro_GiveRGB16(u8 R
, u8 G
, u8 B
)
273 /* actually, the Red color has 5 bits
274 * ditto for blue... green has 6 bits!
276 /* if the not used bit is at the end
281 * if the not used bit is at the beginning
286 * NEW correct way it is
299 if (IsLittleEndian())
301 output
= ((R
* 31) / 255);
303 output
+= ((G
* 63) / 255);
305 output
+= ((B
* 31) / 255);
309 output
= ((R
* 31) / 255);
311 output
+= ((G
* 63) / 255);
313 output
+= ((B
* 31) / 255);
320 Neuro_GiveRGB24(u8 R
, u8 G
, u8 B
)
328 if (IsLittleEndian())
349 Neuro_GiveRGB32(u8 R
, u8 G
, u8 B
)
351 /* if the 2 not used bits are at the end
356 * if the 2 not used bits are at the beginning
365 Neuro_MapRGB(u8 R
, u8 G
, u8 B
)
369 screen
= Neuro_GetScreenBuffer();
371 return Lib_MapRGB(screen
, R
, G
, B
);
375 Neuro_GiveRGBA_special(u8 R
, u8 G
, u8 B
)
379 /* hexadecimal position of the colors
391 * 0000,0000 00|00,000|0
392 * 0000|,0000 0|000,00|00
396 out = ((R * 31) / 255) << 11;
397 out ^= ((G * 31) / 255) << 6;
398 out ^= ((B * 31) / 255);
402 /*out = ((R * 31) / 255);
404 out ^= ((G * 31) / 255);
406 out ^= ((B * 31) / 255);
411 out = ((R * 31) / 255);
413 out += ((G * 31) / 255);
415 out += ((B * 31) / 255);
426 if (IsLittleEndian())
449 Neuro_GiveRGB(u8 R
, u8 G
, u8 B
)
451 return Neuro_GiveRGBA_special(R
, G
, B
);
454 /* convert color of default screen depth to
455 * 24 bit and gives each color separately in
459 Neuro_GiveConvertRGB(u32 color
, u8
*R
, u8
*G
, u8
*B
)
462 u32 tempR
= 0, tempG
= 0, tempB
= 0;
464 switch (Lib_GetDefaultDepth())
468 if (IsLittleEndian())
479 if (IsLittleEndian())
490 if (IsLittleEndian())
492 tempR
= color
& 0x0000F800;
493 tempG
= color
& 0x000007E0;
494 tempB
= color
& 0x0000001F;
500 /* convert it to 255 (8 bit) */
501 *R
= ((tempR
* 255) / 31);
502 *G
= ((tempG
* 255) / 63);
503 *B
= ((tempB
* 255) / 31);
513 if (IsLittleEndian())
530 Neuro_GiveImageSize(v_object
*image
, i32
*width
, i32
*height
)
532 if (image
&& width
&& height
)
534 Lib_GetVObjectData(image
, NULL
, height
, width
, NULL
, NULL
, NULL
,
535 NULL
, NULL
, NULL
, NULL
, NULL
);
540 * * Return the pixel value at (x, y)
541 * * NOTE: The surface must be locked before calling this!
544 Neuro_RawGetPixel(v_object
*srf
, int x
, int y
)
547 return Lib_GetPixel(srf
, x
, y
);
557 Lib_LockVObject(srf
);
559 Lib_GetVObjectData(srf
, NULL
, NULL
, NULL
, &pitch
, &pixels
, NULL
, &bpp
,
560 NULL
, NULL
, NULL
, NULL
);
562 /* bpp = surface->format->BytesPerPixel; */
563 /* Here p is the address to the pixel we want to retrieve */
564 /* p = (u8 *)surface->pixels + y * surface->pitch + x * bpp; */
565 p
= (u8
*)pixels
+ y
* pitch
+ x
* bpp
;
573 /* err = *(u16 *)p; */
585 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
586 err = p[0] << 16 | p[1] << 8 | p[2];
588 err = p[0] | p[1] << 8 | p[2] << 16;
601 err
= 0; /* shouldn't happen, but avoids warnings */
605 Lib_UnlockVObject(srf
);
614 * * Set the pixel at (x, y) to the given value
615 * * NOTE: The surface must be locked before calling this!
618 Neuro_RawPutPixel(v_object
*srf
, int x
, int y
, u32 pixel
)
621 Lib_PutPixel(srf
, x
, y
, pixel
);
624 /* SDL_Surface *surface = (SDL_Surface*)srf; */
625 /* SDL_LockSurface(surface); */
631 Lib_GetVObjectData(srf
, NULL
, NULL
, NULL
, &pitch
, &pixels
, NULL
, &bpp
,
632 NULL
, NULL
, NULL
, NULL
);
634 /* int bpp = surface->format->BytesPerPixel; */
635 /* Here p is the address to the pixel we want to set */
636 /* p = (u8*)surface->pixels + y * surface->pitch + x * bpp; */
637 p
= (u8
*)pixels
+ y
* pitch
+ x
* bpp
;
655 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
657 p[0] = (pixel >> 16) & 0xff;
658 p[1] = (pixel >> 8) & 0xff;
664 p[1] = (pixel >> 8) & 0xff;
665 p[2] = (pixel >> 16) & 0xff;
677 /* SDL_UnlockSurface(surface); */
690 printf("current fps : %d\n", fps
);
694 /* substract num2 from num1 and returns the answer only if it is positive,
695 * if it is not, returns 0
698 Neuro_CalcOnlyPos(i16 num1
, i16 num2
)
702 result
= num1
- num2
;
710 /* skeleton rectangle or square bounds check function.
712 * 0 = depen is inside indep.
713 * 1 = depen and indep are not touching each others(they are far away).
714 * 2 = depen is overlaping indep.
715 * this function needs to be converted to a macro so its lightning quick
718 Neuro_DumbBoundsCheck(Rectan
*indep
, Rectan
*depen
)
720 register u8 status
= 0;
722 status
= Chk_bound(indep
, depen
->x
, depen
->y
, depen
->w
, depen
->h
); /* up left */
723 status
+= Chk_bound(indep
, depen
->x
+ depen
->w
, depen
->y
, depen
->w
* -1, depen
->h
); /* up right */
724 status
+= Chk_bound(indep
, depen
->x
+ depen
->w
, depen
->y
+ depen
->h
, (i16
)depen
->w
* -1, (i16
)depen
->h
* -1); /* bottom right */
725 status
+= Chk_bound(indep
, depen
->x
, depen
->y
+ depen
->h
, depen
->w
, (i16
)depen
->h
* -1); /* bottom left */
729 status
= 0; /* obj is inside form */
734 status
= 2; /* obj overlaps form */
736 status
= 1; /* obj is not touching form */
742 /* rectangle or square bounds check function.
744 * 0 = depen is inside indep.
745 * 1 = depen and indep are not touching each others(they are far away).
746 * 2 = depen is overlaping indep.
747 * 3 = depen and indep links between corners are into the other but the corners
757 * 4 = indep is inside depen (reverse of 0)
759 * this function needs to be converted to a macro so its lightning quick
762 Neuro_BoundsCheck(Rectan
*indep
, Rectan
*depen
)
764 register u8 status
= 0;
766 status
= Neuro_DumbBoundsCheck(indep
, depen
);
768 /* check to see if depen is bigger than indep and indep is inside depen
769 * if its the case, the status will be 4.
773 if (Neuro_DumbBoundsCheck(depen
, indep
) != 1)
777 /* we check to see if we have a type 3 status */
780 if (Neuro_DumbBoundsCheck(depen
, indep
) == 0)
787 /* only play with the x and width values
788 * the Rectan indep should contain a rectangle.
789 * isrc is the Rectan that contains an image source Rectan.
790 * idst is the Rectan that contains the destination for the image
792 * this function will calibrate isrc and idst so the image represented
793 * by those 2 will not go over the rectangle indep.
794 * This function only fixes the vertical way of the image.
796 * This method will only work with cases where Neuro_BoundsCheck
797 * returned 2. No check is done, so watch out, only with case 2 please.
800 Neuro_VerticalBoundCrop(Rectan
*indep
, Rectan
*isrc
, Rectan
*idst
)
802 /* 2 methods : 1 is using statements and the other is mathematical */
804 /* the statement method */
806 if ((indep->x) > idst->x)
808 isrc->x += (indep->x) - idst->x;
809 isrc->w -= abs((indep->x) - idst->x);
813 if ((indep->x + indep->w) < (idst->x + isrc->w))
815 isrc->w -= (idst->x + isrc->w) - (indep->x + indep->w);
819 /* the mathematical method */
821 isrc
->x
+= Neuro_CalcOnlyPos(indep
->x
, idst
->x
);
823 isrc
->w
= Neuro_CalcOnlyPos(isrc
->w
,
824 (Neuro_CalcOnlyPos(indep
->x
, idst
->x
)
825 + Neuro_CalcOnlyPos(idst
->x
+ isrc
->w
, indep
->x
+ indep
->w
)));
827 idst
->x
+= Neuro_CalcOnlyPos(indep
->x
, idst
->x
);
831 /* only play with the y and height values
832 * the Rectan indep should contain a rectangle.
833 * isrc is the Rectan that contains an image source Rectan.
834 * idst is the Rectan that contains the destination for the image
836 * this function will calibrate isrc and idst so the image represented
837 * by those 2 will not go over the rectangle indep.
838 * This function only fixes the horizontal way of the image.
841 Neuro_HorizontalBoundCrop(Rectan
*indep
, Rectan
*isrc
, Rectan
*idst
)
843 /* 2 methods : 1 is using statements and the other is mathematical */
845 /* the statement method */
847 if (indep->y > idst->y)
849 isrc->y += abs(indep->y - idst->y);
850 isrc->h -= abs(indep->y - idst->y);
853 if ((indep->y + indep->h) < (idst->y + isrc->h))
855 isrc->h -= (idst->y + isrc->h) - (indep->y + indep->h);
859 /* the mathematical method */
861 isrc
->y
+= Neuro_CalcOnlyPos(indep
->y
, idst
->y
);
863 isrc
->h
= Neuro_CalcOnlyPos(isrc
->h
,
864 (Neuro_CalcOnlyPos(indep
->y
, idst
->y
)
865 + Neuro_CalcOnlyPos(idst
->y
+ isrc
->h
, indep
->y
+ indep
->h
)));
867 idst
->y
+= Neuro_CalcOnlyPos(indep
->y
, idst
->y
);
872 Neuro_BlitObject(v_object
*source
, Rectan
*src
, v_object
*destination
, Rectan
*dst
)
874 Lib_BlitObject(source
, src
, destination
, dst
);
878 Neuro_FreeVObject(v_object
*source
)
880 Graphics_FreeVObject(source
);
884 Neuro_LoadBMP(const char *path
, v_object
**img
)
886 Lib_LoadBMP(path
, img
);
890 Neuro_SetColorKey(v_object
*vobj
, u32 key
)
892 Lib_SetColorKey(vobj
, key
);
896 Neuro_SetAlpha(v_object
*vobj
, u8 alpha
)
898 Lib_SetAlpha(vobj
, alpha
);
902 Neuro_SyncPixels(v_object
*src
)
908 Neuro_CreateVObject(u32 flags
, i32 width
, i32 height
, i32 depth
, u32 Rmask
, u32 Gmask
,
909 u32 Bmask
, u32 Amask
)
911 return Lib_CreateVObject(flags
, width
, height
, depth
, Rmask
, Gmask
, Bmask
, Amask
);
915 Neuro_LoadFontFile(char *fonts_file_path
)
917 return Lib_LoadFontFile(fonts_file_path
);
921 Neuro_CleanFont(font_object
*font
)
927 Neuro_RenderUnicode(font_object
*ttf
, u32 size
, u32 character
, i16
*x
, i16
*y
, u32 color
, Rectan
*src
, Rectan
*dst
)
929 return Lib_RenderUnicode(ttf
, size
, character
, x
, y
, color
, src
, dst
);
933 Neuro_SetScreenSize(u32 width
, u32 height
)
935 Lib_SetScreenSize(width
, height
);
939 Neuro_GetScreenSize(u32
*width
, u32
*height
)
941 Lib_GetScreenSize(width
, height
);
946 Neuro_LockVObject(v_object
*vobj
)
948 Lib_LockVObject(vobj
);
952 Neuro_UnlockVObject(v_object
*vobj
)
954 Lib_UnlockVObject(vobj
);