Switch to Unix end of line

This commit is contained in:
Thomas Bernard 2017-12-27 22:07:58 +01:00
parent fb197cc0d9
commit cad9aa53fd
6 changed files with 1668 additions and 1668 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,44 +1,44 @@
/* vim:expandtab:ts=2 sw=2: /* vim:expandtab:ts=2 sw=2:
*/ */
/* Grafx2 - The Ultimate 256-color bitmap paint program /* Grafx2 - The Ultimate 256-color bitmap paint program
Copyright 2009 Yves Rizoud Copyright 2009 Yves Rizoud
Copyright 2007 Adrien Destugues Copyright 2007 Adrien Destugues
Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
Grafx2 is free software; you can redistribute it and/or Grafx2 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 as published by the Free Software Foundation; version 2
of the License. of the License.
Grafx2 is distributed in the hope that it will be useful, Grafx2 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Grafx2; if not, see <http://www.gnu.org/licenses/> along with Grafx2; if not, see <http://www.gnu.org/licenses/>
*/ */
void Button_Layer_add(void); void Button_Layer_add(void);
void Button_Layer_duplicate(void); void Button_Layer_duplicate(void);
void Button_Layer_remove(void); void Button_Layer_remove(void);
void Button_Layer_menu(void); void Button_Layer_menu(void);
void Button_Layer_set_transparent(void); void Button_Layer_set_transparent(void);
void Button_Layer_get_transparent(void); void Button_Layer_get_transparent(void);
void Button_Layer_merge(void); void Button_Layer_merge(void);
void Button_Layer_up(void); void Button_Layer_up(void);
void Button_Layer_down(void); void Button_Layer_down(void);
void Button_Layer_select(void); void Button_Layer_select(void);
void Button_Layer_toggle(void); void Button_Layer_toggle(void);
void Layer_activate(int layer, short side); void Layer_activate(int layer, short side);
void Button_Anim_time(void); void Button_Anim_time(void);
void Button_Anim_first_frame(void); void Button_Anim_first_frame(void);
void Button_Anim_prev_frame(void); void Button_Anim_prev_frame(void);
void Button_Anim_next_frame(void); void Button_Anim_next_frame(void);
void Button_Anim_last_frame(void); void Button_Anim_last_frame(void);
void Button_Anim_play(void); void Button_Anim_play(void);
void Button_Anim_continuous_prev(void); void Button_Anim_continuous_prev(void);
void Button_Anim_continuous_next(void); void Button_Anim_continuous_next(void);
short Layer_under_mouse(void); short Layer_under_mouse(void);

View File

