Switch to Unix end of line
This commit is contained in:
		
							parent
							
								
									fb197cc0d9
								
							
						
					
					
						commit
						cad9aa53fd
					
				
							
								
								
									
										1394
									
								
								src/layers.c
									
									
									
									
									
								
							
							
						
						
									
										1394
									
								
								src/layers.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										88
									
								
								src/layers.h
									
									
									
									
									
								
							
							
						
						
									
										88
									
								
								src/layers.h
									
									
									
									
									
								
							@ -1,44 +1,44 @@
 | 
			
		||||
/* vim:expandtab:ts=2 sw=2:
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2009 Yves Rizoud
 | 
			
		||||
    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/>
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
void Button_Layer_add(void);
 | 
			
		||||
void Button_Layer_duplicate(void);
 | 
			
		||||
void Button_Layer_remove(void);
 | 
			
		||||
void Button_Layer_menu(void);
 | 
			
		||||
void Button_Layer_set_transparent(void);
 | 
			
		||||
void Button_Layer_get_transparent(void);
 | 
			
		||||
void Button_Layer_merge(void);
 | 
			
		||||
void Button_Layer_up(void);
 | 
			
		||||
void Button_Layer_down(void);
 | 
			
		||||
void Button_Layer_select(void);
 | 
			
		||||
void Button_Layer_toggle(void);
 | 
			
		||||
void Layer_activate(int layer, short side);
 | 
			
		||||
void Button_Anim_time(void);
 | 
			
		||||
void Button_Anim_first_frame(void);
 | 
			
		||||
void Button_Anim_prev_frame(void);
 | 
			
		||||
void Button_Anim_next_frame(void);
 | 
			
		||||
void Button_Anim_last_frame(void);
 | 
			
		||||
void Button_Anim_play(void);
 | 
			
		||||
void Button_Anim_continuous_prev(void);
 | 
			
		||||
void Button_Anim_continuous_next(void);
 | 
			
		||||
 | 
			
		||||
short Layer_under_mouse(void);
 | 
			
		||||
/* vim:expandtab:ts=2 sw=2:
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2009 Yves Rizoud
 | 
			
		||||
    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/>
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
void Button_Layer_add(void);
 | 
			
		||||
void Button_Layer_duplicate(void);
 | 
			
		||||
void Button_Layer_remove(void);
 | 
			
		||||
void Button_Layer_menu(void);
 | 
			
		||||
void Button_Layer_set_transparent(void);
 | 
			
		||||
void Button_Layer_get_transparent(void);
 | 
			
		||||
void Button_Layer_merge(void);
 | 
			
		||||
void Button_Layer_up(void);
 | 
			
		||||
void Button_Layer_down(void);
 | 
			
		||||
void Button_Layer_select(void);
 | 
			
		||||
void Button_Layer_toggle(void);
 | 
			
		||||
void Layer_activate(int layer, short side);
 | 
			
		||||
void Button_Anim_time(void);
 | 
			
		||||
void Button_Anim_first_frame(void);
 | 
			
		||||
void Button_Anim_prev_frame(void);
 | 
			
		||||
void Button_Anim_next_frame(void);
 | 
			
		||||
void Button_Anim_last_frame(void);
 | 
			
		||||
void Button_Anim_play(void);
 | 
			
		||||
void Button_Anim_continuous_prev(void);
 | 
			
		||||
void Button_Anim_continuous_next(void);
 | 
			
		||||
 | 
			
		||||
short Layer_under_mouse(void);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										828
									
								
								src/oldies.c
									
									
									
									
									
								
							
							
						
						
									
										828
									
								
								src/oldies.c
									
									
									
									
									
								
							@ -1,414 +1,414 @@
 | 
			
		||||
/* vim:expandtab:ts=2 sw=2:
 | 
			
		||||
*/
 | 
			
		||||
/*  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/>
 | 
			
		||||
*/
 | 
			
		||||
#include <SDL.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include "struct.h"
 | 
			
		||||
#include "global.h"
 | 
			
		||||
#include "errors.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "palette.h"
 | 
			
		||||
#include "pages.h"
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
#include "layers.h"
 | 
			
		||||
 | 
			
		||||
