Truetype only, compile with "make NOTTF=1" if you don't want to bother with it. Only TTF is done, aliased (ok) and non-aliased (backgound color is currently stuck to color index 0) The Clear button doesn't update the window. Only one font (certified to be public domain). Preview not done. Font selector not done. SFont support not done. Limit 30 characters. git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@305 416bcca6-2ee7-4201-b75f-2eb2f807beb1
609 lines
18 KiB
C
609 lines
18 KiB
C
/* Grafx2 - The Ultimate 256-color bitmap paint program
|
|
|
|
Copyright 2008 Yves Rizoud
|
|
Copyright 2008 Franck Charlet
|
|
Copyright 2007 Adrien Destugues
|
|
Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
|
|
|
|
Grafx2 is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; version 2
|
|
of the License.
|
|
|
|
Grafx2 is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Grafx2; if not, see <http://www.gnu.org/licenses/> or
|
|
write to the Free Software Foundation, Inc.,
|
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
#include <string.h>
|
|
#include <SDL/SDL.h>
|
|
#include "global.h"
|
|
#include "sdlscreen.h"
|
|
#include "divers.h"
|
|
#include "erreurs.h"
|
|
#include "graph.h"
|
|
|
|
// Mise à jour minimaliste en nombre de pixels
|
|
#define METHODE_UPDATE_MULTI_RECTANGLE 1
|
|
// Mise à jour intermédiaire, par rectangle inclusif.
|
|
#define METHODE_UPDATE_PAR_CUMUL 2
|
|
// Mise à jour totale, pour les plate-formes qui imposent un Vsync à chaque mise à jour écran.
|
|
#define METHODE_UPDATE_PLEINE_PAGE 3
|
|
|
|
// METHODE_UPDATE peut être fixé depuis le makefile, sinon c'est ici:
|
|
#ifndef METHODE_UPDATE
|
|
#ifdef __macosx__
|
|
#define METHODE_UPDATE METHODE_UPDATE_PLEINE_PAGE
|
|
#else
|
|
#define METHODE_UPDATE METHODE_UPDATE_MULTI_RECTANGLE
|
|
#endif
|
|
#endif
|
|
|
|
|
|
void Pixel_SDL (word X,word Y,byte Couleur)
|
|
/* Affiche un pixel de la Couleur aux coords X;Y à l'écran */
|
|
{
|
|
*(Ecran + X + Y * Largeur_ecran)=Couleur;
|
|
}
|
|
|
|
byte Lit_Pixel_SDL (word X,word Y)
|
|
/* On retourne la couleur du pixel aux coords données */
|
|
{
|
|
return *( Ecran + Y * Largeur_ecran + X );
|
|
}
|
|
|
|
void Afficher_partie_de_l_ecran_SDL (word Largeur,word Hauteur,word Largeur_image)
|
|
/* Afficher une partie de l'image telle quelle sur l'écran */
|
|
{
|
|
byte* Dest=Ecran; //On va se mettre en 0,0 dans l'écran (EDI)
|
|
byte* Src=Principal_Decalage_Y*Largeur_image+Principal_Decalage_X+Principal_Ecran; //Coords de départ ds la source (ESI)
|
|
int dx;
|
|
|
|
for(dx=Hauteur;dx!=0;dx--)
|
|
// Pour chaque ligne
|
|
{
|
|
// On fait une copie de la ligne
|
|
memcpy(Dest,Src,Largeur);
|
|
|
|
// On passe à la ligne suivante
|
|
Src+=Largeur_image;
|
|
Dest+=Largeur_ecran;
|
|
}
|
|
UpdateRect(0,0,Largeur,Hauteur);
|
|
}
|
|
|
|
void Block_SDL (word Debut_X,word Debut_Y,word Largeur,word Hauteur,byte Couleur)
|
|
/* On affiche un rectangle de la couleur donnée */
|
|
{
|
|
SDL_Rect rectangle;
|
|
rectangle.x=Debut_X;
|
|
rectangle.y=Debut_Y;
|
|
rectangle.w=Largeur;
|
|
rectangle.h=Hauteur;
|
|
SDL_FillRect(Ecran_SDL,&rectangle,Couleur);
|
|
// UpdateRect(Debut_X,Debut_Y,Largeur,Hauteur);
|
|
}
|
|
|
|
void Pixel_Preview_Normal_SDL (word X,word Y,byte Couleur)
|
|
/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image
|
|
* dans l'écran, en mode normal (pas en mode loupe)
|
|
* Note: si on modifie cette procédure, il faudra penser à faire également
|
|
* la modif dans la procédure Pixel_Preview_Loupe_SDL. */
|
|
{
|
|
// if(X-Principal_Decalage_X >= 0 && Y - Principal_Decalage_Y >= 0)
|
|
Pixel_SDL(X-Principal_Decalage_X,Y-Principal_Decalage_Y,Couleur);
|
|
}
|
|
|
|
void Pixel_Preview_Loupe_SDL (word X,word Y,byte Couleur)
|
|
{
|
|
// Affiche le pixel dans la partie non zoomée
|
|
Pixel_SDL(X-Principal_Decalage_X,Y-Principal_Decalage_Y,Couleur);
|
|
|
|
// Regarde si on doit aussi l'afficher dans la partie zoomée
|
|
if (Y >= Limite_Haut_Zoom && Y <= Limite_visible_Bas_Zoom
|
|
&& X >= Limite_Gauche_Zoom && X <= Limite_visible_Droite_Zoom)
|
|
{
|
|
// On est dedans
|
|
int hauteur;
|
|
int Y_Zoom = Table_mul_facteur_zoom[Y-Loupe_Decalage_Y];
|
|
|
|
if (Menu_Ordonnee - Y_Zoom < Loupe_Facteur)
|
|
// On ne doit dessiner qu'un morceau du pixel
|
|
// sinon on dépasse sur le menu
|
|
hauteur = Menu_Ordonnee - Y_Zoom;
|
|
else
|
|
hauteur = Loupe_Facteur;
|
|
|
|
Block_SDL(
|
|
Table_mul_facteur_zoom[X-Loupe_Decalage_X]
|
|
+ Principal_X_Zoom,
|
|
Y_Zoom, Loupe_Facteur, hauteur, Couleur
|
|
);
|
|
}
|
|
}
|
|
|
|
void Ligne_horizontale_XOR_SDL(word Pos_X,word Pos_Y,word Largeur)
|
|
{
|
|
//On calcule la valeur initiale de EDI:
|
|
byte* edi=Pos_Y*Largeur_ecran+Pos_X+Ecran;
|
|
|
|
int ecx;
|
|
|
|
for (ecx=0;ecx<Largeur;ecx++)
|
|
*(edi+ecx)=~*(edi+ecx);
|
|
}
|
|
|
|
void Ligne_verticale_XOR_SDL (word Pos_X,word Pos_Y,word Hauteur)
|
|
{
|
|
int i;
|
|
byte color;
|
|
for (i=Pos_Y;i<Pos_Y+Hauteur;i++)
|
|
{
|
|
color=*(Ecran+Pos_X+i*Largeur_ecran);
|
|
*(Ecran+Pos_X+i*Largeur_ecran)=~color;
|
|
}
|
|
}
|
|
|
|
void Display_brush_Color_SDL (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,word Largeur_brosse)
|
|
{
|
|
// EDI = Position à l'écran
|
|
byte* EDI = Ecran + Pos_Y * Largeur_ecran + Pos_X;
|
|
// ESI = Position dans la brosse
|
|
byte* ESI = Brosse + Decalage_Y * Largeur_brosse + Decalage_X;
|
|
|
|
word DX,CX;
|
|
|
|
// Pour chaque ligne
|
|
for(DX = Hauteur;DX > 0; DX--)
|
|
{
|
|
// Pour chaque pixel
|
|
for(CX = Largeur;CX > 0; CX--)
|
|
{
|
|
// On vérifie que ce n'est pas la transparence
|
|
if(*ESI != Couleur_de_transparence)
|
|
{
|
|
*EDI = *ESI;
|
|
}
|
|
|
|
// Pixel suivant
|
|
ESI++; EDI++;
|
|
}
|
|
|
|
// On passe à la ligne suivante
|
|
EDI = EDI + Largeur_ecran - Largeur;
|
|
ESI = ESI + Largeur_brosse - Largeur;
|
|
}
|
|
UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur);
|
|
}
|
|
|
|
void Display_brush_Mono_SDL (word Pos_X, word Pos_Y,
|
|
word Decalage_X, word Decalage_Y, word Largeur, word Hauteur,
|
|
byte Couleur_de_transparence, byte Couleur, word Largeur_brosse)
|
|
/* On affiche la brosse en monochrome */
|
|
{
|
|
byte* Dest=Pos_Y*Largeur_ecran+Pos_X+Ecran; // EDI = adr destination à
|
|
// l'écran
|
|
byte* Src=Largeur_brosse*Decalage_Y+Decalage_X+Brosse; // ESI = adr ds
|
|
// la brosse
|
|
int dx,cx;
|
|
|
|
for(dx=Hauteur;dx!=0;dx--)
|
|
//Pour chaque ligne
|
|
{
|
|
for(cx=Largeur;cx!=0;cx--)
|
|
//Pour chaque pixel
|
|
{
|
|
if (*Src!=Couleur_de_transparence)
|
|
*Dest=Couleur;
|
|
|
|
// On passe au pixel suivant
|
|
Src++;
|
|
Dest++;
|
|
}
|
|
|
|
// On passe à la ligne suivante
|
|
Src+=Largeur_brosse-Largeur;
|
|
Dest+=Largeur_ecran-Largeur;
|
|
}
|
|
UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur);
|
|
}
|
|
|
|
void Clear_brush_SDL (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Hauteur,byte Couleur_de_transparence,word Largeur_image)
|
|
{
|
|
byte* Dest=Ecran+Pos_X+Pos_Y*Largeur_ecran; //On va se mettre en 0,0 dans l'écran (EDI)
|
|
byte* Src = ( Pos_Y + Principal_Decalage_Y ) * Largeur_image + Pos_X + Principal_Decalage_X + Principal_Ecran; //Coords de départ ds la source (ESI)
|
|
int dx;
|
|
|
|
for(dx=Hauteur;dx!=0;dx--)
|
|
// Pour chaque ligne
|
|
{
|
|
// On fait une copie de la ligne
|
|
memcpy(Dest,Src,Largeur);
|
|
|
|
// On passe à la ligne suivante
|
|
Src+=Largeur_image;
|
|
Dest+=Largeur_ecran;
|
|
}
|
|
UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur);
|
|
}
|
|
|
|
void Remap_screen_SDL (word Pos_X,word Pos_Y,word Largeur,word Hauteur,byte * Table_de_conversion)
|
|
{
|
|
// EDI = coords a l'écran
|
|
byte* EDI = Ecran + Pos_Y * Largeur_ecran + Pos_X;
|
|
int dx,cx;
|
|
|
|
// Pour chaque ligne
|
|
for(dx=Hauteur;dx>0;dx--)
|
|
{
|
|
// Pour chaque pixel
|
|
for(cx=Largeur;cx>0;cx--)
|
|
{
|
|
*EDI = Table_de_conversion[*EDI];
|
|
EDI ++;
|
|
}
|
|
|
|
EDI = EDI + Largeur_ecran - Largeur;
|
|
}
|
|
|
|
UpdateRect(Pos_X,Pos_Y,Largeur,Hauteur);
|
|
}
|
|
|
|
void Afficher_une_ligne_ecran_SDL (word Pos_X,word Pos_Y,word Largeur,byte * Ligne)
|
|
/* On affiche toute une ligne de pixels. Utilisé pour les textes. */
|
|
{
|
|
memcpy(Ecran+Pos_X+Pos_Y*Largeur_ecran,Ligne,Largeur);
|
|
//UpdateRect(Pos_X,Pos_Y,Largeur,1);
|
|
}
|
|
|
|
void Afficher_une_ligne_transparente_mono_a_l_ecran_SDL(
|
|
word Pos_X, word Pos_Y, word Largeur, byte* Ligne,
|
|
byte Couleur_transparence, byte Couleur)
|
|
// Affiche une ligne à l'écran avec une couleur + transparence.
|
|
// Utilisé par les brosses en mode zoom
|
|
{
|
|
byte* Dest = Ecran+ Pos_Y * Largeur_ecran + Pos_X;
|
|
int Compteur;
|
|
// Pour chaque pixel
|
|
for(Compteur=0;Compteur<Largeur;Compteur++)
|
|
{
|
|
if (Couleur_transparence!=*Ligne)
|
|
*Dest = Couleur;
|
|
Ligne ++; // Pixel suivant
|
|
Dest++;
|
|
}
|
|
}
|
|
|
|
void Lire_une_ligne_ecran_SDL (word Pos_X,word Pos_Y,word Largeur,byte * Ligne)
|
|
{
|
|
memcpy(Ligne,Largeur_ecran * Pos_Y + Pos_X + Ecran,Largeur);
|
|
}
|
|
|
|
void Afficher_partie_de_l_ecran_zoomee_SDL(
|
|
word Largeur, // Largeur non zoomée
|
|
word Hauteur, // Hauteur zoomée
|
|
word Largeur_image,byte * Buffer)
|
|
{
|
|
byte* ESI = Principal_Ecran + Loupe_Decalage_Y * Largeur_image
|
|
+ Loupe_Decalage_X;
|
|
int EDX = 0; // Ligne en cours de traitement
|
|
|
|
// Pour chaque ligne à zoomer
|
|
while(1)
|
|
{
|
|
int CX;
|
|
|
|
// On éclate la ligne
|
|
Zoomer_une_ligne(ESI,Buffer,Loupe_Facteur,Largeur);
|
|
// On l'affiche Facteur fois, sur des lignes consécutives
|
|
CX = Loupe_Facteur;
|
|
// Pour chaque ligne
|
|
do{
|
|
// On affiche la ligne zoomée
|
|
Afficher_une_ligne_ecran_SDL(
|
|
Principal_X_Zoom, EDX, Largeur*Loupe_Facteur,
|
|
Buffer
|
|
);
|
|
// On passe à la suivante
|
|
EDX++;
|
|
if(EDX==Hauteur)
|
|
{
|
|
UpdateRect(Principal_X_Zoom,0,
|
|
Largeur*Loupe_Facteur,Hauteur);
|
|
return;
|
|
}
|
|
CX--;
|
|
}while (CX > 0);
|
|
ESI += Largeur_image;
|
|
}
|
|
// ATTENTION on n'arrive jamais ici !
|
|
}
|
|
|
|
void Afficher_une_ligne_transparente_a_l_ecran_SDL(word Pos_X,word Pos_Y,word Largeur,byte* Ligne,byte Couleur_transparence)
|
|
{
|
|
byte* ESI = Ligne;
|
|
byte* EDI = Ecran + Pos_Y * Largeur_ecran + Pos_X;
|
|
|
|
word cx;
|
|
|
|
// Pour chaque pixel de la ligne
|
|
for(cx = Largeur;cx > 0;cx--)
|
|
{
|
|
if(*ESI!=Couleur_transparence)
|
|
*EDI = *ESI;
|
|
ESI++;
|
|
EDI++;
|
|
}
|
|
}
|
|
|
|
// Affiche une partie de la brosse couleur zoomée
|
|
void Display_brush_Color_zoom_SDL (word Pos_X,word Pos_Y,
|
|
word Decalage_X,word Decalage_Y,
|
|
word Largeur, // Largeur non zoomée
|
|
word Pos_Y_Fin,byte Couleur_de_transparence,
|
|
word Largeur_brosse, // Largeur réelle de la brosse
|
|
byte * Buffer)
|
|
{
|
|
byte* ESI = Brosse+Decalage_Y*Largeur_brosse + Decalage_X;
|
|
word DX = Pos_Y;
|
|
byte bx;
|
|
|
|
// Pour chaque ligne
|
|
while(1)
|
|
{
|
|
Zoomer_une_ligne(ESI,Buffer,Loupe_Facteur,Largeur);
|
|
// On affiche facteur fois la ligne zoomée
|
|
for(bx=Loupe_Facteur;bx>0;bx--)
|
|
{
|
|
Afficher_une_ligne_transparente_a_l_ecran_SDL(Pos_X,DX,Largeur*Loupe_Facteur,Buffer,Couleur_de_transparence);
|
|
DX++;
|
|
if(DX==Pos_Y_Fin)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
ESI += Largeur_brosse;
|
|
|
|
}
|
|
// ATTENTION zone jamais atteinte
|
|
}
|
|
|
|
void Display_brush_Mono_zoom_SDL (word Pos_X, word Pos_Y,
|
|
word Decalage_X, word Decalage_Y,
|
|
word Largeur, // Largeur non zoomée
|
|
word Pos_Y_Fin,
|
|
byte Couleur_de_transparence, byte Couleur,
|
|
word Largeur_brosse, // Largeur réelle de la brosse
|
|
byte * Buffer
|
|
)
|
|
|
|
{
|
|
byte* ESI = Brosse + Decalage_Y * Largeur_brosse + Decalage_X;
|
|
int DX=Pos_Y;
|
|
|
|
//Pour chaque ligne à zoomer :
|
|
while(1)
|
|
{
|
|
int BX;
|
|
// ESI = Ligne originale
|
|
// On éclate la ligne
|
|
Zoomer_une_ligne(ESI,Buffer,Loupe_Facteur,Largeur);
|
|
|
|
// On affiche la ligne Facteur fois à l'écran (sur des
|
|
// lignes consécutives)
|
|
BX = Loupe_Facteur;
|
|
|
|
// Pour chaque ligne écran
|
|
do
|
|
{
|
|
// On affiche la ligne zoomée
|
|
Afficher_une_ligne_transparente_mono_a_l_ecran_SDL(
|
|
Pos_X, DX, Largeur * Loupe_Facteur,
|
|
Buffer, Couleur_de_transparence, Couleur
|
|
);
|
|
// On passe à la ligne suivante
|
|
DX++;
|
|
// On vérifie qu'on est pas à la ligne finale
|
|
if(DX == Pos_Y_Fin)
|
|
{
|
|
UpdateRect( Pos_X, Pos_Y,
|
|
Largeur * Loupe_Facteur, Pos_Y_Fin - Pos_Y );
|
|
return;
|
|
}
|
|
BX --;
|
|
}
|
|
while (BX > 0);
|
|
|
|
// Passage à la ligne suivante dans la brosse aussi
|
|
ESI+=Largeur_brosse;
|
|
}
|
|
}
|
|
|
|
void Clear_brush_zoom_SDL (word Pos_X,word Pos_Y,word Decalage_X,word Decalage_Y,word Largeur,word Pos_Y_Fin,__attribute__((unused)) byte Couleur_de_transparence,word Largeur_image,byte * Buffer)
|
|
{
|
|
// En fait on va recopier l'image non zoomée dans la partie zoomée !
|
|
byte* ESI = Principal_Ecran + Decalage_Y * Largeur_image + Decalage_X;
|
|
int DX = Pos_Y;
|
|
int bx;
|
|
|
|
// Pour chaque ligne à zoomer
|
|
while(1){
|
|
Zoomer_une_ligne(ESI,Buffer,Loupe_Facteur,Largeur);
|
|
|
|
bx=Loupe_Facteur;
|
|
|
|
// Pour chaque ligne
|
|
do{
|
|
Afficher_une_ligne_ecran_SDL(Pos_X,DX,
|
|
Largeur * Loupe_Facteur,Buffer);
|
|
|
|
// Ligne suivante
|
|
DX++;
|
|
if(DX==Pos_Y_Fin)
|
|
{
|
|
UpdateRect(Pos_X,Pos_Y,
|
|
Largeur*Loupe_Facteur,Pos_Y_Fin-Pos_Y);
|
|
return;
|
|
}
|
|
bx--;
|
|
}while(bx!=0);
|
|
|
|
ESI+= Largeur_image;
|
|
}
|
|
}
|
|
|
|
void Set_Mode_SDL()
|
|
/* On règle la résolution de l'écran */
|
|
{
|
|
Ecran_SDL=SDL_SetVideoMode(Largeur_ecran,Hauteur_ecran,8,SDL_FULLSCREEN*Plein_ecran|SDL_RESIZABLE);
|
|
if(Ecran_SDL != NULL)
|
|
{
|
|
// Vérification du mode obtenu (ce n'est pas toujours celui demandé)
|
|
if (Ecran_SDL->w != Largeur_ecran || Ecran_SDL->h != Hauteur_ecran)
|
|
{
|
|
DEBUG("Erreur mode video obtenu différent de celui demandé !!",0);
|
|
Largeur_ecran = Ecran_SDL->w;
|
|
Hauteur_ecran = Ecran_SDL->h;
|
|
}
|
|
Ecran=Ecran_SDL->pixels;
|
|
}
|
|
else
|
|
DEBUG("Erreur changement de mode video !!",0);
|
|
|
|
SDL_ShowCursor(0); // Cache le curseur SDL, on le gère en soft
|
|
}
|
|
|
|
// Fonction qui filtre les evenements génériques.
|
|
void Gere_Evenement_SDL(SDL_Event * event)
|
|
{
|
|
// Redimensionnement fenetre
|
|
if (event->type == SDL_VIDEORESIZE )
|
|
{
|
|
Resize_Largeur = event->resize.w;
|
|
Resize_Hauteur = event->resize.h;
|
|
}
|
|
// Fermeture
|
|
if (event->type == SDL_QUIT )
|
|
{
|
|
Quit_demande=1;
|
|
}
|
|
}
|
|
|
|
#if (METHODE_UPDATE == METHODE_UPDATE_PAR_CUMUL)
|
|
short Min_X=0;
|
|
short Min_Y=0;
|
|
short Max_X=10000;
|
|
short Max_Y=10000;
|
|
#endif
|
|
|
|
#if (METHODE_UPDATE == METHODE_UPDATE_PLEINE_PAGE)
|
|
int Update_necessaire=0;
|
|
#endif
|
|
|
|
void Flush_update(void)
|
|
{
|
|
#if (METHODE_UPDATE == METHODE_UPDATE_PLEINE_PAGE)
|
|
// Mise à jour de la totalité de l'écran
|
|
if (Update_necessaire)
|
|
{
|
|
SDL_UpdateRect(Ecran_SDL, 0, 0, 0, 0);
|
|
Update_necessaire=0;
|
|
}
|
|
#endif
|
|
#if (METHODE_UPDATE == METHODE_UPDATE_PAR_CUMUL)
|
|
if (Min_X>=Max_X || Min_Y>=Max_Y)
|
|
{
|
|
; // Rien a faire
|
|
}
|
|
else
|
|
{
|
|
SDL_UpdateRect(Ecran_SDL, Max(Min_X,0), Max(Min_Y,0), Min(Largeur_ecran, Max_X-Min_X), Min(Hauteur_ecran, Max_Y-Min_Y));
|
|
|
|
Min_X=Min_Y=10000;
|
|
Max_X=Max_Y=0;
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
void UpdateRect(short X, short Y, unsigned short Largeur, unsigned short Hauteur)
|
|
{
|
|
#if (METHODE_UPDATE == METHODE_UPDATE_MULTI_RECTANGLE)
|
|
SDL_UpdateRect(Ecran_SDL, (X), (Y), (Largeur), (Hauteur));
|
|
#endif
|
|
|
|
#if (METHODE_UPDATE == METHODE_UPDATE_PAR_CUMUL)
|
|
if (Largeur==0 || Hauteur==0)
|
|
{
|
|
Min_X=Min_Y=0;
|
|
Max_X=Max_Y=10000;
|
|
}
|
|
else
|
|
{
|
|
if (X < Min_X)
|
|
Min_X = X;
|
|
if (Y < Min_Y)
|
|
Min_Y = Y;
|
|
if (X+Largeur>Max_X)
|
|
Max_X=X+Largeur;
|
|
if (Y+Hauteur>Max_Y)
|
|
Max_Y=Y+Hauteur;
|
|
}
|
|
#endif
|
|
|
|
#if (METHODE_UPDATE == METHODE_UPDATE_PLEINE_PAGE)
|
|
Update_necessaire=1;
|
|
#endif
|
|
|
|
}
|
|
|
|
// Convertit une SDL_Surface (couleurs indexées ou RGB) en tableau de bytes (couleurs indexées)
|
|
// Si on passe NULL comme destination, elle est allouée par malloc(). Sinon,
|
|
// attention aux dimensions!
|
|
byte * Surface_en_bytefield(SDL_Surface *Source, byte * Destination)
|
|
{
|
|
byte *Src;
|
|
byte *Dst;
|
|
int Y;
|
|
int Reste;
|
|
|
|
// Support seulement des images 256 couleurs
|
|
if (Source->format->BytesPerPixel != 1)
|
|
return NULL;
|
|
|
|
if (Source->w & 3)
|
|
Reste=4-(Source->w&3);
|
|
else
|
|
Reste=0;
|
|
|
|
if (Destination==NULL)
|
|
Destination=(byte *)malloc(Source->w*Source->h);
|
|
|
|
Dst=Destination;
|
|
Src=(byte *)(Source->pixels);
|
|
for(Y=0; Y < Source->h; Y++)
|
|
{
|
|
memcpy(Dst, Src,Source->w);
|
|
Dst += Source->w;
|
|
Src += Source->w + Reste;
|
|
}
|
|
return Destination;
|
|
|
|
}
|
|
|
|
// Convertit un index de palette en couleur RGB 24 bits
|
|
SDL_Color Conversion_couleur_SDL(byte Index)
|
|
{
|
|
SDL_Color Couleur;
|
|
Couleur.r = (Principal_Palette[Index].R<<2) + (Principal_Palette[Index].R>>4);
|
|
Couleur.g = (Principal_Palette[Index].V<<2) + (Principal_Palette[Index].V>>4);
|
|
Couleur.b = (Principal_Palette[Index].B<<2) + (Principal_Palette[Index].B>>4);
|
|
Couleur.unused = 255;
|
|
return Couleur;
|
|
}
|