@ -1,414 +1,414 @@
/* vim:expandtab:ts=2 sw=2: /* vim:expandtab:ts=2 sw=2:
*/ */
/* Grafx2 - The Ultimate 256-color bitmap paint program /* Grafx2 - The Ultimate 256-color bitmap paint program
Copyright 2008 Yves Rizoud Copyright 2008 Yves Rizoud
Copyright 2008 Franck Charlet Copyright 2008 Franck Charlet
Copyright 2007 Adrien Destugues Copyright 2007 Adrien Destugues
Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
Grafx2 is free software; you can redistribute it and/or Grafx2 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 as published by the Free Software Foundation; version 2
of the License. of the License.
Grafx2 is distributed in the hope that it will be useful, Grafx2 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Grafx2; if not, see <http://www.gnu.org/licenses/> along with Grafx2; if not, see <http://www.gnu.org/licenses/>
*/ */
#include <SDL.h> #include <SDL.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#include "struct.h" #include "struct.h"
#include "global.h" #include "global.h"
#include "errors.h" #include "errors.h"
#include "misc.h" #include "misc.h"
#include "palette.h" #include "palette.h"
#include "pages.h" #include "pages.h"
#include "windows.h" #include "windows.h"
#include "layers.h" #include "layers.h"
void Pixel_in_layer(word x,word y, byte layer, byte color) void Pixel_in_layer(word x,word y, byte layer, byte color)
{ {
*((y)*Main_image_width+(x)+Main_backups->Pages->Image[layer].Pixels)=color; *((y)*Main_image_width+(x)+Main_backups->Pages->Image[layer].Pixels)=color;
} }
byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background) byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background)
{ {
word used_colors[200][40]; word used_colors[200][40];
word block_used_colors[25][40]; word block_used_colors[25][40];
word line_used_colors[200]; word line_used_colors[200];
byte used_colors_count[200][40]; byte used_colors_count[200][40];
dword usage[16]; dword usage[16];
word x,y,row,col; word x,y,row,col;
int i; int i;
byte line_color[200]; byte line_color[200];
byte block_color[25][40]; byte block_color[25][40];
word best_color_count; word best_color_count;
byte best_color; byte best_color;
const byte no_color=16; const byte no_color=16;
// Prerequisites // Prerequisites
if (Main_backups->Pages->Nb_layers < 3) if (Main_backups->Pages->Nb_layers < 3)
return 1; return 1;
if (Main_image_width != 160 || Main_image_height != 200) if (Main_image_width != 160 || Main_image_height != 200)
return 2; return 2;
memset(used_colors,0,200*40*sizeof(word)); memset(used_colors,0,200*40*sizeof(word));
memset(block_used_colors,0,25*40*sizeof(word)); memset(block_used_colors,0,25*40*sizeof(word));
memset(line_used_colors,0,200*sizeof(word)); memset(line_used_colors,0,200*sizeof(word));
memset(used_colors_count,0,200*40*sizeof(byte)); memset(used_colors_count,0,200*40*sizeof(byte));
// Initialize these as "unset" // Initialize these as "unset"
memset(line_color,no_color,200*sizeof(byte)); memset(line_color,no_color,200*sizeof(byte));
memset(block_color,no_color,25*40*sizeof(byte)); memset(block_color,no_color,25*40*sizeof(byte));
// Examine all 4-pixel blocks to fill used_colors[][] // Examine all 4-pixel blocks to fill used_colors[][]
for (row=0;row<200;row++) for (row=0;row<200;row++)
{ {
for (col=0;col<40;col++) for (col=0;col<40;col++)
{ {
for (x=0;x<4;x++) for (x=0;x<4;x++)
{ {
byte c=*((row)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2].Pixels); byte c=*((row)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2].Pixels);
used_colors[row][col] |= 1<<c; used_colors[row][col] |= 1<<c;
} }
} }
} }
// Get "mandatory colors" from layer 1 // Get "mandatory colors" from layer 1
for (row=0;row<200;row++) for (row=0;row<200;row++)
{ {
byte c=*((row)*Main_image_width+0+Main_backups->Pages->Image[0].Pixels); byte c=*((row)*Main_image_width+0+Main_backups->Pages->Image[0].Pixels);
if (c<16) if (c<16)
{ {
line_color[row]=c; line_color[row]=c;
for (col=0;col<40;col++) for (col=0;col<40;col++)
{ {
// Remove that color from the sets // Remove that color from the sets
used_colors[row][col] &= ~(1<<c); used_colors[row][col] &= ~(1<<c);
} }
} }
} }
// Get "mandatory colors" from layer 2 // Get "mandatory colors" from layer 2
for (row=0;row<200;row+=8) for (row=0;row<200;row+=8)
{ {
for (col=0;col<40;col++) for (col=0;col<40;col++)
{ {
byte c=*((row)*Main_image_width+(col*4)+Main_backups->Pages->Image[1].Pixels); byte c=*((row)*Main_image_width+(col*4)+Main_backups->Pages->Image[1].Pixels);
if (c<16) if (c<16)
{ {
block_color[row/8][col]=c; block_color[row/8][col]=c;
// Remove that color from the sets // Remove that color from the sets
for (y=0; y<8;y++) for (y=0; y<8;y++)
used_colors[row+y][col] &= ~(1<<c); used_colors[row+y][col] &= ~(1<<c);
} }
} }
} }
// Now count the "remaining colors". // Now count the "remaining colors".
for (row=0;row<200;row++) for (row=0;row<200;row++)
{ {
memset(usage,0,16*sizeof(dword)); memset(usage,0,16*sizeof(dword));
for (col=0;col<40;col++) for (col=0;col<40;col++)
{ {
used_colors_count[row][col]=Popcount_word(used_colors[row][col]); used_colors_count[row][col]=Popcount_word(used_colors[row][col]);
// Count which colors are used 3 times // Count which colors are used 3 times
if (used_colors_count[row][col]==3) if (used_colors_count[row][col]==3)
{ {
for (i=0; i<16; i++) for (i=0; i<16; i++)
if (used_colors[row][col] & (1<<i)) if (used_colors[row][col] & (1<<i))
usage[i]+=1; usage[i]+=1;
} }
// Count which colors are used 4 times (important) // Count which colors are used 4 times (important)
else if (used_colors_count[row][col]==4) else if (used_colors_count[row][col]==4)
{ {
for (i=0; i<16; i++) for (i=0; i<16; i++)
if (used_colors[row][col] & (1<<i)) if (used_colors[row][col] & (1<<i))
usage[i]+=2; usage[i]+=2;
} }
} }
// A complete line has been examined. Pick the color which has been tagged most, and set it as // A complete line has been examined. Pick the color which has been tagged most, and set it as
// the line color (unless it already was set.) // the line color (unless it already was set.)
if (line_color[row]==no_color) if (line_color[row]==no_color)
{ {
best_color_count=0; best_color_count=0;
best_color=no_color; best_color=no_color;
for (i=0; i<16; i++) for (i=0; i<16; i++)
{ {
if (usage[i]>best_color_count) if (usage[i]>best_color_count)
{ {
best_color_count=usage[i]; best_color_count=usage[i];
best_color=i; best_color=i;
} }
} }
line_color[row]=best_color; line_color[row]=best_color;
// Remove that color from the sets // Remove that color from the sets
for (col=0;col<40;col++) for (col=0;col<40;col++)
{ {
if (used_colors[row][col] & (1<<best_color)) if (used_colors[row][col] & (1<<best_color))
{ {
used_colors[row][col] &= ~(1<<best_color); used_colors[row][col] &= ~(1<<best_color);
// Update count // Update count
used_colors_count[row][col]--; used_colors_count[row][col]--;
} }
} }
} }
} }
// Now check all 4*8 blocks // Now check all 4*8 blocks
for (col=0;col<40;col++) for (col=0;col<40;col++)
{ {
for (row=0;row<200;row+=8) for (row=0;row<200;row+=8)
{ {
// If there wasn't a preset color for this block // If there wasn't a preset color for this block
if (block_color[row/8][col]==no_color) if (block_color[row/8][col]==no_color)
{ {
word filter=0xFFFF; word filter=0xFFFF;
// Count used colors // Count used colors
memset(usage,0,16*sizeof(dword)); memset(usage,0,16*sizeof(dword));
for (y=0;y<8;y++) for (y=0;y<8;y++)
{ {
if (used_colors_count[row+y][col]>2) if (used_colors_count[row+y][col]>2)
{ {
filter &= used_colors[row+y][col]; filter &= used_colors[row+y][col];
for (i=0; i<16; i++) for (i=0; i<16; i++)
{ {
if (used_colors[row+y][col] & (1<<i)) if (used_colors[row+y][col] & (1<<i))
usage[i]+=1; usage[i]+=1;
} }
} }
} }
if (filter != 0 && Popcount_word(filter) == 1) if (filter != 0 && Popcount_word(filter) == 1)
{ {
// Only one color matched all needs: Use it. // Only one color matched all needs: Use it.
i=1; i=1;
best_color=0; best_color=0;
while (! (filter & i)) while (! (filter & i))
{ {
best_color++; best_color++;
i= i << 1; i= i << 1;
} }
} }
else else
{ {
if (filter==0) if (filter==0)
{ {
// No color in common from multiple lines with 3+ colors... // No color in common from multiple lines with 3+ colors...
// Keep them all for the usage sort. // Keep them all for the usage sort.
filter=0xFFFF; filter=0xFFFF;
} }
// Pick the color which has been tagged most, and set it as // Pick the color which has been tagged most, and set it as
// the block color // the block color
best_color_count=0; best_color_count=0;
best_color=no_color; best_color=no_color;
for (i=0; i<16; i++) for (i=0; i<16; i++)
{ {
if (filter & (1<<i)) if (filter & (1<<i))
{ {
if (usage[i]>best_color_count) if (usage[i]>best_color_count)
{ {
best_color_count=usage[i]; best_color_count=usage[i];
best_color=i; best_color=i;
} }
} }
} }
} }
block_color[row/8][col]=best_color; block_color[row/8][col]=best_color;
// Remove that color from the sets // Remove that color from the sets
for (y=0;y<8;y++) for (y=0;y<8;y++)
{ {
if (used_colors[row+y][col] & (1<<best_color)) if (used_colors[row+y][col] & (1<<best_color))
{ {
used_colors[row+y][col] &= ~(1<<best_color); used_colors[row+y][col] &= ~(1<<best_color);
// Update count // Update count
used_colors_count[row+y][col]--; used_colors_count[row+y][col]--;
} }
} }
} }
} }
} }
// At this point, the following arrays are filled: // At this point, the following arrays are filled:
// - block_color[][] // - block_color[][]
// - line_color[] // - line_color[]
// They contain either a color 0-16, or no_color if no color is mandatory. // They contain either a color 0-16, or no_color if no color is mandatory.
// It's now possible to scan the whole image and choose how to encode it. // It's now possible to scan the whole image and choose how to encode it.
// TODO: Draw problematic places on layer 4, with one of the available colors // TODO: Draw problematic places on layer 4, with one of the available colors
/* /*
if (bitmap!=NULL) if (bitmap!=NULL)
{ {
for (row=0;row<200;row++) for (row=0;row<200;row++)
{ {
for (col=0;col<40;col++) for (col=0;col<40;col++)
{ {
} }
} }
} }
*/ */
// Output background // Output background
if (background!=NULL) if (background!=NULL)
{ {
for (row=0;row<200;row++) for (row=0;row<200;row++)
{ {
if (line_color[row]==no_color) if (line_color[row]==no_color)
background[row]=0; // Unneeded line is black background[row]=0; // Unneeded line is black
else else
background[row]=line_color[row]; background[row]=line_color[row];
} }
} }
// Output Color RAM // Output Color RAM
if (color_ram!=NULL) if (color_ram!=NULL)
{ {
for (col=0;col<40;col++) for (col=0;col<40;col++)
{ {
for (row=0;row<25;row++) for (row=0;row<25;row++)
{ {
if (block_color[row][col]==no_color) if (block_color[row][col]==no_color)
color_ram[row*40+col]=0; // Unneeded block is black color_ram[row*40+col]=0; // Unneeded block is black
else else
color_ram[row*40+col]=block_color[row][col]; color_ram[row*40+col]=block_color[row][col];
} }
} }
} }
for(row=0; row<25; row++) for(row=0; row<25; row++)
{ {
for(col=0; col<40; col++) for(col=0; col<40; col++)
{ {
for(y=0; y<8; y++) for(y=0; y<8; y++)
{ {
byte c1, c2; byte c1, c2;
// Find 2 colors in used_colors[row*8+y][col] // Find 2 colors in used_colors[row*8+y][col]
for (c1=0; c1<16 && !(used_colors[row*8+y][col] & (1<<c1)); c1++) for (c1=0; c1<16 && !(used_colors[row*8+y][col] & (1<<c1)); c1++)
; ;
for (c2=c1+1; c2<16 && !(used_colors[row*8+y][col] & (1<<c2)); c2++) for (c2=c1+1; c2<16 && !(used_colors[row*8+y][col] & (1<<c2)); c2++)
; ;
if (c1>15) if (c1>15)
c1=16; c1=16;
if (c2>15) if (c2>15)
c2=16; c2=16;
// Output Screen RAMs // Output Screen RAMs
if (screen_ram!=NULL) if (screen_ram!=NULL)
screen_ram[y*1024+row*40+col] = (c1&15) | ((c2&15)<<4); screen_ram[y*1024+row*40+col] = (c1&15) | ((c2&15)<<4);
// Output bitmap // Output bitmap
if (bitmap!=NULL) if (bitmap!=NULL)
{ {
for(x=0; x<4; x++) for(x=0; x<4; x++)
{ {
byte bits; byte bits;
byte c=*((row*8+y)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2].Pixels); byte c=*((row*8+y)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2].Pixels);
if (c==line_color[row*8+y]) if (c==line_color[row*8+y])
// BG color // BG color
bits=0; bits=0;
else if (c==block_color[row][col]) else if (c==block_color[row][col])
// block color // block color
bits=3; bits=3;
else if (c==c1) else if (c==c1)
// Color 1 // Color 1
bits=2; bits=2;
else if (c==c2) else if (c==c2)
// Color 2 // Color 2
bits=1; bits=1;
else // problem else // problem
bits=0; bits=0;
// clear target bits // clear target bits
//bitmap[row*320+col*8+y] &= ~(3<<((3-x)*2)); //bitmap[row*320+col*8+y] &= ~(3<<((3-x)*2));
// set them // set them
bitmap[row*320+col*8+y] |= bits<<((3-x)*2); bitmap[row*320+col*8+y] |= bits<<((3-x)*2);
} }
} }
} }
} }
} }
//memset(background,3,200); //memset(background,3,200);
//memset(color_ram,5,8000); //memset(color_ram,5,8000);
//memset(screen_ram,(9<<4) | 7,8192); //memset(screen_ram,(9<<4) | 7,8192);
return 0; return 0;
} }
byte C64_FLI_enforcer(void) byte C64_FLI_enforcer(void)
{ {
byte background[200]; byte background[200];
byte bitmap[8000]; byte bitmap[8000];
byte screen_ram[8192]; byte screen_ram[8192];
byte color_ram[1000]; byte color_ram[1000];
int row, col, x, y; int row, col, x, y;
byte c[4]; byte c[4];
// Checks // Checks
if (Main_image_width != 160) if (Main_image_width != 160)
return 1; return 1;
if (Main_image_height != 200) if (Main_image_height != 200)
return 1; return 1;
if (Main_backups->Pages->Nb_layers != 4) if (Main_backups->Pages->Nb_layers != 4)
return 2; return 2;
Backup_layers(3); Backup_layers(3);
memset(bitmap,0,8000); memset(bitmap,0,8000);
memset(background,0,200); memset(background,0,200);
memset(color_ram,0,1000); memset(color_ram,0,1000);
memset(screen_ram,0,8192); memset(screen_ram,0,8192);
C64_FLI(bitmap, screen_ram, color_ram, background); C64_FLI(bitmap, screen_ram, color_ram, background);
for(row=0; row<25; row++) for(row=0; row<25; row++)
{ {
for(col=0; col<40; col++) for(col=0; col<40; col++)
{ {
c[3]=color_ram[row*40+col]&15; c[3]=color_ram[row*40+col]&15;
for(y=0; y<8; y++) for(y=0; y<8; y++)
{ {
int pixel=bitmap[row*320+col*8+y]; int pixel=bitmap[row*320+col*8+y];
c[0]=background[row*8+y]&15; c[0]=background[row*8+y]&15;
c[1]=screen_ram[y*1024+row*40+col]>>4; c[1]=screen_ram[y*1024+row*40+col]>>4;
c[2]=screen_ram[y*1024+row*40+col]&15; c[2]=screen_ram[y*1024+row*40+col]&15;
for(x=0; x<4; x++) for(x=0; x<4; x++)
{ {
int color=c[(pixel&3)]; int color=c[(pixel&3)];
pixel>>=2; pixel>>=2;
Pixel_in_layer(col*4+(3-x),row*8+y,3,color); Pixel_in_layer(col*4+(3-x),row*8+y,3,color);
} }
} }
} }
} }
End_of_modification(); End_of_modification();
// Visible feedback: // Visible feedback:
// If the "check" layer was visible, manually update the whole thing // If the "check" layer was visible, manually update the whole thing
if (Main_layers_visible & (1<<3)) if (Main_layers_visible & (1<<3))
{ {
Hide_cursor(); Hide_cursor();
Redraw_layered_image(); Redraw_layered_image();
Display_all_screen(); Display_all_screen();
Display_layerbar(); Display_layerbar();
Display_cursor(); Display_cursor();
} }
else else
// Otherwise, simply toggle the layer visiblity // Otherwise, simply toggle the layer visiblity
Layer_activate(3,RIGHT_SIDE); Layer_activate(3,RIGHT_SIDE);
return 0; return 0;
} }