void Pixel_in_layer(word x,word y, byte layer, byte 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)
 | 
			
		||||
{
 | 
			
		||||
  word used_colors[200][40];
 | 
			
		||||
  word block_used_colors[25][40];
 | 
			
		||||
  word line_used_colors[200];
 | 
			
		||||
  byte used_colors_count[200][40];
 | 
			
		||||
  dword usage[16];
 | 
			
		||||
  word x,y,row,col;
 | 
			
		||||
  int i;
 | 
			
		||||
  byte line_color[200];
 | 
			
		||||
  byte block_color[25][40];
 | 
			
		||||
  word best_color_count;
 | 
			
		||||
  byte best_color;
 | 
			
		||||
  const byte no_color=16;
 | 
			
		||||
 | 
			
		||||
  // Prerequisites
 | 
			
		||||
  if (Main_backups->Pages->Nb_layers < 3)
 | 
			
		||||
    return 1;
 | 
			
		||||
  if (Main_image_width != 160 || Main_image_height != 200)
 | 
			
		||||
    return 2;
 | 
			
		||||
 
 | 
			
		||||
  memset(used_colors,0,200*40*sizeof(word));
 | 
			
		||||
  memset(block_used_colors,0,25*40*sizeof(word));
 | 
			
		||||
  memset(line_used_colors,0,200*sizeof(word));
 | 
			
		||||
  memset(used_colors_count,0,200*40*sizeof(byte));
 | 
			
		||||
 | 
			
		||||
  // Initialize these as "unset"
 | 
			
		||||
  memset(line_color,no_color,200*sizeof(byte));
 | 
			
		||||
  memset(block_color,no_color,25*40*sizeof(byte));
 | 
			
		||||
 
 | 
			
		||||
  // Examine all 4-pixel blocks to fill used_colors[][]
 | 
			
		||||
  for (row=0;row<200;row++)
 | 
			
		||||
  {
 | 
			
		||||
    for (col=0;col<40;col++)
 | 
			
		||||
    {
 | 
			
		||||
      for (x=0;x<4;x++)
 | 
			
		||||
      {
 | 
			
		||||
        byte c=*((row)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2].Pixels);
 | 
			
		||||
        used_colors[row][col] |= 1<<c;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // Get "mandatory colors" from layer 1
 | 
			
		||||
  for (row=0;row<200;row++)
 | 
			
		||||
  {
 | 
			
		||||
    byte c=*((row)*Main_image_width+0+Main_backups->Pages->Image[0].Pixels);
 | 
			
		||||
    if (c<16)
 | 
			
		||||
    {
 | 
			
		||||
      line_color[row]=c;
 | 
			
		||||
      for (col=0;col<40;col++)
 | 
			
		||||
      {
 | 
			
		||||
        // Remove that color from the sets
 | 
			
		||||
        used_colors[row][col] &= ~(1<<c);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // Get "mandatory colors" from layer 2
 | 
			
		||||
  for (row=0;row<200;row+=8)
 | 
			
		||||
  {
 | 
			
		||||
    for (col=0;col<40;col++)
 | 
			
		||||
    {
 | 
			
		||||
      byte c=*((row)*Main_image_width+(col*4)+Main_backups->Pages->Image[1].Pixels);
 | 
			
		||||
      if (c<16)
 | 
			
		||||
      {
 | 
			
		||||
        block_color[row/8][col]=c;
 | 
			
		||||
        // Remove that color from the sets
 | 
			
		||||
        for (y=0; y<8;y++)
 | 
			
		||||
          used_colors[row+y][col] &= ~(1<<c);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // Now count the "remaining colors".
 | 
			
		||||
  for (row=0;row<200;row++)
 | 
			
		||||
  {
 | 
			
		||||
    memset(usage,0,16*sizeof(dword));
 | 
			
		||||
    for (col=0;col<40;col++)
 | 
			
		||||
    {
 | 
			
		||||
      used_colors_count[row][col]=Popcount_word(used_colors[row][col]);
 | 
			
		||||
      // Count which colors are used 3 times
 | 
			
		||||
      if (used_colors_count[row][col]==3)
 | 
			
		||||
      {
 | 
			
		||||
        for (i=0; i<16; i++)
 | 
			
		||||
          if (used_colors[row][col] & (1<<i))
 | 
			
		||||
            usage[i]+=1;
 | 
			
		||||
      }
 | 
			
		||||
      // Count which colors are used 4 times (important)
 | 
			
		||||
      else if (used_colors_count[row][col]==4)
 | 
			
		||||
      {
 | 
			
		||||
        for (i=0; i<16; i++)
 | 
			
		||||
          if (used_colors[row][col] & (1<<i))
 | 
			
		||||
            usage[i]+=2;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // 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.)
 | 
			
		||||
    if (line_color[row]==no_color)
 | 
			
		||||
    {
 | 
			
		||||
      best_color_count=0;
 | 
			
		||||
      best_color=no_color;
 | 
			
		||||
      for (i=0; i<16; i++)
 | 
			
		||||
      {
 | 
			
		||||
        if (usage[i]>best_color_count)
 | 
			
		||||
        {
 | 
			
		||||
          best_color_count=usage[i];
 | 
			
		||||
          best_color=i;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      line_color[row]=best_color;
 | 
			
		||||
 | 
			
		||||
      // Remove that color from the sets
 | 
			
		||||
      for (col=0;col<40;col++)
 | 
			
		||||
      {
 | 
			
		||||
        if (used_colors[row][col] & (1<<best_color))
 | 
			
		||||
        {
 | 
			
		||||
          used_colors[row][col] &= ~(1<<best_color);
 | 
			
		||||
          // Update count
 | 
			
		||||
          used_colors_count[row][col]--;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // Now check all 4*8 blocks
 | 
			
		||||
  for (col=0;col<40;col++)
 | 
			
		||||
  {
 | 
			
		||||
    for (row=0;row<200;row+=8)
 | 
			
		||||
    {
 | 
			
		||||
      // If there wasn't a preset color for this block
 | 
			
		||||
      if (block_color[row/8][col]==no_color)
 | 
			
		||||
      {
 | 
			
		||||
        word filter=0xFFFF;
 | 
			
		||||
        
 | 
			
		||||
        // Count used colors
 | 
			
		||||
        memset(usage,0,16*sizeof(dword));
 | 
			
		||||
        for (y=0;y<8;y++)
 | 
			
		||||
        {
 | 
			
		||||
          if (used_colors_count[row+y][col]>2)
 | 
			
		||||
          {
 | 
			
		||||
            filter &= used_colors[row+y][col];
 | 
			
		||||
            
 | 
			
		||||
            for (i=0; i<16; i++)
 | 
			
		||||
            {
 | 
			
		||||
              if (used_colors[row+y][col] & (1<<i))
 | 
			
		||||
                usage[i]+=1;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        if (filter != 0 && Popcount_word(filter) == 1)
 | 
			
		||||
        {
 | 
			
		||||
          // Only one color matched all needs: Use it.
 | 
			
		||||
          i=1;
 | 
			
		||||
          best_color=0;
 | 
			
		||||
          while (! (filter & i))
 | 
			
		||||
          {
 | 
			
		||||
            best_color++;
 | 
			
		||||
            i= i << 1;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          if (filter==0)
 | 
			
		||||
          {
 | 
			
		||||
            // No color in common from multiple lines with 3+ colors...
 | 
			
		||||
            // Keep them all for the usage sort.
 | 
			
		||||
            filter=0xFFFF;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // Pick the color which has been tagged most, and set it as
 | 
			
		||||
          // the block color
 | 
			
		||||
          best_color_count=0;
 | 
			
		||||
          best_color=no_color;
 | 
			
		||||
          for (i=0; i<16; i++)
 | 
			
		||||
          {
 | 
			
		||||
            if (filter & (1<<i))
 | 
			
		||||
            {
 | 
			
		||||
              if (usage[i]>best_color_count)
 | 
			
		||||
              {
 | 
			
		||||
                best_color_count=usage[i];
 | 
			
		||||
                best_color=i;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        block_color[row/8][col]=best_color;
 | 
			
		||||
 | 
			
		||||
        // Remove that color from the sets
 | 
			
		||||
        for (y=0;y<8;y++)
 | 
			
		||||
        {
 | 
			
		||||
          if (used_colors[row+y][col] & (1<<best_color))
 | 
			
		||||
          {
 | 
			
		||||
            used_colors[row+y][col] &= ~(1<<best_color);
 | 
			
		||||
            // Update count
 | 
			
		||||
            used_colors_count[row+y][col]--;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // At this point, the following arrays are filled:
 | 
			
		||||
  // - block_color[][]
 | 
			
		||||
  // - line_color[]
 | 
			
		||||
  // 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.
 | 
			
		||||
  // TODO: Draw problematic places on layer 4, with one of the available colors
 | 
			
		||||
  /*
 | 
			
		||||
  if (bitmap!=NULL)
 | 
			
		||||
  {
 | 
			
		||||
    for (row=0;row<200;row++)
 | 
			
		||||
    {
 | 
			
		||||
      for (col=0;col<40;col++)
 | 
			
		||||
      {
 | 
			
		||||
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  */
 | 
			
		||||
  
 | 
			
		||||
  // Output background
 | 
			
		||||
  if (background!=NULL)
 | 
			
		||||
  {
 | 
			
		||||
    for (row=0;row<200;row++)
 | 
			
		||||
    {
 | 
			
		||||
      if (line_color[row]==no_color)
 | 
			
		||||
        background[row]=0; // Unneeded line is black
 | 
			
		||||
      else
 | 
			
		||||
        background[row]=line_color[row];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Output Color RAM
 | 
			
		||||
  if (color_ram!=NULL)
 | 
			
		||||
  {
 | 
			
		||||
    for (col=0;col<40;col++)
 | 
			
		||||
    {
 | 
			
		||||
      for (row=0;row<25;row++)
 | 
			
		||||
      {
 | 
			
		||||
        if (block_color[row][col]==no_color)
 | 
			
		||||
          color_ram[row*40+col]=0; // Unneeded block is black
 | 
			
		||||
        else
 | 
			
		||||
          color_ram[row*40+col]=block_color[row][col];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  for(row=0; row<25; row++)
 | 
			
		||||
  {
 | 
			
		||||
    for(col=0; col<40; col++)
 | 
			
		||||
    {
 | 
			
		||||
      for(y=0; y<8; y++)
 | 
			
		||||
      {
 | 
			
		||||
        byte c1, c2;
 | 
			
		||||
        
 | 
			
		||||
        // 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 (c2=c1+1; c2<16 && !(used_colors[row*8+y][col] & (1<<c2)); c2++)
 | 
			
		||||
          ;
 | 
			
		||||
        if (c1>15)
 | 
			
		||||
          c1=16;
 | 
			
		||||
        if (c2>15)
 | 
			
		||||
          c2=16;
 | 
			
		||||
        
 | 
			
		||||
        // Output Screen RAMs
 | 
			
		||||
        if (screen_ram!=NULL)
 | 
			
		||||
          screen_ram[y*1024+row*40+col] = (c1&15) | ((c2&15)<<4);
 | 
			
		||||
          
 | 
			
		||||
        // Output bitmap
 | 
			
		||||
        if (bitmap!=NULL)
 | 
			
		||||
        {
 | 
			
		||||
          for(x=0; x<4; x++)
 | 
			
		||||
          {
 | 
			
		||||
            byte bits;
 | 
			
		||||
            byte c=*((row*8+y)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2].Pixels);
 | 
			
		||||
           
 | 
			
		||||
            if (c==line_color[row*8+y])
 | 
			
		||||
              // BG color
 | 
			
		||||
              bits=0;
 | 
			
		||||
            else if (c==block_color[row][col])
 | 
			
		||||
              // block color
 | 
			
		||||
              bits=3;
 | 
			
		||||
            else if (c==c1)
 | 
			
		||||
              // Color 1
 | 
			
		||||
              bits=2;
 | 
			
		||||
            else if (c==c2)
 | 
			
		||||
              // Color 2
 | 
			
		||||
              bits=1;
 | 
			
		||||
            else // problem
 | 
			
		||||
              bits=0;
 | 
			
		||||
            // clear target bits
 | 
			
		||||
            //bitmap[row*320+col*8+y] &= ~(3<<((3-x)*2));
 | 
			
		||||
            // set them
 | 
			
		||||
            bitmap[row*320+col*8+y] |= bits<<((3-x)*2);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  //memset(background,3,200);
 | 
			
		||||
  //memset(color_ram,5,8000);
 | 
			
		||||
  //memset(screen_ram,(9<<4) | 7,8192);
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
byte C64_FLI_enforcer(void)
 | 
			
		||||
{
 | 
			
		||||
  byte background[200];
 | 
			
		||||
  byte bitmap[8000];
 | 
			
		||||
  byte screen_ram[8192];
 | 
			
		||||
  byte color_ram[1000];
 | 
			
		||||
  
 | 
			
		||||
  int row, col, x, y;
 | 
			
		||||
  byte c[4];
 | 
			
		||||
  
 | 
			
		||||
  // Checks
 | 
			
		||||
  if (Main_image_width != 160)
 | 
			
		||||
    return 1;
 | 
			
		||||
  if (Main_image_height != 200)
 | 
			
		||||
    return 1;
 | 
			
		||||
  if (Main_backups->Pages->Nb_layers != 4)
 | 
			
		||||
    return 2;
 | 
			
		||||
  
 | 
			
		||||
  Backup_layers(3);
 | 
			
		||||
  
 | 
			
		||||
  memset(bitmap,0,8000);
 | 
			
		||||
  memset(background,0,200);
 | 
			
		||||
  memset(color_ram,0,1000);
 | 
			
		||||
  memset(screen_ram,0,8192);
 | 
			
		||||
  C64_FLI(bitmap, screen_ram, color_ram, background);
 | 
			
		||||
 | 
			
		||||
  for(row=0; row<25; row++)
 | 
			
		||||
  {
 | 
			
		||||
    for(col=0; col<40; col++)
 | 
			
		||||
    {
 | 
			
		||||
      c[3]=color_ram[row*40+col]&15;
 | 
			
		||||
      for(y=0; y<8; y++)
 | 
			
		||||
      {
 | 
			
		||||
        int pixel=bitmap[row*320+col*8+y];
 | 
			
		||||
        
 | 
			
		||||
        c[0]=background[row*8+y]&15;
 | 
			
		||||
        c[1]=screen_ram[y*1024+row*40+col]>>4;
 | 
			
		||||
        c[2]=screen_ram[y*1024+row*40+col]&15;
 | 
			
		||||
        for(x=0; x<4; x++)
 | 
			
		||||
        {
 | 
			
		||||
          int color=c[(pixel&3)];
 | 
			
		||||
          pixel>>=2;
 | 
			
		||||
          Pixel_in_layer(col*4+(3-x),row*8+y,3,color);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  End_of_modification();
 | 
			
		||||
  
 | 
			
		||||
  // Visible feedback:
 | 
			
		||||
  
 | 
			
		||||
  // If the "check" layer was visible, manually update the whole thing
 | 
			
		||||
  if (Main_layers_visible & (1<<3))
 | 
			
		||||
  {
 | 
			
		||||
    Hide_cursor();
 | 
			
		||||
    Redraw_layered_image();
 | 
			
		||||
    Display_all_screen();
 | 
			
		||||
    Display_layerbar();
 | 
			
		||||
    Display_cursor();
 | 
			
		||||
  }  
 | 
			
		||||
  else
 | 
			
		||||
  // Otherwise, simply toggle the layer visiblity
 | 
			
		||||
    Layer_activate(3,RIGHT_SIDE);
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
/* vim:expandtab:ts=2 sw=2:
 | 
			
		||||
*/
 | 
			
		||||
/*  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/>
 | 
			
		||||
*/
 | 
			
		||||
#include <SDL.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include "struct.h"
 | 
			
		||||
#include "global.h"
 | 
			
		||||
#include "errors.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "palette.h"
 | 
			
		||||
#include "pages.h"
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
#include "layers.h"
 | 
			
		||||
 | 
			
		||||
void Pixel_in_layer(word x,word y, byte layer, byte 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)
 | 
			
		||||
{
 | 
			
		||||
  word used_colors[200][40];
 | 
			
		||||
  word block_used_colors[25][40];
 | 
			
		||||
  word line_used_colors[200];
 | 
			
		||||
  byte used_colors_count[200][40];
 | 
			
		||||
  dword usage[16];
 | 
			
		||||
  word x,y,row,col;
 | 
			
		||||
  int i;
 | 
			
		||||
  byte line_color[200];
 | 
			
		||||
  byte block_color[25][40];
 | 
			
		||||
  word best_color_count;
 | 
			
		||||
  byte best_color;
 | 
			
		||||
  const byte no_color=16;
 | 
			
		||||
 | 
			
		||||
  // Prerequisites
 | 
			
		||||
  if (Main_backups->Pages->Nb_layers < 3)
 | 
			
		||||
    return 1;
 | 
			
		||||
  if (Main_image_width != 160 || Main_image_height != 200)
 | 
			
		||||
    return 2;
 | 
			
		||||
 
 | 
			
		||||
  memset(used_colors,0,200*40*sizeof(word));
 | 
			
		||||
  memset(block_used_colors,0,25*40*sizeof(word));
 | 
			
		||||
  memset(line_used_colors,0,200*sizeof(word));
 | 
			
		||||
  memset(used_colors_count,0,200*40*sizeof(byte));
 | 
			
		||||
 | 
			
		||||
  // Initialize these as "unset"
 | 
			
		||||
  memset(line_color,no_color,200*sizeof(byte));
 | 
			
		||||
  memset(block_color,no_color,25*40*sizeof(byte));
 | 
			
		||||
 
 | 
			
		||||
  // Examine all 4-pixel blocks to fill used_colors[][]
 | 
			
		||||
  for (row=0;row<200;row++)
 | 
			
		||||
  {
 | 
			
		||||
    for (col=0;col<40;col++)
 | 
			
		||||
    {
 | 
			
		||||
      for (x=0;x<4;x++)
 | 
			
		||||
      {
 | 
			
		||||
        byte c=*((row)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2].Pixels);
 | 
			
		||||
        used_colors[row][col] |= 1<<c;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // Get "mandatory colors" from layer 1
 | 
			
		||||
  for (row=0;row<200;row++)
 | 
			
		||||
  {
 | 
			
		||||
    byte c=*((row)*Main_image_width+0+Main_backups->Pages->Image[0].Pixels);
 | 
			
		||||
    if (c<16)
 | 
			
		||||
    {
 | 
			
		||||
      line_color[row]=c;
 | 
			
		||||
      for (col=0;col<40;col++)
 | 
			
		||||
      {
 | 
			
		||||
        // Remove that color from the sets
 | 
			
		||||
        used_colors[row][col] &= ~(1<<c);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // Get "mandatory colors" from layer 2
 | 
			
		||||
  for (row=0;row<200;row+=8)
 | 
			
		||||
  {
 | 
			
		||||
    for (col=0;col<40;col++)
 | 
			
		||||
    {
 | 
			
		||||
      byte c=*((row)*Main_image_width+(col*4)+Main_backups->Pages->Image[1].Pixels);
 | 
			
		||||
      if (c<16)
 | 
			
		||||
      {
 | 
			
		||||
        block_color[row/8][col]=c;
 | 
			
		||||
        // Remove that color from the sets
 | 
			
		||||
        for (y=0; y<8;y++)
 | 
			
		||||
          used_colors[row+y][col] &= ~(1<<c);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // Now count the "remaining colors".
 | 
			
		||||
  for (row=0;row<200;row++)
 | 
			
		||||
  {
 | 
			
		||||
    memset(usage,0,16*sizeof(dword));
 | 
			
		||||
    for (col=0;col<40;col++)
 | 
			
		||||
    {
 | 
			
		||||
      used_colors_count[row][col]=Popcount_word(used_colors[row][col]);
 | 
			
		||||
      // Count which colors are used 3 times
 | 
			
		||||
      if (used_colors_count[row][col]==3)
 | 
			
		||||
      {
 | 
			
		||||
        for (i=0; i<16; i++)
 | 
			
		||||
          if (used_colors[row][col] & (1<<i))
 | 
			
		||||
            usage[i]+=1;
 | 
			
		||||
      }
 | 
			
		||||
      // Count which colors are used 4 times (important)
 | 
			
		||||
      else if (used_colors_count[row][col]==4)
 | 
			
		||||
      {
 | 
			
		||||
        for (i=0; i<16; i++)
 | 
			
		||||
          if (used_colors[row][col] & (1<<i))
 | 
			
		||||
            usage[i]+=2;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // 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.)
 | 
			
		||||
    if (line_color[row]==no_color)
 | 
			
		||||
    {
 | 
			
		||||
      best_color_count=0;
 | 
			
		||||
      best_color=no_color;
 | 
			
		||||
      for (i=0; i<16; i++)
 | 
			
		||||
      {
 | 
			
		||||
        if (usage[i]>best_color_count)
 | 
			
		||||
        {
 | 
			
		||||
          best_color_count=usage[i];
 | 
			
		||||
          best_color=i;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      line_color[row]=best_color;
 | 
			
		||||
 | 
			
		||||
      // Remove that color from the sets
 | 
			
		||||
      for (col=0;col<40;col++)
 | 
			
		||||
      {
 | 
			
		||||
        if (used_colors[row][col] & (1<<best_color))
 | 
			
		||||
        {
 | 
			
		||||
          used_colors[row][col] &= ~(1<<best_color);
 | 
			
		||||
          // Update count
 | 
			
		||||
          used_colors_count[row][col]--;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // Now check all 4*8 blocks
 | 
			
		||||
  for (col=0;col<40;col++)
 | 
			
		||||
  {
 | 
			
		||||
    for (row=0;row<200;row+=8)
 | 
			
		||||
    {
 | 
			
		||||
      // If there wasn't a preset color for this block
 | 
			
		||||
      if (block_color[row/8][col]==no_color)
 | 
			
		||||
      {
 | 
			
		||||
        word filter=0xFFFF;
 | 
			
		||||
        
 | 
			
		||||
        // Count used colors
 | 
			
		||||
        memset(usage,0,16*sizeof(dword));
 | 
			
		||||
        for (y=0;y<8;y++)
 | 
			
		||||
        {
 | 
			
		||||
          if (used_colors_count[row+y][col]>2)
 | 
			
		||||
          {
 | 
			
		||||
            filter &= used_colors[row+y][col];
 | 
			
		||||
            
 | 
			
		||||
            for (i=0; i<16; i++)
 | 
			
		||||
            {
 | 
			
		||||
              if (used_colors[row+y][col] & (1<<i))
 | 
			
		||||
                usage[i]+=1;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        if (filter != 0 && Popcount_word(filter) == 1)
 | 
			
		||||
        {
 | 
			
		||||
          // Only one color matched all needs: Use it.
 | 
			
		||||
          i=1;
 | 
			
		||||
          best_color=0;
 | 
			
		||||
          while (! (filter & i))
 | 
			
		||||
          {
 | 
			
		||||
            best_color++;
 | 
			
		||||
            i= i << 1;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          if (filter==0)
 | 
			
		||||
          {
 | 
			
		||||
            // No color in common from multiple lines with 3+ colors...
 | 
			
		||||
            // Keep them all for the usage sort.
 | 
			
		||||
            filter=0xFFFF;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // Pick the color which has been tagged most, and set it as
 | 
			
		||||
          // the block color
 | 
			
		||||
          best_color_count=0;
 | 
			
		||||
          best_color=no_color;
 | 
			
		||||
          for (i=0; i<16; i++)
 | 
			
		||||
          {
 | 
			
		||||
            if (filter & (1<<i))
 | 
			
		||||
            {
 | 
			
		||||
              if (usage[i]>best_color_count)
 | 
			
		||||
              {
 | 
			
		||||
                best_color_count=usage[i];
 | 
			
		||||
                best_color=i;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        block_color[row/8][col]=best_color;
 | 
			
		||||
 | 
			
		||||
        // Remove that color from the sets
 | 
			
		||||
        for (y=0;y<8;y++)
 | 
			
		||||
        {
 | 
			
		||||
          if (used_colors[row+y][col] & (1<<best_color))
 | 
			
		||||
          {
 | 
			
		||||
            used_colors[row+y][col] &= ~(1<<best_color);
 | 
			
		||||
            // Update count
 | 
			
		||||
            used_colors_count[row+y][col]--;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // At this point, the following arrays are filled:
 | 
			
		||||
  // - block_color[][]
 | 
			
		||||
  // - line_color[]
 | 
			
		||||
  // 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.
 | 
			
		||||
  // TODO: Draw problematic places on layer 4, with one of the available colors
 | 
			
		||||
  /*
 | 
			
		||||
  if (bitmap!=NULL)
 | 
			
		||||
  {
 | 
			
		||||
    for (row=0;row<200;row++)
 | 
			
		||||
    {
 | 
			
		||||
      for (col=0;col<40;col++)
 | 
			
		||||
      {
 | 
			
		||||
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  */
 | 
			
		||||
  
 | 
			
		||||
  // Output background
 | 
			
		||||
  if (background!=NULL)
 | 
			
		||||
  {
 | 
			
		||||
    for (row=0;row<200;row++)
 | 
			
		||||
    {
 | 
			
		||||
      if (line_color[row]==no_color)
 | 
			
		||||
        background[row]=0; // Unneeded line is black
 | 
			
		||||
      else
 | 
			
		||||
        background[row]=line_color[row];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Output Color RAM
 | 
			
		||||
  if (color_ram!=NULL)
 | 
			
		||||
  {
 | 
			
		||||
    for (col=0;col<40;col++)
 | 
			
		||||
    {
 | 
			
		||||
      for (row=0;row<25;row++)
 | 
			
		||||
      {
 | 
			
		||||
        if (block_color[row][col]==no_color)
 | 
			
		||||
          color_ram[row*40+col]=0; // Unneeded block is black
 | 
			
		||||
        else
 | 
			
		||||
          color_ram[row*40+col]=block_color[row][col];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  for(row=0; row<25; row++)
 | 
			
		||||
  {
 | 
			
		||||
    for(col=0; col<40; col++)
 | 
			
		||||
    {
 | 
			
		||||
      for(y=0; y<8; y++)
 | 
			
		||||
      {
 | 
			
		||||
        byte c1, c2;
 | 
			
		||||
        
 | 
			
		||||
        // 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 (c2=c1+1; c2<16 && !(used_colors[row*8+y][col] & (1<<c2)); c2++)
 | 
			
		||||
          ;
 | 
			
		||||
        if (c1>15)
 | 
			
		||||
          c1=16;
 | 
			
		||||
        if (c2>15)
 | 
			
		||||
          c2=16;
 | 
			
		||||
        
 | 
			
		||||
        // Output Screen RAMs
 | 
			
		||||
        if (screen_ram!=NULL)
 | 
			
		||||
          screen_ram[y*1024+row*40+col] = (c1&15) | ((c2&15)<<4);
 | 
			
		||||
          
 | 
			
		||||
        // Output bitmap
 | 
			
		||||
        if (bitmap!=NULL)
 | 
			
		||||
        {
 | 
			
		||||
          for(x=0; x<4; x++)
 | 
			
		||||
          {
 | 
			
		||||
            byte bits;
 | 
			
		||||
            byte c=*((row*8+y)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2].Pixels);
 | 
			
		||||
           
 | 
			
		||||
            if (c==line_color[row*8+y])
 | 
			
		||||
              // BG color
 | 
			
		||||
              bits=0;
 | 
			
		||||
            else if (c==block_color[row][col])
 | 
			
		||||
              // block color
 | 
			
		||||
              bits=3;
 | 
			
		||||
            else if (c==c1)
 | 
			
		||||
              // Color 1
 | 
			
		||||
              bits=2;
 | 
			
		||||
            else if (c==c2)
 | 
			
		||||
              // Color 2
 | 
			
		||||
              bits=1;
 | 
			
		||||
            else // problem
 | 
			
		||||
              bits=0;
 | 
			
		||||
            // clear target bits
 | 
			
		||||
            //bitmap[row*320+col*8+y] &= ~(3<<((3-x)*2));
 | 
			
		||||
            // set them
 | 
			
		||||
            bitmap[row*320+col*8+y] |= bits<<((3-x)*2);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  //memset(background,3,200);
 | 
			
		||||
  //memset(color_ram,5,8000);
 | 
			
		||||
  //memset(screen_ram,(9<<4) | 7,8192);
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
byte C64_FLI_enforcer(void)
 | 
			
		||||
{
 | 
			
		||||
  byte background[200];
 | 
			
		||||
  byte bitmap[8000];
 | 
			
		||||
  byte screen_ram[8192];
 | 
			
		||||
  byte color_ram[1000];
 | 
			
		||||
  
 | 
			
		||||
  int row, col, x, y;
 | 
			
		||||
  byte c[4];
 | 
			
		||||
  
 | 
			
		||||
  // Checks
 | 
			
		||||
  if (Main_image_width != 160)
 | 
			
		||||
    return 1;
 | 
			
		||||
  if (Main_image_height != 200)
 | 
			
		||||
    return 1;
 | 
			
		||||
  if (Main_backups->Pages->Nb_layers != 4)
 | 
			
		||||
    return 2;
 | 
			
		||||
  
 | 
			
		||||
  Backup_layers(3);
 | 
			
		||||
  
 | 
			
		||||
  memset(bitmap,0,8000);
 | 
			
		||||
  memset(background,0,200);
 | 
			
		||||
  memset(color_ram,0,1000);
 | 
			
		||||
  memset(screen_ram,0,8192);
 | 
			
		||||
  C64_FLI(bitmap, screen_ram, color_ram, background);
 | 
			
		||||
 | 
			
		||||
  for(row=0; row<25; row++)
 | 
			
		||||
  {
 | 
			
		||||
    for(col=0; col<40; col++)
 | 
			
		||||
    {
 | 
			
		||||
      c[3]=color_ram[row*40+col]&15;
 | 
			
		||||
      for(y=0; y<8; y++)
 | 
			
		||||
      {
 | 
			
		||||
        int pixel=bitmap[row*320+col*8+y];
 | 
			
		||||
        
 | 
			
		||||
        c[0]=background[row*8+y]&15;
 | 
			
		||||
        c[1]=screen_ram[y*1024+row*40+col]>>4;
 | 
			
		||||
        c[2]=screen_ram[y*1024+row*40+col]&15;
 | 
			
		||||
        for(x=0; x<4; x++)
 | 
			
		||||
        {
 | 
			
		||||
          int color=c[(pixel&3)];
 | 
			
		||||
          pixel>>=2;
 | 
			
		||||
          Pixel_in_layer(col*4+(3-x),row*8+y,3,color);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  End_of_modification();
 | 
			
		||||
  
 | 
			
		||||
  // Visible feedback:
 | 
			
		||||
  
 | 
			
		||||
  // If the "check" layer was visible, manually update the whole thing
 | 
			
		||||
  if (Main_layers_visible & (1<<3))
 | 
			
		||||
  {
 | 
			
		||||
    Hide_cursor();
 | 
			
		||||
    Redraw_layered_image();
 | 
			
		||||
    Display_all_screen();
 | 
			
		||||
    Display_layerbar();
 | 
			
		||||
    Display_cursor();
 | 
			
		||||
  }  
 | 
			
		||||
  else
 | 
			
		||||
  // Otherwise, simply toggle the layer visiblity
 | 
			
		||||
    Layer_activate(3,RIGHT_SIDE);
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										48
									
								
								src/oldies.h
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								src/oldies.h
									
									
									
									
									
								
							@ -1,24 +1,24 @@
 | 
			
		||||
/* vim:expandtab:ts=2 sw=2:
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2008 Adrien Destugues
 | 
			
		||||
 | 
			
		||||
    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/>
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background);
 | 
			
		||||
 | 
			
		||||
byte C64_FLI_enforcer(void);
 | 
			
		||||
 | 
			
		||||
/* vim:expandtab:ts=2 sw=2:
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2008 Adrien Destugues
 | 
			
		||||
 | 
			
		||||
    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/>
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background);
 | 
			
		||||
 | 
			
		||||
byte C64_FLI_enforcer(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										852
									
								
								src/tiles.c
									
									
									
									
									
								
							
							
						
						
									
										852
									
								
								src/tiles.c
									
									
									
									
									
								
							@ -1,426 +1,426 @@
 | 
			
		||||
/* vim:expandtab:ts=2 sw=2:
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Yves Rizoud
 | 
			
		||||
    Copyright 2010-2011 Adrien Destugues
 | 
			
		||||
 | 
			
		||||
    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/>
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "struct.h"
 | 
			
		||||
#include "global.h"
 | 
			
		||||
#include "graph.h"
 | 
			
		||||
#include "sdlscreen.h"
 | 
			
		||||
#include "engine.h"
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
#include "input.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "tiles.h"
 | 
			
		||||
 | 
			
		||||
// 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_AT(x,y) (y)*Main_tilemap_width+(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)
 | 
			
		||||
 | 
			
		||||
enum TILE_FLIPPED
 | 
			
		||||
{
 | 
			
		||||
  TILE_FLIPPED_NONE = 0,
 | 
			
		||||
  TILE_FLIPPED_X = 1,
 | 
			
		||||
  TILE_FLIPPED_Y = 2,
 | 
			
		||||
  TILE_FLIPPED_XY = 3, // needs be TILE_FLIPPED_X|TILE_FLIPPED_Y
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// globals
 | 
			
		||||
 | 
			
		||||
/// Tilemap for the main screen
 | 
			
		||||
T_Tile * Main_tilemap;
 | 
			
		||||
/// Number of tiles (horizontally) for the main page's tilemap
 | 
			
		||||
short Main_tilemap_width;
 | 
			
		||||
/// Number of tiles (vertically) for the main page's tilemap
 | 
			
		||||
short Main_tilemap_height;
 | 
			
		||||
 | 
			
		||||
/// Tilemap for the spare
 | 
			
		||||
T_Tile * Spare_tilemap;
 | 
			
		||||
/// Number of tiles (horizontally) for the spare page's tilemap
 | 
			
		||||
short Spare_tilemap_width;
 | 
			
		||||
/// Number of tiles (vertically) for the spare page's tilemap
 | 
			
		||||
short Spare_tilemap_height;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Draw a pixel while Tilemap mode is active : This will paint on all
 | 
			
		||||
/// similar tiles of the layer, visible on the screen or not.
 | 
			
		||||
void Tilemap_draw(word x, word y, byte color)
 | 
			
		||||
{
 | 
			
		||||
  int tile, first_tile;
 | 
			
		||||
  int rel_x, rel_y;
 | 
			
		||||
  
 | 
			
		||||
  if (x < Snap_offset_X
 | 
			
		||||
   || y < Snap_offset_Y
 | 
			
		||||
   || x >= Snap_offset_X + Main_tilemap_width*Snap_width
 | 
			
		||||
   || y >= Snap_offset_Y + Main_tilemap_height*Snap_height)
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  tile = first_tile = TILE_FOR_COORDS(x,y);
 | 
			
		||||
  
 | 
			
		||||
  rel_x = (x - Snap_offset_X + Snap_width) % Snap_width;
 | 
			
		||||
  rel_y = (y - Snap_offset_Y + Snap_height) % Snap_height;
 | 
			
		||||
  do
 | 
			
		||||
  {
 | 
			
		||||
    int xx,yy;
 | 
			
		||||
    switch(Main_tilemap[tile].Flipped ^ Main_tilemap[first_tile].Flipped)
 | 
			
		||||
    {
 | 
			
		||||
      case 0: // no
 | 
			
		||||
      default:
 | 
			
		||||
        xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + rel_x;
 | 
			
		||||
        yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + rel_y;
 | 
			
		||||
        break;
 | 
			
		||||
      case 1: // horizontal
 | 
			
		||||
        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;
 | 
			
		||||
        break;
 | 
			
		||||
      case 2: // vertical
 | 
			
		||||
        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;
 | 
			
		||||
        break;
 | 
			
		||||
      case 3: // both
 | 
			
		||||
        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;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    if (yy>=Limit_top&&yy<=Limit_bottom&&xx>=Limit_left&&xx<=Limit_right)
 | 
			
		||||
      Pixel_in_current_screen_with_preview(xx,yy,color);
 | 
			
		||||
    else
 | 
			
		||||
      Pixel_in_current_screen(xx,yy,color);
 | 
			
		||||
      
 | 
			
		||||
    tile = Main_tilemap[tile].Next;
 | 
			
		||||
  } while (tile != first_tile);
 | 
			
		||||
 | 
			
		||||
  Update_rect(0,0,0,0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
int Tile_is_same(int t1, int t2)
 | 
			
		||||
{
 | 
			
		||||
  byte *bmp1,*bmp2;
 | 
			
		||||
  int y;
 | 
			
		||||
  
 | 
			
		||||
  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));
 | 
			
		||||
  
 | 
			
		||||
  for (y=0; y < Snap_height; y++)
 | 
			
		||||
  {
 | 
			
		||||
    if (memcmp(bmp1+y*Main_image_width, bmp2+y*Main_image_width, Snap_width))
 | 
			
		||||
      return 0;
 | 
			
		||||
  }
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
int Tile_is_same_flipped_x(int t1, int t2)
 | 
			
		||||
{
 | 
			
		||||
  byte *bmp1,*bmp2;
 | 
			
		||||
  int y, x;
 | 
			
		||||
  
 | 
			
		||||
  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);
 | 
			
		||||
  
 | 
			
		||||
  for (y=0; y < Snap_height; y++)
 | 
			
		||||
  {
 | 
			
		||||
    for (x=0; x < Snap_width; x++)
 | 
			
		||||
      if (*(bmp1+y*Main_image_width+x) != *(bmp2+y*Main_image_width-x))
 | 
			
		||||
        return 0;
 | 
			
		||||
  }
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
int Tile_is_same_flipped_y(int t1, int t2)
 | 
			
		||||
{
 | 
			
		||||
  byte *bmp1,*bmp2;
 | 
			
		||||
  int y;
 | 
			
		||||
  
 | 
			
		||||
  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));
 | 
			
		||||
  
 | 
			
		||||
  for (y=0; y < Snap_height; y++)
 | 
			
		||||
  {
 | 
			
		||||
    if (memcmp(bmp1+y*Main_image_width, bmp2-y*Main_image_width, Snap_width))
 | 
			
		||||
      return 0;
 | 
			
		||||
  }
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
int Tile_is_same_flipped_xy(int t1, int t2)
 | 
			
		||||
{
 | 
			
		||||
  byte *bmp1,*bmp2;
 | 
			
		||||
  int y, x;
 | 
			
		||||
  
 | 
			
		||||
  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);
 | 
			
		||||
  
 | 
			
		||||
  for (y=0; y < Snap_height; y++)
 | 
			
		||||
  {
 | 
			
		||||
    for (x=0; x < Snap_width; x++)
 | 
			
		||||
      if (*(bmp1+y*Main_image_width+x) != *(bmp2-y*Main_image_width-x))
 | 
			
		||||
        return 0;
 | 
			
		||||
  }
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Create or update a tilemap based on current screen (layer)'s pixels.
 | 
			
		||||
void Tilemap_update(void)
 | 
			
		||||
{
 | 
			
		||||
  int width;
 | 
			
		||||
  int height;
 | 
			
		||||
  int tile;
 | 
			
		||||
  int count=1;
 | 
			
		||||
  T_Tile * tile_ptr;
 | 
			
		||||
  
 | 
			
		||||
  int wait_window=0;
 | 
			
		||||
  byte old_cursor=0;
 | 
			
		||||
 | 
			
		||||
  if (!Main_tilemap_mode)
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  width=(Main_image_width-Snap_offset_X)/Snap_width;
 | 
			
		||||
  height=(Main_image_height-Snap_offset_Y)/Snap_height;
 | 
			
		||||
  
 | 
			
		||||
  if (width<1 || height<1 || width*height>1000000l
 | 
			
		||||
   || (tile_ptr=(T_Tile *)malloc(width*height*sizeof(T_Tile))) == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    // Cannot enable tilemap because either the image is too small
 | 
			
		||||
    // for the grid settings (and I don't want to implement partial tiles)
 | 
			
		||||
    // Or the number of tiles seems unreasonable (one million) : This can
 | 
			
		||||
    // happen if you set grid 1x1 for example.
 | 
			
		||||
  
 | 
			
		||||
    Disable_main_tilemap();
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  if (Main_tilemap)
 | 
			
		||||
  {
 | 
			
		||||
    // Recycle existing tilemap
 | 
			
		||||
    free(Main_tilemap);
 | 
			
		||||
    Main_tilemap=NULL;
 | 
			
		||||
  }
 | 
			
		||||
  Main_tilemap=tile_ptr;
 | 
			
		||||
  
 | 
			
		||||
  Main_tilemap_width=width;
 | 
			
		||||
  Main_tilemap_height=height;
 | 
			
		||||
 | 
			
		||||
  if (width*height > 1000 || Config.Tilemap_show_count)
 | 
			
		||||
  {
 | 
			
		||||
    wait_window=1;
 | 
			
		||||
    old_cursor=Cursor_shape;
 | 
			
		||||
    Open_window(180,36,"Creating tileset");
 | 
			
		||||
    Print_in_window(26, 20, "Please wait...",MC_Black,MC_Light);
 | 
			
		||||
    Cursor_shape=CURSOR_SHAPE_HOURGLASS;
 | 
			
		||||
    Update_window_area(0,0,Window_width, Window_height);
 | 
			
		||||
    Display_cursor();
 | 
			
		||||
    Get_input(0);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Initialize array with all tiles unique by default
 | 
			
		||||
  for (tile=0; tile<width*height; tile++)
 | 
			
		||||
  {
 | 
			
		||||
    Main_tilemap[tile].Previous = tile;
 | 
			
		||||
    Main_tilemap[tile].Next = tile;
 | 
			
		||||
    Main_tilemap[tile].Flipped = 0;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Now find similar tiles and link them in circular linked list
 | 
			
		||||
  //It will be used to modify all tiles whenever you draw on one.
 | 
			
		||||
  for (tile=1; tile<width*height; tile++)
 | 
			
		||||
  {
 | 
			
		||||
    int ref_tile;
 | 
			
		||||
    
 | 
			
		||||
    // Try normal comparison
 | 
			
		||||
    
 | 
			
		||||
    for (ref_tile=0; ref_tile<tile; ref_tile++)
 | 
			
		||||
    {
 | 
			
		||||
      if (Main_tilemap[ref_tile].Previous<=ref_tile && Tile_is_same(ref_tile, tile))
 | 
			
		||||
      {
 | 
			
		||||
        break; // stop loop on ref_tile
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (ref_tile<tile)
 | 
			
		||||
    {
 | 
			
		||||
      // New occurence of a known tile
 | 
			
		||||
      // Insert at the end. classic doubly-linked-list.
 | 
			
		||||
      int last_tile=Main_tilemap[ref_tile].Previous;
 | 
			
		||||
      Main_tilemap[tile].Previous=last_tile;
 | 
			
		||||
      Main_tilemap[tile].Next=ref_tile;
 | 
			
		||||
      Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped;
 | 
			
		||||
      Main_tilemap[ref_tile].Previous=tile;
 | 
			
		||||
      Main_tilemap[last_tile].Next=tile;
 | 
			
		||||
      continue; // next tile
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Try flipped-y comparison
 | 
			
		||||
    if (Config.Tilemap_allow_flipped_y)
 | 
			
		||||
    {
 | 
			
		||||
      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))
 | 
			
		||||
        {
 | 
			
		||||
          break; // stop loop on ref_tile
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (ref_tile<tile)
 | 
			
		||||
      {
 | 
			
		||||
        // New occurence of a known tile
 | 
			
		||||
        // Insert at the end. classic doubly-linked-list.
 | 
			
		||||
        int last_tile=Main_tilemap[ref_tile].Previous;
 | 
			
		||||
        Main_tilemap[tile].Previous=last_tile;
 | 
			
		||||
        Main_tilemap[tile].Next=ref_tile;
 | 
			
		||||
        Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped ^ TILE_FLIPPED_Y;
 | 
			
		||||
        Main_tilemap[ref_tile].Previous=tile;
 | 
			
		||||
        Main_tilemap[last_tile].Next=tile;
 | 
			
		||||
        continue; // next tile
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Try flipped-x comparison
 | 
			
		||||
    if (Config.Tilemap_allow_flipped_x)
 | 
			
		||||
    {
 | 
			
		||||
      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))
 | 
			
		||||
        {
 | 
			
		||||
          break; // stop loop on ref_tile
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (ref_tile<tile)
 | 
			
		||||
      {
 | 
			
		||||
        // New occurence of a known tile
 | 
			
		||||
        // Insert at the end. classic doubly-linked-list.
 | 
			
		||||
        int last_tile=Main_tilemap[ref_tile].Previous;
 | 
			
		||||
        Main_tilemap[tile].Previous=last_tile;
 | 
			
		||||
        Main_tilemap[tile].Next=ref_tile;
 | 
			
		||||
        Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped ^ TILE_FLIPPED_X;
 | 
			
		||||
        Main_tilemap[ref_tile].Previous=tile;
 | 
			
		||||
        Main_tilemap[last_tile].Next=tile;
 | 
			
		||||
        continue; // next tile
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Try flipped-xy comparison
 | 
			
		||||
    if (Config.Tilemap_allow_flipped_x && Config.Tilemap_allow_flipped_y)
 | 
			
		||||
    {
 | 
			
		||||
      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))
 | 
			
		||||
        {
 | 
			
		||||
          break; // stop loop on ref_tile
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (ref_tile<tile)
 | 
			
		||||
      {
 | 
			
		||||
        // New occurence of a known tile
 | 
			
		||||
        // Insert at the end. classic doubly-linked-list.
 | 
			
		||||
        int last_tile=Main_tilemap[ref_tile].Previous;
 | 
			
		||||
        Main_tilemap[tile].Previous=last_tile;
 | 
			
		||||
        Main_tilemap[tile].Next=ref_tile;
 | 
			
		||||
        Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped ^ TILE_FLIPPED_XY;
 | 
			
		||||
        Main_tilemap[ref_tile].Previous=tile;
 | 
			
		||||
        Main_tilemap[last_tile].Next=tile;
 | 
			
		||||
        continue; // next tile
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // This tile is really unique.
 | 
			
		||||
    // Nothing to do at this time: the initialization
 | 
			
		||||
    // has already set the right data for Main_tilemap[tile].
 | 
			
		||||
    count++;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  if (wait_window)
 | 
			
		||||
  {
 | 
			
		||||
    char   str[8];
 | 
			
		||||
    Uint32 end;
 | 
			
		||||
    
 | 
			
		||||
    if (Config.Tilemap_show_count)
 | 
			
		||||
    {
 | 
			
		||||
      Num2str(count,str,7);
 | 
			
		||||
      Hide_cursor();
 | 
			
		||||
      Print_in_window(6, 20, "Unique tiles: ",MC_Black,MC_Light);
 | 
			
		||||
      Print_in_window(6+8*14,20,str,MC_Black,MC_Light);
 | 
			
		||||
      Display_cursor();
 | 
			
		||||
      
 | 
			
		||||
      // Wait a moment to display count
 | 
			
		||||
      end = SDL_GetTicks()+750;
 | 
			
		||||
      do
 | 
			
		||||
      {
 | 
			
		||||
        Get_input(20);
 | 
			
		||||
      } while (SDL_GetTicks()<end);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Close_window();
 | 
			
		||||
    Cursor_shape=old_cursor;
 | 
			
		||||
    Display_cursor();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// This exchanges the tilemap settings of the main and spare, it should
 | 
			
		||||
/// be called when swapping pages.
 | 
			
		||||
void Swap_tilemap(void)
 | 
			
		||||
{
 | 
			
		||||
  SWAP_BYTES(Main_tilemap_mode, Spare_tilemap_mode)
 | 
			
		||||
  {
 | 
			
		||||
    T_Tile * a;
 | 
			
		||||
    a=Main_tilemap;
 | 
			
		||||
    Main_tilemap=Spare_tilemap;
 | 
			
		||||
    Spare_tilemap=a;
 | 
			
		||||
  }
 | 
			
		||||
  SWAP_SHORTS(Main_tilemap_width, Spare_tilemap_width)
 | 
			
		||||
  SWAP_SHORTS(Main_tilemap_height, Spare_tilemap_height)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Clears all tilemap data and settings for the main page.
 | 
			
		||||
/// Safe to call again.
 | 
			
		||||
void Disable_main_tilemap(void)
 | 
			
		||||
{
 | 
			
		||||
  if (Main_tilemap)
 | 
			
		||||
  {
 | 
			
		||||
    // Recycle existing tilemap
 | 
			
		||||
    free(Main_tilemap);
 | 
			
		||||
    Main_tilemap=NULL;
 | 
			
		||||
  }
 | 
			
		||||
  Main_tilemap_width=0;
 | 
			
		||||
  Main_tilemap_height=0;
 | 
			
		||||
  Main_tilemap_mode=0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Clears all tilemap data and settings for the spare.
 | 
			
		||||
/// Safe to call again.
 | 
			
		||||
void Disable_spare_tilemap(void)
 | 
			
		||||
{
 | 
			
		||||
    if (Spare_tilemap)
 | 
			
		||||
  {
 | 
			
		||||
    // Recycle existing tilemap
 | 
			
		||||
    free(Spare_tilemap);
 | 
			
		||||
    Spare_tilemap=NULL;
 | 
			
		||||
  }
 | 
			
		||||
  Spare_tilemap_width=0;
 | 
			
		||||
  Spare_tilemap_height=0;
 | 
			
		||||
  Spare_tilemap_mode=0;
 | 
			
		||||
}
 | 
			
		||||
/* vim:expandtab:ts=2 sw=2:
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Yves Rizoud
 | 
			
		||||
    Copyright 2010-2011 Adrien Destugues
 | 
			
		||||
 | 
			
		||||
    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/>
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "struct.h"
 | 
			
		||||
#include "global.h"
 | 
			
		||||
#include "graph.h"
 | 
			
		||||
#include "sdlscreen.h"
 | 
			
		||||
#include "engine.h"
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
#include "input.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "tiles.h"
 | 
			
		||||
 | 
			
		||||
// 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_AT(x,y) (y)*Main_tilemap_width+(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)
 | 
			
		||||
 | 
			
		||||
enum TILE_FLIPPED
 | 
			
		||||
{
 | 
			
		||||
  TILE_FLIPPED_NONE = 0,
 | 
			
		||||
  TILE_FLIPPED_X = 1,
 | 
			
		||||
  TILE_FLIPPED_Y = 2,
 | 
			
		||||
  TILE_FLIPPED_XY = 3, // needs be TILE_FLIPPED_X|TILE_FLIPPED_Y
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// globals
 | 
			
		||||
 | 
			
		||||
/// Tilemap for the main screen
 | 
			
		||||
T_Tile * Main_tilemap;
 | 
			
		||||
/// Number of tiles (horizontally) for the main page's tilemap
 | 
			
		||||
short Main_tilemap_width;
 | 
			
		||||
/// Number of tiles (vertically) for the main page's tilemap
 | 
			
		||||
short Main_tilemap_height;
 | 
			
		||||
 | 
			
		||||
/// Tilemap for the spare
 | 
			
		||||
T_Tile * Spare_tilemap;
 | 
			
		||||
/// Number of tiles (horizontally) for the spare page's tilemap
 | 
			
		||||
short Spare_tilemap_width;
 | 
			
		||||
/// Number of tiles (vertically) for the spare page's tilemap
 | 
			
		||||
short Spare_tilemap_height;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Draw a pixel while Tilemap mode is active : This will paint on all
 | 
			
		||||
/// similar tiles of the layer, visible on the screen or not.
 | 
			
		||||
void Tilemap_draw(word x, word y, byte color)
 | 
			
		||||
{
 | 
			
		||||
  int tile, first_tile;
 | 
			
		||||
  int rel_x, rel_y;
 | 
			
		||||
  
 | 
			
		||||
  if (x < Snap_offset_X
 | 
			
		||||
   || y < Snap_offset_Y
 | 
			
		||||
   || x >= Snap_offset_X + Main_tilemap_width*Snap_width
 | 
			
		||||
   || y >= Snap_offset_Y + Main_tilemap_height*Snap_height)
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  tile = first_tile = TILE_FOR_COORDS(x,y);
 | 
			
		||||
  
 | 
			
		||||
  rel_x = (x - Snap_offset_X + Snap_width) % Snap_width;
 | 
			
		||||
  rel_y = (y - Snap_offset_Y + Snap_height) % Snap_height;
 | 
			
		||||
  do
 | 
			
		||||
  {
 | 
			
		||||
    int xx,yy;
 | 
			
		||||
    switch(Main_tilemap[tile].Flipped ^ Main_tilemap[first_tile].Flipped)
 | 
			
		||||
    {
 | 
			
		||||
      case 0: // no
 | 
			
		||||
      default:
 | 
			
		||||
        xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + rel_x;
 | 
			
		||||
        yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + rel_y;
 | 
			
		||||
        break;
 | 
			
		||||
      case 1: // horizontal
 | 
			
		||||
        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;
 | 
			
		||||
        break;
 | 
			
		||||
      case 2: // vertical
 | 
			
		||||
        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;
 | 
			
		||||
        break;
 | 
			
		||||
      case 3: // both
 | 
			
		||||
        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;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    if (yy>=Limit_top&&yy<=Limit_bottom&&xx>=Limit_left&&xx<=Limit_right)
 | 
			
		||||
      Pixel_in_current_screen_with_preview(xx,yy,color);
 | 
			
		||||
    else
 | 
			
		||||
      Pixel_in_current_screen(xx,yy,color);
 | 
			
		||||
      
 | 
			
		||||
    tile = Main_tilemap[tile].Next;
 | 
			
		||||
  } while (tile != first_tile);
 | 
			
		||||
 | 
			
		||||
  Update_rect(0,0,0,0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
int Tile_is_same(int t1, int t2)
 | 
			
		||||
{
 | 
			
		||||
  byte *bmp1,*bmp2;
 | 
			
		||||
  int y;
 | 
			
		||||
  
 | 
			
		||||
  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));
 | 
			
		||||
  
 | 
			
		||||
  for (y=0; y < Snap_height; y++)
 | 
			
		||||
  {
 | 
			
		||||
    if (memcmp(bmp1+y*Main_image_width, bmp2+y*Main_image_width, Snap_width))
 | 
			
		||||
      return 0;
 | 
			
		||||
  }
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
int Tile_is_same_flipped_x(int t1, int t2)
 | 
			
		||||
{
 | 
			
		||||
  byte *bmp1,*bmp2;
 | 
			
		||||
  int y, x;
 | 
			
		||||
  
 | 
			
		||||
  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);
 | 
			
		||||
  
 | 
			
		||||
  for (y=0; y < Snap_height; y++)
 | 
			
		||||
  {
 | 
			
		||||
    for (x=0; x < Snap_width; x++)
 | 
			
		||||
      if (*(bmp1+y*Main_image_width+x) != *(bmp2+y*Main_image_width-x))
 | 
			
		||||
        return 0;
 | 
			
		||||
  }
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
int Tile_is_same_flipped_y(int t1, int t2)
 | 
			
		||||
{
 | 
			
		||||
  byte *bmp1,*bmp2;
 | 
			
		||||
  int y;
 | 
			
		||||
  
 | 
			
		||||
  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));
 | 
			
		||||
  
 | 
			
		||||
  for (y=0; y < Snap_height; y++)
 | 
			
		||||
  {
 | 
			
		||||
    if (memcmp(bmp1+y*Main_image_width, bmp2-y*Main_image_width, Snap_width))
 | 
			
		||||
      return 0;
 | 
			
		||||
  }
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
int Tile_is_same_flipped_xy(int t1, int t2)
 | 
			
		||||
{
 | 
			
		||||
  byte *bmp1,*bmp2;
 | 
			
		||||
  int y, x;
 | 
			
		||||
  
 | 
			
		||||
  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);
 | 
			
		||||
  
 | 
			
		||||
  for (y=0; y < Snap_height; y++)
 | 
			
		||||
  {
 | 
			
		||||
    for (x=0; x < Snap_width; x++)
 | 
			
		||||
      if (*(bmp1+y*Main_image_width+x) != *(bmp2-y*Main_image_width-x))
 | 
			
		||||
        return 0;
 | 
			
		||||
  }
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Create or update a tilemap based on current screen (layer)'s pixels.
 | 
			
		||||
void Tilemap_update(void)
 | 
			
		||||
{
 | 
			
		||||
  int width;
 | 
			
		||||
  int height;
 | 
			
		||||
  int tile;
 | 
			
		||||
  int count=1;
 | 
			
		||||
  T_Tile * tile_ptr;
 | 
			
		||||
  
 | 
			
		||||
  int wait_window=0;
 | 
			
		||||
  byte old_cursor=0;
 | 
			
		||||
 | 
			
		||||
  if (!Main_tilemap_mode)
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  width=(Main_image_width-Snap_offset_X)/Snap_width;
 | 
			
		||||
  height=(Main_image_height-Snap_offset_Y)/Snap_height;
 | 
			
		||||
  
 | 
			
		||||
  if (width<1 || height<1 || width*height>1000000l
 | 
			
		||||
   || (tile_ptr=(T_Tile *)malloc(width*height*sizeof(T_Tile))) == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    // Cannot enable tilemap because either the image is too small
 | 
			
		||||
    // for the grid settings (and I don't want to implement partial tiles)
 | 
			
		||||
    // Or the number of tiles seems unreasonable (one million) : This can
 | 
			
		||||
    // happen if you set grid 1x1 for example.
 | 
			
		||||
  
 | 
			
		||||
    Disable_main_tilemap();
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  if (Main_tilemap)
 | 
			
		||||
  {
 | 
			
		||||
    // Recycle existing tilemap
 | 
			
		||||
    free(Main_tilemap);
 | 
			
		||||
    Main_tilemap=NULL;
 | 
			
		||||
  }
 | 
			
		||||
  Main_tilemap=tile_ptr;
 | 
			
		||||
  
 | 
			
		||||
  Main_tilemap_width=width;
 | 
			
		||||
  Main_tilemap_height=height;
 | 
			
		||||
 | 
			
		||||
  if (width*height > 1000 || Config.Tilemap_show_count)
 | 
			
		||||
  {
 | 
			
		||||
    wait_window=1;
 | 
			
		||||
    old_cursor=Cursor_shape;
 | 
			
		||||
    Open_window(180,36,"Creating tileset");
 | 
			
		||||
    Print_in_window(26, 20, "Please wait...",MC_Black,MC_Light);
 | 
			
		||||
    Cursor_shape=CURSOR_SHAPE_HOURGLASS;
 | 
			
		||||
    Update_window_area(0,0,Window_width, Window_height);
 | 
			
		||||
    Display_cursor();
 | 
			
		||||
    Get_input(0);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Initialize array with all tiles unique by default
 | 
			
		||||
  for (tile=0; tile<width*height; tile++)
 | 
			
		||||
  {
 | 
			
		||||
    Main_tilemap[tile].Previous = tile;
 | 
			
		||||
    Main_tilemap[tile].Next = tile;
 | 
			
		||||
    Main_tilemap[tile].Flipped = 0;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Now find similar tiles and link them in circular linked list
 | 
			
		||||
  //It will be used to modify all tiles whenever you draw on one.
 | 
			
		||||
  for (tile=1; tile<width*height; tile++)
 | 
			
		||||
  {
 | 
			
		||||
    int ref_tile;
 | 
			
		||||
    
 | 
			
		||||
    // Try normal comparison
 | 
			
		||||
    
 | 
			
		||||
    for (ref_tile=0; ref_tile<tile; ref_tile++)
 | 
			
		||||
    {
 | 
			
		||||
      if (Main_tilemap[ref_tile].Previous<=ref_tile && Tile_is_same(ref_tile, tile))
 | 
			
		||||
      {
 | 
			
		||||
        break; // stop loop on ref_tile
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (ref_tile<tile)
 | 
			
		||||
    {
 | 
			
		||||
      // New occurence of a known tile
 | 
			
		||||
      // Insert at the end. classic doubly-linked-list.
 | 
			
		||||
      int last_tile=Main_tilemap[ref_tile].Previous;
 | 
			
		||||
      Main_tilemap[tile].Previous=last_tile;
 | 
			
		||||
      Main_tilemap[tile].Next=ref_tile;
 | 
			
		||||
      Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped;
 | 
			
		||||
      Main_tilemap[ref_tile].Previous=tile;
 | 
			
		||||
      Main_tilemap[last_tile].Next=tile;
 | 
			
		||||
      continue; // next tile
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Try flipped-y comparison
 | 
			
		||||
    if (Config.Tilemap_allow_flipped_y)
 | 
			
		||||
    {
 | 
			
		||||
      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))
 | 
			
		||||
        {
 | 
			
		||||
          break; // stop loop on ref_tile
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (ref_tile<tile)
 | 
			
		||||
      {
 | 
			
		||||
        // New occurence of a known tile
 | 
			
		||||
        // Insert at the end. classic doubly-linked-list.
 | 
			
		||||
        int last_tile=Main_tilemap[ref_tile].Previous;
 | 
			
		||||
        Main_tilemap[tile].Previous=last_tile;
 | 
			
		||||
        Main_tilemap[tile].Next=ref_tile;
 | 
			
		||||
        Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped ^ TILE_FLIPPED_Y;
 | 
			
		||||
        Main_tilemap[ref_tile].Previous=tile;
 | 
			
		||||
        Main_tilemap[last_tile].Next=tile;
 | 
			
		||||
        continue; // next tile
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Try flipped-x comparison
 | 
			
		||||
    if (Config.Tilemap_allow_flipped_x)
 | 
			
		||||
    {
 | 
			
		||||
      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))
 | 
			
		||||
        {
 | 
			
		||||
          break; // stop loop on ref_tile
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (ref_tile<tile)
 | 
			
		||||
      {
 | 
			
		||||
        // New occurence of a known tile
 | 
			
		||||
        // Insert at the end. classic doubly-linked-list.
 | 
			
		||||
        int last_tile=Main_tilemap[ref_tile].Previous;
 | 
			
		||||
        Main_tilemap[tile].Previous=last_tile;
 | 
			
		||||
        Main_tilemap[tile].Next=ref_tile;
 | 
			
		||||
        Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped ^ TILE_FLIPPED_X;
 | 
			
		||||
        Main_tilemap[ref_tile].Previous=tile;
 | 
			
		||||
        Main_tilemap[last_tile].Next=tile;
 | 
			
		||||
        continue; // next tile
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Try flipped-xy comparison
 | 
			
		||||
    if (Config.Tilemap_allow_flipped_x && Config.Tilemap_allow_flipped_y)
 | 
			
		||||
    {
 | 
			
		||||
      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))
 | 
			
		||||
        {
 | 
			
		||||
          break; // stop loop on ref_tile
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (ref_tile<tile)
 | 
			
		||||
      {
 | 
			
		||||
        // New occurence of a known tile
 | 
			
		||||
        // Insert at the end. classic doubly-linked-list.
 | 
			
		||||
        int last_tile=Main_tilemap[ref_tile].Previous;
 | 
			
		||||
        Main_tilemap[tile].Previous=last_tile;
 | 
			
		||||
        Main_tilemap[tile].Next=ref_tile;
 | 
			
		||||
        Main_tilemap[tile].Flipped=Main_tilemap[ref_tile].Flipped ^ TILE_FLIPPED_XY;
 | 
			
		||||
        Main_tilemap[ref_tile].Previous=tile;
 | 
			
		||||
        Main_tilemap[last_tile].Next=tile;
 | 
			
		||||
        continue; // next tile
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // This tile is really unique.
 | 
			
		||||
    // Nothing to do at this time: the initialization
 | 
			
		||||
    // has already set the right data for Main_tilemap[tile].
 | 
			
		||||
    count++;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  if (wait_window)
 | 
			
		||||
  {
 | 
			
		||||
    char   str[8];
 | 
			
		||||
    Uint32 end;
 | 
			
		||||
    
 | 
			
		||||
    if (Config.Tilemap_show_count)
 | 
			
		||||
    {
 | 
			
		||||
      Num2str(count,str,7);
 | 
			
		||||
      Hide_cursor();
 | 
			
		||||
      Print_in_window(6, 20, "Unique tiles: ",MC_Black,MC_Light);
 | 
			
		||||
      Print_in_window(6+8*14,20,str,MC_Black,MC_Light);
 | 
			
		||||
      Display_cursor();
 | 
			
		||||
      
 | 
			
		||||
      // Wait a moment to display count
 | 
			
		||||
      end = SDL_GetTicks()+750;
 | 
			
		||||
      do
 | 
			
		||||
      {
 | 
			
		||||
        Get_input(20);
 | 
			
		||||
      } while (SDL_GetTicks()<end);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Close_window();
 | 
			
		||||
    Cursor_shape=old_cursor;
 | 
			
		||||
    Display_cursor();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// This exchanges the tilemap settings of the main and spare, it should
 | 
			
		||||
/// be called when swapping pages.
 | 
			
		||||
void Swap_tilemap(void)
 | 
			
		||||
{
 | 
			
		||||
  SWAP_BYTES(Main_tilemap_mode, Spare_tilemap_mode)
 | 
			
		||||
  {
 | 
			
		||||
    T_Tile * a;
 | 
			
		||||
    a=Main_tilemap;
 | 
			
		||||
    Main_tilemap=Spare_tilemap;
 | 
			
		||||
    Spare_tilemap=a;
 | 
			
		||||
  }
 | 
			
		||||
  SWAP_SHORTS(Main_tilemap_width, Spare_tilemap_width)
 | 
			
		||||
  SWAP_SHORTS(Main_tilemap_height, Spare_tilemap_height)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Clears all tilemap data and settings for the main page.
 | 
			
		||||
/// Safe to call again.
 | 
			
		||||
void Disable_main_tilemap(void)
 | 
			
		||||
{
 | 
			
		||||
  if (Main_tilemap)
 | 
			
		||||
  {
 | 
			
		||||
    // Recycle existing tilemap
 | 
			
		||||
    free(Main_tilemap);
 | 
			
		||||
    Main_tilemap=NULL;
 | 
			
		||||
  }
 | 
			
		||||
  Main_tilemap_width=0;
 | 
			
		||||
  Main_tilemap_height=0;
 | 
			
		||||
  Main_tilemap_mode=0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Clears all tilemap data and settings for the spare.
 | 
			
		||||
/// Safe to call again.
 | 
			
		||||
void Disable_spare_tilemap(void)
 | 
			
		||||
{
 | 
			
		||||
    if (Spare_tilemap)
 | 
			
		||||
  {
 | 
			
		||||
    // Recycle existing tilemap
 | 
			
		||||
    free(Spare_tilemap);
 | 
			
		||||
    Spare_tilemap=NULL;
 | 
			
		||||
  }
 | 
			
		||||
  Spare_tilemap_width=0;
 | 
			
		||||
  Spare_tilemap_height=0;
 | 
			
		||||
  Spare_tilemap_mode=0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										126
									
								
								src/tiles.h
									
									
									
									
									
								
							
							
						
						
									
										126
									
								
								src/tiles.h
									
									
									
									
									
								
							@ -1,63 +1,63 @@
 | 
			
		||||
/* vim:expandtab:ts=2 sw=2:
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Yves Rizoud
 | 
			
		||||
    Copyright 2011 Adrien Destugues
 | 
			
		||||
 | 
			
		||||
    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/>
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
///@file tiles.h
 | 
			
		||||
/// Functions for tilemap effect
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
/// Create or update a tilemap based on current screen pixels.
 | 
			
		||||
void Tilemap_update(void);
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Draw a pixel while Tilemap mode is active : This will paint on all
 | 
			
		||||
/// similar tiles of the layer, visible on the screen or not.
 | 
			
		||||
void Tilemap_draw(word x, word y, byte color);
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// This exchanges the tilemap settings of the main and spare, it should
 | 
			
		||||
/// be called when swapping pages.
 | 
			
		||||
void Swap_tilemap(void);
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Clears all tilemap data and settings for the main page.
 | 
			
		||||
/// Safe to call again.
 | 
			
		||||
void Disable_main_tilemap(void);
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Clears all tilemap data and settings for the spare.
 | 
			
		||||
/// Safe to call again.
 | 
			
		||||
void Disable_spare_tilemap(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// Tilemap for the main screen
 | 
			
		||||
extern T_Tile * Main_tilemap;
 | 
			
		||||
/// Number of tiles (horizontally) for the main page's tilemap
 | 
			
		||||
extern short Main_tilemap_width;
 | 
			
		||||
/// Number of tiles (vertically) for the main page's tilemap
 | 
			
		||||
extern short Main_tilemap_height;
 | 
			
		||||
 | 
			
		||||
/// Tilemap for the spare
 | 
			
		||||
extern T_Tile * Spare_tilemap;
 | 
			
		||||
/// Number of tiles (horizontally) for the spare page's tilemap
 | 
			
		||||
extern short Spare_tilemap_width;
 | 
			
		||||
/// Number of tiles (vertically) for the spare page's tilemap
 | 
			
		||||
extern short Spare_tilemap_height;
 | 
			
		||||
/* vim:expandtab:ts=2 sw=2:
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Yves Rizoud
 | 
			
		||||
    Copyright 2011 Adrien Destugues
 | 
			
		||||
 | 
			
		||||
    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/>
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
///@file tiles.h
 | 
			
		||||
/// Functions for tilemap effect
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
/// Create or update a tilemap based on current screen pixels.
 | 
			
		||||
void Tilemap_update(void);
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Draw a pixel while Tilemap mode is active : This will paint on all
 | 
			
		||||
/// similar tiles of the layer, visible on the screen or not.
 | 
			
		||||
void Tilemap_draw(word x, word y, byte color);
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// This exchanges the tilemap settings of the main and spare, it should
 | 
			
		||||
/// be called when swapping pages.
 | 
			
		||||
void Swap_tilemap(void);
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Clears all tilemap data and settings for the main page.
 | 
			
		||||
/// Safe to call again.
 | 
			
		||||
void Disable_main_tilemap(void);
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Clears all tilemap data and settings for the spare.
 | 
			
		||||
/// Safe to call again.
 | 
			
		||||
void Disable_spare_tilemap(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// Tilemap for the main screen
 | 
			
		||||
extern T_Tile * Main_tilemap;
 | 
			
		||||
/// Number of tiles (horizontally) for the main page's tilemap
 | 
			
		||||
extern short Main_tilemap_width;
 | 
			
		||||
/// Number of tiles (vertically) for the main page's tilemap
 | 
			
		||||
extern short Main_tilemap_height;
 | 
			
		||||
 | 
			
		||||
/// Tilemap for the spare
 | 
			
		||||
extern T_Tile * Spare_tilemap;
 | 
			
		||||
/// Number of tiles (horizontally) for the spare page's tilemap
 | 
			
		||||
extern short Spare_tilemap_width;
 | 
			
		||||
/// Number of tiles (vertically) for the spare page's tilemap
 | 
			
		||||
extern short Spare_tilemap_height;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user