642 lines
19 KiB
C
642 lines
19 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 <stdlib.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,__attribute__((unused)) word Decalage_X,__attribute__((unused)) word Decalage_Y,word Largeur,word Hauteur,__attribute__((unused))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);
|
|
}
|
|
|
|
// Affiche une brosse (arbitraire) à l'écran
|
|
void Affiche_brosse_SDL(byte * B, 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 = B + 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;
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|