View File

@ -1,24 +1,24 @@
/* vim:expandtab:ts=2 sw=2: /* vim:expandtab:ts=2 sw=2:
*/ */
/* Grafx2 - The Ultimate 256-color bitmap paint program /* Grafx2 - The Ultimate 256-color bitmap paint program
Copyright 2008 Adrien Destugues Copyright 2008 Adrien Destugues
Grafx2 is free software; you can redistribute it and/or Grafx2 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 as published by the Free Software Foundation; version 2
of the License. of the License.
Grafx2 is distributed in the hope that it will be useful, Grafx2 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Grafx2; if not, see <http://www.gnu.org/licenses/> along with Grafx2; if not, see <http://www.gnu.org/licenses/>
*/ */
byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background); byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background);
byte C64_FLI_enforcer(void); byte C64_FLI_enforcer(void);

View File

@ -1,426 +1,426 @@
/* vim:expandtab:ts=2 sw=2: /* vim:expandtab:ts=2 sw=2:
*/ */
/* Grafx2 - The Ultimate 256-color bitmap paint program /* Grafx2 - The Ultimate 256-color bitmap paint program
Copyright 2011 Yves Rizoud Copyright 2011 Yves Rizoud
Copyright 2010-2011 Adrien Destugues Copyright 2010-2011 Adrien Destugues
Grafx2 is free software; you can redistribute it and/or Grafx2 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 as published by the Free Software Foundation; version 2
of the License. of the License.
Grafx2 is distributed in the hope that it will be useful, Grafx2 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Grafx2; if not, see <http://www.gnu.org/licenses/> along with Grafx2; if not, see <http://www.gnu.org/licenses/>
*/ */
#include "struct.h" #include "struct.h"
#include "global.h" #include "global.h"
#include "graph.h" #include "graph.h"
#include "sdlscreen.h" #include "sdlscreen.h"
#include "engine.h" #include "engine.h"
#include "windows.h" #include "windows.h"
#include "input.h" #include "input.h"
#include "misc.h" #include "misc.h"
#include "tiles.h" #include "tiles.h"
// These helpers are only needed internally at the moment // These helpers are only needed internally at the moment
#define TILE_FOR_COORDS(x,y) (((y)-Snap_offset_Y)/Snap_height*Main_tilemap_width+((x)-Snap_offset_X)/Snap_width) #define TILE_FOR_COORDS(x,y) (((y)-Snap_offset_Y)/Snap_height*Main_tilemap_width+((x)-Snap_offset_X)/Snap_width)
#define TILE_AT(x,y) (y)*Main_tilemap_width+(x) #define TILE_AT(x,y) (y)*Main_tilemap_width+(x)
#define TILE_X(t) (((t)%Main_tilemap_width)*Snap_width+Snap_offset_X) #define TILE_X(t) (((t)%Main_tilemap_width)*Snap_width+Snap_offset_X)
#define TILE_Y(t) (((t)/Main_tilemap_width)*Snap_height+Snap_offset_Y) #define TILE_Y(t) (((t)/Main_tilemap_width)*Snap_height+Snap_offset_Y)
enum TILE_FLIPPED enum TILE_FLIPPED
{ {
TILE_FLIPPED_NONE = 0, TILE_FLIPPED_NONE = 0,
TILE_FLIPPED_X = 1, TILE_FLIPPED_X = 1,
TILE_FLIPPED_Y = 2, TILE_FLIPPED_Y = 2,
TILE_FLIPPED_XY = 3, // needs be TILE_FLIPPED_X|TILE_FLIPPED_Y TILE_FLIPPED_XY = 3, // needs be TILE_FLIPPED_X|TILE_FLIPPED_Y
}; };
// globals // globals
/// Tilemap for the main screen /// Tilemap for the main screen
T_Tile * Main_tilemap; T_Tile * Main_tilemap;
/// Number of tiles (horizontally) for the main page's tilemap /// Number of tiles (horizontally) for the main page's tilemap
short Main_tilemap_width; short Main_tilemap_width;
/// Number of tiles (vertically) for the main page's tilemap /// Number of tiles (vertically) for the main page's tilemap
short Main_tilemap_height; short Main_tilemap_height;
/// Tilemap for the spare /// Tilemap for the spare
T_Tile * Spare_tilemap; T_Tile * Spare_tilemap;
/// Number of tiles (horizontally) for the spare page's tilemap /// Number of tiles (horizontally) for the spare page's tilemap
short Spare_tilemap_width; short Spare_tilemap_width;
/// Number of tiles (vertically) for the spare page's tilemap /// Number of tiles (vertically) for the spare page's tilemap
short Spare_tilemap_height; short Spare_tilemap_height;
/// ///
/// Draw a pixel while Tilemap mode is active : This will paint on all /// Draw a pixel while Tilemap mode is active : This will paint on all
/// similar tiles of the layer, visible on the screen or not. /// similar tiles of the layer, visible on the screen or not.
void Tilemap_draw(word x, word y, byte color) void Tilemap_draw(word x, word y, byte color)
{ {
int tile, first_tile; int tile, first_tile;
int rel_x, rel_y; int rel_x, rel_y;
if (x < Snap_offset_X if (x < Snap_offset_X
|| y < Snap_offset_Y || y < Snap_offset_Y
|| x >= Snap_offset_X + Main_tilemap_width*Snap_width || x >= Snap_offset_X + Main_tilemap_width*Snap_width
|| y >= Snap_offset_Y + Main_tilemap_height*Snap_height) || y >= Snap_offset_Y + Main_tilemap_height*Snap_height)
return; return;
tile = first_tile = TILE_FOR_COORDS(x,y); tile = first_tile = TILE_FOR_COORDS(x,y);
rel_x = (x - Snap_offset_X + Snap_width) % Snap_width; rel_x = (x - Snap_offset_X + Snap_width) % Snap_width;
rel_y = (y - Snap_offset_Y + Snap_height) % Snap_height; rel_y = (y - Snap_offset_Y + Snap_height) % Snap_height;
do do
{ {
int xx,yy; int xx,yy;
switch(Main_tilemap[tile].Flipped ^ Main_tilemap[first_tile].Flipped) switch(Main_tilemap[tile].Flipped ^ Main_tilemap[first_tile].Flipped)
{ {
case 0: // no case 0: // no
default: default:
xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + rel_x; xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + rel_x;
yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + rel_y; yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + rel_y;
break; break;
case 1: // horizontal case 1: // horizontal
xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + Snap_width-rel_x-1; xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + Snap_width-rel_x-1;
yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + rel_y; yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + rel_y;
break; break;
case 2: // vertical case 2: // vertical
xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + rel_x; xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + rel_x;
yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + Snap_height - rel_y - 1; yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + Snap_height - rel_y - 1;
break; break;
case 3: // both case 3: // both
xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + Snap_width-rel_x-1; xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + Snap_width-rel_x-1;
yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + Snap_height - rel_y - 1; yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + Snap_height - rel_y - 1;
break; break;
} }
if (yy>=Limit_top&&yy<=Limit_bottom&&xx>=Limit_left&&xx<=Limit_right) if (yy>=Limit_top&&yy<=Limit_bottom&&xx>=Limit_left&&xx<=Limit_right)
Pixel_in_current_screen_with_preview(xx,yy,color); Pixel_in_current_screen_with_preview(xx,yy,color);
else else
Pixel_in_current_screen(xx,yy,color); Pixel_in_current_screen(xx,yy,color);
tile = Main_tilemap[tile].Next; tile = Main_tilemap[tile].Next;
} while (tile != first_tile); } while (tile != first_tile);
Update_rect(0,0,0,0); Update_rect(0,0,0,0);
} }
/// ///
int Tile_is_same(int t1, int t2) int Tile_is_same(int t1, int t2)
{ {
byte *bmp1,*bmp2; byte *bmp1,*bmp2;
int y; int y;
bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1)); bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1));
bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2))*Main_image_width+(TILE_X(t2)); bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2))*Main_image_width+(TILE_X(t2));
for (y=0; y < Snap_height; y++) for (y=0; y < Snap_height; y++)
{ {
if (memcmp(bmp1+y*Main_image_width, bmp2+y*Main_image_width, Snap_width)) if (memcmp(bmp1+y*Main_image_width, bmp2+y*Main_image_width, Snap_width))
return 0; return 0;
} }
return 1; return 1;
} }
/// ///
int Tile_is_same_flipped_x(int t1, int t2) int Tile_is_same_flipped_x(int t1, int t2)
{ {
byte *bmp1,*bmp2; byte *bmp1,*bmp2;
int y, x; int y, x;
bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1)); bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1));
bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2))*Main_image_width+(TILE_X(t2)+Snap_width-1); bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2))*Main_image_width+(TILE_X(t2)+Snap_width-1);
for (y=0; y < Snap_height; y++) for (y=0; y < Snap_height; y++)
{ {
for (x=0; x < Snap_width; x++) for (x=0; x < Snap_width; x++)
if (*(bmp1+y*Main_image_width+x) != *(bmp2+y*Main_image_width-x)) if (*(bmp1+y*Main_image_width+x) != *(bmp2+y*Main_image_width-x))
return 0; return 0;
} }
return 1; return 1;
} }
/// ///
int Tile_is_same_flipped_y(int t1, int t2) int Tile_is_same_flipped_y(int t1, int t2)
{ {
byte *bmp1,*bmp2; byte *bmp1,*bmp2;
int y; int y;
bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1)); bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1));
bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2)+Snap_height-1)*Main_image_width+(TILE_X(t2)); bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2)+Snap_height-1)*Main_image_width+(TILE_X(t2));
for (y=0; y < Snap_height; y++) for (y=0; y < Snap_height; y++)
{ {
if (memcmp(bmp1+y*Main_image_width, bmp2-y*Main_image_width, Snap_width)) if (memcmp(bmp1+y*Main_image_width, bmp2-y*Main_image_width, Snap_width))
return 0; return 0;
} }
return 1; return 1;
} }
/// ///
int Tile_is_same_flipped_xy(int t1, int t2) int Tile_is_same_flipped_xy(int t1, int t2)
{ {
byte *bmp1,*bmp2; byte *bmp1,*bmp2;
int y, x; int y, x;
bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1)); bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1));
bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2)+Snap_height-1)*Main_image_width+(TILE_X(t2)+Snap_width-1); bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2)+Snap_height-1)*Main_image_width+(TILE_X(t2)+Snap_width-1);
for (y=0; y < Snap_height; y++) for (y=0; y < Snap_height; y++)
{ {
for (x=0; x < Snap_width; x++) for (x=0; x < Snap_width; x++)
if (*(bmp1+y*Main_image_width+x) != *(bmp2-y*Main_image_width-x)) if (*(bmp1+y*Main_image_width+x) != *(bmp2-y*Main_image_width-x))
return 0; return 0;
} }
return 1; return 1;
} }
/// Create or update a tilemap based on current screen (layer)'s pixels. /// Create or update a tilemap based on current screen (layer)'s pixels.
void Tilemap_update(void) void Tilemap_update(void)
{ {
int width; int width;
int height; int height;
int tile; int tile;
int count=1; int count=1;
T_Tile * tile_ptr; T_Tile * tile_ptr;
int wait_window=0; int wait_window=0;
byte old_cursor=0; byte old_cursor=0;
if (!Main_tilemap_mode) if (!Main_tilemap_mode)
return; return;
width=(Main_image_width-Snap_offset_X)/Snap_width; width=(Main_image_width-Snap_offset_X)/Snap_width;
height=(Main_image_height-Snap_offset_Y)/Snap_height; height=(Main_image_height-Snap_offset_Y)/Snap_height;
if (width<1 || height<1 || width*height>1000000l if (width<1 || height<1 || width*height>1000000l
|| (tile_ptr=(T_Tile *)malloc(width*height*sizeof(T_Tile))) == NULL) || (tile_ptr=(T_Tile *)malloc(width*height*sizeof(T_Tile))) == NULL)
{ {
// Cannot enable tilemap because either the image is too small // Cannot enable tilemap because either the image is too small
// for the grid settings (and I don't want to implement partial tiles) // for the grid settings (and I don't want to implement partial tiles)
// Or the number of tiles seems unreasonable (one million) : This can // Or the number of tiles seems unreasonable (one million) : This can
// happen if you set grid 1x1 for example. // happen if you set grid 1x1 for example.
Disable_main_tilemap(); Disable_main_tilemap();
return; return;
} }
if (Main_tilemap) if (Main_tilemap)
{ {
// Recycle existing tilemap // Recycle existing tilemap
free(Main_tilemap); free(Main_tilemap);
Main_tilemap=NULL; Main_tilemap=NULL;
} }
Main_tilemap=tile_ptr; Main_tilemap=tile_ptr;
Main_tilemap_width=width; Main_tilemap_width=width;
Main_tilemap_height=height; Main_tilemap_height=height;
if (width*height > 1000 || Config.Tilemap_show_count) if (width*height > 1000 || Config.Tilemap_show_count)
{ {
wait_window=1; wait_window=1;
old_cursor=Cursor_shape; old_cursor=Cursor_shape;
Open_window(180,36,"Creating tileset"); Open_window(180,36,"Creating tileset");
Print_in_window(26, 20, "Please wait...",MC_Black,MC_Light); Print_in_window(26, 20, "Please wait...",MC_Black,MC_Light);
Cursor_shape=CURSOR_SHAPE_HOURGLASS; Cursor_shape=CURSOR_SHAPE_HOURGLASS;
Update_window_area(0,0,Window_width, Window_height); Update_window_area(0,0,Window_width, Window_height);
Display_cursor(); Display_cursor();
Get_input(0); Get_input(0);
} }
// Initialize array with all tiles unique by default // Initialize array with all tiles unique by default
for (tile=0; tile<width*height; tile++) for (tile=0; tile<width*height; tile++)
{ {
Main_tilemap[tile].Previous = tile; Main_tilemap[tile].Previous = tile;
Main_tilemap[tile].Next = tile; Main_tilemap[tile].Next = tile;
Main_tilemap[tile].Flipped = 0; Main_tilemap[tile].Flipped = 0;
} }
// Now find similar tiles and link them in circular linked list // Now find similar tiles and link them in circular linked list
//It will be used to modify all tiles whenever you draw on one. //It will be used to modify all tiles whenever you draw on one.
for (tile=1; tile<width*height; tile++) for (tile=1; tile<width*height; tile++)
{ {
int ref_tile; int ref_tile;
// Try normal comparison // Try normal comparison
for (ref_tile=0; ref_tile<tile; ref_tile++) for (ref_tile=0; ref_tile<tile; ref_tile++)
{ {
if (Main_tilemap[ref_tile].Previous<=ref_tile && Tile_is_same(ref_tile, tile)) if (Main_tilemap[ref_tile].Previous<=ref_tile && Tile_is_same(ref_tile, tile))
{ {
break; // stop loop on ref_tile break; // stop loop on ref_tile
} }
} }
if (ref_tile<tile) if (ref_tile<tile)
{ {
// New occurence of a known tile // New occurence of a known tile
// Insert at the end. classic doubly-linked-list. // Insert at the end. classic doubly-linked-list.
int last_tile=Main_tilemap[ref_tile].Previous; int last_tile=Main_tilemap[ref_tile].Previous;
Main_tilemap[tile].Previous=last_tile; Main_tilemap[tile].Previous=last_tile;
Main_tilemap[tile].Next=ref_tile; Main_tilemap[tile].Next=ref_tile;
Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped; Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped;
Main_tilemap[ref_tile].Previous=tile; Main_tilemap[ref_tile].Previous=tile;
Main_tilemap[last_tile].Next=tile; Main_tilemap[last_tile].Next=tile;
continue; // next tile continue; // next tile
} }
// Try flipped-y comparison // Try flipped-y comparison
if (Config.Tilemap_allow_flipped_y) if (Config.Tilemap_allow_flipped_y)
{ {
for (ref_tile=0; ref_tile<tile; ref_tile++) for (ref_tile=0; ref_tile<tile; ref_tile++)
{ {
if (Main_tilemap[ref_tile].Previous<=ref_tile && Tile_is_same_flipped_y(ref_tile, tile)) if (Main_tilemap[ref_tile].Previous<=ref_tile && Tile_is_same_flipped_y(ref_tile, tile))
{ {
break; // stop loop on ref_tile break; // stop loop on ref_tile
} }
} }
if (ref_tile<tile) if (ref_tile<tile)
{ {
// New occurence of a known tile // New occurence of a known tile
// Insert at the end. classic doubly-linked-list. // Insert at the end. classic doubly-linked-list.
int last_tile=Main_tilemap[ref_tile].Previous; int last_tile=Main_tilemap[ref_tile].Previous;
Main_tilemap[tile].Previous=last_tile; Main_tilemap[tile].Previous=last_tile;
Main_tilemap[tile].Next=ref_tile; Main_tilemap[tile].Next=ref_tile;
Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped ^ TILE_FLIPPED_Y; Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped ^ TILE_FLIPPED_Y;
Main_tilemap[ref_tile].Previous=tile; Main_tilemap[ref_tile].Previous=tile;
Main_tilemap[last_tile].Next=tile; Main_tilemap[last_tile].Next=tile;
continue; // next tile continue; // next tile
} }
} }
// Try flipped-x comparison // Try flipped-x comparison
if (Config.Tilemap_allow_flipped_x) if (Config.Tilemap_allow_flipped_x)
{ {
for (ref_tile=0; ref_tile<tile; ref_tile++) for (ref_tile=0; ref_tile<tile; ref_tile++)
{ {
if (Main_tilemap[ref_tile].Previous<=ref_tile && Tile_is_same_flipped_x(ref_tile, tile)) if (Main_tilemap[ref_tile].Previous<=ref_tile && Tile_is_same_flipped_x(ref_tile, tile))
{ {
break; // stop loop on ref_tile break; // stop loop on ref_tile
} }
} }
if (ref_tile<tile) if (ref_tile<tile)
{ {
// New occurence of a known tile // New occurence of a known tile
// Insert at the end. classic doubly-linked-list. // Insert at the end. classic doubly-linked-list.
int last_tile=Main_tilemap[ref_tile].Previous; int last_tile=Main_tilemap[ref_tile].Previous;
Main_tilemap[tile].Previous=last_tile; Main_tilemap[tile].Previous=last_tile;
Main_tilemap[tile].Next=ref_tile; Main_tilemap[tile].Next=ref_tile;
Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped ^ TILE_FLIPPED_X; Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped ^ TILE_FLIPPED_X;
Main_tilemap[ref_tile].Previous=tile; Main_tilemap[ref_tile].Previous=tile;
Main_tilemap[last_tile].Next=tile; Main_tilemap[last_tile].Next=tile;
continue; // next tile continue; // next tile
} }
} }
// Try flipped-xy comparison // Try flipped-xy comparison
if (Config.Tilemap_allow_flipped_x && Config.Tilemap_allow_flipped_y) if (Config.Tilemap_allow_flipped_x && Config.Tilemap_allow_flipped_y)
{ {
for (ref_tile=0; ref_tile<tile; ref_tile++) for (ref_tile=0; ref_tile<tile; ref_tile++)
{ {
if (Main_tilemap[ref_tile].Previous<=ref_tile && Tile_is_same_flipped_xy(ref_tile, tile)) if (Main_tilemap[ref_tile].Previous<=ref_tile && Tile_is_same_flipped_xy(ref_tile, tile))
{ {
break; // stop loop on ref_tile break; // stop loop on ref_tile
} }
} }
if (ref_tile<tile) if (ref_tile<tile)
{ {
// New occurence of a known tile // New occurence of a known tile
// Insert at the end. classic doubly-linked-list. // Insert at the end. classic doubly-linked-list.
int last_tile=Main_tilemap[ref_tile].Previous; int last_tile=Main_tilemap[ref_tile].Previous;
Main_tilemap[tile].Previous=last_tile; Main_tilemap[tile].Previous=last_tile;
Main_tilemap[tile].Next=ref_tile; Main_tilemap[tile].Next=ref_tile;
Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped ^ TILE_FLIPPED_XY; Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped ^ TILE_FLIPPED_XY;
Main_tilemap[ref_tile].Previous=tile; Main_tilemap[ref_tile].Previous=tile;
Main_tilemap[last_tile].Next=tile; Main_tilemap[last_tile].Next=tile;
continue; // next tile continue; // next tile
} }
} }
// This tile is really unique. // This tile is really unique.
// Nothing to do at this time: the initialization // Nothing to do at this time: the initialization
// has already set the right data for Main_tilemap[tile]. // has already set the right data for Main_tilemap[tile].
count++; count++;
} }
if (wait_window) if (wait_window)
{ {
char str[8]; char str[8];
Uint32 end; Uint32 end;
if (Config.Tilemap_show_count) if (Config.Tilemap_show_count)
{ {
Num2str(count,str,7); Num2str(count,str,7);
Hide_cursor(); Hide_cursor();
Print_in_window(6, 20, "Unique tiles: ",MC_Black,MC_Light); Print_in_window(6, 20, "Unique tiles: ",MC_Black,MC_Light);
Print_in_window(6+8*14,20,str,MC_Black,MC_Light); Print_in_window(6+8*14,20,str,MC_Black,MC_Light);
Display_cursor(); Display_cursor();
// Wait a moment to display count // Wait a moment to display count
end = SDL_GetTicks()+750; end = SDL_GetTicks()+750;
do do
{ {
Get_input(20); Get_input(20);
} while (SDL_GetTicks()<end); } while (SDL_GetTicks()<end);
} }
Close_window(); Close_window();
Cursor_shape=old_cursor; Cursor_shape=old_cursor;
Display_cursor(); Display_cursor();
} }
} }
/// ///
/// This exchanges the tilemap settings of the main and spare, it should /// This exchanges the tilemap settings of the main and spare, it should
/// be called when swapping pages. /// be called when swapping pages.
void Swap_tilemap(void) void Swap_tilemap(void)
{ {
SWAP_BYTES(Main_tilemap_mode, Spare_tilemap_mode) SWAP_BYTES(Main_tilemap_mode, Spare_tilemap_mode)
{ {
T_Tile * a; T_Tile * a;
a=Main_tilemap; a=Main_tilemap;
Main_tilemap=Spare_tilemap; Main_tilemap=Spare_tilemap;
Spare_tilemap=a; Spare_tilemap=a;
} }
SWAP_SHORTS(Main_tilemap_width, Spare_tilemap_width) SWAP_SHORTS(Main_tilemap_width, Spare_tilemap_width)
SWAP_SHORTS(Main_tilemap_height, Spare_tilemap_height) SWAP_SHORTS(Main_tilemap_height, Spare_tilemap_height)
} }
/// ///
/// Clears all tilemap data and settings for the main page. /// Clears all tilemap data and settings for the main page.
/// Safe to call again. /// Safe to call again.
void Disable_main_tilemap(void) void Disable_main_tilemap(void)
{ {
if (Main_tilemap) if (Main_tilemap)
{ {
// Recycle existing tilemap // Recycle existing tilemap
free(Main_tilemap); free(Main_tilemap);
Main_tilemap=NULL; Main_tilemap=NULL;
} }
Main_tilemap_width=0; Main_tilemap_width=0;
Main_tilemap_height=0; Main_tilemap_height=0;
Main_tilemap_mode=0; Main_tilemap_mode=0;
} }
/// ///
/// Clears all tilemap data and settings for the spare. /// Clears all tilemap data and settings for the spare.
/// Safe to call again. /// Safe to call again.
void Disable_spare_tilemap(void) void Disable_spare_tilemap(void)
{ {
if (Spare_tilemap) if (Spare_tilemap)
{ {
// Recycle existing tilemap // Recycle existing tilemap
free(Spare_tilemap); free(Spare_tilemap);
Spare_tilemap=NULL; Spare_tilemap=NULL;
} }
Spare_tilemap_width=0; Spare_tilemap_width=0;
Spare_tilemap_height=0; Spare_tilemap_height=0;
Spare_tilemap_mode=0; Spare_tilemap_mode=0;
} }

View File

@ -1,63 +1,63 @@
/* vim:expandtab:ts=2 sw=2: /* vim:expandtab:ts=2 sw=2:
*/ */
/* Grafx2 - The Ultimate 256-color bitmap paint program /* Grafx2 - The Ultimate 256-color bitmap paint program
Copyright 2011 Yves Rizoud Copyright 2011 Yves Rizoud
Copyright 2011 Adrien Destugues Copyright 2011 Adrien Destugues
Grafx2 is free software; you can redistribute it and/or Grafx2 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 as published by the Free Software Foundation; version 2
of the License. of the License.
Grafx2 is distributed in the hope that it will be useful, Grafx2 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Grafx2; if not, see <http://www.gnu.org/licenses/> along with Grafx2; if not, see <http://www.gnu.org/licenses/>
*/ */
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
///@file tiles.h ///@file tiles.h
/// Functions for tilemap effect /// Functions for tilemap effect
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// Create or update a tilemap based on current screen pixels. /// Create or update a tilemap based on current screen pixels.
void Tilemap_update(void); void Tilemap_update(void);
/// ///
/// Draw a pixel while Tilemap mode is active : This will paint on all /// Draw a pixel while Tilemap mode is active : This will paint on all
/// similar tiles of the layer, visible on the screen or not. /// similar tiles of the layer, visible on the screen or not.
void Tilemap_draw(word x, word y, byte color); void Tilemap_draw(word x, word y, byte color);
/// ///
/// This exchanges the tilemap settings of the main and spare, it should /// This exchanges the tilemap settings of the main and spare, it should
/// be called when swapping pages. /// be called when swapping pages.
void Swap_tilemap(void); void Swap_tilemap(void);
/// ///
/// Clears all tilemap data and settings for the main page. /// Clears all tilemap data and settings for the main page.
/// Safe to call again. /// Safe to call again.
void Disable_main_tilemap(void); void Disable_main_tilemap(void);
/// ///
/// Clears all tilemap data and settings for the spare. /// Clears all tilemap data and settings for the spare.
/// Safe to call again. /// Safe to call again.
void Disable_spare_tilemap(void); void Disable_spare_tilemap(void);
/// Tilemap for the main screen /// Tilemap for the main screen
extern T_Tile * Main_tilemap; extern T_Tile * Main_tilemap;
/// Number of tiles (horizontally) for the main page's tilemap /// Number of tiles (horizontally) for the main page's tilemap
extern short Main_tilemap_width; extern short Main_tilemap_width;
/// Number of tiles (vertically) for the main page's tilemap /// Number of tiles (vertically) for the main page's tilemap
extern short Main_tilemap_height; extern short Main_tilemap_height;
/// Tilemap for the spare /// Tilemap for the spare
extern T_Tile * Spare_tilemap; extern T_Tile * Spare_tilemap;
/// Number of tiles (horizontally) for the spare page's tilemap /// Number of tiles (horizontally) for the spare page's tilemap
extern short Spare_tilemap_width; extern short Spare_tilemap_width;
/// Number of tiles (vertically) for the spare page's tilemap /// Number of tiles (vertically) for the spare page's tilemap
extern short Spare_tilemap_height; extern short Spare_tilemap_height;