From 97c8453dcd65e9d06c86e2e5fc1cffcdd1815e23 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Thu, 16 Jul 2009 12:58:36 +0000 Subject: [PATCH] Converted all files to unix end of lines. git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@928 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- help.h | 96 +- helpfile.h | 4866 ++++++++++++------------ hotkeys.c | 2668 ++++++------- init.h | 84 +- keyboard.c | 1300 +++---- keyboard.h | 150 +- loadsave.h | 114 +- misc.h | 300 +- mountlist.c | 1828 ++++----- mountlist.h | 94 +- op_c.c | 2452 ++++++------ op_c.h | 430 +-- operatio.c | 10226 +++++++++++++++++++++++++------------------------- operatio.h | 438 +-- pages.h | 186 +- palette.c | 4604 +++++++++++------------ palette.h | 84 +- pxdouble.c | 994 ++--- pxdouble.h | 96 +- pxquad.c | 1064 +++--- pxquad.h | 96 +- pxsimple.c | 940 ++--- pxsimple.h | 102 +- pxtall.c | 906 ++--- pxtall.h | 92 +- pxtall2.c | 1048 +++--- pxtall2.h | 96 +- pxtriple.c | 1040 ++--- pxtriple.h | 96 +- pxwide.c | 1012 ++--- pxwide.h | 98 +- pxwide2.c | 1028 ++--- pxwide2.h | 96 +- readini.h | 54 +- readline.c | 700 ++-- readline.h | 88 +- saveini.h | 50 +- setup.c | 364 +- setup.h | 108 +- shade.h | 64 +- special.c | 728 ++-- special.h | 86 +- struct.h | 820 ++-- text.h | 108 +- transform.c | 818 ++-- transform.h | 54 +- 46 files changed, 21383 insertions(+), 21383 deletions(-) diff --git a/help.h b/help.h index 30ac2c97..883df678 100644 --- a/help.h +++ b/help.h @@ -1,48 +1,48 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file help.h -/// Functions related to the help browser. The help data is in helpfile.h -////////////////////////////////////////////////////////////////////////////// - -#ifndef __HELP_H_ -#define __HELP_H_ - -/*! - Called to open the help window with the keyboard shortcut. - If the mouse is over a button, its contextual help will be displayed. - Else, the default helpscreen will be shown. -*/ -void Button_Help(void); - -/*! - Displays and runs the "Statistics" window -*/ -void Button_Stats(void); - -/*! - Displays and runs the "Help / About..." window - @param section Number of the help section page to display (equals the button number the mouse was hovering for the contextual help), -1 for the main help page. - @param sub_section Help sub-section title (the page will be scrolled so this title is at the top). -*/ -void Window_help(int section, const char * sub_section); - -#endif - +/* Grafx2 - The Ultimate 256-color bitmap paint program + + 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file help.h +/// Functions related to the help browser. The help data is in helpfile.h +////////////////////////////////////////////////////////////////////////////// + +#ifndef __HELP_H_ +#define __HELP_H_ + +/*! + Called to open the help window with the keyboard shortcut. + If the mouse is over a button, its contextual help will be displayed. + Else, the default helpscreen will be shown. +*/ +void Button_Help(void); + +/*! + Displays and runs the "Statistics" window +*/ +void Button_Stats(void); + +/*! + Displays and runs the "Help / About..." window + @param section Number of the help section page to display (equals the button number the mouse was hovering for the contextual help), -1 for the main help page. + @param sub_section Help sub-section title (the page will be scrolled so this title is at the top). +*/ +void Window_help(int section, const char * sub_section); + +#endif + diff --git a/helpfile.h b/helpfile.h index 612b2011..81a26cb2 100644 --- a/helpfile.h +++ b/helpfile.h @@ -1,2433 +1,2433 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 Yves Rizoud - Copyright 2009 Franck Charlet - 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file helpfile.h -/// This is all the text that appears in contextual help and credits. -/// -/// Note: The source code is kept on a public website, so keep this in mind -/// if you're thinking of putting an e-mail address in there. At least, use -/// "\100" instead of @, to help against the most basic email address harvesters. -////////////////////////////////////////////////////////////////////////////// - -#include "const.h" // Uses enumerations BUTTON_NUMBERS and SPECIAL_ACTIONS - -// Some magic formulas: - -#define HELP_TEXT(x) {'N', x, 0}, -// Generates a 'N' line (Normal) - -#define HELP_LINK(x,y) {'K', x, y}, -// Generates a 'K' line (Key) - -#define HELP_BOLD(x) {'S', x, 0}, -// Generates a 'S' line (BOLD) - -#define HELP_TITLE(x) {'T', x, 0}, {'-', x, 0}, -// Generates a 'T' line (Title, upper half) -// and a second '-' line (Title, lower half), with the same text. - -static const T_Help_table helptable_about[] = -/* - Do not exceed 44 characters for normal lines: - HELP_TEXT ("--------------------------------------------") - Do not exceed 22 characters for title lines: - HELP_TITLE("======================") -*/ -{ - HELP_TEXT ("") // Leave enough room for a hard-coded logo, eventually. - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE(" GRAFX 2 ") - HELP_BOLD (" \"Summer Sunset\" Edition") - HELP_BOLD (" THE ULTIMATE MULTI-RESOLUTION GFX EDITOR") - HELP_TEXT (" http://grafx2.googlecode.com") - HELP_TEXT ("") - HELP_TEXT (" Copyright 2007 by the Grafx2 project team") - HELP_TEXT (" Copyright 1996-2001 by SUNSET DESIGN") -}; -static const T_Help_table helptable_licence[] = -{ - HELP_TITLE(" LICENSE") - HELP_TEXT ("") - HELP_TEXT ("Grafx2 is FREE SOFTWARE, you can") - HELP_TEXT ("redistribute it and/or modify it under the") - HELP_TEXT ("terms of the GNU General Public License as") - HELP_TEXT ("published by the Free Software Foundation;") - HELP_TEXT ("version 2 of the License.") - HELP_TEXT ("") - HELP_TEXT ("Grafx2 is distributed in the hope that it") - HELP_TEXT ("will be useful, but WITHOUT ANY WARRANTY;") - HELP_TEXT ("without even the implied warranty of") - HELP_TEXT ("MERCHANTABILITY or FITNESS FOR A PARTICULAR") - HELP_TEXT ("PURPOSE. See the GNU General Public License") - HELP_TEXT ("for more details.") - HELP_TEXT ("") - HELP_TEXT ("You should have received a copy of the GNU") - HELP_TEXT ("General Public License along with Grafx2;") - HELP_TEXT ("if not, see http://www.gnu.org/licenses/ or") - HELP_TEXT ("write to the Free Software Foundation, Inc.") - HELP_TEXT (" 59 Temple Place - Suite 330, Boston,") - HELP_TEXT (" MA 02111-1307, USA.") - -}; -static const T_Help_table helptable_help[] = -{ - HELP_TITLE(" HELP") - HELP_TEXT ("") - HELP_TEXT (" Contextual help is available by pressing") - HELP_LINK (" the %s key",0x100+BUTTON_HELP) - HELP_TEXT (" You can do it while hovering a menu icon,") - HELP_TEXT (" or while a window is open.") - HELP_TEXT (" When a keyboard shortcut is displayed it's") - HELP_TEXT (" your current configuration and you can") - HELP_TEXT (" change it by clicking it.") - HELP_TEXT ("") - HELP_TITLE(" KEYBOARD SHORTCUTS") - HELP_TEXT ("") - HELP_TEXT ("Scroll visible area") - HELP_LINK (" up: %s", SPECIAL_SCROLL_UP) - HELP_LINK (" down: %s", SPECIAL_SCROLL_DOWN) - HELP_LINK (" left: %s", SPECIAL_SCROLL_LEFT) - HELP_LINK (" right: %s", SPECIAL_SCROLL_RIGHT) - HELP_LINK (" up faster: %s", SPECIAL_SCROLL_UP_FAST) - HELP_LINK (" down faster: %s", SPECIAL_SCROLL_DOWN_FAST) - HELP_LINK (" left faster: %s", SPECIAL_SCROLL_LEFT_FAST) - HELP_LINK (" right faster: %s", SPECIAL_SCROLL_RIGHT_FAST) - HELP_LINK (" up slower: %s", SPECIAL_SCROLL_UP_SLOW) - HELP_LINK (" down slower: %s", SPECIAL_SCROLL_DOWN_SLOW) - HELP_LINK (" left slower: %s", SPECIAL_SCROLL_LEFT_SLOW) - HELP_LINK (" right slower: %s", SPECIAL_SCROLL_RIGHT_SLOW) - HELP_TEXT ("Emulate mouse") - HELP_LINK (" Up: %s", SPECIAL_MOUSE_UP) - HELP_LINK (" Down: %s", SPECIAL_MOUSE_DOWN) - HELP_LINK (" Left: %s", SPECIAL_MOUSE_LEFT) - HELP_LINK (" Right: %s", SPECIAL_MOUSE_RIGHT) - HELP_LINK (" Left click: %s", SPECIAL_CLICK_LEFT) - HELP_LINK (" Right click: %s", SPECIAL_CLICK_RIGHT) - HELP_LINK ("Show / Hide menu: %s", 0x100+BUTTON_HIDE) - HELP_LINK ("Show / Hide cursor: %s", SPECIAL_SHOW_HIDE_CURSOR) - HELP_LINK ("Paintbrush = \".\": %s", SPECIAL_DOT_PAINTBRUSH) - HELP_LINK ("Paintbrush choice: %s", 0x100+BUTTON_PAINTBRUSHES) - HELP_LINK ("Monochrome brush: %s", 0x200+BUTTON_PAINTBRUSHES) - HELP_LINK ("Freehand drawing: %s", 0x100+BUTTON_DRAW) - HELP_TEXT ("Switch freehand") - HELP_LINK (" drawing mode: %s", 0x200+BUTTON_DRAW) - HELP_TEXT ("Continuous freehand") - HELP_LINK (" drawing: %s", SPECIAL_CONTINUOUS_DRAW) - HELP_LINK ("Line: %s", 0x100+BUTTON_LINES) - HELP_LINK ("Knotted lines: %s", 0x200+BUTTON_LINES) - HELP_LINK ("Spray: %s", 0x100+BUTTON_AIRBRUSH) - HELP_LINK ("Spray menu: %s", 0x200+BUTTON_AIRBRUSH) - HELP_LINK ("Floodfill: %s", 0x100+BUTTON_FLOODFILL) - HELP_LINK ("Replace color: %s", 0x200+BUTTON_FLOODFILL) - HELP_LINK ("Bezier's curves: %s", 0x100+BUTTON_CURVES) - HELP_TEXT ("Bezier's curve with") - HELP_LINK (" 3 or 4 points %s", 0x200+BUTTON_CURVES) - HELP_LINK ("Empty rectangle: %s", 0x100+BUTTON_RECTANGLES) - HELP_LINK ("Filled rectangle: %s", 0x100+BUTTON_FILLRECT) - HELP_LINK ("Empty circle: %s", 0x100+BUTTON_CIRCLES) - HELP_LINK ("Empty ellipse: %s", 0x200+BUTTON_CIRCLES) - HELP_LINK ("Filled circle: %s", 0x100+BUTTON_FILLCIRC) - HELP_LINK ("Filled ellipse: %s", 0x200+BUTTON_FILLCIRC) - HELP_LINK ("Empty polygon: %s", 0x100+BUTTON_POLYGONS) - HELP_LINK ("Empty polyform: %s", 0x200+BUTTON_POLYGONS) - HELP_LINK ("Polyfill: %s", 0x100+BUTTON_POLYFILL) - HELP_LINK ("Filled polyform: %s", 0x200+BUTTON_POLYFILL) - HELP_LINK ("Gradient rectangle: %s", 0x100+BUTTON_GRADRECT) - HELP_LINK ("Gradation menu: %s", 0x200+BUTTON_GRADRECT) - HELP_LINK ("Spheres: %s", 0x100+BUTTON_SPHERES) - HELP_LINK ("Gradient ellipses: %s", 0x200+BUTTON_SPHERES) - HELP_LINK ("Adjust picture: %s", 0x100+BUTTON_ADJUST) - HELP_LINK ("Flip picture menu: %s", 0x200+BUTTON_ADJUST) - HELP_LINK ("Effects menu: %s", 0x100+BUTTON_EFFECTS) - HELP_LINK ("Effects all off %s", SPECIAL_EFFECTS_OFF) - HELP_LINK ("Shade mode: %s", SPECIAL_SHADE_MODE) - HELP_LINK ("Shade menu: %s", SPECIAL_SHADE_MENU) - HELP_LINK ("Quick-shade mode: %s", SPECIAL_QUICK_SHADE_MODE) - HELP_LINK ("Quick-shade menu: %s", SPECIAL_QUICK_SHADE_MENU) - HELP_LINK ("Stencil mode: %s", SPECIAL_STENCIL_MODE) - HELP_LINK ("Stencil menu: %s", SPECIAL_STENCIL_MENU) - HELP_LINK ("Mask mode: %s", SPECIAL_MASK_MODE) - HELP_LINK ("Mask menu: %s", SPECIAL_MASK_MENU) - HELP_LINK ("Grid mode: %s", SPECIAL_GRID_MODE) - HELP_LINK ("Grid menu: %s", SPECIAL_GRID_MENU) - HELP_LINK ("Sieve mode: %s", SPECIAL_SIEVE_MODE) - HELP_LINK ("Sieve menu: %s", SPECIAL_SIEVE_MENU) - HELP_LINK ("Invert Sieve: %s", SPECIAL_INVERT_SIEVE) - HELP_LINK ("Colorize mode: %s", SPECIAL_COLORIZE_MODE) - HELP_LINK (" At opacity 10%%: %s", SPECIAL_TRANSPARENCY_1) - HELP_LINK (" At opacity 20%%: %s", SPECIAL_TRANSPARENCY_2) - HELP_LINK (" At opacity 30%%: %s", SPECIAL_TRANSPARENCY_3) - HELP_LINK (" At opacity 40%%: %s", SPECIAL_TRANSPARENCY_4) - HELP_LINK (" At opacity 50%%: %s", SPECIAL_TRANSPARENCY_5) - HELP_LINK (" At opacity 60%%: %s", SPECIAL_TRANSPARENCY_6) - HELP_LINK (" At opacity 70%%: %s", SPECIAL_TRANSPARENCY_7) - HELP_LINK (" At opacity 80%%: %s", SPECIAL_TRANSPARENCY_8) - HELP_LINK (" At opacity 90%%: %s", SPECIAL_TRANSPARENCY_9) - HELP_LINK (" At opacity 100%%: %s", SPECIAL_TRANSPARENCY_0) - HELP_LINK ("Colorize menu: %s", SPECIAL_COLORIZE_MENU) - HELP_LINK ("Smooth mode: %s", SPECIAL_SMOOTH_MODE) - HELP_LINK ("Smooth menu: %s", SPECIAL_SMOOTH_MENU) - HELP_LINK ("Smear mode: %s", SPECIAL_SMEAR_MODE) - HELP_LINK ("Tiling mode: %s", SPECIAL_TILING_MODE) - HELP_LINK ("Tiling menu: %s", SPECIAL_TILING_MENU) - HELP_LINK ("Pick brush: %s", 0x100+BUTTON_BRUSH) - HELP_LINK ("Pick polyform brush: %s", 0x100+BUTTON_POLYBRUSH) - HELP_LINK ("Restore brush: %s", 0x200+BUTTON_BRUSH) - HELP_LINK ("Flip brush X: %s", SPECIAL_FLIP_X) - HELP_LINK ("Flip brush Y: %s", SPECIAL_FLIP_Y) - HELP_LINK ("90° brush rotation: %s", SPECIAL_ROTATE_90) - HELP_LINK ("180° brush rotation: %s", SPECIAL_ROTATE_180) - HELP_LINK ("Stretch brush: %s", SPECIAL_STRETCH) - HELP_LINK ("Distort brush: %s", SPECIAL_DISTORT) - HELP_LINK ("Outline brush: %s", SPECIAL_OUTLINE) - HELP_LINK ("Nibble brush: %s", SPECIAL_NIBBLE) - HELP_LINK ("Get brush colors: %s", SPECIAL_GET_BRUSH_COLORS) - HELP_LINK ("Recolorize brush: %s", SPECIAL_RECOLORIZE_BRUSH) - HELP_LINK ("Rotate brush: %s", SPECIAL_ROTATE_ANY_ANGLE) - HELP_LINK ("Pipette: %s", 0x100+BUTTON_COLORPICKER) - HELP_LINK ("Swap fore/back color:%s", 0x200+BUTTON_COLORPICKER) - HELP_LINK ("Magnifier mode: %s", 0x100+BUTTON_MAGNIFIER) - HELP_LINK ("Zoom factor menu: %s", 0x200+BUTTON_MAGNIFIER) - HELP_LINK ("Zoom in: %s", SPECIAL_ZOOM_IN) - HELP_LINK ("Zoom out: %s", SPECIAL_ZOOM_OUT) - HELP_LINK ("Brush effects menu: %s", 0x100+BUTTON_BRUSH_EFFECTS) - HELP_LINK ("Text: %s", 0x100+BUTTON_TEXT) - HELP_LINK ("Resolution menu: %s", 0x100+BUTTON_RESOL) - HELP_LINK ("Safety resolution: %s", 0x200+BUTTON_RESOL) - HELP_LINK ("Help: %s", 0x100+BUTTON_HELP) - HELP_LINK ("Statistics: %s", 0x200+BUTTON_HELP) - HELP_LINK ("Go to spare page: %s", 0x100+BUTTON_PAGE) - HELP_LINK ("Copy to spare page: %s", 0x200+BUTTON_PAGE) - HELP_LINK ("Save as: %s", 0x100+BUTTON_SAVE) - HELP_LINK ("Save: %s", 0x200+BUTTON_SAVE) - HELP_LINK ("Load: %s", 0x100+BUTTON_LOAD) - HELP_LINK ("Re-load: %s", 0x200+BUTTON_LOAD) - HELP_LINK ("Save brush: %s", SPECIAL_SAVE_BRUSH) - HELP_LINK ("Load brush: %s", SPECIAL_LOAD_BRUSH) - HELP_LINK ("Larger brush size: %s", SPECIAL_BIGGER_PAINTBRUSH) - HELP_LINK ("Smaller brush size: %s", SPECIAL_SMALLER_PAINTBRUSH) - HELP_LINK ("Settings: %s", 0x100+BUTTON_SETTINGS) - HELP_LINK ("Undo: %s", 0x100+BUTTON_UNDO) - HELP_LINK ("Redo: %s", 0x200+BUTTON_UNDO) - HELP_LINK ("Kill page: %s", 0x100+BUTTON_KILL) - HELP_LINK ("Clear: %s", 0x100+BUTTON_CLEAR) - HELP_LINK ("Clear with BG color: %s", 0x200+BUTTON_CLEAR) - HELP_LINK ("Quit: %s", 0x100+BUTTON_QUIT) - HELP_LINK ("Palette menu: %s", 0x100+BUTTON_PALETTE) - HELP_LINK ("2nd Palette menu: %s", 0x200+BUTTON_PALETTE) - HELP_LINK ("Exclude colors menu: %s", SPECIAL_EXCLUDE_COLORS_MENU) - HELP_TEXT ("") - HELP_TEXT ("Scroll palette") - HELP_LINK (" Back: %s", 0x100+BUTTON_PAL_LEFT) - HELP_LINK (" Forward: %s", 0x100+BUTTON_PAL_RIGHT) - HELP_LINK (" Back faster: %s", 0x200+BUTTON_PAL_LEFT) - HELP_LINK (" Forward faster: %s", 0x200+BUTTON_PAL_RIGHT) - HELP_TEXT ("") - HELP_TEXT ("Change brush attachement") - HELP_LINK (" Center : %s", SPECIAL_CENTER_ATTACHMENT) - HELP_LINK (" Top-left : %s", SPECIAL_TOP_LEFT_ATTACHMENT) - HELP_LINK (" Top-right : %s", SPECIAL_TOP_RIGHT_ATTACHMENT) - HELP_LINK (" Bottom-left : %s", SPECIAL_BOTTOM_LEFT_ATTACHMENT) - HELP_LINK (" Bottom-right: %s", SPECIAL_BOTTOM_RIGHT_ATTACHMENT) - HELP_TEXT ("") - HELP_TEXT ("Select foreground color") - HELP_TEXT ("") - HELP_LINK (" Next : %s", SPECIAL_NEXT_FORECOLOR) - HELP_LINK (" Previous: %s", SPECIAL_PREVIOUS_FORECOLOR) - HELP_TEXT ("") - HELP_TEXT ("Select background color") - HELP_LINK (" Next : %s", SPECIAL_NEXT_BACKCOLOR) - HELP_LINK (" Previous: %s", SPECIAL_PREVIOUS_BACKCOLOR) - HELP_TEXT ("") - HELP_TEXT ("Select user-defined foreground color") - HELP_TEXT ("") - HELP_LINK (" Next : %s", SPECIAL_NEXT_USER_FORECOLOR) - HELP_LINK (" Previous: %s", SPECIAL_PREVIOUS_USER_FORECOLOR) - HELP_TEXT ("") - HELP_TEXT ("Select user-defined background color") - HELP_LINK (" Next : %s", SPECIAL_NEXT_USER_BACKCOLOR) - HELP_LINK (" Previous: %s", SPECIAL_PREVIOUS_USER_BACKCOLOR) - HELP_TEXT ("") -}; -static const T_Help_table helptable_credits[] = -{ -//HELP_TEXT ("0----5----0----5----0----5----0----5----0--X") - HELP_TITLE(" GRAFX2 IS CREATED BY") - HELP_TEXT ("") - HELP_BOLD (" SUNSET DESIGN") - HELP_BOLD (" AUTHORS OF GRAFX2.0 BETA 96.5%") - HELP_TEXT ("") - HELP_TEXT (" Guillaume Dorme alias \"Robinson\" (code)") - HELP_TEXT (" Karl Maritaud alias \"X-Man\" (code&gfx)") -//HELP_TEXT ("0----5----0----5----0----5----0----5----0--X") - HELP_TEXT ("") - HELP_TEXT (" Re-licensed GrafX2 under the GPL in 2001") - HELP_TEXT ("") - HELP_BOLD (" THE GRAFX2 PROJECT TEAM") - HELP_TEXT ("") - HELP_TEXT (" Adrien Destugues (pulkomandy)") - HELP_TEXT (" Yves Rizoud (yrizoud)") - HELP_TEXT ("") - HELP_TEXT (" Got the source back to life in 2006") - HELP_TEXT ("") - HELP_BOLD (" ART") - HELP_TEXT ("") - HELP_TEXT (" GrafX2 logo by Made (www.m4de.com)") - HELP_TEXT (" Icons and fonts by X-Man ") - HELP_TEXT (" Additional graphics and logo by iLKke") - HELP_TEXT (" (ilkke.blogspot.com)") - HELP_TEXT ("") - HELP_TEXT (" Pixelled all the graphics") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE(" OTHER MACHINES PORTS") - HELP_TEXT ("") - HELP_BOLD (" AMIGA OS 3 PORT") - HELP_TEXT ("") - HELP_TEXT (" Artur Jarosik") - HELP_TEXT ("") - HELP_BOLD (" AMIGA OS 4 PORT") - HELP_TEXT ("") - HELP_TEXT (" Peter Gordon (www.petergordon.org.uk)") - HELP_TEXT ("") - HELP_BOLD (" AROS PORT") - HELP_TEXT ("") - HELP_TEXT (" Fernando Mastandrea (masta.uy)") - HELP_TEXT (" Markus Weiss") - HELP_TEXT ("") - HELP_BOLD (" FREEBSD PORT") - HELP_TEXT ("") - HELP_TEXT (" Jean-Baptiste Berlioz (Tobe)") - HELP_TEXT ("") - HELP_BOLD (" HAIKU OS AND BEOS PORT") - HELP_TEXT ("") - HELP_TEXT (" Luc Schrijvers (Begasus)") - HELP_TEXT ("") - HELP_BOLD (" MAC OS X PORT") - HELP_TEXT ("") - HELP_TEXT (" Franck Charlet (hitchhikr)") - HELP_TEXT (" Per Olofsson (MagerValp)") - HELP_TEXT ("") - HELP_BOLD (" MORPHOS PORT") - HELP_TEXT ("") - HELP_TEXT (" Rusback") - HELP_TEXT ("") - HELP_BOLD (" SKYOS PORT") - HELP_TEXT ("") - HELP_TEXT (" Luc Schrijvers (Begasus)") - HELP_TEXT ("") - HELP_TEXT (" ... made it work on your favourite toaster") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE(" BUGFINDERS") - HELP_TEXT ("") -//HELP_TEXT ("0----5----0----5----0----5----0----5----0--X") - HELP_TEXT (" blumunkee BDCIron Ced ") - HELP_TEXT (" El Topo fallenblood Frost ") - HELP_TEXT (" Grimmy Gürkan Sengün HoraK-FDF ") - HELP_TEXT (" iLKke Jamon keito ") - HELP_TEXT (" kusma Lord Graga MagerValp ") - HELP_TEXT (" mind MooZ the Peach ") - HELP_TEXT (" richienyhus tape.wyrm TeeEmCee ") - HELP_TEXT (" tempest Timo Kurrpa titus^Rab ") - HELP_TEXT (" Tobé 00ai99 ") - HELP_TEXT ("") - HELP_TEXT (" ... posted the annoying bug reports.") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE(" FILE FORMATS CREDITS") - HELP_TEXT ("") - HELP_TEXT (" BMP : Microsoft") - HELP_TEXT (" CEL,KCF : K.O.S. (KISekae Set system)") - HELP_TEXT (" GIF : Compuserve") - HELP_TEXT (" IMG : Bivas (W. Wiedmann?)") - HELP_TEXT (" LBM : Electronic Arts") - HELP_TEXT (" PAL : ermmh... nobody (?)") - HELP_TEXT (" PCX : Z-Soft") - HELP_TEXT (" PI1,PC1 : Degas Elite") - HELP_TEXT (" PKM : Sunset Design") - HELP_TEXT (" PNG : W3C") - HELP_TEXT (" SCx : Colorix (?)") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE (" OUR HOMEPAGE") - HELP_TEXT ("") - HELP_BOLD (" http://grafx2.codegoogle.com") - HELP_TEXT ("") - HELP_TEXT (" Please report any bug you may find there") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE (" GREETINGS") - HELP_TEXT ("") - HELP_TEXT (" To the Pouet.net BBS posters, the #CPC") - HELP_TEXT (" trolls and the bitfellas") - HELP_TEXT (" To every people who makes the scene alive!") - HELP_TEXT (" To all guys making nice pixelled pictures") - HELP_TEXT (" (with or without GrafX2)") - HELP_TEXT ("") - HELP_BOLD (" We send our best regards to...") - HELP_TEXT ("") - HELP_TEXT (" Access Filter Pink") - HELP_TEXT (" Ace Fiver Pixel") - HELP_TEXT (" AcidJam Flan Profil") - HELP_TEXT (" Acryl Fred Prowler") - HELP_TEXT (" Alexel FreddyV Puznik") - HELP_TEXT (" Alias Frost Quick") - HELP_TEXT (" Amiral Gaël(GDC) Ra") - HELP_TEXT (" Arrakis GainX Raster") - HELP_TEXT (" Avocado Gandalf Ravian") - HELP_TEXT (" Baloo Goblin RedBug") - HELP_TEXT (" Barti Greenpix7 Rem") - HELP_TEXT (" Bat Grid Rez") - HELP_TEXT (" Biro GrosQuick Roudoudou") - HELP_TEXT (" Bisounours HackerCroll Sacrilege") - HELP_TEXT (" BlackAxe Haplo Sam") - HELP_TEXT (" Bonnie Hof SandMan") - HELP_TEXT (" Boo Hornet Scape") - HELP_TEXT (" Boz Hulud Sébastien") - HELP_TEXT (" Carine Java Shodan") - HELP_TEXT (" Chandra JBT Skal") - HELP_TEXT (" Cheetah Jérôme Skyfire") - HELP_TEXT (" Chill Julien(JCA) Sphair") - HELP_TEXT (" Cougar KalMinDo Sprocket") - HELP_TEXT (" Cremax KaneWood Stef") - HELP_TEXT (" Cyclone Karma Stony") - HELP_TEXT (" Dake Keith303 Sumaleth") - HELP_TEXT (" Danny Lazur Sunday") - HELP_TEXT (" Danube LightShow Suny") - HELP_TEXT (" Darjul Lluvia Sybaris") - HELP_TEXT (" Darwin Louie TBF") - HELP_TEXT (" DarkAngel Luk Tempest") - HELP_TEXT (" Das Made Thor") - HELP_TEXT (" Decker Mamos TMK") - HELP_TEXT (" DerPiipo Mandrixx TwoFace") - HELP_TEXT (" Destop Mangue Underking") - HELP_TEXT (" Diabolo Mars Unreal") - HELP_TEXT (" DineS Mephisto VaeVictis") - HELP_TEXT (" Drac Mercure Vastator") - HELP_TEXT (" DrYes Mirec Vatin") - HELP_TEXT (" Edyx Moa Veckman") - HELP_TEXT (" Eller Moxica Wain") - HELP_TEXT (" Ellyn MRK Wally") - HELP_TEXT (" EOF Nitch WillBe") - HELP_TEXT (" Fall Noal Xoomie") - HELP_TEXT (" Fame Nytrik Xtrm") - HELP_TEXT (" Fantom Optic YannSulu") - HELP_TEXT (" Fear Orome Z") - HELP_TEXT (" Feather Pahladin Zeb") - HELP_TEXT (" Fennec Phar Zebig") - HELP_TEXT ("") - HELP_TEXT (" and all #pixel, #demofr and #coders.") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE (" SNAIL MAIL") - HELP_TEXT ("") - HELP_TEXT (" (From 2001, current status: unknown)") - HELP_TEXT ("") - HELP_TEXT (" GUILLAUME DORME (Robinson)") - HELP_TEXT (" 15, rue de l'observatoire") - HELP_TEXT (" 87000 LIMOGES (FRANCE)") - HELP_TEXT ("") - HELP_TEXT (" KARL MARITAUD (X-Man)") - HELP_TEXT (" 10, rue de la Brasserie") - HELP_TEXT (" 87000 LIMOGES (FRANCE)") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE(" THANKS") - HELP_TEXT ("") - HELP_TEXT (" Some information taken from several docs") - HELP_TEXT (" (PCGPE, Intervue, PC Interdit...)") - HELP_TEXT (" gave us an invaluable help.") - HELP_TEXT ("") - HELP_TEXT (" Thanks to Shawn Hargreaves for his filled") - HELP_TEXT (" polygon routine from Allegro v2.2.") - HELP_TEXT ("") - HELP_TEXT (" Thanks to Carlos \"Made\" Pardo for his") - HELP_TEXT (" great GrafX2 logo.") - HELP_TEXT ("") - HELP_TEXT (" This is our very first program compiled") - HELP_TEXT (" with the Gnu C Compiler.") - HELP_TEXT (" A thousand thanks to the authors of") - HELP_TEXT (" this compiler.") - HELP_TEXT ("") - HELP_TEXT (" We also would like to thank all the") - HELP_TEXT (" people who gave us ideas to improve") - HELP_TEXT (" GrafX2.") - HELP_TITLE("") -}; -static const T_Help_table helptable_paintbrush[] = -{ - HELP_TITLE("PAINTBRUSHES") - HELP_TEXT ("") - HELP_BOLD (" LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_PAINTBRUSHES) - HELP_TEXT ("") - HELP_TEXT ("Displays a menu where you can choose the") - HELP_TEXT ("shape of your paintbrush.") - HELP_TEXT ("") - HELP_TEXT ("Paintbrushes are sorted by family. You can") - HELP_TEXT ("see some paintbrushes of the same family but") - HELP_TEXT ("with different sizes. There is at least one") - HELP_TEXT ("paint-brush from each family displayed in") - HELP_TEXT ("this menu.") - HELP_TEXT ("Here is the list of all the different") - HELP_TEXT ("paintbrush families:") - HELP_TEXT ("") - HELP_TEXT ("******* *** * * * * * * ") - HELP_TEXT ("******* ***** * * * * * * ") - HELP_TEXT ("******* ******* * * * * * * * * ") - HELP_TEXT ("******* ******* * * * * * * ") - HELP_TEXT ("******* ******* * * * * * * * * ") - HELP_TEXT ("******* ***** * * * * * * ") - HELP_TEXT ("******* *** * * * * * * ") - HELP_TEXT ("") - HELP_TEXT ("Square Disc Sieve Sieve ") - HELP_TEXT (" square disc ") - HELP_TEXT (" ") - HELP_TEXT (" * * * ") - HELP_TEXT (" *** * * * ") - HELP_TEXT (" ***** * * ") - HELP_TEXT ("******* ******* * ") - HELP_TEXT (" ***** * * * * ") - HELP_TEXT (" *** * ") - HELP_TEXT (" * * * * ") - HELP_TEXT (" ") - HELP_TEXT ("Diamond Random Horiz. Vertical") - HELP_TEXT (" bar bar ") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TEXT (" * * * * *") - HELP_TEXT (" * * * * *") - HELP_TEXT (" * * * * *") - HELP_TEXT (" * * * *******") - HELP_TEXT (" * * * * *") - HELP_TEXT (" * * * * *") - HELP_TEXT ("* * * * *") - HELP_TEXT ("") - HELP_TEXT (" Slash Back- Cross X Cross +") - HELP_TEXT (" slash") - HELP_TEXT ("") - HELP_TEXT ("When using one of these, you can change the") - HELP_TEXT ("brush size by using the keys:") - HELP_LINK ("Reduce : %s", SPECIAL_SMALLER_PAINTBRUSH) - HELP_LINK ("Increase : %s", SPECIAL_BIGGER_PAINTBRUSH) - HELP_TEXT ("The last 3 paintbrushes in the menu belong") - HELP_TEXT ("to the \"miscellaneous\" family and their size") - HELP_TEXT ("cannot be modified.") - HELP_TEXT ("") - HELP_BOLD (" RIGHT CLICK ") - HELP_LINK ("(Key:%s)",0x200+BUTTON_PAINTBRUSHES) - HELP_TEXT ("") - HELP_TEXT ("Transforms your current user-defined brush") - HELP_TEXT ("into a paintbrush. This is actually a") - HELP_TEXT ("\"monochromisation\" of your user-defined") - HELP_TEXT ("brush. This means that every color of the") - HELP_TEXT ("brush that aren't the Back-color will be") - HELP_TEXT ("set to the Fore-color. But this option") - HELP_TEXT ("doesn't alter the brush: you'll just have") - HELP_TEXT ("to right-click on the \"Get brush\" buttons") - HELP_TEXT ("to get your brush back.") - HELP_TEXT ("") - HELP_TEXT ("Note: When you press (not in the menu) the") - HELP_LINK ("key %s, the current",SPECIAL_DOT_PAINTBRUSH) - HELP_TEXT ("paintbrush becomes the smallest member of") - HELP_TEXT ("the \"Disc\" family: i.e one pixel.") - -}; -static const T_Help_table helptable_adjust[] = -{ - HELP_TITLE("ADJUST OR TRANSFORM") - HELP_TITLE(" PICTURE") - HELP_TEXT ("") - HELP_BOLD (" LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_ADJUST) - HELP_TEXT ("") - HELP_TEXT ("Allows you to scroll the picture to") - HELP_TEXT ("re-center your graph for example.") - HELP_TEXT ("") - HELP_TEXT ("Any part of the picture that goes out of") - HELP_TEXT ("the image by a side comes back by the") - HELP_TEXT ("opposite one.") - HELP_TEXT ("") - HELP_TEXT ("It is assimilated to the drawing tools") - HELP_TEXT ("family.") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_BOLD (" RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_ADJUST) - HELP_TEXT ("") - HELP_TEXT ("Opens the Picture Transform menu.") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE("PICTURE TRANSFORM") - HELP_TEXT ("") - HELP_BOLD ("RESCALE") - HELP_TEXT ("") - HELP_TEXT ("Allows you to change the image's size,") - HELP_TEXT ("rescaling it accordingly. Enter new size") - HELP_TEXT ("and press RESIZE to confirm.") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TEXT ("When 'Lock proportions' is checked and you") - HELP_TEXT ("change one dimension, the other one is") - HELP_TEXT ("automatically adjusted to preserve the") - HELP_TEXT ("proportions of the original image.") - HELP_TEXT ("") - HELP_TEXT ("You can use the dropdown button to choose") - HELP_TEXT ("between three ways to enter the dimensions:") - HELP_TEXT ("") - HELP_TEXT ("In 'Pixels' mode, the column 'old' shows") - HELP_TEXT ("the original dimensions, and you can set") - HELP_TEXT ("the new size in pixels.") - HELP_TEXT ("") - HELP_TEXT ("In 'Percent' mode, you set a percentage") - HELP_TEXT ("compared to the original image.") - HELP_TEXT ("") - HELP_TEXT ("In 'Ratio' mode, you can set 2 numbers for") - HELP_TEXT ("each dimension, and the resizing factor will") - HELP_TEXT ("be of 'new'÷'old'. For example you can use") - HELP_TEXT ("1:3 to divide the image by three, 2:1 to") - HELP_TEXT ("double it, and any fraction like 15:16.") - HELP_TEXT ("") - HELP_TEXT ("Be careful that moving from one mode to the") - HELP_TEXT ("next can lose precision, if the selected") - HELP_TEXT ("dimensions cannot be represented exactly in") - HELP_TEXT ("the new mode.") - HELP_TEXT ("") - HELP_BOLD ("MIRROR") - HELP_TEXT ("") - HELP_TEXT ("- X: Flip the picture horizontally.") - HELP_TEXT ("") - HELP_TEXT ("- Y: Flip the picture vertically.") - HELP_TEXT ("") - HELP_BOLD ("ROTATE") - HELP_TEXT ("") - HELP_TEXT ("-90°: Rotates the image by 90°") - HELP_TEXT (" clockwise.") - HELP_TEXT ("") - HELP_TEXT ("+90°: Rotates the image by 90°") - HELP_TEXT (" counter-clockwise.") - HELP_TEXT ("180°: Rotates the image by 180°") - HELP_TEXT ("") - HELP_TEXT ("") -}; -static const T_Help_table helptable_draw[] = -{ - HELP_TITLE("HAND-DRAWING") - HELP_TEXT ("") - HELP_BOLD (" LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_DRAW) - HELP_TEXT ("") - HELP_TEXT ("Selects the current hand-drawing mode as the") - HELP_TEXT ("active drawing tool. There are 4") - HELP_TEXT ("hand-drawing modes:") - HELP_TEXT ("") - HELP_TEXT ("Continuous hand-drawing: as you move the") - HELP_TEXT ("mouse, the paintbrush is regularily pasted") - HELP_TEXT ("on the picture. This drawing tool allows to") - HELP_TEXT ("change the fore and back colors when being") - HELP_TEXT ("in use.") - HELP_TEXT ("") - HELP_TEXT ("Discontinuous hand-drawing: as you move the") - HELP_TEXT ("mouse, the paintbrush is pasted on the") - HELP_TEXT ("picture every time a delay is passed") - HELP_TEXT ("(actually, the delay is 1 VBL") - HELP_TEXT ("(vertical blanking)). This drawing tool") - HELP_TEXT ("allows to change the fore and back colors") - HELP_TEXT ("when being in use.") - HELP_TEXT ("") - HELP_TEXT ("Dot by dot hand-drawing: the paintbrush is") - HELP_TEXT ("only pasted at the position where you first") - HELP_TEXT ("clicked.") - HELP_TEXT ("") - HELP_TEXT ("Contour fill: Draws pixels like continuous") - HELP_TEXT ("mode, but when you release the button Grafx2") - HELP_TEXT ("draws a line back to your starting position,") - HELP_TEXT ("and fills the area. This tool doesn't use the") - HELP_TEXT ("current brush, but single pixels.") - HELP_TEXT ("") - HELP_BOLD (" RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_DRAW) - HELP_TEXT ("") - HELP_TEXT ("Toggles the different hand-drawing modes") - HELP_TEXT ("and activates, at the same time, the") - HELP_TEXT ("hand-drawing tool.") -}; -static const T_Help_table helptable_curves[] = -{ - HELP_TITLE("SPLINES") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_CURVES) - HELP_TEXT ("") - HELP_TEXT ("Selects the current curve-drawing mode as") - HELP_TEXT ("the active drawing tool. There are 2") - HELP_TEXT ("different curve-drawing modes:") - HELP_TEXT ("") - HELP_TEXT ("* 4 control points curves: define the basic") - HELP_TEXT ("line like a classical line, then move, with") - HELP_TEXT ("the left mouse button, the inner control") - HELP_TEXT ("points to choose the shape of your curve.") - HELP_TEXT ("When the curve has the shape you want, click") - HELP_TEXT ("with the right mouse button to draw it") - HELP_TEXT ("definitively.") - HELP_TEXT ("") - HELP_TEXT ("* 3 control points curves: the same as") - HELP_TEXT ("above, but you'll have only one inner") - HELP_TEXT ("control point to place. Moreover, the spline") - HELP_TEXT ("will be traced just after placing this") - HELP_TEXT ("point.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_CURVES) - HELP_TEXT ("") - HELP_TEXT ("Toggles the different curve-drawing modes") - HELP_TEXT ("and activates, at the same time, the") - HELP_TEXT ("curve-drawing tool.") -}; -static const T_Help_table helptable_lines[] = -{ - HELP_TITLE("LINES") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_LINES) - HELP_TEXT ("") - HELP_TEXT ("Selects the current line-drawing mode as the") - HELP_TEXT ("active drawing tool. There are 3") - HELP_TEXT ("line-drawing modes:") - HELP_TEXT ("") - HELP_TEXT ("* Classical lines: when first clicking on") - HELP_TEXT ("the picture, you'll define the start of the") - HELP_TEXT ("line. Maintain your click to choose the end") - HELP_TEXT ("of the line and release the mouse button to") - HELP_TEXT ("set it.") - HELP_TEXT ("If you hold SHIFT when drawing, the line") - HELP_TEXT ("will be constrained to horizonal, vertical") - HELP_TEXT ("or diagonal.") - HELP_TEXT ("") - HELP_TEXT ("* Knotted lines: works like classical lines,") - HELP_TEXT ("but the end of your line will automatically") - HELP_TEXT ("become the start of the next one. When you") - HELP_TEXT ("want to stop chaining lines, use the") - HELP_TEXT ("opposite mouse button. \"The opposite button\"") - HELP_TEXT ("means that if you started to draw lignes") - HELP_TEXT ("with the left button (Fore-color), you'll") - HELP_TEXT ("have to stop the procedure with the right") - HELP_TEXT ("button; and conversely.") - HELP_TEXT ("") - HELP_TEXT ("* Concentric lines: when first clicking on") - HELP_TEXT ("the picture, you'll define center of the") - HELP_TEXT ("lines. In fact, the center is defined by the") - HELP_TEXT ("the position of the mouse when you release") - HELP_TEXT ("the mouse button. Then you can draw lines") - HELP_TEXT ("from the center to the current mouse") - HELP_TEXT ("position by clicking. To stop drawing") - HELP_TEXT ("concentric lines, use the opposite mouse") - HELP_TEXT ("button. This drawing tool allows to change") - HELP_TEXT ("the fore and back colors when being in use.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_LINES) - HELP_TEXT ("") - HELP_TEXT ("Toggles the different line-drawing modes and") - HELP_TEXT ("activates, at the same time, the") - HELP_TEXT ("line-drawing tool.") - -}; -static const T_Help_table helptable_airbrush[] = -{ - HELP_TITLE("SPRAY") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_AIRBRUSH) - HELP_TEXT ("") - HELP_TEXT ("Selects the spray as the active drawing") - HELP_TEXT ("tool. This drawing tool allows to change the") - HELP_TEXT ("fore and back colors when being in use.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_AIRBRUSH) - HELP_TEXT ("") - HELP_TEXT ("Displays a menu where you can configure the") - HELP_TEXT ("spray:") - HELP_TEXT ("") - HELP_TEXT ("- Size: Defines the diameter of the circle") - HELP_TEXT ("in which will effectively fit the spray.") - HELP_TEXT ("") - HELP_TEXT ("- Delay: Defines the number of VBLs that") - HELP_TEXT ("will be waited for between two flows of") - HELP_TEXT ("spray.") - HELP_TEXT ("") - HELP_TEXT ("- Mode: Defines whether you want to use a") - HELP_TEXT ("monochrome spray or a multi- colored one.") - HELP_TEXT ("") - HELP_TEXT ("- Mono-flow: Defines the number of") - HELP_TEXT ("paintbrushes that will be pasted in the") - HELP_TEXT ("circle of the spray at each cycle.") - HELP_TEXT ("") - HELP_TEXT ("- Palette: Left-click on a color of the") - HELP_TEXT ("palette to see how much it will be used in") - HELP_TEXT ("the multicolored flow, and modify it by") - HELP_TEXT ("using the gauge on the right. If the flow of") - HELP_TEXT ("this color was equal to 0, then the \"Init\"") - HELP_TEXT ("value will be applied. Or set the flow of a") - HELP_TEXT ("color to 0 by clicking on it with the right") - HELP_TEXT ("mouse button.") - HELP_TEXT ("") - HELP_TEXT ("- Clear: Removes all the colors from the") - HELP_TEXT ("multicolored flow. Actually, this puts a 0") - HELP_TEXT ("value in the use of each color.") - HELP_TEXT ("") - HELP_TEXT ("- Init: Allows you to define a value that") - HELP_TEXT ("will be set to the color you click on in the") - HELP_TEXT ("palette if its value is equal to 0. This") - HELP_TEXT ("permits to tag a set of colors more quickly.") - HELP_TEXT ("") - HELP_TEXT ("- +1,-1,x2,/2: Modify the values of all the") - HELP_TEXT ("tagged colors (and only them).") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TEXT ("Tip: If you often use the Shade mode, and") - HELP_TEXT ("are bored to click many times on a color to") - HELP_TEXT ("reach the color you want, you can define a") - HELP_TEXT ("spray with \"Size\"=1, \"Mono-flow\"=1, and") - HELP_TEXT ("\"Delay\"=2 (or more, according to your") - HELP_TEXT ("reflexes). And then, you'll just have to") - HELP_TEXT ("click a few hundredths of second to modify a") - HELP_TEXT ("color.") -}; -static const T_Help_table helptable_floodfill[] = -{ - HELP_TITLE("FLOODFILL") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_FLOODFILL) - HELP_TEXT ("") - HELP_TEXT ("Selects the filler as the active drawing") - HELP_TEXT ("tool. The filler, as any drawing tool, will") - HELP_TEXT ("be affected by all the effects!") - HELP_TEXT ("") - HELP_TEXT ("Note that only the visible part of the") - HELP_TEXT ("picture will be filled (as every other") - HELP_TEXT ("drawing tools, the floodfill only alters the") - HELP_TEXT ("visible part of the picture; this avoids") - HELP_TEXT ("unwanted effects that wouldn't be controlled") - HELP_TEXT ("by the user).") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_FLOODFILL) - HELP_TEXT ("") - HELP_TEXT ("Selects the color replacement as the active") - HELP_TEXT ("drawing tool.") - HELP_TEXT ("") - HELP_TEXT ("Any rule has its exceptions and this one") - HELP_TEXT ("doesn't depart from that. Indeed, this tool") - HELP_TEXT ("is the only one to be affected by no effect") - HELP_TEXT ("(except Stencil) and to be able to modify") - HELP_TEXT ("non visible parts of the picture.") - HELP_TEXT ("The function of this tool being replacing") - HELP_TEXT ("all the occurences of a color in the picture") - HELP_TEXT ("by another, if would have been a shame to") - HELP_TEXT ("limit modifications only to the visible part") - HELP_TEXT ("of the picture.") -}; -static const T_Help_table helptable_polygons[] = -{ - HELP_TITLE("POLYGONS") - HELP_TITLE("POLYFORMS") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_POLYGONS) - HELP_TEXT ("") - HELP_TEXT ("Selects the polygons as the active drawing") - HELP_TEXT ("tool.") - HELP_TEXT ("") - HELP_TEXT ("This works just like knotted-lines but loops") - HELP_TEXT ("the extremities when you're finished.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_POLYGONS) - HELP_TEXT ("") - HELP_TEXT ("Selects the polyforms as the active drawing") - HELP_TEXT ("tool.") - HELP_TEXT ("") - HELP_TEXT ("This works like a combination of free-hand") - HELP_TEXT ("drawing and knotted-lines. If you keep the") - HELP_TEXT ("mouse button pressed, you'll draw as if you") - HELP_TEXT ("were in free-hand drawing mode. And, if you") - HELP_TEXT ("release the mouse button, it will work like") - HELP_TEXT ("knotted lines.") - HELP_TEXT ("") - HELP_TEXT ("Click on the opposite mouse button (i.e.:") - HELP_TEXT ("click right if you started to draw with the") - HELP_TEXT ("left mouse button, and vice versa) to") - HELP_TEXT ("terminate the operation. The two extremities") - HELP_TEXT ("will be linked automatically.") -}; -static const T_Help_table helptable_polyfill[] = -{ - HELP_TITLE("FILLED POLY") - HELP_LINK ("(Key:%s)",0x100+BUTTON_POLYFILL) - HELP_LINK ("(Key:%s)",0x200+BUTTON_POLYFILL) - HELP_TEXT (" Work exactly the same way as the polygons") - HELP_TEXT ("et polyforms above, but fill in the interior") - HELP_TEXT ("of the drawn shapes.") -}; -static const T_Help_table helptable_rectangles[] = -{ - HELP_TITLE("RECTANGLES") - HELP_LINK ("(Key:%s)",0x100+BUTTON_RECTANGLES) - HELP_TEXT ("") - HELP_TEXT ("Selects the empty rectangles as the active") - HELP_TEXT ("drawing tool.") - HELP_TEXT ("") - HELP_TEXT ("Set a corner of a rectangle. Maintain the") - HELP_TEXT ("click to move the opposite corner and") - HELP_TEXT ("release the mouse button to set it") - HELP_TEXT ("definitively.") -}; -static const T_Help_table helptable_filled_rectangles[] = -{ - HELP_TITLE("FILLED RECT") - HELP_LINK ("(Key:%s)",0x100+BUTTON_FILLRECT) - HELP_TEXT ("") - HELP_TEXT ("Selects the filled rectangles as the active") - HELP_TEXT ("drawing tool.") - HELP_TEXT ("") - HELP_TEXT ("Works like an empty rectangle.") -}; -static const T_Help_table helptable_circles[] = -{ - HELP_TITLE("CIRCLES") - HELP_TITLE("ELLIPSES") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_CIRCLES) - HELP_TEXT ("") - HELP_TEXT ("Selects the empty circles as the active") - HELP_TEXT ("drawing tool.") - HELP_TEXT ("") - HELP_TEXT ("Position the center of the cercle and") - HELP_TEXT ("maintain the mouse button to select its") - HELP_TEXT ("radius.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_CIRCLES) - HELP_TEXT ("") - HELP_TEXT ("Selects the empty ellipses as the active") - HELP_TEXT ("drawing tool.") - HELP_TEXT ("") - HELP_TEXT ("Position the center of the cercle and") - HELP_TEXT ("maintain the mouse button to select its") - HELP_TEXT ("dimensions.") -}; -static const T_Help_table helptable_filled_circles[] = -{ - HELP_TITLE("FILLED CIRCLES") - HELP_TITLE(" AND ELLIPSES") - HELP_TEXT ("") - HELP_BOLD ("FILLED CIRCLES") - HELP_LINK ("(Key:%s)",0x100+BUTTON_CIRCLES) - HELP_TEXT ("") - HELP_TEXT ("Works like empty circles.") - HELP_TEXT ("") - HELP_BOLD ("FILLED ELLIPSES") - HELP_LINK ("(Key:%s)",0x200+BUTTON_CIRCLES) - HELP_TEXT ("") - HELP_TEXT ("Works like empty ellipses.") -}; -static const T_Help_table helptable_grad_rect[] = -{ - HELP_TITLE("GRAD RECTANGLE") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_GRADRECT) - HELP_TEXT ("") - HELP_TEXT ("Selects the rectangle with gradations as") - HELP_TEXT ("the active drawing tool.") - HELP_TEXT ("") - HELP_TEXT ("Set a corner of a rectangle. Maintain the") - HELP_TEXT ("click to move the opposite corner and") - HELP_TEXT ("release the mouse button to set it") - HELP_TEXT ("definitively.") - HELP_TEXT ("") - HELP_TEXT ("If you don't like what you have done and") - HELP_TEXT ("want to restart, you can use the right") - HELP_TEXT ("click to cancel everything at this point.") - HELP_TEXT (" If you think it's nice, then click and hold") - HELP_TEXT ("the mouse in a point you want to have the") - HELP_TEXT ("starting color, drag to a point where you") - HELP_TEXT ("want the ending color, and release the") - HELP_TEXT ("button. You can press SHIFT to enforce your") - HELP_TEXT ("line to be vertical, horizontal, or") - HELP_TEXT ("diagonal.") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_GRADRECT) - HELP_TEXT ("") - HELP_TEXT ("Opens a window where you can define the way") - HELP_TEXT ("gradations are processed. The different") - HELP_TEXT ("sections of this menu are:") - HELP_TEXT ("") - HELP_TEXT ("- Direction (arrow): Switches the direction") - HELP_TEXT ("of the gradation.") - HELP_TEXT ("") - HELP_TEXT ("- Dithering method: Toggles the 3 following") - HELP_TEXT ("methods:") - HELP_TEXT (" - No dithering") - HELP_TEXT (" - Basical dithering") - HELP_TEXT (" - Enhanced dithering") - HELP_TEXT ("") - HELP_TEXT ("- Mix: Mixes the gradation with a more or") - HELP_TEXT ("less random factor.") - HELP_TEXT ("") - HELP_TEXT ("- Palette: Select a color range to build a") - HELP_TEXT ("gradation.") - HELP_TEXT ("") - HELP_TEXT ("- Index scroller: Defines the current") - HELP_TEXT ("gradation among a set of 16 that will be") - HELP_TEXT ("memorised.") -}; -static const T_Help_table helptable_spheres[] = -{ - HELP_TITLE("GRAD SPHERE") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_SPHERES) - HELP_TEXT ("") - HELP_TEXT ("Selects the spheres as the active drawing") - HELP_TEXT ("tool.") - HELP_TEXT ("") - HELP_TEXT ("Position the center of the sphere and") - HELP_TEXT ("maintain the mouse button to select its") - HELP_TEXT ("radius. Then place the spot-light.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_SPHERES) - HELP_TEXT ("") - HELP_TEXT ("Selects the ellipses with gradation as the") - HELP_TEXT ("active drawing tool.") - HELP_TEXT ("") - HELP_TEXT ("Draw the shape like a normal ellipse, and") - HELP_TEXT ("then position the spot-light and click the") - HELP_TEXT ("left mouse button to finish the shape.") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TEXT ("If you trace a sphere or an ellipse with") - HELP_TEXT ("gradation with the right mouse button, the") - HELP_TEXT ("result will be the same figure filled with") - HELP_TEXT ("the Back-color.") -}; -static const T_Help_table helptable_brush[] = -{ - HELP_TITLE("GRAB BRUSH") - HELP_BOLD (" OR RESTORE BRUSH") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_BRUSH) - HELP_TEXT ("") - HELP_TEXT ("Engages a brush grabbing.") - HELP_TEXT ("") - HELP_TEXT ("Click on a corner of the rectangle") - HELP_TEXT ("containing the brush then maintain the click") - HELP_TEXT ("to define the opposite corner of the") - HELP_TEXT ("rectangle. Release the mouse button to grab") - HELP_TEXT ("the brush. Performing this operation with") - HELP_TEXT ("the right mouse button will erase the area") - HELP_TEXT ("where the brush was grabbed with the") - HELP_TEXT ("Back-color.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_BRUSH) - HELP_TEXT ("") - HELP_TEXT ("Restores the old brush.") -}; -static const T_Help_table helptable_polybrush[] = -{ - HELP_TITLE("POLY GRAB") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_POLYBRUSH) - HELP_TEXT ("") - HELP_TEXT ("Grabs a brush of any shape by defining a") - HELP_TEXT ("polyform (please refer to section 8 for more") - HELP_TEXT ("explanations).") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_BRUSH) - HELP_TEXT ("") - HELP_TEXT ("Restores the old brush (same as above).") -}; -static const T_Help_table helptable_brush_fx[] = -{ - HELP_TITLE("BRUSH FX") - HELP_TEXT ("") - HELP_LINK ("(Key:%s)",0x100+BUTTON_BRUSH_EFFECTS) - HELP_TEXT ("") - HELP_TEXT ("Displays a menu where the following options") - HELP_TEXT ("are available:") - HELP_TEXT ("") - HELP_LINK ("- X: (Key:%s)",SPECIAL_FLIP_X) - HELP_TEXT ("Flip horizontally.") - HELP_TEXT ("") - HELP_LINK ("- Y: (Key:%s)",SPECIAL_FLIP_Y) - HELP_TEXT ("Flip vertically.") - HELP_TEXT ("") - HELP_LINK ("- Rotate by 90°: (Key:%s)",SPECIAL_ROTATE_90) - HELP_TEXT ("Rotates the brush by an angle of 90 degrees.") - HELP_TEXT ("") - HELP_LINK ("- Rotate by 180°: (Key:%s)",SPECIAL_ROTATE_180) - HELP_TEXT ("Rotates the brush by an angle of 180") - HELP_TEXT ("degrees.") - HELP_TEXT ("") - HELP_TEXT ("- Rotate by any angle:") - HELP_LINK ("(Key:%s)",SPECIAL_ROTATE_ANY_ANGLE) - HELP_TEXT ("Triggers an interactive operation that") - HELP_TEXT ("allows you to rotate the brush. For this,") - HELP_TEXT ("start by placing the center or rotation with") - HELP_TEXT ("the left mouse button (if, at this moment,") - HELP_TEXT ("you press the right button, the operation") - HELP_TEXT ("with be cancelled). After that, you can") - HELP_TEXT ("define the angle of rotation as many times") - HELP_TEXT ("as you want by moving the mouse and") - HELP_TEXT ("left-clicking. Then validate with the right") - HELP_TEXT ("button when you are satisfied. Meanwhile,") - HELP_TEXT ("you can press on the 8 outer digits of the") - HELP_TEXT ("numeric pad for defining angles multiple of") - HELP_TEXT ("45 degrees:") - HELP_TEXT ("") - HELP_TEXT (" 135 90 45") - HELP_TEXT (" \\ | /") - HELP_TEXT (" '7' '8' '9'") - HELP_TEXT (" 180 -'4' '6'- 0") - HELP_TEXT (" '1' '2' '3'") - HELP_TEXT (" / | \\") - HELP_TEXT (" 225 270 315") - HELP_TEXT ("") - HELP_LINK ("- Stretch: (Key:%s)",SPECIAL_STRETCH) - HELP_TEXT ("Triggers an interactive operation") - HELP_TEXT ("that enables you to stretch the brush. For") - HELP_TEXT ("this, start by placing the upper-left") - HELP_TEXT ("cornerof the brush with the left mouse") - HELP_TEXT ("button (if, at this moment, you press the") - HELP_TEXT ("right button, the operation will be") - HELP_TEXT ("cancelled). after that, you can place the") - HELP_TEXT ("opposite corner as many times as you need,") - HELP_TEXT ("then validate with the right mouse button") - HELP_TEXT ("when you are satisfied. If you place this") - HELP_TEXT ("point at coordinates inferior to the ones of") - HELP_TEXT ("the first point, the brush will be inverted.") - HELP_TEXT ("Meanwhile, you can press the following keys") - HELP_TEXT ("whose effects are: 'D' : double the") - HELP_TEXT ("brush in X and Y 'H' : reduce the") - HELP_TEXT ("brush by half in X and Y 'X' : double") - HELP_TEXT ("the brush in X 'Shift+X': reduce the brush") - HELP_TEXT ("by half in X 'Y' : double the brush") - HELP_TEXT ("in Y 'Shift+Y': reduce the brush by half") - HELP_TEXT ("in Y 'N' : restore the normal size of") - HELP_TEXT ("the brush (can be useful") - HELP_TEXT ("because it's the only way for cancelling)") - HELP_TEXT ("") - HELP_LINK ("- Distort: (Key:%s)",SPECIAL_DISTORT) - HELP_TEXT ("Triggers an interactive operation") - HELP_TEXT ("that allows you to distort your brush.") - HELP_TEXT ("Start by placing the brush somewhere on the") - HELP_TEXT ("screen and left-click. The brush will") - HELP_TEXT ("appear, with a little peg at each corner.") - HELP_TEXT ("Use the left mouse button to displace the") - HELP_TEXT ("corners, which will deform the brush.") - HELP_TEXT ("When you're done, click the right mouse") - HELP_TEXT ("button.") - HELP_TEXT ("") - HELP_LINK ("- Outline: (Key:%s)",SPECIAL_OUTLINE) - HELP_TEXT ("This option permits to draw the") - HELP_TEXT ("outlines of the brush with the Fore- color.") - HELP_TEXT ("") - HELP_LINK ("- Nibble: (Key:%s)",SPECIAL_NIBBLE) - HELP_TEXT ("This option \"nibbles\" the outlines") - HELP_TEXT ("of the brush. It's in some way the opposite") - HELP_TEXT ("effect of the Outline option.") - HELP_TEXT ("") - HELP_LINK ("- Recolorize: (Key:%s)",SPECIAL_RECOLORIZE_BRUSH) - HELP_TEXT ("Remaps the brush so that it") - HELP_TEXT ("looks like it would in the spare page, using") - HELP_TEXT ("the current palette.") - HELP_TEXT ("") - HELP_LINK ("- Get brush colors: (Key:%s)",SPECIAL_GET_BRUSH_COLORS) - HELP_TEXT ("Transfers the spare") - HELP_TEXT ("page's colors used by the brush to the") - HELP_TEXT ("current palette.") - HELP_TEXT ("") - HELP_TEXT ("- Brush handle:") - HELP_TEXT ("Allows you to choose where to place the") - HELP_TEXT ("handle of the brush. Shortcuts are :") - HELP_LINK (" Center : %s", SPECIAL_CENTER_ATTACHMENT) - HELP_LINK (" Top-left : %s", SPECIAL_TOP_LEFT_ATTACHMENT) - HELP_LINK (" Top-right : %s", SPECIAL_TOP_RIGHT_ATTACHMENT) - HELP_LINK (" Bottom-left : %s", SPECIAL_BOTTOM_LEFT_ATTACHMENT) - HELP_LINK (" Bottom-right: %s", SPECIAL_BOTTOM_RIGHT_ATTACHMENT) - HELP_TEXT ("") - HELP_LINK ("- Load : (Key:%s)",SPECIAL_LOAD_BRUSH) - HELP_TEXT ("Load a brush from disk.") - HELP_TEXT ("") - HELP_LINK ("- Save : (Key:%s)",SPECIAL_SAVE_BRUSH) - HELP_TEXT ("Save a brush to disk.") -}; -static const T_Help_table helptable_effects[] = -{ - HELP_TITLE("DRAW MODES") - HELP_LINK ("(Key:%s)",0x100+BUTTON_EFFECTS) - HELP_TEXT ("") - HELP_TEXT (" This button opens a menu where you can") - HELP_TEXT ("switch on or off the different drawing") - HELP_TEXT ("modes.") - HELP_TEXT (" In this menu, the \"All off\" button switches") - HELP_TEXT ("all the drawing modes off. The [Del] key") - HELP_TEXT ("is the keyboard shortcut for this button.") - HELP_TEXT (" The \"Feedback\" button is only used in") - HELP_TEXT ("\"Shade\", \"Quick-shade, \"Transparency\"") - HELP_TEXT ("and \"Smooth\" modes. When it is set, it means") - HELP_TEXT ("that the _current_ state of the picture") - HELP_TEXT ("has to be taken into account for the effect") - HELP_TEXT ("instead of the state in which the image") - HELP_TEXT ("was when you started to click for drawing.") - HELP_TEXT ("The best, as often, is that you try by") - HELP_TEXT ("yourself with and without Feedback to see") - HELP_TEXT ("the difference.") - HELP_TEXT (" The other buttons are the following:") - HELP_TEXT ("") - HELP_TITLE("SHADE") - HELP_TEXT (" It consists in increasing or decreasing the") - HELP_TEXT ("color number within a user-defined range.") - HELP_TEXT ("This shows its real dimension when used with") - HELP_TEXT ("a range of colors that shade off. Then,") - HELP_TEXT ("you can work on a part of your picture where") - HELP_TEXT ("colors belong to the same range without") - HELP_TEXT ("having to change your brush color all the") - HELP_TEXT ("time. You can choose the incrementation or") - HELP_TEXT ("decrementation of the color by pressing") - HELP_TEXT ("the left or right mouse button while") - HELP_TEXT ("drawing. If you click on a color that does") - HELP_TEXT ("not belong to the range, it will remain") - HELP_TEXT ("unchanged.") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key : %s)", SPECIAL_SHADE_MODE) - HELP_TEXT ("") - HELP_TEXT ("Switches the Shade mode.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_SHADE_MENU) - HELP_TEXT ("") - HELP_TEXT ("Opens a menu where you can define one table") - HELP_TEXT ("of shades within a range of 8 memorised by") - HELP_TEXT ("the program. The different sections of this") - HELP_TEXT ("menu are:") - HELP_TEXT ("") - HELP_TEXT ("- Palette: You can define in it the color") - HELP_TEXT ("blocks that will be inserted") - HELP_TEXT ("into the table of shades.") - HELP_TEXT ("") - HELP_TEXT ("- Scroller: Used to change flick through the") - HELP_TEXT ("tables of shades.") - HELP_TEXT ("") - HELP_TEXT ("- Table of shades definition area: The 512") - HELP_TEXT ("squares should be widely") - HELP_TEXT ("sufficient to define the different shades") - HELP_TEXT ("since every 256 colors of") - HELP_TEXT ("the palette cannot be present more than once") - HELP_TEXT ("in each table.") - HELP_TEXT ("") - HELP_TEXT ("- A window (on the top-right side) permits") - HELP_TEXT ("to visualize the different") - HELP_TEXT ("shades defined in he current table.") - HELP_TEXT ("") - HELP_TEXT ("- Copy: Copy the contents of the table in a") - HELP_TEXT ("buffer.") - HELP_TEXT ("(Each time you open this menu, the current") - HELP_TEXT ("table is automatically") - HELP_TEXT ("transfered into this buffer).") - HELP_TEXT ("") - HELP_TEXT ("- Paste: Copy the contents of the buffer") - HELP_TEXT ("above in the current table.") - HELP_TEXT ("") - HELP_TEXT ("- Clear: Reset the \"shades\" table.") - HELP_TEXT ("") - HELP_TEXT ("- Insert: Used to insert the block selected") - HELP_TEXT ("in the palette at the") - HELP_TEXT ("cursor's position in the table of shades.") - HELP_TEXT ("IF you click with the left mouse button on") - HELP_TEXT ("this button THEN IF a block of more than one") - HELP_TEXT ("color is selected in the table THEN It is") - HELP_TEXT ("deleted and the block defined in the palette") - HELP_TEXT ("is inserted. ELSE The block defined in the") - HELP_TEXT ("palette is inserted at the postion just") - HELP_TEXT ("before the selected square. END IF") - HELP_TEXT ("ELSE The block defined in the palette is") - HELP_TEXT ("inserted by erasing the colors following the") - HELP_TEXT ("beginning of the bloc selected in the table.") - HELP_TEXT ("END IF") - HELP_TEXT ("") - HELP_TEXT ("- Delete: Delete the block selected in the") - HELP_TEXT ("table.") - HELP_TEXT ("") - HELP_TEXT ("- Blank: Follows this algorithm:") - HELP_TEXT ("IF you click with the left mouse button on") - HELP_TEXT ("this button THEN Replace the block selected") - HELP_TEXT ("in the table by blank squares.") - HELP_TEXT ("ELSE IF a block of more than one color is") - HELP_TEXT ("selected in the table THEN Insert blank") - HELP_TEXT ("squares to the left and to the right of the") - HELP_TEXT ("block. (this is useful for isolating a") - HELP_TEXT ("shade quickly) ELSE Insert blank squares") - HELP_TEXT ("to the left of the selected square. END IF") - HELP_TEXT ("END IF") - HELP_TEXT ("") - HELP_TEXT ("- Invert: Invert the order of the block") - HELP_TEXT ("selected in the table.") - HELP_TEXT ("") - HELP_TEXT ("- Swap: Allows you you move a block (this") - HELP_TEXT ("exchanges it with what is") - HELP_TEXT ("where you want to move it).") - HELP_TEXT ("") - HELP_TEXT ("- Undo: Cancel the last modification of the") - HELP_TEXT ("table.") - HELP_TEXT ("") - HELP_TEXT ("- The 2 numbers displayed on the right of") - HELP_TEXT ("these buttons are: (above) - the number of") - HELP_TEXT ("the color selected in the palette if only") - HELP_TEXT ("one color is selected. (below) - the number") - HELP_TEXT ("of the color contained in a square in the") - HELP_TEXT ("shades table if this square is the only one") - HELP_TEXT ("selected.") - HELP_TEXT ("") - HELP_TEXT ("- The \"mode\" button displays 3 different") - HELP_TEXT ("modes:") - HELP_TEXT ("\"Normal\": Shades in the range and saturates") - HELP_TEXT ("to its boundaries.") - HELP_TEXT ("\"Loop\": Shades in the range and loops if") - HELP_TEXT ("boundaries are passed.") - HELP_TEXT ("\"No saturation\": Shades in the range and") - HELP_TEXT ("doesn't saturate if boundaries are passed.") - HELP_TEXT ("If the Step (see below) is set to 1, this") - HELP_TEXT ("option does exactly the same as the Normal") - HELP_TEXT ("mode.") - HELP_TEXT ("") - HELP_TEXT ("- Set/Disable: If you want to define several") - HELP_TEXT ("shades in the same table") - HELP_TEXT ("but you'd like these shades not to be") - HELP_TEXT ("effective at the same time, you") - HELP_TEXT ("can mask (disable) some parts of the table") - HELP_TEXT ("so that they will be") - HELP_TEXT ("interpreted a blank squares.") - HELP_TEXT ("To do that, select a block in the table of") - HELP_TEXT ("shades and click on \"Set\".") - HELP_TEXT ("The block will be underlined with a white") - HELP_TEXT ("line; this means that it is") - HELP_TEXT ("disabled.") - HELP_TEXT ("") - HELP_TEXT ("- Clear/Enable: This does exactly the") - HELP_TEXT ("opposite as the button above.") - HELP_TEXT ("") - HELP_TEXT ("- Step: Defines the step of incrementation") - HELP_TEXT ("of the shade. The bigger,") - HELP_TEXT ("the faster you run through the colors of the") - HELP_TEXT ("shade.") - HELP_TEXT ("For example: if the step is 2 and that you") - HELP_TEXT ("have defined a shade with") - HELP_TEXT ("the colors 0,1,4,5,9 and that you click on a") - HELP_TEXT ("pixel of color 1, it will") - HELP_TEXT ("take the value 5 which is 2 positions next") - HELP_TEXT ("in the la table.") - HELP_TEXT ("") - HELP_TEXT ("(We are sorry for these technical") - HELP_TEXT ("considerations quite far from a purely") - HELP_TEXT ("artistic point of view; but know that this") - HELP_TEXT ("effect is really very useful and it is") - HELP_TEXT ("preferable that you understand its whole") - HELP_TEXT ("functionment if you want to fully take") - HELP_TEXT ("advantage of it).") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE("QUICK SHADE") - HELP_TEXT (" This drawing mode has about the same effect") - HELP_TEXT ("as Shade mode's except that it is faster") - HELP_TEXT ("to configurate but a little bit less") - HELP_TEXT ("powerful. When you draw on a color of the") - HELP_TEXT ("image which is between the fore- and the") - HELP_TEXT ("back-color in the palette, the color tends") - HELP_TEXT ("towards the fore-color (according to the") - HELP_TEXT ("step defined) if you draw with the left") - HELP_TEXT ("mouse button, or it tends towards the") - HELP_TEXT ("back-color if you are using the right mouse") - HELP_TEXT ("button.") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_QUICK_SHADE_MODE) - HELP_TEXT ("") - HELP_TEXT ("Switches the Quick-shade mode.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_QUICK_SHADE_MENU) - HELP_TEXT ("") - HELP_TEXT ("Opens a menu with a few parameters that mean") - HELP_TEXT ("exactly the same as in the menu of Shade") - HELP_TEXT ("mode. These parameters are the step and the") - HELP_TEXT ("loop/satu- ration mode (normal, loop, no") - HELP_TEXT ("saturation).") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE("STENCIL") - HELP_TEXT (" It is used to prevent some colors from") - HELP_TEXT ("being modified if you draw on them. The") - HELP_TEXT ("main application of the stencil is when you") - HELP_TEXT ("want to change one color or more into") - HELP_TEXT ("another.") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_STENCIL_MODE) - HELP_TEXT ("") - HELP_TEXT ("Switches the Stencil mode.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_STENCIL_MENU) - HELP_TEXT ("") - HELP_TEXT ("Opens a menu where you can define a stencil.") - HELP_TEXT ("The different sections of this menu are:") - HELP_TEXT ("") - HELP_TEXT ("- Clear: No color is protected.") - HELP_TEXT ("") - HELP_TEXT ("- Invert: Colors that were protected are") - HELP_TEXT ("unprotected and vice versa.") - HELP_TEXT ("") - HELP_TEXT ("- Palette: Select colors that should be") - HELP_TEXT ("protected with the left mouse button or") - HELP_TEXT ("unprotect colors with the right mouse") - HELP_TEXT ("button.") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE("MASK") - HELP_TEXT (" This effect could have been called \"True") - HELP_TEXT ("stencil\" because it protects some parts of") - HELP_TEXT ("the picture instead of some colors. The") - HELP_TEXT ("colors you tag represent the pixels in the") - HELP_TEXT ("spare page, corresponding to the pixels in") - HELP_TEXT ("the current page, that you don't want to") - HELP_TEXT ("alter. For example, draw a simple white") - HELP_TEXT ("figure on a black background in the spare") - HELP_TEXT ("page. Then, tag the black color in the menu") - HELP_TEXT ("of the Mask mode. When you'll draw in the") - HELP_TEXT ("current page, only the pixels corresponding") - HELP_TEXT ("to the white (non-black) ones in the spare") - HELP_TEXT ("page will be modified.") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_MASK_MODE) - HELP_TEXT ("") - HELP_TEXT ("Switches the Mask mode.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_MASK_MENU) - HELP_TEXT ("") - HELP_TEXT ("Opens a menu where you can set the colors of") - HELP_TEXT ("the Mask.") - HELP_TEXT ("This menu works the same way as the one of") - HELP_TEXT ("the Stencil, so please refer to the Stencil") - HELP_TEXT ("paragraph to know how to use it.") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE("GRID") - HELP_TEXT (" This is useful to snap the cursor to the") - HELP_TEXT ("cross-points of a grid. It's generally") - HELP_TEXT ("used to draw a grid before drawing sprites") - HELP_TEXT ("of the same size such as a font or tiles,") - HELP_TEXT ("or for drawing figures or grabbing brushes") - HELP_TEXT ("with their dimensions multiple of the step") - HELP_TEXT ("of the grid.');") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_GRID_MODE) - HELP_TEXT ("") - HELP_TEXT ("Switches the Grid mode.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_GRID_MENU) - HELP_TEXT ("") - HELP_TEXT ("Opens a menu where you can define the grid") - HELP_TEXT ("parameters. These parameters are:") - HELP_TEXT ("") - HELP_TEXT ("- X,Y: Steps of the grid.") - HELP_TEXT ("") - HELP_TEXT ("- dX,dY: Offsets of the grid.") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE("SIEVE") - HELP_TEXT (" This effect allows you, by defining a") - HELP_TEXT ("pattern, to draw only on particular points") - HELP_TEXT ("of the picture. If you are a Manga drawer,") - HELP_TEXT ("you might find this useful to make patterned") - HELP_TEXT ("shades or color transitions.") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_SIEVE_MODE) - HELP_TEXT ("") - HELP_TEXT ("Switches the Sieve mode.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_SIEVE_MENU) - HELP_TEXT ("") - HELP_TEXT ("Opens a menu where you can define the Sieve") - HELP_TEXT ("parameters. This menu consists in:") - HELP_TEXT ("") - HELP_TEXT ("- 16x16 drawing area: You can define a") - HELP_TEXT ("pattern in it (left click => white pixel /") - HELP_TEXT ("right click => black pixel). All the white") - HELP_TEXT ("pixels indicate that, when you'll draw,") - HELP_TEXT ("pixels will be applied on the picture at the") - HELP_TEXT ("corresponding positions whereas black pixels") - HELP_TEXT ("won't modify the picture: whites pixels are") - HELP_TEXT ("the \"holes of the sieve\".") - HELP_TEXT ("") - HELP_TEXT ("- 12 default patterns: They can be copied to") - HELP_TEXT ("the drawing area.") - HELP_TEXT ("") - HELP_TEXT ("- \"Transfer to brush\": Copies the pattern to") - HELP_TEXT ("the brush (white pixels => Fore-color /") - HELP_TEXT ("black pixels => Back-color).") - HELP_TEXT ("") - HELP_TEXT ("- \"Get from brush\": Puts the brush into the") - HELP_TEXT ("drawing area (back-color => black pixels /") - HELP_TEXT ("others => white pixels).") - HELP_TEXT ("") - HELP_TEXT ("- Scrolling 4-arrows pad: Scrolls the") - HELP_TEXT ("pattern in the drawing area.") - HELP_TEXT ("") - HELP_TEXT ("- Resizing 4-arrows pad: Defines the") - HELP_TEXT ("dimensions of the pattern.") - HELP_TEXT ("") - HELP_TEXT ("- Default-value (black or white square):") - HELP_TEXT ("Indicates which value must be inserted when") - HELP_TEXT ("you increase the dimensions of the pattern.") - HELP_TEXT ("") - HELP_TEXT ("- \"Clear\": Sets the whole pattern with the") - HELP_TEXT ("default value (see above).") - HELP_TEXT ("") - HELP_TEXT ("- \"Invert\": It... inverts :) ... black and") - HELP_TEXT ("white pixels.") - HELP_LINK ("(Key: %s)", SPECIAL_INVERT_SIEVE) - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE("TRANSPARENCY") - HELP_TEXT (" This allows to mix the color(s) of the") - HELP_TEXT ("paintbrush with the colors of the picture.") - HELP_TEXT ("It's used to make transparency effects like") - HELP_TEXT ("with watercolors.") - HELP_TEXT ("") - HELP_TEXT ("You can also use the following shortcuts to") - HELP_TEXT ("activate transparency mode and assign an") - HELP_TEXT ("amount of opacity:") - HELP_LINK (" 10%% : %s", SPECIAL_TRANSPARENCY_1) - HELP_LINK (" 20%% : %s", SPECIAL_TRANSPARENCY_2) - HELP_LINK (" 30%% : %s", SPECIAL_TRANSPARENCY_3) - HELP_LINK (" 40%% : %s", SPECIAL_TRANSPARENCY_4) - HELP_LINK (" 50%% : %s", SPECIAL_TRANSPARENCY_5) - HELP_LINK (" 60%% : %s", SPECIAL_TRANSPARENCY_6) - HELP_LINK (" 70%% : %s", SPECIAL_TRANSPARENCY_7) - HELP_LINK (" 80%% : %s", SPECIAL_TRANSPARENCY_8) - HELP_LINK (" 90%% : %s", SPECIAL_TRANSPARENCY_9) - HELP_LINK (" 100%% : %s", SPECIAL_TRANSPARENCY_0) - HELP_TEXT ("If you use two of these shortcuts quickly,") - HELP_TEXT ("the second will set the units for finer") - HELP_TEXT ("control. Ie: 4 5 makes 45%, 0 9 makes 9%.") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_COLORIZE_MODE) - HELP_TEXT ("") - HELP_TEXT ("Switches the Transparency mode.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_COLORIZE_MENU) - HELP_TEXT ("") - HELP_TEXT ("Opens a menu where you can define the") - HELP_TEXT ("Transparency parameters. These parameters") - HELP_TEXT ("are:") - HELP_TEXT ("") - HELP_TEXT ("- Interpolation rate: Indicates the") - HELP_TEXT ("percentage of the applied color that will be") - HELP_TEXT ("considered upon the replaced color.") - HELP_TEXT ("") - HELP_TEXT ("- Interpolation method: Uses an") - HELP_TEXT ("interpolation algorithm to compute the") - HELP_TEXT ("color, according to the interpolation rate.") - HELP_TEXT ("") - HELP_TEXT ("- Additive method: Uses the lightest colors") - HELP_TEXT ("to choose the color to apply. For example:") - HELP_TEXT ("if you want to apply a color RGB:30,20,40 on") - HELP_TEXT ("a color RGB:10,50,20, the color applied will") - HELP_TEXT ("be the one, in the palette, that is the") - HELP_TEXT ("closest to the theoretic color RGB:30,50,40.") - HELP_TEXT ("") - HELP_TEXT ("- Subtractive method: uses the darkest") - HELP_TEXT ("colors to choose the color to apply. For") - HELP_TEXT ("example: if you want to apply a color") - HELP_TEXT ("RGB:30,20,40 on a color RGB:10,50,20, the") - HELP_TEXT ("color applied will be the one, in the") - HELP_TEXT ("palette, that is the closest to the") - HELP_TEXT ("theoretic color RGB:10,20,20.") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE("SMOOTH") - HELP_TEXT (" It provides an easy but not as efficient") - HELP_TEXT ("anti-aliasing as any artist's touch.") - HELP_TEXT ("Anyway this effect finds a better use in") - HELP_TEXT ("making a blurry aspect.") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_SMOOTH_MODE) - HELP_TEXT ("") - HELP_TEXT ("Switches the Smooth mode.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_SMOOTH_MENU) - HELP_TEXT ("") - HELP_TEXT ("Opens a menu where you can define the Smooth") - HELP_TEXT ("matrix or choose one among the 4 ones") - HELP_TEXT ("predefined.") - HELP_TEXT ("The middle square represents the pixel on") - HELP_TEXT ("which you draw and the 8 others represent") - HELP_TEXT ("the neighbour pixels. Then, the point on") - HELP_TEXT ("which one draw will be replaced by the") - HELP_TEXT ("weighted average (according to values of") - HELP_TEXT ("each squares) of the 9 defined points.") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE("SMEAR") - HELP_TEXT (" It smears pixels in the direction you are") - HELP_TEXT ("moving your paintbrush, just as if you") - HELP_TEXT ("wanted to spread fresh paint with your") - HELP_TEXT ("fingers. You can combine this effect with") - HELP_TEXT ("the transparency effect.") - HELP_TEXT ("") - HELP_LINK ("(Key: %s)", SPECIAL_SMEAR_MODE) - HELP_TEXT ("Switches the Smear mode.") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TITLE("TILING") - HELP_TEXT (" It consists in displaying parts of the") - HELP_TEXT ("brush that are adjusted on a tiling when") - HELP_TEXT ("you are drawing. It's mainly used for") - HELP_TEXT ("quickly drawing a background with a") - HELP_TEXT ("pattern, but there is a great number of") - HELP_TEXT ("other possibilities.") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_TILING_MODE) - HELP_TEXT ("") - HELP_TEXT ("Switches the Tiling mode.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key: %s)", SPECIAL_TILING_MENU) - HELP_TEXT ("") - HELP_TEXT ("Opens a menu where you can define the Tiling") - HELP_TEXT ("parameters. These parameters are the offsets") - HELP_TEXT ("of the tiling.") -}; -static const T_Help_table helptable_text[] = -{ - HELP_TITLE("TEXT") - HELP_TEXT ("") - HELP_LINK ("(Key:%s)",0x100+BUTTON_TEXT) - HELP_TEXT ("") - HELP_TEXT ("The text menu allows you to enter some text") - HELP_TEXT ("and render it as a brush.") - HELP_TEXT ("The current background and foreground colors") - HELP_TEXT ("are very important, they determine the text") - HELP_TEXT ("color, the transparent color, and also the") - HELP_TEXT ("color range to use for antialiasing.") - HELP_TEXT ("GrafX2 can use 'bitmap' fonts as long as") - HELP_TEXT ("they are in the special layout supported ") - HELP_TEXT ("by SFont.") - HELP_TEXT ("TrueType fonts can also be used if this") - HELP_TEXT ("version of GrafX2 was compiled with") - HELP_TEXT ("TrueType support.") - HELP_TEXT ("") - HELP_TEXT ("- Txt: Click and enter your text here, a") - HELP_TEXT ("line of up to 250 characters.") - HELP_TEXT ("") - HELP_TEXT ("- Clear txt: Empties the current text.") - HELP_TEXT ("When the text is empty, a standard string") - HELP_TEXT ("is shown instead in the preview area.") - HELP_TEXT ("") - HELP_TEXT ("- Antialias: Click to enable or disable") - HELP_TEXT ("Antialiasing. Only affects TrueType fonts.") - HELP_TEXT ("") - HELP_TEXT ("- Size: Determine the font height. Only") - HELP_TEXT ("affects TrueType fonts.") - HELP_TEXT ("") - HELP_TEXT ("- Font selector: Choose a font. You can") - HELP_TEXT ("use the arrow keys (up and down) to quickly") - HELP_TEXT ("browse your fonts.") - HELP_TEXT ("TrueType fonts are indicated by 'TT'.") - HELP_TEXT ("") - HELP_TEXT ("- Preview area: Shows what the brush will") - HELP_TEXT ("look like.") -}; -static const T_Help_table helptable_magnifier[] = -{ - HELP_TITLE("MAGNIFIER") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_MAGNIFIER) - HELP_TEXT ("") - HELP_TEXT ("Engages/Disengages the choice of the zoomed") - HELP_TEXT ("window. If you're already in magnifier mode,") - HELP_TEXT ("you'll return to normal mode.") - HELP_LINK ("Zoom in : %s",SPECIAL_ZOOM_IN) - HELP_LINK ("Zoom out: %s",SPECIAL_ZOOM_OUT) - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_MAGNIFIER) - HELP_TEXT ("") - HELP_TEXT ("Displays a menu where you can choose the") - HELP_TEXT ("magnifying factor.") - HELP_TEXT ("") - HELP_TEXT (" Note: When you are in Zoom mode, you can") - HELP_TEXT ("move the \"split\" bar by clicking on it and") - HELP_TEXT ("moving your mouse left or right while") - HELP_TEXT ("holding the mouse button down.") -}; -static const T_Help_table helptable_colorpicker[] = -{ - HELP_TITLE("PIPETTE") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_COLORPICKER) - HELP_TEXT ("") - HELP_TEXT ("Engages a color grabbing.") - HELP_TEXT ("") - HELP_TEXT ("Click on the picture to get the color of the") - HELP_TEXT ("pixel you're on. You can either get a new") - HELP_TEXT ("Fore-color or Back-color with respectively") - HELP_TEXT ("left or right mouse button.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_COLORPICKER) - HELP_TEXT ("") - HELP_TEXT ("Swap Fore-color and Back-color.") - HELP_TEXT ("") - HELP_TEXT (" The color currently pointed will be") - HELP_TEXT ("displayed in the tool-bar right after the") - HELP_TEXT ("coordinates. If you click outside the") - HELP_TEXT ("picture, the color 0 will be returned.") -}; -static const T_Help_table helptable_resolution[] = -{ - HELP_TITLE("RESOLUTION AND") - HELP_TITLE(" IMAGE SIZE") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_RESOL) - HELP_TEXT ("") - HELP_TEXT ("Displays a menu where you can define the") - HELP_TEXT ("size of your picture and choose the") - HELP_TEXT ("screen resolution.") - HELP_TEXT ("") - HELP_TEXT ("- Image size") - HELP_TEXT ("Click in the boxes named \"Width\" and") - HELP_TEXT ("\"Height\" to change the size of the image") - HELP_TEXT ("you're editing, up to 9999x9999.") - HELP_TEXT ("You can also right-click a video mode to") - HELP_TEXT ("copy its dimensions to the image's.") - HELP_TEXT ("") - HELP_TEXT ("- Pixel size") - HELP_TEXT ("If you choose any Pixel size other than") - HELP_TEXT ("Normal, Grafx2 will emulate a lower") - HELP_TEXT ("resolution by scaling up everything it") - HELP_TEXT ("displays, including the menus and mouse") - HELP_TEXT ("cursor. In Double, Triple and Quadruple") - HELP_TEXT ("mode, the image will appear zoomed x2, x3 or") - HELP_TEXT ("x4, keeping the original proportions. The") - HELP_TEXT ("scaling is done in software, with no linear") - HELP_TEXT ("interpolation, so it can't cause blur. This") - HELP_TEXT ("setting is especially useful if your") - HELP_TEXT ("hardware or drivers don't support the low") - HELP_TEXT ("resolutions you need, but it also allows you") - HELP_TEXT ("to draw in low-resolution while staying in") - HELP_TEXT ("window mode.") - HELP_TEXT ("If you choose one of the scalers called") - HELP_TEXT ("Wide, Tall, Wide2 and Tall2, this will") - HELP_TEXT ("emulate a video mode which has rectangular") - HELP_TEXT ("pixels (longer horizontally or vertically),") - HELP_TEXT ("like some video modes of the C64, Amstrad") - HELP_TEXT ("CPC, and Commodore Amiga.") - HELP_TEXT ("") - HELP_TEXT ("- Video mode") - HELP_TEXT ("Click on a video mode to select it.") - HELP_TEXT ("Grafx2 only lists modes that are detected") - HELP_TEXT ("as available on your computer. Depending on") - HELP_TEXT ("your video card and drivers, there can be") - HELP_TEXT ("a huge difference in the number of modes") - HELP_TEXT ("it can propose.") - HELP_TEXT ("The small buttons on the left-hand side of") - HELP_TEXT ("the lines in the list of modes have been") - HELP_TEXT ("designed to allow you to disable some modes") - HELP_TEXT ("that are not supported by your card. So, the") - HELP_TEXT ("modes that you will disable won't be used") - HELP_TEXT ("when loading pictures with \"Auto-set") - HELP_TEXT ("resolution\" ON.") - HELP_TEXT ("") - HELP_TEXT ("When you click on one of these buttons, its") - HELP_TEXT ("color changes to one of the 4 following. The") - HELP_TEXT ("signification for each color of these") - HELP_TEXT ("buttons is:") - HELP_TEXT ("") - HELP_TEXT ("- Light gray: The video mode is OK. It can") - HELP_TEXT ("be used by the auto-set resolution option") - HELP_TEXT ("when you load picture, and you can select it") - HELP_TEXT ("in the menu of resolutions.") - HELP_TEXT ("") - HELP_TEXT ("- White: It works exactly the same as above.") - HELP_TEXT ("Moreover, it allows you to tag your") - HELP_TEXT ("favourite modes. Indeed, the huge number of") - HELP_TEXT ("video modes makes it more difficult to find") - HELP_TEXT ("the mode your want in the list; so you can") - HELP_TEXT ("tag your favoutite ones in white, so that it") - HELP_TEXT ("will be easier to locate them. (Note: you") - HELP_TEXT ("cannot disable the standard windowed mode)") - HELP_TEXT ("") - HELP_TEXT ("- Dark gray: It allows you to indicate which") - HELP_TEXT ("modes are not really perfect (flickering,") - HELP_TEXT ("not centered, etc...) but which can be used") - HELP_TEXT ("even so. The difference with the light grey") - HELP_TEXT ("button is that these modes won't be used by") - HELP_TEXT ("the auto-set resolution option.") - HELP_TEXT ("") - HELP_TEXT ("- Black: Use it for totally unsupported") - HELP_TEXT ("modes. Thus, these modes won't be selected") - HELP_TEXT ("the \"auto-set res.\" and the program will") - HELP_TEXT ("not let you select them from the list of") - HELP_TEXT ("resolutions.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_RESOL) - HELP_TEXT ("") - HELP_TEXT (" Automaticaly switches to the 640x400 window") - HELP_TEXT ("mode.") -}; -static const T_Help_table helptable_page[] = -{ - HELP_TITLE("SPARE") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_PAGE) - HELP_TEXT ("") - HELP_TEXT ("Jumps to spare page. The current page is") - HELP_TEXT ("then considered as the new spare page, and") - HELP_TEXT ("the spare page considered as the new current") - HELP_TEXT ("page.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_PAGE) - HELP_TEXT ("") - HELP_TEXT ("Opens a menu where you can choose whether") - HELP_TEXT ("you want to copy the whole picture (keyboard") - HELP_TEXT ("short-cut in this menu is [Return]), only") - HELP_TEXT ("the pixels, only the palette, or only some") - HELP_TEXT ("colors.") - HELP_TEXT ("In this last case, a second menu") - HELP_TEXT ("(stencil-like) will propose you to tag the") - HELP_TEXT ("colors you want to copy (they are all") - HELP_TEXT ("selected by default).") - HELP_TEXT ("Please refer to section \"Stencil\" to know") - HELP_TEXT ("how to use this last menu.") - HELP_TEXT ("The last option the menu (\"Copy palette and") - HELP_TEXT ("remap\"), remaps the spare page with the") - HELP_TEXT ("current palette and replicates this palette") - HELP_TEXT ("to the spare page. This option is useful to") - HELP_TEXT ("quickly remap a picture with the palette of") - HELP_TEXT ("another.") -}; -static const T_Help_table helptable_save[] = -{ - HELP_TITLE("SAVE") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_SAVE) - HELP_TEXT ("") - HELP_TEXT ("Displays a fileselector where the following") - HELP_TEXT ("options are available:") - HELP_TEXT ("") - HELP_TEXT ("- Select drive: Allow you to change the") - HELP_TEXT ("current drive.or volume (depending on your") - HELP_TEXT ("operating system") - HELP_TEXT ("") - HELP_TEXT ("- Format: Allows you to choose the file") - HELP_TEXT ("format you want. (PAL and KCF file formats") - HELP_TEXT ("are \"palette\" files).") - HELP_TEXT ("") - HELP_TEXT ("- Filename: Allows you to give a new name to") - HELP_TEXT ("the picture. If no extension is given, the") - HELP_TEXT ("default (according to the format) will be") - HELP_TEXT ("used.") - HELP_TEXT ("") - HELP_TEXT ("- Bookmarks: The four dropdown buttons allow") - HELP_TEXT ("you to bookmark frequently used directories.") - HELP_TEXT ("Use right-click to open a contextual menu") - HELP_TEXT ("to Set it (memorize current directory),") - HELP_TEXT ("Rename it to change its label, and Clear it") - HELP_TEXT ("if you no longer need it. Use left-click to") - HELP_TEXT ("change to the memorized directory.") - HELP_TEXT ("") - HELP_TEXT ("- File-list: Allows you to flick through the") - HELP_TEXT ("disk tree or to overwrite an existing file.") - HELP_TEXT ("") - HELP_TEXT ("- Delete: Allows you to delete the item") - HELP_TEXT ("under the selection bar. If the item is a") - HELP_TEXT ("directory, it must be empty to be removed.") - HELP_TEXT ("") - HELP_TEXT ("- Save: Saves the picture with the current") - HELP_TEXT ("filename, with the chosen format. If the ") - HELP_TEXT ("current filename represents a directory,") - HELP_TEXT ("you'll enter it.") - HELP_TEXT ("") - HELP_TEXT ("- Comment (Txt): If you're using the PKM") - HELP_TEXT ("or PNG format, you can type in a comment on") - HELP_TEXT ("your picture. It will be memorized in the") - HELP_TEXT ("image.") - HELP_TEXT ("") - HELP_TEXT ("Note: The Backspace key brings you directly") - HELP_TEXT ("to the parent directory. You can also type") - HELP_TEXT ("the first letters of a filename you are") - HELP_TEXT ("looking for, to access it faster.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_SAVE) - HELP_TEXT ("") - HELP_TEXT ("Save the current picture with its current") - HELP_TEXT ("filename, format and comment.") - HELP_TEXT ("") - HELP_TEXT ("If the file already exists, a confirmation") - HELP_TEXT ("box will appear.") -}; -static const T_Help_table helptable_load[] = -{ - - HELP_TITLE("LOAD") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_LOAD) - HELP_TEXT ("") - HELP_TEXT ("This works the same way as Save.") - HELP_TEXT ("") - HELP_TEXT ("You'll have access in the format selector to") - HELP_TEXT ("a \"*.*\" filter. And of course, you won't be") - HELP_TEXT ("able to type in any comment.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_LOAD) - HELP_TEXT ("") - HELP_TEXT ("Reloads the picture.") - HELP_TEXT ("") - HELP_TEXT ("If you want to load a picture and that you") - HELP_TEXT ("haven't saved the last modifications of the") - HELP_TEXT ("current picture, a confirmation box will") - HELP_TEXT ("appear.") -}; -static const T_Help_table helptable_settings[] = -{ - HELP_TITLE("SETTINGS") - HELP_TEXT ("") - HELP_LINK ("(Key:%s)",0x100+BUTTON_SETTINGS) - HELP_TEXT ("") - HELP_TEXT ("Displays a menu where you can configure some") - HELP_TEXT ("miscellaneous elements of the program:") - HELP_TEXT ("") - HELP_TEXT ("- Number of UNDO pages: indicates the total") - HELP_TEXT ("number of pages that GrafX2 will memorize.") - HELP_TEXT ("Each time you modify the picture, its") - HELP_TEXT ("current state is memorized in one of these") - HELP_TEXT ("pages. To flick through these pages, use the") - HELP_TEXT ("\"Oops\" button (Undo/Redo).") - HELP_TEXT ("") - HELP_TEXT ("- Mouse sensibility: Modifies the speed of") - HELP_TEXT ("the mouse when you're in fullscreen. With") - HELP_TEXT ("the normal setting (slider on top), you may") - HELP_TEXT ("find the mouse too fast, especially in ") - HELP_TEXT ("video modes which are much smaller than your") - HELP_TEXT ("desktop. You can lower the slider to divide") - HELP_TEXT ("the speed by 2, 3 or 4.") - HELP_TEXT ("When using videomodes with native skewed") - HELP_TEXT ("pixels like 640x240 or 320x512, you'll") - HELP_TEXT ("probably want to use a stronger reduction") - HELP_TEXT ("on the axis which has less pixels.") - HELP_TEXT ("") - HELP_TEXT ("- Show/Hide in file list: Defines whether") - HELP_TEXT ("some particular files or directories must be") - HELP_TEXT ("displayed by the fileselectors or not.") - HELP_TEXT ("") - HELP_TEXT ("- Show/Hide picture limits: Indicates if the") - HELP_TEXT ("picture boundaries must be displayed when") - HELP_TEXT ("you are in a resolution bigger than the") - HELP_TEXT ("picture.") - HELP_TEXT ("") - HELP_TEXT ("- Clear palette: Indicates if loading a file") - HELP_TEXT ("with a palette of less than 256 colors must") - HELP_TEXT ("erase the rest of the current palette") - HELP_TEXT ("(replace by the black color).") - HELP_TEXT ("") - HELP_TEXT ("- Maximize preview: maximizes the preview of") - HELP_TEXT ("the pictures so that it is as big as") - HELP_TEXT ("possible. If you're not in the same") - HELP_TEXT ("resolution as the picture's one, it can try") - HELP_TEXT ("to correct the aspect ratio, but if the") - HELP_TEXT ("picture does not fill the whole screen, it") - HELP_TEXT ("can be worse.") - HELP_TEXT ("") - HELP_TEXT ("- Backup: when you'll save a picture over an") - HELP_TEXT ("existing file, the program will rename this") - HELP_TEXT ("file to \"*.BAK\" where * is the name of the") - HELP_TEXT ("picture without its extension. If the backup") - HELP_TEXT ("file already exists in the directory, it") - HELP_TEXT ("will be replaced. If you save a picture with") - HELP_TEXT ("the name of the backup file, no backup file") - HELP_TEXT ("will be created (of course!) ;).") - HELP_TEXT ("") - HELP_TEXT ("- Safety colors: Brings back the 4 default") - HELP_TEXT ("colors of the menus if you run an operation") - HELP_TEXT ("that passes the image in less than four") - HELP_TEXT ("colors in the palette editor.") - HELP_TEXT ("") - HELP_TEXT ("- Adjust brush pick: This option is used") - HELP_TEXT ("when you grab a brush in Grid (Snap) mode.") - HELP_TEXT ("Then, the right-most and down-most pixels") - HELP_TEXT ("won't be picked up with the rest of the") - HELP_TEXT ("brush. This option has been made because, if") - HELP_TEXT ("people grab brushes in Grid mode, that's") - HELP_TEXT ("mostly when they want to grab sprites. For") - HELP_TEXT ("example: if you have 16x16 sprites on your") - HELP_TEXT ("page, you'll set the grid mode to 16x16. But") - HELP_TEXT ("the cursor will snap at points like (0,0),") - HELP_TEXT ("(16,0), (16,16) and so on... And the problem") - HELP_TEXT ("is that, from (0,0) to (16,16), there are 17") - HELP_TEXT ("pixels! But if you keep the") - HELP_TEXT ("adjust-brush-pick option on, the unwanted") - HELP_TEXT ("pixels will be ignored. Moreover, this") - HELP_TEXT ("option adjusts the brush handle so that the") - HELP_TEXT ("brush still fits in the grid, instead of") - HELP_TEXT ("placing the handle in the center of the") - HELP_TEXT ("brush.") - HELP_TEXT ("") - HELP_TEXT ("- Separate colors: Draws a squaring around") - HELP_TEXT ("the colors of the tool-bar.") - HELP_TEXT ("") - HELP_TEXT ("- Auto-set resolution: sets the best") - HELP_TEXT ("resolution for the loaded image.") - HELP_TEXT ("") - HELP_TEXT ("- Coordinates: Choose if you want to display") - HELP_TEXT ("relative or absolute coordinates when using") - HELP_TEXT ("tools such as circles, rectangles, etc...") - HELP_TEXT ("for example, if you draw a circle: if coords") - HELP_TEXT ("are relative, the radius of the circle will") - HELP_TEXT ("be displayed, while in absolute coords, the") - HELP_TEXT ("coordinates of the cursor will be displayed.") - HELP_TEXT ("") - HELP_TEXT ("- Reload: loads the previously saved") - HELP_TEXT ("configuration.") - HELP_TEXT ("") - HELP_TEXT ("- Auto-save: means that the configuration") - HELP_TEXT ("will be automatically saved when you'll quit") - HELP_TEXT ("the program.") - HELP_TEXT ("") - HELP_TEXT ("- Save: saves the configuration at once.") - HELP_TEXT (" All modifications will be effective just") - HELP_TEXT ("after closing the menu.") - HELP_TEXT ("") - HELP_TITLE("SKINS") - HELP_TEXT ("") - HELP_TEXT ("This window allow you to change the look and") - HELP_TEXT ("feel of the program.") - HELP_TEXT ("") - HELP_TEXT ("- Font: determines whether you want to use") - HELP_TEXT ("GrafX2 with a classical font, or another one") - HELP_TEXT ("a bit funnier.") - HELP_TEXT ("") - HELP_TEXT ("- Cursor: allows you to choose whether you") - HELP_TEXT ("prefer a solid cursor or a transparent") - HELP_TEXT ("cursor.") - HELP_TEXT ("") - HELP_TEXT ("- Graphic file: you can change the whole") - HELP_TEXT ("interface by selecting where the sprites for") - HELP_TEXT ("all buttons are. Look at the files in the") - HELP_TEXT ("\"skin\" directory if you want to create your") - HELP_TEXT ("own. There are two skins available, the") - HELP_TEXT ("default for 2.1 is called modern. Classic is") - HELP_TEXT ("for nostalgics who wish to remember the old") - HELP_TEXT ("days of Sunset Design. If you create a good") - HELP_TEXT ("skin, feel free to share it with us! We may") - HELP_TEXT ("include it in a future release...") -}; -static const T_Help_table helptable_clear[] = -{ - - HELP_TITLE("CLEAR") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_CLEAR) - HELP_TEXT ("") - HELP_TEXT ("Clears the picture with the color number 0.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_CLEAR) - HELP_TEXT ("") - HELP_TEXT ("Clears the picture with the Back-color.") -}; -static const T_Help_table helptable_general[] = -{ - - HELP_TITLE("HELP STATS") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_HELP) - HELP_TEXT ("") - HELP_TEXT ("Displays an info window where you'll find") - HELP_TEXT ("some credits, help about the credits,") - HELP_TEXT ("different effects, greetings, registering...") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_HELP) - HELP_TEXT ("") - HELP_TEXT ("Displays a window where you'll find") - HELP_TEXT ("miscellaneous informations about the system.") - HELP_TEXT (" Note: you should take care to keep more") - HELP_TEXT ("than 128 Kb in order to let the program") - HELP_TEXT ("run in a proper way.") -}; -static const T_Help_table helptable_undo[] = -{ - - HELP_TITLE("OOPS") - HELP_TEXT ("(UNDO/REDO)") - HELP_TEXT ("LEFT CLICK Allows you to undo the last") - HELP_TEXT ("modification on the picture.") - HELP_LINK ("(Key:%s)",0x100+BUTTON_UNDO) - HELP_TEXT ("") - HELP_TEXT ("RIGHT CLICK Allows you to redo the last") - HELP_TEXT ("modification undone on the picture.") - HELP_TEXT ("The maximum number of UNDO that you can") - HELP_TEXT ("perform can be defined in the settings") - HELP_TEXT ("menu.") - HELP_TEXT ("Undo/Redo aren't effective after page") - HELP_TEXT ("switching, picture loading and picture") - HELP_TEXT ("size modifications.") - HELP_LINK ("(Key:%s)",0x200+BUTTON_UNDO) -}; -static const T_Help_table helptable_kill[] = -{ - - HELP_TITLE("KILL") - HELP_TEXT ("KILL CURRENT PAGE") - HELP_TEXT ("") - HELP_LINK ("(Key:%s)",0x100+BUTTON_KILL) - HELP_TEXT ("") - HELP_TEXT ("Removes the current page from the list of") - HELP_TEXT ("\"Undo\" pages. This allows you to free some") - HELP_TEXT ("memory if you need it. For instance, this") - HELP_TEXT ("will allow you to delete the start-up page") - HELP_TEXT ("after having loaded an image. A message will") - HELP_TEXT ("appear if you've already erased all the") - HELP_TEXT ("pages except the last one.") - HELP_TEXT (" Note: Another way to free some memory is to") - HELP_TEXT ("decrease the number of \"Undo\" pages. Or") - HELP_TEXT ("else, if you have recentlt grabbed a very") - HELP_TEXT ("big brush that you don't use any more, you") - HELP_TEXT ("can grab a new smaller one. The memory") - HELP_TEXT ("allocated by the big brush will be thus") - HELP_TEXT ("freed.") -}; -static const T_Help_table helptable_quit[] = -{ - - HELP_TITLE("QUIT") - HELP_TEXT ("") - HELP_LINK ("(Key:%s)",0x100+BUTTON_QUIT) - HELP_TEXT ("") - HELP_TEXT ("Allows you to leave GrafX2. If there are") - HELP_TEXT ("unsaved modifications in the current or") - HELP_TEXT ("spare page, a confirmation box will ask you") - HELP_TEXT ("if you really want to quit GrafX2, if you") - HELP_TEXT ("want to save (Auto-save, no fileselector) or") - HELP_TEXT ("if you want to stay in GrafX2.") -}; -static const T_Help_table helptable_palette[] = -{ - - HELP_TITLE("PAL MENU") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_LINK ("(Key:%s)",0x100+BUTTON_PALETTE) - HELP_TEXT ("") - HELP_TEXT ("Displays a menu where the following options") - HELP_TEXT ("are available:") - HELP_TEXT ("") - HELP_TEXT ("- Palette: Allows you to choose a") - HELP_TEXT ("color-block to edit. If you click with the") - HELP_TEXT ("right mouse button, you'll choose a new") - HELP_TEXT ("Back-color.") - HELP_TEXT ("") - HELP_TEXT ("- Gauges: Allow you to modify the") - HELP_TEXT ("current selection.") - HELP_TEXT ("") - HELP_TEXT ("- \"+\" and \"-\": Allow you to lighten or") - HELP_TEXT ("darken the current selection.") - HELP_TEXT ("") - HELP_TEXT ("- Default: Restores the predifined GrafX2") - HELP_TEXT ("palette.") - HELP_TEXT ("") - HELP_TEXT ("- Gray: Transforms the current selection") - HELP_TEXT ("into its gray-scaled equivalent.") - HELP_TEXT ("") - HELP_TEXT ("- Negative: Transforms the current selection") - HELP_TEXT ("into its reverse video equivalent.") - HELP_TEXT ("") - HELP_TEXT ("- Invert: Swaps the colors of the current") - HELP_TEXT ("selection so that the first colors become") - HELP_TEXT ("the last ones.") - HELP_TEXT ("") - HELP_TEXT ("- X-Invert: Works as above but modifies the") - HELP_TEXT ("picture so that it looks the same.") - HELP_TEXT ("") - HELP_TEXT ("- Swap: Swaps the current selection with") - HELP_TEXT ("another color-block. Click on the beginning") - HELP_TEXT ("of the new color-block.") - HELP_TEXT ("") - HELP_TEXT ("- X-Swap: Works as above but modifies the") - HELP_TEXT ("picture so that it looks the same. This may") - HELP_TEXT ("be useful if you want to sort your palette.") - HELP_TEXT ("") - HELP_TEXT ("- Copy: Copies the current selection to") - HELP_TEXT ("another color-block. Click on the beginning") - HELP_TEXT ("of the new color-block.") - HELP_TEXT ("") - HELP_TEXT ("- Spread: Computes a gradation between two") - HELP_TEXT ("colors. If your selection is only made up of") - HELP_TEXT ("one color, select the second color in the") - HELP_TEXT ("palette. Otherwise, the two colors used will") - HELP_TEXT ("be its extremities.") - HELP_TEXT ("") - HELP_TEXT ("- Sort: sorts the palette by color ranges.") - HELP_TEXT ("If you click with the left mouse button, it") - HELP_TEXT ("will sort by H S L; and if you click with") - HELP_TEXT ("the right mouse button, it will sort by L") - HELP_TEXT ("only. Note that you can choose a range of") - HELP_TEXT ("colors before sorting, and instead of the") - HELP_TEXT ("whole palette it will sort this range.") - HELP_TEXT ("") - HELP_TEXT ("- Used: Indicates the number of colors used") - HELP_TEXT ("in the picture.") - HELP_TEXT ("") - HELP_TEXT ("- Zap unused: Erases the unused colors with") - HELP_TEXT ("copies of the current selection. (The") - HELP_TEXT ("keyboard shortcut for this button is ).") - HELP_TEXT ("") - HELP_TEXT ("- HSL: Switches between RGB and HSL color") - HELP_TEXT ("spaces. In HSL mode, the three sliders") - HELP_TEXT ("allow you to set the Hue (tint), Saturation") - HELP_TEXT ("(from grayscale to pure color) and") - HELP_TEXT ("Lightness (from black to white).") - HELP_TEXT ("") - HELP_TEXT ("- Reduce: Allows you to reduce the palette") - HELP_TEXT ("to the number of colors you want (and") - HELP_TEXT ("modifies the picture).") - HELP_TEXT ("") - HELP_TEXT ("- Undo: Allows you to recover the last") - HELP_TEXT ("modifications made on the palette. If the") - HELP_TEXT ("last operation modified the picture, it") - HELP_TEXT ("won't recover them: you'll have to click on") - HELP_TEXT ("Cancel to do so.") - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TEXT ("If you press , the program will") - HELP_TEXT ("replace, as well as possible, some unused") - HELP_TEXT ("colors by the four default colors of the") - HELP_TEXT ("menu. The image won't look altered because") - HELP_TEXT ("the modified colors (in the case they were") - HELP_TEXT ("used on a few points) will be replaced by") - HELP_TEXT ("the closest colors in the rest of the") - HELP_TEXT ("palette. This option is really useful when") - HELP_TEXT ("you modify the palette so that there are no") - HELP_TEXT ("colors that fit for the menu (eg: \"Zap") - HELP_TEXT ("unused\" while very little colors are used in") - HELP_TEXT ("the picture; or \"Reduce\" with a very small") - HELP_TEXT ("number of colors).") - HELP_TEXT ("") - HELP_TEXT ("If you press the key below or <,>") - HELP_TEXT ("(QWERTY), the menu will disappear and you") - HELP_TEXT ("will be able to pick up a color from the") - HELP_TEXT ("picture easily. Press to cancel.") - HELP_TEXT ("") - HELP_TEXT ("If only one color is selected (not a block),") - HELP_TEXT ("the <[> and <]> keys can be used to select") - HELP_TEXT ("the previous or next Forecolor (Backcolor if") - HELP_TEXT ("you press at the same time).") - HELP_TEXT ("") - HELP_TEXT ("Warning! If you press Undo after an action") - HELP_TEXT ("that modifies the picture (X-Swap, X-Invert") - HELP_TEXT ("and Reduce colors), the picture won't be") - HELP_TEXT ("remapped as it was just before this action.") - HELP_TEXT ("Only Cancel will.") - HELP_TEXT ("") - HELP_TITLE("PALETTE OPTIONS") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_LINK ("(Key:%s)",0x200+BUTTON_PALETTE) - HELP_TEXT ("") - HELP_TEXT ("Opens a menu from where you have the") - HELP_TEXT ("following options:") - HELP_TEXT ("") - HELP_TEXT ("- Colors for best match:") - HELP_TEXT ("A menu in which you can select the colors") - HELP_TEXT ("that have not to be used for smoothing, for") - HELP_TEXT ("the transparency mode, and for remapping.") - HELP_TEXT ("") - HELP_TEXT ("- User's color series:") - HELP_TEXT ("A menu in which you can define color series") - HELP_TEXT ("for next/previous user color shortcuts.") - HELP_TEXT ("It's the same settings than the shade mode.") - HELP_TEXT ("After you have some color ranges defined in") - HELP_TEXT ("this screen, you can use those shortcuts to") - HELP_TEXT ("move to the next or previous color according") - HELP_TEXT ("to your ranges:") - HELP_TEXT ("") - HELP_TEXT ("Foreground color") - HELP_TEXT ("") - HELP_LINK (" Next : %s", SPECIAL_NEXT_USER_FORECOLOR) - HELP_LINK (" Previous: %s", SPECIAL_PREVIOUS_USER_FORECOLOR) - HELP_TEXT ("") - HELP_TEXT ("Background color") - HELP_LINK (" Next : %s", SPECIAL_NEXT_USER_BACKCOLOR) - HELP_LINK (" Previous: %s", SPECIAL_PREVIOUS_USER_BACKCOLOR) - HELP_TEXT ("") - HELP_TEXT ("") - HELP_TEXT ("- Palette layout:") - HELP_TEXT ("Lets you customize the palette that appears") - HELP_TEXT ("on the right of the menu. You can choose the") - HELP_TEXT ("number of lines and columns.") - HELP_TEXT ("If you want the colors to run top to bottom,") - HELP_TEXT ("check the 'Vertical' button, otherwise the") - HELP_TEXT ("colors runs left to right.") - HELP_TEXT ("") - HELP_TEXT ("- RGB Scale:") - HELP_TEXT ("Lets you set the scale of the R G B sliders") - HELP_TEXT ("in the palette screen. You should normally") - HELP_TEXT ("leave it at 256 to get the full 0-255 range,") - HELP_TEXT ("but if you want to constrain the palette") - HELP_TEXT ("to the capabilities of some specific") - HELP_TEXT ("computers and consoles, you can choose eg:") - HELP_TEXT (" 64 : VGA") - HELP_TEXT (" 16 : Amiga") - HELP_TEXT (" 4 : MSX2") - HELP_TEXT (" 2 : Amstrad CPC") - }; -static const T_Help_table helptable_pal_scroll[] = -{ - - HELP_TITLE("SCROLL PAL") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_TEXT ("") - HELP_TEXT ("Scrolls the palette window in the right of") - HELP_TEXT ("the menu.") - HELP_LINK ("Key for back: %s", 0x100+BUTTON_PAL_LEFT) - HELP_LINK ("Key for forward: %s", 0x100+BUTTON_PAL_RIGHT) - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_TEXT ("") - HELP_TEXT ("Same as above, but faster.") - HELP_LINK ("Key for back: %s", 0x200+BUTTON_PAL_LEFT) - HELP_LINK ("Key for forward: %s", 0x200+BUTTON_PAL_RIGHT) - HELP_TEXT ("") -}; -static const T_Help_table helptable_color_select[] = -{ - - HELP_TITLE("PALETTE") - HELP_TEXT ("") - HELP_BOLD ("LEFT CLICK") - HELP_TEXT ("") - HELP_TEXT ("Defines the Fore-color.") - HELP_TEXT ("") - HELP_BOLD ("RIGHT CLICK") - HELP_TEXT ("") - HELP_TEXT ("Defines the Back-color.") -}; -static const T_Help_table helptable_hide[] = -{ - - HELP_TITLE("HIDE MENU") - HELP_TEXT ("") - HELP_TEXT ("Allows you to hide the menu. If you do this,") - HELP_TEXT ("take care to watch before the key to press") - HELP_TEXT ("to show the menu back (the key is") - HELP_LINK ("%s).",0x100+BUTTON_HIDE) - -}; - -#define HELP_TABLE_DECLARATION(x) {x, sizeof(x)/sizeof(const T_Help_table)}, - -T_Help_section Help_section[] = -{ - HELP_TABLE_DECLARATION(helptable_about) - HELP_TABLE_DECLARATION(helptable_licence) - HELP_TABLE_DECLARATION(helptable_help) - HELP_TABLE_DECLARATION(helptable_credits) - - // Attention, keep the same order as BUTTON_NUMBERS: - HELP_TABLE_DECLARATION(helptable_paintbrush) - HELP_TABLE_DECLARATION(helptable_adjust) - HELP_TABLE_DECLARATION(helptable_draw) - HELP_TABLE_DECLARATION(helptable_curves) - HELP_TABLE_DECLARATION(helptable_lines) - HELP_TABLE_DECLARATION(helptable_airbrush) - HELP_TABLE_DECLARATION(helptable_floodfill) - HELP_TABLE_DECLARATION(helptable_polygons) - HELP_TABLE_DECLARATION(helptable_polyfill) - HELP_TABLE_DECLARATION(helptable_rectangles) - HELP_TABLE_DECLARATION(helptable_filled_rectangles) - HELP_TABLE_DECLARATION(helptable_circles) - HELP_TABLE_DECLARATION(helptable_filled_circles) - HELP_TABLE_DECLARATION(helptable_grad_rect) - HELP_TABLE_DECLARATION(helptable_spheres) - HELP_TABLE_DECLARATION(helptable_brush) - HELP_TABLE_DECLARATION(helptable_polybrush) - HELP_TABLE_DECLARATION(helptable_brush_fx) - HELP_TABLE_DECLARATION(helptable_effects) - HELP_TABLE_DECLARATION(helptable_text) - HELP_TABLE_DECLARATION(helptable_magnifier) - HELP_TABLE_DECLARATION(helptable_colorpicker) - HELP_TABLE_DECLARATION(helptable_resolution) - HELP_TABLE_DECLARATION(helptable_page) - HELP_TABLE_DECLARATION(helptable_save) - HELP_TABLE_DECLARATION(helptable_load) - HELP_TABLE_DECLARATION(helptable_settings) - HELP_TABLE_DECLARATION(helptable_clear) - HELP_TABLE_DECLARATION(helptable_general) - HELP_TABLE_DECLARATION(helptable_undo) - HELP_TABLE_DECLARATION(helptable_kill) - HELP_TABLE_DECLARATION(helptable_quit) - HELP_TABLE_DECLARATION(helptable_palette) - HELP_TABLE_DECLARATION(helptable_pal_scroll) - HELP_TABLE_DECLARATION(helptable_pal_scroll) - HELP_TABLE_DECLARATION(helptable_color_select) - HELP_TABLE_DECLARATION(helptable_hide) -}; +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 Yves Rizoud + Copyright 2009 Franck Charlet + 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file helpfile.h +/// This is all the text that appears in contextual help and credits. +/// +/// Note: The source code is kept on a public website, so keep this in mind +/// if you're thinking of putting an e-mail address in there. At least, use +/// "\100" instead of @, to help against the most basic email address harvesters. +////////////////////////////////////////////////////////////////////////////// + +#include "const.h" // Uses enumerations BUTTON_NUMBERS and SPECIAL_ACTIONS + +// Some magic formulas: + +#define HELP_TEXT(x) {'N', x, 0}, +// Generates a 'N' line (Normal) + +#define HELP_LINK(x,y) {'K', x, y}, +// Generates a 'K' line (Key) + +#define HELP_BOLD(x) {'S', x, 0}, +// Generates a 'S' line (BOLD) + +#define HELP_TITLE(x) {'T', x, 0}, {'-', x, 0}, +// Generates a 'T' line (Title, upper half) +// and a second '-' line (Title, lower half), with the same text. + +static const T_Help_table helptable_about[] = +/* + Do not exceed 44 characters for normal lines: + HELP_TEXT ("--------------------------------------------") + Do not exceed 22 characters for title lines: + HELP_TITLE("======================") +*/ +{ + HELP_TEXT ("") // Leave enough room for a hard-coded logo, eventually. + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE(" GRAFX 2 ") + HELP_BOLD (" \"Summer Sunset\" Edition") + HELP_BOLD (" THE ULTIMATE MULTI-RESOLUTION GFX EDITOR") + HELP_TEXT (" http://grafx2.googlecode.com") + HELP_TEXT ("") + HELP_TEXT (" Copyright 2007 by the Grafx2 project team") + HELP_TEXT (" Copyright 1996-2001 by SUNSET DESIGN") +}; +static const T_Help_table helptable_licence[] = +{ + HELP_TITLE(" LICENSE") + HELP_TEXT ("") + HELP_TEXT ("Grafx2 is FREE SOFTWARE, you can") + HELP_TEXT ("redistribute it and/or modify it under the") + HELP_TEXT ("terms of the GNU General Public License as") + HELP_TEXT ("published by the Free Software Foundation;") + HELP_TEXT ("version 2 of the License.") + HELP_TEXT ("") + HELP_TEXT ("Grafx2 is distributed in the hope that it") + HELP_TEXT ("will be useful, but WITHOUT ANY WARRANTY;") + HELP_TEXT ("without even the implied warranty of") + HELP_TEXT ("MERCHANTABILITY or FITNESS FOR A PARTICULAR") + HELP_TEXT ("PURPOSE. See the GNU General Public License") + HELP_TEXT ("for more details.") + HELP_TEXT ("") + HELP_TEXT ("You should have received a copy of the GNU") + HELP_TEXT ("General Public License along with Grafx2;") + HELP_TEXT ("if not, see http://www.gnu.org/licenses/ or") + HELP_TEXT ("write to the Free Software Foundation, Inc.") + HELP_TEXT (" 59 Temple Place - Suite 330, Boston,") + HELP_TEXT (" MA 02111-1307, USA.") + +}; +static const T_Help_table helptable_help[] = +{ + HELP_TITLE(" HELP") + HELP_TEXT ("") + HELP_TEXT (" Contextual help is available by pressing") + HELP_LINK (" the %s key",0x100+BUTTON_HELP) + HELP_TEXT (" You can do it while hovering a menu icon,") + HELP_TEXT (" or while a window is open.") + HELP_TEXT (" When a keyboard shortcut is displayed it's") + HELP_TEXT (" your current configuration and you can") + HELP_TEXT (" change it by clicking it.") + HELP_TEXT ("") + HELP_TITLE(" KEYBOARD SHORTCUTS") + HELP_TEXT ("") + HELP_TEXT ("Scroll visible area") + HELP_LINK (" up: %s", SPECIAL_SCROLL_UP) + HELP_LINK (" down: %s", SPECIAL_SCROLL_DOWN) + HELP_LINK (" left: %s", SPECIAL_SCROLL_LEFT) + HELP_LINK (" right: %s", SPECIAL_SCROLL_RIGHT) + HELP_LINK (" up faster: %s", SPECIAL_SCROLL_UP_FAST) + HELP_LINK (" down faster: %s", SPECIAL_SCROLL_DOWN_FAST) + HELP_LINK (" left faster: %s", SPECIAL_SCROLL_LEFT_FAST) + HELP_LINK (" right faster: %s", SPECIAL_SCROLL_RIGHT_FAST) + HELP_LINK (" up slower: %s", SPECIAL_SCROLL_UP_SLOW) + HELP_LINK (" down slower: %s", SPECIAL_SCROLL_DOWN_SLOW) + HELP_LINK (" left slower: %s", SPECIAL_SCROLL_LEFT_SLOW) + HELP_LINK (" right slower: %s", SPECIAL_SCROLL_RIGHT_SLOW) + HELP_TEXT ("Emulate mouse") + HELP_LINK (" Up: %s", SPECIAL_MOUSE_UP) + HELP_LINK (" Down: %s", SPECIAL_MOUSE_DOWN) + HELP_LINK (" Left: %s", SPECIAL_MOUSE_LEFT) + HELP_LINK (" Right: %s", SPECIAL_MOUSE_RIGHT) + HELP_LINK (" Left click: %s", SPECIAL_CLICK_LEFT) + HELP_LINK (" Right click: %s", SPECIAL_CLICK_RIGHT) + HELP_LINK ("Show / Hide menu: %s", 0x100+BUTTON_HIDE) + HELP_LINK ("Show / Hide cursor: %s", SPECIAL_SHOW_HIDE_CURSOR) + HELP_LINK ("Paintbrush = \".\": %s", SPECIAL_DOT_PAINTBRUSH) + HELP_LINK ("Paintbrush choice: %s", 0x100+BUTTON_PAINTBRUSHES) + HELP_LINK ("Monochrome brush: %s", 0x200+BUTTON_PAINTBRUSHES) + HELP_LINK ("Freehand drawing: %s", 0x100+BUTTON_DRAW) + HELP_TEXT ("Switch freehand") + HELP_LINK (" drawing mode: %s", 0x200+BUTTON_DRAW) + HELP_TEXT ("Continuous freehand") + HELP_LINK (" drawing: %s", SPECIAL_CONTINUOUS_DRAW) + HELP_LINK ("Line: %s", 0x100+BUTTON_LINES) + HELP_LINK ("Knotted lines: %s", 0x200+BUTTON_LINES) + HELP_LINK ("Spray: %s", 0x100+BUTTON_AIRBRUSH) + HELP_LINK ("Spray menu: %s", 0x200+BUTTON_AIRBRUSH) + HELP_LINK ("Floodfill: %s", 0x100+BUTTON_FLOODFILL) + HELP_LINK ("Replace color: %s", 0x200+BUTTON_FLOODFILL) + HELP_LINK ("Bezier's curves: %s", 0x100+BUTTON_CURVES) + HELP_TEXT ("Bezier's curve with") + HELP_LINK (" 3 or 4 points %s", 0x200+BUTTON_CURVES) + HELP_LINK ("Empty rectangle: %s", 0x100+BUTTON_RECTANGLES) + HELP_LINK ("Filled rectangle: %s", 0x100+BUTTON_FILLRECT) + HELP_LINK ("Empty circle: %s", 0x100+BUTTON_CIRCLES) + HELP_LINK ("Empty ellipse: %s", 0x200+BUTTON_CIRCLES) + HELP_LINK ("Filled circle: %s", 0x100+BUTTON_FILLCIRC) + HELP_LINK ("Filled ellipse: %s", 0x200+BUTTON_FILLCIRC) + HELP_LINK ("Empty polygon: %s", 0x100+BUTTON_POLYGONS) + HELP_LINK ("Empty polyform: %s", 0x200+BUTTON_POLYGONS) + HELP_LINK ("Polyfill: %s", 0x100+BUTTON_POLYFILL) + HELP_LINK ("Filled polyform: %s", 0x200+BUTTON_POLYFILL) + HELP_LINK ("Gradient rectangle: %s", 0x100+BUTTON_GRADRECT) + HELP_LINK ("Gradation menu: %s", 0x200+BUTTON_GRADRECT) + HELP_LINK ("Spheres: %s", 0x100+BUTTON_SPHERES) + HELP_LINK ("Gradient ellipses: %s", 0x200+BUTTON_SPHERES) + HELP_LINK ("Adjust picture: %s", 0x100+BUTTON_ADJUST) + HELP_LINK ("Flip picture menu: %s", 0x200+BUTTON_ADJUST) + HELP_LINK ("Effects menu: %s", 0x100+BUTTON_EFFECTS) + HELP_LINK ("Effects all off %s", SPECIAL_EFFECTS_OFF) + HELP_LINK ("Shade mode: %s", SPECIAL_SHADE_MODE) + HELP_LINK ("Shade menu: %s", SPECIAL_SHADE_MENU) + HELP_LINK ("Quick-shade mode: %s", SPECIAL_QUICK_SHADE_MODE) + HELP_LINK ("Quick-shade menu: %s", SPECIAL_QUICK_SHADE_MENU) + HELP_LINK ("Stencil mode: %s", SPECIAL_STENCIL_MODE) + HELP_LINK ("Stencil menu: %s", SPECIAL_STENCIL_MENU) + HELP_LINK ("Mask mode: %s", SPECIAL_MASK_MODE) + HELP_LINK ("Mask menu: %s", SPECIAL_MASK_MENU) + HELP_LINK ("Grid mode: %s", SPECIAL_GRID_MODE) + HELP_LINK ("Grid menu: %s", SPECIAL_GRID_MENU) + HELP_LINK ("Sieve mode: %s", SPECIAL_SIEVE_MODE) + HELP_LINK ("Sieve menu: %s", SPECIAL_SIEVE_MENU) + HELP_LINK ("Invert Sieve: %s", SPECIAL_INVERT_SIEVE) + HELP_LINK ("Colorize mode: %s", SPECIAL_COLORIZE_MODE) + HELP_LINK (" At opacity 10%%: %s", SPECIAL_TRANSPARENCY_1) + HELP_LINK (" At opacity 20%%: %s", SPECIAL_TRANSPARENCY_2) + HELP_LINK (" At opacity 30%%: %s", SPECIAL_TRANSPARENCY_3) + HELP_LINK (" At opacity 40%%: %s", SPECIAL_TRANSPARENCY_4) + HELP_LINK (" At opacity 50%%: %s", SPECIAL_TRANSPARENCY_5) + HELP_LINK (" At opacity 60%%: %s", SPECIAL_TRANSPARENCY_6) + HELP_LINK (" At opacity 70%%: %s", SPECIAL_TRANSPARENCY_7) + HELP_LINK (" At opacity 80%%: %s", SPECIAL_TRANSPARENCY_8) + HELP_LINK (" At opacity 90%%: %s", SPECIAL_TRANSPARENCY_9) + HELP_LINK (" At opacity 100%%: %s", SPECIAL_TRANSPARENCY_0) + HELP_LINK ("Colorize menu: %s", SPECIAL_COLORIZE_MENU) + HELP_LINK ("Smooth mode: %s", SPECIAL_SMOOTH_MODE) + HELP_LINK ("Smooth menu: %s", SPECIAL_SMOOTH_MENU) + HELP_LINK ("Smear mode: %s", SPECIAL_SMEAR_MODE) + HELP_LINK ("Tiling mode: %s", SPECIAL_TILING_MODE) + HELP_LINK ("Tiling menu: %s", SPECIAL_TILING_MENU) + HELP_LINK ("Pick brush: %s", 0x100+BUTTON_BRUSH) + HELP_LINK ("Pick polyform brush: %s", 0x100+BUTTON_POLYBRUSH) + HELP_LINK ("Restore brush: %s", 0x200+BUTTON_BRUSH) + HELP_LINK ("Flip brush X: %s", SPECIAL_FLIP_X) + HELP_LINK ("Flip brush Y: %s", SPECIAL_FLIP_Y) + HELP_LINK ("90° brush rotation: %s", SPECIAL_ROTATE_90) + HELP_LINK ("180° brush rotation: %s", SPECIAL_ROTATE_180) + HELP_LINK ("Stretch brush: %s", SPECIAL_STRETCH) + HELP_LINK ("Distort brush: %s", SPECIAL_DISTORT) + HELP_LINK ("Outline brush: %s", SPECIAL_OUTLINE) + HELP_LINK ("Nibble brush: %s", SPECIAL_NIBBLE) + HELP_LINK ("Get brush colors: %s", SPECIAL_GET_BRUSH_COLORS) + HELP_LINK ("Recolorize brush: %s", SPECIAL_RECOLORIZE_BRUSH) + HELP_LINK ("Rotate brush: %s", SPECIAL_ROTATE_ANY_ANGLE) + HELP_LINK ("Pipette: %s", 0x100+BUTTON_COLORPICKER) + HELP_LINK ("Swap fore/back color:%s", 0x200+BUTTON_COLORPICKER) + HELP_LINK ("Magnifier mode: %s", 0x100+BUTTON_MAGNIFIER) + HELP_LINK ("Zoom factor menu: %s", 0x200+BUTTON_MAGNIFIER) + HELP_LINK ("Zoom in: %s", SPECIAL_ZOOM_IN) + HELP_LINK ("Zoom out: %s", SPECIAL_ZOOM_OUT) + HELP_LINK ("Brush effects menu: %s", 0x100+BUTTON_BRUSH_EFFECTS) + HELP_LINK ("Text: %s", 0x100+BUTTON_TEXT) + HELP_LINK ("Resolution menu: %s", 0x100+BUTTON_RESOL) + HELP_LINK ("Safety resolution: %s", 0x200+BUTTON_RESOL) + HELP_LINK ("Help: %s", 0x100+BUTTON_HELP) + HELP_LINK ("Statistics: %s", 0x200+BUTTON_HELP) + HELP_LINK ("Go to spare page: %s", 0x100+BUTTON_PAGE) + HELP_LINK ("Copy to spare page: %s", 0x200+BUTTON_PAGE) + HELP_LINK ("Save as: %s", 0x100+BUTTON_SAVE) + HELP_LINK ("Save: %s", 0x200+BUTTON_SAVE) + HELP_LINK ("Load: %s", 0x100+BUTTON_LOAD) + HELP_LINK ("Re-load: %s", 0x200+BUTTON_LOAD) + HELP_LINK ("Save brush: %s", SPECIAL_SAVE_BRUSH) + HELP_LINK ("Load brush: %s", SPECIAL_LOAD_BRUSH) + HELP_LINK ("Larger brush size: %s", SPECIAL_BIGGER_PAINTBRUSH) + HELP_LINK ("Smaller brush size: %s", SPECIAL_SMALLER_PAINTBRUSH) + HELP_LINK ("Settings: %s", 0x100+BUTTON_SETTINGS) + HELP_LINK ("Undo: %s", 0x100+BUTTON_UNDO) + HELP_LINK ("Redo: %s", 0x200+BUTTON_UNDO) + HELP_LINK ("Kill page: %s", 0x100+BUTTON_KILL) + HELP_LINK ("Clear: %s", 0x100+BUTTON_CLEAR) + HELP_LINK ("Clear with BG color: %s", 0x200+BUTTON_CLEAR) + HELP_LINK ("Quit: %s", 0x100+BUTTON_QUIT) + HELP_LINK ("Palette menu: %s", 0x100+BUTTON_PALETTE) + HELP_LINK ("2nd Palette menu: %s", 0x200+BUTTON_PALETTE) + HELP_LINK ("Exclude colors menu: %s", SPECIAL_EXCLUDE_COLORS_MENU) + HELP_TEXT ("") + HELP_TEXT ("Scroll palette") + HELP_LINK (" Back: %s", 0x100+BUTTON_PAL_LEFT) + HELP_LINK (" Forward: %s", 0x100+BUTTON_PAL_RIGHT) + HELP_LINK (" Back faster: %s", 0x200+BUTTON_PAL_LEFT) + HELP_LINK (" Forward faster: %s", 0x200+BUTTON_PAL_RIGHT) + HELP_TEXT ("") + HELP_TEXT ("Change brush attachement") + HELP_LINK (" Center : %s", SPECIAL_CENTER_ATTACHMENT) + HELP_LINK (" Top-left : %s", SPECIAL_TOP_LEFT_ATTACHMENT) + HELP_LINK (" Top-right : %s", SPECIAL_TOP_RIGHT_ATTACHMENT) + HELP_LINK (" Bottom-left : %s", SPECIAL_BOTTOM_LEFT_ATTACHMENT) + HELP_LINK (" Bottom-right: %s", SPECIAL_BOTTOM_RIGHT_ATTACHMENT) + HELP_TEXT ("") + HELP_TEXT ("Select foreground color") + HELP_TEXT ("") + HELP_LINK (" Next : %s", SPECIAL_NEXT_FORECOLOR) + HELP_LINK (" Previous: %s", SPECIAL_PREVIOUS_FORECOLOR) + HELP_TEXT ("") + HELP_TEXT ("Select background color") + HELP_LINK (" Next : %s", SPECIAL_NEXT_BACKCOLOR) + HELP_LINK (" Previous: %s", SPECIAL_PREVIOUS_BACKCOLOR) + HELP_TEXT ("") + HELP_TEXT ("Select user-defined foreground color") + HELP_TEXT ("") + HELP_LINK (" Next : %s", SPECIAL_NEXT_USER_FORECOLOR) + HELP_LINK (" Previous: %s", SPECIAL_PREVIOUS_USER_FORECOLOR) + HELP_TEXT ("") + HELP_TEXT ("Select user-defined background color") + HELP_LINK (" Next : %s", SPECIAL_NEXT_USER_BACKCOLOR) + HELP_LINK (" Previous: %s", SPECIAL_PREVIOUS_USER_BACKCOLOR) + HELP_TEXT ("") +}; +static const T_Help_table helptable_credits[] = +{ +//HELP_TEXT ("0----5----0----5----0----5----0----5----0--X") + HELP_TITLE(" GRAFX2 IS CREATED BY") + HELP_TEXT ("") + HELP_BOLD (" SUNSET DESIGN") + HELP_BOLD (" AUTHORS OF GRAFX2.0 BETA 96.5%") + HELP_TEXT ("") + HELP_TEXT (" Guillaume Dorme alias \"Robinson\" (code)") + HELP_TEXT (" Karl Maritaud alias \"X-Man\" (code&gfx)") +//HELP_TEXT ("0----5----0----5----0----5----0----5----0--X") + HELP_TEXT ("") + HELP_TEXT (" Re-licensed GrafX2 under the GPL in 2001") + HELP_TEXT ("") + HELP_BOLD (" THE GRAFX2 PROJECT TEAM") + HELP_TEXT ("") + HELP_TEXT (" Adrien Destugues (pulkomandy)") + HELP_TEXT (" Yves Rizoud (yrizoud)") + HELP_TEXT ("") + HELP_TEXT (" Got the source back to life in 2006") + HELP_TEXT ("") + HELP_BOLD (" ART") + HELP_TEXT ("") + HELP_TEXT (" GrafX2 logo by Made (www.m4de.com)") + HELP_TEXT (" Icons and fonts by X-Man ") + HELP_TEXT (" Additional graphics and logo by iLKke") + HELP_TEXT (" (ilkke.blogspot.com)") + HELP_TEXT ("") + HELP_TEXT (" Pixelled all the graphics") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE(" OTHER MACHINES PORTS") + HELP_TEXT ("") + HELP_BOLD (" AMIGA OS 3 PORT") + HELP_TEXT ("") + HELP_TEXT (" Artur Jarosik") + HELP_TEXT ("") + HELP_BOLD (" AMIGA OS 4 PORT") + HELP_TEXT ("") + HELP_TEXT (" Peter Gordon (www.petergordon.org.uk)") + HELP_TEXT ("") + HELP_BOLD (" AROS PORT") + HELP_TEXT ("") + HELP_TEXT (" Fernando Mastandrea (masta.uy)") + HELP_TEXT (" Markus Weiss") + HELP_TEXT ("") + HELP_BOLD (" FREEBSD PORT") + HELP_TEXT ("") + HELP_TEXT (" Jean-Baptiste Berlioz (Tobe)") + HELP_TEXT ("") + HELP_BOLD (" HAIKU OS AND BEOS PORT") + HELP_TEXT ("") + HELP_TEXT (" Luc Schrijvers (Begasus)") + HELP_TEXT ("") + HELP_BOLD (" MAC OS X PORT") + HELP_TEXT ("") + HELP_TEXT (" Franck Charlet (hitchhikr)") + HELP_TEXT (" Per Olofsson (MagerValp)") + HELP_TEXT ("") + HELP_BOLD (" MORPHOS PORT") + HELP_TEXT ("") + HELP_TEXT (" Rusback") + HELP_TEXT ("") + HELP_BOLD (" SKYOS PORT") + HELP_TEXT ("") + HELP_TEXT (" Luc Schrijvers (Begasus)") + HELP_TEXT ("") + HELP_TEXT (" ... made it work on your favourite toaster") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE(" BUGFINDERS") + HELP_TEXT ("") +//HELP_TEXT ("0----5----0----5----0----5----0----5----0--X") + HELP_TEXT (" blumunkee BDCIron Ced ") + HELP_TEXT (" El Topo fallenblood Frost ") + HELP_TEXT (" Grimmy Gürkan Sengün HoraK-FDF ") + HELP_TEXT (" iLKke Jamon keito ") + HELP_TEXT (" kusma Lord Graga MagerValp ") + HELP_TEXT (" mind MooZ the Peach ") + HELP_TEXT (" richienyhus tape.wyrm TeeEmCee ") + HELP_TEXT (" tempest Timo Kurrpa titus^Rab ") + HELP_TEXT (" Tobé 00ai99 ") + HELP_TEXT ("") + HELP_TEXT (" ... posted the annoying bug reports.") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE(" FILE FORMATS CREDITS") + HELP_TEXT ("") + HELP_TEXT (" BMP : Microsoft") + HELP_TEXT (" CEL,KCF : K.O.S. (KISekae Set system)") + HELP_TEXT (" GIF : Compuserve") + HELP_TEXT (" IMG : Bivas (W. Wiedmann?)") + HELP_TEXT (" LBM : Electronic Arts") + HELP_TEXT (" PAL : ermmh... nobody (?)") + HELP_TEXT (" PCX : Z-Soft") + HELP_TEXT (" PI1,PC1 : Degas Elite") + HELP_TEXT (" PKM : Sunset Design") + HELP_TEXT (" PNG : W3C") + HELP_TEXT (" SCx : Colorix (?)") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE (" OUR HOMEPAGE") + HELP_TEXT ("") + HELP_BOLD (" http://grafx2.codegoogle.com") + HELP_TEXT ("") + HELP_TEXT (" Please report any bug you may find there") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE (" GREETINGS") + HELP_TEXT ("") + HELP_TEXT (" To the Pouet.net BBS posters, the #CPC") + HELP_TEXT (" trolls and the bitfellas") + HELP_TEXT (" To every people who makes the scene alive!") + HELP_TEXT (" To all guys making nice pixelled pictures") + HELP_TEXT (" (with or without GrafX2)") + HELP_TEXT ("") + HELP_BOLD (" We send our best regards to...") + HELP_TEXT ("") + HELP_TEXT (" Access Filter Pink") + HELP_TEXT (" Ace Fiver Pixel") + HELP_TEXT (" AcidJam Flan Profil") + HELP_TEXT (" Acryl Fred Prowler") + HELP_TEXT (" Alexel FreddyV Puznik") + HELP_TEXT (" Alias Frost Quick") + HELP_TEXT (" Amiral Gaël(GDC) Ra") + HELP_TEXT (" Arrakis GainX Raster") + HELP_TEXT (" Avocado Gandalf Ravian") + HELP_TEXT (" Baloo Goblin RedBug") + HELP_TEXT (" Barti Greenpix7 Rem") + HELP_TEXT (" Bat Grid Rez") + HELP_TEXT (" Biro GrosQuick Roudoudou") + HELP_TEXT (" Bisounours HackerCroll Sacrilege") + HELP_TEXT (" BlackAxe Haplo Sam") + HELP_TEXT (" Bonnie Hof SandMan") + HELP_TEXT (" Boo Hornet Scape") + HELP_TEXT (" Boz Hulud Sébastien") + HELP_TEXT (" Carine Java Shodan") + HELP_TEXT (" Chandra JBT Skal") + HELP_TEXT (" Cheetah Jérôme Skyfire") + HELP_TEXT (" Chill Julien(JCA) Sphair") + HELP_TEXT (" Cougar KalMinDo Sprocket") + HELP_TEXT (" Cremax KaneWood Stef") + HELP_TEXT (" Cyclone Karma Stony") + HELP_TEXT (" Dake Keith303 Sumaleth") + HELP_TEXT (" Danny Lazur Sunday") + HELP_TEXT (" Danube LightShow Suny") + HELP_TEXT (" Darjul Lluvia Sybaris") + HELP_TEXT (" Darwin Louie TBF") + HELP_TEXT (" DarkAngel Luk Tempest") + HELP_TEXT (" Das Made Thor") + HELP_TEXT (" Decker Mamos TMK") + HELP_TEXT (" DerPiipo Mandrixx TwoFace") + HELP_TEXT (" Destop Mangue Underking") + HELP_TEXT (" Diabolo Mars Unreal") + HELP_TEXT (" DineS Mephisto VaeVictis") + HELP_TEXT (" Drac Mercure Vastator") + HELP_TEXT (" DrYes Mirec Vatin") + HELP_TEXT (" Edyx Moa Veckman") + HELP_TEXT (" Eller Moxica Wain") + HELP_TEXT (" Ellyn MRK Wally") + HELP_TEXT (" EOF Nitch WillBe") + HELP_TEXT (" Fall Noal Xoomie") + HELP_TEXT (" Fame Nytrik Xtrm") + HELP_TEXT (" Fantom Optic YannSulu") + HELP_TEXT (" Fear Orome Z") + HELP_TEXT (" Feather Pahladin Zeb") + HELP_TEXT (" Fennec Phar Zebig") + HELP_TEXT ("") + HELP_TEXT (" and all #pixel, #demofr and #coders.") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE (" SNAIL MAIL") + HELP_TEXT ("") + HELP_TEXT (" (From 2001, current status: unknown)") + HELP_TEXT ("") + HELP_TEXT (" GUILLAUME DORME (Robinson)") + HELP_TEXT (" 15, rue de l'observatoire") + HELP_TEXT (" 87000 LIMOGES (FRANCE)") + HELP_TEXT ("") + HELP_TEXT (" KARL MARITAUD (X-Man)") + HELP_TEXT (" 10, rue de la Brasserie") + HELP_TEXT (" 87000 LIMOGES (FRANCE)") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE(" THANKS") + HELP_TEXT ("") + HELP_TEXT (" Some information taken from several docs") + HELP_TEXT (" (PCGPE, Intervue, PC Interdit...)") + HELP_TEXT (" gave us an invaluable help.") + HELP_TEXT ("") + HELP_TEXT (" Thanks to Shawn Hargreaves for his filled") + HELP_TEXT (" polygon routine from Allegro v2.2.") + HELP_TEXT ("") + HELP_TEXT (" Thanks to Carlos \"Made\" Pardo for his") + HELP_TEXT (" great GrafX2 logo.") + HELP_TEXT ("") + HELP_TEXT (" This is our very first program compiled") + HELP_TEXT (" with the Gnu C Compiler.") + HELP_TEXT (" A thousand thanks to the authors of") + HELP_TEXT (" this compiler.") + HELP_TEXT ("") + HELP_TEXT (" We also would like to thank all the") + HELP_TEXT (" people who gave us ideas to improve") + HELP_TEXT (" GrafX2.") + HELP_TITLE("") +}; +static const T_Help_table helptable_paintbrush[] = +{ + HELP_TITLE("PAINTBRUSHES") + HELP_TEXT ("") + HELP_BOLD (" LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_PAINTBRUSHES) + HELP_TEXT ("") + HELP_TEXT ("Displays a menu where you can choose the") + HELP_TEXT ("shape of your paintbrush.") + HELP_TEXT ("") + HELP_TEXT ("Paintbrushes are sorted by family. You can") + HELP_TEXT ("see some paintbrushes of the same family but") + HELP_TEXT ("with different sizes. There is at least one") + HELP_TEXT ("paint-brush from each family displayed in") + HELP_TEXT ("this menu.") + HELP_TEXT ("Here is the list of all the different") + HELP_TEXT ("paintbrush families:") + HELP_TEXT ("") + HELP_TEXT ("******* *** * * * * * * ") + HELP_TEXT ("******* ***** * * * * * * ") + HELP_TEXT ("******* ******* * * * * * * * * ") + HELP_TEXT ("******* ******* * * * * * * ") + HELP_TEXT ("******* ******* * * * * * * * * ") + HELP_TEXT ("******* ***** * * * * * * ") + HELP_TEXT ("******* *** * * * * * * ") + HELP_TEXT ("") + HELP_TEXT ("Square Disc Sieve Sieve ") + HELP_TEXT (" square disc ") + HELP_TEXT (" ") + HELP_TEXT (" * * * ") + HELP_TEXT (" *** * * * ") + HELP_TEXT (" ***** * * ") + HELP_TEXT ("******* ******* * ") + HELP_TEXT (" ***** * * * * ") + HELP_TEXT (" *** * ") + HELP_TEXT (" * * * * ") + HELP_TEXT (" ") + HELP_TEXT ("Diamond Random Horiz. Vertical") + HELP_TEXT (" bar bar ") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TEXT (" * * * * *") + HELP_TEXT (" * * * * *") + HELP_TEXT (" * * * * *") + HELP_TEXT (" * * * *******") + HELP_TEXT (" * * * * *") + HELP_TEXT (" * * * * *") + HELP_TEXT ("* * * * *") + HELP_TEXT ("") + HELP_TEXT (" Slash Back- Cross X Cross +") + HELP_TEXT (" slash") + HELP_TEXT ("") + HELP_TEXT ("When using one of these, you can change the") + HELP_TEXT ("brush size by using the keys:") + HELP_LINK ("Reduce : %s", SPECIAL_SMALLER_PAINTBRUSH) + HELP_LINK ("Increase : %s", SPECIAL_BIGGER_PAINTBRUSH) + HELP_TEXT ("The last 3 paintbrushes in the menu belong") + HELP_TEXT ("to the \"miscellaneous\" family and their size") + HELP_TEXT ("cannot be modified.") + HELP_TEXT ("") + HELP_BOLD (" RIGHT CLICK ") + HELP_LINK ("(Key:%s)",0x200+BUTTON_PAINTBRUSHES) + HELP_TEXT ("") + HELP_TEXT ("Transforms your current user-defined brush") + HELP_TEXT ("into a paintbrush. This is actually a") + HELP_TEXT ("\"monochromisation\" of your user-defined") + HELP_TEXT ("brush. This means that every color of the") + HELP_TEXT ("brush that aren't the Back-color will be") + HELP_TEXT ("set to the Fore-color. But this option") + HELP_TEXT ("doesn't alter the brush: you'll just have") + HELP_TEXT ("to right-click on the \"Get brush\" buttons") + HELP_TEXT ("to get your brush back.") + HELP_TEXT ("") + HELP_TEXT ("Note: When you press (not in the menu) the") + HELP_LINK ("key %s, the current",SPECIAL_DOT_PAINTBRUSH) + HELP_TEXT ("paintbrush becomes the smallest member of") + HELP_TEXT ("the \"Disc\" family: i.e one pixel.") + +}; +static const T_Help_table helptable_adjust[] = +{ + HELP_TITLE("ADJUST OR TRANSFORM") + HELP_TITLE(" PICTURE") + HELP_TEXT ("") + HELP_BOLD (" LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_ADJUST) + HELP_TEXT ("") + HELP_TEXT ("Allows you to scroll the picture to") + HELP_TEXT ("re-center your graph for example.") + HELP_TEXT ("") + HELP_TEXT ("Any part of the picture that goes out of") + HELP_TEXT ("the image by a side comes back by the") + HELP_TEXT ("opposite one.") + HELP_TEXT ("") + HELP_TEXT ("It is assimilated to the drawing tools") + HELP_TEXT ("family.") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_BOLD (" RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_ADJUST) + HELP_TEXT ("") + HELP_TEXT ("Opens the Picture Transform menu.") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE("PICTURE TRANSFORM") + HELP_TEXT ("") + HELP_BOLD ("RESCALE") + HELP_TEXT ("") + HELP_TEXT ("Allows you to change the image's size,") + HELP_TEXT ("rescaling it accordingly. Enter new size") + HELP_TEXT ("and press RESIZE to confirm.") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TEXT ("When 'Lock proportions' is checked and you") + HELP_TEXT ("change one dimension, the other one is") + HELP_TEXT ("automatically adjusted to preserve the") + HELP_TEXT ("proportions of the original image.") + HELP_TEXT ("") + HELP_TEXT ("You can use the dropdown button to choose") + HELP_TEXT ("between three ways to enter the dimensions:") + HELP_TEXT ("") + HELP_TEXT ("In 'Pixels' mode, the column 'old' shows") + HELP_TEXT ("the original dimensions, and you can set") + HELP_TEXT ("the new size in pixels.") + HELP_TEXT ("") + HELP_TEXT ("In 'Percent' mode, you set a percentage") + HELP_TEXT ("compared to the original image.") + HELP_TEXT ("") + HELP_TEXT ("In 'Ratio' mode, you can set 2 numbers for") + HELP_TEXT ("each dimension, and the resizing factor will") + HELP_TEXT ("be of 'new'÷'old'. For example you can use") + HELP_TEXT ("1:3 to divide the image by three, 2:1 to") + HELP_TEXT ("double it, and any fraction like 15:16.") + HELP_TEXT ("") + HELP_TEXT ("Be careful that moving from one mode to the") + HELP_TEXT ("next can lose precision, if the selected") + HELP_TEXT ("dimensions cannot be represented exactly in") + HELP_TEXT ("the new mode.") + HELP_TEXT ("") + HELP_BOLD ("MIRROR") + HELP_TEXT ("") + HELP_TEXT ("- X: Flip the picture horizontally.") + HELP_TEXT ("") + HELP_TEXT ("- Y: Flip the picture vertically.") + HELP_TEXT ("") + HELP_BOLD ("ROTATE") + HELP_TEXT ("") + HELP_TEXT ("-90°: Rotates the image by 90°") + HELP_TEXT (" clockwise.") + HELP_TEXT ("") + HELP_TEXT ("+90°: Rotates the image by 90°") + HELP_TEXT (" counter-clockwise.") + HELP_TEXT ("180°: Rotates the image by 180°") + HELP_TEXT ("") + HELP_TEXT ("") +}; +static const T_Help_table helptable_draw[] = +{ + HELP_TITLE("HAND-DRAWING") + HELP_TEXT ("") + HELP_BOLD (" LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_DRAW) + HELP_TEXT ("") + HELP_TEXT ("Selects the current hand-drawing mode as the") + HELP_TEXT ("active drawing tool. There are 4") + HELP_TEXT ("hand-drawing modes:") + HELP_TEXT ("") + HELP_TEXT ("Continuous hand-drawing: as you move the") + HELP_TEXT ("mouse, the paintbrush is regularily pasted") + HELP_TEXT ("on the picture. This drawing tool allows to") + HELP_TEXT ("change the fore and back colors when being") + HELP_TEXT ("in use.") + HELP_TEXT ("") + HELP_TEXT ("Discontinuous hand-drawing: as you move the") + HELP_TEXT ("mouse, the paintbrush is pasted on the") + HELP_TEXT ("picture every time a delay is passed") + HELP_TEXT ("(actually, the delay is 1 VBL") + HELP_TEXT ("(vertical blanking)). This drawing tool") + HELP_TEXT ("allows to change the fore and back colors") + HELP_TEXT ("when being in use.") + HELP_TEXT ("") + HELP_TEXT ("Dot by dot hand-drawing: the paintbrush is") + HELP_TEXT ("only pasted at the position where you first") + HELP_TEXT ("clicked.") + HELP_TEXT ("") + HELP_TEXT ("Contour fill: Draws pixels like continuous") + HELP_TEXT ("mode, but when you release the button Grafx2") + HELP_TEXT ("draws a line back to your starting position,") + HELP_TEXT ("and fills the area. This tool doesn't use the") + HELP_TEXT ("current brush, but single pixels.") + HELP_TEXT ("") + HELP_BOLD (" RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_DRAW) + HELP_TEXT ("") + HELP_TEXT ("Toggles the different hand-drawing modes") + HELP_TEXT ("and activates, at the same time, the") + HELP_TEXT ("hand-drawing tool.") +}; +static const T_Help_table helptable_curves[] = +{ + HELP_TITLE("SPLINES") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_CURVES) + HELP_TEXT ("") + HELP_TEXT ("Selects the current curve-drawing mode as") + HELP_TEXT ("the active drawing tool. There are 2") + HELP_TEXT ("different curve-drawing modes:") + HELP_TEXT ("") + HELP_TEXT ("* 4 control points curves: define the basic") + HELP_TEXT ("line like a classical line, then move, with") + HELP_TEXT ("the left mouse button, the inner control") + HELP_TEXT ("points to choose the shape of your curve.") + HELP_TEXT ("When the curve has the shape you want, click") + HELP_TEXT ("with the right mouse button to draw it") + HELP_TEXT ("definitively.") + HELP_TEXT ("") + HELP_TEXT ("* 3 control points curves: the same as") + HELP_TEXT ("above, but you'll have only one inner") + HELP_TEXT ("control point to place. Moreover, the spline") + HELP_TEXT ("will be traced just after placing this") + HELP_TEXT ("point.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_CURVES) + HELP_TEXT ("") + HELP_TEXT ("Toggles the different curve-drawing modes") + HELP_TEXT ("and activates, at the same time, the") + HELP_TEXT ("curve-drawing tool.") +}; +static const T_Help_table helptable_lines[] = +{ + HELP_TITLE("LINES") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_LINES) + HELP_TEXT ("") + HELP_TEXT ("Selects the current line-drawing mode as the") + HELP_TEXT ("active drawing tool. There are 3") + HELP_TEXT ("line-drawing modes:") + HELP_TEXT ("") + HELP_TEXT ("* Classical lines: when first clicking on") + HELP_TEXT ("the picture, you'll define the start of the") + HELP_TEXT ("line. Maintain your click to choose the end") + HELP_TEXT ("of the line and release the mouse button to") + HELP_TEXT ("set it.") + HELP_TEXT ("If you hold SHIFT when drawing, the line") + HELP_TEXT ("will be constrained to horizonal, vertical") + HELP_TEXT ("or diagonal.") + HELP_TEXT ("") + HELP_TEXT ("* Knotted lines: works like classical lines,") + HELP_TEXT ("but the end of your line will automatically") + HELP_TEXT ("become the start of the next one. When you") + HELP_TEXT ("want to stop chaining lines, use the") + HELP_TEXT ("opposite mouse button. \"The opposite button\"") + HELP_TEXT ("means that if you started to draw lignes") + HELP_TEXT ("with the left button (Fore-color), you'll") + HELP_TEXT ("have to stop the procedure with the right") + HELP_TEXT ("button; and conversely.") + HELP_TEXT ("") + HELP_TEXT ("* Concentric lines: when first clicking on") + HELP_TEXT ("the picture, you'll define center of the") + HELP_TEXT ("lines. In fact, the center is defined by the") + HELP_TEXT ("the position of the mouse when you release") + HELP_TEXT ("the mouse button. Then you can draw lines") + HELP_TEXT ("from the center to the current mouse") + HELP_TEXT ("position by clicking. To stop drawing") + HELP_TEXT ("concentric lines, use the opposite mouse") + HELP_TEXT ("button. This drawing tool allows to change") + HELP_TEXT ("the fore and back colors when being in use.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_LINES) + HELP_TEXT ("") + HELP_TEXT ("Toggles the different line-drawing modes and") + HELP_TEXT ("activates, at the same time, the") + HELP_TEXT ("line-drawing tool.") + +}; +static const T_Help_table helptable_airbrush[] = +{ + HELP_TITLE("SPRAY") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_AIRBRUSH) + HELP_TEXT ("") + HELP_TEXT ("Selects the spray as the active drawing") + HELP_TEXT ("tool. This drawing tool allows to change the") + HELP_TEXT ("fore and back colors when being in use.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_AIRBRUSH) + HELP_TEXT ("") + HELP_TEXT ("Displays a menu where you can configure the") + HELP_TEXT ("spray:") + HELP_TEXT ("") + HELP_TEXT ("- Size: Defines the diameter of the circle") + HELP_TEXT ("in which will effectively fit the spray.") + HELP_TEXT ("") + HELP_TEXT ("- Delay: Defines the number of VBLs that") + HELP_TEXT ("will be waited for between two flows of") + HELP_TEXT ("spray.") + HELP_TEXT ("") + HELP_TEXT ("- Mode: Defines whether you want to use a") + HELP_TEXT ("monochrome spray or a multi- colored one.") + HELP_TEXT ("") + HELP_TEXT ("- Mono-flow: Defines the number of") + HELP_TEXT ("paintbrushes that will be pasted in the") + HELP_TEXT ("circle of the spray at each cycle.") + HELP_TEXT ("") + HELP_TEXT ("- Palette: Left-click on a color of the") + HELP_TEXT ("palette to see how much it will be used in") + HELP_TEXT ("the multicolored flow, and modify it by") + HELP_TEXT ("using the gauge on the right. If the flow of") + HELP_TEXT ("this color was equal to 0, then the \"Init\"") + HELP_TEXT ("value will be applied. Or set the flow of a") + HELP_TEXT ("color to 0 by clicking on it with the right") + HELP_TEXT ("mouse button.") + HELP_TEXT ("") + HELP_TEXT ("- Clear: Removes all the colors from the") + HELP_TEXT ("multicolored flow. Actually, this puts a 0") + HELP_TEXT ("value in the use of each color.") + HELP_TEXT ("") + HELP_TEXT ("- Init: Allows you to define a value that") + HELP_TEXT ("will be set to the color you click on in the") + HELP_TEXT ("palette if its value is equal to 0. This") + HELP_TEXT ("permits to tag a set of colors more quickly.") + HELP_TEXT ("") + HELP_TEXT ("- +1,-1,x2,/2: Modify the values of all the") + HELP_TEXT ("tagged colors (and only them).") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TEXT ("Tip: If you often use the Shade mode, and") + HELP_TEXT ("are bored to click many times on a color to") + HELP_TEXT ("reach the color you want, you can define a") + HELP_TEXT ("spray with \"Size\"=1, \"Mono-flow\"=1, and") + HELP_TEXT ("\"Delay\"=2 (or more, according to your") + HELP_TEXT ("reflexes). And then, you'll just have to") + HELP_TEXT ("click a few hundredths of second to modify a") + HELP_TEXT ("color.") +}; +static const T_Help_table helptable_floodfill[] = +{ + HELP_TITLE("FLOODFILL") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_FLOODFILL) + HELP_TEXT ("") + HELP_TEXT ("Selects the filler as the active drawing") + HELP_TEXT ("tool. The filler, as any drawing tool, will") + HELP_TEXT ("be affected by all the effects!") + HELP_TEXT ("") + HELP_TEXT ("Note that only the visible part of the") + HELP_TEXT ("picture will be filled (as every other") + HELP_TEXT ("drawing tools, the floodfill only alters the") + HELP_TEXT ("visible part of the picture; this avoids") + HELP_TEXT ("unwanted effects that wouldn't be controlled") + HELP_TEXT ("by the user).") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_FLOODFILL) + HELP_TEXT ("") + HELP_TEXT ("Selects the color replacement as the active") + HELP_TEXT ("drawing tool.") + HELP_TEXT ("") + HELP_TEXT ("Any rule has its exceptions and this one") + HELP_TEXT ("doesn't depart from that. Indeed, this tool") + HELP_TEXT ("is the only one to be affected by no effect") + HELP_TEXT ("(except Stencil) and to be able to modify") + HELP_TEXT ("non visible parts of the picture.") + HELP_TEXT ("The function of this tool being replacing") + HELP_TEXT ("all the occurences of a color in the picture") + HELP_TEXT ("by another, if would have been a shame to") + HELP_TEXT ("limit modifications only to the visible part") + HELP_TEXT ("of the picture.") +}; +static const T_Help_table helptable_polygons[] = +{ + HELP_TITLE("POLYGONS") + HELP_TITLE("POLYFORMS") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_POLYGONS) + HELP_TEXT ("") + HELP_TEXT ("Selects the polygons as the active drawing") + HELP_TEXT ("tool.") + HELP_TEXT ("") + HELP_TEXT ("This works just like knotted-lines but loops") + HELP_TEXT ("the extremities when you're finished.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_POLYGONS) + HELP_TEXT ("") + HELP_TEXT ("Selects the polyforms as the active drawing") + HELP_TEXT ("tool.") + HELP_TEXT ("") + HELP_TEXT ("This works like a combination of free-hand") + HELP_TEXT ("drawing and knotted-lines. If you keep the") + HELP_TEXT ("mouse button pressed, you'll draw as if you") + HELP_TEXT ("were in free-hand drawing mode. And, if you") + HELP_TEXT ("release the mouse button, it will work like") + HELP_TEXT ("knotted lines.") + HELP_TEXT ("") + HELP_TEXT ("Click on the opposite mouse button (i.e.:") + HELP_TEXT ("click right if you started to draw with the") + HELP_TEXT ("left mouse button, and vice versa) to") + HELP_TEXT ("terminate the operation. The two extremities") + HELP_TEXT ("will be linked automatically.") +}; +static const T_Help_table helptable_polyfill[] = +{ + HELP_TITLE("FILLED POLY") + HELP_LINK ("(Key:%s)",0x100+BUTTON_POLYFILL) + HELP_LINK ("(Key:%s)",0x200+BUTTON_POLYFILL) + HELP_TEXT (" Work exactly the same way as the polygons") + HELP_TEXT ("et polyforms above, but fill in the interior") + HELP_TEXT ("of the drawn shapes.") +}; +static const T_Help_table helptable_rectangles[] = +{ + HELP_TITLE("RECTANGLES") + HELP_LINK ("(Key:%s)",0x100+BUTTON_RECTANGLES) + HELP_TEXT ("") + HELP_TEXT ("Selects the empty rectangles as the active") + HELP_TEXT ("drawing tool.") + HELP_TEXT ("") + HELP_TEXT ("Set a corner of a rectangle. Maintain the") + HELP_TEXT ("click to move the opposite corner and") + HELP_TEXT ("release the mouse button to set it") + HELP_TEXT ("definitively.") +}; +static const T_Help_table helptable_filled_rectangles[] = +{ + HELP_TITLE("FILLED RECT") + HELP_LINK ("(Key:%s)",0x100+BUTTON_FILLRECT) + HELP_TEXT ("") + HELP_TEXT ("Selects the filled rectangles as the active") + HELP_TEXT ("drawing tool.") + HELP_TEXT ("") + HELP_TEXT ("Works like an empty rectangle.") +}; +static const T_Help_table helptable_circles[] = +{ + HELP_TITLE("CIRCLES") + HELP_TITLE("ELLIPSES") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_CIRCLES) + HELP_TEXT ("") + HELP_TEXT ("Selects the empty circles as the active") + HELP_TEXT ("drawing tool.") + HELP_TEXT ("") + HELP_TEXT ("Position the center of the cercle and") + HELP_TEXT ("maintain the mouse button to select its") + HELP_TEXT ("radius.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_CIRCLES) + HELP_TEXT ("") + HELP_TEXT ("Selects the empty ellipses as the active") + HELP_TEXT ("drawing tool.") + HELP_TEXT ("") + HELP_TEXT ("Position the center of the cercle and") + HELP_TEXT ("maintain the mouse button to select its") + HELP_TEXT ("dimensions.") +}; +static const T_Help_table helptable_filled_circles[] = +{ + HELP_TITLE("FILLED CIRCLES") + HELP_TITLE(" AND ELLIPSES") + HELP_TEXT ("") + HELP_BOLD ("FILLED CIRCLES") + HELP_LINK ("(Key:%s)",0x100+BUTTON_CIRCLES) + HELP_TEXT ("") + HELP_TEXT ("Works like empty circles.") + HELP_TEXT ("") + HELP_BOLD ("FILLED ELLIPSES") + HELP_LINK ("(Key:%s)",0x200+BUTTON_CIRCLES) + HELP_TEXT ("") + HELP_TEXT ("Works like empty ellipses.") +}; +static const T_Help_table helptable_grad_rect[] = +{ + HELP_TITLE("GRAD RECTANGLE") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_GRADRECT) + HELP_TEXT ("") + HELP_TEXT ("Selects the rectangle with gradations as") + HELP_TEXT ("the active drawing tool.") + HELP_TEXT ("") + HELP_TEXT ("Set a corner of a rectangle. Maintain the") + HELP_TEXT ("click to move the opposite corner and") + HELP_TEXT ("release the mouse button to set it") + HELP_TEXT ("definitively.") + HELP_TEXT ("") + HELP_TEXT ("If you don't like what you have done and") + HELP_TEXT ("want to restart, you can use the right") + HELP_TEXT ("click to cancel everything at this point.") + HELP_TEXT (" If you think it's nice, then click and hold") + HELP_TEXT ("the mouse in a point you want to have the") + HELP_TEXT ("starting color, drag to a point where you") + HELP_TEXT ("want the ending color, and release the") + HELP_TEXT ("button. You can press SHIFT to enforce your") + HELP_TEXT ("line to be vertical, horizontal, or") + HELP_TEXT ("diagonal.") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_GRADRECT) + HELP_TEXT ("") + HELP_TEXT ("Opens a window where you can define the way") + HELP_TEXT ("gradations are processed. The different") + HELP_TEXT ("sections of this menu are:") + HELP_TEXT ("") + HELP_TEXT ("- Direction (arrow): Switches the direction") + HELP_TEXT ("of the gradation.") + HELP_TEXT ("") + HELP_TEXT ("- Dithering method: Toggles the 3 following") + HELP_TEXT ("methods:") + HELP_TEXT (" - No dithering") + HELP_TEXT (" - Basical dithering") + HELP_TEXT (" - Enhanced dithering") + HELP_TEXT ("") + HELP_TEXT ("- Mix: Mixes the gradation with a more or") + HELP_TEXT ("less random factor.") + HELP_TEXT ("") + HELP_TEXT ("- Palette: Select a color range to build a") + HELP_TEXT ("gradation.") + HELP_TEXT ("") + HELP_TEXT ("- Index scroller: Defines the current") + HELP_TEXT ("gradation among a set of 16 that will be") + HELP_TEXT ("memorised.") +}; +static const T_Help_table helptable_spheres[] = +{ + HELP_TITLE("GRAD SPHERE") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_SPHERES) + HELP_TEXT ("") + HELP_TEXT ("Selects the spheres as the active drawing") + HELP_TEXT ("tool.") + HELP_TEXT ("") + HELP_TEXT ("Position the center of the sphere and") + HELP_TEXT ("maintain the mouse button to select its") + HELP_TEXT ("radius. Then place the spot-light.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_SPHERES) + HELP_TEXT ("") + HELP_TEXT ("Selects the ellipses with gradation as the") + HELP_TEXT ("active drawing tool.") + HELP_TEXT ("") + HELP_TEXT ("Draw the shape like a normal ellipse, and") + HELP_TEXT ("then position the spot-light and click the") + HELP_TEXT ("left mouse button to finish the shape.") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TEXT ("If you trace a sphere or an ellipse with") + HELP_TEXT ("gradation with the right mouse button, the") + HELP_TEXT ("result will be the same figure filled with") + HELP_TEXT ("the Back-color.") +}; +static const T_Help_table helptable_brush[] = +{ + HELP_TITLE("GRAB BRUSH") + HELP_BOLD (" OR RESTORE BRUSH") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_BRUSH) + HELP_TEXT ("") + HELP_TEXT ("Engages a brush grabbing.") + HELP_TEXT ("") + HELP_TEXT ("Click on a corner of the rectangle") + HELP_TEXT ("containing the brush then maintain the click") + HELP_TEXT ("to define the opposite corner of the") + HELP_TEXT ("rectangle. Release the mouse button to grab") + HELP_TEXT ("the brush. Performing this operation with") + HELP_TEXT ("the right mouse button will erase the area") + HELP_TEXT ("where the brush was grabbed with the") + HELP_TEXT ("Back-color.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_BRUSH) + HELP_TEXT ("") + HELP_TEXT ("Restores the old brush.") +}; +static const T_Help_table helptable_polybrush[] = +{ + HELP_TITLE("POLY GRAB") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_POLYBRUSH) + HELP_TEXT ("") + HELP_TEXT ("Grabs a brush of any shape by defining a") + HELP_TEXT ("polyform (please refer to section 8 for more") + HELP_TEXT ("explanations).") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_BRUSH) + HELP_TEXT ("") + HELP_TEXT ("Restores the old brush (same as above).") +}; +static const T_Help_table helptable_brush_fx[] = +{ + HELP_TITLE("BRUSH FX") + HELP_TEXT ("") + HELP_LINK ("(Key:%s)",0x100+BUTTON_BRUSH_EFFECTS) + HELP_TEXT ("") + HELP_TEXT ("Displays a menu where the following options") + HELP_TEXT ("are available:") + HELP_TEXT ("") + HELP_LINK ("- X: (Key:%s)",SPECIAL_FLIP_X) + HELP_TEXT ("Flip horizontally.") + HELP_TEXT ("") + HELP_LINK ("- Y: (Key:%s)",SPECIAL_FLIP_Y) + HELP_TEXT ("Flip vertically.") + HELP_TEXT ("") + HELP_LINK ("- Rotate by 90°: (Key:%s)",SPECIAL_ROTATE_90) + HELP_TEXT ("Rotates the brush by an angle of 90 degrees.") + HELP_TEXT ("") + HELP_LINK ("- Rotate by 180°: (Key:%s)",SPECIAL_ROTATE_180) + HELP_TEXT ("Rotates the brush by an angle of 180") + HELP_TEXT ("degrees.") + HELP_TEXT ("") + HELP_TEXT ("- Rotate by any angle:") + HELP_LINK ("(Key:%s)",SPECIAL_ROTATE_ANY_ANGLE) + HELP_TEXT ("Triggers an interactive operation that") + HELP_TEXT ("allows you to rotate the brush. For this,") + HELP_TEXT ("start by placing the center or rotation with") + HELP_TEXT ("the left mouse button (if, at this moment,") + HELP_TEXT ("you press the right button, the operation") + HELP_TEXT ("with be cancelled). After that, you can") + HELP_TEXT ("define the angle of rotation as many times") + HELP_TEXT ("as you want by moving the mouse and") + HELP_TEXT ("left-clicking. Then validate with the right") + HELP_TEXT ("button when you are satisfied. Meanwhile,") + HELP_TEXT ("you can press on the 8 outer digits of the") + HELP_TEXT ("numeric pad for defining angles multiple of") + HELP_TEXT ("45 degrees:") + HELP_TEXT ("") + HELP_TEXT (" 135 90 45") + HELP_TEXT (" \\ | /") + HELP_TEXT (" '7' '8' '9'") + HELP_TEXT (" 180 -'4' '6'- 0") + HELP_TEXT (" '1' '2' '3'") + HELP_TEXT (" / | \\") + HELP_TEXT (" 225 270 315") + HELP_TEXT ("") + HELP_LINK ("- Stretch: (Key:%s)",SPECIAL_STRETCH) + HELP_TEXT ("Triggers an interactive operation") + HELP_TEXT ("that enables you to stretch the brush. For") + HELP_TEXT ("this, start by placing the upper-left") + HELP_TEXT ("cornerof the brush with the left mouse") + HELP_TEXT ("button (if, at this moment, you press the") + HELP_TEXT ("right button, the operation will be") + HELP_TEXT ("cancelled). after that, you can place the") + HELP_TEXT ("opposite corner as many times as you need,") + HELP_TEXT ("then validate with the right mouse button") + HELP_TEXT ("when you are satisfied. If you place this") + HELP_TEXT ("point at coordinates inferior to the ones of") + HELP_TEXT ("the first point, the brush will be inverted.") + HELP_TEXT ("Meanwhile, you can press the following keys") + HELP_TEXT ("whose effects are: 'D' : double the") + HELP_TEXT ("brush in X and Y 'H' : reduce the") + HELP_TEXT ("brush by half in X and Y 'X' : double") + HELP_TEXT ("the brush in X 'Shift+X': reduce the brush") + HELP_TEXT ("by half in X 'Y' : double the brush") + HELP_TEXT ("in Y 'Shift+Y': reduce the brush by half") + HELP_TEXT ("in Y 'N' : restore the normal size of") + HELP_TEXT ("the brush (can be useful") + HELP_TEXT ("because it's the only way for cancelling)") + HELP_TEXT ("") + HELP_LINK ("- Distort: (Key:%s)",SPECIAL_DISTORT) + HELP_TEXT ("Triggers an interactive operation") + HELP_TEXT ("that allows you to distort your brush.") + HELP_TEXT ("Start by placing the brush somewhere on the") + HELP_TEXT ("screen and left-click. The brush will") + HELP_TEXT ("appear, with a little peg at each corner.") + HELP_TEXT ("Use the left mouse button to displace the") + HELP_TEXT ("corners, which will deform the brush.") + HELP_TEXT ("When you're done, click the right mouse") + HELP_TEXT ("button.") + HELP_TEXT ("") + HELP_LINK ("- Outline: (Key:%s)",SPECIAL_OUTLINE) + HELP_TEXT ("This option permits to draw the") + HELP_TEXT ("outlines of the brush with the Fore- color.") + HELP_TEXT ("") + HELP_LINK ("- Nibble: (Key:%s)",SPECIAL_NIBBLE) + HELP_TEXT ("This option \"nibbles\" the outlines") + HELP_TEXT ("of the brush. It's in some way the opposite") + HELP_TEXT ("effect of the Outline option.") + HELP_TEXT ("") + HELP_LINK ("- Recolorize: (Key:%s)",SPECIAL_RECOLORIZE_BRUSH) + HELP_TEXT ("Remaps the brush so that it") + HELP_TEXT ("looks like it would in the spare page, using") + HELP_TEXT ("the current palette.") + HELP_TEXT ("") + HELP_LINK ("- Get brush colors: (Key:%s)",SPECIAL_GET_BRUSH_COLORS) + HELP_TEXT ("Transfers the spare") + HELP_TEXT ("page's colors used by the brush to the") + HELP_TEXT ("current palette.") + HELP_TEXT ("") + HELP_TEXT ("- Brush handle:") + HELP_TEXT ("Allows you to choose where to place the") + HELP_TEXT ("handle of the brush. Shortcuts are :") + HELP_LINK (" Center : %s", SPECIAL_CENTER_ATTACHMENT) + HELP_LINK (" Top-left : %s", SPECIAL_TOP_LEFT_ATTACHMENT) + HELP_LINK (" Top-right : %s", SPECIAL_TOP_RIGHT_ATTACHMENT) + HELP_LINK (" Bottom-left : %s", SPECIAL_BOTTOM_LEFT_ATTACHMENT) + HELP_LINK (" Bottom-right: %s", SPECIAL_BOTTOM_RIGHT_ATTACHMENT) + HELP_TEXT ("") + HELP_LINK ("- Load : (Key:%s)",SPECIAL_LOAD_BRUSH) + HELP_TEXT ("Load a brush from disk.") + HELP_TEXT ("") + HELP_LINK ("- Save : (Key:%s)",SPECIAL_SAVE_BRUSH) + HELP_TEXT ("Save a brush to disk.") +}; +static const T_Help_table helptable_effects[] = +{ + HELP_TITLE("DRAW MODES") + HELP_LINK ("(Key:%s)",0x100+BUTTON_EFFECTS) + HELP_TEXT ("") + HELP_TEXT (" This button opens a menu where you can") + HELP_TEXT ("switch on or off the different drawing") + HELP_TEXT ("modes.") + HELP_TEXT (" In this menu, the \"All off\" button switches") + HELP_TEXT ("all the drawing modes off. The [Del] key") + HELP_TEXT ("is the keyboard shortcut for this button.") + HELP_TEXT (" The \"Feedback\" button is only used in") + HELP_TEXT ("\"Shade\", \"Quick-shade, \"Transparency\"") + HELP_TEXT ("and \"Smooth\" modes. When it is set, it means") + HELP_TEXT ("that the _current_ state of the picture") + HELP_TEXT ("has to be taken into account for the effect") + HELP_TEXT ("instead of the state in which the image") + HELP_TEXT ("was when you started to click for drawing.") + HELP_TEXT ("The best, as often, is that you try by") + HELP_TEXT ("yourself with and without Feedback to see") + HELP_TEXT ("the difference.") + HELP_TEXT (" The other buttons are the following:") + HELP_TEXT ("") + HELP_TITLE("SHADE") + HELP_TEXT (" It consists in increasing or decreasing the") + HELP_TEXT ("color number within a user-defined range.") + HELP_TEXT ("This shows its real dimension when used with") + HELP_TEXT ("a range of colors that shade off. Then,") + HELP_TEXT ("you can work on a part of your picture where") + HELP_TEXT ("colors belong to the same range without") + HELP_TEXT ("having to change your brush color all the") + HELP_TEXT ("time. You can choose the incrementation or") + HELP_TEXT ("decrementation of the color by pressing") + HELP_TEXT ("the left or right mouse button while") + HELP_TEXT ("drawing. If you click on a color that does") + HELP_TEXT ("not belong to the range, it will remain") + HELP_TEXT ("unchanged.") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key : %s)", SPECIAL_SHADE_MODE) + HELP_TEXT ("") + HELP_TEXT ("Switches the Shade mode.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_SHADE_MENU) + HELP_TEXT ("") + HELP_TEXT ("Opens a menu where you can define one table") + HELP_TEXT ("of shades within a range of 8 memorised by") + HELP_TEXT ("the program. The different sections of this") + HELP_TEXT ("menu are:") + HELP_TEXT ("") + HELP_TEXT ("- Palette: You can define in it the color") + HELP_TEXT ("blocks that will be inserted") + HELP_TEXT ("into the table of shades.") + HELP_TEXT ("") + HELP_TEXT ("- Scroller: Used to change flick through the") + HELP_TEXT ("tables of shades.") + HELP_TEXT ("") + HELP_TEXT ("- Table of shades definition area: The 512") + HELP_TEXT ("squares should be widely") + HELP_TEXT ("sufficient to define the different shades") + HELP_TEXT ("since every 256 colors of") + HELP_TEXT ("the palette cannot be present more than once") + HELP_TEXT ("in each table.") + HELP_TEXT ("") + HELP_TEXT ("- A window (on the top-right side) permits") + HELP_TEXT ("to visualize the different") + HELP_TEXT ("shades defined in he current table.") + HELP_TEXT ("") + HELP_TEXT ("- Copy: Copy the contents of the table in a") + HELP_TEXT ("buffer.") + HELP_TEXT ("(Each time you open this menu, the current") + HELP_TEXT ("table is automatically") + HELP_TEXT ("transfered into this buffer).") + HELP_TEXT ("") + HELP_TEXT ("- Paste: Copy the contents of the buffer") + HELP_TEXT ("above in the current table.") + HELP_TEXT ("") + HELP_TEXT ("- Clear: Reset the \"shades\" table.") + HELP_TEXT ("") + HELP_TEXT ("- Insert: Used to insert the block selected") + HELP_TEXT ("in the palette at the") + HELP_TEXT ("cursor's position in the table of shades.") + HELP_TEXT ("IF you click with the left mouse button on") + HELP_TEXT ("this button THEN IF a block of more than one") + HELP_TEXT ("color is selected in the table THEN It is") + HELP_TEXT ("deleted and the block defined in the palette") + HELP_TEXT ("is inserted. ELSE The block defined in the") + HELP_TEXT ("palette is inserted at the postion just") + HELP_TEXT ("before the selected square. END IF") + HELP_TEXT ("ELSE The block defined in the palette is") + HELP_TEXT ("inserted by erasing the colors following the") + HELP_TEXT ("beginning of the bloc selected in the table.") + HELP_TEXT ("END IF") + HELP_TEXT ("") + HELP_TEXT ("- Delete: Delete the block selected in the") + HELP_TEXT ("table.") + HELP_TEXT ("") + HELP_TEXT ("- Blank: Follows this algorithm:") + HELP_TEXT ("IF you click with the left mouse button on") + HELP_TEXT ("this button THEN Replace the block selected") + HELP_TEXT ("in the table by blank squares.") + HELP_TEXT ("ELSE IF a block of more than one color is") + HELP_TEXT ("selected in the table THEN Insert blank") + HELP_TEXT ("squares to the left and to the right of the") + HELP_TEXT ("block. (this is useful for isolating a") + HELP_TEXT ("shade quickly) ELSE Insert blank squares") + HELP_TEXT ("to the left of the selected square. END IF") + HELP_TEXT ("END IF") + HELP_TEXT ("") + HELP_TEXT ("- Invert: Invert the order of the block") + HELP_TEXT ("selected in the table.") + HELP_TEXT ("") + HELP_TEXT ("- Swap: Allows you you move a block (this") + HELP_TEXT ("exchanges it with what is") + HELP_TEXT ("where you want to move it).") + HELP_TEXT ("") + HELP_TEXT ("- Undo: Cancel the last modification of the") + HELP_TEXT ("table.") + HELP_TEXT ("") + HELP_TEXT ("- The 2 numbers displayed on the right of") + HELP_TEXT ("these buttons are: (above) - the number of") + HELP_TEXT ("the color selected in the palette if only") + HELP_TEXT ("one color is selected. (below) - the number") + HELP_TEXT ("of the color contained in a square in the") + HELP_TEXT ("shades table if this square is the only one") + HELP_TEXT ("selected.") + HELP_TEXT ("") + HELP_TEXT ("- The \"mode\" button displays 3 different") + HELP_TEXT ("modes:") + HELP_TEXT ("\"Normal\": Shades in the range and saturates") + HELP_TEXT ("to its boundaries.") + HELP_TEXT ("\"Loop\": Shades in the range and loops if") + HELP_TEXT ("boundaries are passed.") + HELP_TEXT ("\"No saturation\": Shades in the range and") + HELP_TEXT ("doesn't saturate if boundaries are passed.") + HELP_TEXT ("If the Step (see below) is set to 1, this") + HELP_TEXT ("option does exactly the same as the Normal") + HELP_TEXT ("mode.") + HELP_TEXT ("") + HELP_TEXT ("- Set/Disable: If you want to define several") + HELP_TEXT ("shades in the same table") + HELP_TEXT ("but you'd like these shades not to be") + HELP_TEXT ("effective at the same time, you") + HELP_TEXT ("can mask (disable) some parts of the table") + HELP_TEXT ("so that they will be") + HELP_TEXT ("interpreted a blank squares.") + HELP_TEXT ("To do that, select a block in the table of") + HELP_TEXT ("shades and click on \"Set\".") + HELP_TEXT ("The block will be underlined with a white") + HELP_TEXT ("line; this means that it is") + HELP_TEXT ("disabled.") + HELP_TEXT ("") + HELP_TEXT ("- Clear/Enable: This does exactly the") + HELP_TEXT ("opposite as the button above.") + HELP_TEXT ("") + HELP_TEXT ("- Step: Defines the step of incrementation") + HELP_TEXT ("of the shade. The bigger,") + HELP_TEXT ("the faster you run through the colors of the") + HELP_TEXT ("shade.") + HELP_TEXT ("For example: if the step is 2 and that you") + HELP_TEXT ("have defined a shade with") + HELP_TEXT ("the colors 0,1,4,5,9 and that you click on a") + HELP_TEXT ("pixel of color 1, it will") + HELP_TEXT ("take the value 5 which is 2 positions next") + HELP_TEXT ("in the la table.") + HELP_TEXT ("") + HELP_TEXT ("(We are sorry for these technical") + HELP_TEXT ("considerations quite far from a purely") + HELP_TEXT ("artistic point of view; but know that this") + HELP_TEXT ("effect is really very useful and it is") + HELP_TEXT ("preferable that you understand its whole") + HELP_TEXT ("functionment if you want to fully take") + HELP_TEXT ("advantage of it).") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE("QUICK SHADE") + HELP_TEXT (" This drawing mode has about the same effect") + HELP_TEXT ("as Shade mode's except that it is faster") + HELP_TEXT ("to configurate but a little bit less") + HELP_TEXT ("powerful. When you draw on a color of the") + HELP_TEXT ("image which is between the fore- and the") + HELP_TEXT ("back-color in the palette, the color tends") + HELP_TEXT ("towards the fore-color (according to the") + HELP_TEXT ("step defined) if you draw with the left") + HELP_TEXT ("mouse button, or it tends towards the") + HELP_TEXT ("back-color if you are using the right mouse") + HELP_TEXT ("button.") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_QUICK_SHADE_MODE) + HELP_TEXT ("") + HELP_TEXT ("Switches the Quick-shade mode.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_QUICK_SHADE_MENU) + HELP_TEXT ("") + HELP_TEXT ("Opens a menu with a few parameters that mean") + HELP_TEXT ("exactly the same as in the menu of Shade") + HELP_TEXT ("mode. These parameters are the step and the") + HELP_TEXT ("loop/satu- ration mode (normal, loop, no") + HELP_TEXT ("saturation).") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE("STENCIL") + HELP_TEXT (" It is used to prevent some colors from") + HELP_TEXT ("being modified if you draw on them. The") + HELP_TEXT ("main application of the stencil is when you") + HELP_TEXT ("want to change one color or more into") + HELP_TEXT ("another.") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_STENCIL_MODE) + HELP_TEXT ("") + HELP_TEXT ("Switches the Stencil mode.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_STENCIL_MENU) + HELP_TEXT ("") + HELP_TEXT ("Opens a menu where you can define a stencil.") + HELP_TEXT ("The different sections of this menu are:") + HELP_TEXT ("") + HELP_TEXT ("- Clear: No color is protected.") + HELP_TEXT ("") + HELP_TEXT ("- Invert: Colors that were protected are") + HELP_TEXT ("unprotected and vice versa.") + HELP_TEXT ("") + HELP_TEXT ("- Palette: Select colors that should be") + HELP_TEXT ("protected with the left mouse button or") + HELP_TEXT ("unprotect colors with the right mouse") + HELP_TEXT ("button.") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE("MASK") + HELP_TEXT (" This effect could have been called \"True") + HELP_TEXT ("stencil\" because it protects some parts of") + HELP_TEXT ("the picture instead of some colors. The") + HELP_TEXT ("colors you tag represent the pixels in the") + HELP_TEXT ("spare page, corresponding to the pixels in") + HELP_TEXT ("the current page, that you don't want to") + HELP_TEXT ("alter. For example, draw a simple white") + HELP_TEXT ("figure on a black background in the spare") + HELP_TEXT ("page. Then, tag the black color in the menu") + HELP_TEXT ("of the Mask mode. When you'll draw in the") + HELP_TEXT ("current page, only the pixels corresponding") + HELP_TEXT ("to the white (non-black) ones in the spare") + HELP_TEXT ("page will be modified.") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_MASK_MODE) + HELP_TEXT ("") + HELP_TEXT ("Switches the Mask mode.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_MASK_MENU) + HELP_TEXT ("") + HELP_TEXT ("Opens a menu where you can set the colors of") + HELP_TEXT ("the Mask.") + HELP_TEXT ("This menu works the same way as the one of") + HELP_TEXT ("the Stencil, so please refer to the Stencil") + HELP_TEXT ("paragraph to know how to use it.") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE("GRID") + HELP_TEXT (" This is useful to snap the cursor to the") + HELP_TEXT ("cross-points of a grid. It's generally") + HELP_TEXT ("used to draw a grid before drawing sprites") + HELP_TEXT ("of the same size such as a font or tiles,") + HELP_TEXT ("or for drawing figures or grabbing brushes") + HELP_TEXT ("with their dimensions multiple of the step") + HELP_TEXT ("of the grid.');") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_GRID_MODE) + HELP_TEXT ("") + HELP_TEXT ("Switches the Grid mode.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_GRID_MENU) + HELP_TEXT ("") + HELP_TEXT ("Opens a menu where you can define the grid") + HELP_TEXT ("parameters. These parameters are:") + HELP_TEXT ("") + HELP_TEXT ("- X,Y: Steps of the grid.") + HELP_TEXT ("") + HELP_TEXT ("- dX,dY: Offsets of the grid.") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE("SIEVE") + HELP_TEXT (" This effect allows you, by defining a") + HELP_TEXT ("pattern, to draw only on particular points") + HELP_TEXT ("of the picture. If you are a Manga drawer,") + HELP_TEXT ("you might find this useful to make patterned") + HELP_TEXT ("shades or color transitions.") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_SIEVE_MODE) + HELP_TEXT ("") + HELP_TEXT ("Switches the Sieve mode.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_SIEVE_MENU) + HELP_TEXT ("") + HELP_TEXT ("Opens a menu where you can define the Sieve") + HELP_TEXT ("parameters. This menu consists in:") + HELP_TEXT ("") + HELP_TEXT ("- 16x16 drawing area: You can define a") + HELP_TEXT ("pattern in it (left click => white pixel /") + HELP_TEXT ("right click => black pixel). All the white") + HELP_TEXT ("pixels indicate that, when you'll draw,") + HELP_TEXT ("pixels will be applied on the picture at the") + HELP_TEXT ("corresponding positions whereas black pixels") + HELP_TEXT ("won't modify the picture: whites pixels are") + HELP_TEXT ("the \"holes of the sieve\".") + HELP_TEXT ("") + HELP_TEXT ("- 12 default patterns: They can be copied to") + HELP_TEXT ("the drawing area.") + HELP_TEXT ("") + HELP_TEXT ("- \"Transfer to brush\": Copies the pattern to") + HELP_TEXT ("the brush (white pixels => Fore-color /") + HELP_TEXT ("black pixels => Back-color).") + HELP_TEXT ("") + HELP_TEXT ("- \"Get from brush\": Puts the brush into the") + HELP_TEXT ("drawing area (back-color => black pixels /") + HELP_TEXT ("others => white pixels).") + HELP_TEXT ("") + HELP_TEXT ("- Scrolling 4-arrows pad: Scrolls the") + HELP_TEXT ("pattern in the drawing area.") + HELP_TEXT ("") + HELP_TEXT ("- Resizing 4-arrows pad: Defines the") + HELP_TEXT ("dimensions of the pattern.") + HELP_TEXT ("") + HELP_TEXT ("- Default-value (black or white square):") + HELP_TEXT ("Indicates which value must be inserted when") + HELP_TEXT ("you increase the dimensions of the pattern.") + HELP_TEXT ("") + HELP_TEXT ("- \"Clear\": Sets the whole pattern with the") + HELP_TEXT ("default value (see above).") + HELP_TEXT ("") + HELP_TEXT ("- \"Invert\": It... inverts :) ... black and") + HELP_TEXT ("white pixels.") + HELP_LINK ("(Key: %s)", SPECIAL_INVERT_SIEVE) + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE("TRANSPARENCY") + HELP_TEXT (" This allows to mix the color(s) of the") + HELP_TEXT ("paintbrush with the colors of the picture.") + HELP_TEXT ("It's used to make transparency effects like") + HELP_TEXT ("with watercolors.") + HELP_TEXT ("") + HELP_TEXT ("You can also use the following shortcuts to") + HELP_TEXT ("activate transparency mode and assign an") + HELP_TEXT ("amount of opacity:") + HELP_LINK (" 10%% : %s", SPECIAL_TRANSPARENCY_1) + HELP_LINK (" 20%% : %s", SPECIAL_TRANSPARENCY_2) + HELP_LINK (" 30%% : %s", SPECIAL_TRANSPARENCY_3) + HELP_LINK (" 40%% : %s", SPECIAL_TRANSPARENCY_4) + HELP_LINK (" 50%% : %s", SPECIAL_TRANSPARENCY_5) + HELP_LINK (" 60%% : %s", SPECIAL_TRANSPARENCY_6) + HELP_LINK (" 70%% : %s", SPECIAL_TRANSPARENCY_7) + HELP_LINK (" 80%% : %s", SPECIAL_TRANSPARENCY_8) + HELP_LINK (" 90%% : %s", SPECIAL_TRANSPARENCY_9) + HELP_LINK (" 100%% : %s", SPECIAL_TRANSPARENCY_0) + HELP_TEXT ("If you use two of these shortcuts quickly,") + HELP_TEXT ("the second will set the units for finer") + HELP_TEXT ("control. Ie: 4 5 makes 45%, 0 9 makes 9%.") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_COLORIZE_MODE) + HELP_TEXT ("") + HELP_TEXT ("Switches the Transparency mode.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_COLORIZE_MENU) + HELP_TEXT ("") + HELP_TEXT ("Opens a menu where you can define the") + HELP_TEXT ("Transparency parameters. These parameters") + HELP_TEXT ("are:") + HELP_TEXT ("") + HELP_TEXT ("- Interpolation rate: Indicates the") + HELP_TEXT ("percentage of the applied color that will be") + HELP_TEXT ("considered upon the replaced color.") + HELP_TEXT ("") + HELP_TEXT ("- Interpolation method: Uses an") + HELP_TEXT ("interpolation algorithm to compute the") + HELP_TEXT ("color, according to the interpolation rate.") + HELP_TEXT ("") + HELP_TEXT ("- Additive method: Uses the lightest colors") + HELP_TEXT ("to choose the color to apply. For example:") + HELP_TEXT ("if you want to apply a color RGB:30,20,40 on") + HELP_TEXT ("a color RGB:10,50,20, the color applied will") + HELP_TEXT ("be the one, in the palette, that is the") + HELP_TEXT ("closest to the theoretic color RGB:30,50,40.") + HELP_TEXT ("") + HELP_TEXT ("- Subtractive method: uses the darkest") + HELP_TEXT ("colors to choose the color to apply. For") + HELP_TEXT ("example: if you want to apply a color") + HELP_TEXT ("RGB:30,20,40 on a color RGB:10,50,20, the") + HELP_TEXT ("color applied will be the one, in the") + HELP_TEXT ("palette, that is the closest to the") + HELP_TEXT ("theoretic color RGB:10,20,20.") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE("SMOOTH") + HELP_TEXT (" It provides an easy but not as efficient") + HELP_TEXT ("anti-aliasing as any artist's touch.") + HELP_TEXT ("Anyway this effect finds a better use in") + HELP_TEXT ("making a blurry aspect.") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_SMOOTH_MODE) + HELP_TEXT ("") + HELP_TEXT ("Switches the Smooth mode.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_SMOOTH_MENU) + HELP_TEXT ("") + HELP_TEXT ("Opens a menu where you can define the Smooth") + HELP_TEXT ("matrix or choose one among the 4 ones") + HELP_TEXT ("predefined.") + HELP_TEXT ("The middle square represents the pixel on") + HELP_TEXT ("which you draw and the 8 others represent") + HELP_TEXT ("the neighbour pixels. Then, the point on") + HELP_TEXT ("which one draw will be replaced by the") + HELP_TEXT ("weighted average (according to values of") + HELP_TEXT ("each squares) of the 9 defined points.") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE("SMEAR") + HELP_TEXT (" It smears pixels in the direction you are") + HELP_TEXT ("moving your paintbrush, just as if you") + HELP_TEXT ("wanted to spread fresh paint with your") + HELP_TEXT ("fingers. You can combine this effect with") + HELP_TEXT ("the transparency effect.") + HELP_TEXT ("") + HELP_LINK ("(Key: %s)", SPECIAL_SMEAR_MODE) + HELP_TEXT ("Switches the Smear mode.") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TITLE("TILING") + HELP_TEXT (" It consists in displaying parts of the") + HELP_TEXT ("brush that are adjusted on a tiling when") + HELP_TEXT ("you are drawing. It's mainly used for") + HELP_TEXT ("quickly drawing a background with a") + HELP_TEXT ("pattern, but there is a great number of") + HELP_TEXT ("other possibilities.") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_TILING_MODE) + HELP_TEXT ("") + HELP_TEXT ("Switches the Tiling mode.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key: %s)", SPECIAL_TILING_MENU) + HELP_TEXT ("") + HELP_TEXT ("Opens a menu where you can define the Tiling") + HELP_TEXT ("parameters. These parameters are the offsets") + HELP_TEXT ("of the tiling.") +}; +static const T_Help_table helptable_text[] = +{ + HELP_TITLE("TEXT") + HELP_TEXT ("") + HELP_LINK ("(Key:%s)",0x100+BUTTON_TEXT) + HELP_TEXT ("") + HELP_TEXT ("The text menu allows you to enter some text") + HELP_TEXT ("and render it as a brush.") + HELP_TEXT ("The current background and foreground colors") + HELP_TEXT ("are very important, they determine the text") + HELP_TEXT ("color, the transparent color, and also the") + HELP_TEXT ("color range to use for antialiasing.") + HELP_TEXT ("GrafX2 can use 'bitmap' fonts as long as") + HELP_TEXT ("they are in the special layout supported ") + HELP_TEXT ("by SFont.") + HELP_TEXT ("TrueType fonts can also be used if this") + HELP_TEXT ("version of GrafX2 was compiled with") + HELP_TEXT ("TrueType support.") + HELP_TEXT ("") + HELP_TEXT ("- Txt: Click and enter your text here, a") + HELP_TEXT ("line of up to 250 characters.") + HELP_TEXT ("") + HELP_TEXT ("- Clear txt: Empties the current text.") + HELP_TEXT ("When the text is empty, a standard string") + HELP_TEXT ("is shown instead in the preview area.") + HELP_TEXT ("") + HELP_TEXT ("- Antialias: Click to enable or disable") + HELP_TEXT ("Antialiasing. Only affects TrueType fonts.") + HELP_TEXT ("") + HELP_TEXT ("- Size: Determine the font height. Only") + HELP_TEXT ("affects TrueType fonts.") + HELP_TEXT ("") + HELP_TEXT ("- Font selector: Choose a font. You can") + HELP_TEXT ("use the arrow keys (up and down) to quickly") + HELP_TEXT ("browse your fonts.") + HELP_TEXT ("TrueType fonts are indicated by 'TT'.") + HELP_TEXT ("") + HELP_TEXT ("- Preview area: Shows what the brush will") + HELP_TEXT ("look like.") +}; +static const T_Help_table helptable_magnifier[] = +{ + HELP_TITLE("MAGNIFIER") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_MAGNIFIER) + HELP_TEXT ("") + HELP_TEXT ("Engages/Disengages the choice of the zoomed") + HELP_TEXT ("window. If you're already in magnifier mode,") + HELP_TEXT ("you'll return to normal mode.") + HELP_LINK ("Zoom in : %s",SPECIAL_ZOOM_IN) + HELP_LINK ("Zoom out: %s",SPECIAL_ZOOM_OUT) + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_MAGNIFIER) + HELP_TEXT ("") + HELP_TEXT ("Displays a menu where you can choose the") + HELP_TEXT ("magnifying factor.") + HELP_TEXT ("") + HELP_TEXT (" Note: When you are in Zoom mode, you can") + HELP_TEXT ("move the \"split\" bar by clicking on it and") + HELP_TEXT ("moving your mouse left or right while") + HELP_TEXT ("holding the mouse button down.") +}; +static const T_Help_table helptable_colorpicker[] = +{ + HELP_TITLE("PIPETTE") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_COLORPICKER) + HELP_TEXT ("") + HELP_TEXT ("Engages a color grabbing.") + HELP_TEXT ("") + HELP_TEXT ("Click on the picture to get the color of the") + HELP_TEXT ("pixel you're on. You can either get a new") + HELP_TEXT ("Fore-color or Back-color with respectively") + HELP_TEXT ("left or right mouse button.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_COLORPICKER) + HELP_TEXT ("") + HELP_TEXT ("Swap Fore-color and Back-color.") + HELP_TEXT ("") + HELP_TEXT (" The color currently pointed will be") + HELP_TEXT ("displayed in the tool-bar right after the") + HELP_TEXT ("coordinates. If you click outside the") + HELP_TEXT ("picture, the color 0 will be returned.") +}; +static const T_Help_table helptable_resolution[] = +{ + HELP_TITLE("RESOLUTION AND") + HELP_TITLE(" IMAGE SIZE") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_RESOL) + HELP_TEXT ("") + HELP_TEXT ("Displays a menu where you can define the") + HELP_TEXT ("size of your picture and choose the") + HELP_TEXT ("screen resolution.") + HELP_TEXT ("") + HELP_TEXT ("- Image size") + HELP_TEXT ("Click in the boxes named \"Width\" and") + HELP_TEXT ("\"Height\" to change the size of the image") + HELP_TEXT ("you're editing, up to 9999x9999.") + HELP_TEXT ("You can also right-click a video mode to") + HELP_TEXT ("copy its dimensions to the image's.") + HELP_TEXT ("") + HELP_TEXT ("- Pixel size") + HELP_TEXT ("If you choose any Pixel size other than") + HELP_TEXT ("Normal, Grafx2 will emulate a lower") + HELP_TEXT ("resolution by scaling up everything it") + HELP_TEXT ("displays, including the menus and mouse") + HELP_TEXT ("cursor. In Double, Triple and Quadruple") + HELP_TEXT ("mode, the image will appear zoomed x2, x3 or") + HELP_TEXT ("x4, keeping the original proportions. The") + HELP_TEXT ("scaling is done in software, with no linear") + HELP_TEXT ("interpolation, so it can't cause blur. This") + HELP_TEXT ("setting is especially useful if your") + HELP_TEXT ("hardware or drivers don't support the low") + HELP_TEXT ("resolutions you need, but it also allows you") + HELP_TEXT ("to draw in low-resolution while staying in") + HELP_TEXT ("window mode.") + HELP_TEXT ("If you choose one of the scalers called") + HELP_TEXT ("Wide, Tall, Wide2 and Tall2, this will") + HELP_TEXT ("emulate a video mode which has rectangular") + HELP_TEXT ("pixels (longer horizontally or vertically),") + HELP_TEXT ("like some video modes of the C64, Amstrad") + HELP_TEXT ("CPC, and Commodore Amiga.") + HELP_TEXT ("") + HELP_TEXT ("- Video mode") + HELP_TEXT ("Click on a video mode to select it.") + HELP_TEXT ("Grafx2 only lists modes that are detected") + HELP_TEXT ("as available on your computer. Depending on") + HELP_TEXT ("your video card and drivers, there can be") + HELP_TEXT ("a huge difference in the number of modes") + HELP_TEXT ("it can propose.") + HELP_TEXT ("The small buttons on the left-hand side of") + HELP_TEXT ("the lines in the list of modes have been") + HELP_TEXT ("designed to allow you to disable some modes") + HELP_TEXT ("that are not supported by your card. So, the") + HELP_TEXT ("modes that you will disable won't be used") + HELP_TEXT ("when loading pictures with \"Auto-set") + HELP_TEXT ("resolution\" ON.") + HELP_TEXT ("") + HELP_TEXT ("When you click on one of these buttons, its") + HELP_TEXT ("color changes to one of the 4 following. The") + HELP_TEXT ("signification for each color of these") + HELP_TEXT ("buttons is:") + HELP_TEXT ("") + HELP_TEXT ("- Light gray: The video mode is OK. It can") + HELP_TEXT ("be used by the auto-set resolution option") + HELP_TEXT ("when you load picture, and you can select it") + HELP_TEXT ("in the menu of resolutions.") + HELP_TEXT ("") + HELP_TEXT ("- White: It works exactly the same as above.") + HELP_TEXT ("Moreover, it allows you to tag your") + HELP_TEXT ("favourite modes. Indeed, the huge number of") + HELP_TEXT ("video modes makes it more difficult to find") + HELP_TEXT ("the mode your want in the list; so you can") + HELP_TEXT ("tag your favoutite ones in white, so that it") + HELP_TEXT ("will be easier to locate them. (Note: you") + HELP_TEXT ("cannot disable the standard windowed mode)") + HELP_TEXT ("") + HELP_TEXT ("- Dark gray: It allows you to indicate which") + HELP_TEXT ("modes are not really perfect (flickering,") + HELP_TEXT ("not centered, etc...) but which can be used") + HELP_TEXT ("even so. The difference with the light grey") + HELP_TEXT ("button is that these modes won't be used by") + HELP_TEXT ("the auto-set resolution option.") + HELP_TEXT ("") + HELP_TEXT ("- Black: Use it for totally unsupported") + HELP_TEXT ("modes. Thus, these modes won't be selected") + HELP_TEXT ("the \"auto-set res.\" and the program will") + HELP_TEXT ("not let you select them from the list of") + HELP_TEXT ("resolutions.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_RESOL) + HELP_TEXT ("") + HELP_TEXT (" Automaticaly switches to the 640x400 window") + HELP_TEXT ("mode.") +}; +static const T_Help_table helptable_page[] = +{ + HELP_TITLE("SPARE") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_PAGE) + HELP_TEXT ("") + HELP_TEXT ("Jumps to spare page. The current page is") + HELP_TEXT ("then considered as the new spare page, and") + HELP_TEXT ("the spare page considered as the new current") + HELP_TEXT ("page.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_PAGE) + HELP_TEXT ("") + HELP_TEXT ("Opens a menu where you can choose whether") + HELP_TEXT ("you want to copy the whole picture (keyboard") + HELP_TEXT ("short-cut in this menu is [Return]), only") + HELP_TEXT ("the pixels, only the palette, or only some") + HELP_TEXT ("colors.") + HELP_TEXT ("In this last case, a second menu") + HELP_TEXT ("(stencil-like) will propose you to tag the") + HELP_TEXT ("colors you want to copy (they are all") + HELP_TEXT ("selected by default).") + HELP_TEXT ("Please refer to section \"Stencil\" to know") + HELP_TEXT ("how to use this last menu.") + HELP_TEXT ("The last option the menu (\"Copy palette and") + HELP_TEXT ("remap\"), remaps the spare page with the") + HELP_TEXT ("current palette and replicates this palette") + HELP_TEXT ("to the spare page. This option is useful to") + HELP_TEXT ("quickly remap a picture with the palette of") + HELP_TEXT ("another.") +}; +static const T_Help_table helptable_save[] = +{ + HELP_TITLE("SAVE") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_SAVE) + HELP_TEXT ("") + HELP_TEXT ("Displays a fileselector where the following") + HELP_TEXT ("options are available:") + HELP_TEXT ("") + HELP_TEXT ("- Select drive: Allow you to change the") + HELP_TEXT ("current drive.or volume (depending on your") + HELP_TEXT ("operating system") + HELP_TEXT ("") + HELP_TEXT ("- Format: Allows you to choose the file") + HELP_TEXT ("format you want. (PAL and KCF file formats") + HELP_TEXT ("are \"palette\" files).") + HELP_TEXT ("") + HELP_TEXT ("- Filename: Allows you to give a new name to") + HELP_TEXT ("the picture. If no extension is given, the") + HELP_TEXT ("default (according to the format) will be") + HELP_TEXT ("used.") + HELP_TEXT ("") + HELP_TEXT ("- Bookmarks: The four dropdown buttons allow") + HELP_TEXT ("you to bookmark frequently used directories.") + HELP_TEXT ("Use right-click to open a contextual menu") + HELP_TEXT ("to Set it (memorize current directory),") + HELP_TEXT ("Rename it to change its label, and Clear it") + HELP_TEXT ("if you no longer need it. Use left-click to") + HELP_TEXT ("change to the memorized directory.") + HELP_TEXT ("") + HELP_TEXT ("- File-list: Allows you to flick through the") + HELP_TEXT ("disk tree or to overwrite an existing file.") + HELP_TEXT ("") + HELP_TEXT ("- Delete: Allows you to delete the item") + HELP_TEXT ("under the selection bar. If the item is a") + HELP_TEXT ("directory, it must be empty to be removed.") + HELP_TEXT ("") + HELP_TEXT ("- Save: Saves the picture with the current") + HELP_TEXT ("filename, with the chosen format. If the ") + HELP_TEXT ("current filename represents a directory,") + HELP_TEXT ("you'll enter it.") + HELP_TEXT ("") + HELP_TEXT ("- Comment (Txt): If you're using the PKM") + HELP_TEXT ("or PNG format, you can type in a comment on") + HELP_TEXT ("your picture. It will be memorized in the") + HELP_TEXT ("image.") + HELP_TEXT ("") + HELP_TEXT ("Note: The Backspace key brings you directly") + HELP_TEXT ("to the parent directory. You can also type") + HELP_TEXT ("the first letters of a filename you are") + HELP_TEXT ("looking for, to access it faster.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_SAVE) + HELP_TEXT ("") + HELP_TEXT ("Save the current picture with its current") + HELP_TEXT ("filename, format and comment.") + HELP_TEXT ("") + HELP_TEXT ("If the file already exists, a confirmation") + HELP_TEXT ("box will appear.") +}; +static const T_Help_table helptable_load[] = +{ + + HELP_TITLE("LOAD") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_LOAD) + HELP_TEXT ("") + HELP_TEXT ("This works the same way as Save.") + HELP_TEXT ("") + HELP_TEXT ("You'll have access in the format selector to") + HELP_TEXT ("a \"*.*\" filter. And of course, you won't be") + HELP_TEXT ("able to type in any comment.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_LOAD) + HELP_TEXT ("") + HELP_TEXT ("Reloads the picture.") + HELP_TEXT ("") + HELP_TEXT ("If you want to load a picture and that you") + HELP_TEXT ("haven't saved the last modifications of the") + HELP_TEXT ("current picture, a confirmation box will") + HELP_TEXT ("appear.") +}; +static const T_Help_table helptable_settings[] = +{ + HELP_TITLE("SETTINGS") + HELP_TEXT ("") + HELP_LINK ("(Key:%s)",0x100+BUTTON_SETTINGS) + HELP_TEXT ("") + HELP_TEXT ("Displays a menu where you can configure some") + HELP_TEXT ("miscellaneous elements of the program:") + HELP_TEXT ("") + HELP_TEXT ("- Number of UNDO pages: indicates the total") + HELP_TEXT ("number of pages that GrafX2 will memorize.") + HELP_TEXT ("Each time you modify the picture, its") + HELP_TEXT ("current state is memorized in one of these") + HELP_TEXT ("pages. To flick through these pages, use the") + HELP_TEXT ("\"Oops\" button (Undo/Redo).") + HELP_TEXT ("") + HELP_TEXT ("- Mouse sensibility: Modifies the speed of") + HELP_TEXT ("the mouse when you're in fullscreen. With") + HELP_TEXT ("the normal setting (slider on top), you may") + HELP_TEXT ("find the mouse too fast, especially in ") + HELP_TEXT ("video modes which are much smaller than your") + HELP_TEXT ("desktop. You can lower the slider to divide") + HELP_TEXT ("the speed by 2, 3 or 4.") + HELP_TEXT ("When using videomodes with native skewed") + HELP_TEXT ("pixels like 640x240 or 320x512, you'll") + HELP_TEXT ("probably want to use a stronger reduction") + HELP_TEXT ("on the axis which has less pixels.") + HELP_TEXT ("") + HELP_TEXT ("- Show/Hide in file list: Defines whether") + HELP_TEXT ("some particular files or directories must be") + HELP_TEXT ("displayed by the fileselectors or not.") + HELP_TEXT ("") + HELP_TEXT ("- Show/Hide picture limits: Indicates if the") + HELP_TEXT ("picture boundaries must be displayed when") + HELP_TEXT ("you are in a resolution bigger than the") + HELP_TEXT ("picture.") + HELP_TEXT ("") + HELP_TEXT ("- Clear palette: Indicates if loading a file") + HELP_TEXT ("with a palette of less than 256 colors must") + HELP_TEXT ("erase the rest of the current palette") + HELP_TEXT ("(replace by the black color).") + HELP_TEXT ("") + HELP_TEXT ("- Maximize preview: maximizes the preview of") + HELP_TEXT ("the pictures so that it is as big as") + HELP_TEXT ("possible. If you're not in the same") + HELP_TEXT ("resolution as the picture's one, it can try") + HELP_TEXT ("to correct the aspect ratio, but if the") + HELP_TEXT ("picture does not fill the whole screen, it") + HELP_TEXT ("can be worse.") + HELP_TEXT ("") + HELP_TEXT ("- Backup: when you'll save a picture over an") + HELP_TEXT ("existing file, the program will rename this") + HELP_TEXT ("file to \"*.BAK\" where * is the name of the") + HELP_TEXT ("picture without its extension. If the backup") + HELP_TEXT ("file already exists in the directory, it") + HELP_TEXT ("will be replaced. If you save a picture with") + HELP_TEXT ("the name of the backup file, no backup file") + HELP_TEXT ("will be created (of course!) ;).") + HELP_TEXT ("") + HELP_TEXT ("- Safety colors: Brings back the 4 default") + HELP_TEXT ("colors of the menus if you run an operation") + HELP_TEXT ("that passes the image in less than four") + HELP_TEXT ("colors in the palette editor.") + HELP_TEXT ("") + HELP_TEXT ("- Adjust brush pick: This option is used") + HELP_TEXT ("when you grab a brush in Grid (Snap) mode.") + HELP_TEXT ("Then, the right-most and down-most pixels") + HELP_TEXT ("won't be picked up with the rest of the") + HELP_TEXT ("brush. This option has been made because, if") + HELP_TEXT ("people grab brushes in Grid mode, that's") + HELP_TEXT ("mostly when they want to grab sprites. For") + HELP_TEXT ("example: if you have 16x16 sprites on your") + HELP_TEXT ("page, you'll set the grid mode to 16x16. But") + HELP_TEXT ("the cursor will snap at points like (0,0),") + HELP_TEXT ("(16,0), (16,16) and so on... And the problem") + HELP_TEXT ("is that, from (0,0) to (16,16), there are 17") + HELP_TEXT ("pixels! But if you keep the") + HELP_TEXT ("adjust-brush-pick option on, the unwanted") + HELP_TEXT ("pixels will be ignored. Moreover, this") + HELP_TEXT ("option adjusts the brush handle so that the") + HELP_TEXT ("brush still fits in the grid, instead of") + HELP_TEXT ("placing the handle in the center of the") + HELP_TEXT ("brush.") + HELP_TEXT ("") + HELP_TEXT ("- Separate colors: Draws a squaring around") + HELP_TEXT ("the colors of the tool-bar.") + HELP_TEXT ("") + HELP_TEXT ("- Auto-set resolution: sets the best") + HELP_TEXT ("resolution for the loaded image.") + HELP_TEXT ("") + HELP_TEXT ("- Coordinates: Choose if you want to display") + HELP_TEXT ("relative or absolute coordinates when using") + HELP_TEXT ("tools such as circles, rectangles, etc...") + HELP_TEXT ("for example, if you draw a circle: if coords") + HELP_TEXT ("are relative, the radius of the circle will") + HELP_TEXT ("be displayed, while in absolute coords, the") + HELP_TEXT ("coordinates of the cursor will be displayed.") + HELP_TEXT ("") + HELP_TEXT ("- Reload: loads the previously saved") + HELP_TEXT ("configuration.") + HELP_TEXT ("") + HELP_TEXT ("- Auto-save: means that the configuration") + HELP_TEXT ("will be automatically saved when you'll quit") + HELP_TEXT ("the program.") + HELP_TEXT ("") + HELP_TEXT ("- Save: saves the configuration at once.") + HELP_TEXT (" All modifications will be effective just") + HELP_TEXT ("after closing the menu.") + HELP_TEXT ("") + HELP_TITLE("SKINS") + HELP_TEXT ("") + HELP_TEXT ("This window allow you to change the look and") + HELP_TEXT ("feel of the program.") + HELP_TEXT ("") + HELP_TEXT ("- Font: determines whether you want to use") + HELP_TEXT ("GrafX2 with a classical font, or another one") + HELP_TEXT ("a bit funnier.") + HELP_TEXT ("") + HELP_TEXT ("- Cursor: allows you to choose whether you") + HELP_TEXT ("prefer a solid cursor or a transparent") + HELP_TEXT ("cursor.") + HELP_TEXT ("") + HELP_TEXT ("- Graphic file: you can change the whole") + HELP_TEXT ("interface by selecting where the sprites for") + HELP_TEXT ("all buttons are. Look at the files in the") + HELP_TEXT ("\"skin\" directory if you want to create your") + HELP_TEXT ("own. There are two skins available, the") + HELP_TEXT ("default for 2.1 is called modern. Classic is") + HELP_TEXT ("for nostalgics who wish to remember the old") + HELP_TEXT ("days of Sunset Design. If you create a good") + HELP_TEXT ("skin, feel free to share it with us! We may") + HELP_TEXT ("include it in a future release...") +}; +static const T_Help_table helptable_clear[] = +{ + + HELP_TITLE("CLEAR") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_CLEAR) + HELP_TEXT ("") + HELP_TEXT ("Clears the picture with the color number 0.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_CLEAR) + HELP_TEXT ("") + HELP_TEXT ("Clears the picture with the Back-color.") +}; +static const T_Help_table helptable_general[] = +{ + + HELP_TITLE("HELP STATS") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_HELP) + HELP_TEXT ("") + HELP_TEXT ("Displays an info window where you'll find") + HELP_TEXT ("some credits, help about the credits,") + HELP_TEXT ("different effects, greetings, registering...") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_HELP) + HELP_TEXT ("") + HELP_TEXT ("Displays a window where you'll find") + HELP_TEXT ("miscellaneous informations about the system.") + HELP_TEXT (" Note: you should take care to keep more") + HELP_TEXT ("than 128 Kb in order to let the program") + HELP_TEXT ("run in a proper way.") +}; +static const T_Help_table helptable_undo[] = +{ + + HELP_TITLE("OOPS") + HELP_TEXT ("(UNDO/REDO)") + HELP_TEXT ("LEFT CLICK Allows you to undo the last") + HELP_TEXT ("modification on the picture.") + HELP_LINK ("(Key:%s)",0x100+BUTTON_UNDO) + HELP_TEXT ("") + HELP_TEXT ("RIGHT CLICK Allows you to redo the last") + HELP_TEXT ("modification undone on the picture.") + HELP_TEXT ("The maximum number of UNDO that you can") + HELP_TEXT ("perform can be defined in the settings") + HELP_TEXT ("menu.") + HELP_TEXT ("Undo/Redo aren't effective after page") + HELP_TEXT ("switching, picture loading and picture") + HELP_TEXT ("size modifications.") + HELP_LINK ("(Key:%s)",0x200+BUTTON_UNDO) +}; +static const T_Help_table helptable_kill[] = +{ + + HELP_TITLE("KILL") + HELP_TEXT ("KILL CURRENT PAGE") + HELP_TEXT ("") + HELP_LINK ("(Key:%s)",0x100+BUTTON_KILL) + HELP_TEXT ("") + HELP_TEXT ("Removes the current page from the list of") + HELP_TEXT ("\"Undo\" pages. This allows you to free some") + HELP_TEXT ("memory if you need it. For instance, this") + HELP_TEXT ("will allow you to delete the start-up page") + HELP_TEXT ("after having loaded an image. A message will") + HELP_TEXT ("appear if you've already erased all the") + HELP_TEXT ("pages except the last one.") + HELP_TEXT (" Note: Another way to free some memory is to") + HELP_TEXT ("decrease the number of \"Undo\" pages. Or") + HELP_TEXT ("else, if you have recentlt grabbed a very") + HELP_TEXT ("big brush that you don't use any more, you") + HELP_TEXT ("can grab a new smaller one. The memory") + HELP_TEXT ("allocated by the big brush will be thus") + HELP_TEXT ("freed.") +}; +static const T_Help_table helptable_quit[] = +{ + + HELP_TITLE("QUIT") + HELP_TEXT ("") + HELP_LINK ("(Key:%s)",0x100+BUTTON_QUIT) + HELP_TEXT ("") + HELP_TEXT ("Allows you to leave GrafX2. If there are") + HELP_TEXT ("unsaved modifications in the current or") + HELP_TEXT ("spare page, a confirmation box will ask you") + HELP_TEXT ("if you really want to quit GrafX2, if you") + HELP_TEXT ("want to save (Auto-save, no fileselector) or") + HELP_TEXT ("if you want to stay in GrafX2.") +}; +static const T_Help_table helptable_palette[] = +{ + + HELP_TITLE("PAL MENU") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_LINK ("(Key:%s)",0x100+BUTTON_PALETTE) + HELP_TEXT ("") + HELP_TEXT ("Displays a menu where the following options") + HELP_TEXT ("are available:") + HELP_TEXT ("") + HELP_TEXT ("- Palette: Allows you to choose a") + HELP_TEXT ("color-block to edit. If you click with the") + HELP_TEXT ("right mouse button, you'll choose a new") + HELP_TEXT ("Back-color.") + HELP_TEXT ("") + HELP_TEXT ("- Gauges: Allow you to modify the") + HELP_TEXT ("current selection.") + HELP_TEXT ("") + HELP_TEXT ("- \"+\" and \"-\": Allow you to lighten or") + HELP_TEXT ("darken the current selection.") + HELP_TEXT ("") + HELP_TEXT ("- Default: Restores the predifined GrafX2") + HELP_TEXT ("palette.") + HELP_TEXT ("") + HELP_TEXT ("- Gray: Transforms the current selection") + HELP_TEXT ("into its gray-scaled equivalent.") + HELP_TEXT ("") + HELP_TEXT ("- Negative: Transforms the current selection") + HELP_TEXT ("into its reverse video equivalent.") + HELP_TEXT ("") + HELP_TEXT ("- Invert: Swaps the colors of the current") + HELP_TEXT ("selection so that the first colors become") + HELP_TEXT ("the last ones.") + HELP_TEXT ("") + HELP_TEXT ("- X-Invert: Works as above but modifies the") + HELP_TEXT ("picture so that it looks the same.") + HELP_TEXT ("") + HELP_TEXT ("- Swap: Swaps the current selection with") + HELP_TEXT ("another color-block. Click on the beginning") + HELP_TEXT ("of the new color-block.") + HELP_TEXT ("") + HELP_TEXT ("- X-Swap: Works as above but modifies the") + HELP_TEXT ("picture so that it looks the same. This may") + HELP_TEXT ("be useful if you want to sort your palette.") + HELP_TEXT ("") + HELP_TEXT ("- Copy: Copies the current selection to") + HELP_TEXT ("another color-block. Click on the beginning") + HELP_TEXT ("of the new color-block.") + HELP_TEXT ("") + HELP_TEXT ("- Spread: Computes a gradation between two") + HELP_TEXT ("colors. If your selection is only made up of") + HELP_TEXT ("one color, select the second color in the") + HELP_TEXT ("palette. Otherwise, the two colors used will") + HELP_TEXT ("be its extremities.") + HELP_TEXT ("") + HELP_TEXT ("- Sort: sorts the palette by color ranges.") + HELP_TEXT ("If you click with the left mouse button, it") + HELP_TEXT ("will sort by H S L; and if you click with") + HELP_TEXT ("the right mouse button, it will sort by L") + HELP_TEXT ("only. Note that you can choose a range of") + HELP_TEXT ("colors before sorting, and instead of the") + HELP_TEXT ("whole palette it will sort this range.") + HELP_TEXT ("") + HELP_TEXT ("- Used: Indicates the number of colors used") + HELP_TEXT ("in the picture.") + HELP_TEXT ("") + HELP_TEXT ("- Zap unused: Erases the unused colors with") + HELP_TEXT ("copies of the current selection. (The") + HELP_TEXT ("keyboard shortcut for this button is ).") + HELP_TEXT ("") + HELP_TEXT ("- HSL: Switches between RGB and HSL color") + HELP_TEXT ("spaces. In HSL mode, the three sliders") + HELP_TEXT ("allow you to set the Hue (tint), Saturation") + HELP_TEXT ("(from grayscale to pure color) and") + HELP_TEXT ("Lightness (from black to white).") + HELP_TEXT ("") + HELP_TEXT ("- Reduce: Allows you to reduce the palette") + HELP_TEXT ("to the number of colors you want (and") + HELP_TEXT ("modifies the picture).") + HELP_TEXT ("") + HELP_TEXT ("- Undo: Allows you to recover the last") + HELP_TEXT ("modifications made on the palette. If the") + HELP_TEXT ("last operation modified the picture, it") + HELP_TEXT ("won't recover them: you'll have to click on") + HELP_TEXT ("Cancel to do so.") + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TEXT ("If you press , the program will") + HELP_TEXT ("replace, as well as possible, some unused") + HELP_TEXT ("colors by the four default colors of the") + HELP_TEXT ("menu. The image won't look altered because") + HELP_TEXT ("the modified colors (in the case they were") + HELP_TEXT ("used on a few points) will be replaced by") + HELP_TEXT ("the closest colors in the rest of the") + HELP_TEXT ("palette. This option is really useful when") + HELP_TEXT ("you modify the palette so that there are no") + HELP_TEXT ("colors that fit for the menu (eg: \"Zap") + HELP_TEXT ("unused\" while very little colors are used in") + HELP_TEXT ("the picture; or \"Reduce\" with a very small") + HELP_TEXT ("number of colors).") + HELP_TEXT ("") + HELP_TEXT ("If you press the key below or <,>") + HELP_TEXT ("(QWERTY), the menu will disappear and you") + HELP_TEXT ("will be able to pick up a color from the") + HELP_TEXT ("picture easily. Press to cancel.") + HELP_TEXT ("") + HELP_TEXT ("If only one color is selected (not a block),") + HELP_TEXT ("the <[> and <]> keys can be used to select") + HELP_TEXT ("the previous or next Forecolor (Backcolor if") + HELP_TEXT ("you press at the same time).") + HELP_TEXT ("") + HELP_TEXT ("Warning! If you press Undo after an action") + HELP_TEXT ("that modifies the picture (X-Swap, X-Invert") + HELP_TEXT ("and Reduce colors), the picture won't be") + HELP_TEXT ("remapped as it was just before this action.") + HELP_TEXT ("Only Cancel will.") + HELP_TEXT ("") + HELP_TITLE("PALETTE OPTIONS") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_LINK ("(Key:%s)",0x200+BUTTON_PALETTE) + HELP_TEXT ("") + HELP_TEXT ("Opens a menu from where you have the") + HELP_TEXT ("following options:") + HELP_TEXT ("") + HELP_TEXT ("- Colors for best match:") + HELP_TEXT ("A menu in which you can select the colors") + HELP_TEXT ("that have not to be used for smoothing, for") + HELP_TEXT ("the transparency mode, and for remapping.") + HELP_TEXT ("") + HELP_TEXT ("- User's color series:") + HELP_TEXT ("A menu in which you can define color series") + HELP_TEXT ("for next/previous user color shortcuts.") + HELP_TEXT ("It's the same settings than the shade mode.") + HELP_TEXT ("After you have some color ranges defined in") + HELP_TEXT ("this screen, you can use those shortcuts to") + HELP_TEXT ("move to the next or previous color according") + HELP_TEXT ("to your ranges:") + HELP_TEXT ("") + HELP_TEXT ("Foreground color") + HELP_TEXT ("") + HELP_LINK (" Next : %s", SPECIAL_NEXT_USER_FORECOLOR) + HELP_LINK (" Previous: %s", SPECIAL_PREVIOUS_USER_FORECOLOR) + HELP_TEXT ("") + HELP_TEXT ("Background color") + HELP_LINK (" Next : %s", SPECIAL_NEXT_USER_BACKCOLOR) + HELP_LINK (" Previous: %s", SPECIAL_PREVIOUS_USER_BACKCOLOR) + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TEXT ("- Palette layout:") + HELP_TEXT ("Lets you customize the palette that appears") + HELP_TEXT ("on the right of the menu. You can choose the") + HELP_TEXT ("number of lines and columns.") + HELP_TEXT ("If you want the colors to run top to bottom,") + HELP_TEXT ("check the 'Vertical' button, otherwise the") + HELP_TEXT ("colors runs left to right.") + HELP_TEXT ("") + HELP_TEXT ("- RGB Scale:") + HELP_TEXT ("Lets you set the scale of the R G B sliders") + HELP_TEXT ("in the palette screen. You should normally") + HELP_TEXT ("leave it at 256 to get the full 0-255 range,") + HELP_TEXT ("but if you want to constrain the palette") + HELP_TEXT ("to the capabilities of some specific") + HELP_TEXT ("computers and consoles, you can choose eg:") + HELP_TEXT (" 64 : VGA") + HELP_TEXT (" 16 : Amiga") + HELP_TEXT (" 4 : MSX2") + HELP_TEXT (" 2 : Amstrad CPC") + }; +static const T_Help_table helptable_pal_scroll[] = +{ + + HELP_TITLE("SCROLL PAL") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_TEXT ("") + HELP_TEXT ("Scrolls the palette window in the right of") + HELP_TEXT ("the menu.") + HELP_LINK ("Key for back: %s", 0x100+BUTTON_PAL_LEFT) + HELP_LINK ("Key for forward: %s", 0x100+BUTTON_PAL_RIGHT) + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_TEXT ("") + HELP_TEXT ("Same as above, but faster.") + HELP_LINK ("Key for back: %s", 0x200+BUTTON_PAL_LEFT) + HELP_LINK ("Key for forward: %s", 0x200+BUTTON_PAL_RIGHT) + HELP_TEXT ("") +}; +static const T_Help_table helptable_color_select[] = +{ + + HELP_TITLE("PALETTE") + HELP_TEXT ("") + HELP_BOLD ("LEFT CLICK") + HELP_TEXT ("") + HELP_TEXT ("Defines the Fore-color.") + HELP_TEXT ("") + HELP_BOLD ("RIGHT CLICK") + HELP_TEXT ("") + HELP_TEXT ("Defines the Back-color.") +}; +static const T_Help_table helptable_hide[] = +{ + + HELP_TITLE("HIDE MENU") + HELP_TEXT ("") + HELP_TEXT ("Allows you to hide the menu. If you do this,") + HELP_TEXT ("take care to watch before the key to press") + HELP_TEXT ("to show the menu back (the key is") + HELP_LINK ("%s).",0x100+BUTTON_HIDE) + +}; + +#define HELP_TABLE_DECLARATION(x) {x, sizeof(x)/sizeof(const T_Help_table)}, + +T_Help_section Help_section[] = +{ + HELP_TABLE_DECLARATION(helptable_about) + HELP_TABLE_DECLARATION(helptable_licence) + HELP_TABLE_DECLARATION(helptable_help) + HELP_TABLE_DECLARATION(helptable_credits) + + // Attention, keep the same order as BUTTON_NUMBERS: + HELP_TABLE_DECLARATION(helptable_paintbrush) + HELP_TABLE_DECLARATION(helptable_adjust) + HELP_TABLE_DECLARATION(helptable_draw) + HELP_TABLE_DECLARATION(helptable_curves) + HELP_TABLE_DECLARATION(helptable_lines) + HELP_TABLE_DECLARATION(helptable_airbrush) + HELP_TABLE_DECLARATION(helptable_floodfill) + HELP_TABLE_DECLARATION(helptable_polygons) + HELP_TABLE_DECLARATION(helptable_polyfill) + HELP_TABLE_DECLARATION(helptable_rectangles) + HELP_TABLE_DECLARATION(helptable_filled_rectangles) + HELP_TABLE_DECLARATION(helptable_circles) + HELP_TABLE_DECLARATION(helptable_filled_circles) + HELP_TABLE_DECLARATION(helptable_grad_rect) + HELP_TABLE_DECLARATION(helptable_spheres) + HELP_TABLE_DECLARATION(helptable_brush) + HELP_TABLE_DECLARATION(helptable_polybrush) + HELP_TABLE_DECLARATION(helptable_brush_fx) + HELP_TABLE_DECLARATION(helptable_effects) + HELP_TABLE_DECLARATION(helptable_text) + HELP_TABLE_DECLARATION(helptable_magnifier) + HELP_TABLE_DECLARATION(helptable_colorpicker) + HELP_TABLE_DECLARATION(helptable_resolution) + HELP_TABLE_DECLARATION(helptable_page) + HELP_TABLE_DECLARATION(helptable_save) + HELP_TABLE_DECLARATION(helptable_load) + HELP_TABLE_DECLARATION(helptable_settings) + HELP_TABLE_DECLARATION(helptable_clear) + HELP_TABLE_DECLARATION(helptable_general) + HELP_TABLE_DECLARATION(helptable_undo) + HELP_TABLE_DECLARATION(helptable_kill) + HELP_TABLE_DECLARATION(helptable_quit) + HELP_TABLE_DECLARATION(helptable_palette) + HELP_TABLE_DECLARATION(helptable_pal_scroll) + HELP_TABLE_DECLARATION(helptable_pal_scroll) + HELP_TABLE_DECLARATION(helptable_color_select) + HELP_TABLE_DECLARATION(helptable_hide) +}; diff --git a/hotkeys.c b/hotkeys.c index 02a7bcb1..da8f0382 100644 --- a/hotkeys.c +++ b/hotkeys.c @@ -1,1334 +1,1334 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 Yves Rizoud - Copyright 2008 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 -*/ -#include "struct.h" -#include "global.h" -#include "hotkeys.h" - -T_Key_config ConfigKey[NB_SHORTCUTS] = { - {0, - "Scroll up", - "Scrolls the picture up, both in", - "magnify and normal mode.", - "", - false, - SDLK_UP, // HAUT - 0}, - {1, - "Scroll down", - "Scrolls the picture down, both in", - "magnify and normal mode.", - "", - false, - SDLK_DOWN, // BAS - 0}, - {2, - "Scroll left", - "Scrolls the picture to the left,", - "both in magnify and normal mode.", - "", - false, - SDLK_LEFT, // GAUCHE - 0}, - {3, - "Scroll right", - "Scrolls the picture to the right,", - "both in magnify and normal mode.", - "", - false, - SDLK_RIGHT, // DROITE - 0}, - {4, - "Faster scroll up", - "Used to scroll upwards in the", - "picture fast, either in magnify and", - "normal mode.", - true, - SDLK_UP|MOD_SHIFT, // Shift + Haut - 0}, - {5, - "Faster scroll down", - "Used to scroll downwards in the", - "picture fast, either in magnify and", - "normal mode.", - true, - SDLK_DOWN|MOD_SHIFT, // Shift + Bas - 0}, - {6, - "Faster scroll left", - "Used to scroll to the left in the", - "picture fast, either in magnify and", - "normal mode.", - true, - SDLK_LEFT|MOD_SHIFT, // Shift + Gauche - 0}, - {7, - "Faster scroll right", - "Used to scroll to the right in the", - "picture fast, either in magnify and", - "normal mode.", - true, - SDLK_RIGHT|MOD_SHIFT, // Shift + Droite - 0}, - {8, - "Slower scroll up", - "Used to scroll upwards in the", - "picture pixel by pixel, either in", - "magnify and normal mode.", - true, - SDLK_UP|MOD_ALT, // Alt + Haut - 0}, - {9, - "Slower scroll down", - "Used to scroll downwards in the", - "picture pixel by pixel, either in", - "magnify and normal mode.", - true, - SDLK_DOWN|MOD_ALT, // Alt + Bas - 0}, - {10, - "Slower scroll left", - "Used to scroll to the left in the", - "picture pixel by pixel, either in", - "magnify and normal mode.", - true, - SDLK_LEFT|MOD_ALT, // Alt + Gauche - 0}, - {11, - "Slower scroll right", - "Used to scroll to the right in the", - "picture pixel by pixel, either in", - "magnify and normal mode.", - true, - SDLK_RIGHT|MOD_ALT, // Alt + Droite - 0}, - {12, - "Move mouse cursor 1 pixel up", - "Used to simulate a very small mouse", - "deplacement up.It""s very useful", - "when you want ultra-high precision.", - true, - SDLK_UP|MOD_CTRL, // Ctrl + Haut - 0}, - {13, - "Move mouse cursor 1 pixel down", - "Used to simulate a very small mouse", - "deplacement down.It""s very useful", - "when you want ultra-high precision.", - true, - SDLK_DOWN|MOD_CTRL, // Ctrl + Bas - 0}, - {14, - "Move mouse cursor 1 pixel left", - "Used to simulate a very small mouse", - "deplacement left.It""s very useful", - "when you want ultra-high precision.", - true, - SDLK_LEFT|MOD_CTRL, // Ctrl + Gauche - 0}, - {15, - "Move mouse cursor 1 pixel right", - "Used to simulate a very small mouse", - "deplacement right.It""s very useful", - "when you want ultra-high precision.", - true, - SDLK_RIGHT|MOD_CTRL, // Ctrl + Droite - 0}, - {16, - "Simulate left mouse click", - "Used to simulate a click with the", - "left mouse button. It""s useful", - "when you want ultra-high precision.", - true, - SDLK_SPACE, // Space - 0}, - {17, - "Simulate right mouse click", - "Used to simulate a click with the", - "right mouse button.. It""s useful", - "when you want ultra-high precision.", - true, - SDLK_SPACE|MOD_SHIFT, // Shift + Space - 0}, - {18, - "Show/hide option menu", - "Switch the tool bar display on/off.", - "This hot-key cannot be removed.", - "", - false, - SDLK_F10, // F10 - 0}, - {19, - "Show/hide cursor", - "Switch the cursor display on/off.", - "This only works on the \"small cross\"", - "and \"hand\" cursors.", - true, - SDLK_F9, // F9 - 0}, - {20, - "Set paintbrush to 1 pixel", - "Useful when you want to use a", - "\"single-pixel-brush\".", - "", - true, - SDLK_DELETE, // Del - 0}, - {21, - "Paintbrush choice", - "Opens a menu where you can choose a", - "paintbrush out of 24 predefined", - "ones.", - true, - SDLK_F4, // F4 - 0}, - {22, - "Monochrome brush", - "Turn your current user-defined brush", - "into a single colored one. All non-", - "transparent colors are set to FG.", - true, - SDLK_F4|MOD_SHIFT, // Shift + F4 - 0}, - {23, - "Freehand drawing", - "Set the drawing mode to the", - "classical freehand one.", - "", - true, - SDLK_d, // D - 0}, - {24, - "Switch freehand drawing mode", - "Alternates between: continuous,", - "discontinuous, point by point,", - "and contour fill", - true, - SDLK_d|MOD_SHIFT, // Shift + D - 0}, - {25, - "Continuous freehand drawing", - "Switch directly to continuous", - "freehand drawing mode.", - "", - true, - SDLK_d|MOD_CTRL, // Ctrl + D - 0}, - {26, - "Line", - "Allows you to draw lines.", - "", - "", - true, - SDLK_l, // L - 0}, - {27, - "Knotted lines", - "Allows you to draw linked lines.", - "This mode can also be called", - "\"Polyline\".", - true, - SDLK_l|MOD_SHIFT, // Shift + L - 0}, - {28, - "Spray", - "Allows you to spray brushes", - "randomly in the picture.", - "", - true, - SDLK_a, // A (Q en AZERTY) - 0}, - {29, - "Spray menu", - "Opens a menu in which you can", - "configure the spray flow and size.", - "", - true, - SDLK_a|MOD_SHIFT, // Shift + A - 0}, - {30, - "Flood-fill", - "Allows you to fill an area of the", - "picture made of pixels of the same", - "color.", - true, - SDLK_f, // F - 0}, - {124, - "Replace color", - "This tool replaces all the pixels of", - "the clicked color to the fore-color", - "or the back-color.", - true, - SDLK_f|MOD_SHIFT, // Shift + F - 0}, - {31, - "Bezier""s curves", - "Allows you to draw Bezier""s curves.", - "", - "", - true, - SDLK_i, // I - 0}, - {32, - "Bezier""s curve with 3 or 4 points", - "Allows you to choose whether you", - "want to draw Bezier""s curves with", - "3 or 4 points.", - true, - SDLK_i|MOD_SHIFT, // Shift + I - 0}, - {33, - "Empty rectangle", - "Allows you to draw a rectangle using", - "the brush.", - "", - true, - SDLK_r, // R - 0}, - {34, - "Filled rectangle", - "Allows you to draw a filled", - "rectangle.", - "", - true, - SDLK_r|MOD_SHIFT, // Shift + R - 0}, - {35, - "Empty circle", - "Allows you to draw a circle using", - "the brush.", - "", - true, - SDLK_c, // C - 0}, - {36, - "Empty ellipse", - "Allows you to draw an ellipse using", - "the brush.", - "", - true, - SDLK_c|MOD_CTRL, // Ctrl + C - 0}, - {37, - "Filled circle", - "Allows you to draw a filled circle.", - "", - "", - true, - SDLK_c|MOD_SHIFT, // Shift + C - 0}, - {38, - "Filled ellipse", - "Allows you to draw a filled ellipse.", - "", - "", - true, - SDLK_c|MOD_SHIFT|MOD_CTRL, // Shift + Ctrl + C - 0}, - {39, - "Empty polygon", - "Allows you to draw a polygon using", - "the brush.", - "", - true, - SDLK_n, // N - 0}, - {40, - "Empty \"polyform\"", - "Allows you to draw a freehand", - "polygon using the brush.", - "", - true, - SDLK_n|MOD_CTRL, // Ctrl + N - 0}, - {41, - "Filled polygon", - "Allows you to draw a filled polygon.", - "", - "", - true, - SDLK_n|MOD_SHIFT, // Shift + N - 0}, - {42, - "Filled \"polyform\"", - "Allows you to draw a filled freehand", - "polygon.", - "", - true, - SDLK_n|MOD_SHIFT|MOD_CTRL, // Shift + Ctrl + N - 0}, - {43, - "Rectangle with gradation", - "Allows you to draw a rectangle with", - "a color gradation.", - "", - true, - SDLK_r|MOD_ALT, // Alt + R - 0}, - {44, - "Gradation menu", - "Allows you to configure the way", - "color gradations are calculated.", - "", - true, - SDLK_g|MOD_ALT, // Alt + G - 0}, - {45, - "Sphere with gradation", - "Allows you to draw a rectangle with", - "a color gradation.", - "", - true, - SDLK_c|MOD_ALT, // Alt + C - 0}, - {46, - "Ellipse with gradation", - "Allows you to draw an ellipse filled", - "with a color gradation.", - "", - true, - SDLK_c|MOD_SHIFT|MOD_ALT, // Shift + Alt + C - 0}, - {47, - "Adjust picture", - "Allows you to move the whole picture", - "Around. What gets out from a side", - "reappears on the other.", - true, - SDLK_KP5, // Kpad5 - 0}, - {48, - "Picture effects", - "Opens the 'Picture effects' window.", - "", - "", - true, - SDLK_KP5|MOD_SHIFT, // Shift + Kpad5 - 0}, - {49, - "Drawing effects", - "Opens a menu where you can enable/", - "disable and configure the drawing", - "effects.", - true, - SDLK_e, // E - 0}, - {50, - "Shade mode", - "Enables or disables Shade mode", - "", - "", - true, - SDLK_F5, // F5 - 0}, - {51, - "Shade menu", - "Opens a the menu for Shade settings.", - "", - "", - true, - SDLK_F5|MOD_SHIFT, // Shift + F5 - 0}, - {131, - "Quick-shade mode", - "Enables or disables Quick-shade", - "mode.", - "", - true, - SDLK_F5|MOD_CTRL, // Ctrl + F5 - 0}, - {132, - "Quick-shade menu", - "Opens a the menu for Quick-shade", - "settings.", - "", - true, - SDLK_F5|MOD_SHIFT|MOD_CTRL, // Shift + Ctrl + F5 - 0}, - {52, - "Stencil mode", - "Enables or disables Stencil mode.", - "", - "", - true, - SDLK_F6, // F6 - 0}, - {53, - "Stencil menu", - "Opens a the menu for Stencil", - "settings.", - "", - true, - SDLK_F6|MOD_SHIFT, // Shift + F6 - 0}, - {54, - "Mask mode", - "Enables or disables Mask mode.", - "", - "", - true, - SDLK_F6|MOD_ALT, // Alt + F6 - 0}, - {55, - "Mask menu", - "Opens a the menu for Mask settings.", - "", - "", - true, - SDLK_F6|MOD_SHIFT|MOD_ALT, // Shift + Alt + F6 - 0}, - {56, - "Grid mode", - "Enables or disables the Grid mode.", - "", - "", - true, - SDLK_g, // G - 0}, - {57, - "Grid menu", - "Open a menu where you can configure", - "the grid used by Grid mode.", - "", - true, - SDLK_g|MOD_SHIFT, // Shift + G - 0}, - {58, - "Sieve mode", - "Enables or disables the Sieve mode.", - "", - "", - true, - SDLK_g|MOD_CTRL, // Ctrl + G - 0}, - {59, - "Sieve menu", - "Opens a menu where you can configure", - "the sieve.", - "", - true, - SDLK_g|MOD_SHIFT|MOD_CTRL, // Shift + Ctrl + G - 0}, - {60, - "Invert sieve", - "Inverts the pattern defined in the", - "Sieve menu.", - "", - true, - SDLK_g|MOD_CTRL|MOD_ALT, // Ctrl + Alt + G - 0}, - {61, - "Colorize mode", - "Enables or disables the Colorize", - "mode.", - "", - true, - SDLK_F7, // F7 - 0}, - {62, - "Colorize menu", - "Opens a menu where you can give the", - "opacity percentage for Colorize", - "mode.", - true, - SDLK_F7|MOD_SHIFT, // Shift + F7 - 0}, - {63, - "Smooth mode", - "Enables or disables the Smooth", - "mode.", - "", - true, - SDLK_F8, // F8 - 0}, - {123, - "Smooth menu", - "Opens a menu where you can define", - "the Smooth matrix.", - "", - true, - SDLK_F8|MOD_SHIFT, // Shift + F8 - 0}, - {64, - "Smear mode", - "Enables or disables the Smear mode.", - "", - "", - true, - SDLK_F8|MOD_ALT, // Alt + F8 - 0}, - {65, - "Tiling mode", - "Enables or disables the Tiling", - "mode.", - "", - true, - SDLK_b|MOD_ALT, // Alt + B - 0}, - {66, - "Tiling menu", - "Opens a menu where you can configure", - "the origin of the tiling.", - "", - true, - SDLK_b|MOD_SHIFT|MOD_ALT, // Shift + Alt + B - 0}, - {67, - "Classical brush grabbing", - "Allows you to pick a brush defined", - "within a rectangle.", - "", - true, - SDLK_b, // B - 0}, - {68, - "\"Lasso\" brush grabbing", - "Allows you to pick a brush defined", - "within a freehand polygon.", - "", - true, - SDLK_b|MOD_CTRL, // Ctrl + B - 0}, - {69, - "Get previous brush back", - "Restore the last user-defined brush.", - "", - "", - true, - SDLK_b|MOD_SHIFT, // Shift + B - 0}, - {70, - "Horizontal brush flipping", - "Reverse brush horizontally.", - "", - "", - true, - SDLK_x, // X - 0}, - {71, - "Vertical brush flipping", - "Reverse brush vertically.", - "", - "", - true, - SDLK_y, // Y - 0}, - {72, - "90° brush rotation", - "Rotate the user-defined brush by 90°", - "(counter-clockwise).", - "", - true, - SDLK_z, // Z (W en AZERTY) - 0}, - {73, - "180° brush rotation", - "Rotate the user-defined brush by", - "180°.", - "", - true, - SDLK_z|MOD_SHIFT, // Shift + Z - 0}, - {74, - "Strech brush", - "Allows you to resize the", - "user-defined brush.", - "", - true, - SDLK_s, // S - 0}, - {75, - "Distort brush", - "Allows you to distort the", - "user-defined brush.", - "", - true, - SDLK_s|MOD_SHIFT, // Shift + S - 0}, - {76, - "Outline brush", - "Outlines the user-defined brush", - "with the fore color.", - "", - true, - SDLK_o, // O - 0}, - {77, - "Nibble brush", - "Deletes the borders of the", - "user-defined brush.This does the", - "opposite of the Outline option.", - true, - SDLK_o|MOD_SHIFT, // Shift + O - 0}, - {78, - "Get colors from brush", - "Copy colors of the spare page that", - "are used in the brush.", - "", - true, - SDLK_F11, // F11 - 0}, - {79, - "Recolorize brush", - "Recolorize the user-defined brush in", - "order to get a brush which looks as", - "if it was grabbed in the spare page.", - true, - SDLK_F12, // F12 - 0}, - {80, - "Rotate by any angle", - "Rotate the brush by an angle that", - "you can define.", - "", - true, - SDLK_w, // W (Z en AZERTY) - 0}, - {81, - "Pipette", - "Allows you to copy the color of a", - "pixel in the picture into the", - "foreground or background color.", - true, - SDLK_BACKQUOTE, // `~ (Key sous le Esc - ² en AZERTY) - 0}, - {82, - "Swap foreground/background colors", - "Invert foreground and background", - "colors.", - "", - true, - SDLK_BACKQUOTE|MOD_SHIFT, // Shift + `~ - 0}, - {83, - "Magnifier mode", - "Allows you to zoom into the picture.", - "", - "", - true, - SDLK_m, // M (, ? sur AZERTY) - KEY_MOUSEMIDDLE}, - {84, - "Zoom factor menu", - "Opens a menu where you can choose a", - "magnifying factor.", - "", - true, - SDLK_m|MOD_SHIFT, // Shift + M - 0}, - {85, - "Zoom in", - "Increase magnifying factor.", - "", - "", - true, - SDLK_KP_PLUS, // Grey + - KEY_MOUSEWHEELUP}, - {86, - "Zoom out", - "Decrease magnifying factor.", - "", - "", - true, - SDLK_KP_MINUS, // Grey - - KEY_MOUSEWHEELDOWN}, - {87, - "Brush effects menu", - "Opens a menu which proposes", - "different effects on the", - "user-defined brush.", - true, - SDLK_b|MOD_CTRL|MOD_ALT, // Ctrl + Alt + B - 0}, - {88, - "Text", - "Opens a menu which permits you to", - "type in a character string and", - "render it as a brush.", - true, - SDLK_t, // T - 0}, - {89, - "Screen resolution menu", - "Opens a menu where you can choose", - "the screen resolution and image", - "dimensions.", - true, - SDLK_RETURN, // Enter - 0}, - {90, - "\"Safety\" resolution", - "Resets the resolution to a 'safe'", - "mode that should work everywhere:", - "usually a 640x400 window.", - false, - SDLK_RETURN|MOD_SHIFT, // Shift + Enter - 0}, - {91, - "Help and credits", - "Opens a window where you can get", - "information about the program,", - "or contextual help.", - true, - SDLK_F1, // F1 - 0}, - {92, - "Statistics", - "Displays miscellaneous more or less", - "useful information.", - "", - true, - SDLK_F1|MOD_SHIFT, // Shift + F1 - 0}, - {93, - "Jump to spare page", - "Swap current page and spare page.", - "", - "", - true, - SDLK_TAB, // Tab - 0}, - {94, - "Copy current page to spare page", - "Copy current page to spare page.", - "", - "", - true, - SDLK_TAB|MOD_SHIFT, // Shift + Tab - 0}, - {95, - "Save picture as...", - "Opens a file-selector that allows", - "you to save your picture with a new", - "path-name.", - true, - SDLK_F2, // F2 - 0}, - {96, - "Save picture", - "Saves your picture with the last", - "name you gave it.", - "", - true, - SDLK_F2|MOD_SHIFT, // Shift + F2 - 0}, - {97, - "Load picture", - "Opens a file-selector that allows", - "you to load a new picture.", - "", - true, - SDLK_F3, // F3 - 0}, - {98, - "Re-load picture", - "Re-load the current picture. This", - "allows you to cancel modifications", - "made since last saving.", - true, - SDLK_F3|MOD_SHIFT, // Shift + F3 - 0}, - {99, - "Save brush", - "Opens a file-selector that allows", - "you to save your current", - "user-defined brush.", - true, - SDLK_F2|MOD_CTRL, // Ctrl + F2 - 0}, - {100, - "Load brush", - "Opens a file-selector that allows", - "you to load a brush.", - "", - true, - SDLK_F3|MOD_CTRL, // Ctrl + F3 - 0}, - {101, - "Settings", - "Opens a menu which permits you to", - "modify some parameters of the", - "program.", - true, - SDLK_F10|MOD_SHIFT, // Shift + F10 - 0}, - {102, - "Undo (Oops!)", - "Cancel the last action which", - "modified the picture.", - "", - true, - SDLK_u, // U - 0}, - {103, - "Redo", - "Redo the last undone action.", - "", - "", - true, - SDLK_u|MOD_SHIFT, // Shift + U - 0}, - {133, - "Kill", - "Kills the current page. It actually", - "removes the current page from the", - "list of \"Undo\" pages.", - true, - SDLK_DELETE|MOD_SHIFT, // Shift + Suppr - 0}, - {104, - "Clear page", - "Clears the picture with the first", - "color of the palette (usually black)", - "", - true, - SDLK_BACKSPACE, // BackSpace - 0}, - {105, - "Clear page with backcolor", - "Clears the picture with the", - "current backcolor.", - "", - true, - SDLK_BACKSPACE|MOD_SHIFT, // Shift + BackSpace - 0}, - {106, - "Quit program", - "Allows you to leave the program.", - "If modifications were not saved,", - "confirmation is asked.", - false, - SDLK_q, // Q (A en AZERTY) - 0}, - {107, - "Palette menu", - "Opens a menu which allows you to", - "modify the current palette.", - "", - true, - SDLK_p, // P - 0}, - {125, - "Secondary palette menu", - "Opens a menu which allows you to", - "define color series and some tagged", - "colors.", - true, - SDLK_p|MOD_SHIFT, // Shift + P - 0}, - {130, - "Exclude colors menu", - "Opens a menu which allows you to", - "define the colors you don""t want to", - "use in Smooth and Transparency", - true, - SDLK_p|MOD_CTRL, // Ctrl + P - 0}, - {108, - "Scroll palette to the left", - "Scroll palette in the tool bar to", - "the left, column by column.", - "", - true, - SDLK_PAGEUP, // PgUp - 0}, - {109, - "Scroll palette to the right", - "Scroll palette in the tool bar to", - "the right, column by column.", - "", - true, - SDLK_PAGEDOWN, // PgDn - 0}, - {110, - "Scroll palette to the left faster", - "Scroll palette in the tool bar to", - "the left, 8 columns by 8 columns.", - "", - true, - SDLK_PAGEUP|MOD_SHIFT, // Shift + PgUp - 0}, - {111, - "Scroll palette to the right faster", - "Scroll palette in the tool bar to", - "the right, 8 columns by 8 columns.", - "", - true, - SDLK_PAGEDOWN|MOD_SHIFT, // Shift + PgDn - 0}, - {112, - "Center brush attachment point", - "Set the attachement of the", - "user-defined brush to its center.", - "", - true, - SDLK_KP5|MOD_CTRL, // Ctrl + 5 (pavé numérique) - 0}, - {113, - "Top-left brush attachment point", - "Set the attachement of the", - "user-defined brush to its top-left", - "corner.", - true, - SDLK_HOME|MOD_CTRL, // Ctrl + 7 - 0}, - {114, - "Top-right brush attachment point", - "Set the attachement of the", - "user-defined brush to its top-right", - "corner.", - true, - SDLK_PAGEUP|MOD_CTRL, // Ctrl + 9 - 0}, - {115, - "Bottom-left brush attachment point", - "Set the attachement of the", - "user-defined brush to its", - "bottom-left corner.", - true, - SDLK_END|MOD_CTRL, // Ctrl + 1 - 0}, - {116, - "Bottom-right brush attachment point", - "Set the attachement of the", - "user-defined brush to its", - "bottom-right corner.", - true, - SDLK_PAGEDOWN|MOD_CTRL, // Ctrl + 3 - 0}, - {117, - "Next foreground color", - "Set the foreground color to the next", - "in the palette.", - "", - true, - SDLK_RIGHTBRACKET, // ] (0x en AZERTY) - 0}, - {118, - "Previous foreground color", - "Set the foreground color to the", - "previous in the palette.", - "", - true, - SDLK_LEFTBRACKET, // [ (^ en AZERTY) - 0}, - {119, - "Next background color", - "Set the background color to the next", - "in the palette.", - "", - true, - SDLK_RIGHTBRACKET|MOD_SHIFT, // Shift + ] - 0}, - {120, - "Previous background color", - "Set the background color to the", - "previous in the palette.", - "", - true, - SDLK_LEFTBRACKET|MOD_SHIFT, // Shift + [ - 0}, - {126, - "Next user-defined forecolor", - "Set the foreground color to the next", - "in the user-defined color series.", - "", - true, - SDLK_EQUALS, // "=+" - 0}, - {127, - "Previous user-defined forecolor", - "Set the foreground color to the", - "previous in the user-defined color", - "series.", - true, - SDLK_MINUS, // "-_" (")°" en AZERTY - 0}, - {128, - "Next user-defined backcolor", - "Set the background color to the next", - "in the user-defined color series.", - "", - true, - SDLK_EQUALS|MOD_SHIFT, // Shift + "=+" - 0}, - {129, - "Previous user-defined backcolor", - "Set the background color to the", - "previous in the user-defined color", - "series.", - true, - SDLK_MINUS|MOD_SHIFT, // Shift + "-_" (")°" en AZERTY - 0}, - {121, - "Shrink paintbrush", - "Decrease the width of the paintbrush", - "if it is special circle or square.", - "", - true, - SDLK_COMMA, // , < (;. en AZERTY) - 0}, - {122, - "Enlarge paintbrush", - "Increase the width of the paintbrush", - "if it is special circle or square.", - "", - true, - SDLK_PERIOD, // .> (:/ en AZERTY) - 0}, - {134, - "Effects off", - "Turns off all drawing effects. This", - "is the same as the 'All off' button", - "in the Effects screen", - true, - SDLK_e|MOD_SHIFT, // Shift-E - 0}, - {135, - "Transparency 10%", - "Turns transparency on and sets its", - "opacity at 10%.", - "", - true, - SDLK_1, // 1 - 0}, - {136, - "Transparency 20%", - "Turns transparency on and sets its", - "opacity at 20%.", - "", - true, - SDLK_2, // 2 - 0}, - {137, - "Transparency 30%", - "Turns transparency on and sets its", - "opacity at 30%.", - "", - true, - SDLK_3, // 3 - 0}, - {138, - "Transparency 40%", - "Turns transparency on and sets its", - "opacity at 40%.", - "", - true, - SDLK_4, // 4 - 0}, - {139, - "Transparency 50%", - "Turns transparency on and sets its", - "opacity at 50%.", - "", - true, - SDLK_5, // 5 - 0}, - {140, - "Transparency 60%", - "Turns transparency on and sets its", - "opacity at 60%.", - "", - true, - SDLK_6, // 6 - 0}, - {141, - "Transparency 70%", - "Turns transparency on and sets its", - "opacity at 70%.", - "", - true, - SDLK_7, // 7 - 0}, - {142, - "Transparency 80%", - "Turns transparency on and sets its", - "opacity at 80%.", - "", - true, - SDLK_8, // 8 - 0}, - {143, - "Transparency 90%", - "Turns transparency on and sets its", - "opacity at 90%.", - "", - true, - SDLK_9, // 9 - 0}, - {144, - "Transparency 0%", - "Turns transparency on and sets its", - "opacity at 0%.", - "", - true, - SDLK_0, // 0 - 0}, -}; - -word Ordering[NB_SHORTCUTS]= -{ - SPECIAL_SCROLL_UP, // Scroll up - SPECIAL_SCROLL_DOWN, // Scroll down - SPECIAL_SCROLL_LEFT, // Scroll left - SPECIAL_SCROLL_RIGHT, // Scroll right - SPECIAL_SCROLL_UP_FAST, // Scroll up faster - SPECIAL_SCROLL_DOWN_FAST, // Scroll down faster - SPECIAL_SCROLL_LEFT_FAST, // Scroll left faster - SPECIAL_SCROLL_RIGHT_FAST, // Scroll right faster - SPECIAL_SCROLL_UP_SLOW, // Scroll up slower - SPECIAL_SCROLL_DOWN_SLOW, // Scroll down slower - SPECIAL_SCROLL_LEFT_SLOW, // Scroll left slower - SPECIAL_SCROLL_RIGHT_SLOW, // Scroll right slower - SPECIAL_MOUSE_UP, // Emulate mouse up - SPECIAL_MOUSE_DOWN, // Emulate mouse down - SPECIAL_MOUSE_LEFT, // Emulate mouse left - SPECIAL_MOUSE_RIGHT, // Emulate mouse right - SPECIAL_CLICK_LEFT, // Emulate mouse click left - SPECIAL_CLICK_RIGHT, // Emulate mouse click right - 0x100+BUTTON_HIDE, // Show / Hide menu - SPECIAL_SHOW_HIDE_CURSOR, // Show / Hide cursor - SPECIAL_DOT_PAINTBRUSH, // Paintbrush = "." - 0x100+BUTTON_PAINTBRUSHES, // Paintbrush choice - 0x200+BUTTON_PAINTBRUSHES, // Monochrome brush - 0x100+BUTTON_DRAW, // Freehand drawing - 0x200+BUTTON_DRAW, // Switch freehand drawing mode - SPECIAL_CONTINUOUS_DRAW, // Continuous freehand drawing - 0x100+BUTTON_LINES, // Line - 0x200+BUTTON_LINES, // Knotted lines - 0x100+BUTTON_AIRBRUSH, // Spray - 0x200+BUTTON_AIRBRUSH, // Spray menu - 0x100+BUTTON_FLOODFILL, // Floodfill - 0x200+BUTTON_FLOODFILL, // Replace color - 0x100+BUTTON_CURVES, // Bézier's curves - 0x200+BUTTON_CURVES, // Bézier's curve with 3 or 4 points - 0x100+BUTTON_RECTANGLES, // Empty rectangle - 0x100+BUTTON_FILLRECT, // Filled rectangle - 0x100+BUTTON_CIRCLES, // Empty circle - 0x200+BUTTON_CIRCLES, // Empty ellipse - 0x100+BUTTON_FILLCIRC, // Filled circle - 0x200+BUTTON_FILLCIRC, // Filled ellipse - 0x100+BUTTON_POLYGONS, // Empty polygon - 0x200+BUTTON_POLYGONS, // Empty polyform - 0x100+BUTTON_POLYFILL, // Polyfill - 0x200+BUTTON_POLYFILL, // Filled polyform - 0x100+BUTTON_GRADRECT, // Gradient rectangle - 0x200+BUTTON_GRADRECT, // Gradation menu - 0x100+BUTTON_SPHERES, // Spheres - 0x200+BUTTON_SPHERES, // Gradient ellipses - 0x100+BUTTON_ADJUST, // Adjust picture - 0x200+BUTTON_ADJUST, // Flip picture menu - 0x100+BUTTON_EFFECTS, // Menu des effets - SPECIAL_SHADE_MODE, // Shade mode - SPECIAL_SHADE_MENU, // Shade menu - SPECIAL_QUICK_SHADE_MODE, // Quick-shade mode - SPECIAL_QUICK_SHADE_MENU, // Quick-shade menu - SPECIAL_STENCIL_MODE, // Stencil mode - SPECIAL_STENCIL_MENU, // Stencil menu - SPECIAL_MASK_MODE, // Mask mode - SPECIAL_MASK_MENU, // Mask menu - SPECIAL_GRID_MODE, // Grid mode - SPECIAL_GRID_MENU, // Grid menu - SPECIAL_SIEVE_MODE, // Sieve mode - SPECIAL_SIEVE_MENU, // Sieve menu - SPECIAL_INVERT_SIEVE, // Inverser la trame du mode Sieve - SPECIAL_COLORIZE_MODE, // Colorize mode - SPECIAL_COLORIZE_MENU, // Colorize menu - SPECIAL_SMOOTH_MODE, // Smooth mode - SPECIAL_SMOOTH_MENU, // Smooth menu - SPECIAL_SMEAR_MODE, // Smear mode - SPECIAL_TILING_MODE, // Tiling mode - SPECIAL_TILING_MENU, // Tiling menu - 0x100+BUTTON_BRUSH, // Pick brush - 0x100+BUTTON_POLYBRUSH, // Pick polyform brush - 0x200+BUTTON_BRUSH, // Restore brush - SPECIAL_FLIP_X, // Flip X - SPECIAL_FLIP_Y, // Flip Y - SPECIAL_ROTATE_90, // 90° brush rotation - SPECIAL_ROTATE_180, // 180° brush rotation - SPECIAL_STRETCH, // Stretch brush - SPECIAL_DISTORT, // Distort brush - SPECIAL_OUTLINE, // Outline brush - SPECIAL_NIBBLE, // Nibble brush - SPECIAL_GET_BRUSH_COLORS, // Get colors from brush - SPECIAL_RECOLORIZE_BRUSH, // Recolorize brush - SPECIAL_ROTATE_ANY_ANGLE, // Rotate brush by any angle - 0x100+BUTTON_COLORPICKER, // Pipette - 0x200+BUTTON_COLORPICKER, // Swap fore/back color - 0x100+BUTTON_MAGNIFIER, // Magnifier mode - 0x200+BUTTON_MAGNIFIER, // Zoom factor menu - SPECIAL_ZOOM_IN, // Zoom in - SPECIAL_ZOOM_OUT, // Zoom out - 0x100+BUTTON_BRUSH_EFFECTS, // Brush effects menu - 0x100+BUTTON_TEXT, // Text - 0x100+BUTTON_RESOL, // Resolution menu - 0x200+BUTTON_RESOL, // Safety resolution - 0x100+BUTTON_HELP, // Help & credits - 0x200+BUTTON_HELP, // Statistics - 0x100+BUTTON_PAGE, // Go to spare page - 0x200+BUTTON_PAGE, // Copy to spare page - 0x100+BUTTON_SAVE, // Save as - 0x200+BUTTON_SAVE, // Save - 0x100+BUTTON_LOAD, // Load - 0x200+BUTTON_LOAD, // Re-load - SPECIAL_SAVE_BRUSH, // Save brush - SPECIAL_LOAD_BRUSH, // Load brush - 0x100+BUTTON_SETTINGS, // Settings - 0x100+BUTTON_UNDO, // Undo - 0x200+BUTTON_UNDO, // Redo - 0x100+BUTTON_KILL, // Kill - 0x100+BUTTON_CLEAR, // Clear - 0x200+BUTTON_CLEAR, // Clear with backcolor - 0x100+BUTTON_QUIT, // Quit - 0x100+BUTTON_PALETTE, // Palette menu - 0x200+BUTTON_PALETTE, // Palette menu secondaire - SPECIAL_EXCLUDE_COLORS_MENU, // Exclude colors menu - 0x100+BUTTON_PAL_LEFT, // Scroll palette left - 0x100+BUTTON_PAL_RIGHT, // Scroll palette right - 0x200+BUTTON_PAL_LEFT, // Scroll palette left faster - 0x200+BUTTON_PAL_RIGHT, // Scroll palette right faster - SPECIAL_CENTER_ATTACHMENT, // Center brush attachement - SPECIAL_TOP_LEFT_ATTACHMENT, // Top-left brush attachement - SPECIAL_TOP_RIGHT_ATTACHMENT, // Top-right brush attachement - SPECIAL_BOTTOM_LEFT_ATTACHMENT, // Bottom-left brush attachement - SPECIAL_BOTTOM_RIGHT_ATTACHMENT, // Bottom right brush attachement - SPECIAL_NEXT_FORECOLOR, // Next foreground color - SPECIAL_PREVIOUS_FORECOLOR, // Previous foreground color - SPECIAL_NEXT_BACKCOLOR, // Next background color - SPECIAL_PREVIOUS_BACKCOLOR, // Previous background color - SPECIAL_NEXT_USER_FORECOLOR, // Next user-defined foreground color - SPECIAL_PREVIOUS_USER_FORECOLOR, // Previous user-defined foreground color - SPECIAL_NEXT_USER_BACKCOLOR, // Next user-defined background color - SPECIAL_PREVIOUS_USER_BACKCOLOR, // Previous user-defined background color - SPECIAL_SMALLER_PAINTBRUSH, // Sets paintbrush size: smaller - SPECIAL_BIGGER_PAINTBRUSH, // Sets paintbrush size: bigger - SPECIAL_EFFECTS_OFF, // Turns off all effects - SPECIAL_TRANSPARENCY_1, // Sets transparency level 10% - SPECIAL_TRANSPARENCY_2, // Sets transparency level 20% - SPECIAL_TRANSPARENCY_3, // Sets transparency level 30% - SPECIAL_TRANSPARENCY_4, // Sets transparency level 40% - SPECIAL_TRANSPARENCY_5, // Sets transparency level 50% - SPECIAL_TRANSPARENCY_6, // Sets transparency level 60% - SPECIAL_TRANSPARENCY_7, // Sets transparency level 70% - SPECIAL_TRANSPARENCY_8, // Sets transparency level 80% - SPECIAL_TRANSPARENCY_9, // Sets transparency level 90% - SPECIAL_TRANSPARENCY_0, // Sets transparency level 00% -}; +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 Yves Rizoud + Copyright 2008 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 +*/ +#include "struct.h" +#include "global.h" +#include "hotkeys.h" + +T_Key_config ConfigKey[NB_SHORTCUTS] = { + {0, + "Scroll up", + "Scrolls the picture up, both in", + "magnify and normal mode.", + "", + false, + SDLK_UP, // HAUT + 0}, + {1, + "Scroll down", + "Scrolls the picture down, both in", + "magnify and normal mode.", + "", + false, + SDLK_DOWN, // BAS + 0}, + {2, + "Scroll left", + "Scrolls the picture to the left,", + "both in magnify and normal mode.", + "", + false, + SDLK_LEFT, // GAUCHE + 0}, + {3, + "Scroll right", + "Scrolls the picture to the right,", + "both in magnify and normal mode.", + "", + false, + SDLK_RIGHT, // DROITE + 0}, + {4, + "Faster scroll up", + "Used to scroll upwards in the", + "picture fast, either in magnify and", + "normal mode.", + true, + SDLK_UP|MOD_SHIFT, // Shift + Haut + 0}, + {5, + "Faster scroll down", + "Used to scroll downwards in the", + "picture fast, either in magnify and", + "normal mode.", + true, + SDLK_DOWN|MOD_SHIFT, // Shift + Bas + 0}, + {6, + "Faster scroll left", + "Used to scroll to the left in the", + "picture fast, either in magnify and", + "normal mode.", + true, + SDLK_LEFT|MOD_SHIFT, // Shift + Gauche + 0}, + {7, + "Faster scroll right", + "Used to scroll to the right in the", + "picture fast, either in magnify and", + "normal mode.", + true, + SDLK_RIGHT|MOD_SHIFT, // Shift + Droite + 0}, + {8, + "Slower scroll up", + "Used to scroll upwards in the", + "picture pixel by pixel, either in", + "magnify and normal mode.", + true, + SDLK_UP|MOD_ALT, // Alt + Haut + 0}, + {9, + "Slower scroll down", + "Used to scroll downwards in the", + "picture pixel by pixel, either in", + "magnify and normal mode.", + true, + SDLK_DOWN|MOD_ALT, // Alt + Bas + 0}, + {10, + "Slower scroll left", + "Used to scroll to the left in the", + "picture pixel by pixel, either in", + "magnify and normal mode.", + true, + SDLK_LEFT|MOD_ALT, // Alt + Gauche + 0}, + {11, + "Slower scroll right", + "Used to scroll to the right in the", + "picture pixel by pixel, either in", + "magnify and normal mode.", + true, + SDLK_RIGHT|MOD_ALT, // Alt + Droite + 0}, + {12, + "Move mouse cursor 1 pixel up", + "Used to simulate a very small mouse", + "deplacement up.It""s very useful", + "when you want ultra-high precision.", + true, + SDLK_UP|MOD_CTRL, // Ctrl + Haut + 0}, + {13, + "Move mouse cursor 1 pixel down", + "Used to simulate a very small mouse", + "deplacement down.It""s very useful", + "when you want ultra-high precision.", + true, + SDLK_DOWN|MOD_CTRL, // Ctrl + Bas + 0}, + {14, + "Move mouse cursor 1 pixel left", + "Used to simulate a very small mouse", + "deplacement left.It""s very useful", + "when you want ultra-high precision.", + true, + SDLK_LEFT|MOD_CTRL, // Ctrl + Gauche + 0}, + {15, + "Move mouse cursor 1 pixel right", + "Used to simulate a very small mouse", + "deplacement right.It""s very useful", + "when you want ultra-high precision.", + true, + SDLK_RIGHT|MOD_CTRL, // Ctrl + Droite + 0}, + {16, + "Simulate left mouse click", + "Used to simulate a click with the", + "left mouse button. It""s useful", + "when you want ultra-high precision.", + true, + SDLK_SPACE, // Space + 0}, + {17, + "Simulate right mouse click", + "Used to simulate a click with the", + "right mouse button.. It""s useful", + "when you want ultra-high precision.", + true, + SDLK_SPACE|MOD_SHIFT, // Shift + Space + 0}, + {18, + "Show/hide option menu", + "Switch the tool bar display on/off.", + "This hot-key cannot be removed.", + "", + false, + SDLK_F10, // F10 + 0}, + {19, + "Show/hide cursor", + "Switch the cursor display on/off.", + "This only works on the \"small cross\"", + "and \"hand\" cursors.", + true, + SDLK_F9, // F9 + 0}, + {20, + "Set paintbrush to 1 pixel", + "Useful when you want to use a", + "\"single-pixel-brush\".", + "", + true, + SDLK_DELETE, // Del + 0}, + {21, + "Paintbrush choice", + "Opens a menu where you can choose a", + "paintbrush out of 24 predefined", + "ones.", + true, + SDLK_F4, // F4 + 0}, + {22, + "Monochrome brush", + "Turn your current user-defined brush", + "into a single colored one. All non-", + "transparent colors are set to FG.", + true, + SDLK_F4|MOD_SHIFT, // Shift + F4 + 0}, + {23, + "Freehand drawing", + "Set the drawing mode to the", + "classical freehand one.", + "", + true, + SDLK_d, // D + 0}, + {24, + "Switch freehand drawing mode", + "Alternates between: continuous,", + "discontinuous, point by point,", + "and contour fill", + true, + SDLK_d|MOD_SHIFT, // Shift + D + 0}, + {25, + "Continuous freehand drawing", + "Switch directly to continuous", + "freehand drawing mode.", + "", + true, + SDLK_d|MOD_CTRL, // Ctrl + D + 0}, + {26, + "Line", + "Allows you to draw lines.", + "", + "", + true, + SDLK_l, // L + 0}, + {27, + "Knotted lines", + "Allows you to draw linked lines.", + "This mode can also be called", + "\"Polyline\".", + true, + SDLK_l|MOD_SHIFT, // Shift + L + 0}, + {28, + "Spray", + "Allows you to spray brushes", + "randomly in the picture.", + "", + true, + SDLK_a, // A (Q en AZERTY) + 0}, + {29, + "Spray menu", + "Opens a menu in which you can", + "configure the spray flow and size.", + "", + true, + SDLK_a|MOD_SHIFT, // Shift + A + 0}, + {30, + "Flood-fill", + "Allows you to fill an area of the", + "picture made of pixels of the same", + "color.", + true, + SDLK_f, // F + 0}, + {124, + "Replace color", + "This tool replaces all the pixels of", + "the clicked color to the fore-color", + "or the back-color.", + true, + SDLK_f|MOD_SHIFT, // Shift + F + 0}, + {31, + "Bezier""s curves", + "Allows you to draw Bezier""s curves.", + "", + "", + true, + SDLK_i, // I + 0}, + {32, + "Bezier""s curve with 3 or 4 points", + "Allows you to choose whether you", + "want to draw Bezier""s curves with", + "3 or 4 points.", + true, + SDLK_i|MOD_SHIFT, // Shift + I + 0}, + {33, + "Empty rectangle", + "Allows you to draw a rectangle using", + "the brush.", + "", + true, + SDLK_r, // R + 0}, + {34, + "Filled rectangle", + "Allows you to draw a filled", + "rectangle.", + "", + true, + SDLK_r|MOD_SHIFT, // Shift + R + 0}, + {35, + "Empty circle", + "Allows you to draw a circle using", + "the brush.", + "", + true, + SDLK_c, // C + 0}, + {36, + "Empty ellipse", + "Allows you to draw an ellipse using", + "the brush.", + "", + true, + SDLK_c|MOD_CTRL, // Ctrl + C + 0}, + {37, + "Filled circle", + "Allows you to draw a filled circle.", + "", + "", + true, + SDLK_c|MOD_SHIFT, // Shift + C + 0}, + {38, + "Filled ellipse", + "Allows you to draw a filled ellipse.", + "", + "", + true, + SDLK_c|MOD_SHIFT|MOD_CTRL, // Shift + Ctrl + C + 0}, + {39, + "Empty polygon", + "Allows you to draw a polygon using", + "the brush.", + "", + true, + SDLK_n, // N + 0}, + {40, + "Empty \"polyform\"", + "Allows you to draw a freehand", + "polygon using the brush.", + "", + true, + SDLK_n|MOD_CTRL, // Ctrl + N + 0}, + {41, + "Filled polygon", + "Allows you to draw a filled polygon.", + "", + "", + true, + SDLK_n|MOD_SHIFT, // Shift + N + 0}, + {42, + "Filled \"polyform\"", + "Allows you to draw a filled freehand", + "polygon.", + "", + true, + SDLK_n|MOD_SHIFT|MOD_CTRL, // Shift + Ctrl + N + 0}, + {43, + "Rectangle with gradation", + "Allows you to draw a rectangle with", + "a color gradation.", + "", + true, + SDLK_r|MOD_ALT, // Alt + R + 0}, + {44, + "Gradation menu", + "Allows you to configure the way", + "color gradations are calculated.", + "", + true, + SDLK_g|MOD_ALT, // Alt + G + 0}, + {45, + "Sphere with gradation", + "Allows you to draw a rectangle with", + "a color gradation.", + "", + true, + SDLK_c|MOD_ALT, // Alt + C + 0}, + {46, + "Ellipse with gradation", + "Allows you to draw an ellipse filled", + "with a color gradation.", + "", + true, + SDLK_c|MOD_SHIFT|MOD_ALT, // Shift + Alt + C + 0}, + {47, + "Adjust picture", + "Allows you to move the whole picture", + "Around. What gets out from a side", + "reappears on the other.", + true, + SDLK_KP5, // Kpad5 + 0}, + {48, + "Picture effects", + "Opens the 'Picture effects' window.", + "", + "", + true, + SDLK_KP5|MOD_SHIFT, // Shift + Kpad5 + 0}, + {49, + "Drawing effects", + "Opens a menu where you can enable/", + "disable and configure the drawing", + "effects.", + true, + SDLK_e, // E + 0}, + {50, + "Shade mode", + "Enables or disables Shade mode", + "", + "", + true, + SDLK_F5, // F5 + 0}, + {51, + "Shade menu", + "Opens a the menu for Shade settings.", + "", + "", + true, + SDLK_F5|MOD_SHIFT, // Shift + F5 + 0}, + {131, + "Quick-shade mode", + "Enables or disables Quick-shade", + "mode.", + "", + true, + SDLK_F5|MOD_CTRL, // Ctrl + F5 + 0}, + {132, + "Quick-shade menu", + "Opens a the menu for Quick-shade", + "settings.", + "", + true, + SDLK_F5|MOD_SHIFT|MOD_CTRL, // Shift + Ctrl + F5 + 0}, + {52, + "Stencil mode", + "Enables or disables Stencil mode.", + "", + "", + true, + SDLK_F6, // F6 + 0}, + {53, + "Stencil menu", + "Opens a the menu for Stencil", + "settings.", + "", + true, + SDLK_F6|MOD_SHIFT, // Shift + F6 + 0}, + {54, + "Mask mode", + "Enables or disables Mask mode.", + "", + "", + true, + SDLK_F6|MOD_ALT, // Alt + F6 + 0}, + {55, + "Mask menu", + "Opens a the menu for Mask settings.", + "", + "", + true, + SDLK_F6|MOD_SHIFT|MOD_ALT, // Shift + Alt + F6 + 0}, + {56, + "Grid mode", + "Enables or disables the Grid mode.", + "", + "", + true, + SDLK_g, // G + 0}, + {57, + "Grid menu", + "Open a menu where you can configure", + "the grid used by Grid mode.", + "", + true, + SDLK_g|MOD_SHIFT, // Shift + G + 0}, + {58, + "Sieve mode", + "Enables or disables the Sieve mode.", + "", + "", + true, + SDLK_g|MOD_CTRL, // Ctrl + G + 0}, + {59, + "Sieve menu", + "Opens a menu where you can configure", + "the sieve.", + "", + true, + SDLK_g|MOD_SHIFT|MOD_CTRL, // Shift + Ctrl + G + 0}, + {60, + "Invert sieve", + "Inverts the pattern defined in the", + "Sieve menu.", + "", + true, + SDLK_g|MOD_CTRL|MOD_ALT, // Ctrl + Alt + G + 0}, + {61, + "Colorize mode", + "Enables or disables the Colorize", + "mode.", + "", + true, + SDLK_F7, // F7 + 0}, + {62, + "Colorize menu", + "Opens a menu where you can give the", + "opacity percentage for Colorize", + "mode.", + true, + SDLK_F7|MOD_SHIFT, // Shift + F7 + 0}, + {63, + "Smooth mode", + "Enables or disables the Smooth", + "mode.", + "", + true, + SDLK_F8, // F8 + 0}, + {123, + "Smooth menu", + "Opens a menu where you can define", + "the Smooth matrix.", + "", + true, + SDLK_F8|MOD_SHIFT, // Shift + F8 + 0}, + {64, + "Smear mode", + "Enables or disables the Smear mode.", + "", + "", + true, + SDLK_F8|MOD_ALT, // Alt + F8 + 0}, + {65, + "Tiling mode", + "Enables or disables the Tiling", + "mode.", + "", + true, + SDLK_b|MOD_ALT, // Alt + B + 0}, + {66, + "Tiling menu", + "Opens a menu where you can configure", + "the origin of the tiling.", + "", + true, + SDLK_b|MOD_SHIFT|MOD_ALT, // Shift + Alt + B + 0}, + {67, + "Classical brush grabbing", + "Allows you to pick a brush defined", + "within a rectangle.", + "", + true, + SDLK_b, // B + 0}, + {68, + "\"Lasso\" brush grabbing", + "Allows you to pick a brush defined", + "within a freehand polygon.", + "", + true, + SDLK_b|MOD_CTRL, // Ctrl + B + 0}, + {69, + "Get previous brush back", + "Restore the last user-defined brush.", + "", + "", + true, + SDLK_b|MOD_SHIFT, // Shift + B + 0}, + {70, + "Horizontal brush flipping", + "Reverse brush horizontally.", + "", + "", + true, + SDLK_x, // X + 0}, + {71, + "Vertical brush flipping", + "Reverse brush vertically.", + "", + "", + true, + SDLK_y, // Y + 0}, + {72, + "90° brush rotation", + "Rotate the user-defined brush by 90°", + "(counter-clockwise).", + "", + true, + SDLK_z, // Z (W en AZERTY) + 0}, + {73, + "180° brush rotation", + "Rotate the user-defined brush by", + "180°.", + "", + true, + SDLK_z|MOD_SHIFT, // Shift + Z + 0}, + {74, + "Strech brush", + "Allows you to resize the", + "user-defined brush.", + "", + true, + SDLK_s, // S + 0}, + {75, + "Distort brush", + "Allows you to distort the", + "user-defined brush.", + "", + true, + SDLK_s|MOD_SHIFT, // Shift + S + 0}, + {76, + "Outline brush", + "Outlines the user-defined brush", + "with the fore color.", + "", + true, + SDLK_o, // O + 0}, + {77, + "Nibble brush", + "Deletes the borders of the", + "user-defined brush.This does the", + "opposite of the Outline option.", + true, + SDLK_o|MOD_SHIFT, // Shift + O + 0}, + {78, + "Get colors from brush", + "Copy colors of the spare page that", + "are used in the brush.", + "", + true, + SDLK_F11, // F11 + 0}, + {79, + "Recolorize brush", + "Recolorize the user-defined brush in", + "order to get a brush which looks as", + "if it was grabbed in the spare page.", + true, + SDLK_F12, // F12 + 0}, + {80, + "Rotate by any angle", + "Rotate the brush by an angle that", + "you can define.", + "", + true, + SDLK_w, // W (Z en AZERTY) + 0}, + {81, + "Pipette", + "Allows you to copy the color of a", + "pixel in the picture into the", + "foreground or background color.", + true, + SDLK_BACKQUOTE, // `~ (Key sous le Esc - ² en AZERTY) + 0}, + {82, + "Swap foreground/background colors", + "Invert foreground and background", + "colors.", + "", + true, + SDLK_BACKQUOTE|MOD_SHIFT, // Shift + `~ + 0}, + {83, + "Magnifier mode", + "Allows you to zoom into the picture.", + "", + "", + true, + SDLK_m, // M (, ? sur AZERTY) + KEY_MOUSEMIDDLE}, + {84, + "Zoom factor menu", + "Opens a menu where you can choose a", + "magnifying factor.", + "", + true, + SDLK_m|MOD_SHIFT, // Shift + M + 0}, + {85, + "Zoom in", + "Increase magnifying factor.", + "", + "", + true, + SDLK_KP_PLUS, // Grey + + KEY_MOUSEWHEELUP}, + {86, + "Zoom out", + "Decrease magnifying factor.", + "", + "", + true, + SDLK_KP_MINUS, // Grey - + KEY_MOUSEWHEELDOWN}, + {87, + "Brush effects menu", + "Opens a menu which proposes", + "different effects on the", + "user-defined brush.", + true, + SDLK_b|MOD_CTRL|MOD_ALT, // Ctrl + Alt + B + 0}, + {88, + "Text", + "Opens a menu which permits you to", + "type in a character string and", + "render it as a brush.", + true, + SDLK_t, // T + 0}, + {89, + "Screen resolution menu", + "Opens a menu where you can choose", + "the screen resolution and image", + "dimensions.", + true, + SDLK_RETURN, // Enter + 0}, + {90, + "\"Safety\" resolution", + "Resets the resolution to a 'safe'", + "mode that should work everywhere:", + "usually a 640x400 window.", + false, + SDLK_RETURN|MOD_SHIFT, // Shift + Enter + 0}, + {91, + "Help and credits", + "Opens a window where you can get", + "information about the program,", + "or contextual help.", + true, + SDLK_F1, // F1 + 0}, + {92, + "Statistics", + "Displays miscellaneous more or less", + "useful information.", + "", + true, + SDLK_F1|MOD_SHIFT, // Shift + F1 + 0}, + {93, + "Jump to spare page", + "Swap current page and spare page.", + "", + "", + true, + SDLK_TAB, // Tab + 0}, + {94, + "Copy current page to spare page", + "Copy current page to spare page.", + "", + "", + true, + SDLK_TAB|MOD_SHIFT, // Shift + Tab + 0}, + {95, + "Save picture as...", + "Opens a file-selector that allows", + "you to save your picture with a new", + "path-name.", + true, + SDLK_F2, // F2 + 0}, + {96, + "Save picture", + "Saves your picture with the last", + "name you gave it.", + "", + true, + SDLK_F2|MOD_SHIFT, // Shift + F2 + 0}, + {97, + "Load picture", + "Opens a file-selector that allows", + "you to load a new picture.", + "", + true, + SDLK_F3, // F3 + 0}, + {98, + "Re-load picture", + "Re-load the current picture. This", + "allows you to cancel modifications", + "made since last saving.", + true, + SDLK_F3|MOD_SHIFT, // Shift + F3 + 0}, + {99, + "Save brush", + "Opens a file-selector that allows", + "you to save your current", + "user-defined brush.", + true, + SDLK_F2|MOD_CTRL, // Ctrl + F2 + 0}, + {100, + "Load brush", + "Opens a file-selector that allows", + "you to load a brush.", + "", + true, + SDLK_F3|MOD_CTRL, // Ctrl + F3 + 0}, + {101, + "Settings", + "Opens a menu which permits you to", + "modify some parameters of the", + "program.", + true, + SDLK_F10|MOD_SHIFT, // Shift + F10 + 0}, + {102, + "Undo (Oops!)", + "Cancel the last action which", + "modified the picture.", + "", + true, + SDLK_u, // U + 0}, + {103, + "Redo", + "Redo the last undone action.", + "", + "", + true, + SDLK_u|MOD_SHIFT, // Shift + U + 0}, + {133, + "Kill", + "Kills the current page. It actually", + "removes the current page from the", + "list of \"Undo\" pages.", + true, + SDLK_DELETE|MOD_SHIFT, // Shift + Suppr + 0}, + {104, + "Clear page", + "Clears the picture with the first", + "color of the palette (usually black)", + "", + true, + SDLK_BACKSPACE, // BackSpace + 0}, + {105, + "Clear page with backcolor", + "Clears the picture with the", + "current backcolor.", + "", + true, + SDLK_BACKSPACE|MOD_SHIFT, // Shift + BackSpace + 0}, + {106, + "Quit program", + "Allows you to leave the program.", + "If modifications were not saved,", + "confirmation is asked.", + false, + SDLK_q, // Q (A en AZERTY) + 0}, + {107, + "Palette menu", + "Opens a menu which allows you to", + "modify the current palette.", + "", + true, + SDLK_p, // P + 0}, + {125, + "Secondary palette menu", + "Opens a menu which allows you to", + "define color series and some tagged", + "colors.", + true, + SDLK_p|MOD_SHIFT, // Shift + P + 0}, + {130, + "Exclude colors menu", + "Opens a menu which allows you to", + "define the colors you don""t want to", + "use in Smooth and Transparency", + true, + SDLK_p|MOD_CTRL, // Ctrl + P + 0}, + {108, + "Scroll palette to the left", + "Scroll palette in the tool bar to", + "the left, column by column.", + "", + true, + SDLK_PAGEUP, // PgUp + 0}, + {109, + "Scroll palette to the right", + "Scroll palette in the tool bar to", + "the right, column by column.", + "", + true, + SDLK_PAGEDOWN, // PgDn + 0}, + {110, + "Scroll palette to the left faster", + "Scroll palette in the tool bar to", + "the left, 8 columns by 8 columns.", + "", + true, + SDLK_PAGEUP|MOD_SHIFT, // Shift + PgUp + 0}, + {111, + "Scroll palette to the right faster", + "Scroll palette in the tool bar to", + "the right, 8 columns by 8 columns.", + "", + true, + SDLK_PAGEDOWN|MOD_SHIFT, // Shift + PgDn + 0}, + {112, + "Center brush attachment point", + "Set the attachement of the", + "user-defined brush to its center.", + "", + true, + SDLK_KP5|MOD_CTRL, // Ctrl + 5 (pavé numérique) + 0}, + {113, + "Top-left brush attachment point", + "Set the attachement of the", + "user-defined brush to its top-left", + "corner.", + true, + SDLK_HOME|MOD_CTRL, // Ctrl + 7 + 0}, + {114, + "Top-right brush attachment point", + "Set the attachement of the", + "user-defined brush to its top-right", + "corner.", + true, + SDLK_PAGEUP|MOD_CTRL, // Ctrl + 9 + 0}, + {115, + "Bottom-left brush attachment point", + "Set the attachement of the", + "user-defined brush to its", + "bottom-left corner.", + true, + SDLK_END|MOD_CTRL, // Ctrl + 1 + 0}, + {116, + "Bottom-right brush attachment point", + "Set the attachement of the", + "user-defined brush to its", + "bottom-right corner.", + true, + SDLK_PAGEDOWN|MOD_CTRL, // Ctrl + 3 + 0}, + {117, + "Next foreground color", + "Set the foreground color to the next", + "in the palette.", + "", + true, + SDLK_RIGHTBRACKET, // ] (0x en AZERTY) + 0}, + {118, + "Previous foreground color", + "Set the foreground color to the", + "previous in the palette.", + "", + true, + SDLK_LEFTBRACKET, // [ (^ en AZERTY) + 0}, + {119, + "Next background color", + "Set the background color to the next", + "in the palette.", + "", + true, + SDLK_RIGHTBRACKET|MOD_SHIFT, // Shift + ] + 0}, + {120, + "Previous background color", + "Set the background color to the", + "previous in the palette.", + "", + true, + SDLK_LEFTBRACKET|MOD_SHIFT, // Shift + [ + 0}, + {126, + "Next user-defined forecolor", + "Set the foreground color to the next", + "in the user-defined color series.", + "", + true, + SDLK_EQUALS, // "=+" + 0}, + {127, + "Previous user-defined forecolor", + "Set the foreground color to the", + "previous in the user-defined color", + "series.", + true, + SDLK_MINUS, // "-_" (")°" en AZERTY + 0}, + {128, + "Next user-defined backcolor", + "Set the background color to the next", + "in the user-defined color series.", + "", + true, + SDLK_EQUALS|MOD_SHIFT, // Shift + "=+" + 0}, + {129, + "Previous user-defined backcolor", + "Set the background color to the", + "previous in the user-defined color", + "series.", + true, + SDLK_MINUS|MOD_SHIFT, // Shift + "-_" (")°" en AZERTY + 0}, + {121, + "Shrink paintbrush", + "Decrease the width of the paintbrush", + "if it is special circle or square.", + "", + true, + SDLK_COMMA, // , < (;. en AZERTY) + 0}, + {122, + "Enlarge paintbrush", + "Increase the width of the paintbrush", + "if it is special circle or square.", + "", + true, + SDLK_PERIOD, // .> (:/ en AZERTY) + 0}, + {134, + "Effects off", + "Turns off all drawing effects. This", + "is the same as the 'All off' button", + "in the Effects screen", + true, + SDLK_e|MOD_SHIFT, // Shift-E + 0}, + {135, + "Transparency 10%", + "Turns transparency on and sets its", + "opacity at 10%.", + "", + true, + SDLK_1, // 1 + 0}, + {136, + "Transparency 20%", + "Turns transparency on and sets its", + "opacity at 20%.", + "", + true, + SDLK_2, // 2 + 0}, + {137, + "Transparency 30%", + "Turns transparency on and sets its", + "opacity at 30%.", + "", + true, + SDLK_3, // 3 + 0}, + {138, + "Transparency 40%", + "Turns transparency on and sets its", + "opacity at 40%.", + "", + true, + SDLK_4, // 4 + 0}, + {139, + "Transparency 50%", + "Turns transparency on and sets its", + "opacity at 50%.", + "", + true, + SDLK_5, // 5 + 0}, + {140, + "Transparency 60%", + "Turns transparency on and sets its", + "opacity at 60%.", + "", + true, + SDLK_6, // 6 + 0}, + {141, + "Transparency 70%", + "Turns transparency on and sets its", + "opacity at 70%.", + "", + true, + SDLK_7, // 7 + 0}, + {142, + "Transparency 80%", + "Turns transparency on and sets its", + "opacity at 80%.", + "", + true, + SDLK_8, // 8 + 0}, + {143, + "Transparency 90%", + "Turns transparency on and sets its", + "opacity at 90%.", + "", + true, + SDLK_9, // 9 + 0}, + {144, + "Transparency 0%", + "Turns transparency on and sets its", + "opacity at 0%.", + "", + true, + SDLK_0, // 0 + 0}, +}; + +word Ordering[NB_SHORTCUTS]= +{ + SPECIAL_SCROLL_UP, // Scroll up + SPECIAL_SCROLL_DOWN, // Scroll down + SPECIAL_SCROLL_LEFT, // Scroll left + SPECIAL_SCROLL_RIGHT, // Scroll right + SPECIAL_SCROLL_UP_FAST, // Scroll up faster + SPECIAL_SCROLL_DOWN_FAST, // Scroll down faster + SPECIAL_SCROLL_LEFT_FAST, // Scroll left faster + SPECIAL_SCROLL_RIGHT_FAST, // Scroll right faster + SPECIAL_SCROLL_UP_SLOW, // Scroll up slower + SPECIAL_SCROLL_DOWN_SLOW, // Scroll down slower + SPECIAL_SCROLL_LEFT_SLOW, // Scroll left slower + SPECIAL_SCROLL_RIGHT_SLOW, // Scroll right slower + SPECIAL_MOUSE_UP, // Emulate mouse up + SPECIAL_MOUSE_DOWN, // Emulate mouse down + SPECIAL_MOUSE_LEFT, // Emulate mouse left + SPECIAL_MOUSE_RIGHT, // Emulate mouse right + SPECIAL_CLICK_LEFT, // Emulate mouse click left + SPECIAL_CLICK_RIGHT, // Emulate mouse click right + 0x100+BUTTON_HIDE, // Show / Hide menu + SPECIAL_SHOW_HIDE_CURSOR, // Show / Hide cursor + SPECIAL_DOT_PAINTBRUSH, // Paintbrush = "." + 0x100+BUTTON_PAINTBRUSHES, // Paintbrush choice + 0x200+BUTTON_PAINTBRUSHES, // Monochrome brush + 0x100+BUTTON_DRAW, // Freehand drawing + 0x200+BUTTON_DRAW, // Switch freehand drawing mode + SPECIAL_CONTINUOUS_DRAW, // Continuous freehand drawing + 0x100+BUTTON_LINES, // Line + 0x200+BUTTON_LINES, // Knotted lines + 0x100+BUTTON_AIRBRUSH, // Spray + 0x200+BUTTON_AIRBRUSH, // Spray menu + 0x100+BUTTON_FLOODFILL, // Floodfill + 0x200+BUTTON_FLOODFILL, // Replace color + 0x100+BUTTON_CURVES, // Bézier's curves + 0x200+BUTTON_CURVES, // Bézier's curve with 3 or 4 points + 0x100+BUTTON_RECTANGLES, // Empty rectangle + 0x100+BUTTON_FILLRECT, // Filled rectangle + 0x100+BUTTON_CIRCLES, // Empty circle + 0x200+BUTTON_CIRCLES, // Empty ellipse + 0x100+BUTTON_FILLCIRC, // Filled circle + 0x200+BUTTON_FILLCIRC, // Filled ellipse + 0x100+BUTTON_POLYGONS, // Empty polygon + 0x200+BUTTON_POLYGONS, // Empty polyform + 0x100+BUTTON_POLYFILL, // Polyfill + 0x200+BUTTON_POLYFILL, // Filled polyform + 0x100+BUTTON_GRADRECT, // Gradient rectangle + 0x200+BUTTON_GRADRECT, // Gradation menu + 0x100+BUTTON_SPHERES, // Spheres + 0x200+BUTTON_SPHERES, // Gradient ellipses + 0x100+BUTTON_ADJUST, // Adjust picture + 0x200+BUTTON_ADJUST, // Flip picture menu + 0x100+BUTTON_EFFECTS, // Menu des effets + SPECIAL_SHADE_MODE, // Shade mode + SPECIAL_SHADE_MENU, // Shade menu + SPECIAL_QUICK_SHADE_MODE, // Quick-shade mode + SPECIAL_QUICK_SHADE_MENU, // Quick-shade menu + SPECIAL_STENCIL_MODE, // Stencil mode + SPECIAL_STENCIL_MENU, // Stencil menu + SPECIAL_MASK_MODE, // Mask mode + SPECIAL_MASK_MENU, // Mask menu + SPECIAL_GRID_MODE, // Grid mode + SPECIAL_GRID_MENU, // Grid menu + SPECIAL_SIEVE_MODE, // Sieve mode + SPECIAL_SIEVE_MENU, // Sieve menu + SPECIAL_INVERT_SIEVE, // Inverser la trame du mode Sieve + SPECIAL_COLORIZE_MODE, // Colorize mode + SPECIAL_COLORIZE_MENU, // Colorize menu + SPECIAL_SMOOTH_MODE, // Smooth mode + SPECIAL_SMOOTH_MENU, // Smooth menu + SPECIAL_SMEAR_MODE, // Smear mode + SPECIAL_TILING_MODE, // Tiling mode + SPECIAL_TILING_MENU, // Tiling menu + 0x100+BUTTON_BRUSH, // Pick brush + 0x100+BUTTON_POLYBRUSH, // Pick polyform brush + 0x200+BUTTON_BRUSH, // Restore brush + SPECIAL_FLIP_X, // Flip X + SPECIAL_FLIP_Y, // Flip Y + SPECIAL_ROTATE_90, // 90° brush rotation + SPECIAL_ROTATE_180, // 180° brush rotation + SPECIAL_STRETCH, // Stretch brush + SPECIAL_DISTORT, // Distort brush + SPECIAL_OUTLINE, // Outline brush + SPECIAL_NIBBLE, // Nibble brush + SPECIAL_GET_BRUSH_COLORS, // Get colors from brush + SPECIAL_RECOLORIZE_BRUSH, // Recolorize brush + SPECIAL_ROTATE_ANY_ANGLE, // Rotate brush by any angle + 0x100+BUTTON_COLORPICKER, // Pipette + 0x200+BUTTON_COLORPICKER, // Swap fore/back color + 0x100+BUTTON_MAGNIFIER, // Magnifier mode + 0x200+BUTTON_MAGNIFIER, // Zoom factor menu + SPECIAL_ZOOM_IN, // Zoom in + SPECIAL_ZOOM_OUT, // Zoom out + 0x100+BUTTON_BRUSH_EFFECTS, // Brush effects menu + 0x100+BUTTON_TEXT, // Text + 0x100+BUTTON_RESOL, // Resolution menu + 0x200+BUTTON_RESOL, // Safety resolution + 0x100+BUTTON_HELP, // Help & credits + 0x200+BUTTON_HELP, // Statistics + 0x100+BUTTON_PAGE, // Go to spare page + 0x200+BUTTON_PAGE, // Copy to spare page + 0x100+BUTTON_SAVE, // Save as + 0x200+BUTTON_SAVE, // Save + 0x100+BUTTON_LOAD, // Load + 0x200+BUTTON_LOAD, // Re-load + SPECIAL_SAVE_BRUSH, // Save brush + SPECIAL_LOAD_BRUSH, // Load brush + 0x100+BUTTON_SETTINGS, // Settings + 0x100+BUTTON_UNDO, // Undo + 0x200+BUTTON_UNDO, // Redo + 0x100+BUTTON_KILL, // Kill + 0x100+BUTTON_CLEAR, // Clear + 0x200+BUTTON_CLEAR, // Clear with backcolor + 0x100+BUTTON_QUIT, // Quit + 0x100+BUTTON_PALETTE, // Palette menu + 0x200+BUTTON_PALETTE, // Palette menu secondaire + SPECIAL_EXCLUDE_COLORS_MENU, // Exclude colors menu + 0x100+BUTTON_PAL_LEFT, // Scroll palette left + 0x100+BUTTON_PAL_RIGHT, // Scroll palette right + 0x200+BUTTON_PAL_LEFT, // Scroll palette left faster + 0x200+BUTTON_PAL_RIGHT, // Scroll palette right faster + SPECIAL_CENTER_ATTACHMENT, // Center brush attachement + SPECIAL_TOP_LEFT_ATTACHMENT, // Top-left brush attachement + SPECIAL_TOP_RIGHT_ATTACHMENT, // Top-right brush attachement + SPECIAL_BOTTOM_LEFT_ATTACHMENT, // Bottom-left brush attachement + SPECIAL_BOTTOM_RIGHT_ATTACHMENT, // Bottom right brush attachement + SPECIAL_NEXT_FORECOLOR, // Next foreground color + SPECIAL_PREVIOUS_FORECOLOR, // Previous foreground color + SPECIAL_NEXT_BACKCOLOR, // Next background color + SPECIAL_PREVIOUS_BACKCOLOR, // Previous background color + SPECIAL_NEXT_USER_FORECOLOR, // Next user-defined foreground color + SPECIAL_PREVIOUS_USER_FORECOLOR, // Previous user-defined foreground color + SPECIAL_NEXT_USER_BACKCOLOR, // Next user-defined background color + SPECIAL_PREVIOUS_USER_BACKCOLOR, // Previous user-defined background color + SPECIAL_SMALLER_PAINTBRUSH, // Sets paintbrush size: smaller + SPECIAL_BIGGER_PAINTBRUSH, // Sets paintbrush size: bigger + SPECIAL_EFFECTS_OFF, // Turns off all effects + SPECIAL_TRANSPARENCY_1, // Sets transparency level 10% + SPECIAL_TRANSPARENCY_2, // Sets transparency level 20% + SPECIAL_TRANSPARENCY_3, // Sets transparency level 30% + SPECIAL_TRANSPARENCY_4, // Sets transparency level 40% + SPECIAL_TRANSPARENCY_5, // Sets transparency level 50% + SPECIAL_TRANSPARENCY_6, // Sets transparency level 60% + SPECIAL_TRANSPARENCY_7, // Sets transparency level 70% + SPECIAL_TRANSPARENCY_8, // Sets transparency level 80% + SPECIAL_TRANSPARENCY_9, // Sets transparency level 90% + SPECIAL_TRANSPARENCY_0, // Sets transparency level 00% +}; diff --git a/init.h b/init.h index 86053986..6031eef6 100644 --- a/init.h +++ b/init.h @@ -1,42 +1,42 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file init.h -/// Initialization (and some de-initialization) functions. -////////////////////////////////////////////////////////////////////////////// - -T_Gui_skin *Load_graphics(const char * skin_file); -void Init_buttons(void); -void Init_operations(void); -int Load_CFG(int reload_all); -int Save_CFG(void); -void Set_all_video_modes(void); -void Set_config_defaults(void); -void Init_sighandler(void); - -extern char Gui_loading_error_message[512]; - -/// -/// Loads a 8x8 monochrome font, the kind used in all menus and screens. -/// This function allocates the memory, and returns a pointer to it when -/// successful. -/// If an error is encountered, it frees what needs it, prints an error message -/// in ::Gui_loading_error_message, and returns NULL. -byte * Load_font(const char * font_name); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file init.h +/// Initialization (and some de-initialization) functions. +////////////////////////////////////////////////////////////////////////////// + +T_Gui_skin *Load_graphics(const char * skin_file); +void Init_buttons(void); +void Init_operations(void); +int Load_CFG(int reload_all); +int Save_CFG(void); +void Set_all_video_modes(void); +void Set_config_defaults(void); +void Init_sighandler(void); + +extern char Gui_loading_error_message[512]; + +/// +/// Loads a 8x8 monochrome font, the kind used in all menus and screens. +/// This function allocates the memory, and returns a pointer to it when +/// successful. +/// If an error is encountered, it frees what needs it, prints an error message +/// in ::Gui_loading_error_message, and returns NULL. +byte * Load_font(const char * font_name); diff --git a/keyboard.c b/keyboard.c index a9de06a3..5582d931 100644 --- a/keyboard.c +++ b/keyboard.c @@ -1,650 +1,650 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2009 Franck Charlet - Copyright 2008 Yves Rizoud - 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 -*/ -#include -#include -#include "global.h" -#include "keyboard.h" - -// Table de correspondance des scancode de clavier IBM PC AT vers -// les symboles de touches SDL (sym). -// La correspondance est bonne si le clavier est QWERTY US, ou si -// l'utilisateur est sous Windows. -// Dans l'ordre des colonnes: Normal, +Shift, +Control, +Alt -const word Scancode_to_sym[256][4] = -{ -/* 00 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 01 Esc */ { SDLK_ESCAPE ,SDLK_ESCAPE ,SDLK_ESCAPE ,SDLK_ESCAPE }, -/* 02 1 ! */ { SDLK_1 ,SDLK_1 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 03 2 @ */ { SDLK_2 ,SDLK_2 ,SDLK_2 ,SDLK_UNKNOWN }, -/* 04 3 # */ { SDLK_3 ,SDLK_3 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 05 4 $ */ { SDLK_4 ,SDLK_4 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 06 5 % */ { SDLK_5 ,SDLK_5 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 07 6 ^ */ { SDLK_6 ,SDLK_6 ,SDLK_6 ,SDLK_UNKNOWN }, -/* 08 7 & */ { SDLK_7 ,SDLK_7 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 09 8 * */ { SDLK_8 ,SDLK_8 ,SDLK_8 ,SDLK_UNKNOWN }, -/* 0A 9 ( */ { SDLK_9 ,SDLK_9 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 0B 0 ) */ { SDLK_0 ,SDLK_0 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 0C - _ */ { SDLK_MINUS ,SDLK_MINUS ,SDLK_MINUS ,SDLK_UNKNOWN }, -/* 0D = + */ { SDLK_EQUALS ,SDLK_EQUALS ,SDLK_EQUALS ,SDLK_UNKNOWN }, -/* 0E BkSpc */ { SDLK_BACKSPACE ,SDLK_BACKSPACE ,SDLK_BACKSPACE ,SDLK_BACKSPACE }, -/* 0F Tab */ { SDLK_TAB ,SDLK_TAB ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 10 Q */ { SDLK_q ,SDLK_q ,SDLK_q ,SDLK_q }, -/* 11 W */ { SDLK_w ,SDLK_w ,SDLK_w ,SDLK_w }, -/* 12 E */ { SDLK_e ,SDLK_e ,SDLK_e ,SDLK_e }, -/* 13 R */ { SDLK_r ,SDLK_r ,SDLK_r ,SDLK_r }, -/* 14 T */ { SDLK_t ,SDLK_t ,SDLK_t ,SDLK_t }, -/* 15 Y */ { SDLK_y ,SDLK_y ,SDLK_y ,SDLK_y }, -/* 16 U */ { SDLK_u ,SDLK_u ,SDLK_u ,SDLK_u }, -/* 17 I */ { SDLK_i ,SDLK_i ,SDLK_i ,SDLK_i }, -/* 18 O */ { SDLK_o ,SDLK_o ,SDLK_o ,SDLK_o }, -/* 19 P */ { SDLK_p ,SDLK_p ,SDLK_p ,SDLK_p }, -/* 1A [ */ { SDLK_LEFTBRACKET ,SDLK_LEFTBRACKET ,SDLK_LEFTBRACKET ,SDLK_LEFTBRACKET }, -/* 1B ] */ { SDLK_RIGHTBRACKET,SDLK_RIGHTBRACKET,SDLK_RIGHTBRACKET,SDLK_RIGHTBRACKET}, -/* 1C Retrn */ { SDLK_RETURN ,SDLK_RETURN ,SDLK_RETURN ,SDLK_RETURN }, -/* 1D ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 1E A */ { SDLK_a ,SDLK_a ,SDLK_a ,SDLK_a }, -/* 1F S */ { SDLK_s ,SDLK_s ,SDLK_s ,SDLK_s }, -/* 20 D */ { SDLK_d ,SDLK_d ,SDLK_d ,SDLK_d }, -/* 21 F */ { SDLK_f ,SDLK_f ,SDLK_f ,SDLK_f }, -/* 22 G */ { SDLK_g ,SDLK_g ,SDLK_g ,SDLK_g }, -/* 23 H */ { SDLK_h ,SDLK_h ,SDLK_h ,SDLK_h }, -/* 24 J */ { SDLK_j ,SDLK_j ,SDLK_j ,SDLK_j }, -/* 25 K */ { SDLK_k ,SDLK_k ,SDLK_k ,SDLK_k }, -/* 26 L */ { SDLK_l ,SDLK_l ,SDLK_l ,SDLK_l }, -/* 27 ; : */ { SDLK_SEMICOLON ,SDLK_SEMICOLON ,SDLK_SEMICOLON ,SDLK_SEMICOLON }, -/* 28 ' */ { SDLK_QUOTE ,SDLK_QUOTE ,SDLK_UNKNOWN ,SDLK_QUOTE }, -/* 29 ` ~ */ { SDLK_BACKQUOTE ,SDLK_BACKQUOTE ,SDLK_UNKNOWN ,SDLK_BACKQUOTE }, -/* 2A ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 2B \\ */ { SDLK_BACKSLASH ,SDLK_BACKSLASH ,SDLK_BACKSLASH ,SDLK_BACKSLASH }, -/* 2C Z */ { SDLK_z ,SDLK_z ,SDLK_z ,SDLK_z }, -/* 2D X */ { SDLK_x ,SDLK_x ,SDLK_x ,SDLK_x }, -/* 2E C */ { SDLK_c ,SDLK_c ,SDLK_c ,SDLK_c }, -/* 2F V */ { SDLK_v ,SDLK_v ,SDLK_v ,SDLK_v }, -/* 30 B */ { SDLK_b ,SDLK_b ,SDLK_b ,SDLK_b }, -/* 31 N */ { SDLK_n ,SDLK_n ,SDLK_n ,SDLK_n }, -/* 32 M */ { SDLK_m ,SDLK_m ,SDLK_m ,SDLK_m }, -/* 33 , < */ { SDLK_COMMA ,SDLK_COMMA ,SDLK_UNKNOWN ,SDLK_COMMA }, -/* 34 . > */ { SDLK_PERIOD ,SDLK_PERIOD ,SDLK_UNKNOWN ,SDLK_PERIOD }, -/* 35 / ? */ { SDLK_SLASH ,SDLK_SLASH ,SDLK_UNKNOWN ,SDLK_SLASH }, -/* 36 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 37 Grey* */ { SDLK_KP_MULTIPLY ,SDLK_KP_MULTIPLY ,SDLK_UNKNOWN ,SDLK_KP_MULTIPLY }, -/* 38 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 39 Space */ { SDLK_SPACE ,SDLK_SPACE ,SDLK_SPACE ,SDLK_SPACE }, -/* 3A ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 3B F1 */ { SDLK_F1 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 3C F2 */ { SDLK_F2 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 3D F3 */ { SDLK_F3 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 3E F4 */ { SDLK_F4 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 3F F5 */ { SDLK_F5 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 40 F6 */ { SDLK_F6 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 41 F7 */ { SDLK_F7 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 42 F8 */ { SDLK_F8 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 43 F9 */ { SDLK_F9 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 44 F10 */ { SDLK_F10 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 45 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 46 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 47 Home */ { SDLK_HOME ,SDLK_HOME ,SDLK_UNKNOWN ,SDLK_HOME }, -/* 48 Up */ { SDLK_UP ,SDLK_UP ,SDLK_UNKNOWN ,SDLK_UP }, -/* 49 PgUp */ { SDLK_PAGEUP ,SDLK_PAGEUP ,SDLK_UNKNOWN ,SDLK_PAGEUP }, -/* 4A Grey- */ { SDLK_KP_MINUS ,SDLK_KP_MINUS ,SDLK_UNKNOWN ,SDLK_KP_MINUS }, -/* 4B Left */ { SDLK_LEFT ,SDLK_LEFT ,SDLK_UNKNOWN ,SDLK_LEFT }, -/* 4C Kpad5 */ { SDLK_KP5 ,SDLK_KP5 ,SDLK_UNKNOWN ,SDLK_KP5 }, -/* 4D Right */ { SDLK_RIGHT ,SDLK_RIGHT ,SDLK_UNKNOWN ,SDLK_RIGHT }, -/* 4E Grey+ */ { SDLK_KP_PLUS ,SDLK_KP_PLUS ,SDLK_UNKNOWN ,SDLK_KP_PLUS }, -/* 4F End */ { SDLK_END ,SDLK_END ,SDLK_UNKNOWN ,SDLK_END }, -/* 50 Down */ { SDLK_DOWN ,SDLK_DOWN ,SDLK_UNKNOWN ,SDLK_DOWN }, -/* 51 PgDn */ { SDLK_PAGEDOWN ,SDLK_PAGEDOWN ,SDLK_UNKNOWN ,SDLK_PAGEDOWN }, -/* 52 Ins */ { SDLK_INSERT ,SDLK_INSERT ,SDLK_UNKNOWN ,SDLK_INSERT }, -/* 53 Del */ { SDLK_DELETE ,SDLK_DELETE ,SDLK_UNKNOWN ,SDLK_DELETE }, -/* 54 ??? */ { SDLK_UNKNOWN ,SDLK_F1 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 55 ??? */ { SDLK_UNKNOWN ,SDLK_F2 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 56 Lft| */ { SDLK_UNKNOWN ,SDLK_F3 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 57 ??? */ { SDLK_UNKNOWN ,SDLK_F4 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 58 ??? */ { SDLK_UNKNOWN ,SDLK_F5 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 59 ??? */ { SDLK_UNKNOWN ,SDLK_F6 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 5A ??? */ { SDLK_UNKNOWN ,SDLK_F7 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 5B ??? */ { SDLK_UNKNOWN ,SDLK_F8 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 5C ??? */ { SDLK_UNKNOWN ,SDLK_F9 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 5D ??? */ { SDLK_UNKNOWN ,SDLK_F10 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 5E ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F1 ,SDLK_UNKNOWN }, -/* 5F ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F2 ,SDLK_UNKNOWN }, -/* 60 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F3 ,SDLK_UNKNOWN }, -/* 61 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F4 ,SDLK_UNKNOWN }, -/* 62 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F5 ,SDLK_UNKNOWN }, -/* 63 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F6 ,SDLK_UNKNOWN }, -/* 64 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F7 ,SDLK_UNKNOWN }, -/* 65 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F8 ,SDLK_UNKNOWN }, -/* 66 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F9 ,SDLK_UNKNOWN }, -/* 67 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F10 ,SDLK_UNKNOWN }, -/* 68 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F1 }, -/* 69 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F2 }, -/* 6A ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F3 }, -/* 6B ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F4 }, -/* 6C ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F5 }, -/* 6D ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F6 }, -/* 6E ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F7 }, -/* 6F ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F8 }, -/* 70 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F9 }, -/* 71 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F10 }, -/* 72 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 73 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_LEFT ,SDLK_UNKNOWN }, -/* 74 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_RIGHT ,SDLK_UNKNOWN }, -/* 75 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_END ,SDLK_UNKNOWN }, -/* 76 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_PAGEDOWN ,SDLK_UNKNOWN }, -/* 77 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_HOME ,SDLK_UNKNOWN }, -/* 78 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_1 }, -/* 79 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_2 }, -/* 7A ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_3 }, -/* 7B ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_4 }, -/* 7C ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_5 }, -/* 7D ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_6 }, -/* 7E ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_7 }, -/* 7F ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_8 }, -/* 80 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_9 }, -/* 81 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_0 }, -/* 82 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_MINUS }, -/* 83 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_EQUALS }, -/* 84 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_PAGEUP ,SDLK_UNKNOWN }, -/* 85 F11 */ { SDLK_F11 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 86 F12 */ { SDLK_F12 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 87 ??? */ { SDLK_UNKNOWN ,SDLK_F11 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 88 ??? */ { SDLK_UNKNOWN ,SDLK_F12 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 89 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F11 ,SDLK_UNKNOWN }, -/* 8A ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F12 ,SDLK_UNKNOWN }, -/* 8B ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F11 }, -/* 8C ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F12 }, -/* 8D ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UP ,SDLK_UNKNOWN }, -/* 8E ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_KP_MINUS ,SDLK_UNKNOWN }, -/* 8F ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_KP5 ,SDLK_UNKNOWN }, -/* 90 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_KP_PLUS ,SDLK_UNKNOWN }, -/* 91 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_DOWN ,SDLK_UNKNOWN }, -/* 92 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_INSERT ,SDLK_UNKNOWN }, -/* 93 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_DELETE ,SDLK_UNKNOWN }, -/* 94 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_TAB ,SDLK_UNKNOWN }, -/* 95 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_KP_DIVIDE ,SDLK_UNKNOWN }, -/* 96 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_KP_MULTIPLY ,SDLK_UNKNOWN }, -/* 97 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_HOME }, -/* 98 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UP }, -/* 99 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_PAGEUP }, -/* 9A ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 9B ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_LEFT }, -/* 9C ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 9D ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_RIGHT }, -/* 9E ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* 9F ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_END }, -/* A0 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_DOWN }, -/* A1 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_PAGEUP }, -/* A2 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_INSERT }, -/* A3 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_DELETE }, -/* A4 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_KP_DIVIDE }, -/* A5 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_TAB }, -/* A6 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_KP_ENTER }, -/* A7 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* A8 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* A9 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* AA ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* AB ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* AC ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* AD ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* AE ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* AF ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* B0 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* B1 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* B2 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* B3 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* B4 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* B5 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* B6 Win L */ { SDLK_LSUPER ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* B7 Win R */ { SDLK_RSUPER ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* B8 Win M */ { SDLK_MENU ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* B9 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* BA ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* BB ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* BC ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* BD ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* BE ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* BF ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* C0 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* C1 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* C2 ??? */ { SDLK_UNKNOWN ,SDLK_LSUPER ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* C3 ??? */ { SDLK_UNKNOWN ,SDLK_RSUPER ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* C4 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* C5 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* C6 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* C7 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* C8 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* C9 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* CA ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* CB ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* CC ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* CD ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* CE ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_LSUPER ,SDLK_UNKNOWN }, -/* CF ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_RSUPER ,SDLK_UNKNOWN }, -/* D0 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_MENU ,SDLK_UNKNOWN }, -/* D1 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* D2 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* D3 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* D4 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* D5 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* D6 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* D7 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* D8 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* D9 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* DA ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_LSUPER }, -/* DB ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_RSUPER }, -/* DC ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_MENU }, -/* DD ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* DE ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* DF ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* E0 Enter */ { SDLK_KP_ENTER ,SDLK_KP_ENTER ,SDLK_KP_ENTER ,SDLK_UNKNOWN }, -/* E1 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* E2 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* E3 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* E4 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* E5 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* E6 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* E7 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* E8 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* E9 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* EA ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* EB ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* EC ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* ED ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* EE ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* EF ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* F0 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* F1 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* F2 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* F3 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* F4 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* F5 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* F6 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* F7 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* F8 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* F9 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* FA ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* FB ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* FC ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* FD ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* FE ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -/* FF ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, -}; - -// Conversion de l'ancien codage des touches: -// 0x00FF le scancode (maintenant code sym sur 0x0FFF) -// 0x0100 shift (maintenant 0x1000) -// 0x0200 control (maintenant 0x2000) -// 0x0400 alt (maintenant 0x4000) -word Key_for_scancode(word scancode) -{ - if (scancode & 0x0400) - return Scancode_to_sym[scancode & 0xFF][3] | - (scancode & 0x0700) << 4; - else if (scancode & 0x0200) - return Scancode_to_sym[scancode & 0xFF][2] | - (scancode & 0x0700) << 4; - else if (scancode & 0x0100) - return Scancode_to_sym[scancode & 0xFF][1] | - (scancode & 0x0700) << 4; - else - return Scancode_to_sym[scancode & 0xFF][0]; -} - -// Convertit des modificateurs de touches SDL en modificateurs GrafX2 -word Key_modifiers(SDLMod mod) -{ - word modifiers=0; - - if (mod & KMOD_CTRL ) - modifiers|=MOD_CTRL; - if (mod & KMOD_SHIFT ) - modifiers|=MOD_SHIFT; - if (mod & (KMOD_ALT|KMOD_MODE)) - modifiers|=MOD_ALT; - if (mod & (KMOD_META)) - modifiers|=MOD_META; - - return modifiers; -} - -word Keysym_to_keycode(SDL_keysym keysym) -{ - word key_code = 0; - word mod; - - // On ignore shift, alt et control isolés. - if (keysym.sym == SDLK_RSHIFT || keysym.sym == SDLK_LSHIFT || - keysym.sym == SDLK_RCTRL || keysym.sym == SDLK_LCTRL || - keysym.sym == SDLK_RALT || keysym.sym == SDLK_LALT || - keysym.sym == SDLK_RMETA || keysym.sym == SDLK_LMETA || - keysym.sym == SDLK_MODE) // AltGr - return 0; - - // Les touches qui n'ont qu'une valeur unicode (très rares) - // seront codées sur 11 bits, le 12e bit est mis à 1 (0x0800) - if (keysym.sym != 0) - key_code = keysym.sym; - else if (keysym.scancode != 0) - { - key_code = (keysym.scancode & 0x07FF) | 0x0800; - } - - // Normally I should test keysym.mod here, but on windows the implementation - // is buggy: if you release a modifier key, the following keys (when they repeat) - // still name the original modifiers. - mod=Key_modifiers(SDL_GetModState()); - - // SDL_GetModState() seems to get the right up-to-date info. - key_code |= mod; - return key_code; -} - -const char * Key_name(word Key) -{ - typedef struct - { - word keysym; - char *Key_name; - } T_key_label; - T_key_label key_labels[] = - { - { SDLK_BACKSPACE , "Backspace" }, - { SDLK_TAB , "Tab" }, - { SDLK_CLEAR , "Clear" }, - { SDLK_RETURN , "Return" }, - { SDLK_PAUSE , "Pause" }, - { SDLK_ESCAPE , "Esc" }, - { SDLK_DELETE , "Del" }, - { SDLK_KP0 , "KP 0" }, - { SDLK_KP1 , "KP 1" }, - { SDLK_KP2 , "KP 2" }, - { SDLK_KP3 , "KP 3" }, - { SDLK_KP4 , "KP 4" }, - { SDLK_KP5 , "KP 5" }, - { SDLK_KP6 , "KP 6" }, - { SDLK_KP7 , "KP 7" }, - { SDLK_KP8 , "KP 8" }, - { SDLK_KP9 , "KP 9" }, - { SDLK_KP_PERIOD , "KP ." }, - { SDLK_KP_DIVIDE , "KP /" }, - { SDLK_KP_MULTIPLY, "KP *" }, - { SDLK_KP_MINUS , "KP -" }, - { SDLK_KP_PLUS , "KP +" }, - { SDLK_KP_ENTER , "KP Enter" }, - { SDLK_KP_EQUALS , "KP =" }, - { SDLK_UP , "Up" }, - { SDLK_DOWN , "Down" }, - { SDLK_RIGHT , "Right" }, - { SDLK_LEFT , "Left" }, - { SDLK_INSERT , "Ins" }, - { SDLK_HOME , "Home" }, - { SDLK_END , "End" }, - { SDLK_PAGEUP , "PgUp" }, - { SDLK_PAGEDOWN , "PgDn" }, - { SDLK_F1 , "F1" }, - { SDLK_F2 , "F2" }, - { SDLK_F3 , "F3" }, - { SDLK_F4 , "F4" }, - { SDLK_F5 , "F5" }, - { SDLK_F6 , "F6" }, - { SDLK_F7 , "F7" }, - { SDLK_F8 , "F8" }, - { SDLK_F9 , "F9" }, - { SDLK_F10 , "F10" }, - { SDLK_F11 , "F11" }, - { SDLK_F12 , "F12" }, - { SDLK_F13 , "F13" }, - { SDLK_F14 , "F14" }, - { SDLK_F15 , "F15" }, - { SDLK_NUMLOCK , "NumLock" }, - { SDLK_CAPSLOCK , "CapsLck" }, - { SDLK_SCROLLOCK , "ScrlLock" }, - { SDLK_RSHIFT , "RShift" }, - { SDLK_LSHIFT , "LShift" }, - { SDLK_RCTRL , "RCtrl" }, - { SDLK_LCTRL , "LCtrl" }, - { SDLK_RALT , "RAlt" }, - { SDLK_LALT , "LAlt" }, - { SDLK_RMETA , "RMeta" }, - { SDLK_LMETA , "LMeta" }, - { SDLK_LSUPER , "LWin" }, - { SDLK_RSUPER , "RWin" }, - { SDLK_MODE , "AltGr" }, - { SDLK_COMPOSE , "Comp" }, - { SDLK_HELP , "Help" }, - { SDLK_PRINT , "Print" }, - { SDLK_SYSREQ , "SysReq" }, - { SDLK_BREAK , "Break" }, - { SDLK_MENU , "Menu" }, - { SDLK_POWER , "Power" }, - { SDLK_EURO , "Euro" }, - { SDLK_UNDO , "Undo" }, - { KEY_MOUSEMIDDLE, "Mouse3" }, - { KEY_MOUSEWHEELUP, "WheelUp" }, - { KEY_MOUSEWHEELDOWN, "WheelDown" } - }; - - int index; - static char buffer[41]; - buffer[0] = '\0'; - - if (Key == SDLK_UNKNOWN) - return "None"; - - if (Key & MOD_CTRL) - strcat(buffer, "Ctrl+"); - if (Key & MOD_ALT) - strcat(buffer, "Alt+"); - if (Key & MOD_SHIFT) - strcat(buffer, "Shift+"); - if (Key & MOD_META) - strcat(buffer, "\201"); - // Note: Apple's "command" character is not present in the ANSI table, so we - // recycled an ANSI value that doesn't have any displayable character - // associated. - - - Key=Key & ~(MOD_CTRL|MOD_ALT|MOD_SHIFT); - - if (Key>=KEY_JOYBUTTON && Key<=KEY_JOYBUTTON+18) - { -#ifdef __GP2X__ - - char *button_name; - switch(Key-KEY_JOYBUTTON) - { - case GP2X_BUTTON_UP: button_name="[UP]"; break; - case GP2X_BUTTON_DOWN: button_name="[DOWN]"; break; - case GP2X_BUTTON_LEFT: button_name="[LEFT]"; break; - case GP2X_BUTTON_RIGHT: button_name="[RIGHT]"; break; - case GP2X_BUTTON_UPLEFT: button_name="[UP-LEFT]"; break; - case GP2X_BUTTON_UPRIGHT: button_name="[UP-RIGHT]"; break; - case GP2X_BUTTON_DOWNLEFT: button_name="[DOWN-LEFT]"; break; - case GP2X_BUTTON_DOWNRIGHT: button_name="[DOWN-RIGHT]"; break; - case GP2X_BUTTON_CLICK: button_name="[CLICK]"; break; - case GP2X_BUTTON_A: button_name="[A]"; break; - case GP2X_BUTTON_B: button_name="[B]"; break; - case GP2X_BUTTON_X: button_name="[X]"; break; - case GP2X_BUTTON_Y: button_name="[Y]"; break; - case GP2X_BUTTON_L: button_name="[L]"; break; - case GP2X_BUTTON_R: button_name="[R]"; break; - case GP2X_BUTTON_START: button_name="[START]"; break; - case GP2X_BUTTON_SELECT: button_name="[SELECT]"; break; - case GP2X_BUTTON_VOLUP: button_name="[VOL UP]"; break; - case GP2X_BUTTON_VOLDOWN: button_name="[VOL DOWN]"; break; - default: sprintf(buffer+strlen(buffer), "[B%d]", Key);return buffer; - } - strcat(buffer,button_name); -#else - sprintf(buffer+strlen(buffer), "[B%d]", Key-KEY_JOYBUTTON); -#endif - return buffer; - } - - if (Key & 0x800) - { - sprintf(buffer+strlen(buffer), "[%d]", Key & 0x7FF); - return buffer; - } - Key = Key & 0x7FF; - // Touches ASCII - if (Key>=' ' && Key < 127) - { - sprintf(buffer+strlen(buffer), "'%c'", toupper(Key)); - return buffer; - } - // Touches 'World' - if (Key>=SDLK_WORLD_0 && Key <= SDLK_WORLD_95) - { - sprintf(buffer+strlen(buffer), "w%d", Key - SDLK_WORLD_0); - return buffer; - } - - // Touches au libellé connu - for (index=0; index < (long)sizeof(key_labels)/(long)sizeof(T_key_label);index++) - { - if (Key == key_labels[index].keysym) - { - sprintf(buffer+strlen(buffer), "%s", key_labels[index].Key_name); - return buffer; - } - } - // Autres touches inconnues - sprintf(buffer+strlen(buffer), "0x%X", Key & 0x7FF); - return buffer; - -} - -// Obtient le caractère ANSI tapé, à partir d'un keysym. -// (Valeur 32 à 255) -// Renvoie 0 s'il n'y a pas de caractère associé (shift, backspace, etc) -word Keysym_to_ANSI(SDL_keysym keysym) -{ - // This part was removed from the MacOSX port, but I put it back for others - // as on Linux and Windows, it's what allows editing a text line with the keys - // SDLK_LEFT, SDLK_RIGHT, SDLK_HOME, SDLK_END etc. - #if !(defined(__macosx__) || defined(__FreeBSD__)) - if ( keysym.unicode == 0) - { - switch(keysym.sym) - { - case SDLK_DELETE: - case SDLK_LEFT: - case SDLK_RIGHT: - case SDLK_HOME: - case SDLK_END: - case SDLK_BACKSPACE: - case KEY_ESC: - case SDLK_RETURN: - return keysym.sym; - default: - return 0; - } - } - #endif - // - if ( keysym.unicode > 32 && keysym.unicode < 127) - { - return keysym.unicode; // Pas de souci, on est en ASCII standard - } - - // Quelques conversions Unicode-ANSI - switch(keysym.unicode) - { - case 0x8100: - return 'ü'; // ü - case 0x1A20: - return 'é'; // é - case 0x201A: - return 'è'; // è - case 0x9201: - return 'â'; // â - case 0x1E20: - return 'ä'; // ä - case 0x2620: - return 'à'; // à - case 0x2020: - return 'å'; // å - case 0x2120: - return 'ç'; // ç - case 0xC602: - return 'ê'; // ê - case 0x3020: - return 'ë'; // ë - case 0x6001: - return 'è'; // è - case 0x3920: - return 'ï'; // ï - case 0x5201: - return 'î'; // î - case 0x8D00: - return 'ì'; // ì - case 0x1C20: - return 'ô'; // ô - case 0x1D20: - return 'ö'; // ö - case 0x2220: - return 'ò'; // ò - case 0x1320: - return 'û'; // û - case 0x1420: - return 'ù'; // ù - case 0xDC02: - return 'ÿ'; // ÿ - case 0x5301: - return '£'; // £ - case 0xA000: - return 'á'; // á - case 0xA100: - return 'í'; // í - case 0xA200: - return 'ó'; // ó - case 0xA300: - return 'ú'; // ú - case 0xA400: - return 'ñ'; // ñ - case 0xA700: - return 'º'; // º - case 0xC600: - return 'ã'; // ã - } - - // Key entre 127 et 255 - if (keysym.unicode<256) - { -#if defined(__macosx__) || defined(__FreeBSD__) - // fc: Looks like there's a mismatch with delete & backspace - // i don't why SDLK_DELETE was returned instead of SDLK_BACKSPACE - if(keysym.unicode == 127) - { - return(SDLK_BACKSPACE); - } - // We don't make any difference between return & enter in the app context. - if(keysym.unicode == 3) - { - return(SDLK_RETURN); - } -#endif - return keysym.unicode; - } - - // Sinon c'est une touche spéciale, on retourne son scancode - return keysym.sym; -} +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2009 Franck Charlet + Copyright 2008 Yves Rizoud + 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 +*/ +#include +#include +#include "global.h" +#include "keyboard.h" + +// Table de correspondance des scancode de clavier IBM PC AT vers +// les symboles de touches SDL (sym). +// La correspondance est bonne si le clavier est QWERTY US, ou si +// l'utilisateur est sous Windows. +// Dans l'ordre des colonnes: Normal, +Shift, +Control, +Alt +const word Scancode_to_sym[256][4] = +{ +/* 00 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 01 Esc */ { SDLK_ESCAPE ,SDLK_ESCAPE ,SDLK_ESCAPE ,SDLK_ESCAPE }, +/* 02 1 ! */ { SDLK_1 ,SDLK_1 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 03 2 @ */ { SDLK_2 ,SDLK_2 ,SDLK_2 ,SDLK_UNKNOWN }, +/* 04 3 # */ { SDLK_3 ,SDLK_3 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 05 4 $ */ { SDLK_4 ,SDLK_4 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 06 5 % */ { SDLK_5 ,SDLK_5 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 07 6 ^ */ { SDLK_6 ,SDLK_6 ,SDLK_6 ,SDLK_UNKNOWN }, +/* 08 7 & */ { SDLK_7 ,SDLK_7 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 09 8 * */ { SDLK_8 ,SDLK_8 ,SDLK_8 ,SDLK_UNKNOWN }, +/* 0A 9 ( */ { SDLK_9 ,SDLK_9 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 0B 0 ) */ { SDLK_0 ,SDLK_0 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 0C - _ */ { SDLK_MINUS ,SDLK_MINUS ,SDLK_MINUS ,SDLK_UNKNOWN }, +/* 0D = + */ { SDLK_EQUALS ,SDLK_EQUALS ,SDLK_EQUALS ,SDLK_UNKNOWN }, +/* 0E BkSpc */ { SDLK_BACKSPACE ,SDLK_BACKSPACE ,SDLK_BACKSPACE ,SDLK_BACKSPACE }, +/* 0F Tab */ { SDLK_TAB ,SDLK_TAB ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 10 Q */ { SDLK_q ,SDLK_q ,SDLK_q ,SDLK_q }, +/* 11 W */ { SDLK_w ,SDLK_w ,SDLK_w ,SDLK_w }, +/* 12 E */ { SDLK_e ,SDLK_e ,SDLK_e ,SDLK_e }, +/* 13 R */ { SDLK_r ,SDLK_r ,SDLK_r ,SDLK_r }, +/* 14 T */ { SDLK_t ,SDLK_t ,SDLK_t ,SDLK_t }, +/* 15 Y */ { SDLK_y ,SDLK_y ,SDLK_y ,SDLK_y }, +/* 16 U */ { SDLK_u ,SDLK_u ,SDLK_u ,SDLK_u }, +/* 17 I */ { SDLK_i ,SDLK_i ,SDLK_i ,SDLK_i }, +/* 18 O */ { SDLK_o ,SDLK_o ,SDLK_o ,SDLK_o }, +/* 19 P */ { SDLK_p ,SDLK_p ,SDLK_p ,SDLK_p }, +/* 1A [ */ { SDLK_LEFTBRACKET ,SDLK_LEFTBRACKET ,SDLK_LEFTBRACKET ,SDLK_LEFTBRACKET }, +/* 1B ] */ { SDLK_RIGHTBRACKET,SDLK_RIGHTBRACKET,SDLK_RIGHTBRACKET,SDLK_RIGHTBRACKET}, +/* 1C Retrn */ { SDLK_RETURN ,SDLK_RETURN ,SDLK_RETURN ,SDLK_RETURN }, +/* 1D ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 1E A */ { SDLK_a ,SDLK_a ,SDLK_a ,SDLK_a }, +/* 1F S */ { SDLK_s ,SDLK_s ,SDLK_s ,SDLK_s }, +/* 20 D */ { SDLK_d ,SDLK_d ,SDLK_d ,SDLK_d }, +/* 21 F */ { SDLK_f ,SDLK_f ,SDLK_f ,SDLK_f }, +/* 22 G */ { SDLK_g ,SDLK_g ,SDLK_g ,SDLK_g }, +/* 23 H */ { SDLK_h ,SDLK_h ,SDLK_h ,SDLK_h }, +/* 24 J */ { SDLK_j ,SDLK_j ,SDLK_j ,SDLK_j }, +/* 25 K */ { SDLK_k ,SDLK_k ,SDLK_k ,SDLK_k }, +/* 26 L */ { SDLK_l ,SDLK_l ,SDLK_l ,SDLK_l }, +/* 27 ; : */ { SDLK_SEMICOLON ,SDLK_SEMICOLON ,SDLK_SEMICOLON ,SDLK_SEMICOLON }, +/* 28 ' */ { SDLK_QUOTE ,SDLK_QUOTE ,SDLK_UNKNOWN ,SDLK_QUOTE }, +/* 29 ` ~ */ { SDLK_BACKQUOTE ,SDLK_BACKQUOTE ,SDLK_UNKNOWN ,SDLK_BACKQUOTE }, +/* 2A ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 2B \\ */ { SDLK_BACKSLASH ,SDLK_BACKSLASH ,SDLK_BACKSLASH ,SDLK_BACKSLASH }, +/* 2C Z */ { SDLK_z ,SDLK_z ,SDLK_z ,SDLK_z }, +/* 2D X */ { SDLK_x ,SDLK_x ,SDLK_x ,SDLK_x }, +/* 2E C */ { SDLK_c ,SDLK_c ,SDLK_c ,SDLK_c }, +/* 2F V */ { SDLK_v ,SDLK_v ,SDLK_v ,SDLK_v }, +/* 30 B */ { SDLK_b ,SDLK_b ,SDLK_b ,SDLK_b }, +/* 31 N */ { SDLK_n ,SDLK_n ,SDLK_n ,SDLK_n }, +/* 32 M */ { SDLK_m ,SDLK_m ,SDLK_m ,SDLK_m }, +/* 33 , < */ { SDLK_COMMA ,SDLK_COMMA ,SDLK_UNKNOWN ,SDLK_COMMA }, +/* 34 . > */ { SDLK_PERIOD ,SDLK_PERIOD ,SDLK_UNKNOWN ,SDLK_PERIOD }, +/* 35 / ? */ { SDLK_SLASH ,SDLK_SLASH ,SDLK_UNKNOWN ,SDLK_SLASH }, +/* 36 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 37 Grey* */ { SDLK_KP_MULTIPLY ,SDLK_KP_MULTIPLY ,SDLK_UNKNOWN ,SDLK_KP_MULTIPLY }, +/* 38 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 39 Space */ { SDLK_SPACE ,SDLK_SPACE ,SDLK_SPACE ,SDLK_SPACE }, +/* 3A ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 3B F1 */ { SDLK_F1 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 3C F2 */ { SDLK_F2 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 3D F3 */ { SDLK_F3 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 3E F4 */ { SDLK_F4 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 3F F5 */ { SDLK_F5 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 40 F6 */ { SDLK_F6 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 41 F7 */ { SDLK_F7 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 42 F8 */ { SDLK_F8 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 43 F9 */ { SDLK_F9 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 44 F10 */ { SDLK_F10 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 45 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 46 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 47 Home */ { SDLK_HOME ,SDLK_HOME ,SDLK_UNKNOWN ,SDLK_HOME }, +/* 48 Up */ { SDLK_UP ,SDLK_UP ,SDLK_UNKNOWN ,SDLK_UP }, +/* 49 PgUp */ { SDLK_PAGEUP ,SDLK_PAGEUP ,SDLK_UNKNOWN ,SDLK_PAGEUP }, +/* 4A Grey- */ { SDLK_KP_MINUS ,SDLK_KP_MINUS ,SDLK_UNKNOWN ,SDLK_KP_MINUS }, +/* 4B Left */ { SDLK_LEFT ,SDLK_LEFT ,SDLK_UNKNOWN ,SDLK_LEFT }, +/* 4C Kpad5 */ { SDLK_KP5 ,SDLK_KP5 ,SDLK_UNKNOWN ,SDLK_KP5 }, +/* 4D Right */ { SDLK_RIGHT ,SDLK_RIGHT ,SDLK_UNKNOWN ,SDLK_RIGHT }, +/* 4E Grey+ */ { SDLK_KP_PLUS ,SDLK_KP_PLUS ,SDLK_UNKNOWN ,SDLK_KP_PLUS }, +/* 4F End */ { SDLK_END ,SDLK_END ,SDLK_UNKNOWN ,SDLK_END }, +/* 50 Down */ { SDLK_DOWN ,SDLK_DOWN ,SDLK_UNKNOWN ,SDLK_DOWN }, +/* 51 PgDn */ { SDLK_PAGEDOWN ,SDLK_PAGEDOWN ,SDLK_UNKNOWN ,SDLK_PAGEDOWN }, +/* 52 Ins */ { SDLK_INSERT ,SDLK_INSERT ,SDLK_UNKNOWN ,SDLK_INSERT }, +/* 53 Del */ { SDLK_DELETE ,SDLK_DELETE ,SDLK_UNKNOWN ,SDLK_DELETE }, +/* 54 ??? */ { SDLK_UNKNOWN ,SDLK_F1 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 55 ??? */ { SDLK_UNKNOWN ,SDLK_F2 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 56 Lft| */ { SDLK_UNKNOWN ,SDLK_F3 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 57 ??? */ { SDLK_UNKNOWN ,SDLK_F4 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 58 ??? */ { SDLK_UNKNOWN ,SDLK_F5 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 59 ??? */ { SDLK_UNKNOWN ,SDLK_F6 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 5A ??? */ { SDLK_UNKNOWN ,SDLK_F7 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 5B ??? */ { SDLK_UNKNOWN ,SDLK_F8 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 5C ??? */ { SDLK_UNKNOWN ,SDLK_F9 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 5D ??? */ { SDLK_UNKNOWN ,SDLK_F10 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 5E ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F1 ,SDLK_UNKNOWN }, +/* 5F ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F2 ,SDLK_UNKNOWN }, +/* 60 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F3 ,SDLK_UNKNOWN }, +/* 61 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F4 ,SDLK_UNKNOWN }, +/* 62 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F5 ,SDLK_UNKNOWN }, +/* 63 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F6 ,SDLK_UNKNOWN }, +/* 64 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F7 ,SDLK_UNKNOWN }, +/* 65 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F8 ,SDLK_UNKNOWN }, +/* 66 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F9 ,SDLK_UNKNOWN }, +/* 67 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F10 ,SDLK_UNKNOWN }, +/* 68 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F1 }, +/* 69 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F2 }, +/* 6A ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F3 }, +/* 6B ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F4 }, +/* 6C ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F5 }, +/* 6D ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F6 }, +/* 6E ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F7 }, +/* 6F ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F8 }, +/* 70 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F9 }, +/* 71 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F10 }, +/* 72 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 73 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_LEFT ,SDLK_UNKNOWN }, +/* 74 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_RIGHT ,SDLK_UNKNOWN }, +/* 75 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_END ,SDLK_UNKNOWN }, +/* 76 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_PAGEDOWN ,SDLK_UNKNOWN }, +/* 77 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_HOME ,SDLK_UNKNOWN }, +/* 78 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_1 }, +/* 79 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_2 }, +/* 7A ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_3 }, +/* 7B ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_4 }, +/* 7C ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_5 }, +/* 7D ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_6 }, +/* 7E ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_7 }, +/* 7F ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_8 }, +/* 80 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_9 }, +/* 81 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_0 }, +/* 82 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_MINUS }, +/* 83 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_EQUALS }, +/* 84 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_PAGEUP ,SDLK_UNKNOWN }, +/* 85 F11 */ { SDLK_F11 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 86 F12 */ { SDLK_F12 ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 87 ??? */ { SDLK_UNKNOWN ,SDLK_F11 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 88 ??? */ { SDLK_UNKNOWN ,SDLK_F12 ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 89 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F11 ,SDLK_UNKNOWN }, +/* 8A ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F12 ,SDLK_UNKNOWN }, +/* 8B ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F11 }, +/* 8C ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_F12 }, +/* 8D ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UP ,SDLK_UNKNOWN }, +/* 8E ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_KP_MINUS ,SDLK_UNKNOWN }, +/* 8F ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_KP5 ,SDLK_UNKNOWN }, +/* 90 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_KP_PLUS ,SDLK_UNKNOWN }, +/* 91 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_DOWN ,SDLK_UNKNOWN }, +/* 92 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_INSERT ,SDLK_UNKNOWN }, +/* 93 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_DELETE ,SDLK_UNKNOWN }, +/* 94 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_TAB ,SDLK_UNKNOWN }, +/* 95 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_KP_DIVIDE ,SDLK_UNKNOWN }, +/* 96 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_KP_MULTIPLY ,SDLK_UNKNOWN }, +/* 97 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_HOME }, +/* 98 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UP }, +/* 99 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_PAGEUP }, +/* 9A ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 9B ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_LEFT }, +/* 9C ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 9D ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_RIGHT }, +/* 9E ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* 9F ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_END }, +/* A0 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_DOWN }, +/* A1 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_PAGEUP }, +/* A2 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_INSERT }, +/* A3 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_DELETE }, +/* A4 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_KP_DIVIDE }, +/* A5 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_TAB }, +/* A6 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_KP_ENTER }, +/* A7 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* A8 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* A9 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* AA ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* AB ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* AC ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* AD ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* AE ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* AF ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* B0 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* B1 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* B2 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* B3 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* B4 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* B5 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* B6 Win L */ { SDLK_LSUPER ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* B7 Win R */ { SDLK_RSUPER ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* B8 Win M */ { SDLK_MENU ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* B9 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* BA ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* BB ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* BC ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* BD ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* BE ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* BF ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* C0 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* C1 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* C2 ??? */ { SDLK_UNKNOWN ,SDLK_LSUPER ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* C3 ??? */ { SDLK_UNKNOWN ,SDLK_RSUPER ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* C4 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* C5 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* C6 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* C7 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* C8 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* C9 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* CA ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* CB ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* CC ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* CD ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* CE ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_LSUPER ,SDLK_UNKNOWN }, +/* CF ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_RSUPER ,SDLK_UNKNOWN }, +/* D0 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_MENU ,SDLK_UNKNOWN }, +/* D1 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* D2 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* D3 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* D4 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* D5 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* D6 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* D7 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* D8 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* D9 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* DA ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_LSUPER }, +/* DB ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_RSUPER }, +/* DC ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_MENU }, +/* DD ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* DE ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* DF ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* E0 Enter */ { SDLK_KP_ENTER ,SDLK_KP_ENTER ,SDLK_KP_ENTER ,SDLK_UNKNOWN }, +/* E1 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* E2 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* E3 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* E4 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* E5 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* E6 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* E7 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* E8 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* E9 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* EA ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* EB ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* EC ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* ED ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* EE ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* EF ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* F0 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* F1 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* F2 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* F3 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* F4 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* F5 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* F6 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* F7 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* F8 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* F9 ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* FA ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* FB ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* FC ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* FD ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* FE ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +/* FF ??? */ { SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN ,SDLK_UNKNOWN }, +}; + +// Conversion de l'ancien codage des touches: +// 0x00FF le scancode (maintenant code sym sur 0x0FFF) +// 0x0100 shift (maintenant 0x1000) +// 0x0200 control (maintenant 0x2000) +// 0x0400 alt (maintenant 0x4000) +word Key_for_scancode(word scancode) +{ + if (scancode & 0x0400) + return Scancode_to_sym[scancode & 0xFF][3] | + (scancode & 0x0700) << 4; + else if (scancode & 0x0200) + return Scancode_to_sym[scancode & 0xFF][2] | + (scancode & 0x0700) << 4; + else if (scancode & 0x0100) + return Scancode_to_sym[scancode & 0xFF][1] | + (scancode & 0x0700) << 4; + else + return Scancode_to_sym[scancode & 0xFF][0]; +} + +// Convertit des modificateurs de touches SDL en modificateurs GrafX2 +word Key_modifiers(SDLMod mod) +{ + word modifiers=0; + + if (mod & KMOD_CTRL ) + modifiers|=MOD_CTRL; + if (mod & KMOD_SHIFT ) + modifiers|=MOD_SHIFT; + if (mod & (KMOD_ALT|KMOD_MODE)) + modifiers|=MOD_ALT; + if (mod & (KMOD_META)) + modifiers|=MOD_META; + + return modifiers; +} + +word Keysym_to_keycode(SDL_keysym keysym) +{ + word key_code = 0; + word mod; + + // On ignore shift, alt et control isolés. + if (keysym.sym == SDLK_RSHIFT || keysym.sym == SDLK_LSHIFT || + keysym.sym == SDLK_RCTRL || keysym.sym == SDLK_LCTRL || + keysym.sym == SDLK_RALT || keysym.sym == SDLK_LALT || + keysym.sym == SDLK_RMETA || keysym.sym == SDLK_LMETA || + keysym.sym == SDLK_MODE) // AltGr + return 0; + + // Les touches qui n'ont qu'une valeur unicode (très rares) + // seront codées sur 11 bits, le 12e bit est mis à 1 (0x0800) + if (keysym.sym != 0) + key_code = keysym.sym; + else if (keysym.scancode != 0) + { + key_code = (keysym.scancode & 0x07FF) | 0x0800; + } + + // Normally I should test keysym.mod here, but on windows the implementation + // is buggy: if you release a modifier key, the following keys (when they repeat) + // still name the original modifiers. + mod=Key_modifiers(SDL_GetModState()); + + // SDL_GetModState() seems to get the right up-to-date info. + key_code |= mod; + return key_code; +} + +const char * Key_name(word Key) +{ + typedef struct + { + word keysym; + char *Key_name; + } T_key_label; + T_key_label key_labels[] = + { + { SDLK_BACKSPACE , "Backspace" }, + { SDLK_TAB , "Tab" }, + { SDLK_CLEAR , "Clear" }, + { SDLK_RETURN , "Return" }, + { SDLK_PAUSE , "Pause" }, + { SDLK_ESCAPE , "Esc" }, + { SDLK_DELETE , "Del" }, + { SDLK_KP0 , "KP 0" }, + { SDLK_KP1 , "KP 1" }, + { SDLK_KP2 , "KP 2" }, + { SDLK_KP3 , "KP 3" }, + { SDLK_KP4 , "KP 4" }, + { SDLK_KP5 , "KP 5" }, + { SDLK_KP6 , "KP 6" }, + { SDLK_KP7 , "KP 7" }, + { SDLK_KP8 , "KP 8" }, + { SDLK_KP9 , "KP 9" }, + { SDLK_KP_PERIOD , "KP ." }, + { SDLK_KP_DIVIDE , "KP /" }, + { SDLK_KP_MULTIPLY, "KP *" }, + { SDLK_KP_MINUS , "KP -" }, + { SDLK_KP_PLUS , "KP +" }, + { SDLK_KP_ENTER , "KP Enter" }, + { SDLK_KP_EQUALS , "KP =" }, + { SDLK_UP , "Up" }, + { SDLK_DOWN , "Down" }, + { SDLK_RIGHT , "Right" }, + { SDLK_LEFT , "Left" }, + { SDLK_INSERT , "Ins" }, + { SDLK_HOME , "Home" }, + { SDLK_END , "End" }, + { SDLK_PAGEUP , "PgUp" }, + { SDLK_PAGEDOWN , "PgDn" }, + { SDLK_F1 , "F1" }, + { SDLK_F2 , "F2" }, + { SDLK_F3 , "F3" }, + { SDLK_F4 , "F4" }, + { SDLK_F5 , "F5" }, + { SDLK_F6 , "F6" }, + { SDLK_F7 , "F7" }, + { SDLK_F8 , "F8" }, + { SDLK_F9 , "F9" }, + { SDLK_F10 , "F10" }, + { SDLK_F11 , "F11" }, + { SDLK_F12 , "F12" }, + { SDLK_F13 , "F13" }, + { SDLK_F14 , "F14" }, + { SDLK_F15 , "F15" }, + { SDLK_NUMLOCK , "NumLock" }, + { SDLK_CAPSLOCK , "CapsLck" }, + { SDLK_SCROLLOCK , "ScrlLock" }, + { SDLK_RSHIFT , "RShift" }, + { SDLK_LSHIFT , "LShift" }, + { SDLK_RCTRL , "RCtrl" }, + { SDLK_LCTRL , "LCtrl" }, + { SDLK_RALT , "RAlt" }, + { SDLK_LALT , "LAlt" }, + { SDLK_RMETA , "RMeta" }, + { SDLK_LMETA , "LMeta" }, + { SDLK_LSUPER , "LWin" }, + { SDLK_RSUPER , "RWin" }, + { SDLK_MODE , "AltGr" }, + { SDLK_COMPOSE , "Comp" }, + { SDLK_HELP , "Help" }, + { SDLK_PRINT , "Print" }, + { SDLK_SYSREQ , "SysReq" }, + { SDLK_BREAK , "Break" }, + { SDLK_MENU , "Menu" }, + { SDLK_POWER , "Power" }, + { SDLK_EURO , "Euro" }, + { SDLK_UNDO , "Undo" }, + { KEY_MOUSEMIDDLE, "Mouse3" }, + { KEY_MOUSEWHEELUP, "WheelUp" }, + { KEY_MOUSEWHEELDOWN, "WheelDown" } + }; + + int index; + static char buffer[41]; + buffer[0] = '\0'; + + if (Key == SDLK_UNKNOWN) + return "None"; + + if (Key & MOD_CTRL) + strcat(buffer, "Ctrl+"); + if (Key & MOD_ALT) + strcat(buffer, "Alt+"); + if (Key & MOD_SHIFT) + strcat(buffer, "Shift+"); + if (Key & MOD_META) + strcat(buffer, "\201"); + // Note: Apple's "command" character is not present in the ANSI table, so we + // recycled an ANSI value that doesn't have any displayable character + // associated. + + + Key=Key & ~(MOD_CTRL|MOD_ALT|MOD_SHIFT); + + if (Key>=KEY_JOYBUTTON && Key<=KEY_JOYBUTTON+18) + { +#ifdef __GP2X__ + + char *button_name; + switch(Key-KEY_JOYBUTTON) + { + case GP2X_BUTTON_UP: button_name="[UP]"; break; + case GP2X_BUTTON_DOWN: button_name="[DOWN]"; break; + case GP2X_BUTTON_LEFT: button_name="[LEFT]"; break; + case GP2X_BUTTON_RIGHT: button_name="[RIGHT]"; break; + case GP2X_BUTTON_UPLEFT: button_name="[UP-LEFT]"; break; + case GP2X_BUTTON_UPRIGHT: button_name="[UP-RIGHT]"; break; + case GP2X_BUTTON_DOWNLEFT: button_name="[DOWN-LEFT]"; break; + case GP2X_BUTTON_DOWNRIGHT: button_name="[DOWN-RIGHT]"; break; + case GP2X_BUTTON_CLICK: button_name="[CLICK]"; break; + case GP2X_BUTTON_A: button_name="[A]"; break; + case GP2X_BUTTON_B: button_name="[B]"; break; + case GP2X_BUTTON_X: button_name="[X]"; break; + case GP2X_BUTTON_Y: button_name="[Y]"; break; + case GP2X_BUTTON_L: button_name="[L]"; break; + case GP2X_BUTTON_R: button_name="[R]"; break; + case GP2X_BUTTON_START: button_name="[START]"; break; + case GP2X_BUTTON_SELECT: button_name="[SELECT]"; break; + case GP2X_BUTTON_VOLUP: button_name="[VOL UP]"; break; + case GP2X_BUTTON_VOLDOWN: button_name="[VOL DOWN]"; break; + default: sprintf(buffer+strlen(buffer), "[B%d]", Key);return buffer; + } + strcat(buffer,button_name); +#else + sprintf(buffer+strlen(buffer), "[B%d]", Key-KEY_JOYBUTTON); +#endif + return buffer; + } + + if (Key & 0x800) + { + sprintf(buffer+strlen(buffer), "[%d]", Key & 0x7FF); + return buffer; + } + Key = Key & 0x7FF; + // Touches ASCII + if (Key>=' ' && Key < 127) + { + sprintf(buffer+strlen(buffer), "'%c'", toupper(Key)); + return buffer; + } + // Touches 'World' + if (Key>=SDLK_WORLD_0 && Key <= SDLK_WORLD_95) + { + sprintf(buffer+strlen(buffer), "w%d", Key - SDLK_WORLD_0); + return buffer; + } + + // Touches au libellé connu + for (index=0; index < (long)sizeof(key_labels)/(long)sizeof(T_key_label);index++) + { + if (Key == key_labels[index].keysym) + { + sprintf(buffer+strlen(buffer), "%s", key_labels[index].Key_name); + return buffer; + } + } + // Autres touches inconnues + sprintf(buffer+strlen(buffer), "0x%X", Key & 0x7FF); + return buffer; + +} + +// Obtient le caractère ANSI tapé, à partir d'un keysym. +// (Valeur 32 à 255) +// Renvoie 0 s'il n'y a pas de caractère associé (shift, backspace, etc) +word Keysym_to_ANSI(SDL_keysym keysym) +{ + // This part was removed from the MacOSX port, but I put it back for others + // as on Linux and Windows, it's what allows editing a text line with the keys + // SDLK_LEFT, SDLK_RIGHT, SDLK_HOME, SDLK_END etc. + #if !(defined(__macosx__) || defined(__FreeBSD__)) + if ( keysym.unicode == 0) + { + switch(keysym.sym) + { + case SDLK_DELETE: + case SDLK_LEFT: + case SDLK_RIGHT: + case SDLK_HOME: + case SDLK_END: + case SDLK_BACKSPACE: + case KEY_ESC: + case SDLK_RETURN: + return keysym.sym; + default: + return 0; + } + } + #endif + // + if ( keysym.unicode > 32 && keysym.unicode < 127) + { + return keysym.unicode; // Pas de souci, on est en ASCII standard + } + + // Quelques conversions Unicode-ANSI + switch(keysym.unicode) + { + case 0x8100: + return 'ü'; // ü + case 0x1A20: + return 'é'; // é + case 0x201A: + return 'è'; // è + case 0x9201: + return 'â'; // â + case 0x1E20: + return 'ä'; // ä + case 0x2620: + return 'à'; // à + case 0x2020: + return 'å'; // å + case 0x2120: + return 'ç'; // ç + case 0xC602: + return 'ê'; // ê + case 0x3020: + return 'ë'; // ë + case 0x6001: + return 'è'; // è + case 0x3920: + return 'ï'; // ï + case 0x5201: + return 'î'; // î + case 0x8D00: + return 'ì'; // ì + case 0x1C20: + return 'ô'; // ô + case 0x1D20: + return 'ö'; // ö + case 0x2220: + return 'ò'; // ò + case 0x1320: + return 'û'; // û + case 0x1420: + return 'ù'; // ù + case 0xDC02: + return 'ÿ'; // ÿ + case 0x5301: + return '£'; // £ + case 0xA000: + return 'á'; // á + case 0xA100: + return 'í'; // í + case 0xA200: + return 'ó'; // ó + case 0xA300: + return 'ú'; // ú + case 0xA400: + return 'ñ'; // ñ + case 0xA700: + return 'º'; // º + case 0xC600: + return 'ã'; // ã + } + + // Key entre 127 et 255 + if (keysym.unicode<256) + { +#if defined(__macosx__) || defined(__FreeBSD__) + // fc: Looks like there's a mismatch with delete & backspace + // i don't why SDLK_DELETE was returned instead of SDLK_BACKSPACE + if(keysym.unicode == 127) + { + return(SDLK_BACKSPACE); + } + // We don't make any difference between return & enter in the app context. + if(keysym.unicode == 3) + { + return(SDLK_RETURN); + } +#endif + return keysym.unicode; + } + + // Sinon c'est une touche spéciale, on retourne son scancode + return keysym.sym; +} diff --git a/keyboard.h b/keyboard.h index d3776d8b..eca0352e 100644 --- a/keyboard.h +++ b/keyboard.h @@ -1,75 +1,75 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file keyboard.h -/// Functions to convert bewteen the SDL key formats and the keycode we use -/// in grafx2. -/// The keycode we're using is generalized to handle mouse and joystick shortcuts -/// as well. The format can be broken down as: -/// - 0x0000 + a number between 0 and SDLK_LAST (about 324) : the SDL "sym" key number. -/// - 0x0000 + SDLK_LAST+1: Mouse middle button. -/// - 0x0000 + SDLK_LAST+2: Mouse wheel up. -/// - 0x0000 + SDLK_LAST+3: Mouse wheel down. -/// - 0x0000 + SDLK_LAST+4+B : Joystick button number "B", starting at B=0. -/// - 0x0800 + a number between 0 and 0x7FF: The scancode key number, for keys which have no "sym", such as keys from multimedia keyboards, and "fn" and "Thinkpad" key for a laptop. -/// Add 0x1000 for the Shift modifier MOD_SHIFT -/// Add 0x2000 for the Control modifier ::MOD_CONTROL -/// Add 0x4000 for the Alt modifier ::MOD_ALT -/// Add 0x8000 for the "Meta" modifier ::MOD_META (On MacOS X it's the CMD key) -////////////////////////////////////////////////////////////////////////////// - -/*! - Convert an SDL keysym to an ANSI/ASCII character. - This is used to type text and numeric values in input boxes. - @param keysym SDL symbol to convert -*/ -word Keysym_to_ANSI(SDL_keysym keysym); - -/*! - Convert an SDL keysym to an internal keycode number. - This is needed because SDL tends to split the information across the unicode sym, the regular sym, and the raw keycode. - We also need to differenciate 1 (keypad) and 1 (regular keyboard), and some other things. - See the notice at the beginning of keyboard.h for the format of a keycode. - @param keysym SDL symbol to convert -*/ -word Keysym_to_keycode(SDL_keysym keysym); - -/*! - Helper function to convert between SDL system and the old coding for PC keycodes. - This is only used to convert configuration files from the DOS version of - Grafx2, where keyboard codes are in in the IBM PC AT form. - @param scancode Scancode to convert -*/ -word Key_for_scancode(word scancode); - -/*! - Returns key name in a string. Used to display them in the helpscreens and in the keymapper window. - @param Key keycode of the key to translate, including modifiers -*/ -const char * Key_name(word Key); - -/*! - Gets the modifiers in our format from the SDL_Mod information. - Returns a combination of ::MOD_SHIFT, ::MOD_ALT, ::MOD_CONTROL - @param mod SDL modifiers state -*/ -word Key_modifiers(SDLMod mod); - +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file keyboard.h +/// Functions to convert bewteen the SDL key formats and the keycode we use +/// in grafx2. +/// The keycode we're using is generalized to handle mouse and joystick shortcuts +/// as well. The format can be broken down as: +/// - 0x0000 + a number between 0 and SDLK_LAST (about 324) : the SDL "sym" key number. +/// - 0x0000 + SDLK_LAST+1: Mouse middle button. +/// - 0x0000 + SDLK_LAST+2: Mouse wheel up. +/// - 0x0000 + SDLK_LAST+3: Mouse wheel down. +/// - 0x0000 + SDLK_LAST+4+B : Joystick button number "B", starting at B=0. +/// - 0x0800 + a number between 0 and 0x7FF: The scancode key number, for keys which have no "sym", such as keys from multimedia keyboards, and "fn" and "Thinkpad" key for a laptop. +/// Add 0x1000 for the Shift modifier MOD_SHIFT +/// Add 0x2000 for the Control modifier ::MOD_CONTROL +/// Add 0x4000 for the Alt modifier ::MOD_ALT +/// Add 0x8000 for the "Meta" modifier ::MOD_META (On MacOS X it's the CMD key) +////////////////////////////////////////////////////////////////////////////// + +/*! + Convert an SDL keysym to an ANSI/ASCII character. + This is used to type text and numeric values in input boxes. + @param keysym SDL symbol to convert +*/ +word Keysym_to_ANSI(SDL_keysym keysym); + +/*! + Convert an SDL keysym to an internal keycode number. + This is needed because SDL tends to split the information across the unicode sym, the regular sym, and the raw keycode. + We also need to differenciate 1 (keypad) and 1 (regular keyboard), and some other things. + See the notice at the beginning of keyboard.h for the format of a keycode. + @param keysym SDL symbol to convert +*/ +word Keysym_to_keycode(SDL_keysym keysym); + +/*! + Helper function to convert between SDL system and the old coding for PC keycodes. + This is only used to convert configuration files from the DOS version of + Grafx2, where keyboard codes are in in the IBM PC AT form. + @param scancode Scancode to convert +*/ +word Key_for_scancode(word scancode); + +/*! + Returns key name in a string. Used to display them in the helpscreens and in the keymapper window. + @param Key keycode of the key to translate, including modifiers +*/ +const char * Key_name(word Key); + +/*! + Gets the modifiers in our format from the SDL_Mod information. + Returns a combination of ::MOD_SHIFT, ::MOD_ALT, ::MOD_CONTROL + @param mod SDL modifiers state +*/ +word Key_modifiers(SDLMod mod); + diff --git a/loadsave.h b/loadsave.h index 3f185d80..e8fd0c83 100644 --- a/loadsave.h +++ b/loadsave.h @@ -1,57 +1,57 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - 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 -*/ -////////////////////////////////////////////////////////////////////////////// -///@file loadsave.h -/// Saving and loading different picture formats. -/// Also handles showing the preview in fileselectors. -////////////////////////////////////////////////////////////////////////////// - -void Pixel_load_in_current_screen(word x_pos,word y_pos,byte color); -void Pixel_load_in_preview (word x_pos,word y_pos,byte color); -void Pixel_load_in_brush (word x_pos,word y_pos,byte color); - -void Get_full_filename(char * filename, byte is_colorix_format); - -/// -/// High-level picture loading function. -/// Handles loading an image or a brush, or previewing only. -/// @param image true if the fileselector is the one for loading images (not brush) -void Load_image(byte image); -/// -/// High-level picture saving function. -/// @param image true if the image should be saved (instead of the brush) -void Save_image(byte image); - -/// Data for an image file format. -typedef struct { - char *Extension; ///< Three-letter file extension - Func_action Test; ///< Function which tests if the file is of this format - Func_action Load; ///< Function which loads an image of this format - Func_action Save; ///< Function which saves an image of this format - byte Backup_done; ///< Boolean, true if this format saves all the image, and considers it backed up. Set false for formats which only save the palette. - byte Comment; ///< This file format allows a text comment -} T_Format; - -/// Array of the known file formats -extern T_Format File_formats[NB_KNOWN_FORMATS]; - -/// -/// Function which attempts to save backups of the images (main and spare), -/// called in case of SIGSEGV. -void Image_emergency_backup(void); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + 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 +*/ +////////////////////////////////////////////////////////////////////////////// +///@file loadsave.h +/// Saving and loading different picture formats. +/// Also handles showing the preview in fileselectors. +////////////////////////////////////////////////////////////////////////////// + +void Pixel_load_in_current_screen(word x_pos,word y_pos,byte color); +void Pixel_load_in_preview (word x_pos,word y_pos,byte color); +void Pixel_load_in_brush (word x_pos,word y_pos,byte color); + +void Get_full_filename(char * filename, byte is_colorix_format); + +/// +/// High-level picture loading function. +/// Handles loading an image or a brush, or previewing only. +/// @param image true if the fileselector is the one for loading images (not brush) +void Load_image(byte image); +/// +/// High-level picture saving function. +/// @param image true if the image should be saved (instead of the brush) +void Save_image(byte image); + +/// Data for an image file format. +typedef struct { + char *Extension; ///< Three-letter file extension + Func_action Test; ///< Function which tests if the file is of this format + Func_action Load; ///< Function which loads an image of this format + Func_action Save; ///< Function which saves an image of this format + byte Backup_done; ///< Boolean, true if this format saves all the image, and considers it backed up. Set false for formats which only save the palette. + byte Comment; ///< This file format allows a text comment +} T_Format; + +/// Array of the known file formats +extern T_Format File_formats[NB_KNOWN_FORMATS]; + +/// +/// Function which attempts to save backups of the images (main and spare), +/// called in case of SIGSEGV. +void Image_emergency_backup(void); diff --git a/misc.h b/misc.h index 88eb23d0..15ae058b 100644 --- a/misc.h +++ b/misc.h @@ -1,150 +1,150 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - 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 -*/ -////////////////////////////////////////////////////////////////////////////// -///@file misc.h -/// Miscellanous unsorted functions. -////////////////////////////////////////////////////////////////////////////// - -void Copy_image_to_brush(short start_x,short start_y,short Brush_width,short Brush_height,word image_width); -void Remap_general_lowlevel(byte * conversion_table,byte * buffer,short width,short height,short buffer_width); -void Scroll_picture(short x_offset,short y_offset); -void Wait_end_of_click(void); -void Set_color(byte color, byte red, byte green, byte blue); -void Set_palette(T_Palette palette); -void Palette_256_to_64(T_Palette palette); -void Palette_64_to_256(T_Palette palette); -void Hide_current_image(byte color); -void Hide_current_image_with_stencil(byte color, byte * stencil); -void Slider_timer(byte speed); -dword Round_div(dword numerator,dword divisor); -word Count_used_colors(dword * usage); -word Count_used_colors_area(dword* usage, word start_x, word start_y, word width, word height); -void Pixel_in_current_screen (word x,word y,byte color); -void Pixel_in_brush (word x,word y,byte color); -byte Read_pixel_from_current_screen (word x,word y); -byte Read_pixel_from_spare_screen(word x,word y); -byte Read_pixel_from_backup_screen (word x,word y); -byte Read_pixel_from_feedback_screen (word x,word y); -byte Read_pixel_from_brush (word x,word y); - -void Ellipse_compute_limites(short horizontal_radius,short vertical_radius); -// Calcule les valeurs suivantes en fonction des deux paramètres: -// -// Ellipse_vertical_radius_squared -// Ellipse_horizontal_radius_squared -// Ellipse_Limit_High -// Ellipse_Limit_Low - - -byte Pixel_in_ellipse(void); -// Indique si le pixel se trouvant à Ellipse_cursor_X pixels -// (Ellipse_cursor_X>0 = à droite, Ellipse_cursor_X<0 = à gauche) et à -// Ellipse_cursor_Y pixels (Ellipse_cursor_Y>0 = en bas, -// Ellipse_cursor_Y<0 = en haut) du centre se trouve dans l'ellipse en -// cours. - -byte Pixel_in_circle(void); -// Indique si le pixel se trouvant à Circle_cursor_X pixels -// (Circle_cursor_X>0 = à droite, Circle_cursor_X<0 = à gauche) et à -// Circle_cursor_Y pixels (Circle_cursor_Y>0 = en bas, -// Circle_cursor_Y<0 = en haut) du centre se trouve dans le cercle en -// cours. - -// Gestion du chrono dans les fileselects -void Init_chrono(dword delay); -void Check_timer(void); - -void Replace_a_color(byte old_color, byte New_color); -void Replace_colors_within_limits(byte * replace_table); - -byte Effect_interpolated_colorize (word x,word y,byte color); -byte Effect_additive_colorize (word x,word y,byte color); -byte Effect_substractive_colorize(word x,word y,byte color); -byte Effect_sieve(word x,word y); - -/// -/// Inverts a pixel buffer, according to a horizontal axis. -/// @param src Pointer to the pixel buffer to process. -/// @param width Width of the buffer. -/// @param height Height of the buffer. -void Flip_Y_lowlevel(byte *src, short width, short height); - -/// -/// Inverts a pixel buffer, according to a vertical axis. -/// @param src Pointer to the pixel buffer to process. -/// @param width Width of the buffer. -/// @param height Height of the buffer. -void Flip_X_lowlevel(byte *src, short width, short height); -/// -/// Rotate a pixel buffer by 90 degrees, clockwise. -/// @param source Source pixel buffer. -/// @param dest Destination pixel buffer. -/// @param width Width of the original buffer (height of the destination one). -/// @param height Height of the original buffer (width of the destination one). -void Rotate_90_deg_lowlevel(byte * source, byte * dest, short width, short height); -/// -/// Rotate a pixel buffer by 90 degrees, counter-clockwise. -/// @param source Source pixel buffer. -/// @param dest Destination pixel buffer. -/// @param width Width of the original buffer (height of the destination one). -/// @param height Height of the original buffer (width of the destination one). -void Rotate_270_deg_lowlevel(byte * source, byte * dest, short width, short height); -/// -/// Rotate a pixel buffer by 180 degrees. -/// @param src The pixel buffer (source and destination). -/// @param width Width of the buffer. -/// @param height Height of the buffer. -void Rotate_180_deg_lowlevel(byte *src, short width, short height); - -/// -/// Copies an image to another, rescaling it and optionally flipping it. -/// @param src_buffer Original image (address of first byte) -/// @param src_width Original image's width in pixels -/// @param src_height Original image's height in pixels -/// @param dst_buffer Destination image (address of first byte) -/// @param dst_width Destination image's width in pixels -/// @param dst_height Destination image's height in pixels -/// @param x_flipped Boolean, true to flip the image horizontally -/// @param y_flipped Boolean, true to flip the image vertically -void Rescale(byte *src_buffer, short src_width, short src_height, byte *dst_buffer, short dst_width, short dst_height, short x_flipped, short y_flipped); - -void Zoom_a_line(byte * original_line,byte * zoomed_line,word factor,word width); -void Copy_part_of_image_to_another(byte * source,word source_x,word source_y,word width,word height,word source_width,byte * dest,word dest_x,word dest_y,word destination_width); - -// -- Gestion du chrono -- -byte Timer_state; // State du chrono: 0=Attente d'un Xème de seconde - // 1=Il faut afficher la preview - // 2=Plus de chrono à gerer pour l'instant -dword Timer_delay; // Nombre de 18.2ème de secondes demandés -dword Timer_start; // Heure de départ du chrono -byte New_preview_is_needed; // Booléen "Il faut relancer le chrono de preview" - - -unsigned long Memory_free(void); - -void Num2str(dword number,char * str,byte nb_char); - -short Round(float value); -short Round_div_max(short numerator,short divisor); - -int Min(int a,int b); -int Max(int a,int b); - -char* Mode_label(int mode); -int Convert_videomode_arg(const char *argument); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + 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 +*/ +////////////////////////////////////////////////////////////////////////////// +///@file misc.h +/// Miscellanous unsorted functions. +////////////////////////////////////////////////////////////////////////////// + +void Copy_image_to_brush(short start_x,short start_y,short Brush_width,short Brush_height,word image_width); +void Remap_general_lowlevel(byte * conversion_table,byte * buffer,short width,short height,short buffer_width); +void Scroll_picture(short x_offset,short y_offset); +void Wait_end_of_click(void); +void Set_color(byte color, byte red, byte green, byte blue); +void Set_palette(T_Palette palette); +void Palette_256_to_64(T_Palette palette); +void Palette_64_to_256(T_Palette palette); +void Hide_current_image(byte color); +void Hide_current_image_with_stencil(byte color, byte * stencil); +void Slider_timer(byte speed); +dword Round_div(dword numerator,dword divisor); +word Count_used_colors(dword * usage); +word Count_used_colors_area(dword* usage, word start_x, word start_y, word width, word height); +void Pixel_in_current_screen (word x,word y,byte color); +void Pixel_in_brush (word x,word y,byte color); +byte Read_pixel_from_current_screen (word x,word y); +byte Read_pixel_from_spare_screen(word x,word y); +byte Read_pixel_from_backup_screen (word x,word y); +byte Read_pixel_from_feedback_screen (word x,word y); +byte Read_pixel_from_brush (word x,word y); + +void Ellipse_compute_limites(short horizontal_radius,short vertical_radius); +// Calcule les valeurs suivantes en fonction des deux paramètres: +// +// Ellipse_vertical_radius_squared +// Ellipse_horizontal_radius_squared +// Ellipse_Limit_High +// Ellipse_Limit_Low + + +byte Pixel_in_ellipse(void); +// Indique si le pixel se trouvant à Ellipse_cursor_X pixels +// (Ellipse_cursor_X>0 = à droite, Ellipse_cursor_X<0 = à gauche) et à +// Ellipse_cursor_Y pixels (Ellipse_cursor_Y>0 = en bas, +// Ellipse_cursor_Y<0 = en haut) du centre se trouve dans l'ellipse en +// cours. + +byte Pixel_in_circle(void); +// Indique si le pixel se trouvant à Circle_cursor_X pixels +// (Circle_cursor_X>0 = à droite, Circle_cursor_X<0 = à gauche) et à +// Circle_cursor_Y pixels (Circle_cursor_Y>0 = en bas, +// Circle_cursor_Y<0 = en haut) du centre se trouve dans le cercle en +// cours. + +// Gestion du chrono dans les fileselects +void Init_chrono(dword delay); +void Check_timer(void); + +void Replace_a_color(byte old_color, byte New_color); +void Replace_colors_within_limits(byte * replace_table); + +byte Effect_interpolated_colorize (word x,word y,byte color); +byte Effect_additive_colorize (word x,word y,byte color); +byte Effect_substractive_colorize(word x,word y,byte color); +byte Effect_sieve(word x,word y); + +/// +/// Inverts a pixel buffer, according to a horizontal axis. +/// @param src Pointer to the pixel buffer to process. +/// @param width Width of the buffer. +/// @param height Height of the buffer. +void Flip_Y_lowlevel(byte *src, short width, short height); + +/// +/// Inverts a pixel buffer, according to a vertical axis. +/// @param src Pointer to the pixel buffer to process. +/// @param width Width of the buffer. +/// @param height Height of the buffer. +void Flip_X_lowlevel(byte *src, short width, short height); +/// +/// Rotate a pixel buffer by 90 degrees, clockwise. +/// @param source Source pixel buffer. +/// @param dest Destination pixel buffer. +/// @param width Width of the original buffer (height of the destination one). +/// @param height Height of the original buffer (width of the destination one). +void Rotate_90_deg_lowlevel(byte * source, byte * dest, short width, short height); +/// +/// Rotate a pixel buffer by 90 degrees, counter-clockwise. +/// @param source Source pixel buffer. +/// @param dest Destination pixel buffer. +/// @param width Width of the original buffer (height of the destination one). +/// @param height Height of the original buffer (width of the destination one). +void Rotate_270_deg_lowlevel(byte * source, byte * dest, short width, short height); +/// +/// Rotate a pixel buffer by 180 degrees. +/// @param src The pixel buffer (source and destination). +/// @param width Width of the buffer. +/// @param height Height of the buffer. +void Rotate_180_deg_lowlevel(byte *src, short width, short height); + +/// +/// Copies an image to another, rescaling it and optionally flipping it. +/// @param src_buffer Original image (address of first byte) +/// @param src_width Original image's width in pixels +/// @param src_height Original image's height in pixels +/// @param dst_buffer Destination image (address of first byte) +/// @param dst_width Destination image's width in pixels +/// @param dst_height Destination image's height in pixels +/// @param x_flipped Boolean, true to flip the image horizontally +/// @param y_flipped Boolean, true to flip the image vertically +void Rescale(byte *src_buffer, short src_width, short src_height, byte *dst_buffer, short dst_width, short dst_height, short x_flipped, short y_flipped); + +void Zoom_a_line(byte * original_line,byte * zoomed_line,word factor,word width); +void Copy_part_of_image_to_another(byte * source,word source_x,word source_y,word width,word height,word source_width,byte * dest,word dest_x,word dest_y,word destination_width); + +// -- Gestion du chrono -- +byte Timer_state; // State du chrono: 0=Attente d'un Xème de seconde + // 1=Il faut afficher la preview + // 2=Plus de chrono à gerer pour l'instant +dword Timer_delay; // Nombre de 18.2ème de secondes demandés +dword Timer_start; // Heure de départ du chrono +byte New_preview_is_needed; // Booléen "Il faut relancer le chrono de preview" + + +unsigned long Memory_free(void); + +void Num2str(dword number,char * str,byte nb_char); + +short Round(float value); +short Round_div_max(short numerator,short divisor); + +int Min(int a,int b); +int Max(int a,int b); + +char* Mode_label(int mode); +int Convert_videomode_arg(const char *argument); diff --git a/mountlist.c b/mountlist.c index 43067554..74674df2 100644 --- a/mountlist.c +++ b/mountlist.c @@ -1,914 +1,914 @@ -/* mountlist.c -- return a list of mounted file systems - - Copyright (C) 1991, 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006, 2007 Free Software Foundation, Inc. - - This program 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; either version 2, or (at your option) - any later version. - - This program 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 this program; if not, see . -*/ - -// This file is not used on some platforms, so don't do anything for them -#if(!defined(__WIN32__))&&(!defined(__amigaos4__))&&(!defined(__AROS__))&&(!defined(__MORPHOS__))&&(!defined(__amigaos__)) - -// We don't use autoconf and all that in grafx2, so let's do the config here ... -#if defined(__macosx__) || defined(__FreeBSD__) // MacOS X is POSIX compliant - #define MOUNTED_GETMNTINFO -#elif defined(__BEOS__) || defined(__HAIKU__) - #define MOUNTED_FS_STAT_DEV -#elif defined(__SKYOS__) - #warning "Your platform is missing some specific code here ! please check and fix :)" -#else - #define MOUNTED_GETMNTENT1 -#endif -// --- END GRAFX2 CUSTOM CONFIG --- - -#include "mountlist.h" - -#include -#include -#include -#include - -#include - -#include - -#include - -#if HAVE_SYS_PARAM_H -# include -#endif - -#if defined MOUNTED_GETFSSTAT /* OSF_1 and Darwin1.3.x */ -# if HAVE_SYS_UCRED_H -# include /* needed on OSF V4.0 for definition of NGROUPS, - NGROUPS is used as an array dimension in ucred.h */ -# include /* needed by powerpc-apple-darwin1.3.7 */ -# endif -# if HAVE_SYS_MOUNT_H -# include -# endif -# if HAVE_SYS_FS_TYPES_H -# include /* needed by powerpc-apple-darwin1.3.7 */ -# endif -# if HAVE_STRUCT_FSSTAT_F_FSTYPENAME -# define FS_TYPE(Ent) ((Ent).f_fstypename) -# else -# define FS_TYPE(Ent) mnt_names[(Ent).f_type] -# endif -#endif /* MOUNTED_GETFSSTAT */ - -#ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ -# include -# if !defined MOUNTED -# if defined _PATH_MOUNTED /* GNU libc */ -# define MOUNTED _PATH_MOUNTED -# endif -# if defined MNT_MNTTAB /* HP-UX. */ -# define MOUNTED MNT_MNTTAB -# endif -# if defined MNTTABNAME /* Dynix. */ -# define MOUNTED MNTTABNAME -# endif -# endif -#endif - -#ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */ -# include -#endif - -#ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */ -# include -#endif - -#ifdef MOUNTED_GETMNT /* Ultrix. */ -# include -# include -#endif - -#ifdef MOUNTED_FS_STAT_DEV /* BeOS. */ -# include -# include -#endif - -#ifdef MOUNTED_FREAD /* SVR2. */ -# include -#endif - -#ifdef MOUNTED_FREAD_FSTYP /* SVR3. */ -# include -# include -# include -#endif - -#ifdef MOUNTED_LISTMNTENT -# include -#endif - -#ifdef MOUNTED_GETMNTENT2 /* SVR4. */ -# include -#endif - -#ifdef MOUNTED_VMOUNT /* AIX. */ -# include -# include -#endif - -#ifdef DOLPHIN -/* So special that it's not worth putting this in autoconf. */ -# undef MOUNTED_FREAD_FSTYP -# define MOUNTED_GETMNTTBL -#endif - -#if HAVE_SYS_MNTENT_H -/* This is to get MNTOPT_IGNORE on e.g. SVR4. */ -# include -#endif - -#undef MNT_IGNORE -#if defined MNTOPT_IGNORE && defined HAVE_HASMNTOPT -# define MNT_IGNORE(M) hasmntopt ((M), MNTOPT_IGNORE) -#else -# define MNT_IGNORE(M) 0 -#endif - -#if USE_UNLOCKED_IO -# include "unlocked-io.h" -#endif - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -/* The results of open() in this file are not used with fchdir, - therefore save some unnecessary work in fchdir.c. */ -#undef open -#undef close - -/* The results of opendir() in this file are not used with dirfd and fchdir, - therefore save some unnecessary work in fchdir.c. */ -#undef opendir -#undef closedir - -// gcc2 under haiku and beos don't like these macros for some reason. -// As they are not used there anyways, we remove them and everyone is happy. -#if !defined(__HAIKU__) && !defined(__BEOS__) -#ifndef ME_DUMMY -# define ME_DUMMY(Fs_name, Fs_type) \ - (strcmp (Fs_type, "autofs") == 0 \ - || strcmp (Fs_type, "none") == 0 \ - || strcmp (Fs_type, "proc") == 0 \ - || strcmp (Fs_type, "subfs") == 0 \ - || strcmp (Fs_type, "sysfs") == 0 \ - || strcmp (Fs_type, "usbfs") == 0 \ - || strcmp (Fs_type, "devpts") == 0 \ - || strcmp (Fs_type, "tmpfs") == 0 \ - /* for NetBSD 3.0 */ \ - || strcmp (Fs_type, "kernfs") == 0 \ - /* for Irix 6.5 */ \ - || strcmp (Fs_type, "ignore") == 0 \ - /* for MacOSX */ \ - || strcmp (Fs_type, "devfs") == 0 \ - || strcmp (Fs_type, "fdesc") == 0 \ - || strcmp (Fs_type, "nfs") == 0 \ - || strcmp (Fs_type, "volfs") == 0) -#endif - -#ifndef ME_REMOTE -/* A file system is `remote' if its Fs_name contains a `:' - or if (it is of type (smbfs or cifs) and its Fs_name starts with `//'). */ -# define ME_REMOTE(Fs_name, Fs_type) \ - (strchr (Fs_name, ':') != NULL \ - || ((Fs_name)[0] == '/' \ - && (Fs_name)[1] == '/' \ - && (strcmp (Fs_type, "smbfs") == 0 \ - || strcmp (Fs_type, "cifs") == 0))) -#endif -#endif // HAIKU / BEOS - -#ifdef MOUNTED_GETMNTINFO - -# if ! HAVE_STRUCT_STATFS_F_FSTYPENAME -static char * -fstype_to_string (short int t) -{ - switch (t) - { -# ifdef MOUNT_PC - case MOUNT_PC: - return "pc"; -# endif -# ifdef MOUNT_MFS - case MOUNT_MFS: - return "mfs"; -# endif -# ifdef MOUNT_LO - case MOUNT_LO: - return "lo"; -# endif -# ifdef MOUNT_TFS - case MOUNT_TFS: - return "tfs"; -# endif -# ifdef MOUNT_TMP - case MOUNT_TMP: - return "tmp"; -# endif -# ifdef MOUNT_UFS - case MOUNT_UFS: - return "ufs" ; -# endif -# ifdef MOUNT_NFS - case MOUNT_NFS: - return "nfs" ; -# endif -# ifdef MOUNT_MSDOS - case MOUNT_MSDOS: - return "msdos" ; -# endif -# ifdef MOUNT_LFS - case MOUNT_LFS: - return "lfs" ; -# endif -# ifdef MOUNT_LOFS - case MOUNT_LOFS: - return "lofs" ; -# endif -# ifdef MOUNT_FDESC - case MOUNT_FDESC: - return "fdesc" ; -# endif -# ifdef MOUNT_PORTAL - case MOUNT_PORTAL: - return "portal" ; -# endif -# ifdef MOUNT_NULL - case MOUNT_NULL: - return "null" ; -# endif -# ifdef MOUNT_UMAP - case MOUNT_UMAP: - return "umap" ; -# endif -# ifdef MOUNT_KERNFS - case MOUNT_KERNFS: - return "kernfs" ; -# endif -# ifdef MOUNT_PROCFS - case MOUNT_PROCFS: - return "procfs" ; -# endif -# ifdef MOUNT_AFS - case MOUNT_AFS: - return "afs" ; -# endif -# ifdef MOUNT_CD9660 - case MOUNT_CD9660: - return "cd9660" ; -# endif -# ifdef MOUNT_UNION - case MOUNT_UNION: - return "union" ; -# endif -# ifdef MOUNT_DEVFS - case MOUNT_DEVFS: - return "devfs" ; -# endif -# ifdef MOUNT_EXT2FS - case MOUNT_EXT2FS: - return "ext2fs" ; -# endif - default: - return "?"; - } -} -# endif - -static char * -fsp_to_string (const struct statfs *fsp) -{ -# if HAVE_STRUCT_STATFS_F_FSTYPENAME - return (char *) (fsp->f_fstypename); -# else - return fstype_to_string (fsp->f_type); -# endif -} - -#endif /* MOUNTED_GETMNTINFO */ - -#ifdef MOUNTED_VMOUNT /* AIX. */ -static char * -fstype_to_string (int t) -{ - struct vfs_ent *e; - - e = getvfsbytype (t); - if (!e || !e->vfsent_name) - return "none"; - else - return e->vfsent_name; -} -#endif /* MOUNTED_VMOUNT */ - - -#if defined MOUNTED_GETMNTENT1 || defined MOUNTED_GETMNTENT2 - -/* Return the device number from MOUNT_OPTIONS, if possible. - Otherwise return (dev_t) -1. */ - -static dev_t -dev_from_mount_options (char const *mount_options) -{ - /* GNU/Linux allows file system implementations to define their own - meaning for "dev=" mount options, so don't trust the meaning - here. */ -# ifndef __linux__ - - static char const dev_pattern[] = ",dev="; - char const *devopt = strstr (mount_options, dev_pattern); - - if (devopt) - { - char const *optval = devopt + sizeof dev_pattern - 1; - char *optvalend; - unsigned long int dev; - errno = 0; - dev = strtoul (optval, &optvalend, 16); - if (optval != optvalend - && (*optvalend == '\0' || *optvalend == ',') - && ! (dev == ULONG_MAX && errno == ERANGE) - && dev == (dev_t) dev) - return dev; - } - -# endif - - return -1; -} - -#endif - -/* Return a list of the currently mounted file systems, or NULL on error. - Add each entry to the tail of the list so that they stay in order. - If NEED_FS_TYPE is true, ensure that the file system type fields in - the returned list are valid. Otherwise, they might not be. */ - -struct mount_entry * -read_file_system_list (bool need_fs_type) -{ - struct mount_entry *mount_list; - struct mount_entry *me; - struct mount_entry **mtail = &mount_list; - -#ifdef MOUNTED_LISTMNTENT - { - struct tabmntent *mntlist, *p; - struct mntent *mnt; - struct mount_entry *me; - - /* the third and fourth arguments could be used to filter mounts, - but Crays doesn't seem to have any mounts that we want to - remove. Specifically, automount create normal NFS mounts. - */ - - if (listmntent (&mntlist, KMTAB, NULL, NULL) < 0) - return NULL; - for (p = mntlist; p; p = p->next) { - mnt = p->ment; - me = xmalloc (sizeof *me); - me->me_devname = xstrdup (mnt->mnt_fsname); - me->me_mountdir = xstrdup (mnt->mnt_dir); - me->me_type = xstrdup (mnt->mnt_type); - me->me_type_malloced = 1; - me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); - me->me_remote = ME_REMOTE (me->me_devname, me->me_type); - me->me_dev = -1; - *mtail = me; - mtail = &me->me_next; - } - freemntlist (mntlist); - } -#endif - -#ifdef MOUNTED_GETMNTENT1 /* GNU/Linux, 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ - { - struct mntent *mnt; - char *table = MOUNTED; - FILE *fp; - - fp = setmntent (table, "r"); - if (fp == NULL) - return NULL; - - while ((mnt = getmntent (fp))) - { - me = malloc (sizeof *me); - me->me_devname = strdup (mnt->mnt_fsname); - me->me_mountdir = strdup (mnt->mnt_dir); - me->me_type = strdup (mnt->mnt_type); - me->me_type_malloced = 1; - me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); - me->me_remote = ME_REMOTE (me->me_devname, me->me_type); - me->me_dev = dev_from_mount_options (mnt->mnt_opts); - - /* Add to the linked list. */ - *mtail = me; - mtail = &me->me_next; - } - - if (endmntent (fp) == 0) - goto free_then_fail; - } -#endif /* MOUNTED_GETMNTENT1. */ - -#ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */ - { - struct statfs *fsp; - int entries; - - entries = getmntinfo (&fsp, MNT_NOWAIT); - if (entries < 0) - return NULL; - for (; entries-- > 0; fsp++) - { - me = malloc (sizeof *me); - me->me_devname = strdup (fsp->f_mntfromname); - me->me_mountdir = strdup (fsp->f_mntonname); -#if defined(__macosx__) - me->me_type = fsp->f_fstypename; -#else - me->me_type = fsp->fs_typename; -#endif - me->me_type_malloced = 0; - me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); - me->me_remote = ME_REMOTE (me->me_devname, me->me_type); - me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ - - /* Add to the linked list. */ - *mtail = me; - mtail = &me->me_next; - } - } -#endif /* MOUNTED_GETMNTINFO */ - -#ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */ - { - struct statvfs *fsp; - int entries; - - entries = getmntinfo (&fsp, MNT_NOWAIT); - if (entries < 0) - return NULL; - for (; entries-- > 0; fsp++) - { - me = xmalloc (sizeof *me); - me->me_devname = xstrdup (fsp->f_mntfromname); - me->me_mountdir = xstrdup (fsp->f_mntonname); - me->me_type = xstrdup (fsp->f_fstypename); - me->me_type_malloced = 1; - me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); - me->me_remote = ME_REMOTE (me->me_devname, me->me_type); - me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ - - /* Add to the linked list. */ - *mtail = me; - mtail = &me->me_next; - } - } -#endif /* MOUNTED_GETMNTINFO2 */ - -#ifdef MOUNTED_GETMNT /* Ultrix. */ - { - int offset = 0; - int val; - struct fs_data fsd; - - while (errno = 0, - 0 < (val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY, - (char *) 0))) - { - me = xmalloc (sizeof *me); - me->me_devname = xstrdup (fsd.fd_req.devname); - me->me_mountdir = xstrdup (fsd.fd_req.path); - me->me_type = gt_names[fsd.fd_req.fstype]; - me->me_type_malloced = 0; - me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); - me->me_remote = ME_REMOTE (me->me_devname, me->me_type); - me->me_dev = fsd.fd_req.dev; - - /* Add to the linked list. */ - *mtail = me; - mtail = &me->me_next; - } - if (val < 0) - goto free_then_fail; - } -#endif /* MOUNTED_GETMNT. */ - -#if defined MOUNTED_FS_STAT_DEV /* BeOS */ - { - /* The next_dev() and fs_stat_dev() system calls give the list of - all file systems, including the information returned by statvfs() - (fs type, total blocks, free blocks etc.), but without the mount - point. But on BeOS all file systems except / are mounted in the - rootfs, directly under /. - The directory name of the mount point is often, but not always, - identical to the volume name of the device. - We therefore get the list of subdirectories of /, and the list - of all file systems, and match the two lists. */ - - DIR *dirp; - struct rootdir_entry - { - char *name; - dev_t dev; - ino_t ino; - struct rootdir_entry *next; - }; - struct rootdir_entry *rootdir_list; - struct rootdir_entry **rootdir_tail; - int32 pos; - dev_t dev; - fs_info fi; - - /* All volumes are mounted in the rootfs, directly under /. */ - rootdir_list = NULL; - rootdir_tail = &rootdir_list; - dirp = opendir ("/"); - if (dirp) - { - struct dirent *d; - - while ((d = readdir (dirp)) != NULL) - { - char *name; - struct stat statbuf; - - if (strcmp (d->d_name, "..") == 0) - continue; - - if (strcmp (d->d_name, ".") == 0) - name = strdup ("/"); - else - { - name = malloc (1 + strlen (d->d_name) + 1); - name[0] = '/'; - strcpy (name + 1, d->d_name); - } - - if (lstat (name, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode)) - { - struct rootdir_entry *re = malloc (sizeof *re); - re->name = name; - re->dev = statbuf.st_dev; - re->ino = statbuf.st_ino; - - /* Add to the linked list. */ - *rootdir_tail = re; - rootdir_tail = &re->next; - } - else - free (name); - } - closedir (dirp); - } - *rootdir_tail = NULL; - - for (pos = 0; (dev = next_dev (&pos)) >= 0; ) - if (fs_stat_dev (dev, &fi) >= 0) - { - /* Note: fi.dev == dev. */ - struct rootdir_entry *re; - - for (re = rootdir_list; re; re = re->next) - if (re->dev == fi.dev && re->ino == fi.root) - break; - - me = malloc (sizeof *me); - me->me_devname = strdup (fi.device_name[0] != '\0' ? fi.device_name : fi.fsh_name); - me->me_mountdir = strdup (re != NULL ? re->name : fi.fsh_name); - me->me_type = strdup (fi.fsh_name); - me->me_type_malloced = 1; - me->me_dev = fi.dev; - me->me_dummy = 0; - me->me_remote = (fi.flags & B_FS_IS_SHARED) != 0; - - /* Add to the linked list. */ - *mtail = me; - mtail = &me->me_next; - } - *mtail = NULL; - - while (rootdir_list != NULL) - { - struct rootdir_entry *re = rootdir_list; - rootdir_list = re->next; - free (re->name); - free (re); - } - } -#endif /* MOUNTED_FS_STAT_DEV */ - -#if defined MOUNTED_GETFSSTAT /* __alpha running OSF_1 */ - { - int numsys, counter; - size_t bufsize; - struct statfs *stats; - - numsys = getfsstat ((struct statfs *)0, 0L, MNT_NOWAIT); - if (numsys < 0) - return (NULL); - if (SIZE_MAX / sizeof *stats <= numsys) - xalloc_die (); - - bufsize = (1 + numsys) * sizeof *stats; - stats = xmalloc (bufsize); - numsys = getfsstat (stats, bufsize, MNT_NOWAIT); - - if (numsys < 0) - { - free (stats); - return (NULL); - } - - for (counter = 0; counter < numsys; counter++) - { - me = xmalloc (sizeof *me); - me->me_devname = xstrdup (stats[counter].f_mntfromname); - me->me_mountdir = xstrdup (stats[counter].f_mntonname); - me->me_type = xstrdup (FS_TYPE (stats[counter])); - me->me_type_malloced = 1; - me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); - me->me_remote = ME_REMOTE (me->me_devname, me->me_type); - me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ - - /* Add to the linked list. */ - *mtail = me; - mtail = &me->me_next; - } - - free (stats); - } -#endif /* MOUNTED_GETFSSTAT */ - -#if defined MOUNTED_FREAD || defined MOUNTED_FREAD_FSTYP /* SVR[23]. */ - { - struct mnttab mnt; - char *table = "/etc/mnttab"; - FILE *fp; - - fp = fopen (table, "r"); - if (fp == NULL) - return NULL; - - while (fread (&mnt, sizeof mnt, 1, fp) > 0) - { - me = xmalloc (sizeof *me); -# ifdef GETFSTYP /* SVR3. */ - me->me_devname = xstrdup (mnt.mt_dev); -# else - me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6); - strcpy (me->me_devname, "/dev/"); - strcpy (me->me_devname + 5, mnt.mt_dev); -# endif - me->me_mountdir = xstrdup (mnt.mt_filsys); - me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ - me->me_type = ""; - me->me_type_malloced = 0; -# ifdef GETFSTYP /* SVR3. */ - if (need_fs_type) - { - struct statfs fsd; - char typebuf[FSTYPSZ]; - - if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1 - && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1) - { - me->me_type = xstrdup (typebuf); - me->me_type_malloced = 1; - } - } -# endif - me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); - me->me_remote = ME_REMOTE (me->me_devname, me->me_type); - - /* Add to the linked list. */ - *mtail = me; - mtail = &me->me_next; - } - - if (ferror (fp)) - { - /* The last fread() call must have failed. */ - int saved_errno = errno; - fclose (fp); - errno = saved_errno; - goto free_then_fail; - } - - if (fclose (fp) == EOF) - goto free_then_fail; - } -#endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */ - -#ifdef MOUNTED_GETMNTTBL /* DolphinOS goes its own way. */ - { - struct mntent **mnttbl = getmnttbl (), **ent; - for (ent=mnttbl;*ent;ent++) - { - me = xmalloc (sizeof *me); - me->me_devname = xstrdup ( (*ent)->mt_resource); - me->me_mountdir = xstrdup ( (*ent)->mt_directory); - me->me_type = xstrdup ((*ent)->mt_fstype); - me->me_type_malloced = 1; - me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); - me->me_remote = ME_REMOTE (me->me_devname, me->me_type); - me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ - - /* Add to the linked list. */ - *mtail = me; - mtail = &me->me_next; - } - endmnttbl (); - } -#endif - -#ifdef MOUNTED_GETMNTENT2 /* SVR4. */ - { - struct mnttab mnt; - char *table = MNTTAB; - FILE *fp; - int ret; - int lockfd = -1; - -# if defined F_RDLCK && defined F_SETLKW - /* MNTTAB_LOCK is a macro name of our own invention; it's not present in - e.g. Solaris 2.6. If the SVR4 folks ever define a macro - for this file name, we should use their macro name instead. - (Why not just lock MNTTAB directly? We don't know.) */ -# ifndef MNTTAB_LOCK -# define MNTTAB_LOCK "/etc/.mnttab.lock" -# endif - lockfd = open (MNTTAB_LOCK, O_RDONLY); - if (0 <= lockfd) - { - struct flock flock; - flock.l_type = F_RDLCK; - flock.l_whence = SEEK_SET; - flock.l_start = 0; - flock.l_len = 0; - while (fcntl (lockfd, F_SETLKW, &flock) == -1) - if (errno != EINTR) - { - int saved_errno = errno; - close (lockfd); - errno = saved_errno; - return NULL; - } - } - else if (errno != ENOENT) - return NULL; -# endif - - errno = 0; - fp = fopen (table, "r"); - if (fp == NULL) - ret = errno; - else - { - while ((ret = getmntent (fp, &mnt)) == 0) - { - me = xmalloc (sizeof *me); - me->me_devname = xstrdup (mnt.mnt_special); - me->me_mountdir = xstrdup (mnt.mnt_mountp); - me->me_type = xstrdup (mnt.mnt_fstype); - me->me_type_malloced = 1; - me->me_dummy = MNT_IGNORE (&mnt) != 0; - me->me_remote = ME_REMOTE (me->me_devname, me->me_type); - me->me_dev = dev_from_mount_options (mnt.mnt_mntopts); - - /* Add to the linked list. */ - *mtail = me; - mtail = &me->me_next; - } - - ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1; - } - - if (0 <= lockfd && close (lockfd) != 0) - ret = errno; - - if (0 <= ret) - { - errno = ret; - goto free_then_fail; - } - } -#endif /* MOUNTED_GETMNTENT2. */ - -#ifdef MOUNTED_VMOUNT /* AIX. */ - { - int bufsize; - char *entries, *thisent; - struct vmount *vmp; - int n_entries; - int i; - - /* Ask how many bytes to allocate for the mounted file system info. */ - if (mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize) != 0) - return NULL; - entries = xmalloc (bufsize); - - /* Get the list of mounted file systems. */ - n_entries = mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries); - if (n_entries < 0) - { - int saved_errno = errno; - free (entries); - errno = saved_errno; - return NULL; - } - - for (i = 0, thisent = entries; - i < n_entries; - i++, thisent += vmp->vmt_length) - { - char *options, *ignore; - - vmp = (struct vmount *) thisent; - me = xmalloc (sizeof *me); - if (vmp->vmt_flags & MNT_REMOTE) - { - char *host, *dir; - - me->me_remote = 1; - /* Prepend the remote dirname. */ - host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off; - dir = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off; - me->me_devname = xmalloc (strlen (host) + strlen (dir) + 2); - strcpy (me->me_devname, host); - strcat (me->me_devname, ":"); - strcat (me->me_devname, dir); - } - else - { - me->me_remote = 0; - me->me_devname = xstrdup (thisent + - vmp->vmt_data[VMT_OBJECT].vmt_off); - } - me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off); - me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype)); - me->me_type_malloced = 1; - options = thisent + vmp->vmt_data[VMT_ARGS].vmt_off; - ignore = strstr (options, "ignore"); - me->me_dummy = (ignore - && (ignore == options || ignore[-1] == ',') - && (ignore[sizeof "ignore" - 1] == ',' - || ignore[sizeof "ignore" - 1] == '\0')); - me->me_dev = (dev_t) -1; /* vmt_fsid might be the info we want. */ - - /* Add to the linked list. */ - *mtail = me; - mtail = &me->me_next; - } - free (entries); - } -#endif /* MOUNTED_VMOUNT. */ - - *mtail = NULL; - return mount_list; - - - free_then_fail: - { - int saved_errno = errno; - *mtail = NULL; - - while (mount_list) - { - me = mount_list->me_next; - free (mount_list->me_devname); - free (mount_list->me_mountdir); - if (mount_list->me_type_malloced) - free (mount_list->me_type); - free (mount_list); - mount_list = me; - } - - errno = saved_errno; - return NULL; - } -} - -#endif - +/* mountlist.c -- return a list of mounted file systems + + Copyright (C) 1991, 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, + 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + + This program 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; either version 2, or (at your option) + any later version. + + This program 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 this program; if not, see . +*/ + +// This file is not used on some platforms, so don't do anything for them +#if(!defined(__WIN32__))&&(!defined(__amigaos4__))&&(!defined(__AROS__))&&(!defined(__MORPHOS__))&&(!defined(__amigaos__)) + +// We don't use autoconf and all that in grafx2, so let's do the config here ... +#if defined(__macosx__) || defined(__FreeBSD__) // MacOS X is POSIX compliant + #define MOUNTED_GETMNTINFO +#elif defined(__BEOS__) || defined(__HAIKU__) + #define MOUNTED_FS_STAT_DEV +#elif defined(__SKYOS__) + #warning "Your platform is missing some specific code here ! please check and fix :)" +#else + #define MOUNTED_GETMNTENT1 +#endif +// --- END GRAFX2 CUSTOM CONFIG --- + +#include "mountlist.h" + +#include +#include +#include +#include + +#include + +#include + +#include + +#if HAVE_SYS_PARAM_H +# include +#endif + +#if defined MOUNTED_GETFSSTAT /* OSF_1 and Darwin1.3.x */ +# if HAVE_SYS_UCRED_H +# include /* needed on OSF V4.0 for definition of NGROUPS, + NGROUPS is used as an array dimension in ucred.h */ +# include /* needed by powerpc-apple-darwin1.3.7 */ +# endif +# if HAVE_SYS_MOUNT_H +# include +# endif +# if HAVE_SYS_FS_TYPES_H +# include /* needed by powerpc-apple-darwin1.3.7 */ +# endif +# if HAVE_STRUCT_FSSTAT_F_FSTYPENAME +# define FS_TYPE(Ent) ((Ent).f_fstypename) +# else +# define FS_TYPE(Ent) mnt_names[(Ent).f_type] +# endif +#endif /* MOUNTED_GETFSSTAT */ + +#ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ +# include +# if !defined MOUNTED +# if defined _PATH_MOUNTED /* GNU libc */ +# define MOUNTED _PATH_MOUNTED +# endif +# if defined MNT_MNTTAB /* HP-UX. */ +# define MOUNTED MNT_MNTTAB +# endif +# if defined MNTTABNAME /* Dynix. */ +# define MOUNTED MNTTABNAME +# endif +# endif +#endif + +#ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */ +# include +#endif + +#ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */ +# include +#endif + +#ifdef MOUNTED_GETMNT /* Ultrix. */ +# include +# include +#endif + +#ifdef MOUNTED_FS_STAT_DEV /* BeOS. */ +# include +# include +#endif + +#ifdef MOUNTED_FREAD /* SVR2. */ +# include +#endif + +#ifdef MOUNTED_FREAD_FSTYP /* SVR3. */ +# include +# include +# include +#endif + +#ifdef MOUNTED_LISTMNTENT +# include +#endif + +#ifdef MOUNTED_GETMNTENT2 /* SVR4. */ +# include +#endif + +#ifdef MOUNTED_VMOUNT /* AIX. */ +# include +# include +#endif + +#ifdef DOLPHIN +/* So special that it's not worth putting this in autoconf. */ +# undef MOUNTED_FREAD_FSTYP +# define MOUNTED_GETMNTTBL +#endif + +#if HAVE_SYS_MNTENT_H +/* This is to get MNTOPT_IGNORE on e.g. SVR4. */ +# include +#endif + +#undef MNT_IGNORE +#if defined MNTOPT_IGNORE && defined HAVE_HASMNTOPT +# define MNT_IGNORE(M) hasmntopt ((M), MNTOPT_IGNORE) +#else +# define MNT_IGNORE(M) 0 +#endif + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif + +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef open +#undef close + +/* The results of opendir() in this file are not used with dirfd and fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef opendir +#undef closedir + +// gcc2 under haiku and beos don't like these macros for some reason. +// As they are not used there anyways, we remove them and everyone is happy. +#if !defined(__HAIKU__) && !defined(__BEOS__) +#ifndef ME_DUMMY +# define ME_DUMMY(Fs_name, Fs_type) \ + (strcmp (Fs_type, "autofs") == 0 \ + || strcmp (Fs_type, "none") == 0 \ + || strcmp (Fs_type, "proc") == 0 \ + || strcmp (Fs_type, "subfs") == 0 \ + || strcmp (Fs_type, "sysfs") == 0 \ + || strcmp (Fs_type, "usbfs") == 0 \ + || strcmp (Fs_type, "devpts") == 0 \ + || strcmp (Fs_type, "tmpfs") == 0 \ + /* for NetBSD 3.0 */ \ + || strcmp (Fs_type, "kernfs") == 0 \ + /* for Irix 6.5 */ \ + || strcmp (Fs_type, "ignore") == 0 \ + /* for MacOSX */ \ + || strcmp (Fs_type, "devfs") == 0 \ + || strcmp (Fs_type, "fdesc") == 0 \ + || strcmp (Fs_type, "nfs") == 0 \ + || strcmp (Fs_type, "volfs") == 0) +#endif + +#ifndef ME_REMOTE +/* A file system is `remote' if its Fs_name contains a `:' + or if (it is of type (smbfs or cifs) and its Fs_name starts with `//'). */ +# define ME_REMOTE(Fs_name, Fs_type) \ + (strchr (Fs_name, ':') != NULL \ + || ((Fs_name)[0] == '/' \ + && (Fs_name)[1] == '/' \ + && (strcmp (Fs_type, "smbfs") == 0 \ + || strcmp (Fs_type, "cifs") == 0))) +#endif +#endif // HAIKU / BEOS + +#ifdef MOUNTED_GETMNTINFO + +# if ! HAVE_STRUCT_STATFS_F_FSTYPENAME +static char * +fstype_to_string (short int t) +{ + switch (t) + { +# ifdef MOUNT_PC + case MOUNT_PC: + return "pc"; +# endif +# ifdef MOUNT_MFS + case MOUNT_MFS: + return "mfs"; +# endif +# ifdef MOUNT_LO + case MOUNT_LO: + return "lo"; +# endif +# ifdef MOUNT_TFS + case MOUNT_TFS: + return "tfs"; +# endif +# ifdef MOUNT_TMP + case MOUNT_TMP: + return "tmp"; +# endif +# ifdef MOUNT_UFS + case MOUNT_UFS: + return "ufs" ; +# endif +# ifdef MOUNT_NFS + case MOUNT_NFS: + return "nfs" ; +# endif +# ifdef MOUNT_MSDOS + case MOUNT_MSDOS: + return "msdos" ; +# endif +# ifdef MOUNT_LFS + case MOUNT_LFS: + return "lfs" ; +# endif +# ifdef MOUNT_LOFS + case MOUNT_LOFS: + return "lofs" ; +# endif +# ifdef MOUNT_FDESC + case MOUNT_FDESC: + return "fdesc" ; +# endif +# ifdef MOUNT_PORTAL + case MOUNT_PORTAL: + return "portal" ; +# endif +# ifdef MOUNT_NULL + case MOUNT_NULL: + return "null" ; +# endif +# ifdef MOUNT_UMAP + case MOUNT_UMAP: + return "umap" ; +# endif +# ifdef MOUNT_KERNFS + case MOUNT_KERNFS: + return "kernfs" ; +# endif +# ifdef MOUNT_PROCFS + case MOUNT_PROCFS: + return "procfs" ; +# endif +# ifdef MOUNT_AFS + case MOUNT_AFS: + return "afs" ; +# endif +# ifdef MOUNT_CD9660 + case MOUNT_CD9660: + return "cd9660" ; +# endif +# ifdef MOUNT_UNION + case MOUNT_UNION: + return "union" ; +# endif +# ifdef MOUNT_DEVFS + case MOUNT_DEVFS: + return "devfs" ; +# endif +# ifdef MOUNT_EXT2FS + case MOUNT_EXT2FS: + return "ext2fs" ; +# endif + default: + return "?"; + } +} +# endif + +static char * +fsp_to_string (const struct statfs *fsp) +{ +# if HAVE_STRUCT_STATFS_F_FSTYPENAME + return (char *) (fsp->f_fstypename); +# else + return fstype_to_string (fsp->f_type); +# endif +} + +#endif /* MOUNTED_GETMNTINFO */ + +#ifdef MOUNTED_VMOUNT /* AIX. */ +static char * +fstype_to_string (int t) +{ + struct vfs_ent *e; + + e = getvfsbytype (t); + if (!e || !e->vfsent_name) + return "none"; + else + return e->vfsent_name; +} +#endif /* MOUNTED_VMOUNT */ + + +#if defined MOUNTED_GETMNTENT1 || defined MOUNTED_GETMNTENT2 + +/* Return the device number from MOUNT_OPTIONS, if possible. + Otherwise return (dev_t) -1. */ + +static dev_t +dev_from_mount_options (char const *mount_options) +{ + /* GNU/Linux allows file system implementations to define their own + meaning for "dev=" mount options, so don't trust the meaning + here. */ +# ifndef __linux__ + + static char const dev_pattern[] = ",dev="; + char const *devopt = strstr (mount_options, dev_pattern); + + if (devopt) + { + char const *optval = devopt + sizeof dev_pattern - 1; + char *optvalend; + unsigned long int dev; + errno = 0; + dev = strtoul (optval, &optvalend, 16); + if (optval != optvalend + && (*optvalend == '\0' || *optvalend == ',') + && ! (dev == ULONG_MAX && errno == ERANGE) + && dev == (dev_t) dev) + return dev; + } + +# endif + + return -1; +} + +#endif + +/* Return a list of the currently mounted file systems, or NULL on error. + Add each entry to the tail of the list so that they stay in order. + If NEED_FS_TYPE is true, ensure that the file system type fields in + the returned list are valid. Otherwise, they might not be. */ + +struct mount_entry * +read_file_system_list (bool need_fs_type) +{ + struct mount_entry *mount_list; + struct mount_entry *me; + struct mount_entry **mtail = &mount_list; + +#ifdef MOUNTED_LISTMNTENT + { + struct tabmntent *mntlist, *p; + struct mntent *mnt; + struct mount_entry *me; + + /* the third and fourth arguments could be used to filter mounts, + but Crays doesn't seem to have any mounts that we want to + remove. Specifically, automount create normal NFS mounts. + */ + + if (listmntent (&mntlist, KMTAB, NULL, NULL) < 0) + return NULL; + for (p = mntlist; p; p = p->next) { + mnt = p->ment; + me = xmalloc (sizeof *me); + me->me_devname = xstrdup (mnt->mnt_fsname); + me->me_mountdir = xstrdup (mnt->mnt_dir); + me->me_type = xstrdup (mnt->mnt_type); + me->me_type_malloced = 1; + me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); + me->me_remote = ME_REMOTE (me->me_devname, me->me_type); + me->me_dev = -1; + *mtail = me; + mtail = &me->me_next; + } + freemntlist (mntlist); + } +#endif + +#ifdef MOUNTED_GETMNTENT1 /* GNU/Linux, 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ + { + struct mntent *mnt; + char *table = MOUNTED; + FILE *fp; + + fp = setmntent (table, "r"); + if (fp == NULL) + return NULL; + + while ((mnt = getmntent (fp))) + { + me = malloc (sizeof *me); + me->me_devname = strdup (mnt->mnt_fsname); + me->me_mountdir = strdup (mnt->mnt_dir); + me->me_type = strdup (mnt->mnt_type); + me->me_type_malloced = 1; + me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); + me->me_remote = ME_REMOTE (me->me_devname, me->me_type); + me->me_dev = dev_from_mount_options (mnt->mnt_opts); + + /* Add to the linked list. */ + *mtail = me; + mtail = &me->me_next; + } + + if (endmntent (fp) == 0) + goto free_then_fail; + } +#endif /* MOUNTED_GETMNTENT1. */ + +#ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */ + { + struct statfs *fsp; + int entries; + + entries = getmntinfo (&fsp, MNT_NOWAIT); + if (entries < 0) + return NULL; + for (; entries-- > 0; fsp++) + { + me = malloc (sizeof *me); + me->me_devname = strdup (fsp->f_mntfromname); + me->me_mountdir = strdup (fsp->f_mntonname); +#if defined(__macosx__) + me->me_type = fsp->f_fstypename; +#else + me->me_type = fsp->fs_typename; +#endif + me->me_type_malloced = 0; + me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); + me->me_remote = ME_REMOTE (me->me_devname, me->me_type); + me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ + + /* Add to the linked list. */ + *mtail = me; + mtail = &me->me_next; + } + } +#endif /* MOUNTED_GETMNTINFO */ + +#ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */ + { + struct statvfs *fsp; + int entries; + + entries = getmntinfo (&fsp, MNT_NOWAIT); + if (entries < 0) + return NULL; + for (; entries-- > 0; fsp++) + { + me = xmalloc (sizeof *me); + me->me_devname = xstrdup (fsp->f_mntfromname); + me->me_mountdir = xstrdup (fsp->f_mntonname); + me->me_type = xstrdup (fsp->f_fstypename); + me->me_type_malloced = 1; + me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); + me->me_remote = ME_REMOTE (me->me_devname, me->me_type); + me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ + + /* Add to the linked list. */ + *mtail = me; + mtail = &me->me_next; + } + } +#endif /* MOUNTED_GETMNTINFO2 */ + +#ifdef MOUNTED_GETMNT /* Ultrix. */ + { + int offset = 0; + int val; + struct fs_data fsd; + + while (errno = 0, + 0 < (val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY, + (char *) 0))) + { + me = xmalloc (sizeof *me); + me->me_devname = xstrdup (fsd.fd_req.devname); + me->me_mountdir = xstrdup (fsd.fd_req.path); + me->me_type = gt_names[fsd.fd_req.fstype]; + me->me_type_malloced = 0; + me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); + me->me_remote = ME_REMOTE (me->me_devname, me->me_type); + me->me_dev = fsd.fd_req.dev; + + /* Add to the linked list. */ + *mtail = me; + mtail = &me->me_next; + } + if (val < 0) + goto free_then_fail; + } +#endif /* MOUNTED_GETMNT. */ + +#if defined MOUNTED_FS_STAT_DEV /* BeOS */ + { + /* The next_dev() and fs_stat_dev() system calls give the list of + all file systems, including the information returned by statvfs() + (fs type, total blocks, free blocks etc.), but without the mount + point. But on BeOS all file systems except / are mounted in the + rootfs, directly under /. + The directory name of the mount point is often, but not always, + identical to the volume name of the device. + We therefore get the list of subdirectories of /, and the list + of all file systems, and match the two lists. */ + + DIR *dirp; + struct rootdir_entry + { + char *name; + dev_t dev; + ino_t ino; + struct rootdir_entry *next; + }; + struct rootdir_entry *rootdir_list; + struct rootdir_entry **rootdir_tail; + int32 pos; + dev_t dev; + fs_info fi; + + /* All volumes are mounted in the rootfs, directly under /. */ + rootdir_list = NULL; + rootdir_tail = &rootdir_list; + dirp = opendir ("/"); + if (dirp) + { + struct dirent *d; + + while ((d = readdir (dirp)) != NULL) + { + char *name; + struct stat statbuf; + + if (strcmp (d->d_name, "..") == 0) + continue; + + if (strcmp (d->d_name, ".") == 0) + name = strdup ("/"); + else + { + name = malloc (1 + strlen (d->d_name) + 1); + name[0] = '/'; + strcpy (name + 1, d->d_name); + } + + if (lstat (name, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode)) + { + struct rootdir_entry *re = malloc (sizeof *re); + re->name = name; + re->dev = statbuf.st_dev; + re->ino = statbuf.st_ino; + + /* Add to the linked list. */ + *rootdir_tail = re; + rootdir_tail = &re->next; + } + else + free (name); + } + closedir (dirp); + } + *rootdir_tail = NULL; + + for (pos = 0; (dev = next_dev (&pos)) >= 0; ) + if (fs_stat_dev (dev, &fi) >= 0) + { + /* Note: fi.dev == dev. */ + struct rootdir_entry *re; + + for (re = rootdir_list; re; re = re->next) + if (re->dev == fi.dev && re->ino == fi.root) + break; + + me = malloc (sizeof *me); + me->me_devname = strdup (fi.device_name[0] != '\0' ? fi.device_name : fi.fsh_name); + me->me_mountdir = strdup (re != NULL ? re->name : fi.fsh_name); + me->me_type = strdup (fi.fsh_name); + me->me_type_malloced = 1; + me->me_dev = fi.dev; + me->me_dummy = 0; + me->me_remote = (fi.flags & B_FS_IS_SHARED) != 0; + + /* Add to the linked list. */ + *mtail = me; + mtail = &me->me_next; + } + *mtail = NULL; + + while (rootdir_list != NULL) + { + struct rootdir_entry *re = rootdir_list; + rootdir_list = re->next; + free (re->name); + free (re); + } + } +#endif /* MOUNTED_FS_STAT_DEV */ + +#if defined MOUNTED_GETFSSTAT /* __alpha running OSF_1 */ + { + int numsys, counter; + size_t bufsize; + struct statfs *stats; + + numsys = getfsstat ((struct statfs *)0, 0L, MNT_NOWAIT); + if (numsys < 0) + return (NULL); + if (SIZE_MAX / sizeof *stats <= numsys) + xalloc_die (); + + bufsize = (1 + numsys) * sizeof *stats; + stats = xmalloc (bufsize); + numsys = getfsstat (stats, bufsize, MNT_NOWAIT); + + if (numsys < 0) + { + free (stats); + return (NULL); + } + + for (counter = 0; counter < numsys; counter++) + { + me = xmalloc (sizeof *me); + me->me_devname = xstrdup (stats[counter].f_mntfromname); + me->me_mountdir = xstrdup (stats[counter].f_mntonname); + me->me_type = xstrdup (FS_TYPE (stats[counter])); + me->me_type_malloced = 1; + me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); + me->me_remote = ME_REMOTE (me->me_devname, me->me_type); + me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ + + /* Add to the linked list. */ + *mtail = me; + mtail = &me->me_next; + } + + free (stats); + } +#endif /* MOUNTED_GETFSSTAT */ + +#if defined MOUNTED_FREAD || defined MOUNTED_FREAD_FSTYP /* SVR[23]. */ + { + struct mnttab mnt; + char *table = "/etc/mnttab"; + FILE *fp; + + fp = fopen (table, "r"); + if (fp == NULL) + return NULL; + + while (fread (&mnt, sizeof mnt, 1, fp) > 0) + { + me = xmalloc (sizeof *me); +# ifdef GETFSTYP /* SVR3. */ + me->me_devname = xstrdup (mnt.mt_dev); +# else + me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6); + strcpy (me->me_devname, "/dev/"); + strcpy (me->me_devname + 5, mnt.mt_dev); +# endif + me->me_mountdir = xstrdup (mnt.mt_filsys); + me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ + me->me_type = ""; + me->me_type_malloced = 0; +# ifdef GETFSTYP /* SVR3. */ + if (need_fs_type) + { + struct statfs fsd; + char typebuf[FSTYPSZ]; + + if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1 + && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1) + { + me->me_type = xstrdup (typebuf); + me->me_type_malloced = 1; + } + } +# endif + me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); + me->me_remote = ME_REMOTE (me->me_devname, me->me_type); + + /* Add to the linked list. */ + *mtail = me; + mtail = &me->me_next; + } + + if (ferror (fp)) + { + /* The last fread() call must have failed. */ + int saved_errno = errno; + fclose (fp); + errno = saved_errno; + goto free_then_fail; + } + + if (fclose (fp) == EOF) + goto free_then_fail; + } +#endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */ + +#ifdef MOUNTED_GETMNTTBL /* DolphinOS goes its own way. */ + { + struct mntent **mnttbl = getmnttbl (), **ent; + for (ent=mnttbl;*ent;ent++) + { + me = xmalloc (sizeof *me); + me->me_devname = xstrdup ( (*ent)->mt_resource); + me->me_mountdir = xstrdup ( (*ent)->mt_directory); + me->me_type = xstrdup ((*ent)->mt_fstype); + me->me_type_malloced = 1; + me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); + me->me_remote = ME_REMOTE (me->me_devname, me->me_type); + me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ + + /* Add to the linked list. */ + *mtail = me; + mtail = &me->me_next; + } + endmnttbl (); + } +#endif + +#ifdef MOUNTED_GETMNTENT2 /* SVR4. */ + { + struct mnttab mnt; + char *table = MNTTAB; + FILE *fp; + int ret; + int lockfd = -1; + +# if defined F_RDLCK && defined F_SETLKW + /* MNTTAB_LOCK is a macro name of our own invention; it's not present in + e.g. Solaris 2.6. If the SVR4 folks ever define a macro + for this file name, we should use their macro name instead. + (Why not just lock MNTTAB directly? We don't know.) */ +# ifndef MNTTAB_LOCK +# define MNTTAB_LOCK "/etc/.mnttab.lock" +# endif + lockfd = open (MNTTAB_LOCK, O_RDONLY); + if (0 <= lockfd) + { + struct flock flock; + flock.l_type = F_RDLCK; + flock.l_whence = SEEK_SET; + flock.l_start = 0; + flock.l_len = 0; + while (fcntl (lockfd, F_SETLKW, &flock) == -1) + if (errno != EINTR) + { + int saved_errno = errno; + close (lockfd); + errno = saved_errno; + return NULL; + } + } + else if (errno != ENOENT) + return NULL; +# endif + + errno = 0; + fp = fopen (table, "r"); + if (fp == NULL) + ret = errno; + else + { + while ((ret = getmntent (fp, &mnt)) == 0) + { + me = xmalloc (sizeof *me); + me->me_devname = xstrdup (mnt.mnt_special); + me->me_mountdir = xstrdup (mnt.mnt_mountp); + me->me_type = xstrdup (mnt.mnt_fstype); + me->me_type_malloced = 1; + me->me_dummy = MNT_IGNORE (&mnt) != 0; + me->me_remote = ME_REMOTE (me->me_devname, me->me_type); + me->me_dev = dev_from_mount_options (mnt.mnt_mntopts); + + /* Add to the linked list. */ + *mtail = me; + mtail = &me->me_next; + } + + ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1; + } + + if (0 <= lockfd && close (lockfd) != 0) + ret = errno; + + if (0 <= ret) + { + errno = ret; + goto free_then_fail; + } + } +#endif /* MOUNTED_GETMNTENT2. */ + +#ifdef MOUNTED_VMOUNT /* AIX. */ + { + int bufsize; + char *entries, *thisent; + struct vmount *vmp; + int n_entries; + int i; + + /* Ask how many bytes to allocate for the mounted file system info. */ + if (mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize) != 0) + return NULL; + entries = xmalloc (bufsize); + + /* Get the list of mounted file systems. */ + n_entries = mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries); + if (n_entries < 0) + { + int saved_errno = errno; + free (entries); + errno = saved_errno; + return NULL; + } + + for (i = 0, thisent = entries; + i < n_entries; + i++, thisent += vmp->vmt_length) + { + char *options, *ignore; + + vmp = (struct vmount *) thisent; + me = xmalloc (sizeof *me); + if (vmp->vmt_flags & MNT_REMOTE) + { + char *host, *dir; + + me->me_remote = 1; + /* Prepend the remote dirname. */ + host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off; + dir = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off; + me->me_devname = xmalloc (strlen (host) + strlen (dir) + 2); + strcpy (me->me_devname, host); + strcat (me->me_devname, ":"); + strcat (me->me_devname, dir); + } + else + { + me->me_remote = 0; + me->me_devname = xstrdup (thisent + + vmp->vmt_data[VMT_OBJECT].vmt_off); + } + me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off); + me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype)); + me->me_type_malloced = 1; + options = thisent + vmp->vmt_data[VMT_ARGS].vmt_off; + ignore = strstr (options, "ignore"); + me->me_dummy = (ignore + && (ignore == options || ignore[-1] == ',') + && (ignore[sizeof "ignore" - 1] == ',' + || ignore[sizeof "ignore" - 1] == '\0')); + me->me_dev = (dev_t) -1; /* vmt_fsid might be the info we want. */ + + /* Add to the linked list. */ + *mtail = me; + mtail = &me->me_next; + } + free (entries); + } +#endif /* MOUNTED_VMOUNT. */ + + *mtail = NULL; + return mount_list; + + + free_then_fail: + { + int saved_errno = errno; + *mtail = NULL; + + while (mount_list) + { + me = mount_list->me_next; + free (mount_list->me_devname); + free (mount_list->me_mountdir); + if (mount_list->me_type_malloced) + free (mount_list->me_type); + free (mount_list); + mount_list = me; + } + + errno = saved_errno; + return NULL; + } +} + +#endif + diff --git a/mountlist.h b/mountlist.h index 04ac3535..43a15b21 100644 --- a/mountlist.h +++ b/mountlist.h @@ -1,47 +1,47 @@ -/* mountlist.h -- declarations for list of mounted file systems - - Copyright (C) 1991, 1992, 1998, 2000, 2001, 2002, 2003, 2004, 2005 - Free Software Foundation, Inc. - - This program 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; either version 2, or (at your option) - any later version. - - This program 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 this program; if not, see . -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file mountlist.h -/// A function to enumerate the mounting points in the filesystem. -/// Used to display them in fileselectors. -////////////////////////////////////////////////////////////////////////////// - -#ifndef MOUNTLIST_H_ -# define MOUNTLIST_H_ - -# include -# include - -/* A mount table entry. */ -struct mount_entry -{ - char *me_devname; /* Device node name, including "/dev/". */ - char *me_mountdir; /* Mount point directory name. */ - char *me_type; /* "nfs", "4.2", etc. */ - dev_t me_dev; /* Device number of me_mountdir. */ - unsigned int me_dummy : 1; /* Nonzero for dummy file systems. */ - unsigned int me_remote : 1; /* Nonzero for remote fileystems. */ - unsigned int me_type_malloced : 1; /* Nonzero if me_type was malloced. */ - struct mount_entry *me_next; -}; - -struct mount_entry *read_file_system_list (bool need_fs_type); - -#endif +/* mountlist.h -- declarations for list of mounted file systems + + Copyright (C) 1991, 1992, 1998, 2000, 2001, 2002, 2003, 2004, 2005 + Free Software Foundation, Inc. + + This program 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; either version 2, or (at your option) + any later version. + + This program 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 this program; if not, see . +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file mountlist.h +/// A function to enumerate the mounting points in the filesystem. +/// Used to display them in fileselectors. +////////////////////////////////////////////////////////////////////////////// + +#ifndef MOUNTLIST_H_ +# define MOUNTLIST_H_ + +# include +# include + +/* A mount table entry. */ +struct mount_entry +{ + char *me_devname; /* Device node name, including "/dev/". */ + char *me_mountdir; /* Mount point directory name. */ + char *me_type; /* "nfs", "4.2", etc. */ + dev_t me_dev; /* Device number of me_mountdir. */ + unsigned int me_dummy : 1; /* Nonzero for dummy file systems. */ + unsigned int me_remote : 1; /* Nonzero for remote fileystems. */ + unsigned int me_type_malloced : 1; /* Nonzero if me_type was malloced. */ + struct mount_entry *me_next; +}; + +struct mount_entry *read_file_system_list (bool need_fs_type); + +#endif diff --git a/op_c.c b/op_c.c index 418ba8a6..6f62980e 100644 --- a/op_c.c +++ b/op_c.c @@ -1,1226 +1,1226 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - 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 -*/ -#include -#include -#include -#include -#include -#include -#include - -#include "op_c.h" -#include "errors.h" - -void RGB_to_HSL(int r,int g,int b,byte * hr,byte * sr,byte* lr) -{ - double rd,gd,bd,h,s,l,max,min; - - // convert RGB to HSV - rd = r / 255.0; // rd,gd,bd range 0-1 instead of 0-255 - gd = g / 255.0; - bd = b / 255.0; - - // compute L -// l=(rd*0.30)+(gd*0.59)+(bd*0.11); - - // compute maximum of rd,gd,bd - if (rd>=gd) - { - if (rd>=bd) - max = rd; - else - max = bd; - } - else - { - if (gd>=bd) - max = gd; - else - max = bd; - } - - // compute minimum of rd,gd,bd - if (rd<=gd) - { - if (rd<=bd) - min = rd; - else - min = bd; - } - else - { - if (gd<=bd) - min = gd; - else - min = bd; - } - - l = (max + min) / 2.0; - - if(max==min) - s = h = 0; - else - { - if (l<=0.5) - s = (max - min) / (max + min); - else - s = (max - min) / (2 - (max + min)); - - if (max == rd) - h = 42.5 * (gd-bd)/(max-min); - else if (max == gd) - h = 42.5 * (bd-rd)/(max-min)+85; - else - h = 42.5 * (rd-gd)/(max-min)+170; - if (h<0) h+=255; - } - - *hr = h; - *lr = (l*255.0); - *sr = (s*255.0); -} - -void HSL_to_RGB(byte h,byte s,byte l, byte* r, byte* g, byte* b) -{ - float rf =0 ,gf = 0,bf = 0; - float hf,lf,sf; - float p,q; - - if(s==0) - { - *r=*g=*b=l; - return; - } - - hf = h / 255.0; - lf = l / 255.0; - sf = s / 255.0; - - if (lf<=0.5) - q = lf*(1+sf); - else - q = lf+sf-lf*sf; - p = 2*lf-q; - - rf = hf + (1 / 3.0); - gf = hf; - bf = hf - (1 / 3.0); - - if (rf < 0) rf+=1; - if (rf > 1) rf-=1; - if (gf < 0) gf+=1; - if (gf > 1) gf-=1; - if (bf < 0) bf+=1; - if (bf > 1) bf-=1; - - if (rf < 1/6.0) - rf = p + ((q-p)*6*rf); - else if(rf < 0.5) - rf = q; - else if(rf < 2/3.0) - rf = p + ((q-p)*6*(2/3.0-rf)); - else - rf = p; - - if (gf < 1/6.0) - gf = p + ((q-p)*6*gf); - else if(gf < 0.5) - gf = q; - else if(gf < 2/3.0) - gf = p + ((q-p)*6*(2/3.0-gf)); - else - gf = p; - - if (bf < 1/6.0) - bf = p + ((q-p)*6*bf); - else if(bf < 0.5) - bf = q; - else if(bf < 2/3.0) - bf = p + ((q-p)*6*(2/3.0-bf)); - else - bf = p; - - *r = rf * (255); - *g = gf * (255); - *b = bf * (255); -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////// Méthodes de gestion des tables de conversion // -///////////////////////////////////////////////////////////////////////////// - -T_Conversion_table * CT_new(int nbb_r,int nbb_g,int nbb_b) -{ - T_Conversion_table * n; - int size; - - n=(T_Conversion_table *)malloc(sizeof(T_Conversion_table)); - if (n!=NULL) - { - // On recopie les paramŠtres demand‚s - n->nbb_r=nbb_r; - n->nbb_g=nbb_g; - n->nbb_b=nbb_b; - - // On calcule les autres - n->rng_r=(1<rng_g=(1<rng_b=(1<dec_r=nbb_g+nbb_b; - n->dec_g=nbb_b; - n->dec_b=0; - n->red_r=8-nbb_r; - n->red_g=8-nbb_g; - n->red_b=8-nbb_b; - - // On tente d'allouer la table - size=(n->rng_r)*(n->rng_g)*(n->rng_b); - n->table=(byte *)malloc(size); - if (n->table!=NULL) - // C'est bon! - memset(n->table,0,size); // Inutile, mais plus propre - else - { - // Table impossible … allouer - free(n); - n=NULL; - } - } - - return n; -} - -void CT_delete(T_Conversion_table * t) -{ - free(t->table); - free(t); -} - -byte CT_get(T_Conversion_table * t,int r,int g,int b) -{ - int index; - - // On réduit le nombre de bits par couleur - r=(r>>t->red_r); - g=(g>>t->red_g); - b=(b>>t->red_b); - - // On recherche la couleur la plus proche dans la table de conversion - index=(r<dec_r) | (g<dec_g) | (b<dec_b); - - return t->table[index]; -} - -void CT_set(T_Conversion_table * t,int r,int g,int b,byte i) -{ - int index; - - index=(r<dec_r) | (g<dec_g) | (b<dec_b); - t->table[index]=i; -} - - - -///////////////////////////////////////////////////////////////////////////// -/////////////////////////////// M‚thodes de gestion des tables d'occurence // -///////////////////////////////////////////////////////////////////////////// - -void OT_init(T_Occurrence_table * t) -{ - int size; - - size=(t->rng_r)*(t->rng_g)*(t->rng_b)*sizeof(int); - memset(t->table,0,size); // On initialise … 0 -} - -T_Occurrence_table * OT_new(int nbb_r,int nbb_g,int nbb_b) -{ - T_Occurrence_table * n; - int size; - - n=(T_Occurrence_table *)malloc(sizeof(T_Occurrence_table)); - if (n!=0) - { - // On recopie les paramŠtres demand‚s - n->nbb_r=nbb_r; - n->nbb_g=nbb_g; - n->nbb_b=nbb_b; - - // On calcule les autres - n->rng_r=(1<rng_g=(1<rng_b=(1<dec_r=nbb_g+nbb_b; - n->dec_g=nbb_b; - n->dec_b=0; - n->red_r=8-nbb_r; - n->red_g=8-nbb_g; - n->red_b=8-nbb_b; - - // On tente d'allouer la table - size=(n->rng_r)*(n->rng_g)*(n->rng_b)*sizeof(int); - n->table=(int *)malloc(size); - if (n->table!=0) - // C'est bon! On initialise … 0 - OT_init(n); - else - { - // Table impossible … allouer - free(n); - n=0; - } - } - - return n; -} - -void OT_delete(T_Occurrence_table * t) -{ - free(t->table); - free(t); -} - -int OT_get(T_Occurrence_table * t,int r,int g,int b) -{ - int index; - - index=(r<dec_r) | (g<dec_g) | (b<dec_b); - return t->table[index]; -} - -void OT_inc(T_Occurrence_table * t,int r,int g,int b) -{ - int index; - - r=(r>>t->red_r); - g=(g>>t->red_g); - b=(b>>t->red_b); - index=(r<dec_r) | (g<dec_g) | (b<dec_b); - t->table[index]++; -} - -void OT_count_occurrences(T_Occurrence_table * t,T_Bitmap24B image,int size) -{ - T_Bitmap24B ptr; - int index; - - for (index=size,ptr=image;index>0;index--,ptr++) - OT_inc(t,ptr->R,ptr->G,ptr->B); -} - -int OT_count_colors(T_Occurrence_table * t) -{ - int val; // Valeur de retour - int nb; // Nombre de couleurs … tester - int i; // Compteur de couleurs test‚es - - val=0; - nb=(t->rng_r)*(t->rng_g)*(t->rng_b); - for (i=0;itable[i]>0) - val++; - - return val; -} - - - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////// M‚thodes de gestion des clusters // -///////////////////////////////////////////////////////////////////////////// - -void Cluster_analyser(T_Cluster * c,T_Occurrence_table * to) -{ - int rmin,rmax,vmin,vmax,bmin,bmax; - int r,g,b; - - // On cherche les mins et les maxs de chaque composante sur la couverture - - // int nbocc; - - // On prédécale tout pour éviter de faire trop de bazar en se forçant à utiliser OT_get, plus rapide - rmin=c->rmax <<16; rmax=c->rmin << 16; - vmin=c->vmax << 8; vmax=c->vmin << 8; - bmin=c->bmax; bmax=c->bmin; - c->occurences=0; - /* - for (r=c->rmin<<16;r<=c->rmax<<16;r+=1<<16) - for (g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) - for (b=c->bmin;b<=c->bmax;b++) - { - nbocc=to->table[r + g + b]; // OT_get - if (nbocc) - { - if (rrmax) rmax=r; - if (gvmax) vmax=g; - if (bbmax) bmax=b; - c->occurences+=nbocc; - } - } - */ - - // On recherche le minimum et le maximum en parcourant le cluster selon chaque composante, - // ça évite des accès mémoires inutiles, de plus chaque boucle est plus petite que la - // précédente puisqu'on connait une borne supplémentaire - - for(r=c->rmin<<16;r<=c->rmax<<16;r+=1<<16) - for(g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) - for(b=c->bmin;b<=c->bmax;b++) - { - if(to->table[r + g + b]) // OT_get - { - rmin=r; - goto RMAX; - } - } -RMAX: - for(r=c->rmax<<16;r>=rmin;r-=1<<16) - for(g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) - for(b=c->bmin;b<=c->bmax;b++) - { - if(to->table[r + g + b]) // OT_get - { - rmax=r; - goto VMIN; - } - } -VMIN: - for(g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) - for(r=rmin;r<=rmax;r+=1<<16) - for(b=c->bmin;b<=c->bmax;b++) - { - if(to->table[r + g + b]) // OT_get - { - vmin=g; - goto VMAX; - } - } -VMAX: - for(g=c->vmax<<8;g>=vmin;g-=1<<8) - for(r=rmin;r<=rmax;r+=1<<16) - for(b=c->bmin;b<=c->bmax;b++) - { - if(to->table[r + g + b]) // OT_get - { - vmax=g; - goto BMIN; - } - } -BMIN: - for(b=c->bmin;b<=c->bmax;b++) - for(r=rmin;r<=rmax;r+=1<<16) - for(g=vmin;g<=vmax;g+=1<<8) - { - if(to->table[r + g + b]) // OT_get - { - bmin=b; - goto BMAX; - } - } -BMAX: - for(b=c->bmax;b>=bmin;b--) - for(r=rmin;r<=rmax;r+=1<<16) - for(g=vmin;g<=vmax;g+=1<<8) - { - if(to->table[r + g + b]) // OT_get - { - bmax=b; - goto ENDCRUSH; - } - } -ENDCRUSH: - // Il faut quand même parcourir la partie utile du cluster, pour savoir combien il y a d'occurences - for(r=rmin;r<=rmax;r+=1<<16) - for(g=vmin;g<=vmax;g+=1<<8) - for(b=bmin;b<=bmax;b++) - { - c->occurences+=to->table[r + g + b]; // OT_get - } - - c->rmin=rmin>>16; c->rmax=rmax>>16; - c->vmin=vmin>>8; c->vmax=vmax>>8; - c->bmin=bmin; c->bmax=bmax; - - // On regarde la composante qui a la variation la plus grande - r=(c->rmax-c->rmin)*299; - g=(c->vmax-c->vmin)*587; - b=(c->bmax-c->bmin)*114; - - if (g>=r) - { - // G>=R - if (g>=b) - { - // G>=R et G>=B - c->plus_large=1; - } - else - { - // G>=R et Gplus_large=2; - } - } - else - { - // R>G - if (r>=b) - { - // R>G et R>=B - c->plus_large=0; - } - else - { - // R>G et Rplus_large=2; - } - } -} - -void Cluster_split(T_Cluster * c,T_Cluster * c1,T_Cluster * c2,int hue,T_Occurrence_table * to) -{ - int limit; - int cumul; - int r,g,b; - - limit=(c->occurences)/2; - cumul=0; - if (hue==0) - { - for (r=c->rmin<<16;r<=c->rmax<<16;r+=1<<16) - { - for (g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) - { - for (b=c->bmin;b<=c->bmax;b++) - { - cumul+=to->table[r + g + b]; - if (cumul>=limit) - break; - } - if (cumul>=limit) - break; - } - if (cumul>=limit) - break; - } - - r>>=16; - g>>=8; - - if (r==c->rmin) - r++; - // R est la valeur de d‚but du 2nd cluster - - c1->Rmin=c->Rmin; c1->Rmax=r-1; - c1->rmin=c->rmin; c1->rmax=r-1; - c1->Gmin=c->Gmin; c1->Vmax=c->Vmax; - c1->vmin=c->vmin; c1->vmax=c->vmax; - c1->Bmin=c->Bmin; c1->Bmax=c->Bmax; - c1->bmin=c->bmin; c1->bmax=c->bmax; - c2->Rmin=r; c2->Rmax=c->Rmax; - c2->rmin=r; c2->rmax=c->rmax; - c2->Gmin=c->Gmin; c2->Vmax=c->Vmax; - c2->vmin=c->vmin; c2->vmax=c->vmax; - c2->Bmin=c->Bmin; c2->Bmax=c->Bmax; - c2->bmin=c->bmin; c2->bmax=c->bmax; - } - else - if (hue==1) - { - - for (g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) - { - for (r=c->rmin<<16;r<=c->rmax<<16;r+=1<<16) - { - for (b=c->bmin;b<=c->bmax;b++) - { - cumul+=to->table[r + g + b]; - if (cumul>=limit) - break; - } - if (cumul>=limit) - break; - } - if (cumul>=limit) - break; - } - - r>>=16; g>>=8; - - if (g==c->vmin) - g++; - // G est la valeur de d‚but du 2nd cluster - - c1->Rmin=c->Rmin; c1->Rmax=c->Rmax; - c1->rmin=c->rmin; c1->rmax=c->rmax; - c1->Gmin=c->Gmin; c1->Vmax=g-1; - c1->vmin=c->vmin; c1->vmax=g-1; - c1->Bmin=c->Bmin; c1->Bmax=c->Bmax; - c1->bmin=c->bmin; c1->bmax=c->bmax; - c2->Rmin=c->Rmin; c2->Rmax=c->Rmax; - c2->rmin=c->rmin; c2->rmax=c->rmax; - c2->Gmin=g; c2->Vmax=c->Vmax; - c2->vmin=g; c2->vmax=c->vmax; - c2->Bmin=c->Bmin; c2->Bmax=c->Bmax; - c2->bmin=c->bmin; c2->bmax=c->bmax; - } - else - { - - for (b=c->bmin;b<=c->bmax;b++) - { - for (g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) - { - for (r=c->rmin<<16;r<=c->rmax<<16;r+=1<<16) - { - cumul+=to->table[r + g + b]; - if (cumul>=limit) - break; - } - if (cumul>=limit) - break; - } - if (cumul>=limit) - break; - } - - r>>=16; g>>=8; - - if (b==c->bmin) - b++; - // B est la valeur de d‚but du 2nd cluster - - c1->Rmin=c->Rmin; c1->Rmax=c->Rmax; - c1->rmin=c->rmin; c1->rmax=c->rmax; - c1->Gmin=c->Gmin; c1->Vmax=c->Vmax; - c1->vmin=c->vmin; c1->vmax=c->vmax; - c1->Bmin=c->Bmin; c1->Bmax=b-1; - c1->bmin=c->bmin; c1->bmax=b-1; - c2->Rmin=c->Rmin; c2->Rmax=c->Rmax; - c2->rmin=c->rmin; c2->rmax=c->rmax; - c2->Gmin=c->Gmin; c2->Vmax=c->Vmax; - c2->vmin=c->vmin; c2->vmax=c->vmax; - c2->Bmin=b; c2->Bmax=c->Bmax; - c2->bmin=b; c2->bmax=c->bmax; - } -} - -void Cluster_compute_hue(T_Cluster * c,T_Occurrence_table * to) -{ - int cumul_r,cumul_g,cumul_b; - int r,g,b; - int nbocc; - - byte s=0; - - cumul_r=cumul_g=cumul_b=0; - for (r=c->rmin;r<=c->rmax;r++) - for (g=c->vmin;g<=c->vmax;g++) - for (b=c->bmin;b<=c->bmax;b++) - { - nbocc=OT_get(to,r,g,b); - if (nbocc) - { - cumul_r+=r*nbocc; - cumul_g+=g*nbocc; - cumul_b+=b*nbocc; - } - } - - c->r=(cumul_r<red_r)/c->occurences; - c->g=(cumul_g<red_g)/c->occurences; - c->b=(cumul_b<red_b)/c->occurences; - RGB_to_HSL(c->r,c->g,c->b,&c->h,&s,&c->l); -} - - - -///////////////////////////////////////////////////////////////////////////// -//////////////////////////// M‚thodes de gestion des ensembles de clusters // -///////////////////////////////////////////////////////////////////////////// - -/// Setup the first cluster before we start the operations -void CS_Init(T_Cluster_set * cs,T_Occurrence_table * to) -{ - cs->clusters->Rmin = cs->clusters->rmin = 0; - cs->clusters->Gmin = cs->clusters->vmin = 0; - cs->clusters->Bmin = cs->clusters->bmin = 0; - cs->clusters->Rmax = cs->clusters->rmax = to->rng_r-1; - cs->clusters->Vmax = cs->clusters->vmax = to->rng_g-1; - cs->clusters->Bmax = cs->clusters->bmax = to->rng_b-1; - cs->clusters->next = NULL; - Cluster_analyser(cs->clusters,to); - cs->nb=1; -} - -/// Allocate a new cluster set -T_Cluster_set * CS_New(int nbmax,T_Occurrence_table * to) -{ - T_Cluster_set * n; - - n=(T_Cluster_set *)malloc(sizeof(T_Cluster_set)); - if (n != NULL) - { - // On recopie les paramŠtres demand‚s - n->nb_max=OT_count_colors(to); - - // On vient de compter le nombre de couleurs existantes, s'il est plus grand que 256 on limite à 256 - // (nombre de couleurs voulu au final) - if (n->nb_max>nbmax) - { - n->nb_max=nbmax; - } - - // On tente d'allouer le premier cluster - n->clusters=(T_Cluster *)malloc(sizeof(T_Cluster)); - if (n->clusters!=NULL) - // C'est bon! On initialise - CS_Init(n,to); - else - { - // Table impossible … allouer - free(n); - n=0; - } - } - - return n; -} - -/// Free a cluster set -void CS_Delete(T_Cluster_set * cs) -{ - T_Cluster* nxt; - while(cs->clusters != NULL) - { - nxt = cs->clusters->next; - free(cs->clusters); - cs->clusters = nxt; - } - free(cs); -} - -void CS_Get(T_Cluster_set * cs,T_Cluster * c) -{ - T_Cluster* current = cs->clusters; - T_Cluster* prev = NULL; - - // Search a cluster with at least 2 distinct colors so we can split it - do - { - if ( (current->rmin < current->rmax) || - (current->vmin < current->vmax) || - (current->bmin < current->bmax) ) - break; - - prev = current; - - } while((current = current -> next)); - - // copy it to c - *c = *current; - - // remove it from the list - cs->nb--; - - if(prev) - prev->next = current->next; - else - cs->clusters = current->next; - free(current); - current = NULL; -} - -void CS_Set(T_Cluster_set * cs,T_Cluster * c) -{ - T_Cluster* current = cs->clusters; - T_Cluster* prev = NULL; - - // Search the first cluster that is smaller than ours - if(current != NULL) // don't search if the list is empty - do - { - if (current->occurences < c->occurences) - break; - prev = current; - } while((current = current -> next)); - - // Now insert our cluster just before the one we found - c -> next = current; - - current = malloc(sizeof(T_Cluster)); - *current = *c ; - - if(prev) prev -> next = current; - else cs->clusters = current; - - cs -> nb++; -} - -// Détermination de la meilleure palette en utilisant l'algo Median Cut : -// 1) On considère l'espace (R,G,B) comme 1 boîte -// 2) On cherche les extrêmes de la boîte en (R,G,B) -// 3) On trie les pixels de l'image selon l'axe le plus long parmi (R,G,B) -// 4) On coupe la boîte en deux au milieu, et on compacte pour que chaque bord corresponde bien à un pixel extreme -// 5) On recommence à couper selon le plus grand axe toutes boîtes confondues -// 6) On s'arrête quand on a le nombre de couleurs voulu -void CS_Generate(T_Cluster_set * cs,T_Occurrence_table * to) -{ - T_Cluster current; - T_Cluster Nouveau1; - T_Cluster Nouveau2; - - // Tant qu'on a moins de 256 clusters - while (cs->nbnb_max) - { - // On récupère le plus grand cluster - CS_Get(cs,¤t); - - // On le coupe en deux - Cluster_split(¤t,&Nouveau1,&Nouveau2,current.plus_large,to); - - // On compacte ces deux nouveaux (il peut y avoir un espace entre l'endroit de la coupure et les premiers pixels du cluster) - Cluster_analyser(&Nouveau1,to); - Cluster_analyser(&Nouveau2,to); - - // On met ces deux nouveaux clusters dans le clusterSet... sauf s'ils sont vides - if(Nouveau1.occurences>0) - CS_Set(cs,&Nouveau1); - if(Nouveau2.occurences>0) - CS_Set(cs,&Nouveau2); - } -} - -void CS_Compute_colors(T_Cluster_set * cs,T_Occurrence_table * to) -{ - T_Cluster * c; - - for (c=cs->clusters;c!=NULL;c=c->next) - Cluster_compute_hue(c,to); -} - -void CS_Sort_by_chrominance(T_Cluster_set * cs) -{ - T_Cluster* nc; - T_Cluster* prev = NULL; - T_Cluster* place; - T_Cluster* newlist = NULL; - - while((nc = cs->clusters)) - { - // Remove the first cluster from the original list - nc = cs->clusters; - cs->clusters = cs->clusters->next; - - // Find his position in the new list - for(place = newlist;place != NULL; place = place->next) - { - if(place->h > nc->h) break; - prev = place; - } - - // Chain it there - nc->next = place; - if(prev) prev->next = nc; - else newlist = nc; - - } - - // Put the new list bavk in place - cs->clusters = newlist; -} - -void CS_Sort_by_luminance(T_Cluster_set * cs) -{ - T_Cluster* nc; - T_Cluster* prev = NULL; - T_Cluster* place; - T_Cluster* newlist = NULL; - - while((nc = cs->clusters)) - { - // Remove the first cluster from the original list - nc = cs->clusters; - cs->clusters = cs->clusters->next; - - // Find his position in the new list - for(place = newlist;place != NULL; place = place->next) - { - if(place->l > nc->l) break; - prev = place; - } - - // Chain it there - nc->next = place; - if(prev) prev->next = nc; - else newlist = nc; - - } - - // Put the new list bavk in place - cs->clusters = newlist; -} - -void CS_Generate_color_table_and_palette(T_Cluster_set * cs,T_Conversion_table * tc,T_Components * palette) -{ - int index; - int r,g,b; - T_Cluster* current = cs->clusters; - - for (index=0;indexnb;index++) - { - palette[index].R=current->r; - palette[index].G=current->g; - palette[index].B=current->b; - - for (r=current->Rmin; r<=current->Rmax; r++) - for (g=current->Gmin;g<=current->Vmax;g++) - for (b=current->Bmin;b<=current->Bmax;b++) - CT_set(tc,r,g,b,index); - current = current->next; - } -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////// Méthodes de gestion des dégradés // -///////////////////////////////////////////////////////////////////////////// - -void GS_Init(T_Gradient_set * ds,T_Cluster_set * cs) -{ - ds->gradients[0].nb_colors=1; - ds->gradients[0].min=cs->clusters->h; - ds->gradients[0].max=cs->clusters->h; - ds->gradients[0].hue=cs->clusters->h; - // Et hop : le 1er ensemble de d‚grad‚s est initialis‚ - ds->nb=1; -} - -T_Gradient_set * GS_New(T_Cluster_set * cs) -{ - T_Gradient_set * n; - - n=(T_Gradient_set *)malloc(sizeof(T_Gradient_set)); - if (n!=NULL) - { - // On recopie les paramŠtres demand‚s - n->nb_max=cs->nb_max; - - // On tente d'allouer la table - n->gradients=(T_Gradient *)malloc((n->nb_max)*sizeof(T_Gradient)); - if (n->gradients!=0) - // C'est bon! On initialise - GS_Init(n,cs); - else - { - // Table impossible … allouer - free(n); - n=0; - } - } - - return n; -} - -void GS_Delete(T_Gradient_set * ds) -{ - free(ds->gradients); - free(ds); -} - -void GS_Generate(T_Gradient_set * ds,T_Cluster_set * cs) -{ - int id; // Les indexs de parcours des ensembles - int best_gradient; // Meilleur d‚grad‚ - int best_diff; // Meilleure diff‚rence de chrominance - int diff; // difference de chrominance courante - T_Cluster * current = cs->clusters; - - // Pour chacun des clusters … traiter - do - { - // On recherche le d‚grad‚ le plus proche de la chrominance du cluster - best_gradient=-1; - best_diff=99999999; - for (id=0;idnb;id++) - { - diff=abs(current->h - ds->gradients[id].hue); - if ((best_diff>diff) && (diff<16)) - { - best_gradient=id; - best_diff=diff; - } - } - - // Si on a trouv‚ un d‚grad‚ dans lequel inclure le cluster - if (best_gradient!=-1) - { - // On met … jour le d‚grad‚ - if (current->h < ds->gradients[best_gradient].min) - ds->gradients[best_gradient].min=current->h; - if (current->h > ds->gradients[best_gradient].max) - ds->gradients[best_gradient].max=current->h; - ds->gradients[best_gradient].hue=((ds->gradients[best_gradient].hue* - ds->gradients[best_gradient].nb_colors) - +current->h) - /(ds->gradients[best_gradient].nb_colors+1); - ds->gradients[best_gradient].nb_colors++; - } - else - { - // On cr‚e un nouveau d‚grad‚ - best_gradient=ds->nb; - ds->gradients[best_gradient].nb_colors=1; - ds->gradients[best_gradient].min=current->h; - ds->gradients[best_gradient].max=current->h; - ds->gradients[best_gradient].hue=current->h; - ds->nb++; - } - current->h=best_gradient; - } while((current = current->next)); - - // On redistribue les valeurs dans les clusters - current = cs -> clusters; - do - current->h=ds->gradients[current->h].hue; - while((current = current ->next)); -} - - - - -T_Conversion_table * Optimize_palette(T_Bitmap24B image,int size,T_Components * palette,int r,int g,int b) -{ - T_Occurrence_table * to; - T_Conversion_table * tc; - T_Cluster_set * cs; - T_Gradient_set * ds; - - // Création des éléments nécessaires au calcul de palette optimisée: - to=0; tc=0; cs=0; ds=0; - - to=OT_new(r,g,b); - if (to!=0) - { - tc=CT_new(r,g,b); - if (tc!=0) - { - - // Première étape : on compte les pixels de chaque couleur pour pouvoir trier là dessus - OT_count_occurrences(to,image,size); - - cs=CS_New(256,to); - if (cs!=0) - { - // C'est bon, on a pu tout allouer - - // On génère les clusters (avec l'algo du median cut) - CS_Generate(cs,to); - - // On calcule la teinte de chaque pixel (Luminance et chrominance) - CS_Compute_colors(cs,to); - - ds=GS_New(cs); - if (ds!=0) - { - GS_Generate(ds,cs); - GS_Delete(ds); - } - - // Enfin on trie les clusters (donc les couleurs de la palette) dans un ordre sympa : par couleur, et par luminosité pour chaque couleur - CS_Sort_by_luminance(cs); - CS_Sort_by_chrominance(cs); - - // Enfin on génère la palette et la table de correspondance entre chaque couleur 24b et sa couleur palette associée. - CS_Generate_color_table_and_palette(cs,tc,palette); - - CS_Delete(cs); - OT_delete(to); - return tc; - } - CT_delete(tc); - } - OT_delete(to); - } - // Si on arrive ici c'est que l'allocation n'a pas réussi, - // l'appelant devra recommencer avec une précision plus faible (3 derniers paramètres) - return 0; -} - -int Modified_value(int value,int modif) -{ - value+=modif; - if (value<0) - { - value=0; - } - else if (value>255) - { - value=255; - } - return value; -} - -void Convert_24b_bitmap_to_256_Floyd_Steinberg(T_Bitmap256 dest,T_Bitmap24B source,int width,int height,T_Components * palette,T_Conversion_table * tc) -// Cette fonction dégrade au fur et à mesure le bitmap source, donc soit on ne -// s'en ressert pas, soit on passe à la fonction une copie de travail du -// bitmap original. -{ - T_Bitmap24B current; - T_Bitmap24B c_plus1; - T_Bitmap24B u_minus1; - T_Bitmap24B next; - T_Bitmap24B u_plus1; - T_Bitmap256 d; - int x_pos,y_pos; - int red,green,blue; - float e_red,e_green,e_blue; - - // On initialise les variables de parcours: - current =source; // Le pixel dont on s'occupe - next =current+width; // Le pixel en dessous - c_plus1 =current+1; // Le pixel à droite - u_minus1=next-1; // Le pixel en bas à gauche - u_plus1 =next+1; // Le pixel en bas à droite - d =dest; - - // On parcours chaque pixel: - for (y_pos=0;y_posR; - green =current->G; - blue =current->B; - // Cherche la couleur correspondant dans la palette et la range dans l'image de destination - *d=CT_get(tc,red,green,blue); - - // Puis on calcule pour chaque composante l'erreur dûe à l'approximation - red-=palette[*d].R; - green -=palette[*d].G; - blue -=palette[*d].B; - - // Et dans chaque pixel voisin on propage l'erreur - // A droite: - e_red=(red*7)/16.0; - e_green =(green *7)/16.0; - e_blue =(blue *7)/16.0; - if (x_pos+1R=Modified_value(c_plus1->R,e_red); - c_plus1->G=Modified_value(c_plus1->G,e_green ); - c_plus1->B=Modified_value(c_plus1->B,e_blue ); - } - // En bas à gauche: - if (y_pos+10) - { - u_minus1->R=Modified_value(u_minus1->R,e_red); - u_minus1->G=Modified_value(u_minus1->G,e_green ); - u_minus1->B=Modified_value(u_minus1->B,e_blue ); - } - // En bas: - e_red=(red*5/16.0); - e_green =(green*5 /16.0); - e_blue =(blue*5 /16.0); - next->R=Modified_value(next->R,e_red); - next->G=Modified_value(next->G,e_green ); - next->B=Modified_value(next->B,e_blue ); - // En bas à droite: - if (x_pos+1R=Modified_value(u_plus1->R,e_red); - u_plus1->G=Modified_value(u_plus1->G,e_green ); - u_plus1->B=Modified_value(u_plus1->B,e_blue ); - } - } - - // On passe au pixel suivant : - current++; - c_plus1++; - u_minus1++; - next++; - u_plus1++; - d++; - } - } - -} - - - -static const byte precision_24b[]= -{ - 8,8,8, - 6,6,6, - 6,6,5, - 5,6,5, - 5,5,5, - 5,5,4, - 4,5,4, - 4,4,4, - 4,4,3, - 3,4,3, - 3,3,3, - 3,3,2}; - - -// Convertie avec le plus de précision possible une image 24b en 256c -// Renvoie s'il y a eu une erreur ou pas.. - -// Cette fonction utilise l'algorithme "median cut" (Optimize_palette) pour trouver la palette, et diffuse les erreurs avec floyd-steinberg. - -int Convert_24b_bitmap_to_256(T_Bitmap256 dest,T_Bitmap24B source,int width,int height,T_Components * palette) -{ - T_Conversion_table * table; // table de conversion - int ip; // index de précision pour la conversion - - // On essaye d'obtenir une table de conversion qui loge en mémoire, avec la - // meilleure précision possible - for (ip=0;ip<(10*3);ip+=3) - { - table=Optimize_palette(source,width*height,palette,precision_24b[ip+0], - precision_24b[ip+1],precision_24b[ip+2]); - if (table!=0) - break; - } - - if (table!=0) - { - Convert_24b_bitmap_to_256_Floyd_Steinberg(dest,source,width,height,palette,table); - CT_delete(table); - return 0; - } - else - return 1; -} - - - +/* Grafx2 - The Ultimate 256-color bitmap paint program + + 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 +*/ +#include +#include +#include +#include +#include +#include +#include + +#include "op_c.h" +#include "errors.h" + +void RGB_to_HSL(int r,int g,int b,byte * hr,byte * sr,byte* lr) +{ + double rd,gd,bd,h,s,l,max,min; + + // convert RGB to HSV + rd = r / 255.0; // rd,gd,bd range 0-1 instead of 0-255 + gd = g / 255.0; + bd = b / 255.0; + + // compute L +// l=(rd*0.30)+(gd*0.59)+(bd*0.11); + + // compute maximum of rd,gd,bd + if (rd>=gd) + { + if (rd>=bd) + max = rd; + else + max = bd; + } + else + { + if (gd>=bd) + max = gd; + else + max = bd; + } + + // compute minimum of rd,gd,bd + if (rd<=gd) + { + if (rd<=bd) + min = rd; + else + min = bd; + } + else + { + if (gd<=bd) + min = gd; + else + min = bd; + } + + l = (max + min) / 2.0; + + if(max==min) + s = h = 0; + else + { + if (l<=0.5) + s = (max - min) / (max + min); + else + s = (max - min) / (2 - (max + min)); + + if (max == rd) + h = 42.5 * (gd-bd)/(max-min); + else if (max == gd) + h = 42.5 * (bd-rd)/(max-min)+85; + else + h = 42.5 * (rd-gd)/(max-min)+170; + if (h<0) h+=255; + } + + *hr = h; + *lr = (l*255.0); + *sr = (s*255.0); +} + +void HSL_to_RGB(byte h,byte s,byte l, byte* r, byte* g, byte* b) +{ + float rf =0 ,gf = 0,bf = 0; + float hf,lf,sf; + float p,q; + + if(s==0) + { + *r=*g=*b=l; + return; + } + + hf = h / 255.0; + lf = l / 255.0; + sf = s / 255.0; + + if (lf<=0.5) + q = lf*(1+sf); + else + q = lf+sf-lf*sf; + p = 2*lf-q; + + rf = hf + (1 / 3.0); + gf = hf; + bf = hf - (1 / 3.0); + + if (rf < 0) rf+=1; + if (rf > 1) rf-=1; + if (gf < 0) gf+=1; + if (gf > 1) gf-=1; + if (bf < 0) bf+=1; + if (bf > 1) bf-=1; + + if (rf < 1/6.0) + rf = p + ((q-p)*6*rf); + else if(rf < 0.5) + rf = q; + else if(rf < 2/3.0) + rf = p + ((q-p)*6*(2/3.0-rf)); + else + rf = p; + + if (gf < 1/6.0) + gf = p + ((q-p)*6*gf); + else if(gf < 0.5) + gf = q; + else if(gf < 2/3.0) + gf = p + ((q-p)*6*(2/3.0-gf)); + else + gf = p; + + if (bf < 1/6.0) + bf = p + ((q-p)*6*bf); + else if(bf < 0.5) + bf = q; + else if(bf < 2/3.0) + bf = p + ((q-p)*6*(2/3.0-bf)); + else + bf = p; + + *r = rf * (255); + *g = gf * (255); + *b = bf * (255); +} + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////// Méthodes de gestion des tables de conversion // +///////////////////////////////////////////////////////////////////////////// + +T_Conversion_table * CT_new(int nbb_r,int nbb_g,int nbb_b) +{ + T_Conversion_table * n; + int size; + + n=(T_Conversion_table *)malloc(sizeof(T_Conversion_table)); + if (n!=NULL) + { + // On recopie les paramŠtres demand‚s + n->nbb_r=nbb_r; + n->nbb_g=nbb_g; + n->nbb_b=nbb_b; + + // On calcule les autres + n->rng_r=(1<rng_g=(1<rng_b=(1<dec_r=nbb_g+nbb_b; + n->dec_g=nbb_b; + n->dec_b=0; + n->red_r=8-nbb_r; + n->red_g=8-nbb_g; + n->red_b=8-nbb_b; + + // On tente d'allouer la table + size=(n->rng_r)*(n->rng_g)*(n->rng_b); + n->table=(byte *)malloc(size); + if (n->table!=NULL) + // C'est bon! + memset(n->table,0,size); // Inutile, mais plus propre + else + { + // Table impossible … allouer + free(n); + n=NULL; + } + } + + return n; +} + +void CT_delete(T_Conversion_table * t) +{ + free(t->table); + free(t); +} + +byte CT_get(T_Conversion_table * t,int r,int g,int b) +{ + int index; + + // On réduit le nombre de bits par couleur + r=(r>>t->red_r); + g=(g>>t->red_g); + b=(b>>t->red_b); + + // On recherche la couleur la plus proche dans la table de conversion + index=(r<dec_r) | (g<dec_g) | (b<dec_b); + + return t->table[index]; +} + +void CT_set(T_Conversion_table * t,int r,int g,int b,byte i) +{ + int index; + + index=(r<dec_r) | (g<dec_g) | (b<dec_b); + t->table[index]=i; +} + + + +///////////////////////////////////////////////////////////////////////////// +/////////////////////////////// M‚thodes de gestion des tables d'occurence // +///////////////////////////////////////////////////////////////////////////// + +void OT_init(T_Occurrence_table * t) +{ + int size; + + size=(t->rng_r)*(t->rng_g)*(t->rng_b)*sizeof(int); + memset(t->table,0,size); // On initialise … 0 +} + +T_Occurrence_table * OT_new(int nbb_r,int nbb_g,int nbb_b) +{ + T_Occurrence_table * n; + int size; + + n=(T_Occurrence_table *)malloc(sizeof(T_Occurrence_table)); + if (n!=0) + { + // On recopie les paramŠtres demand‚s + n->nbb_r=nbb_r; + n->nbb_g=nbb_g; + n->nbb_b=nbb_b; + + // On calcule les autres + n->rng_r=(1<rng_g=(1<rng_b=(1<dec_r=nbb_g+nbb_b; + n->dec_g=nbb_b; + n->dec_b=0; + n->red_r=8-nbb_r; + n->red_g=8-nbb_g; + n->red_b=8-nbb_b; + + // On tente d'allouer la table + size=(n->rng_r)*(n->rng_g)*(n->rng_b)*sizeof(int); + n->table=(int *)malloc(size); + if (n->table!=0) + // C'est bon! On initialise … 0 + OT_init(n); + else + { + // Table impossible … allouer + free(n); + n=0; + } + } + + return n; +} + +void OT_delete(T_Occurrence_table * t) +{ + free(t->table); + free(t); +} + +int OT_get(T_Occurrence_table * t,int r,int g,int b) +{ + int index; + + index=(r<dec_r) | (g<dec_g) | (b<dec_b); + return t->table[index]; +} + +void OT_inc(T_Occurrence_table * t,int r,int g,int b) +{ + int index; + + r=(r>>t->red_r); + g=(g>>t->red_g); + b=(b>>t->red_b); + index=(r<dec_r) | (g<dec_g) | (b<dec_b); + t->table[index]++; +} + +void OT_count_occurrences(T_Occurrence_table * t,T_Bitmap24B image,int size) +{ + T_Bitmap24B ptr; + int index; + + for (index=size,ptr=image;index>0;index--,ptr++) + OT_inc(t,ptr->R,ptr->G,ptr->B); +} + +int OT_count_colors(T_Occurrence_table * t) +{ + int val; // Valeur de retour + int nb; // Nombre de couleurs … tester + int i; // Compteur de couleurs test‚es + + val=0; + nb=(t->rng_r)*(t->rng_g)*(t->rng_b); + for (i=0;itable[i]>0) + val++; + + return val; +} + + + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////// M‚thodes de gestion des clusters // +///////////////////////////////////////////////////////////////////////////// + +void Cluster_analyser(T_Cluster * c,T_Occurrence_table * to) +{ + int rmin,rmax,vmin,vmax,bmin,bmax; + int r,g,b; + + // On cherche les mins et les maxs de chaque composante sur la couverture + + // int nbocc; + + // On prédécale tout pour éviter de faire trop de bazar en se forçant à utiliser OT_get, plus rapide + rmin=c->rmax <<16; rmax=c->rmin << 16; + vmin=c->vmax << 8; vmax=c->vmin << 8; + bmin=c->bmax; bmax=c->bmin; + c->occurences=0; + /* + for (r=c->rmin<<16;r<=c->rmax<<16;r+=1<<16) + for (g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) + for (b=c->bmin;b<=c->bmax;b++) + { + nbocc=to->table[r + g + b]; // OT_get + if (nbocc) + { + if (rrmax) rmax=r; + if (gvmax) vmax=g; + if (bbmax) bmax=b; + c->occurences+=nbocc; + } + } + */ + + // On recherche le minimum et le maximum en parcourant le cluster selon chaque composante, + // ça évite des accès mémoires inutiles, de plus chaque boucle est plus petite que la + // précédente puisqu'on connait une borne supplémentaire + + for(r=c->rmin<<16;r<=c->rmax<<16;r+=1<<16) + for(g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) + for(b=c->bmin;b<=c->bmax;b++) + { + if(to->table[r + g + b]) // OT_get + { + rmin=r; + goto RMAX; + } + } +RMAX: + for(r=c->rmax<<16;r>=rmin;r-=1<<16) + for(g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) + for(b=c->bmin;b<=c->bmax;b++) + { + if(to->table[r + g + b]) // OT_get + { + rmax=r; + goto VMIN; + } + } +VMIN: + for(g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) + for(r=rmin;r<=rmax;r+=1<<16) + for(b=c->bmin;b<=c->bmax;b++) + { + if(to->table[r + g + b]) // OT_get + { + vmin=g; + goto VMAX; + } + } +VMAX: + for(g=c->vmax<<8;g>=vmin;g-=1<<8) + for(r=rmin;r<=rmax;r+=1<<16) + for(b=c->bmin;b<=c->bmax;b++) + { + if(to->table[r + g + b]) // OT_get + { + vmax=g; + goto BMIN; + } + } +BMIN: + for(b=c->bmin;b<=c->bmax;b++) + for(r=rmin;r<=rmax;r+=1<<16) + for(g=vmin;g<=vmax;g+=1<<8) + { + if(to->table[r + g + b]) // OT_get + { + bmin=b; + goto BMAX; + } + } +BMAX: + for(b=c->bmax;b>=bmin;b--) + for(r=rmin;r<=rmax;r+=1<<16) + for(g=vmin;g<=vmax;g+=1<<8) + { + if(to->table[r + g + b]) // OT_get + { + bmax=b; + goto ENDCRUSH; + } + } +ENDCRUSH: + // Il faut quand même parcourir la partie utile du cluster, pour savoir combien il y a d'occurences + for(r=rmin;r<=rmax;r+=1<<16) + for(g=vmin;g<=vmax;g+=1<<8) + for(b=bmin;b<=bmax;b++) + { + c->occurences+=to->table[r + g + b]; // OT_get + } + + c->rmin=rmin>>16; c->rmax=rmax>>16; + c->vmin=vmin>>8; c->vmax=vmax>>8; + c->bmin=bmin; c->bmax=bmax; + + // On regarde la composante qui a la variation la plus grande + r=(c->rmax-c->rmin)*299; + g=(c->vmax-c->vmin)*587; + b=(c->bmax-c->bmin)*114; + + if (g>=r) + { + // G>=R + if (g>=b) + { + // G>=R et G>=B + c->plus_large=1; + } + else + { + // G>=R et Gplus_large=2; + } + } + else + { + // R>G + if (r>=b) + { + // R>G et R>=B + c->plus_large=0; + } + else + { + // R>G et Rplus_large=2; + } + } +} + +void Cluster_split(T_Cluster * c,T_Cluster * c1,T_Cluster * c2,int hue,T_Occurrence_table * to) +{ + int limit; + int cumul; + int r,g,b; + + limit=(c->occurences)/2; + cumul=0; + if (hue==0) + { + for (r=c->rmin<<16;r<=c->rmax<<16;r+=1<<16) + { + for (g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) + { + for (b=c->bmin;b<=c->bmax;b++) + { + cumul+=to->table[r + g + b]; + if (cumul>=limit) + break; + } + if (cumul>=limit) + break; + } + if (cumul>=limit) + break; + } + + r>>=16; + g>>=8; + + if (r==c->rmin) + r++; + // R est la valeur de d‚but du 2nd cluster + + c1->Rmin=c->Rmin; c1->Rmax=r-1; + c1->rmin=c->rmin; c1->rmax=r-1; + c1->Gmin=c->Gmin; c1->Vmax=c->Vmax; + c1->vmin=c->vmin; c1->vmax=c->vmax; + c1->Bmin=c->Bmin; c1->Bmax=c->Bmax; + c1->bmin=c->bmin; c1->bmax=c->bmax; + c2->Rmin=r; c2->Rmax=c->Rmax; + c2->rmin=r; c2->rmax=c->rmax; + c2->Gmin=c->Gmin; c2->Vmax=c->Vmax; + c2->vmin=c->vmin; c2->vmax=c->vmax; + c2->Bmin=c->Bmin; c2->Bmax=c->Bmax; + c2->bmin=c->bmin; c2->bmax=c->bmax; + } + else + if (hue==1) + { + + for (g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) + { + for (r=c->rmin<<16;r<=c->rmax<<16;r+=1<<16) + { + for (b=c->bmin;b<=c->bmax;b++) + { + cumul+=to->table[r + g + b]; + if (cumul>=limit) + break; + } + if (cumul>=limit) + break; + } + if (cumul>=limit) + break; + } + + r>>=16; g>>=8; + + if (g==c->vmin) + g++; + // G est la valeur de d‚but du 2nd cluster + + c1->Rmin=c->Rmin; c1->Rmax=c->Rmax; + c1->rmin=c->rmin; c1->rmax=c->rmax; + c1->Gmin=c->Gmin; c1->Vmax=g-1; + c1->vmin=c->vmin; c1->vmax=g-1; + c1->Bmin=c->Bmin; c1->Bmax=c->Bmax; + c1->bmin=c->bmin; c1->bmax=c->bmax; + c2->Rmin=c->Rmin; c2->Rmax=c->Rmax; + c2->rmin=c->rmin; c2->rmax=c->rmax; + c2->Gmin=g; c2->Vmax=c->Vmax; + c2->vmin=g; c2->vmax=c->vmax; + c2->Bmin=c->Bmin; c2->Bmax=c->Bmax; + c2->bmin=c->bmin; c2->bmax=c->bmax; + } + else + { + + for (b=c->bmin;b<=c->bmax;b++) + { + for (g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) + { + for (r=c->rmin<<16;r<=c->rmax<<16;r+=1<<16) + { + cumul+=to->table[r + g + b]; + if (cumul>=limit) + break; + } + if (cumul>=limit) + break; + } + if (cumul>=limit) + break; + } + + r>>=16; g>>=8; + + if (b==c->bmin) + b++; + // B est la valeur de d‚but du 2nd cluster + + c1->Rmin=c->Rmin; c1->Rmax=c->Rmax; + c1->rmin=c->rmin; c1->rmax=c->rmax; + c1->Gmin=c->Gmin; c1->Vmax=c->Vmax; + c1->vmin=c->vmin; c1->vmax=c->vmax; + c1->Bmin=c->Bmin; c1->Bmax=b-1; + c1->bmin=c->bmin; c1->bmax=b-1; + c2->Rmin=c->Rmin; c2->Rmax=c->Rmax; + c2->rmin=c->rmin; c2->rmax=c->rmax; + c2->Gmin=c->Gmin; c2->Vmax=c->Vmax; + c2->vmin=c->vmin; c2->vmax=c->vmax; + c2->Bmin=b; c2->Bmax=c->Bmax; + c2->bmin=b; c2->bmax=c->bmax; + } +} + +void Cluster_compute_hue(T_Cluster * c,T_Occurrence_table * to) +{ + int cumul_r,cumul_g,cumul_b; + int r,g,b; + int nbocc; + + byte s=0; + + cumul_r=cumul_g=cumul_b=0; + for (r=c->rmin;r<=c->rmax;r++) + for (g=c->vmin;g<=c->vmax;g++) + for (b=c->bmin;b<=c->bmax;b++) + { + nbocc=OT_get(to,r,g,b); + if (nbocc) + { + cumul_r+=r*nbocc; + cumul_g+=g*nbocc; + cumul_b+=b*nbocc; + } + } + + c->r=(cumul_r<red_r)/c->occurences; + c->g=(cumul_g<red_g)/c->occurences; + c->b=(cumul_b<red_b)/c->occurences; + RGB_to_HSL(c->r,c->g,c->b,&c->h,&s,&c->l); +} + + + +///////////////////////////////////////////////////////////////////////////// +//////////////////////////// M‚thodes de gestion des ensembles de clusters // +///////////////////////////////////////////////////////////////////////////// + +/// Setup the first cluster before we start the operations +void CS_Init(T_Cluster_set * cs,T_Occurrence_table * to) +{ + cs->clusters->Rmin = cs->clusters->rmin = 0; + cs->clusters->Gmin = cs->clusters->vmin = 0; + cs->clusters->Bmin = cs->clusters->bmin = 0; + cs->clusters->Rmax = cs->clusters->rmax = to->rng_r-1; + cs->clusters->Vmax = cs->clusters->vmax = to->rng_g-1; + cs->clusters->Bmax = cs->clusters->bmax = to->rng_b-1; + cs->clusters->next = NULL; + Cluster_analyser(cs->clusters,to); + cs->nb=1; +} + +/// Allocate a new cluster set +T_Cluster_set * CS_New(int nbmax,T_Occurrence_table * to) +{ + T_Cluster_set * n; + + n=(T_Cluster_set *)malloc(sizeof(T_Cluster_set)); + if (n != NULL) + { + // On recopie les paramŠtres demand‚s + n->nb_max=OT_count_colors(to); + + // On vient de compter le nombre de couleurs existantes, s'il est plus grand que 256 on limite à 256 + // (nombre de couleurs voulu au final) + if (n->nb_max>nbmax) + { + n->nb_max=nbmax; + } + + // On tente d'allouer le premier cluster + n->clusters=(T_Cluster *)malloc(sizeof(T_Cluster)); + if (n->clusters!=NULL) + // C'est bon! On initialise + CS_Init(n,to); + else + { + // Table impossible … allouer + free(n); + n=0; + } + } + + return n; +} + +/// Free a cluster set +void CS_Delete(T_Cluster_set * cs) +{ + T_Cluster* nxt; + while(cs->clusters != NULL) + { + nxt = cs->clusters->next; + free(cs->clusters); + cs->clusters = nxt; + } + free(cs); +} + +void CS_Get(T_Cluster_set * cs,T_Cluster * c) +{ + T_Cluster* current = cs->clusters; + T_Cluster* prev = NULL; + + // Search a cluster with at least 2 distinct colors so we can split it + do + { + if ( (current->rmin < current->rmax) || + (current->vmin < current->vmax) || + (current->bmin < current->bmax) ) + break; + + prev = current; + + } while((current = current -> next)); + + // copy it to c + *c = *current; + + // remove it from the list + cs->nb--; + + if(prev) + prev->next = current->next; + else + cs->clusters = current->next; + free(current); + current = NULL; +} + +void CS_Set(T_Cluster_set * cs,T_Cluster * c) +{ + T_Cluster* current = cs->clusters; + T_Cluster* prev = NULL; + + // Search the first cluster that is smaller than ours + if(current != NULL) // don't search if the list is empty + do + { + if (current->occurences < c->occurences) + break; + prev = current; + } while((current = current -> next)); + + // Now insert our cluster just before the one we found + c -> next = current; + + current = malloc(sizeof(T_Cluster)); + *current = *c ; + + if(prev) prev -> next = current; + else cs->clusters = current; + + cs -> nb++; +} + +// Détermination de la meilleure palette en utilisant l'algo Median Cut : +// 1) On considère l'espace (R,G,B) comme 1 boîte +// 2) On cherche les extrêmes de la boîte en (R,G,B) +// 3) On trie les pixels de l'image selon l'axe le plus long parmi (R,G,B) +// 4) On coupe la boîte en deux au milieu, et on compacte pour que chaque bord corresponde bien à un pixel extreme +// 5) On recommence à couper selon le plus grand axe toutes boîtes confondues +// 6) On s'arrête quand on a le nombre de couleurs voulu +void CS_Generate(T_Cluster_set * cs,T_Occurrence_table * to) +{ + T_Cluster current; + T_Cluster Nouveau1; + T_Cluster Nouveau2; + + // Tant qu'on a moins de 256 clusters + while (cs->nbnb_max) + { + // On récupère le plus grand cluster + CS_Get(cs,¤t); + + // On le coupe en deux + Cluster_split(¤t,&Nouveau1,&Nouveau2,current.plus_large,to); + + // On compacte ces deux nouveaux (il peut y avoir un espace entre l'endroit de la coupure et les premiers pixels du cluster) + Cluster_analyser(&Nouveau1,to); + Cluster_analyser(&Nouveau2,to); + + // On met ces deux nouveaux clusters dans le clusterSet... sauf s'ils sont vides + if(Nouveau1.occurences>0) + CS_Set(cs,&Nouveau1); + if(Nouveau2.occurences>0) + CS_Set(cs,&Nouveau2); + } +} + +void CS_Compute_colors(T_Cluster_set * cs,T_Occurrence_table * to) +{ + T_Cluster * c; + + for (c=cs->clusters;c!=NULL;c=c->next) + Cluster_compute_hue(c,to); +} + +void CS_Sort_by_chrominance(T_Cluster_set * cs) +{ + T_Cluster* nc; + T_Cluster* prev = NULL; + T_Cluster* place; + T_Cluster* newlist = NULL; + + while((nc = cs->clusters)) + { + // Remove the first cluster from the original list + nc = cs->clusters; + cs->clusters = cs->clusters->next; + + // Find his position in the new list + for(place = newlist;place != NULL; place = place->next) + { + if(place->h > nc->h) break; + prev = place; + } + + // Chain it there + nc->next = place; + if(prev) prev->next = nc; + else newlist = nc; + + } + + // Put the new list bavk in place + cs->clusters = newlist; +} + +void CS_Sort_by_luminance(T_Cluster_set * cs) +{ + T_Cluster* nc; + T_Cluster* prev = NULL; + T_Cluster* place; + T_Cluster* newlist = NULL; + + while((nc = cs->clusters)) + { + // Remove the first cluster from the original list + nc = cs->clusters; + cs->clusters = cs->clusters->next; + + // Find his position in the new list + for(place = newlist;place != NULL; place = place->next) + { + if(place->l > nc->l) break; + prev = place; + } + + // Chain it there + nc->next = place; + if(prev) prev->next = nc; + else newlist = nc; + + } + + // Put the new list bavk in place + cs->clusters = newlist; +} + +void CS_Generate_color_table_and_palette(T_Cluster_set * cs,T_Conversion_table * tc,T_Components * palette) +{ + int index; + int r,g,b; + T_Cluster* current = cs->clusters; + + for (index=0;indexnb;index++) + { + palette[index].R=current->r; + palette[index].G=current->g; + palette[index].B=current->b; + + for (r=current->Rmin; r<=current->Rmax; r++) + for (g=current->Gmin;g<=current->Vmax;g++) + for (b=current->Bmin;b<=current->Bmax;b++) + CT_set(tc,r,g,b,index); + current = current->next; + } +} + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////// Méthodes de gestion des dégradés // +///////////////////////////////////////////////////////////////////////////// + +void GS_Init(T_Gradient_set * ds,T_Cluster_set * cs) +{ + ds->gradients[0].nb_colors=1; + ds->gradients[0].min=cs->clusters->h; + ds->gradients[0].max=cs->clusters->h; + ds->gradients[0].hue=cs->clusters->h; + // Et hop : le 1er ensemble de d‚grad‚s est initialis‚ + ds->nb=1; +} + +T_Gradient_set * GS_New(T_Cluster_set * cs) +{ + T_Gradient_set * n; + + n=(T_Gradient_set *)malloc(sizeof(T_Gradient_set)); + if (n!=NULL) + { + // On recopie les paramŠtres demand‚s + n->nb_max=cs->nb_max; + + // On tente d'allouer la table + n->gradients=(T_Gradient *)malloc((n->nb_max)*sizeof(T_Gradient)); + if (n->gradients!=0) + // C'est bon! On initialise + GS_Init(n,cs); + else + { + // Table impossible … allouer + free(n); + n=0; + } + } + + return n; +} + +void GS_Delete(T_Gradient_set * ds) +{ + free(ds->gradients); + free(ds); +} + +void GS_Generate(T_Gradient_set * ds,T_Cluster_set * cs) +{ + int id; // Les indexs de parcours des ensembles + int best_gradient; // Meilleur d‚grad‚ + int best_diff; // Meilleure diff‚rence de chrominance + int diff; // difference de chrominance courante + T_Cluster * current = cs->clusters; + + // Pour chacun des clusters … traiter + do + { + // On recherche le d‚grad‚ le plus proche de la chrominance du cluster + best_gradient=-1; + best_diff=99999999; + for (id=0;idnb;id++) + { + diff=abs(current->h - ds->gradients[id].hue); + if ((best_diff>diff) && (diff<16)) + { + best_gradient=id; + best_diff=diff; + } + } + + // Si on a trouv‚ un d‚grad‚ dans lequel inclure le cluster + if (best_gradient!=-1) + { + // On met … jour le d‚grad‚ + if (current->h < ds->gradients[best_gradient].min) + ds->gradients[best_gradient].min=current->h; + if (current->h > ds->gradients[best_gradient].max) + ds->gradients[best_gradient].max=current->h; + ds->gradients[best_gradient].hue=((ds->gradients[best_gradient].hue* + ds->gradients[best_gradient].nb_colors) + +current->h) + /(ds->gradients[best_gradient].nb_colors+1); + ds->gradients[best_gradient].nb_colors++; + } + else + { + // On cr‚e un nouveau d‚grad‚ + best_gradient=ds->nb; + ds->gradients[best_gradient].nb_colors=1; + ds->gradients[best_gradient].min=current->h; + ds->gradients[best_gradient].max=current->h; + ds->gradients[best_gradient].hue=current->h; + ds->nb++; + } + current->h=best_gradient; + } while((current = current->next)); + + // On redistribue les valeurs dans les clusters + current = cs -> clusters; + do + current->h=ds->gradients[current->h].hue; + while((current = current ->next)); +} + + + + +T_Conversion_table * Optimize_palette(T_Bitmap24B image,int size,T_Components * palette,int r,int g,int b) +{ + T_Occurrence_table * to; + T_Conversion_table * tc; + T_Cluster_set * cs; + T_Gradient_set * ds; + + // Création des éléments nécessaires au calcul de palette optimisée: + to=0; tc=0; cs=0; ds=0; + + to=OT_new(r,g,b); + if (to!=0) + { + tc=CT_new(r,g,b); + if (tc!=0) + { + + // Première étape : on compte les pixels de chaque couleur pour pouvoir trier là dessus + OT_count_occurrences(to,image,size); + + cs=CS_New(256,to); + if (cs!=0) + { + // C'est bon, on a pu tout allouer + + // On génère les clusters (avec l'algo du median cut) + CS_Generate(cs,to); + + // On calcule la teinte de chaque pixel (Luminance et chrominance) + CS_Compute_colors(cs,to); + + ds=GS_New(cs); + if (ds!=0) + { + GS_Generate(ds,cs); + GS_Delete(ds); + } + + // Enfin on trie les clusters (donc les couleurs de la palette) dans un ordre sympa : par couleur, et par luminosité pour chaque couleur + CS_Sort_by_luminance(cs); + CS_Sort_by_chrominance(cs); + + // Enfin on génère la palette et la table de correspondance entre chaque couleur 24b et sa couleur palette associée. + CS_Generate_color_table_and_palette(cs,tc,palette); + + CS_Delete(cs); + OT_delete(to); + return tc; + } + CT_delete(tc); + } + OT_delete(to); + } + // Si on arrive ici c'est que l'allocation n'a pas réussi, + // l'appelant devra recommencer avec une précision plus faible (3 derniers paramètres) + return 0; +} + +int Modified_value(int value,int modif) +{ + value+=modif; + if (value<0) + { + value=0; + } + else if (value>255) + { + value=255; + } + return value; +} + +void Convert_24b_bitmap_to_256_Floyd_Steinberg(T_Bitmap256 dest,T_Bitmap24B source,int width,int height,T_Components * palette,T_Conversion_table * tc) +// Cette fonction dégrade au fur et à mesure le bitmap source, donc soit on ne +// s'en ressert pas, soit on passe à la fonction une copie de travail du +// bitmap original. +{ + T_Bitmap24B current; + T_Bitmap24B c_plus1; + T_Bitmap24B u_minus1; + T_Bitmap24B next; + T_Bitmap24B u_plus1; + T_Bitmap256 d; + int x_pos,y_pos; + int red,green,blue; + float e_red,e_green,e_blue; + + // On initialise les variables de parcours: + current =source; // Le pixel dont on s'occupe + next =current+width; // Le pixel en dessous + c_plus1 =current+1; // Le pixel à droite + u_minus1=next-1; // Le pixel en bas à gauche + u_plus1 =next+1; // Le pixel en bas à droite + d =dest; + + // On parcours chaque pixel: + for (y_pos=0;y_posR; + green =current->G; + blue =current->B; + // Cherche la couleur correspondant dans la palette et la range dans l'image de destination + *d=CT_get(tc,red,green,blue); + + // Puis on calcule pour chaque composante l'erreur dûe à l'approximation + red-=palette[*d].R; + green -=palette[*d].G; + blue -=palette[*d].B; + + // Et dans chaque pixel voisin on propage l'erreur + // A droite: + e_red=(red*7)/16.0; + e_green =(green *7)/16.0; + e_blue =(blue *7)/16.0; + if (x_pos+1R=Modified_value(c_plus1->R,e_red); + c_plus1->G=Modified_value(c_plus1->G,e_green ); + c_plus1->B=Modified_value(c_plus1->B,e_blue ); + } + // En bas à gauche: + if (y_pos+10) + { + u_minus1->R=Modified_value(u_minus1->R,e_red); + u_minus1->G=Modified_value(u_minus1->G,e_green ); + u_minus1->B=Modified_value(u_minus1->B,e_blue ); + } + // En bas: + e_red=(red*5/16.0); + e_green =(green*5 /16.0); + e_blue =(blue*5 /16.0); + next->R=Modified_value(next->R,e_red); + next->G=Modified_value(next->G,e_green ); + next->B=Modified_value(next->B,e_blue ); + // En bas à droite: + if (x_pos+1R=Modified_value(u_plus1->R,e_red); + u_plus1->G=Modified_value(u_plus1->G,e_green ); + u_plus1->B=Modified_value(u_plus1->B,e_blue ); + } + } + + // On passe au pixel suivant : + current++; + c_plus1++; + u_minus1++; + next++; + u_plus1++; + d++; + } + } + +} + + + +static const byte precision_24b[]= +{ + 8,8,8, + 6,6,6, + 6,6,5, + 5,6,5, + 5,5,5, + 5,5,4, + 4,5,4, + 4,4,4, + 4,4,3, + 3,4,3, + 3,3,3, + 3,3,2}; + + +// Convertie avec le plus de précision possible une image 24b en 256c +// Renvoie s'il y a eu une erreur ou pas.. + +// Cette fonction utilise l'algorithme "median cut" (Optimize_palette) pour trouver la palette, et diffuse les erreurs avec floyd-steinberg. + +int Convert_24b_bitmap_to_256(T_Bitmap256 dest,T_Bitmap24B source,int width,int height,T_Components * palette) +{ + T_Conversion_table * table; // table de conversion + int ip; // index de précision pour la conversion + + // On essaye d'obtenir une table de conversion qui loge en mémoire, avec la + // meilleure précision possible + for (ip=0;ip<(10*3);ip+=3) + { + table=Optimize_palette(source,width*height,palette,precision_24b[ip+0], + precision_24b[ip+1],precision_24b[ip+2]); + if (table!=0) + break; + } + + if (table!=0) + { + Convert_24b_bitmap_to_256_Floyd_Steinberg(dest,source,width,height,palette,table); + CT_delete(table); + return 0; + } + else + return 1; +} + + + diff --git a/op_c.h b/op_c.h index 4fd6739f..a1339aea 100644 --- a/op_c.h +++ b/op_c.h @@ -1,215 +1,215 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file op_c.h -/// Color reduction and color conversion (24b->8b, RGB<->HSL). -/// This is called op_c because half of the process was originally -/// coded in op_asm, in assembler. -////////////////////////////////////////////////////////////////////////////// - -#ifndef _OP_C_H_ -#define _OP_C_H_ - -#include "struct.h" - -//////////////////////////////////////////////// Définition des types de base - -typedef T_Components * T_Bitmap24B; -typedef byte * T_Bitmap256; - - - -//////////////////////////////////////// Définition d'une table de conversion - -typedef struct -{ - int nbb_r; // Nb de bits de précision sur les rouges - int nbb_g; // Nb de bits de précision sur les verts - int nbb_b; // Nb de bits de précision sur les bleu - - int rng_r; // Nb de valeurs sur les rouges (= 1< +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file op_c.h +/// Color reduction and color conversion (24b->8b, RGB<->HSL). +/// This is called op_c because half of the process was originally +/// coded in op_asm, in assembler. +////////////////////////////////////////////////////////////////////////////// + +#ifndef _OP_C_H_ +#define _OP_C_H_ + +#include "struct.h" + +//////////////////////////////////////////////// Définition des types de base + +typedef T_Components * T_Bitmap24B; +typedef byte * T_Bitmap256; + + + +//////////////////////////////////////// Définition d'une table de conversion + +typedef struct +{ + int nbb_r; // Nb de bits de précision sur les rouges + int nbb_g; // Nb de bits de précision sur les verts + int nbb_b; // Nb de bits de précision sur les bleu + + int rng_r; // Nb de valeurs sur les rouges (= 1< -*/ -#include -#include -#include - -#include "const.h" -#include "struct.h" -#include "global.h" -#include "misc.h" -#include "engine.h" -#include "graph.h" -#include "operatio.h" -#include "buttons.h" -#include "pages.h" -#include "errors.h" -#include "sdlscreen.h" -#include "brush.h" -#include "windows.h" - -#if defined(__GP2X__) - #define M_PI 3.14159265358979323846 -#endif - -/// Time (in SDL ticks) when the next airbrush drawing should be done. Also used -/// for discontinuous freehand drawing. -Uint32 Airbrush_next_time; - -void Start_operation_stack(word new_operation) -{ - Brush_rotation_center_is_defined=0; - - // On mémorise l'opération précédente si on démarre une interruption - switch(new_operation) - { - case OPERATION_MAGNIFY : - case OPERATION_COLORPICK : - case OPERATION_GRAB_BRUSH : - case OPERATION_POLYBRUSH : - case OPERATION_STRETCH_BRUSH : - case OPERATION_ROTATE_BRUSH: - Operation_before_interrupt=Current_operation; - // On passe à l'operation demandée - Current_operation=new_operation; - break; - default : - // On passe à l'operation demandée - Current_operation=new_operation; - Operation_before_interrupt=Current_operation; - } - - // On spécifie si l'opération autorise le changement de couleur au clavier - switch(new_operation) - { - case OPERATION_CONTINUOUS_DRAW: - case OPERATION_DISCONTINUOUS_DRAW: - case OPERATION_AIRBRUSH: - case OPERATION_CENTERED_LINES: - Allow_color_change_during_operation=1; - break; - default : - Allow_color_change_during_operation=0; - } - - // Et on passe au curseur qui va avec - Cursor_shape=CURSOR_FOR_OPERATION[new_operation]; - Operation_stack_size=0; -} - - -void Init_start_operation(void) -{ - Operation_in_magnifier=(Mouse_X>=Main_X_zoom); - Smear_start=1; -} - - -void Operation_push(short value) -{ - Operation_stack[++Operation_stack_size]=value; -} - - -void Operation_pop(short * value) -{ - *value=Operation_stack[Operation_stack_size--]; -} - - -byte Paintbrush_shape_before_operation; -byte Paintbrush_hidden_before_scroll; - - - -short Distance(short x1, short y1, short x2, short y2) -{ - short x2_moins_x1=x2-x1; - short y2_minus_y1=y2-y1; - - return Round( sqrt( (x2_moins_x1*x2_moins_x1) + (y2_minus_y1*y2_minus_y1) ) ); -} - - -void Display_coords_rel_or_abs(short start_x, short start_y) -{ - char str[6]; - - if (Config.Coords_rel) - { - if (Menu_is_visible) - { - if (Paintbrush_X>start_x) - { - Num2str(Paintbrush_X-start_x,str,5); - str[0]='+'; - } - else if (Paintbrush_Xstart_y) - { - Num2str(Paintbrush_Y-start_y,str,5); - str[0]='+'; - } - else if (Paintbrush_YAirbrush_next_time) - { - Airbrush_next_time+=Airbrush_delay*10; - Hide_cursor(); - // On affiche définitivement le pinceau - Display_paintbrush(Paintbrush_X,Paintbrush_Y,Fore_color,0); - Display_cursor(); - } - } - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - -// ---------- - -void Freehand_mode2_2_0(void) -// Opération : OPERATION_DISCONTINUOUS_DRAW -// Click Souris: 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui -{ - Init_start_operation(); - Backup(); - Shade_table=Shade_table_right; - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Print_coordinates(); - Airbrush_next_time = SDL_GetTicks() + Airbrush_delay*10; - // On affiche définitivement le pinceau - Display_paintbrush(Paintbrush_X,Paintbrush_Y,Back_color,0); -} - - -void Freehand_mode2_2_2(void) -// Opération : OPERATION_DISCONTINUOUS_DRAW -// Click Souris: 2 -// Taille_Pile : 2 -// -// Souris effacée: Non -{ - short start_x; - short start_y; - - Operation_pop(&start_y); - Operation_pop(&start_x); - - if ( (start_x!=Paintbrush_X) || (start_y!=Paintbrush_Y) ) - { - Print_coordinates(); - if (SDL_GetTicks()>Airbrush_next_time) - { - Airbrush_next_time+=Airbrush_delay*10; - Hide_cursor(); - // On affiche définitivement le pinceau - Display_paintbrush(Paintbrush_X,Paintbrush_Y,Back_color,0); - Display_cursor(); - } - } - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -////////////////////////////////////////////////////// OPERATION_POINT_DRAW - -void Freehand_mode3_1_0(void) -// Opération : OPERATION_POINT_DRAW -// Click Souris: 1 -// Taille_Pile : 0 -// -// Souris effacée: Oui -{ - Init_start_operation(); - Backup(); - Shade_table=Shade_table_left; - // On affiche définitivement le pinceau - Display_paintbrush(Paintbrush_X,Paintbrush_Y,Fore_color,0); - Operation_push(0); // On change simplement l'état de la pile... -} - - -void Freehand_Mode3_2_0(void) -// Opération : OPERATION_POINT_DRAW -// Click Souris: 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui -{ - Init_start_operation(); - Backup(); - Shade_table=Shade_table_right; - // On affiche définitivement le pinceau - Display_paintbrush(Paintbrush_X,Paintbrush_Y,Back_color,0); - Operation_push(0); // On change simplement l'état de la pile... -} - - -void Freehand_mode3_0_1(void) -// Opération : OPERATION_POINT_DRAW -// Click Souris: 0 -// Taille_Pile : 1 -// -// Souris effacée: Non -{ - Operation_stack_size--; -} - - -///////////////////////////////////////////////////////////// OPERATION_LINE - -void Line_12_0(void) -// Opération : OPERATION_LINE -// Click Souris: 1 ou 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui - -// Début du tracé d'une ligne (premier clic) -{ - Init_start_operation(); - Backup(); - Paintbrush_shape_before_operation=Paintbrush_shape; - Paintbrush_shape=PAINTBRUSH_SHAPE_POINT; - - if (Mouse_K==LEFT_SIDE) - { - Shade_table=Shade_table_left; - Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,Fore_color); - Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); - Operation_push(Fore_color); - } - else - { - Shade_table=Shade_table_right; - Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,Back_color); - Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); - Operation_push(Back_color); - } - - if ((Config.Coords_rel) && (Menu_is_visible)) - Print_in_menu("X:± 0 Y:± 0",0); - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -void Line_12_5(void) -// Opération : OPERATION_LINE -// Click Souris: 1 -// Taille_Pile : 5 -// -// Souris effacée: Non - -// Poursuite du tracé d'une ligne (déplacement de la souris en gardant le -// curseur appuyé) -{ - short start_x; - short start_y; - short end_x; - short end_y; - - short cursor_x; - short cursor_y; - - Operation_pop(&end_y); - Operation_pop(&end_x); - Operation_pop(&start_y); - Operation_pop(&start_x); - - cursor_x = Paintbrush_X; - cursor_y = Paintbrush_Y; - - // On corrige les coordonnées de la ligne si la touche shift est appuyée... - if(SDL_GetModState() & KMOD_SHIFT) - { - Clamp_coordinates_regular_angle(start_x,start_y,&cursor_x,&cursor_y); - } - - // On vient de bouger - if ((cursor_x!=end_x) || (cursor_y!=end_y)) - { - Hide_cursor(); - - Display_coords_rel_or_abs(start_x,start_y); - - Hide_line_preview(start_x,start_y,end_x,end_y); - if (Mouse_K==LEFT_SIDE) - { - Pixel_figure_preview (start_x,start_y,Fore_color); - Draw_line_preview (start_x,start_y,cursor_x,cursor_y,Fore_color); - } - else - { - Pixel_figure_preview (start_x,start_y,Back_color); - Draw_line_preview (start_x,start_y,cursor_x,cursor_y,Back_color); - } - - Operation_push(start_x); - Operation_push(start_y); - Operation_push(cursor_x); - Operation_push(cursor_y); - - Display_cursor(); - } - else - { - Operation_push(start_x); - Operation_push(start_y); - Operation_push(end_x); - Operation_push(end_y); - } -} - - -void Line_0_5(void) -// Opération : OPERATION_LINE -// Click Souris: 0 -// Taille_Pile : 5 -// -// Souris effacée: Oui - -// End du tracé d'une ligne (relachage du bouton) -{ - short start_x; - short start_y; - short end_x; - short end_y; - short color; - - Operation_pop(&end_y); - Operation_pop(&end_x); - Operation_pop(&start_y); - Operation_pop(&start_x); - Operation_pop(&color); - - Paintbrush_shape=Paintbrush_shape_before_operation; - - Pixel_figure_preview_auto (start_x,start_y); - Hide_line_preview (start_x,start_y,end_x,end_y); - Display_paintbrush (start_x,start_y,color,0); - Draw_line_permanet(start_x,start_y,end_x,end_y,color); - - if ( (Config.Coords_rel) && (Menu_is_visible) ) - { - Print_in_menu("X: Y: ",0); - Print_coordinates(); - } -} - - -/////////////////////////////////////////////////////////// OPERATION_K_LIGNE - - -void K_line_12_0(void) -// Opération : OPERATION_K_LIGNE -// Click Souris: 1 ou 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui -{ - byte color; - - Init_start_operation(); - Backup(); - Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right; - Paintbrush_shape_before_operation=Paintbrush_shape; - Paintbrush_shape=PAINTBRUSH_SHAPE_POINT; - - color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color; - - // On place temporairement le début de la ligne qui ne s'afficherait pas sinon - Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color); - - if ((Config.Coords_rel) && (Menu_is_visible)) - Print_in_menu("X:± 0 Y:± 0",0); - - Operation_push(Mouse_K | 0x80); - Operation_push(color); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - // Taille de pile 6 : phase d'appui, non interruptible -} - - -void K_line_12_6(void) -// Opération : OPERATION_K_LIGNE -// Click Souris: 1 ou 2 | 0 -// Taille_Pile : 6 | 7 -// -// Souris effacée: Non -{ - short start_x; - short start_y; - short end_x; - short end_y; - short color; - - Operation_pop(&end_y); - Operation_pop(&end_x); - - if ((Paintbrush_X!=end_x) || (Paintbrush_Y!=end_y)) - { - Hide_cursor(); - Operation_pop(&start_y); - Operation_pop(&start_x); - Operation_pop(&color); - - Display_coords_rel_or_abs(start_x,start_y); - - Hide_line_preview(start_x,start_y,end_x,end_y); - Pixel_figure_preview (start_x,start_y,color); - Draw_line_preview (start_x,start_y,Paintbrush_X,Paintbrush_Y,color); - - Operation_push(color); - Operation_push(start_x); - Operation_push(start_y); - Display_cursor(); - } - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -void K_line_0_6(void) -// Opération : OPERATION_K_LIGNE -// Click Souris: 0 -// Taille_Pile : 6 -// -// Souris effacée: Oui -{ - short start_x; - short start_y; - short end_x; - short end_y; - short color; - short direction; - - Operation_pop(&end_y); - Operation_pop(&end_x); - Operation_pop(&start_y); - Operation_pop(&start_x); - Operation_pop(&color); - Operation_pop(&direction); - - if ((Config.Coords_rel) && (Menu_is_visible)) - Print_in_menu("X:± 0 Y:± 0",0); - - Pixel_figure_preview_auto (start_x,start_y); - Hide_line_preview (start_x,start_y,end_x,end_y); - /* Doesn't work if fast moving - Pixel_figure_preview_xor (start_x,start_y, 0); - Draw_line_preview_xor (start_x,start_y,end_x,end_y,0); - */ - Paintbrush_shape=Paintbrush_shape_before_operation; - if (direction & 0x80) - { - Display_paintbrush(start_x,start_y,color,0); - direction=(direction & 0x7F); - } - Draw_line_permanet(start_x,start_y,Paintbrush_X,Paintbrush_Y,color); - Paintbrush_shape=PAINTBRUSH_SHAPE_POINT; - - Operation_push(direction); - Operation_push(direction); // Valeur bidon servant de nouvel état de pile - Operation_push(color); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - // Taille de pile 7 : phase de "repos", interruptible (comme Elliot Ness :)) -} - - -void K_line_12_7(void) -// Opération : OPERATION_K_LIGNE -// Click Souris: 1 ou 2 -// Taille_Pile : 7 -// -// Souris effacée: Oui -{ - short start_x; - short start_y; - short end_x; - short end_y; - short color; - short direction; - - Operation_pop(&end_y); - Operation_pop(&end_x); - Operation_pop(&start_y); - Operation_pop(&start_x); - Operation_pop(&color); - Operation_pop(&direction); - Operation_pop(&direction); - - if (direction==Mouse_K) - { - Operation_push(direction); - Operation_push(color); - Operation_push(start_x); - Operation_push(start_y); - Operation_push(end_x); - Operation_push(end_y); - // Taille de pile 6 : phase d'appui, non interruptible - } - else - { - // La série de ligne est terminée, il faut donc effacer la dernière - // preview de ligne - Pixel_figure_preview_auto (start_x,start_y); - Hide_line_preview (start_x,start_y,end_x,end_y); - - Display_cursor(); - Wait_end_of_click(); - Hide_cursor(); - Paintbrush_shape=Paintbrush_shape_before_operation; - - if ( (Config.Coords_rel) && (Menu_is_visible) ) - { - Print_in_menu("X: Y: ",0); - Print_coordinates(); - } - } -} - - -// ---------------------------------------------------------- OPERATION_MAGNIFY - - -void Magnifier_12_0(void) - -// Opération : 4 (item d'une Loupe) -// Click Souris: 1 ou 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui - -{ - - // On passe en mode loupe - Main_magnifier_mode=1; - - // La fonction d'affichage dans la partie image est désormais un affichage - // spécial loupe. - Pixel_preview=Pixel_preview_magnifier; - - // On calcule l'origine de la loupe - Main_magnifier_offset_X=Mouse_X-(Main_magnifier_width>>1); - Main_magnifier_offset_Y=Mouse_Y-(Main_magnifier_height>>1); - - // Calcul du coin haut_gauche de la fenêtre devant être zoomée DANS L'ECRAN - if (Main_magnifier_offset_X+Main_magnifier_width>=Limit_right-Main_offset_X) - Main_magnifier_offset_X=Limit_right-Main_magnifier_width-Main_offset_X+1; - if (Main_magnifier_offset_Y+Main_magnifier_height>=Limit_bottom-Main_offset_Y) - Main_magnifier_offset_Y=Limit_bottom-Main_magnifier_height-Main_offset_Y+1; - - // Calcul des coordonnées absolues de ce coin DANS L'IMAGE - Main_magnifier_offset_X+=Main_offset_X; - Main_magnifier_offset_Y+=Main_offset_Y; - - if (Main_magnifier_offset_X<0) - Main_magnifier_offset_X=0; - if (Main_magnifier_offset_Y<0) - Main_magnifier_offset_Y=0; - - // On calcule les bornes visibles dans l'écran - Position_screen_according_to_zoom(); - Compute_limits(); - Display_all_screen(); - - // Repositionner le curseur en fonction des coordonnées visibles - Compute_paintbrush_coordinates(); - - // On fait de notre mieux pour restaurer l'ancienne opération: - Start_operation_stack(Operation_before_interrupt); - Display_cursor(); - Wait_end_of_click(); -} - -/////////////////////////////////////////////////// OPERATION_RECTANGLE_????? - -void Rectangle_12_0(void) -// Opération : OPERATION_EMPTY_RECTANGLE / OPERATION_FILLED_RECTANGLE -// Click Souris: 1 ou 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui -{ - Init_start_operation(); - - if ((Config.Coords_rel) && (Menu_is_visible)) - Print_in_menu("\035: 1 \022: 1",0); - // On laisse une trace du curseur à l'écran - Display_cursor(); - - if (Mouse_K==LEFT_SIDE) - { - Shade_table=Shade_table_left; - Operation_push(Fore_color); - } - else - { - Shade_table=Shade_table_right; - Operation_push(Back_color); - } - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -void Rectangle_12_5(void) -// Opération : OPERATION_EMPTY_RECTANGLE / OPERATION_FILLED_RECTANGLE -// Click Souris: 1 ou 2 -// Taille_Pile : 5 -// -// Souris effacée: Non -{ - short start_x; - short start_y; - short old_x; - short old_y; - char str[5]; - - Operation_pop(&old_y); - Operation_pop(&old_x); - - if ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y)) - { - Operation_pop(&start_y); - Operation_pop(&start_x); - - if ((Config.Coords_rel) && (Menu_is_visible)) - { - Num2str(((start_xcenter_x)?tangent_x-center_x - :center_x-tangent_x; - vertical_radius =(tangent_y>center_y)?tangent_y-center_y - :center_y-tangent_y; - Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius); - - horizontal_radius=(Paintbrush_X>center_x)?Paintbrush_X-center_x - :center_x-Paintbrush_X; - vertical_radius =(Paintbrush_Y>center_y)?Paintbrush_Y-center_y - :center_y-Paintbrush_Y; - Draw_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius,color); - - Display_cursor(); - } - - Operation_push(color); - Operation_push(center_x); - Operation_push(center_y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -void Empty_ellipse_0_5(void) -// -// Opération : OPERATION_EMPTY_ELLIPSE -// Click Souris: 0 -// Taille_Pile : 5 (color, X_Centre, Y_Centre, X_Tangente, Y_Tangente) -// -// Souris effacée: Oui -// -{ - short tangent_x; - short tangent_y; - short center_x; - short center_y; - short color; - short horizontal_radius; - short vertical_radius; - - Operation_pop(&tangent_y); - Operation_pop(&tangent_x); - Operation_pop(¢er_y); - Operation_pop(¢er_x); - Operation_pop(&color); - - horizontal_radius=(tangent_x>center_x)?tangent_x-center_x - :center_x-tangent_x; - vertical_radius =(tangent_y>center_y)?tangent_y-center_y - :center_y-tangent_y; - Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius); - - Paintbrush_shape=Paintbrush_shape_before_operation; - - Draw_empty_ellipse_permanent(center_x,center_y,horizontal_radius,vertical_radius,color); - - if ( (Config.Coords_rel) && (Menu_is_visible) ) - { - Print_in_menu("X: Y: ",0); - Print_coordinates(); - } -} - - -void Filled_ellipse_0_5(void) -// -// Opération : OPERATION_FILLED_ELLIPSE -// Click Souris: 0 -// Taille_Pile : 5 (color, X_Centre, Y_Centre, X_Tangente, Y_Tangente) -// -// Souris effacée: Oui -// -{ - short tangent_x; - short tangent_y; - short center_x; - short center_y; - short color; - short horizontal_radius; - short vertical_radius; - - Operation_pop(&tangent_y); - Operation_pop(&tangent_x); - Operation_pop(¢er_y); - Operation_pop(¢er_x); - Operation_pop(&color); - - horizontal_radius=(tangent_x>center_x)?tangent_x-center_x - :center_x-tangent_x; - vertical_radius =(tangent_y>center_y)?tangent_y-center_y - :center_y-tangent_y; - Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius); - - Paintbrush_shape=Paintbrush_shape_before_operation; - - Draw_filled_ellipse(center_x,center_y,horizontal_radius,vertical_radius,color); - - if ( (Config.Coords_rel) && (Menu_is_visible) ) - { - Print_in_menu("X: Y: ",0); - Print_coordinates(); - } -} - - -////////////////////////////////////////////////////////////// OPERATION_FILL - - -void Fill_1_0(void) -// -// Opération : OPERATION_FILL -// Click Souris: 1 -// Taille_Pile : 0 -// -// Souris effacée: Oui -// -{ - Hide_cursor(); - // Pas besoin d'initialiser le début d'opération car le Smear n'affecte pas - // le Fill, et on se fout de savoir si on est dans la partie gauche ou - // droite de la loupe. - // On ne s'occupe pas de faire un Backup: c'est "Fill_general" qui s'en charge. - Shade_table=Shade_table_left; - Fill_general(Fore_color); - Display_cursor(); - Wait_end_of_click(); -} - - -void Fill_2_0(void) -// -// Opération : OPERATION_FILL -// Click Souris: 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui -// -{ - Hide_cursor(); - // Pas besoin d'initialiser le début d'opération car le Smear n'affecte pas - // le Fill, et on se fout de savoir si on est dans la partie gauche ou - // droite de la loupe. - // On ne s'occupe pas de faire un Backup: c'est "Fill_general" qui s'en charge. - Shade_table=Shade_table_right; - Fill_general(Back_color); - Display_cursor(); - Wait_end_of_click(); -} - - -///////////////////////////////////////////////////////// OPERATION_REPLACE - - -void Replace_1_0(void) -// -// Opération : OPERATION_REPLACE -// Click Souris: 1 -// Taille_Pile : 0 -// -// Souris effacée: Oui -// -{ - Hide_cursor(); - // Pas besoin d'initialiser le début d'opération car le Smear n'affecte pas - // le Replace, et on se fout de savoir si on est dans la partie gauche ou - // droite de la loupe. - Backup(); -// Shade_table=Shade_table_left; - Replace(Fore_color); - Display_cursor(); - Wait_end_of_click(); -} - - -void Replace_2_0(void) -// -// Opération : OPERATION_REPLACE -// Click Souris: 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui -// -{ - Hide_cursor(); - // Pas besoin d'initialiser le début d'opération car le Smear n'affecte pas - // le Replace, et on se fout de savoir si on est dans la partie gauche ou - // droite de la loupe. - Backup(); -// Shade_table=Shade_table_right; - Replace(Back_color); - Display_cursor(); - Wait_end_of_click(); -} - - -/////////////////////////////////////////////////////////// OPERATION_COLORPICK - - -void Colorpicker_12_0(void) -// -// Opération : OPERATION_COLORPICK -// Click Souris: 1 ou 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui -// -{ - Init_start_operation(); - - if (Mouse_K==LEFT_SIDE) - { - Set_fore_color(Colorpicker_color); - } - else - { - Set_back_color(Colorpicker_color); - } - Operation_push(Mouse_K); -} - - -void Colorpicker_1_1(void) -// -// Opération : OPERATION_COLORPICK -// Click Souris: 1 -// Taille_Pile : 1 -// -// Souris effacée: Non -// -{ - char str[4]; - - if ( (Paintbrush_X>=0) && (Paintbrush_Y>=0) - && (Paintbrush_X=0) && (Paintbrush_Y>=0) - && (Paintbrush_X=Limit_left+3) - start_x=0; - else - start_x=3-(x_pos-Limit_left); - - if (y_pos>=Limit_top+3) - start_y=0; - else - start_y=3-(y_pos-Limit_top); - - if (x_pos<=Limit_visible_right-3) - end_x=6; - else - end_x=3+(Limit_visible_right-x_pos); - - if (y_pos<=Limit_visible_bottom-3) - end_y=6; - else - end_y=3+(Limit_visible_bottom-y_pos); - - if (start_x<=end_x && start_y<=end_y) - { - for (i=start_x; i<=end_x; i++) - { - temp=x_pos+i-3; - Pixel_preview(temp,y_pos,~Read_pixel(temp -Main_offset_X, - y_pos-Main_offset_Y)); - } - for (i=start_y; i<=end_y; i++) - { - temp=y_pos+i-3; - Pixel_preview(x_pos,temp,~Read_pixel(x_pos-Main_offset_X, - temp -Main_offset_Y)); - } - Update_part_of_screen(x_pos+start_x-3,y_pos+start_y-3,end_x-start_x+1,end_y-start_y+1); - } -} - - -void Curve_34_points_1_0(void) -// -// Opération : OPERATION_COURBE_?_POINTS -// Click Souris: 1 -// Taille_Pile : 0 -// -// Souris effacée: Oui -// -{ - Init_start_operation(); - Backup(); - Shade_table=Shade_table_left; - - Paintbrush_hidden=1; - - Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,Fore_color); - Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); - - if ((Config.Coords_rel) && (Menu_is_visible)) - Print_in_menu("X:± 0 Y:± 0",0); - - Operation_push(Fore_color); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - -void Curve_34_points_2_0(void) -// -// Opération : OPERATION_COURBE_?_POINTS -// Click Souris: 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui -// -{ - Init_start_operation(); - Backup(); - Shade_table=Shade_table_right; - - Paintbrush_hidden=1; - - Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,Back_color); - Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); - - if ((Config.Coords_rel) && (Menu_is_visible)) - Print_in_menu("X:± 0 Y:± 0",0); - - Operation_push(Back_color); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -void Curve_34_points_1_5(void) -// -// Opération : OPERATION_COURBE_?_POINTS -// Click Souris: 1 -// Taille_Pile : 5 -// -// Souris effacée: Non -// -{ - short x1,x2,y1,y2; - - Operation_pop(&y2); - Operation_pop(&x2); - Operation_pop(&y1); - Operation_pop(&x1); - - if ( (y2!=Paintbrush_Y) || (x2!=Paintbrush_X) ) - { - Hide_cursor(); - Display_coords_rel_or_abs(x1,y1); - - Hide_line_preview(x1,y1,x2,y2); - Pixel_figure_preview (x1,y1,Fore_color); - Draw_line_preview (x1,y1,Paintbrush_X,Paintbrush_Y,Fore_color); - - Display_cursor(); - } - - Operation_push(x1); - Operation_push(y1); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - -void Curve_34_points_2_5(void) -// -// Opération : OPERATION_COURBE_?_POINTS -// Click Souris: 2 -// Taille_Pile : 5 -// -// Souris effacée: Non -// -{ - short x1,x2,y1,y2; - - Operation_pop(&y2); - Operation_pop(&x2); - Operation_pop(&y1); - Operation_pop(&x1); - - if ( (y2!=Paintbrush_Y) || (x2!=Paintbrush_X) ) - { - Hide_cursor(); - Display_coords_rel_or_abs(x1,y1); - - Hide_line_preview(x1,y1,x2,y2); - Pixel_figure_preview (x1,y1,Back_color); - Draw_line_preview (x1,y1,Paintbrush_X,Paintbrush_Y,Back_color); - - Display_cursor(); - } - - Operation_push(x1); - Operation_push(y1); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -byte Cursor_hidden_before_curve; - -void Curve_4_points_0_5(void) -// -// Opération : OPERATION_4_POINTS_CURVE -// Click Souris: 0 -// Taille_Pile : 5 -// -// Souris effacée: Oui -// -{ - short x1,y1,x2,y2,x3,y3,x4,y4; - short third_x,third_y; - short color; - - Operation_pop(&y4); - Operation_pop(&x4); - Operation_pop(&y1); - Operation_pop(&x1); - Operation_pop(&color); - - third_x=Round_div(abs(x4-x1),3); - third_y=Round_div(abs(y4-y1),3); - - if (x1B=(8/3) * C->P - *x3=Round((bx+x4)/2.0); // · _/·· P3 P2=milieu de [P1,B] - *y3=Round((by+y4)/2.0); // P4*-- P3=milieu de [P4,B] -} - - -void Curve_3_points_0_5(void) -// -// Opération : OPERATION_3_POINTS_CURVE -// Click Souris: 0 -// Taille_Pile : 5 -// -// Souris effacée: Oui -// -{ - short x1,y1,x2,y2,x3,y3,x4,y4; - short color; - - Operation_pop(&y4); - Operation_pop(&x4); - Operation_pop(&y1); - Operation_pop(&x1); - Operation_pop(&color); - - Compute_3_point_curve(x1,y1,x4,y4,&x2,&y2,&x3,&y3); - - Hide_line_preview(x1,y1,x4,y4); - Draw_curve_preview(x1,y1,x2,y2,x3,y3,x4,y4,color); - - if ( (Config.Coords_rel) && (Menu_is_visible) ) - { - Print_in_menu("X: Y: ",0); - Print_coordinates(); - } - - Operation_push(color); - Operation_push(x1); - Operation_push(y1); - Operation_push(x2); - Operation_push(y2); - Operation_push(x3); - Operation_push(y3); - Operation_push(x4); - Operation_push(y4); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -void Curve_3_points_0_11(void) -// -// Opération : OPERATION_3_POINTS_CURVE -// Click Souris: 0 -// Taille_Pile : 11 -// -// Souris effacée: Non -// -{ - short x1,y1,x2,y2,x3,y3,x4,y4; - short old_x,old_y; - short color; - - Operation_pop(&old_y); - Operation_pop(&old_x); - - if ( (Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y) ) - { - Operation_pop(&y4); - Operation_pop(&x4); - Operation_pop(&y3); - Operation_pop(&x3); - Operation_pop(&y2); - Operation_pop(&x2); - Operation_pop(&y1); - Operation_pop(&x1); - Operation_pop(&color); - - Hide_cursor(); - Print_coordinates(); - - Hide_curve_preview(x1,y1,x2,y2,x3,y3,x4,y4,color); - Compute_3_point_curve(x1,y1,x4,y4,&x2,&y2,&x3,&y3); - Draw_curve_preview (x1,y1,x2,y2,x3,y3,x4,y4,color); - Display_cursor(); - - Operation_push(color); - Operation_push(x1); - Operation_push(y1); - Operation_push(x2); - Operation_push(y2); - Operation_push(x3); - Operation_push(y3); - Operation_push(x4); - Operation_push(y4); - } - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -void Curve_3_points_12_11(void) -// -// Opération : OPERATION_3_POINTS_CURVE -// Click Souris: 1 ou 2 -// Taille_Pile : 11 -// -// Souris effacée: Oui -// -{ - short x1,y1,x2,y2,x3,y3,x4,y4; - short old_x,old_y; - short color; - - Operation_pop(&old_y); - Operation_pop(&old_x); - Operation_pop(&y4); - Operation_pop(&x4); - Operation_pop(&y3); - Operation_pop(&x3); - Operation_pop(&y2); - Operation_pop(&x2); - Operation_pop(&y1); - Operation_pop(&x1); - Operation_pop(&color); - - Paintbrush_hidden=0; - - Hide_cursor(); - - Hide_curve_preview (x1,y1,x2,y2,x3,y3,x4,y4,color); - Compute_3_point_curve(x1,y1,x4,y4,&x2,&y2,&x3,&y3); - Draw_curve_permanent(x1,y1,x2,y2,x3,y3,x4,y4,color); - - Display_cursor(); - Wait_end_of_click(); -} - - -///////////////////////////////////////////////////////////// OPERATION_AIRBRUSH - -void Airbrush_1_0(void) -// -// Opération : OPERATION_AIRBRUSH -// Click Souris: 1 -// Taille_Pile : 0 -// -// Souris effacée: Non -// -{ - Init_start_operation(); - Backup(); - Shade_table=Shade_table_left; - - Airbrush_next_time = SDL_GetTicks()+Airbrush_delay*10; - Airbrush(LEFT_SIDE); - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - -void Airbrush_2_0(void) -// -// Opération : OPERATION_AIRBRUSH -// Click Souris: 2 -// Taille_Pile : 0 -// -// Souris effacée: Non -// -{ - Init_start_operation(); - Backup(); - Shade_table=Shade_table_right; - Airbrush_next_time = SDL_GetTicks()+Airbrush_delay*10; - Airbrush(RIGHT_SIDE); - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - -void Airbrush_12_2(void) -// -// Opération : OPERATION_AIRBRUSH -// Click Souris: 1 ou 2 -// Taille_Pile : 2 -// -// Souris effacée: Non -// -{ - short old_x,old_y; - - Operation_pop(&old_y); - Operation_pop(&old_x); - - if ( (Menu_is_visible) && ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y)) ) - { - Hide_cursor(); - Print_coordinates(); - Display_cursor(); - } - - if (SDL_GetTicks()>Airbrush_next_time) - { - Airbrush_next_time+=Airbrush_delay*10; - Airbrush(Mouse_K_unique); - } - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - -void Airbrush_0_2(void) -// -// Opération : OPERATION_AIRBRUSH -// Click Souris: 0 -// Taille_Pile : 2 -// -// Souris effacée: Non -// -{ - Operation_stack_size-=2; -} - - -////////////////////////////////////////////////////////// OPERATION_POLYGON - - -void Polygon_12_0(void) -// Opération : OPERATION_POLYGON -// Click Souris: 1 ou 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui -{ - byte color; - - Init_start_operation(); - Backup(); - Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right; - Paintbrush_shape_before_operation=Paintbrush_shape; - Paintbrush_shape=PAINTBRUSH_SHAPE_POINT; - - color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color; - - // On place temporairement le début de la ligne qui ne s'afficherait pas sinon - Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color); - Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); - - if ((Config.Coords_rel) && (Menu_is_visible)) - Print_in_menu("X:± 0 Y:± 0",0); - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(Mouse_K | 0x80); - Operation_push(color); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - // Taille de pile 8 : phase d'appui, non interruptible -} - - - -void Polygon_12_9(void) -// Opération : OPERATION_POLYGON -// Click Souris: 1 ou 2 -// Taille_Pile : 9 -// -// Souris effacée: Oui -{ - short start_x; - short start_y; - short end_x; - short end_y; - short color; - short direction; - - Operation_pop(&end_y); - Operation_pop(&end_x); - Operation_pop(&start_y); - Operation_pop(&start_x); - Operation_pop(&color); - Operation_pop(&direction); - Operation_pop(&direction); - - if (direction==Mouse_K) - { - Operation_push(direction); - Operation_push(color); - Operation_push(start_x); - Operation_push(start_y); - Operation_push(end_x); - Operation_push(end_y); - // Taille de pile 8 : phase d'appui, non interruptible - } - else - { - // La série de ligne est terminée, il faut donc effacer la dernière - // preview de ligne et relier le dernier point avec le premier - Pixel_figure_preview_auto (start_x,start_y); - Hide_line_preview (start_x,start_y,end_x,end_y); - Operation_pop(&end_y); - Operation_pop(&end_x); - Paintbrush_shape=Paintbrush_shape_before_operation; - // Le pied aurait été de ne pas repasser sur le 1er point de la 1ère ligne - // mais c'est pas possible :( - Draw_line_permanet(start_x,start_y,end_x,end_y,color); - Paintbrush_shape=PAINTBRUSH_SHAPE_POINT; - - Display_cursor(); - Wait_end_of_click(); - Hide_cursor(); - - if ( (Config.Coords_rel) && (Menu_is_visible) ) - { - Print_in_menu("X: Y: ",0); - Print_coordinates(); - } - - Paintbrush_shape=Paintbrush_shape_before_operation; - } -} - - -////////////////////////////////////////////////////////// OPERATION_POLYFILL - -short * Polyfill_table_of_points; -int Polyfill_number_of_points; - -void Polyfill_12_0(void) -// Opération : OPERATION_POLYFILL -// Click Souris: 1 ou 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui -{ - byte color; - - Init_start_operation(); - Backup(); - Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right; - Paintbrush_hidden=1; - - color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color; - - Polyfill_table_of_points=(short *) malloc((Config.Nb_max_vertices_per_polygon<<1)*sizeof(short)); - Polyfill_table_of_points[0]=Paintbrush_X; - Polyfill_table_of_points[1]=Paintbrush_Y; - Polyfill_number_of_points=1; - - // On place temporairement le début de la ligne qui ne s'afficherait pas sinon - Pixel_figure_preview_xor(Paintbrush_X,Paintbrush_Y,0); - Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); - - if ((Config.Coords_rel) && (Menu_is_visible)) - Print_in_menu("X:± 0 Y:± 0",0); - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(Mouse_K | 0x80); - Operation_push(color); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - // Taille de pile 8 : phase d'appui, non interruptible -} - - -void Polyfill_0_8(void) -// Opération : OPERATION_POLYFILL -// Click Souris: 0 -// Taille_Pile : 8 -// -// Souris effacée: Oui -{ - short start_x; - short start_y; - short end_x; - short end_y; - short color; - short direction; - - Operation_pop(&end_y); - Operation_pop(&end_x); - Operation_pop(&start_y); - Operation_pop(&start_x); - Operation_pop(&color); - Operation_pop(&direction); - - if ((Config.Coords_rel) && (Menu_is_visible)) - Print_in_menu("X:± 0 Y:± 0",0); - - Draw_line_preview_xor(start_x,start_y,end_x,end_y,0); - - if (direction & 0x80) - direction=(direction & 0x7F); - - Operation_push(direction); // Valeur bidon servant de nouvel état de pile - Operation_push(direction); - Operation_push(color); - - Draw_line_preview_xor(start_x,start_y,Paintbrush_X,Paintbrush_Y,0); - - if (Polyfill_number_of_points1) width--; - if (height>1) height--; - } - - Num2str(width,str,4); - Print_in_menu(str,2); - Num2str(height,str,4); - Print_in_menu(str,11); - } - else - Print_coordinates(); - } - - Display_all_screen(); - - x=Paintbrush_X; - y=Paintbrush_Y; - if (Snap_mode && Config.Adjust_brush_pick) - { - dx=Paintbrush_X-start_x; - dy=Paintbrush_Y-start_y; - if (dx<0) x++; else {if (dx>0) x--;} - if (dy<0) y++; else {if (dy>0) y--;} - Stretch_brush_preview(start_x,start_y,x,y); - } - else - Stretch_brush_preview(start_x,start_y,Paintbrush_X,Paintbrush_Y); - - old_x=Paintbrush_X; - old_y=Paintbrush_Y; - Paintbrush_X=start_x; - Paintbrush_Y=start_y; - Display_cursor(); - Paintbrush_X=old_x; - Paintbrush_Y=old_y; - Display_cursor(); - - Operation_stack_size-=2; - Operation_push(x); - Operation_push(y); - - Operation_push(start_x); - Operation_push(start_y); - } - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(2); -} - - - -void Stretch_brush_0_7(void) -// -// Opération : OPERATION_STRETCH_BRUSH -// Click Souris: 0 -// Taille_Pile : 7 -// -// Souris effacée: Non -// -{ - char str[5]; - short start_x; - short start_y; - short old_x; - short old_y; - short width=0; - short height=0; - byte size_change; - short prev_state; - - Operation_pop(&prev_state); - Operation_pop(&old_y); - Operation_pop(&old_x); - Operation_pop(&start_y); - Operation_pop(&start_x); - - if ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y) || (prev_state!=3)) - { - if (Menu_is_visible) - { - if (Config.Coords_rel) - { - width=((start_x1)?start_x+(Brush_width>>1)-1:1; - height=(Brush_height>1)?start_y+(Brush_height>>1)-1:1; - break; - case 'X': // Moitié X - width=(Brush_width>1)?start_x+(Brush_width>>1)-1:1; - height=start_y+Brush_height-1; - break; - case 'Y': // Moitié Y - width=start_x+Brush_width-1; - height=(Brush_height>1)?start_y+(Brush_height>>1)-1:1; - break; - case 'n': // Normal - width=start_x+Brush_width-1; - height=start_y+Brush_height-1; - break; - default : - size_change=0; - } - Key_ANSI=0; - } - else - size_change=0; - - if (size_change) - { - // On efface la preview de la brosse (et la croix) - Display_all_screen(); - - old_x=Paintbrush_X; - old_y=Paintbrush_Y; - Paintbrush_X=start_x; - Paintbrush_Y=start_y; - Display_cursor(); - Paintbrush_X=old_x; - Paintbrush_Y=old_y; - - Stretch_brush_preview(start_x,start_y,width,height); - Display_cursor(); - - Operation_stack_size-=2; - Operation_push(width); - Operation_push(height); - } - - Operation_push(start_x); - Operation_push(start_y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(3); -} - - -void Stretch_brush_2_7(void) -// -// Opération : OPERATION_STRETCH_BRUSH -// Click Souris: 2 -// Taille_Pile : 7 -// -// Souris effacée: Oui -// -{ - short computed_x; - short computed_y; - short start_x; - short start_y; - - - Operation_stack_size-=3; - Operation_pop(&start_y); - Operation_pop(&start_x); - Operation_pop(&computed_y); - Operation_pop(&computed_x); - - // On efface la preview de la brosse (et la croix) - Display_all_screen(); - - // Et enfin on stocke pour de bon la nouvelle brosse étirée - Stretch_brush(start_x,start_y,computed_x,computed_y); - - Return_to_draw_mode(); -} - - -//////////////////////////////////////////////////// OPERATION_ROTATE_BRUSH - - -void Rotate_brush_12_0(void) -// -// Opération : OPERATION_ROTATE_BRUSH -// Click Souris: 1 ou 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui -// -{ - Init_start_operation(); - if (Mouse_K==LEFT_SIDE) - { - Brush_rotation_center_X=Paintbrush_X+(Brush_width>>1)-Brush_width; - Brush_rotation_center_Y=Paintbrush_Y; - Brush_rotation_center_is_defined=1; - Operation_push(Paintbrush_X); // Dernière position calculée X - Operation_push(Paintbrush_Y); // Dernière position calculée Y - Operation_push(Paintbrush_X); // Dernière position X - Operation_push(Paintbrush_Y); // Dernière position Y - Operation_push(1); // State précédent - - if ((Config.Coords_rel) && (Menu_is_visible)) - Print_in_menu("Angle: 0° ",0); - } - else - { - Start_operation_stack(Operation_before_interrupt); - Wait_end_of_click(); // FIXME: celui-la il donne un résultat pas très chouette en visuel - } -} - - - -void Rotate_brush_1_5(void) -// -// Opération : OPERATION_ROTATE_BRUSH -// Click Souris: 1 -// Taille_Pile : 5 -// -// Souris effacée: Non -// -{ - char str[4]; - short old_x; - short old_y; - short prev_state; - float angle; - int dx,dy; - - Operation_pop(&prev_state); - Operation_pop(&old_y); - Operation_pop(&old_x); - - if ( (Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y) || (prev_state!=2) ) - { - if ( (Brush_rotation_center_X==Paintbrush_X) - && (Brush_rotation_center_Y==Paintbrush_Y) ) - angle=0.0; - else - { - dx=Paintbrush_X-Brush_rotation_center_X; - dy=Paintbrush_Y-Brush_rotation_center_Y; - angle=acos(((float)dx)/sqrt((dx*dx)+(dy*dy))); - if (dy>0) angle=M_2PI-angle; - } - - if (Menu_is_visible) - { - if (Config.Coords_rel) - { - Num2str((int)(angle*180.0/M_PI),str,3); - Print_in_menu(str,7); - } - else - Print_coordinates(); - } - - Display_all_screen(); - Rotate_brush_preview(angle); - Display_cursor(); - - Operation_stack_size-=2; - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - } - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(2); -} - - - -void Rotate_brush_0_5(void) -// -// Opération : OPERATION_ROTATE_BRUSH -// Click Souris: 0 -// Taille_Pile : 5 -// -// Souris effacée: Non -// -{ - char str[4]; - short old_x; - short old_y; - short computed_x=0; - short computed_y=0; - byte angle_change; - short prev_state; - float angle=0.0; - int dx,dy; - - Operation_pop(&prev_state); - Operation_pop(&old_y); - Operation_pop(&old_x); - - if ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y) || (prev_state!=3)) - { - if ( (Brush_rotation_center_X==Paintbrush_X) - && (Brush_rotation_center_Y==Paintbrush_Y) ) - angle=0.0; - else - { - dx=Paintbrush_X-Brush_rotation_center_X; - dy=Paintbrush_Y-Brush_rotation_center_Y; - angle=acos(((float)dx)/sqrt((dx*dx)+(dy*dy))); - if (dy>0) angle=M_2PI-angle; - } - - if (Menu_is_visible) - { - if (Config.Coords_rel) - { - Num2str(Round(angle*180.0/M_PI),str,3); - Print_in_menu(str,7); - } - else - Print_coordinates(); - } - } - - // Utilise Key_ANSI au lieu de Key, car Get_input() met ce dernier - // à zero si une operation est en cours (Operation_stack_size!=0) - if (Key_ANSI) - { - angle_change=1; - computed_x=Brush_rotation_center_X; - computed_y=Brush_rotation_center_Y; - switch (Key_ANSI) - { - case '6': angle= 0.0 ; computed_x++; break; - case '9': angle=M_PI*0.25; computed_x++; computed_y--; break; - case '8': angle=M_PI*0.5 ; computed_y--; break; - case '7': angle=M_PI*0.75; computed_x--; computed_y--; break; - case '4': angle=M_PI ; computed_x--; break; - case '1': angle=M_PI*1.25; computed_x--; computed_y++; break; - case '2': angle=M_PI*1.5 ; computed_y++; break; - case '3': angle=M_PI*1.75; computed_x++; computed_y++; break; - default : - angle_change=0; - } - Key_ANSI=0; - } - else - angle_change=0; - - if (angle_change) - { - // On efface la preview de la brosse - Display_all_screen(); - Rotate_brush_preview(angle); - Display_cursor(); - - Operation_stack_size-=2; - Operation_push(computed_x); - Operation_push(computed_y); - } - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(3); -} - - -void Rotate_brush_2_5(void) -// -// Opération : OPERATION_ROTATE_BRUSH -// Click Souris: 2 -// Taille_Pile : 5 -// -// Souris effacée: Oui -// -{ - short computed_x; - short computed_y; - int dx,dy; - float angle; - - - // On efface la preview de la brosse - Display_all_screen(); - - Operation_stack_size-=3; - Operation_pop(&computed_y); - Operation_pop(&computed_x); - - // Calcul de l'angle par rapport à la dernière position calculée - if ( (Brush_rotation_center_X==computed_x) - && (Brush_rotation_center_Y==computed_y) ) - angle=0.0; - else - { - dx=computed_x-Brush_rotation_center_X; - dy=computed_y-Brush_rotation_center_Y; - angle=acos(((float)dx)/sqrt((dx*dx)+(dy*dy))); - if (dy>0) angle=M_2PI-angle; - } - - // Et enfin on stocke pour de bon la nouvelle brosse étirée - Rotate_brush(angle); - - Return_to_draw_mode(); -} - -///////////////////////////////////////////////////// OPERATION_DISTORT_BRUSH - -/// Draws a 2x2 XOR square at the specified picture coordinates, on the screen. -void Draw_stretch_spot(short x_pos, short y_pos) -{ - short x,y; - - for (y=y_pos-1;y=Limit_top && y<=Limit_visible_bottom) - for (x=x_pos-1;x=Limit_left && x<=Limit_visible_right) - Pixel_preview(x,y,~Read_pixel(x-Main_offset_X,y-Main_offset_Y)); - Update_part_of_screen(x_pos-1, y_pos-1, 2, 2); -} - -void Distort_brush_0_0(void) -// -// Opération : OPERATION_DISTORT_BRUSH -// Click Souris: 0 -// Taille_Pile : 0 -// -// Souris effacée: Non -// -{ - if ( Menu_is_visible ) - { - Print_in_menu("POSITION BRUSH TO START ",0); - } -} - -void Distort_brush_1_0(void) -// -// Opération : OPERATION_DISTORT_BRUSH -// Click Souris: 1 -// Taille_Pile : 0 -// -// Souris effacée: Non -// -{ - short x_pos, y_pos; - - Init_start_operation(); - Paintbrush_hidden=1; - Hide_cursor(); - - // Top left angle - x_pos=Paintbrush_X-Brush_offset_X; - y_pos=Paintbrush_Y-Brush_offset_Y; - Draw_stretch_spot(x_pos,y_pos); - Operation_push(x_pos); - Operation_push(y_pos); - - // Top right angle - x_pos+=Brush_width; - Draw_stretch_spot(x_pos,y_pos); - Operation_push(x_pos); - Operation_push(y_pos); - - // Bottom right angle - y_pos+=Brush_height; - Draw_stretch_spot(x_pos,y_pos); - Operation_push(x_pos); - Operation_push(y_pos); - - // Bottom left angle - x_pos-=Brush_width; - Draw_stretch_spot(x_pos,y_pos); - Operation_push(x_pos); - Operation_push(y_pos); - - Distort_brush_preview( - Operation_stack[1], - Operation_stack[2], - Operation_stack[3], - Operation_stack[4], - Operation_stack[5], - Operation_stack[6], - Operation_stack[7], - Operation_stack[8]); - Display_cursor(); - Update_part_of_screen(Paintbrush_X-Brush_offset_X, Paintbrush_Y-Brush_offset_Y, Brush_width, Brush_height); - Wait_end_of_click(); - // Erase the message in status bar - if ( (Config.Coords_rel) && (Menu_is_visible) ) - { - Print_in_menu("X: Y: ",0); - } -} - -void Distort_brush_1_8(void) -// -// Opération : OPERATION_DISTORT_BRUSH -// Click Souris: 1 -// Taille_Pile : 8 -// -// Souris effacée: No -// -{ - // How far (in pixels) you can catch a handle - #define REACH_DISTANCE 100 - short i; - short x[4]; - short y[4]; - long best_distance=REACH_DISTANCE; - short best_spot=-1; - - for (i=3;i>=0;i--) - { - long distance; - Operation_pop(&y[i]); - Operation_pop(&x[i]); - distance=Distance(Paintbrush_X,Paintbrush_Y,x[i],y[i]); - if (distance-1) - { - Operation_push(best_spot); - } - if ( (Config.Coords_rel) && (Menu_is_visible) ) - { - Print_in_menu("X: Y: ",0); - Print_coordinates(); - } -} - -void Distort_brush_1_9(void) -// -// Opération : OPERATION_DISTORT_BRUSH -// Click Souris: 1 -// Taille_Pile : 9 -// -// Souris effacée: No -// -{ - short i; - short x[4]; - short y[4]; - short selected_corner; - - // Pop all arguments - Operation_pop(&selected_corner); - for (i=3;i>=0;i--) - { - Operation_pop(&y[i]); - Operation_pop(&x[i]); - } - - if (Paintbrush_X!=x[selected_corner] || Paintbrush_Y!=y[selected_corner]) - { - Hide_cursor(); - - // Easiest refresh mode: make no assumptions on how the brush was - // displayed before. - Display_all_screen(); - - x[selected_corner]=Paintbrush_X; - y[selected_corner]=Paintbrush_Y; - - for (i=0;i<4;i++) - Draw_stretch_spot(x[i],y[i]); - - Distort_brush_preview(x[0],y[0],x[1],y[1],x[2],y[2],x[3],y[3]); - - Display_cursor(); - - if ( (Config.Coords_rel) && (Menu_is_visible) ) - { - Print_in_menu("X: Y: ",0); - Print_coordinates(); - } - Update_rect(0,0,Screen_width,Menu_Y); - } - - // Push back all arguments - for (i=0;i<4;i++) - { - Operation_push(x[i]); - Operation_push(y[i]); - } - Operation_push(selected_corner); - -} -void Distort_brush_0_9(void) -// -// Opération : OPERATION_DISTORT_BRUSH -// Click Souris: 0 -// Taille_Pile : 9 -// -// Souris effacée: No -// -{ - short selected_corner; - Operation_pop(&selected_corner); - -} - -void Distort_brush_2_0(void) -// -// Opération : OPERATION_DISTORT_BRUSH -// Click Souris: 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui -// -{ - Paintbrush_hidden=0; - Display_all_screen(); - // Erase the message in status bar - if ( (Config.Coords_rel) && (Menu_is_visible) ) - { - Print_in_menu("X: Y: ",0); - } - Return_to_draw_mode(); -} - -void Distort_brush_2_8(void) -// -// Opération : OPERATION_DISTORT_BRUSH -// Click Souris: 2 -// Taille_Pile : 8 -// -// Souris effacée: Oui -// -{ - short i; - short x[4]; - short y[4]; - - // Pop all arguments - for (i=3;i>=0;i--) - { - Operation_pop(&y[i]); - Operation_pop(&x[i]); - } - Distort_brush(x[0],y[0],x[1],y[1],x[2],y[2],x[3],y[3]); - - Paintbrush_hidden=0; - Display_all_screen(); - - Return_to_draw_mode(); -} - -//////////////////////////////////////////////////////////// OPERATION_SCROLL - - -byte Cursor_hidden_before_scroll; - -void Scroll_12_0(void) -// -// Opération : OPERATION_SCROLL -// Click Souris: 1 ou 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui -// -{ - Init_start_operation(); - Backup(); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Cursor_hidden_before_scroll=Cursor_hidden; - Cursor_hidden=1; - if ((Config.Coords_rel) && (Menu_is_visible)) - Print_in_menu("X:± 0 Y:± 0",0); -} - - -void Scroll_12_4(void) -// -// Opération : OPERATION_SCROLL -// Click Souris: 1 ou 2 -// Taille_Pile : 4 -// -// Souris effacée: Non -// -{ - short center_x; - short center_y; - short x_pos; - short y_pos; - short x_offset; - short y_offset; - //char str[5]; - - Operation_pop(&y_pos); - Operation_pop(&x_pos); - Operation_pop(¢er_y); - Operation_pop(¢er_x); - - if ( (Paintbrush_X!=x_pos) || (Paintbrush_Y!=y_pos) ) - { - // L'utilisateur a bougé, il faut scroller l'image - - if (Paintbrush_X>=center_x) - x_offset=(Paintbrush_X-center_x)%Main_image_width; - else - x_offset=Main_image_width-((center_x-Paintbrush_X)%Main_image_width); - - if (Paintbrush_Y>=center_y) - y_offset=(Paintbrush_Y-center_y)%Main_image_height; - else - y_offset=Main_image_height-((center_y-Paintbrush_Y)%Main_image_height); - - Display_coords_rel_or_abs(center_x,center_y); - - Scroll_picture(x_offset,y_offset); - - Display_all_screen(); - } - - Operation_push(center_x); - Operation_push(center_y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - -void Scroll_0_4(void) -// -// Opération : OPERATION_SCROLL -// Click Souris: 0 -// Taille_Pile : 4 -// -// Souris effacée: Oui -// -{ - Operation_stack_size-=4; - Cursor_hidden=Cursor_hidden_before_scroll; - if ((Config.Coords_rel) && (Menu_is_visible)) - { - Print_in_menu("X: Y: ",0); - Print_coordinates(); - } -} - - -//////////////////////////////////////////////////// OPERATION_GRAD_CIRCLE - - -void Grad_circle_12_0(void) -// -// Opération : OPERATION_GRAD_CIRCLE -// Click Souris: 1 ou 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui -{ - byte color; - - Init_start_operation(); - Backup(); - - Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right; - color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color; - - Paintbrush_hidden_before_scroll=Paintbrush_hidden; - Paintbrush_hidden=1; - - Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color); - Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); - - if ((Config.Coords_rel) && (Menu_is_visible)) - Print_in_menu("Radius: 0 ",0); - - Operation_push(Mouse_K); - Operation_push(color); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -void Grad_circle_12_6(void) -// -// Opération : OPERATION_GRAD_CIRCLE -// Click Souris: 1 ou 2 -// Taille_Pile : 6 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente) -// -// Souris effacée: Non -// -{ - short tangent_x; - short tangent_y; - short center_x; - short center_y; - short color; - short radius; - char str[5]; - - Operation_pop(&tangent_y); - Operation_pop(&tangent_x); - Operation_pop(¢er_y); - Operation_pop(¢er_x); - Operation_pop(&color); - - if ( (tangent_x!=Paintbrush_X) || (tangent_y!=Paintbrush_Y) ) - { - Hide_cursor(); - if ((Config.Coords_rel) && (Menu_is_visible)) - { - Num2str(Distance(center_x,center_y,Paintbrush_X,Paintbrush_Y),str,4); - Print_in_menu(str,7); - } - else - Print_coordinates(); - - Circle_limit=((tangent_x-center_x)*(tangent_x-center_x))+ - ((tangent_y-center_y)*(tangent_y-center_y)); - radius=sqrt(Circle_limit); - Hide_empty_circle_preview(center_x,center_y,radius); - - Circle_limit=((Paintbrush_X-center_x)*(Paintbrush_X-center_x))+ - ((Paintbrush_Y-center_y)*(Paintbrush_Y-center_y)); - radius=sqrt(Circle_limit); - Draw_empty_circle_preview(center_x,center_y,radius,color); - - Display_cursor(); - } - - Operation_push(color); - Operation_push(center_x); - Operation_push(center_y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -void Grad_circle_0_6(void) -// -// Opération : OPERATION_GRAD_CIRCLE -// Click Souris: 0 -// Taille_Pile : 6 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente) -// -// Souris effacée: Oui -// -{ - short tangent_x; - short tangent_y; - short center_x; - short center_y; - short color; - short click; - short radius; - - Operation_pop(&tangent_y); - Operation_pop(&tangent_x); - Operation_pop(¢er_y); - Operation_pop(¢er_x); - - Operation_pop(&color); - Operation_pop(&click); - - if (click==LEFT_SIDE) - { - Operation_push(click); - Operation_push(color); - - Operation_push(center_x); - Operation_push(center_y); - Operation_push(tangent_x); - Operation_push(tangent_y); - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - - // On change la forme du curseur - Cursor_shape=CURSOR_SHAPE_XOR_TARGET; - - // On affiche une croix XOR au centre du cercle - Draw_curve_cross(center_x,center_y); - - if (Menu_is_visible) - { - if (Config.Coords_rel) - Print_in_menu("X: Y:",0); - else - Print_in_menu("X: Y: ",0); - Display_coords_rel_or_abs(center_x,center_y); - } - } - else - { - Circle_limit=((tangent_x-center_x)*(tangent_x-center_x))+ - ((tangent_y-center_y)*(tangent_y-center_y)); - radius=sqrt(Circle_limit); - Hide_empty_circle_preview(center_x,center_y,radius); - - Paintbrush_hidden=Paintbrush_hidden_before_scroll; - Cursor_shape=CURSOR_SHAPE_TARGET; - - Draw_filled_circle(center_x,center_y,radius,Back_color); - - if ((Config.Coords_rel) && (Menu_is_visible)) - { - Print_in_menu("X: Y: ",0); - Print_coordinates(); - } - } -} - - -void Grad_circle_12_8(void) -// -// Opération : OPERATION_GRAD_CIRCLE -// Click Souris: 0 -// Taille_Pile : 8 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente, old_x, old_y) -// -// Souris effacée: Oui -// -{ - short tangent_x; - short tangent_y; - short center_x; - short center_y; - short color; - short old_mouse_k; - - short radius; - - Operation_stack_size-=2; // On fait sauter les 2 derniers élts de la pile - Operation_pop(&tangent_y); - Operation_pop(&tangent_x); - Operation_pop(¢er_y); - Operation_pop(¢er_x); - Operation_pop(&color); - Operation_pop(&old_mouse_k); - - Hide_cursor(); - // On efface la croix XOR au centre du cercle - Draw_curve_cross(center_x,center_y); - - Circle_limit=((tangent_x-center_x)*(tangent_x-center_x))+ - ((tangent_y-center_y)*(tangent_y-center_y)); - radius=sqrt(Circle_limit); - Hide_empty_circle_preview(center_x,center_y,radius); - - Paintbrush_hidden=Paintbrush_hidden_before_scroll; - Cursor_shape=CURSOR_SHAPE_TARGET; - - if (Mouse_K==old_mouse_k) - Draw_grad_circle(center_x,center_y,radius,Paintbrush_X,Paintbrush_Y); - - Display_cursor(); - Wait_end_of_click(); - - if ((Config.Coords_rel) && (Menu_is_visible)) - { - Print_in_menu("X: Y: ",0); - Print_coordinates(); - } -} - - -void Grad_circle_or_ellipse_0_8(void) -// -// Opération : OPERATION_{CERCLE|ELLIPSE}_DEGRADE -// Click Souris: 0 -// Taille_Pile : 8 -// -// Souris effacée: Non -// -{ - short start_x; - short start_y; - short tangent_x; - short tangent_y; - short old_x; - short old_y; - - Operation_pop(&old_y); - Operation_pop(&old_x); - - if ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y)) - { - Operation_pop(&tangent_y); - Operation_pop(&tangent_x); - Operation_pop(&start_y); - Operation_pop(&start_x); - Display_coords_rel_or_abs(start_x,start_y); - Operation_push(start_x); - Operation_push(start_y); - Operation_push(tangent_x); - Operation_push(tangent_y); - } - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -////////////////////////////////////////////////// OPERATION_GRAD_ELLIPSE - - -void Grad_ellipse_12_0(void) -// -// Opération : OPERATION_GRAD_ELLIPSE -// Click Souris: 1 ou 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui -{ - byte color; - - Init_start_operation(); - Backup(); - - Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right; - color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color; - - Paintbrush_hidden_before_scroll=Paintbrush_hidden; - Paintbrush_hidden=1; - - Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color); - Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); - - if ((Config.Coords_rel) && (Menu_is_visible)) - Print_in_menu("X:± 0 Y:± 0",0); - - Operation_push(Mouse_K); - Operation_push(color); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -void Grad_ellipse_12_6(void) -// -// Opération : OPERATION_GRAD_ELLIPSE -// Click Souris: 1 ou 2 -// Taille_Pile : 6 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente) -// -// Souris effacée: Non -// -{ - short tangent_x; - short tangent_y; - short center_x; - short center_y; - short color; - short horizontal_radius; - short vertical_radius; - - Operation_pop(&tangent_y); - Operation_pop(&tangent_x); - Operation_pop(¢er_y); - Operation_pop(¢er_x); - Operation_pop(&color); - - if ( (tangent_x!=Paintbrush_X) || (tangent_y!=Paintbrush_Y) ) - { - Hide_cursor(); - Display_coords_rel_or_abs(center_x,center_y); - - horizontal_radius=(tangent_x>center_x)?tangent_x-center_x - :center_x-tangent_x; - vertical_radius =(tangent_y>center_y)?tangent_y-center_y - :center_y-tangent_y; - Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius); - - horizontal_radius=(Paintbrush_X>center_x)?Paintbrush_X-center_x - :center_x-Paintbrush_X; - vertical_radius =(Paintbrush_Y>center_y)?Paintbrush_Y-center_y - :center_y-Paintbrush_Y; - Draw_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius,color); - - Display_cursor(); - } - - Operation_push(color); - Operation_push(center_x); - Operation_push(center_y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -void Grad_ellipse_0_6(void) -// -// Opération : OPERATION_GRAD_ELLIPSE -// Click Souris: 0 -// Taille_Pile : 6 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente) -// -// Souris effacée: Oui -// -{ - short tangent_x; - short tangent_y; - short center_x; - short center_y; - short color; - short click; - //short radius; - short horizontal_radius; - short vertical_radius; - - Operation_pop(&tangent_y); - Operation_pop(&tangent_x); - Operation_pop(¢er_y); - Operation_pop(¢er_x); - - Operation_pop(&color); - Operation_pop(&click); - - if (click==LEFT_SIDE) - { - Operation_push(click); - Operation_push(color); - - Operation_push(center_x); - Operation_push(center_y); - Operation_push(tangent_x); - Operation_push(tangent_y); - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - - // On change la forme du curseur - Cursor_shape=CURSOR_SHAPE_XOR_TARGET; - - // On affiche une croix XOR au centre du cercle - Draw_curve_cross(center_x,center_y); - - if (Menu_is_visible) - { - if (Config.Coords_rel) - Print_in_menu("X: Y:",0); - else - Print_in_menu("X: Y: ",0); - Display_coords_rel_or_abs(center_x,center_y); - } - } - else - { - horizontal_radius=(tangent_x>center_x)?tangent_x-center_x - :center_x-tangent_x; - vertical_radius =(tangent_y>center_y)?tangent_y-center_y - :center_y-tangent_y; - Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius); - - Paintbrush_hidden=Paintbrush_hidden_before_scroll; - Cursor_shape=CURSOR_SHAPE_TARGET; - - Draw_filled_ellipse(center_x,center_y,horizontal_radius,vertical_radius,Back_color); - - if ((Config.Coords_rel) && (Menu_is_visible)) - { - Print_in_menu("X: Y: ",0); - Print_coordinates(); - } - } -} - - -void Grad_ellipse_12_8(void) -// -// Opération : OPERATION_GRAD_ELLIPSE -// Click Souris: 0 -// Taille_Pile : 8 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente, old_x, old_y) -// -// Souris effacée: Oui -// -{ - short tangent_x; - short tangent_y; - short center_x; - short center_y; - short color; - short horizontal_radius; - short vertical_radius; - short old_mouse_k; - - Operation_stack_size-=2; // On fait sauter les 2 derniers élts de la pile - Operation_pop(&tangent_y); - Operation_pop(&tangent_x); - Operation_pop(¢er_y); - Operation_pop(¢er_x); - Operation_pop(&color); - Operation_pop(&old_mouse_k); - - Hide_cursor(); - // On efface la croix XOR au centre de l'ellipse - Draw_curve_cross(center_x,center_y); - - horizontal_radius=(tangent_x>center_x)?tangent_x-center_x - :center_x-tangent_x; - vertical_radius =(tangent_y>center_y)?tangent_y-center_y - :center_y-tangent_y; - Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius); - - Paintbrush_hidden=Paintbrush_hidden_before_scroll; - Cursor_shape=CURSOR_SHAPE_TARGET; - - if (Mouse_K==old_mouse_k) - Draw_grad_ellipse(center_x,center_y,horizontal_radius,vertical_radius,Paintbrush_X,Paintbrush_Y); - - Display_cursor(); - - Wait_end_of_click(); - - if ((Config.Coords_rel) && (Menu_is_visible)) - { - Print_in_menu("X: Y: ",0); - Print_coordinates(); - } -} - -/****************************** -* Operation_Rectangle_Degrade * -******************************/ - -// 1) tracé d'un rectangle classique avec les lignes XOR -// 2) tracé d'une ligne vecteur de dégradé, comme une ligne normale -// 3) dessin du dégradé - - -void Grad_rectangle_12_0(void) -// Opération : OPERATION_GRAD_RECTANGLE -// Click Souris: 1 ou 2 -// Taille_Pile : 0 -// -// Souris effacée: Oui - -// Initialisation de l'étape 1, on commence à dessiner le rectangle -{ - Init_start_operation(); - Backup(); - - if ((Config.Coords_rel) && (Menu_is_visible)) - Print_in_menu("\035: 1 \022: 1",0); - // On laisse une trace du curseur à l'écran - Display_cursor(); - - if (Mouse_K==LEFT_SIDE) - { - Shade_table=Shade_table_left; - Operation_push(Mouse_K); - } - else - { - Shade_table=Shade_table_right; - Operation_push(Mouse_K); - } - - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -void Grad_rectangle_12_5(void) -// Opération : OPERATION_GRAD_RECTANGLE -// Click Souris: 1 ou 2 -// Taille_Pile : 5 -// -// Souris effacée: Non - -// Modification de la taille du rectangle -{ - short start_x; - short start_y; - short old_x; - short old_y; - char str[5]; - - Operation_pop(&old_y); - Operation_pop(&old_x); - - if ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y)) - { - Operation_pop(&start_y); - Operation_pop(&start_x); - - if ((Config.Coords_rel) && (Menu_is_visible)) - { - Num2str(((start_x Min(Main_image_width,Main_magnifier_mode?Main_separator_position:Screen_width)) // Tous les clippings à gérer sont là - offset_width = Max(rax,rbx) - Min(Main_image_width,Main_magnifier_mode?Main_separator_position:Screen_width); - - if (Max(ray,rby)-Main_offset_Y > Min(Main_image_height,Menu_Y)) - offset_height = Max(ray,rby) - Min(Main_image_height,Menu_Y); - - // Dessin dans la zone de dessin normale - Horizontal_XOR_line(Min(rax,rbx)-Main_offset_X,Min(ray,rby)-Main_offset_Y,width - offset_width); - if(offset_height == 0) - Horizontal_XOR_line(Min(rax,rbx)-Main_offset_X,Max(ray,rby)-1-Main_offset_Y,width - offset_width); - - Vertical_XOR_line(Min(rax,rbx)-Main_offset_X,Min(ray,rby)-Main_offset_Y,height-offset_height); - if (offset_width == 0) // Sinon cette ligne est en dehors de la zone image, inutile de la dessiner - Vertical_XOR_line(Max(rax,rbx)-1-Main_offset_X,Min(ray,rby)-Main_offset_Y,height-offset_height); - - Update_rect(Min(rax,rbx)-Main_offset_X,Min(ray,rby)-Main_offset_Y,width+1-offset_width,height+1-offset_height); - - // Dessin dans la zone zoomée - if(Main_magnifier_mode && Min(rax,rbx)Limit_left_zoom && Min(ray,rby)Limit_top_zoom ) - { - offset_width = 0; - offset_height=0; - - if(Min(rax,rbx)Limit_visible_right_zoom) // On dépasse du zoom à droite - offset_width += Max(rax,rbx) - Limit_visible_right_zoom; - - if(Min(ray,rby)Limit_visible_bottom_zoom) // On dépasse du zoom en bas - offset_height += Max(ray,rby) - Limit_visible_bottom_zoom; - - if(width > offset_width) - { - if(offset_top==0) // La ligne du haut est visible - Horizontal_XOR_line_zoom(offset_left>0?offset_left:Min(rax,rbx),Min(ray,rby),width-offset_width); - - if(Max(ray,rby)0?offset_left:Min(rax,rbx),Max(ray,rby),width-offset_width); - } - - if(height>offset_height) - { - if(offset_left==0) // La ligne de gauche est visible - Vertical_XOR_line_zoom(Min(rax,rbx),offset_top>0?offset_top:Min(ray,rby),height-offset_height); - - if(Max(rax,rbx)0?offset_top:Min(ray,rby),height-offset_height); - } - } - - Operation_push(rax); - Operation_push(ray); - Operation_push(rbx); - Operation_push(rby); - - // On ajoute des trucs dans la pile pour forcer le passage à l'étape suivante - Operation_push(rbx); - Operation_push(rby); -} - -void Grad_rectangle_0_7(void) -// OPERATION_GRAD_RECTANGLE -// click souris 0 -// Taile pile : 5 -// -// Souris effacée : non - -// On continue à attendre que l'utilisateur clique en gardant les coords à jour -{ - Operation_stack_size -= 2; - Print_coordinates(); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - -void Grad_rectangle_12_7(void) -// Opération : OPERATION_GRAD_RECTANGLE -// Click Souris: 1 ou 2 -// Taille_Pile : 7 -// -// Souris effacée: Oui - -// Début du tracé du vecteur (premier clic) -// On garde les anciennes coordonnées dans la pile, et on ajoute les nouvelles par dessus - -// Si l'utilisateur utilise le mauvais bouton, on annule le tracé. Mais ça nous oblige à vider toute la pile pour vérifier :( -{ - short rax,rbx,ray,rby,vax,vay,click; - - Operation_pop(&vay); - Operation_pop(&vax); - Operation_pop(&ray); - Operation_pop(&rax); - Operation_pop(&rby); - Operation_pop(&rbx); - Operation_pop(&click); - - - if(click==Mouse_K) - { - Operation_push(click); - Operation_push(rbx); - Operation_push(rby); - Operation_push(rax); - Operation_push(ray); - Operation_push(vax); - Operation_push(vay); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - - } - else - { - // Mauvais bouton > anulation de l'opération. - // On a déjà vidé la pile, il reste à effacer le rectangle XOR - short width, height; - short offset_width = 0; - short offset_height = 0; - short offset_left = 0; - short offset_top = 0; - - width = abs(rbx-rax); - height = abs(rby-ray); - - if (Max(rax,rbx)-Main_offset_X > Min(Main_image_width,Main_magnifier_mode?Main_separator_position:Screen_width)) // Tous les clippings à gérer sont là - offset_width = Max(rax,rbx) - Min(Main_image_width,Main_magnifier_mode?Main_separator_position:Screen_width); - - if (Max(ray,rby)-Main_offset_Y > Min(Main_image_height,Menu_Y)) - offset_height = Max(ray,rby) - Min(Main_image_height,Menu_Y); - - // Dessin dans la zone de dessin normale - Horizontal_XOR_line(Min(rax,rbx)-Main_offset_X,Min(ray,rby)-Main_offset_Y,width - offset_width); - if(offset_height == 0) - Horizontal_XOR_line(Min(rax,rbx)-Main_offset_X,Max(ray,rby)-1-Main_offset_Y,width - offset_width); - - Vertical_XOR_line(Min(rax,rbx)-Main_offset_X,Min(ray,rby)-Main_offset_Y,height-offset_height); - if (offset_width == 0) // Sinon cette ligne est en dehors de la zone image, inutile de la dessiner - Vertical_XOR_line(Max(rax,rbx)-1-Main_offset_X,Min(ray,rby)-Main_offset_Y,height-offset_height); - - Update_rect(Min(rax,rbx)-Main_offset_X,Min(ray,rby)-Main_offset_Y,width+1-offset_width,height+1-offset_height); - - // Dessin dans la zone zoomée - if(Main_magnifier_mode && Min(rax,rbx)Limit_left_zoom && Min(ray,rby)Limit_top_zoom ) - { - offset_width = 0; - offset_height=0; - - if(Min(rax,rbx)Limit_visible_right_zoom) // On dépasse du zoom à droite - offset_width += Max(rax,rbx) - Limit_visible_right_zoom; - - if(Min(ray,rby)Limit_visible_bottom_zoom) // On dépasse du zoom en bas - offset_height += Max(ray,rby) - Limit_visible_bottom_zoom; - - if(width > offset_width) - { - if(offset_top==0) // La ligne du haut est visible - Horizontal_XOR_line_zoom(offset_left>0?offset_left:Min(rax,rbx),Min(ray,rby),width-offset_width); - - if(Max(ray,rby)0?offset_left:Min(rax,rbx),Max(ray,rby),width-offset_width); - } - - if(height>offset_height) - { - if(offset_left==0) // La ligne de gauche est visible - Vertical_XOR_line_zoom(Min(rax,rbx),offset_top>0?offset_top:Min(ray,rby),height-offset_height); - - if(Max(rax,rbx)0?offset_top:Min(ray,rby),height-offset_height); - } - } - } -} - -void Grad_rectangle_12_9(void) - // Opération : OPERATION_GRAD_RECTANGLE - // Click Souris: 1 - // Taille_Pile : 5 - // - // Souris effacée: Oui - - // Poursuite du tracé du vecteur (déplacement de la souris en gardant le curseur appuyé) -{ - short start_x; - short start_y; - short end_x; - short end_y; - short cursor_x; - short cursor_y; - - Operation_pop(&end_y); - Operation_pop(&end_x); - Operation_pop(&start_y); - Operation_pop(&start_x); - - cursor_x = Paintbrush_X; - cursor_y = Paintbrush_Y; - // On corrige les coordonnées de la ligne si la touche shift est appuyée... - if(SDL_GetModState() & KMOD_SHIFT) - Clamp_coordinates_regular_angle(start_x,start_y,&cursor_x,&cursor_y); - - if ((cursor_x!=end_x) || (cursor_y!=end_y)) - { - Display_coords_rel_or_abs(start_x,start_y); - - Draw_line_preview_xor(start_x,start_y,end_x,end_y,0); - Draw_line_preview_xor(start_x,start_y,cursor_x,cursor_y,0); - - } - - - Operation_push(start_x); - Operation_push(start_y); - Operation_push(cursor_x); - Operation_push(cursor_y); -} - -void Grad_rectangle_0_9(void) - // Opération : OPERATION_GRAD_RECTANGLE - // Click Souris: 0 - // Taille_Pile : 9 - // - // Souris effacée: Oui - - // Ouf, fini ! on dessine enfin le rectangle avec son dégradé -{ - short rect_start_x; - short rect_start_y; - short rect_end_x; - short rect_end_y; - - short vector_start_x; - short vector_start_y; - short vector_end_x; - short vector_end_y; - - Operation_pop(&vector_end_y); - Operation_pop(&vector_end_x); - Operation_pop(&vector_start_y); - Operation_pop(&vector_start_x); - Operation_pop(&rect_end_y); - Operation_pop(&rect_end_x); - Operation_pop(&rect_start_y); - Operation_pop(&rect_start_x); - Operation_stack_size--; - - Hide_cursor(); - // Maintenant on efface tout le bazar temporaire : rectangle et ligne XOR - Hide_line_preview(vector_start_x,vector_start_y,vector_end_x,vector_end_y); - - // Et enfin on trace le rectangle avec le dégradé dedans ! - if (vector_end_x==vector_start_x && vector_end_y==vector_start_y) - { - // Vecteur nul > pas de rectangle tracé - // Du coup on doit effacer la preview xor ... - short width, height; - short offset_width = 0; - short offset_height = 0; - short offset_left = 0; - short offset_top = 0; - - width = abs(rect_end_x-rect_start_x); - height = abs(rect_end_y-rect_start_y); - - if (Max(rect_start_x,rect_end_x)-Main_offset_X > Min(Main_image_width,Main_magnifier_mode?Main_separator_position:Screen_width)) // Tous les clippings à gérer sont là - offset_width = Max(rect_start_x,rect_end_x) - Min(Main_image_width,Main_magnifier_mode?Main_separator_position:Screen_width); - - if (Max(rect_start_y,rect_end_y)-Main_offset_Y > Min(Main_image_height,Menu_Y)) - offset_height = Max(rect_start_y,rect_end_y) - Min(Main_image_height,Menu_Y); - - // Dessin dans la zone de dessin normale - Horizontal_XOR_line(Min(rect_start_x,rect_end_x)-Main_offset_X,Min(rect_start_y,rect_end_y)-Main_offset_Y,width - offset_width); - if(offset_height == 0) - Horizontal_XOR_line(Min(rect_start_x,rect_end_x)-Main_offset_X,Max(rect_start_y,rect_end_y)-1-Main_offset_Y,width - offset_width); - - Vertical_XOR_line(Min(rect_start_x,rect_end_x)-Main_offset_X,Min(rect_start_y,rect_end_y)-Main_offset_Y,height-offset_height); - if (offset_width == 0) // Sinon cette ligne est en dehors de la zone image, inutile de la dessiner - Vertical_XOR_line(Max(rect_start_x,rect_end_x)-1-Main_offset_X,Min(rect_start_y,rect_end_y)-Main_offset_Y,height-offset_height); - - Update_rect(Min(rect_start_x,rect_end_x)-Main_offset_X,Min(rect_start_y,rect_end_y)-Main_offset_Y,width+1-offset_width,height+1-offset_height); - - // Dessin dans la zone zoomée - if(Main_magnifier_mode && Min(rect_start_x,rect_end_x)Limit_left_zoom && Min(rect_start_y,rect_end_y)Limit_top_zoom ) - { - offset_width = 0; - offset_height=0; - - if(Min(rect_start_x,rect_end_x)Limit_visible_right_zoom) // On dépasse du zoom à droite - offset_width += Max(rect_start_x,rect_end_x) - Limit_visible_right_zoom; - - if(Min(rect_start_y,rect_end_y)Limit_visible_bottom_zoom) // On dépasse du zoom en bas - offset_height += Max(rect_start_y,rect_end_y) - Limit_visible_bottom_zoom; - - if(width > offset_width) - { - if(offset_top==0) // La ligne du haut est visible - Horizontal_XOR_line_zoom(offset_left>0?offset_left:Min(rect_start_x,rect_end_x),Min(rect_start_y,rect_end_y),width-offset_width); - - if(Max(rect_start_y,rect_end_y)0?offset_left:Min(rect_start_x,rect_end_x),Max(rect_start_y,rect_end_y),width-offset_width); - } - - if(height>offset_height) - { - if(offset_left==0) // La ligne de gauche est visible - Vertical_XOR_line_zoom(Min(rect_start_x,rect_end_x),offset_top>0?offset_top:Min(rect_start_y,rect_end_y),height-offset_height); - - if(Max(rect_start_x,rect_end_x)0?offset_top:Min(rect_start_y,rect_end_y),height-offset_height); - } - } - } - else - Draw_grad_rectangle(rect_start_x,rect_start_y,rect_end_x,rect_end_y,vector_start_x,vector_start_y,vector_end_x,vector_end_y); - - Display_cursor(); - Wait_end_of_click(); - - if ((Config.Coords_rel) && (Menu_is_visible)) - { - Print_in_menu("X: Y: ",0); - Print_coordinates(); - } -} -/////////////////////////////////////////////////// OPERATION_CENTERED_LINES - - -void Centered_lines_12_0(void) - // Opération : OPERATION_CENTERED_LINES - // Click Souris: 1 ou 2 - // Taille_Pile : 0 - // - // Souris effacée: Oui -{ - Init_start_operation(); - Backup(); - Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right; - - if ((Config.Coords_rel) && (Menu_is_visible)) - Print_in_menu("X:± 0 Y:± 0",0); - - Operation_push(Mouse_K); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -void Centered_lines_12_3(void) - // Opération : OPERATION_CENTERED_LINES - // Click Souris: 1 ou 2 - // Taille_Pile : 3 - // - // Souris effacée: Non -{ - short start_x; - short start_y; - - Operation_pop(&start_y); - Operation_pop(&start_x); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - -void Centered_lines_0_3(void) - // Opération : OPERATION_CENTERED_LINES - // Click Souris: 0 - // Taille_Pile : 3 - // - // Souris effacée: Oui -{ - short start_x; - short start_y; - short Button; - short color; - - Operation_pop(&start_y); - Operation_pop(&start_x); - Operation_pop(&Button); - - color=(Button==LEFT_SIDE)?Fore_color:Back_color; - - Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color); - Paintbrush_shape_before_operation=Paintbrush_shape; - Paintbrush_shape=PAINTBRUSH_SHAPE_POINT; - - Operation_push(Button); - Operation_push(Paintbrush_X); // Nouveau début X - Operation_push(Paintbrush_Y); // Nouveau début Y - Operation_push(Paintbrush_X); // Nouvelle dernière fin X - Operation_push(Paintbrush_Y); // Nouvelle dernière fin Y - Operation_push(Paintbrush_X); // Nouvelle dernière position X - Operation_push(Paintbrush_Y); // Nouvelle dernière position Y -} - - -void Centered_lines_12_7(void) - // Opération : OPERATION_CENTERED_LINES - // Click Souris: 1 ou 2 - // Taille_Pile : 7 - // - // Souris effacée: Non -{ - short Button; - short start_x; - short start_y; - short end_x; - short end_y; - short last_x; - short last_y; - short color; - - Operation_pop(&last_y); - Operation_pop(&last_x); - Operation_pop(&end_y); - Operation_pop(&end_x); - Operation_pop(&start_y); - Operation_pop(&start_x); - Operation_pop(&Button); - - if (Mouse_K==Button) - { - if ( (end_x!=Paintbrush_X) || (end_y!=Paintbrush_Y) || - (last_x!=Paintbrush_X) || (last_y!=Paintbrush_Y) ) - { - Hide_cursor(); - - color=(Button==LEFT_SIDE)?Fore_color:Back_color; - - Paintbrush_shape=Paintbrush_shape_before_operation; - - Pixel_figure_preview_auto (start_x,start_y); - Hide_line_preview (start_x,start_y,last_x,last_y); - - Smear_start=1; - Display_paintbrush (start_x,start_y,color,0); - Draw_line_permanet(start_x,start_y,Paintbrush_X,Paintbrush_Y,color); - - Paintbrush_shape=PAINTBRUSH_SHAPE_POINT; - Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color); - Draw_line_preview(start_x,start_y,Paintbrush_X,Paintbrush_Y,color); - - Display_cursor(); - } - - Operation_push(Button); - Operation_push(start_x); - Operation_push(start_y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); - } - else - { - Hide_cursor(); - - Paintbrush_shape=Paintbrush_shape_before_operation; - - Pixel_figure_preview_auto (start_x,start_y); - Hide_line_preview (start_x,start_y,last_x,last_y); - - if ( (Config.Coords_rel) && (Menu_is_visible) ) - { - Print_in_menu("X: Y: ",0); - Print_coordinates(); - } - - Display_cursor(); - Wait_end_of_click(); - } -} - - -void Centered_lines_0_7(void) - // Opération : OPERATION_CENTERED_LINES - // Click Souris: 0 - // Taille_Pile : 7 - // - // Souris effacée: Non -{ - short Button; - short start_x; - short start_y; - short end_x; - short end_y; - short last_x; - short last_y; - short color; - - Operation_pop(&last_y); - Operation_pop(&last_x); - Operation_pop(&end_y); - Operation_pop(&end_x); - - if ((Paintbrush_X!=last_x) || (Paintbrush_Y!=last_y)) - { - Hide_cursor(); - Operation_pop(&start_y); - Operation_pop(&start_x); - Operation_pop(&Button); - - color=(Button==LEFT_SIDE)?Fore_color:Back_color; - - Display_coords_rel_or_abs(start_x,start_y); - - Hide_line_preview(start_x,start_y,last_x,last_y); - - Pixel_figure_preview(start_x,start_y,color); - Draw_line_preview(start_x,start_y,Paintbrush_X,Paintbrush_Y,color); - - Operation_push(Button); - Operation_push(start_x); - Operation_push(start_y); - Display_cursor(); - } - - Operation_push(end_x); - Operation_push(end_y); - Operation_push(Paintbrush_X); - Operation_push(Paintbrush_Y); -} - - +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2007 Adrien Destugues + Copyright 2009 Franck Charlet + 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 +*/ +#include +#include +#include + +#include "const.h" +#include "struct.h" +#include "global.h" +#include "misc.h" +#include "engine.h" +#include "graph.h" +#include "operatio.h" +#include "buttons.h" +#include "pages.h" +#include "errors.h" +#include "sdlscreen.h" +#include "brush.h" +#include "windows.h" + +#if defined(__GP2X__) + #define M_PI 3.14159265358979323846 +#endif + +/// Time (in SDL ticks) when the next airbrush drawing should be done. Also used +/// for discontinuous freehand drawing. +Uint32 Airbrush_next_time; + +void Start_operation_stack(word new_operation) +{ + Brush_rotation_center_is_defined=0; + + // On mémorise l'opération précédente si on démarre une interruption + switch(new_operation) + { + case OPERATION_MAGNIFY : + case OPERATION_COLORPICK : + case OPERATION_GRAB_BRUSH : + case OPERATION_POLYBRUSH : + case OPERATION_STRETCH_BRUSH : + case OPERATION_ROTATE_BRUSH: + Operation_before_interrupt=Current_operation; + // On passe à l'operation demandée + Current_operation=new_operation; + break; + default : + // On passe à l'operation demandée + Current_operation=new_operation; + Operation_before_interrupt=Current_operation; + } + + // On spécifie si l'opération autorise le changement de couleur au clavier + switch(new_operation) + { + case OPERATION_CONTINUOUS_DRAW: + case OPERATION_DISCONTINUOUS_DRAW: + case OPERATION_AIRBRUSH: + case OPERATION_CENTERED_LINES: + Allow_color_change_during_operation=1; + break; + default : + Allow_color_change_during_operation=0; + } + + // Et on passe au curseur qui va avec + Cursor_shape=CURSOR_FOR_OPERATION[new_operation]; + Operation_stack_size=0; +} + + +void Init_start_operation(void) +{ + Operation_in_magnifier=(Mouse_X>=Main_X_zoom); + Smear_start=1; +} + + +void Operation_push(short value) +{ + Operation_stack[++Operation_stack_size]=value; +} + + +void Operation_pop(short * value) +{ + *value=Operation_stack[Operation_stack_size--]; +} + + +byte Paintbrush_shape_before_operation; +byte Paintbrush_hidden_before_scroll; + + + +short Distance(short x1, short y1, short x2, short y2) +{ + short x2_moins_x1=x2-x1; + short y2_minus_y1=y2-y1; + + return Round( sqrt( (x2_moins_x1*x2_moins_x1) + (y2_minus_y1*y2_minus_y1) ) ); +} + + +void Display_coords_rel_or_abs(short start_x, short start_y) +{ + char str[6]; + + if (Config.Coords_rel) + { + if (Menu_is_visible) + { + if (Paintbrush_X>start_x) + { + Num2str(Paintbrush_X-start_x,str,5); + str[0]='+'; + } + else if (Paintbrush_Xstart_y) + { + Num2str(Paintbrush_Y-start_y,str,5); + str[0]='+'; + } + else if (Paintbrush_YAirbrush_next_time) + { + Airbrush_next_time+=Airbrush_delay*10; + Hide_cursor(); + // On affiche définitivement le pinceau + Display_paintbrush(Paintbrush_X,Paintbrush_Y,Fore_color,0); + Display_cursor(); + } + } + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + +// ---------- + +void Freehand_mode2_2_0(void) +// Opération : OPERATION_DISCONTINUOUS_DRAW +// Click Souris: 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui +{ + Init_start_operation(); + Backup(); + Shade_table=Shade_table_right; + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Print_coordinates(); + Airbrush_next_time = SDL_GetTicks() + Airbrush_delay*10; + // On affiche définitivement le pinceau + Display_paintbrush(Paintbrush_X,Paintbrush_Y,Back_color,0); +} + + +void Freehand_mode2_2_2(void) +// Opération : OPERATION_DISCONTINUOUS_DRAW +// Click Souris: 2 +// Taille_Pile : 2 +// +// Souris effacée: Non +{ + short start_x; + short start_y; + + Operation_pop(&start_y); + Operation_pop(&start_x); + + if ( (start_x!=Paintbrush_X) || (start_y!=Paintbrush_Y) ) + { + Print_coordinates(); + if (SDL_GetTicks()>Airbrush_next_time) + { + Airbrush_next_time+=Airbrush_delay*10; + Hide_cursor(); + // On affiche définitivement le pinceau + Display_paintbrush(Paintbrush_X,Paintbrush_Y,Back_color,0); + Display_cursor(); + } + } + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +////////////////////////////////////////////////////// OPERATION_POINT_DRAW + +void Freehand_mode3_1_0(void) +// Opération : OPERATION_POINT_DRAW +// Click Souris: 1 +// Taille_Pile : 0 +// +// Souris effacée: Oui +{ + Init_start_operation(); + Backup(); + Shade_table=Shade_table_left; + // On affiche définitivement le pinceau + Display_paintbrush(Paintbrush_X,Paintbrush_Y,Fore_color,0); + Operation_push(0); // On change simplement l'état de la pile... +} + + +void Freehand_Mode3_2_0(void) +// Opération : OPERATION_POINT_DRAW +// Click Souris: 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui +{ + Init_start_operation(); + Backup(); + Shade_table=Shade_table_right; + // On affiche définitivement le pinceau + Display_paintbrush(Paintbrush_X,Paintbrush_Y,Back_color,0); + Operation_push(0); // On change simplement l'état de la pile... +} + + +void Freehand_mode3_0_1(void) +// Opération : OPERATION_POINT_DRAW +// Click Souris: 0 +// Taille_Pile : 1 +// +// Souris effacée: Non +{ + Operation_stack_size--; +} + + +///////////////////////////////////////////////////////////// OPERATION_LINE + +void Line_12_0(void) +// Opération : OPERATION_LINE +// Click Souris: 1 ou 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui + +// Début du tracé d'une ligne (premier clic) +{ + Init_start_operation(); + Backup(); + Paintbrush_shape_before_operation=Paintbrush_shape; + Paintbrush_shape=PAINTBRUSH_SHAPE_POINT; + + if (Mouse_K==LEFT_SIDE) + { + Shade_table=Shade_table_left; + Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,Fore_color); + Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); + Operation_push(Fore_color); + } + else + { + Shade_table=Shade_table_right; + Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,Back_color); + Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); + Operation_push(Back_color); + } + + if ((Config.Coords_rel) && (Menu_is_visible)) + Print_in_menu("X:± 0 Y:± 0",0); + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +void Line_12_5(void) +// Opération : OPERATION_LINE +// Click Souris: 1 +// Taille_Pile : 5 +// +// Souris effacée: Non + +// Poursuite du tracé d'une ligne (déplacement de la souris en gardant le +// curseur appuyé) +{ + short start_x; + short start_y; + short end_x; + short end_y; + + short cursor_x; + short cursor_y; + + Operation_pop(&end_y); + Operation_pop(&end_x); + Operation_pop(&start_y); + Operation_pop(&start_x); + + cursor_x = Paintbrush_X; + cursor_y = Paintbrush_Y; + + // On corrige les coordonnées de la ligne si la touche shift est appuyée... + if(SDL_GetModState() & KMOD_SHIFT) + { + Clamp_coordinates_regular_angle(start_x,start_y,&cursor_x,&cursor_y); + } + + // On vient de bouger + if ((cursor_x!=end_x) || (cursor_y!=end_y)) + { + Hide_cursor(); + + Display_coords_rel_or_abs(start_x,start_y); + + Hide_line_preview(start_x,start_y,end_x,end_y); + if (Mouse_K==LEFT_SIDE) + { + Pixel_figure_preview (start_x,start_y,Fore_color); + Draw_line_preview (start_x,start_y,cursor_x,cursor_y,Fore_color); + } + else + { + Pixel_figure_preview (start_x,start_y,Back_color); + Draw_line_preview (start_x,start_y,cursor_x,cursor_y,Back_color); + } + + Operation_push(start_x); + Operation_push(start_y); + Operation_push(cursor_x); + Operation_push(cursor_y); + + Display_cursor(); + } + else + { + Operation_push(start_x); + Operation_push(start_y); + Operation_push(end_x); + Operation_push(end_y); + } +} + + +void Line_0_5(void) +// Opération : OPERATION_LINE +// Click Souris: 0 +// Taille_Pile : 5 +// +// Souris effacée: Oui + +// End du tracé d'une ligne (relachage du bouton) +{ + short start_x; + short start_y; + short end_x; + short end_y; + short color; + + Operation_pop(&end_y); + Operation_pop(&end_x); + Operation_pop(&start_y); + Operation_pop(&start_x); + Operation_pop(&color); + + Paintbrush_shape=Paintbrush_shape_before_operation; + + Pixel_figure_preview_auto (start_x,start_y); + Hide_line_preview (start_x,start_y,end_x,end_y); + Display_paintbrush (start_x,start_y,color,0); + Draw_line_permanet(start_x,start_y,end_x,end_y,color); + + if ( (Config.Coords_rel) && (Menu_is_visible) ) + { + Print_in_menu("X: Y: ",0); + Print_coordinates(); + } +} + + +/////////////////////////////////////////////////////////// OPERATION_K_LIGNE + + +void K_line_12_0(void) +// Opération : OPERATION_K_LIGNE +// Click Souris: 1 ou 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui +{ + byte color; + + Init_start_operation(); + Backup(); + Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right; + Paintbrush_shape_before_operation=Paintbrush_shape; + Paintbrush_shape=PAINTBRUSH_SHAPE_POINT; + + color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color; + + // On place temporairement le début de la ligne qui ne s'afficherait pas sinon + Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color); + + if ((Config.Coords_rel) && (Menu_is_visible)) + Print_in_menu("X:± 0 Y:± 0",0); + + Operation_push(Mouse_K | 0x80); + Operation_push(color); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + // Taille de pile 6 : phase d'appui, non interruptible +} + + +void K_line_12_6(void) +// Opération : OPERATION_K_LIGNE +// Click Souris: 1 ou 2 | 0 +// Taille_Pile : 6 | 7 +// +// Souris effacée: Non +{ + short start_x; + short start_y; + short end_x; + short end_y; + short color; + + Operation_pop(&end_y); + Operation_pop(&end_x); + + if ((Paintbrush_X!=end_x) || (Paintbrush_Y!=end_y)) + { + Hide_cursor(); + Operation_pop(&start_y); + Operation_pop(&start_x); + Operation_pop(&color); + + Display_coords_rel_or_abs(start_x,start_y); + + Hide_line_preview(start_x,start_y,end_x,end_y); + Pixel_figure_preview (start_x,start_y,color); + Draw_line_preview (start_x,start_y,Paintbrush_X,Paintbrush_Y,color); + + Operation_push(color); + Operation_push(start_x); + Operation_push(start_y); + Display_cursor(); + } + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +void K_line_0_6(void) +// Opération : OPERATION_K_LIGNE +// Click Souris: 0 +// Taille_Pile : 6 +// +// Souris effacée: Oui +{ + short start_x; + short start_y; + short end_x; + short end_y; + short color; + short direction; + + Operation_pop(&end_y); + Operation_pop(&end_x); + Operation_pop(&start_y); + Operation_pop(&start_x); + Operation_pop(&color); + Operation_pop(&direction); + + if ((Config.Coords_rel) && (Menu_is_visible)) + Print_in_menu("X:± 0 Y:± 0",0); + + Pixel_figure_preview_auto (start_x,start_y); + Hide_line_preview (start_x,start_y,end_x,end_y); + /* Doesn't work if fast moving + Pixel_figure_preview_xor (start_x,start_y, 0); + Draw_line_preview_xor (start_x,start_y,end_x,end_y,0); + */ + Paintbrush_shape=Paintbrush_shape_before_operation; + if (direction & 0x80) + { + Display_paintbrush(start_x,start_y,color,0); + direction=(direction & 0x7F); + } + Draw_line_permanet(start_x,start_y,Paintbrush_X,Paintbrush_Y,color); + Paintbrush_shape=PAINTBRUSH_SHAPE_POINT; + + Operation_push(direction); + Operation_push(direction); // Valeur bidon servant de nouvel état de pile + Operation_push(color); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + // Taille de pile 7 : phase de "repos", interruptible (comme Elliot Ness :)) +} + + +void K_line_12_7(void) +// Opération : OPERATION_K_LIGNE +// Click Souris: 1 ou 2 +// Taille_Pile : 7 +// +// Souris effacée: Oui +{ + short start_x; + short start_y; + short end_x; + short end_y; + short color; + short direction; + + Operation_pop(&end_y); + Operation_pop(&end_x); + Operation_pop(&start_y); + Operation_pop(&start_x); + Operation_pop(&color); + Operation_pop(&direction); + Operation_pop(&direction); + + if (direction==Mouse_K) + { + Operation_push(direction); + Operation_push(color); + Operation_push(start_x); + Operation_push(start_y); + Operation_push(end_x); + Operation_push(end_y); + // Taille de pile 6 : phase d'appui, non interruptible + } + else + { + // La série de ligne est terminée, il faut donc effacer la dernière + // preview de ligne + Pixel_figure_preview_auto (start_x,start_y); + Hide_line_preview (start_x,start_y,end_x,end_y); + + Display_cursor(); + Wait_end_of_click(); + Hide_cursor(); + Paintbrush_shape=Paintbrush_shape_before_operation; + + if ( (Config.Coords_rel) && (Menu_is_visible) ) + { + Print_in_menu("X: Y: ",0); + Print_coordinates(); + } + } +} + + +// ---------------------------------------------------------- OPERATION_MAGNIFY + + +void Magnifier_12_0(void) + +// Opération : 4 (item d'une Loupe) +// Click Souris: 1 ou 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui + +{ + + // On passe en mode loupe + Main_magnifier_mode=1; + + // La fonction d'affichage dans la partie image est désormais un affichage + // spécial loupe. + Pixel_preview=Pixel_preview_magnifier; + + // On calcule l'origine de la loupe + Main_magnifier_offset_X=Mouse_X-(Main_magnifier_width>>1); + Main_magnifier_offset_Y=Mouse_Y-(Main_magnifier_height>>1); + + // Calcul du coin haut_gauche de la fenêtre devant être zoomée DANS L'ECRAN + if (Main_magnifier_offset_X+Main_magnifier_width>=Limit_right-Main_offset_X) + Main_magnifier_offset_X=Limit_right-Main_magnifier_width-Main_offset_X+1; + if (Main_magnifier_offset_Y+Main_magnifier_height>=Limit_bottom-Main_offset_Y) + Main_magnifier_offset_Y=Limit_bottom-Main_magnifier_height-Main_offset_Y+1; + + // Calcul des coordonnées absolues de ce coin DANS L'IMAGE + Main_magnifier_offset_X+=Main_offset_X; + Main_magnifier_offset_Y+=Main_offset_Y; + + if (Main_magnifier_offset_X<0) + Main_magnifier_offset_X=0; + if (Main_magnifier_offset_Y<0) + Main_magnifier_offset_Y=0; + + // On calcule les bornes visibles dans l'écran + Position_screen_according_to_zoom(); + Compute_limits(); + Display_all_screen(); + + // Repositionner le curseur en fonction des coordonnées visibles + Compute_paintbrush_coordinates(); + + // On fait de notre mieux pour restaurer l'ancienne opération: + Start_operation_stack(Operation_before_interrupt); + Display_cursor(); + Wait_end_of_click(); +} + +/////////////////////////////////////////////////// OPERATION_RECTANGLE_????? + +void Rectangle_12_0(void) +// Opération : OPERATION_EMPTY_RECTANGLE / OPERATION_FILLED_RECTANGLE +// Click Souris: 1 ou 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui +{ + Init_start_operation(); + + if ((Config.Coords_rel) && (Menu_is_visible)) + Print_in_menu("\035: 1 \022: 1",0); + // On laisse une trace du curseur à l'écran + Display_cursor(); + + if (Mouse_K==LEFT_SIDE) + { + Shade_table=Shade_table_left; + Operation_push(Fore_color); + } + else + { + Shade_table=Shade_table_right; + Operation_push(Back_color); + } + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +void Rectangle_12_5(void) +// Opération : OPERATION_EMPTY_RECTANGLE / OPERATION_FILLED_RECTANGLE +// Click Souris: 1 ou 2 +// Taille_Pile : 5 +// +// Souris effacée: Non +{ + short start_x; + short start_y; + short old_x; + short old_y; + char str[5]; + + Operation_pop(&old_y); + Operation_pop(&old_x); + + if ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y)) + { + Operation_pop(&start_y); + Operation_pop(&start_x); + + if ((Config.Coords_rel) && (Menu_is_visible)) + { + Num2str(((start_xcenter_x)?tangent_x-center_x + :center_x-tangent_x; + vertical_radius =(tangent_y>center_y)?tangent_y-center_y + :center_y-tangent_y; + Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius); + + horizontal_radius=(Paintbrush_X>center_x)?Paintbrush_X-center_x + :center_x-Paintbrush_X; + vertical_radius =(Paintbrush_Y>center_y)?Paintbrush_Y-center_y + :center_y-Paintbrush_Y; + Draw_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius,color); + + Display_cursor(); + } + + Operation_push(color); + Operation_push(center_x); + Operation_push(center_y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +void Empty_ellipse_0_5(void) +// +// Opération : OPERATION_EMPTY_ELLIPSE +// Click Souris: 0 +// Taille_Pile : 5 (color, X_Centre, Y_Centre, X_Tangente, Y_Tangente) +// +// Souris effacée: Oui +// +{ + short tangent_x; + short tangent_y; + short center_x; + short center_y; + short color; + short horizontal_radius; + short vertical_radius; + + Operation_pop(&tangent_y); + Operation_pop(&tangent_x); + Operation_pop(¢er_y); + Operation_pop(¢er_x); + Operation_pop(&color); + + horizontal_radius=(tangent_x>center_x)?tangent_x-center_x + :center_x-tangent_x; + vertical_radius =(tangent_y>center_y)?tangent_y-center_y + :center_y-tangent_y; + Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius); + + Paintbrush_shape=Paintbrush_shape_before_operation; + + Draw_empty_ellipse_permanent(center_x,center_y,horizontal_radius,vertical_radius,color); + + if ( (Config.Coords_rel) && (Menu_is_visible) ) + { + Print_in_menu("X: Y: ",0); + Print_coordinates(); + } +} + + +void Filled_ellipse_0_5(void) +// +// Opération : OPERATION_FILLED_ELLIPSE +// Click Souris: 0 +// Taille_Pile : 5 (color, X_Centre, Y_Centre, X_Tangente, Y_Tangente) +// +// Souris effacée: Oui +// +{ + short tangent_x; + short tangent_y; + short center_x; + short center_y; + short color; + short horizontal_radius; + short vertical_radius; + + Operation_pop(&tangent_y); + Operation_pop(&tangent_x); + Operation_pop(¢er_y); + Operation_pop(¢er_x); + Operation_pop(&color); + + horizontal_radius=(tangent_x>center_x)?tangent_x-center_x + :center_x-tangent_x; + vertical_radius =(tangent_y>center_y)?tangent_y-center_y + :center_y-tangent_y; + Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius); + + Paintbrush_shape=Paintbrush_shape_before_operation; + + Draw_filled_ellipse(center_x,center_y,horizontal_radius,vertical_radius,color); + + if ( (Config.Coords_rel) && (Menu_is_visible) ) + { + Print_in_menu("X: Y: ",0); + Print_coordinates(); + } +} + + +////////////////////////////////////////////////////////////// OPERATION_FILL + + +void Fill_1_0(void) +// +// Opération : OPERATION_FILL +// Click Souris: 1 +// Taille_Pile : 0 +// +// Souris effacée: Oui +// +{ + Hide_cursor(); + // Pas besoin d'initialiser le début d'opération car le Smear n'affecte pas + // le Fill, et on se fout de savoir si on est dans la partie gauche ou + // droite de la loupe. + // On ne s'occupe pas de faire un Backup: c'est "Fill_general" qui s'en charge. + Shade_table=Shade_table_left; + Fill_general(Fore_color); + Display_cursor(); + Wait_end_of_click(); +} + + +void Fill_2_0(void) +// +// Opération : OPERATION_FILL +// Click Souris: 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui +// +{ + Hide_cursor(); + // Pas besoin d'initialiser le début d'opération car le Smear n'affecte pas + // le Fill, et on se fout de savoir si on est dans la partie gauche ou + // droite de la loupe. + // On ne s'occupe pas de faire un Backup: c'est "Fill_general" qui s'en charge. + Shade_table=Shade_table_right; + Fill_general(Back_color); + Display_cursor(); + Wait_end_of_click(); +} + + +///////////////////////////////////////////////////////// OPERATION_REPLACE + + +void Replace_1_0(void) +// +// Opération : OPERATION_REPLACE +// Click Souris: 1 +// Taille_Pile : 0 +// +// Souris effacée: Oui +// +{ + Hide_cursor(); + // Pas besoin d'initialiser le début d'opération car le Smear n'affecte pas + // le Replace, et on se fout de savoir si on est dans la partie gauche ou + // droite de la loupe. + Backup(); +// Shade_table=Shade_table_left; + Replace(Fore_color); + Display_cursor(); + Wait_end_of_click(); +} + + +void Replace_2_0(void) +// +// Opération : OPERATION_REPLACE +// Click Souris: 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui +// +{ + Hide_cursor(); + // Pas besoin d'initialiser le début d'opération car le Smear n'affecte pas + // le Replace, et on se fout de savoir si on est dans la partie gauche ou + // droite de la loupe. + Backup(); +// Shade_table=Shade_table_right; + Replace(Back_color); + Display_cursor(); + Wait_end_of_click(); +} + + +/////////////////////////////////////////////////////////// OPERATION_COLORPICK + + +void Colorpicker_12_0(void) +// +// Opération : OPERATION_COLORPICK +// Click Souris: 1 ou 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui +// +{ + Init_start_operation(); + + if (Mouse_K==LEFT_SIDE) + { + Set_fore_color(Colorpicker_color); + } + else + { + Set_back_color(Colorpicker_color); + } + Operation_push(Mouse_K); +} + + +void Colorpicker_1_1(void) +// +// Opération : OPERATION_COLORPICK +// Click Souris: 1 +// Taille_Pile : 1 +// +// Souris effacée: Non +// +{ + char str[4]; + + if ( (Paintbrush_X>=0) && (Paintbrush_Y>=0) + && (Paintbrush_X=0) && (Paintbrush_Y>=0) + && (Paintbrush_X=Limit_left+3) + start_x=0; + else + start_x=3-(x_pos-Limit_left); + + if (y_pos>=Limit_top+3) + start_y=0; + else + start_y=3-(y_pos-Limit_top); + + if (x_pos<=Limit_visible_right-3) + end_x=6; + else + end_x=3+(Limit_visible_right-x_pos); + + if (y_pos<=Limit_visible_bottom-3) + end_y=6; + else + end_y=3+(Limit_visible_bottom-y_pos); + + if (start_x<=end_x && start_y<=end_y) + { + for (i=start_x; i<=end_x; i++) + { + temp=x_pos+i-3; + Pixel_preview(temp,y_pos,~Read_pixel(temp -Main_offset_X, + y_pos-Main_offset_Y)); + } + for (i=start_y; i<=end_y; i++) + { + temp=y_pos+i-3; + Pixel_preview(x_pos,temp,~Read_pixel(x_pos-Main_offset_X, + temp -Main_offset_Y)); + } + Update_part_of_screen(x_pos+start_x-3,y_pos+start_y-3,end_x-start_x+1,end_y-start_y+1); + } +} + + +void Curve_34_points_1_0(void) +// +// Opération : OPERATION_COURBE_?_POINTS +// Click Souris: 1 +// Taille_Pile : 0 +// +// Souris effacée: Oui +// +{ + Init_start_operation(); + Backup(); + Shade_table=Shade_table_left; + + Paintbrush_hidden=1; + + Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,Fore_color); + Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); + + if ((Config.Coords_rel) && (Menu_is_visible)) + Print_in_menu("X:± 0 Y:± 0",0); + + Operation_push(Fore_color); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + +void Curve_34_points_2_0(void) +// +// Opération : OPERATION_COURBE_?_POINTS +// Click Souris: 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui +// +{ + Init_start_operation(); + Backup(); + Shade_table=Shade_table_right; + + Paintbrush_hidden=1; + + Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,Back_color); + Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); + + if ((Config.Coords_rel) && (Menu_is_visible)) + Print_in_menu("X:± 0 Y:± 0",0); + + Operation_push(Back_color); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +void Curve_34_points_1_5(void) +// +// Opération : OPERATION_COURBE_?_POINTS +// Click Souris: 1 +// Taille_Pile : 5 +// +// Souris effacée: Non +// +{ + short x1,x2,y1,y2; + + Operation_pop(&y2); + Operation_pop(&x2); + Operation_pop(&y1); + Operation_pop(&x1); + + if ( (y2!=Paintbrush_Y) || (x2!=Paintbrush_X) ) + { + Hide_cursor(); + Display_coords_rel_or_abs(x1,y1); + + Hide_line_preview(x1,y1,x2,y2); + Pixel_figure_preview (x1,y1,Fore_color); + Draw_line_preview (x1,y1,Paintbrush_X,Paintbrush_Y,Fore_color); + + Display_cursor(); + } + + Operation_push(x1); + Operation_push(y1); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + +void Curve_34_points_2_5(void) +// +// Opération : OPERATION_COURBE_?_POINTS +// Click Souris: 2 +// Taille_Pile : 5 +// +// Souris effacée: Non +// +{ + short x1,x2,y1,y2; + + Operation_pop(&y2); + Operation_pop(&x2); + Operation_pop(&y1); + Operation_pop(&x1); + + if ( (y2!=Paintbrush_Y) || (x2!=Paintbrush_X) ) + { + Hide_cursor(); + Display_coords_rel_or_abs(x1,y1); + + Hide_line_preview(x1,y1,x2,y2); + Pixel_figure_preview (x1,y1,Back_color); + Draw_line_preview (x1,y1,Paintbrush_X,Paintbrush_Y,Back_color); + + Display_cursor(); + } + + Operation_push(x1); + Operation_push(y1); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +byte Cursor_hidden_before_curve; + +void Curve_4_points_0_5(void) +// +// Opération : OPERATION_4_POINTS_CURVE +// Click Souris: 0 +// Taille_Pile : 5 +// +// Souris effacée: Oui +// +{ + short x1,y1,x2,y2,x3,y3,x4,y4; + short third_x,third_y; + short color; + + Operation_pop(&y4); + Operation_pop(&x4); + Operation_pop(&y1); + Operation_pop(&x1); + Operation_pop(&color); + + third_x=Round_div(abs(x4-x1),3); + third_y=Round_div(abs(y4-y1),3); + + if (x1B=(8/3) * C->P + *x3=Round((bx+x4)/2.0); // · _/·· P3 P2=milieu de [P1,B] + *y3=Round((by+y4)/2.0); // P4*-- P3=milieu de [P4,B] +} + + +void Curve_3_points_0_5(void) +// +// Opération : OPERATION_3_POINTS_CURVE +// Click Souris: 0 +// Taille_Pile : 5 +// +// Souris effacée: Oui +// +{ + short x1,y1,x2,y2,x3,y3,x4,y4; + short color; + + Operation_pop(&y4); + Operation_pop(&x4); + Operation_pop(&y1); + Operation_pop(&x1); + Operation_pop(&color); + + Compute_3_point_curve(x1,y1,x4,y4,&x2,&y2,&x3,&y3); + + Hide_line_preview(x1,y1,x4,y4); + Draw_curve_preview(x1,y1,x2,y2,x3,y3,x4,y4,color); + + if ( (Config.Coords_rel) && (Menu_is_visible) ) + { + Print_in_menu("X: Y: ",0); + Print_coordinates(); + } + + Operation_push(color); + Operation_push(x1); + Operation_push(y1); + Operation_push(x2); + Operation_push(y2); + Operation_push(x3); + Operation_push(y3); + Operation_push(x4); + Operation_push(y4); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +void Curve_3_points_0_11(void) +// +// Opération : OPERATION_3_POINTS_CURVE +// Click Souris: 0 +// Taille_Pile : 11 +// +// Souris effacée: Non +// +{ + short x1,y1,x2,y2,x3,y3,x4,y4; + short old_x,old_y; + short color; + + Operation_pop(&old_y); + Operation_pop(&old_x); + + if ( (Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y) ) + { + Operation_pop(&y4); + Operation_pop(&x4); + Operation_pop(&y3); + Operation_pop(&x3); + Operation_pop(&y2); + Operation_pop(&x2); + Operation_pop(&y1); + Operation_pop(&x1); + Operation_pop(&color); + + Hide_cursor(); + Print_coordinates(); + + Hide_curve_preview(x1,y1,x2,y2,x3,y3,x4,y4,color); + Compute_3_point_curve(x1,y1,x4,y4,&x2,&y2,&x3,&y3); + Draw_curve_preview (x1,y1,x2,y2,x3,y3,x4,y4,color); + Display_cursor(); + + Operation_push(color); + Operation_push(x1); + Operation_push(y1); + Operation_push(x2); + Operation_push(y2); + Operation_push(x3); + Operation_push(y3); + Operation_push(x4); + Operation_push(y4); + } + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +void Curve_3_points_12_11(void) +// +// Opération : OPERATION_3_POINTS_CURVE +// Click Souris: 1 ou 2 +// Taille_Pile : 11 +// +// Souris effacée: Oui +// +{ + short x1,y1,x2,y2,x3,y3,x4,y4; + short old_x,old_y; + short color; + + Operation_pop(&old_y); + Operation_pop(&old_x); + Operation_pop(&y4); + Operation_pop(&x4); + Operation_pop(&y3); + Operation_pop(&x3); + Operation_pop(&y2); + Operation_pop(&x2); + Operation_pop(&y1); + Operation_pop(&x1); + Operation_pop(&color); + + Paintbrush_hidden=0; + + Hide_cursor(); + + Hide_curve_preview (x1,y1,x2,y2,x3,y3,x4,y4,color); + Compute_3_point_curve(x1,y1,x4,y4,&x2,&y2,&x3,&y3); + Draw_curve_permanent(x1,y1,x2,y2,x3,y3,x4,y4,color); + + Display_cursor(); + Wait_end_of_click(); +} + + +///////////////////////////////////////////////////////////// OPERATION_AIRBRUSH + +void Airbrush_1_0(void) +// +// Opération : OPERATION_AIRBRUSH +// Click Souris: 1 +// Taille_Pile : 0 +// +// Souris effacée: Non +// +{ + Init_start_operation(); + Backup(); + Shade_table=Shade_table_left; + + Airbrush_next_time = SDL_GetTicks()+Airbrush_delay*10; + Airbrush(LEFT_SIDE); + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + +void Airbrush_2_0(void) +// +// Opération : OPERATION_AIRBRUSH +// Click Souris: 2 +// Taille_Pile : 0 +// +// Souris effacée: Non +// +{ + Init_start_operation(); + Backup(); + Shade_table=Shade_table_right; + Airbrush_next_time = SDL_GetTicks()+Airbrush_delay*10; + Airbrush(RIGHT_SIDE); + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + +void Airbrush_12_2(void) +// +// Opération : OPERATION_AIRBRUSH +// Click Souris: 1 ou 2 +// Taille_Pile : 2 +// +// Souris effacée: Non +// +{ + short old_x,old_y; + + Operation_pop(&old_y); + Operation_pop(&old_x); + + if ( (Menu_is_visible) && ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y)) ) + { + Hide_cursor(); + Print_coordinates(); + Display_cursor(); + } + + if (SDL_GetTicks()>Airbrush_next_time) + { + Airbrush_next_time+=Airbrush_delay*10; + Airbrush(Mouse_K_unique); + } + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + +void Airbrush_0_2(void) +// +// Opération : OPERATION_AIRBRUSH +// Click Souris: 0 +// Taille_Pile : 2 +// +// Souris effacée: Non +// +{ + Operation_stack_size-=2; +} + + +////////////////////////////////////////////////////////// OPERATION_POLYGON + + +void Polygon_12_0(void) +// Opération : OPERATION_POLYGON +// Click Souris: 1 ou 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui +{ + byte color; + + Init_start_operation(); + Backup(); + Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right; + Paintbrush_shape_before_operation=Paintbrush_shape; + Paintbrush_shape=PAINTBRUSH_SHAPE_POINT; + + color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color; + + // On place temporairement le début de la ligne qui ne s'afficherait pas sinon + Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color); + Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); + + if ((Config.Coords_rel) && (Menu_is_visible)) + Print_in_menu("X:± 0 Y:± 0",0); + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(Mouse_K | 0x80); + Operation_push(color); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + // Taille de pile 8 : phase d'appui, non interruptible +} + + + +void Polygon_12_9(void) +// Opération : OPERATION_POLYGON +// Click Souris: 1 ou 2 +// Taille_Pile : 9 +// +// Souris effacée: Oui +{ + short start_x; + short start_y; + short end_x; + short end_y; + short color; + short direction; + + Operation_pop(&end_y); + Operation_pop(&end_x); + Operation_pop(&start_y); + Operation_pop(&start_x); + Operation_pop(&color); + Operation_pop(&direction); + Operation_pop(&direction); + + if (direction==Mouse_K) + { + Operation_push(direction); + Operation_push(color); + Operation_push(start_x); + Operation_push(start_y); + Operation_push(end_x); + Operation_push(end_y); + // Taille de pile 8 : phase d'appui, non interruptible + } + else + { + // La série de ligne est terminée, il faut donc effacer la dernière + // preview de ligne et relier le dernier point avec le premier + Pixel_figure_preview_auto (start_x,start_y); + Hide_line_preview (start_x,start_y,end_x,end_y); + Operation_pop(&end_y); + Operation_pop(&end_x); + Paintbrush_shape=Paintbrush_shape_before_operation; + // Le pied aurait été de ne pas repasser sur le 1er point de la 1ère ligne + // mais c'est pas possible :( + Draw_line_permanet(start_x,start_y,end_x,end_y,color); + Paintbrush_shape=PAINTBRUSH_SHAPE_POINT; + + Display_cursor(); + Wait_end_of_click(); + Hide_cursor(); + + if ( (Config.Coords_rel) && (Menu_is_visible) ) + { + Print_in_menu("X: Y: ",0); + Print_coordinates(); + } + + Paintbrush_shape=Paintbrush_shape_before_operation; + } +} + + +////////////////////////////////////////////////////////// OPERATION_POLYFILL + +short * Polyfill_table_of_points; +int Polyfill_number_of_points; + +void Polyfill_12_0(void) +// Opération : OPERATION_POLYFILL +// Click Souris: 1 ou 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui +{ + byte color; + + Init_start_operation(); + Backup(); + Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right; + Paintbrush_hidden=1; + + color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color; + + Polyfill_table_of_points=(short *) malloc((Config.Nb_max_vertices_per_polygon<<1)*sizeof(short)); + Polyfill_table_of_points[0]=Paintbrush_X; + Polyfill_table_of_points[1]=Paintbrush_Y; + Polyfill_number_of_points=1; + + // On place temporairement le début de la ligne qui ne s'afficherait pas sinon + Pixel_figure_preview_xor(Paintbrush_X,Paintbrush_Y,0); + Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); + + if ((Config.Coords_rel) && (Menu_is_visible)) + Print_in_menu("X:± 0 Y:± 0",0); + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(Mouse_K | 0x80); + Operation_push(color); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + // Taille de pile 8 : phase d'appui, non interruptible +} + + +void Polyfill_0_8(void) +// Opération : OPERATION_POLYFILL +// Click Souris: 0 +// Taille_Pile : 8 +// +// Souris effacée: Oui +{ + short start_x; + short start_y; + short end_x; + short end_y; + short color; + short direction; + + Operation_pop(&end_y); + Operation_pop(&end_x); + Operation_pop(&start_y); + Operation_pop(&start_x); + Operation_pop(&color); + Operation_pop(&direction); + + if ((Config.Coords_rel) && (Menu_is_visible)) + Print_in_menu("X:± 0 Y:± 0",0); + + Draw_line_preview_xor(start_x,start_y,end_x,end_y,0); + + if (direction & 0x80) + direction=(direction & 0x7F); + + Operation_push(direction); // Valeur bidon servant de nouvel état de pile + Operation_push(direction); + Operation_push(color); + + Draw_line_preview_xor(start_x,start_y,Paintbrush_X,Paintbrush_Y,0); + + if (Polyfill_number_of_points1) width--; + if (height>1) height--; + } + + Num2str(width,str,4); + Print_in_menu(str,2); + Num2str(height,str,4); + Print_in_menu(str,11); + } + else + Print_coordinates(); + } + + Display_all_screen(); + + x=Paintbrush_X; + y=Paintbrush_Y; + if (Snap_mode && Config.Adjust_brush_pick) + { + dx=Paintbrush_X-start_x; + dy=Paintbrush_Y-start_y; + if (dx<0) x++; else {if (dx>0) x--;} + if (dy<0) y++; else {if (dy>0) y--;} + Stretch_brush_preview(start_x,start_y,x,y); + } + else + Stretch_brush_preview(start_x,start_y,Paintbrush_X,Paintbrush_Y); + + old_x=Paintbrush_X; + old_y=Paintbrush_Y; + Paintbrush_X=start_x; + Paintbrush_Y=start_y; + Display_cursor(); + Paintbrush_X=old_x; + Paintbrush_Y=old_y; + Display_cursor(); + + Operation_stack_size-=2; + Operation_push(x); + Operation_push(y); + + Operation_push(start_x); + Operation_push(start_y); + } + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(2); +} + + + +void Stretch_brush_0_7(void) +// +// Opération : OPERATION_STRETCH_BRUSH +// Click Souris: 0 +// Taille_Pile : 7 +// +// Souris effacée: Non +// +{ + char str[5]; + short start_x; + short start_y; + short old_x; + short old_y; + short width=0; + short height=0; + byte size_change; + short prev_state; + + Operation_pop(&prev_state); + Operation_pop(&old_y); + Operation_pop(&old_x); + Operation_pop(&start_y); + Operation_pop(&start_x); + + if ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y) || (prev_state!=3)) + { + if (Menu_is_visible) + { + if (Config.Coords_rel) + { + width=((start_x1)?start_x+(Brush_width>>1)-1:1; + height=(Brush_height>1)?start_y+(Brush_height>>1)-1:1; + break; + case 'X': // Moitié X + width=(Brush_width>1)?start_x+(Brush_width>>1)-1:1; + height=start_y+Brush_height-1; + break; + case 'Y': // Moitié Y + width=start_x+Brush_width-1; + height=(Brush_height>1)?start_y+(Brush_height>>1)-1:1; + break; + case 'n': // Normal + width=start_x+Brush_width-1; + height=start_y+Brush_height-1; + break; + default : + size_change=0; + } + Key_ANSI=0; + } + else + size_change=0; + + if (size_change) + { + // On efface la preview de la brosse (et la croix) + Display_all_screen(); + + old_x=Paintbrush_X; + old_y=Paintbrush_Y; + Paintbrush_X=start_x; + Paintbrush_Y=start_y; + Display_cursor(); + Paintbrush_X=old_x; + Paintbrush_Y=old_y; + + Stretch_brush_preview(start_x,start_y,width,height); + Display_cursor(); + + Operation_stack_size-=2; + Operation_push(width); + Operation_push(height); + } + + Operation_push(start_x); + Operation_push(start_y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(3); +} + + +void Stretch_brush_2_7(void) +// +// Opération : OPERATION_STRETCH_BRUSH +// Click Souris: 2 +// Taille_Pile : 7 +// +// Souris effacée: Oui +// +{ + short computed_x; + short computed_y; + short start_x; + short start_y; + + + Operation_stack_size-=3; + Operation_pop(&start_y); + Operation_pop(&start_x); + Operation_pop(&computed_y); + Operation_pop(&computed_x); + + // On efface la preview de la brosse (et la croix) + Display_all_screen(); + + // Et enfin on stocke pour de bon la nouvelle brosse étirée + Stretch_brush(start_x,start_y,computed_x,computed_y); + + Return_to_draw_mode(); +} + + +//////////////////////////////////////////////////// OPERATION_ROTATE_BRUSH + + +void Rotate_brush_12_0(void) +// +// Opération : OPERATION_ROTATE_BRUSH +// Click Souris: 1 ou 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui +// +{ + Init_start_operation(); + if (Mouse_K==LEFT_SIDE) + { + Brush_rotation_center_X=Paintbrush_X+(Brush_width>>1)-Brush_width; + Brush_rotation_center_Y=Paintbrush_Y; + Brush_rotation_center_is_defined=1; + Operation_push(Paintbrush_X); // Dernière position calculée X + Operation_push(Paintbrush_Y); // Dernière position calculée Y + Operation_push(Paintbrush_X); // Dernière position X + Operation_push(Paintbrush_Y); // Dernière position Y + Operation_push(1); // State précédent + + if ((Config.Coords_rel) && (Menu_is_visible)) + Print_in_menu("Angle: 0° ",0); + } + else + { + Start_operation_stack(Operation_before_interrupt); + Wait_end_of_click(); // FIXME: celui-la il donne un résultat pas très chouette en visuel + } +} + + + +void Rotate_brush_1_5(void) +// +// Opération : OPERATION_ROTATE_BRUSH +// Click Souris: 1 +// Taille_Pile : 5 +// +// Souris effacée: Non +// +{ + char str[4]; + short old_x; + short old_y; + short prev_state; + float angle; + int dx,dy; + + Operation_pop(&prev_state); + Operation_pop(&old_y); + Operation_pop(&old_x); + + if ( (Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y) || (prev_state!=2) ) + { + if ( (Brush_rotation_center_X==Paintbrush_X) + && (Brush_rotation_center_Y==Paintbrush_Y) ) + angle=0.0; + else + { + dx=Paintbrush_X-Brush_rotation_center_X; + dy=Paintbrush_Y-Brush_rotation_center_Y; + angle=acos(((float)dx)/sqrt((dx*dx)+(dy*dy))); + if (dy>0) angle=M_2PI-angle; + } + + if (Menu_is_visible) + { + if (Config.Coords_rel) + { + Num2str((int)(angle*180.0/M_PI),str,3); + Print_in_menu(str,7); + } + else + Print_coordinates(); + } + + Display_all_screen(); + Rotate_brush_preview(angle); + Display_cursor(); + + Operation_stack_size-=2; + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + } + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(2); +} + + + +void Rotate_brush_0_5(void) +// +// Opération : OPERATION_ROTATE_BRUSH +// Click Souris: 0 +// Taille_Pile : 5 +// +// Souris effacée: Non +// +{ + char str[4]; + short old_x; + short old_y; + short computed_x=0; + short computed_y=0; + byte angle_change; + short prev_state; + float angle=0.0; + int dx,dy; + + Operation_pop(&prev_state); + Operation_pop(&old_y); + Operation_pop(&old_x); + + if ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y) || (prev_state!=3)) + { + if ( (Brush_rotation_center_X==Paintbrush_X) + && (Brush_rotation_center_Y==Paintbrush_Y) ) + angle=0.0; + else + { + dx=Paintbrush_X-Brush_rotation_center_X; + dy=Paintbrush_Y-Brush_rotation_center_Y; + angle=acos(((float)dx)/sqrt((dx*dx)+(dy*dy))); + if (dy>0) angle=M_2PI-angle; + } + + if (Menu_is_visible) + { + if (Config.Coords_rel) + { + Num2str(Round(angle*180.0/M_PI),str,3); + Print_in_menu(str,7); + } + else + Print_coordinates(); + } + } + + // Utilise Key_ANSI au lieu de Key, car Get_input() met ce dernier + // à zero si une operation est en cours (Operation_stack_size!=0) + if (Key_ANSI) + { + angle_change=1; + computed_x=Brush_rotation_center_X; + computed_y=Brush_rotation_center_Y; + switch (Key_ANSI) + { + case '6': angle= 0.0 ; computed_x++; break; + case '9': angle=M_PI*0.25; computed_x++; computed_y--; break; + case '8': angle=M_PI*0.5 ; computed_y--; break; + case '7': angle=M_PI*0.75; computed_x--; computed_y--; break; + case '4': angle=M_PI ; computed_x--; break; + case '1': angle=M_PI*1.25; computed_x--; computed_y++; break; + case '2': angle=M_PI*1.5 ; computed_y++; break; + case '3': angle=M_PI*1.75; computed_x++; computed_y++; break; + default : + angle_change=0; + } + Key_ANSI=0; + } + else + angle_change=0; + + if (angle_change) + { + // On efface la preview de la brosse + Display_all_screen(); + Rotate_brush_preview(angle); + Display_cursor(); + + Operation_stack_size-=2; + Operation_push(computed_x); + Operation_push(computed_y); + } + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(3); +} + + +void Rotate_brush_2_5(void) +// +// Opération : OPERATION_ROTATE_BRUSH +// Click Souris: 2 +// Taille_Pile : 5 +// +// Souris effacée: Oui +// +{ + short computed_x; + short computed_y; + int dx,dy; + float angle; + + + // On efface la preview de la brosse + Display_all_screen(); + + Operation_stack_size-=3; + Operation_pop(&computed_y); + Operation_pop(&computed_x); + + // Calcul de l'angle par rapport à la dernière position calculée + if ( (Brush_rotation_center_X==computed_x) + && (Brush_rotation_center_Y==computed_y) ) + angle=0.0; + else + { + dx=computed_x-Brush_rotation_center_X; + dy=computed_y-Brush_rotation_center_Y; + angle=acos(((float)dx)/sqrt((dx*dx)+(dy*dy))); + if (dy>0) angle=M_2PI-angle; + } + + // Et enfin on stocke pour de bon la nouvelle brosse étirée + Rotate_brush(angle); + + Return_to_draw_mode(); +} + +///////////////////////////////////////////////////// OPERATION_DISTORT_BRUSH + +/// Draws a 2x2 XOR square at the specified picture coordinates, on the screen. +void Draw_stretch_spot(short x_pos, short y_pos) +{ + short x,y; + + for (y=y_pos-1;y=Limit_top && y<=Limit_visible_bottom) + for (x=x_pos-1;x=Limit_left && x<=Limit_visible_right) + Pixel_preview(x,y,~Read_pixel(x-Main_offset_X,y-Main_offset_Y)); + Update_part_of_screen(x_pos-1, y_pos-1, 2, 2); +} + +void Distort_brush_0_0(void) +// +// Opération : OPERATION_DISTORT_BRUSH +// Click Souris: 0 +// Taille_Pile : 0 +// +// Souris effacée: Non +// +{ + if ( Menu_is_visible ) + { + Print_in_menu("POSITION BRUSH TO START ",0); + } +} + +void Distort_brush_1_0(void) +// +// Opération : OPERATION_DISTORT_BRUSH +// Click Souris: 1 +// Taille_Pile : 0 +// +// Souris effacée: Non +// +{ + short x_pos, y_pos; + + Init_start_operation(); + Paintbrush_hidden=1; + Hide_cursor(); + + // Top left angle + x_pos=Paintbrush_X-Brush_offset_X; + y_pos=Paintbrush_Y-Brush_offset_Y; + Draw_stretch_spot(x_pos,y_pos); + Operation_push(x_pos); + Operation_push(y_pos); + + // Top right angle + x_pos+=Brush_width; + Draw_stretch_spot(x_pos,y_pos); + Operation_push(x_pos); + Operation_push(y_pos); + + // Bottom right angle + y_pos+=Brush_height; + Draw_stretch_spot(x_pos,y_pos); + Operation_push(x_pos); + Operation_push(y_pos); + + // Bottom left angle + x_pos-=Brush_width; + Draw_stretch_spot(x_pos,y_pos); + Operation_push(x_pos); + Operation_push(y_pos); + + Distort_brush_preview( + Operation_stack[1], + Operation_stack[2], + Operation_stack[3], + Operation_stack[4], + Operation_stack[5], + Operation_stack[6], + Operation_stack[7], + Operation_stack[8]); + Display_cursor(); + Update_part_of_screen(Paintbrush_X-Brush_offset_X, Paintbrush_Y-Brush_offset_Y, Brush_width, Brush_height); + Wait_end_of_click(); + // Erase the message in status bar + if ( (Config.Coords_rel) && (Menu_is_visible) ) + { + Print_in_menu("X: Y: ",0); + } +} + +void Distort_brush_1_8(void) +// +// Opération : OPERATION_DISTORT_BRUSH +// Click Souris: 1 +// Taille_Pile : 8 +// +// Souris effacée: No +// +{ + // How far (in pixels) you can catch a handle + #define REACH_DISTANCE 100 + short i; + short x[4]; + short y[4]; + long best_distance=REACH_DISTANCE; + short best_spot=-1; + + for (i=3;i>=0;i--) + { + long distance; + Operation_pop(&y[i]); + Operation_pop(&x[i]); + distance=Distance(Paintbrush_X,Paintbrush_Y,x[i],y[i]); + if (distance-1) + { + Operation_push(best_spot); + } + if ( (Config.Coords_rel) && (Menu_is_visible) ) + { + Print_in_menu("X: Y: ",0); + Print_coordinates(); + } +} + +void Distort_brush_1_9(void) +// +// Opération : OPERATION_DISTORT_BRUSH +// Click Souris: 1 +// Taille_Pile : 9 +// +// Souris effacée: No +// +{ + short i; + short x[4]; + short y[4]; + short selected_corner; + + // Pop all arguments + Operation_pop(&selected_corner); + for (i=3;i>=0;i--) + { + Operation_pop(&y[i]); + Operation_pop(&x[i]); + } + + if (Paintbrush_X!=x[selected_corner] || Paintbrush_Y!=y[selected_corner]) + { + Hide_cursor(); + + // Easiest refresh mode: make no assumptions on how the brush was + // displayed before. + Display_all_screen(); + + x[selected_corner]=Paintbrush_X; + y[selected_corner]=Paintbrush_Y; + + for (i=0;i<4;i++) + Draw_stretch_spot(x[i],y[i]); + + Distort_brush_preview(x[0],y[0],x[1],y[1],x[2],y[2],x[3],y[3]); + + Display_cursor(); + + if ( (Config.Coords_rel) && (Menu_is_visible) ) + { + Print_in_menu("X: Y: ",0); + Print_coordinates(); + } + Update_rect(0,0,Screen_width,Menu_Y); + } + + // Push back all arguments + for (i=0;i<4;i++) + { + Operation_push(x[i]); + Operation_push(y[i]); + } + Operation_push(selected_corner); + +} +void Distort_brush_0_9(void) +// +// Opération : OPERATION_DISTORT_BRUSH +// Click Souris: 0 +// Taille_Pile : 9 +// +// Souris effacée: No +// +{ + short selected_corner; + Operation_pop(&selected_corner); + +} + +void Distort_brush_2_0(void) +// +// Opération : OPERATION_DISTORT_BRUSH +// Click Souris: 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui +// +{ + Paintbrush_hidden=0; + Display_all_screen(); + // Erase the message in status bar + if ( (Config.Coords_rel) && (Menu_is_visible) ) + { + Print_in_menu("X: Y: ",0); + } + Return_to_draw_mode(); +} + +void Distort_brush_2_8(void) +// +// Opération : OPERATION_DISTORT_BRUSH +// Click Souris: 2 +// Taille_Pile : 8 +// +// Souris effacée: Oui +// +{ + short i; + short x[4]; + short y[4]; + + // Pop all arguments + for (i=3;i>=0;i--) + { + Operation_pop(&y[i]); + Operation_pop(&x[i]); + } + Distort_brush(x[0],y[0],x[1],y[1],x[2],y[2],x[3],y[3]); + + Paintbrush_hidden=0; + Display_all_screen(); + + Return_to_draw_mode(); +} + +//////////////////////////////////////////////////////////// OPERATION_SCROLL + + +byte Cursor_hidden_before_scroll; + +void Scroll_12_0(void) +// +// Opération : OPERATION_SCROLL +// Click Souris: 1 ou 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui +// +{ + Init_start_operation(); + Backup(); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Cursor_hidden_before_scroll=Cursor_hidden; + Cursor_hidden=1; + if ((Config.Coords_rel) && (Menu_is_visible)) + Print_in_menu("X:± 0 Y:± 0",0); +} + + +void Scroll_12_4(void) +// +// Opération : OPERATION_SCROLL +// Click Souris: 1 ou 2 +// Taille_Pile : 4 +// +// Souris effacée: Non +// +{ + short center_x; + short center_y; + short x_pos; + short y_pos; + short x_offset; + short y_offset; + //char str[5]; + + Operation_pop(&y_pos); + Operation_pop(&x_pos); + Operation_pop(¢er_y); + Operation_pop(¢er_x); + + if ( (Paintbrush_X!=x_pos) || (Paintbrush_Y!=y_pos) ) + { + // L'utilisateur a bougé, il faut scroller l'image + + if (Paintbrush_X>=center_x) + x_offset=(Paintbrush_X-center_x)%Main_image_width; + else + x_offset=Main_image_width-((center_x-Paintbrush_X)%Main_image_width); + + if (Paintbrush_Y>=center_y) + y_offset=(Paintbrush_Y-center_y)%Main_image_height; + else + y_offset=Main_image_height-((center_y-Paintbrush_Y)%Main_image_height); + + Display_coords_rel_or_abs(center_x,center_y); + + Scroll_picture(x_offset,y_offset); + + Display_all_screen(); + } + + Operation_push(center_x); + Operation_push(center_y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + +void Scroll_0_4(void) +// +// Opération : OPERATION_SCROLL +// Click Souris: 0 +// Taille_Pile : 4 +// +// Souris effacée: Oui +// +{ + Operation_stack_size-=4; + Cursor_hidden=Cursor_hidden_before_scroll; + if ((Config.Coords_rel) && (Menu_is_visible)) + { + Print_in_menu("X: Y: ",0); + Print_coordinates(); + } +} + + +//////////////////////////////////////////////////// OPERATION_GRAD_CIRCLE + + +void Grad_circle_12_0(void) +// +// Opération : OPERATION_GRAD_CIRCLE +// Click Souris: 1 ou 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui +{ + byte color; + + Init_start_operation(); + Backup(); + + Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right; + color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color; + + Paintbrush_hidden_before_scroll=Paintbrush_hidden; + Paintbrush_hidden=1; + + Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color); + Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); + + if ((Config.Coords_rel) && (Menu_is_visible)) + Print_in_menu("Radius: 0 ",0); + + Operation_push(Mouse_K); + Operation_push(color); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +void Grad_circle_12_6(void) +// +// Opération : OPERATION_GRAD_CIRCLE +// Click Souris: 1 ou 2 +// Taille_Pile : 6 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente) +// +// Souris effacée: Non +// +{ + short tangent_x; + short tangent_y; + short center_x; + short center_y; + short color; + short radius; + char str[5]; + + Operation_pop(&tangent_y); + Operation_pop(&tangent_x); + Operation_pop(¢er_y); + Operation_pop(¢er_x); + Operation_pop(&color); + + if ( (tangent_x!=Paintbrush_X) || (tangent_y!=Paintbrush_Y) ) + { + Hide_cursor(); + if ((Config.Coords_rel) && (Menu_is_visible)) + { + Num2str(Distance(center_x,center_y,Paintbrush_X,Paintbrush_Y),str,4); + Print_in_menu(str,7); + } + else + Print_coordinates(); + + Circle_limit=((tangent_x-center_x)*(tangent_x-center_x))+ + ((tangent_y-center_y)*(tangent_y-center_y)); + radius=sqrt(Circle_limit); + Hide_empty_circle_preview(center_x,center_y,radius); + + Circle_limit=((Paintbrush_X-center_x)*(Paintbrush_X-center_x))+ + ((Paintbrush_Y-center_y)*(Paintbrush_Y-center_y)); + radius=sqrt(Circle_limit); + Draw_empty_circle_preview(center_x,center_y,radius,color); + + Display_cursor(); + } + + Operation_push(color); + Operation_push(center_x); + Operation_push(center_y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +void Grad_circle_0_6(void) +// +// Opération : OPERATION_GRAD_CIRCLE +// Click Souris: 0 +// Taille_Pile : 6 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente) +// +// Souris effacée: Oui +// +{ + short tangent_x; + short tangent_y; + short center_x; + short center_y; + short color; + short click; + short radius; + + Operation_pop(&tangent_y); + Operation_pop(&tangent_x); + Operation_pop(¢er_y); + Operation_pop(¢er_x); + + Operation_pop(&color); + Operation_pop(&click); + + if (click==LEFT_SIDE) + { + Operation_push(click); + Operation_push(color); + + Operation_push(center_x); + Operation_push(center_y); + Operation_push(tangent_x); + Operation_push(tangent_y); + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + + // On change la forme du curseur + Cursor_shape=CURSOR_SHAPE_XOR_TARGET; + + // On affiche une croix XOR au centre du cercle + Draw_curve_cross(center_x,center_y); + + if (Menu_is_visible) + { + if (Config.Coords_rel) + Print_in_menu("X: Y:",0); + else + Print_in_menu("X: Y: ",0); + Display_coords_rel_or_abs(center_x,center_y); + } + } + else + { + Circle_limit=((tangent_x-center_x)*(tangent_x-center_x))+ + ((tangent_y-center_y)*(tangent_y-center_y)); + radius=sqrt(Circle_limit); + Hide_empty_circle_preview(center_x,center_y,radius); + + Paintbrush_hidden=Paintbrush_hidden_before_scroll; + Cursor_shape=CURSOR_SHAPE_TARGET; + + Draw_filled_circle(center_x,center_y,radius,Back_color); + + if ((Config.Coords_rel) && (Menu_is_visible)) + { + Print_in_menu("X: Y: ",0); + Print_coordinates(); + } + } +} + + +void Grad_circle_12_8(void) +// +// Opération : OPERATION_GRAD_CIRCLE +// Click Souris: 0 +// Taille_Pile : 8 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente, old_x, old_y) +// +// Souris effacée: Oui +// +{ + short tangent_x; + short tangent_y; + short center_x; + short center_y; + short color; + short old_mouse_k; + + short radius; + + Operation_stack_size-=2; // On fait sauter les 2 derniers élts de la pile + Operation_pop(&tangent_y); + Operation_pop(&tangent_x); + Operation_pop(¢er_y); + Operation_pop(¢er_x); + Operation_pop(&color); + Operation_pop(&old_mouse_k); + + Hide_cursor(); + // On efface la croix XOR au centre du cercle + Draw_curve_cross(center_x,center_y); + + Circle_limit=((tangent_x-center_x)*(tangent_x-center_x))+ + ((tangent_y-center_y)*(tangent_y-center_y)); + radius=sqrt(Circle_limit); + Hide_empty_circle_preview(center_x,center_y,radius); + + Paintbrush_hidden=Paintbrush_hidden_before_scroll; + Cursor_shape=CURSOR_SHAPE_TARGET; + + if (Mouse_K==old_mouse_k) + Draw_grad_circle(center_x,center_y,radius,Paintbrush_X,Paintbrush_Y); + + Display_cursor(); + Wait_end_of_click(); + + if ((Config.Coords_rel) && (Menu_is_visible)) + { + Print_in_menu("X: Y: ",0); + Print_coordinates(); + } +} + + +void Grad_circle_or_ellipse_0_8(void) +// +// Opération : OPERATION_{CERCLE|ELLIPSE}_DEGRADE +// Click Souris: 0 +// Taille_Pile : 8 +// +// Souris effacée: Non +// +{ + short start_x; + short start_y; + short tangent_x; + short tangent_y; + short old_x; + short old_y; + + Operation_pop(&old_y); + Operation_pop(&old_x); + + if ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y)) + { + Operation_pop(&tangent_y); + Operation_pop(&tangent_x); + Operation_pop(&start_y); + Operation_pop(&start_x); + Display_coords_rel_or_abs(start_x,start_y); + Operation_push(start_x); + Operation_push(start_y); + Operation_push(tangent_x); + Operation_push(tangent_y); + } + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +////////////////////////////////////////////////// OPERATION_GRAD_ELLIPSE + + +void Grad_ellipse_12_0(void) +// +// Opération : OPERATION_GRAD_ELLIPSE +// Click Souris: 1 ou 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui +{ + byte color; + + Init_start_operation(); + Backup(); + + Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right; + color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color; + + Paintbrush_hidden_before_scroll=Paintbrush_hidden; + Paintbrush_hidden=1; + + Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color); + Update_part_of_screen(Paintbrush_X,Paintbrush_Y,1,1); + + if ((Config.Coords_rel) && (Menu_is_visible)) + Print_in_menu("X:± 0 Y:± 0",0); + + Operation_push(Mouse_K); + Operation_push(color); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +void Grad_ellipse_12_6(void) +// +// Opération : OPERATION_GRAD_ELLIPSE +// Click Souris: 1 ou 2 +// Taille_Pile : 6 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente) +// +// Souris effacée: Non +// +{ + short tangent_x; + short tangent_y; + short center_x; + short center_y; + short color; + short horizontal_radius; + short vertical_radius; + + Operation_pop(&tangent_y); + Operation_pop(&tangent_x); + Operation_pop(¢er_y); + Operation_pop(¢er_x); + Operation_pop(&color); + + if ( (tangent_x!=Paintbrush_X) || (tangent_y!=Paintbrush_Y) ) + { + Hide_cursor(); + Display_coords_rel_or_abs(center_x,center_y); + + horizontal_radius=(tangent_x>center_x)?tangent_x-center_x + :center_x-tangent_x; + vertical_radius =(tangent_y>center_y)?tangent_y-center_y + :center_y-tangent_y; + Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius); + + horizontal_radius=(Paintbrush_X>center_x)?Paintbrush_X-center_x + :center_x-Paintbrush_X; + vertical_radius =(Paintbrush_Y>center_y)?Paintbrush_Y-center_y + :center_y-Paintbrush_Y; + Draw_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius,color); + + Display_cursor(); + } + + Operation_push(color); + Operation_push(center_x); + Operation_push(center_y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +void Grad_ellipse_0_6(void) +// +// Opération : OPERATION_GRAD_ELLIPSE +// Click Souris: 0 +// Taille_Pile : 6 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente) +// +// Souris effacée: Oui +// +{ + short tangent_x; + short tangent_y; + short center_x; + short center_y; + short color; + short click; + //short radius; + short horizontal_radius; + short vertical_radius; + + Operation_pop(&tangent_y); + Operation_pop(&tangent_x); + Operation_pop(¢er_y); + Operation_pop(¢er_x); + + Operation_pop(&color); + Operation_pop(&click); + + if (click==LEFT_SIDE) + { + Operation_push(click); + Operation_push(color); + + Operation_push(center_x); + Operation_push(center_y); + Operation_push(tangent_x); + Operation_push(tangent_y); + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + + // On change la forme du curseur + Cursor_shape=CURSOR_SHAPE_XOR_TARGET; + + // On affiche une croix XOR au centre du cercle + Draw_curve_cross(center_x,center_y); + + if (Menu_is_visible) + { + if (Config.Coords_rel) + Print_in_menu("X: Y:",0); + else + Print_in_menu("X: Y: ",0); + Display_coords_rel_or_abs(center_x,center_y); + } + } + else + { + horizontal_radius=(tangent_x>center_x)?tangent_x-center_x + :center_x-tangent_x; + vertical_radius =(tangent_y>center_y)?tangent_y-center_y + :center_y-tangent_y; + Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius); + + Paintbrush_hidden=Paintbrush_hidden_before_scroll; + Cursor_shape=CURSOR_SHAPE_TARGET; + + Draw_filled_ellipse(center_x,center_y,horizontal_radius,vertical_radius,Back_color); + + if ((Config.Coords_rel) && (Menu_is_visible)) + { + Print_in_menu("X: Y: ",0); + Print_coordinates(); + } + } +} + + +void Grad_ellipse_12_8(void) +// +// Opération : OPERATION_GRAD_ELLIPSE +// Click Souris: 0 +// Taille_Pile : 8 (Mouse_K, color, X_Centre, Y_Centre, X_Tangente, Y_Tangente, old_x, old_y) +// +// Souris effacée: Oui +// +{ + short tangent_x; + short tangent_y; + short center_x; + short center_y; + short color; + short horizontal_radius; + short vertical_radius; + short old_mouse_k; + + Operation_stack_size-=2; // On fait sauter les 2 derniers élts de la pile + Operation_pop(&tangent_y); + Operation_pop(&tangent_x); + Operation_pop(¢er_y); + Operation_pop(¢er_x); + Operation_pop(&color); + Operation_pop(&old_mouse_k); + + Hide_cursor(); + // On efface la croix XOR au centre de l'ellipse + Draw_curve_cross(center_x,center_y); + + horizontal_radius=(tangent_x>center_x)?tangent_x-center_x + :center_x-tangent_x; + vertical_radius =(tangent_y>center_y)?tangent_y-center_y + :center_y-tangent_y; + Hide_empty_ellipse_preview(center_x,center_y,horizontal_radius,vertical_radius); + + Paintbrush_hidden=Paintbrush_hidden_before_scroll; + Cursor_shape=CURSOR_SHAPE_TARGET; + + if (Mouse_K==old_mouse_k) + Draw_grad_ellipse(center_x,center_y,horizontal_radius,vertical_radius,Paintbrush_X,Paintbrush_Y); + + Display_cursor(); + + Wait_end_of_click(); + + if ((Config.Coords_rel) && (Menu_is_visible)) + { + Print_in_menu("X: Y: ",0); + Print_coordinates(); + } +} + +/****************************** +* Operation_Rectangle_Degrade * +******************************/ + +// 1) tracé d'un rectangle classique avec les lignes XOR +// 2) tracé d'une ligne vecteur de dégradé, comme une ligne normale +// 3) dessin du dégradé + + +void Grad_rectangle_12_0(void) +// Opération : OPERATION_GRAD_RECTANGLE +// Click Souris: 1 ou 2 +// Taille_Pile : 0 +// +// Souris effacée: Oui + +// Initialisation de l'étape 1, on commence à dessiner le rectangle +{ + Init_start_operation(); + Backup(); + + if ((Config.Coords_rel) && (Menu_is_visible)) + Print_in_menu("\035: 1 \022: 1",0); + // On laisse une trace du curseur à l'écran + Display_cursor(); + + if (Mouse_K==LEFT_SIDE) + { + Shade_table=Shade_table_left; + Operation_push(Mouse_K); + } + else + { + Shade_table=Shade_table_right; + Operation_push(Mouse_K); + } + + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +void Grad_rectangle_12_5(void) +// Opération : OPERATION_GRAD_RECTANGLE +// Click Souris: 1 ou 2 +// Taille_Pile : 5 +// +// Souris effacée: Non + +// Modification de la taille du rectangle +{ + short start_x; + short start_y; + short old_x; + short old_y; + char str[5]; + + Operation_pop(&old_y); + Operation_pop(&old_x); + + if ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y)) + { + Operation_pop(&start_y); + Operation_pop(&start_x); + + if ((Config.Coords_rel) && (Menu_is_visible)) + { + Num2str(((start_x Min(Main_image_width,Main_magnifier_mode?Main_separator_position:Screen_width)) // Tous les clippings à gérer sont là + offset_width = Max(rax,rbx) - Min(Main_image_width,Main_magnifier_mode?Main_separator_position:Screen_width); + + if (Max(ray,rby)-Main_offset_Y > Min(Main_image_height,Menu_Y)) + offset_height = Max(ray,rby) - Min(Main_image_height,Menu_Y); + + // Dessin dans la zone de dessin normale + Horizontal_XOR_line(Min(rax,rbx)-Main_offset_X,Min(ray,rby)-Main_offset_Y,width - offset_width); + if(offset_height == 0) + Horizontal_XOR_line(Min(rax,rbx)-Main_offset_X,Max(ray,rby)-1-Main_offset_Y,width - offset_width); + + Vertical_XOR_line(Min(rax,rbx)-Main_offset_X,Min(ray,rby)-Main_offset_Y,height-offset_height); + if (offset_width == 0) // Sinon cette ligne est en dehors de la zone image, inutile de la dessiner + Vertical_XOR_line(Max(rax,rbx)-1-Main_offset_X,Min(ray,rby)-Main_offset_Y,height-offset_height); + + Update_rect(Min(rax,rbx)-Main_offset_X,Min(ray,rby)-Main_offset_Y,width+1-offset_width,height+1-offset_height); + + // Dessin dans la zone zoomée + if(Main_magnifier_mode && Min(rax,rbx)Limit_left_zoom && Min(ray,rby)Limit_top_zoom ) + { + offset_width = 0; + offset_height=0; + + if(Min(rax,rbx)Limit_visible_right_zoom) // On dépasse du zoom à droite + offset_width += Max(rax,rbx) - Limit_visible_right_zoom; + + if(Min(ray,rby)Limit_visible_bottom_zoom) // On dépasse du zoom en bas + offset_height += Max(ray,rby) - Limit_visible_bottom_zoom; + + if(width > offset_width) + { + if(offset_top==0) // La ligne du haut est visible + Horizontal_XOR_line_zoom(offset_left>0?offset_left:Min(rax,rbx),Min(ray,rby),width-offset_width); + + if(Max(ray,rby)0?offset_left:Min(rax,rbx),Max(ray,rby),width-offset_width); + } + + if(height>offset_height) + { + if(offset_left==0) // La ligne de gauche est visible + Vertical_XOR_line_zoom(Min(rax,rbx),offset_top>0?offset_top:Min(ray,rby),height-offset_height); + + if(Max(rax,rbx)0?offset_top:Min(ray,rby),height-offset_height); + } + } + + Operation_push(rax); + Operation_push(ray); + Operation_push(rbx); + Operation_push(rby); + + // On ajoute des trucs dans la pile pour forcer le passage à l'étape suivante + Operation_push(rbx); + Operation_push(rby); +} + +void Grad_rectangle_0_7(void) +// OPERATION_GRAD_RECTANGLE +// click souris 0 +// Taile pile : 5 +// +// Souris effacée : non + +// On continue à attendre que l'utilisateur clique en gardant les coords à jour +{ + Operation_stack_size -= 2; + Print_coordinates(); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + +void Grad_rectangle_12_7(void) +// Opération : OPERATION_GRAD_RECTANGLE +// Click Souris: 1 ou 2 +// Taille_Pile : 7 +// +// Souris effacée: Oui + +// Début du tracé du vecteur (premier clic) +// On garde les anciennes coordonnées dans la pile, et on ajoute les nouvelles par dessus + +// Si l'utilisateur utilise le mauvais bouton, on annule le tracé. Mais ça nous oblige à vider toute la pile pour vérifier :( +{ + short rax,rbx,ray,rby,vax,vay,click; + + Operation_pop(&vay); + Operation_pop(&vax); + Operation_pop(&ray); + Operation_pop(&rax); + Operation_pop(&rby); + Operation_pop(&rbx); + Operation_pop(&click); + + + if(click==Mouse_K) + { + Operation_push(click); + Operation_push(rbx); + Operation_push(rby); + Operation_push(rax); + Operation_push(ray); + Operation_push(vax); + Operation_push(vay); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + + } + else + { + // Mauvais bouton > anulation de l'opération. + // On a déjà vidé la pile, il reste à effacer le rectangle XOR + short width, height; + short offset_width = 0; + short offset_height = 0; + short offset_left = 0; + short offset_top = 0; + + width = abs(rbx-rax); + height = abs(rby-ray); + + if (Max(rax,rbx)-Main_offset_X > Min(Main_image_width,Main_magnifier_mode?Main_separator_position:Screen_width)) // Tous les clippings à gérer sont là + offset_width = Max(rax,rbx) - Min(Main_image_width,Main_magnifier_mode?Main_separator_position:Screen_width); + + if (Max(ray,rby)-Main_offset_Y > Min(Main_image_height,Menu_Y)) + offset_height = Max(ray,rby) - Min(Main_image_height,Menu_Y); + + // Dessin dans la zone de dessin normale + Horizontal_XOR_line(Min(rax,rbx)-Main_offset_X,Min(ray,rby)-Main_offset_Y,width - offset_width); + if(offset_height == 0) + Horizontal_XOR_line(Min(rax,rbx)-Main_offset_X,Max(ray,rby)-1-Main_offset_Y,width - offset_width); + + Vertical_XOR_line(Min(rax,rbx)-Main_offset_X,Min(ray,rby)-Main_offset_Y,height-offset_height); + if (offset_width == 0) // Sinon cette ligne est en dehors de la zone image, inutile de la dessiner + Vertical_XOR_line(Max(rax,rbx)-1-Main_offset_X,Min(ray,rby)-Main_offset_Y,height-offset_height); + + Update_rect(Min(rax,rbx)-Main_offset_X,Min(ray,rby)-Main_offset_Y,width+1-offset_width,height+1-offset_height); + + // Dessin dans la zone zoomée + if(Main_magnifier_mode && Min(rax,rbx)Limit_left_zoom && Min(ray,rby)Limit_top_zoom ) + { + offset_width = 0; + offset_height=0; + + if(Min(rax,rbx)Limit_visible_right_zoom) // On dépasse du zoom à droite + offset_width += Max(rax,rbx) - Limit_visible_right_zoom; + + if(Min(ray,rby)Limit_visible_bottom_zoom) // On dépasse du zoom en bas + offset_height += Max(ray,rby) - Limit_visible_bottom_zoom; + + if(width > offset_width) + { + if(offset_top==0) // La ligne du haut est visible + Horizontal_XOR_line_zoom(offset_left>0?offset_left:Min(rax,rbx),Min(ray,rby),width-offset_width); + + if(Max(ray,rby)0?offset_left:Min(rax,rbx),Max(ray,rby),width-offset_width); + } + + if(height>offset_height) + { + if(offset_left==0) // La ligne de gauche est visible + Vertical_XOR_line_zoom(Min(rax,rbx),offset_top>0?offset_top:Min(ray,rby),height-offset_height); + + if(Max(rax,rbx)0?offset_top:Min(ray,rby),height-offset_height); + } + } + } +} + +void Grad_rectangle_12_9(void) + // Opération : OPERATION_GRAD_RECTANGLE + // Click Souris: 1 + // Taille_Pile : 5 + // + // Souris effacée: Oui + + // Poursuite du tracé du vecteur (déplacement de la souris en gardant le curseur appuyé) +{ + short start_x; + short start_y; + short end_x; + short end_y; + short cursor_x; + short cursor_y; + + Operation_pop(&end_y); + Operation_pop(&end_x); + Operation_pop(&start_y); + Operation_pop(&start_x); + + cursor_x = Paintbrush_X; + cursor_y = Paintbrush_Y; + // On corrige les coordonnées de la ligne si la touche shift est appuyée... + if(SDL_GetModState() & KMOD_SHIFT) + Clamp_coordinates_regular_angle(start_x,start_y,&cursor_x,&cursor_y); + + if ((cursor_x!=end_x) || (cursor_y!=end_y)) + { + Display_coords_rel_or_abs(start_x,start_y); + + Draw_line_preview_xor(start_x,start_y,end_x,end_y,0); + Draw_line_preview_xor(start_x,start_y,cursor_x,cursor_y,0); + + } + + + Operation_push(start_x); + Operation_push(start_y); + Operation_push(cursor_x); + Operation_push(cursor_y); +} + +void Grad_rectangle_0_9(void) + // Opération : OPERATION_GRAD_RECTANGLE + // Click Souris: 0 + // Taille_Pile : 9 + // + // Souris effacée: Oui + + // Ouf, fini ! on dessine enfin le rectangle avec son dégradé +{ + short rect_start_x; + short rect_start_y; + short rect_end_x; + short rect_end_y; + + short vector_start_x; + short vector_start_y; + short vector_end_x; + short vector_end_y; + + Operation_pop(&vector_end_y); + Operation_pop(&vector_end_x); + Operation_pop(&vector_start_y); + Operation_pop(&vector_start_x); + Operation_pop(&rect_end_y); + Operation_pop(&rect_end_x); + Operation_pop(&rect_start_y); + Operation_pop(&rect_start_x); + Operation_stack_size--; + + Hide_cursor(); + // Maintenant on efface tout le bazar temporaire : rectangle et ligne XOR + Hide_line_preview(vector_start_x,vector_start_y,vector_end_x,vector_end_y); + + // Et enfin on trace le rectangle avec le dégradé dedans ! + if (vector_end_x==vector_start_x && vector_end_y==vector_start_y) + { + // Vecteur nul > pas de rectangle tracé + // Du coup on doit effacer la preview xor ... + short width, height; + short offset_width = 0; + short offset_height = 0; + short offset_left = 0; + short offset_top = 0; + + width = abs(rect_end_x-rect_start_x); + height = abs(rect_end_y-rect_start_y); + + if (Max(rect_start_x,rect_end_x)-Main_offset_X > Min(Main_image_width,Main_magnifier_mode?Main_separator_position:Screen_width)) // Tous les clippings à gérer sont là + offset_width = Max(rect_start_x,rect_end_x) - Min(Main_image_width,Main_magnifier_mode?Main_separator_position:Screen_width); + + if (Max(rect_start_y,rect_end_y)-Main_offset_Y > Min(Main_image_height,Menu_Y)) + offset_height = Max(rect_start_y,rect_end_y) - Min(Main_image_height,Menu_Y); + + // Dessin dans la zone de dessin normale + Horizontal_XOR_line(Min(rect_start_x,rect_end_x)-Main_offset_X,Min(rect_start_y,rect_end_y)-Main_offset_Y,width - offset_width); + if(offset_height == 0) + Horizontal_XOR_line(Min(rect_start_x,rect_end_x)-Main_offset_X,Max(rect_start_y,rect_end_y)-1-Main_offset_Y,width - offset_width); + + Vertical_XOR_line(Min(rect_start_x,rect_end_x)-Main_offset_X,Min(rect_start_y,rect_end_y)-Main_offset_Y,height-offset_height); + if (offset_width == 0) // Sinon cette ligne est en dehors de la zone image, inutile de la dessiner + Vertical_XOR_line(Max(rect_start_x,rect_end_x)-1-Main_offset_X,Min(rect_start_y,rect_end_y)-Main_offset_Y,height-offset_height); + + Update_rect(Min(rect_start_x,rect_end_x)-Main_offset_X,Min(rect_start_y,rect_end_y)-Main_offset_Y,width+1-offset_width,height+1-offset_height); + + // Dessin dans la zone zoomée + if(Main_magnifier_mode && Min(rect_start_x,rect_end_x)Limit_left_zoom && Min(rect_start_y,rect_end_y)Limit_top_zoom ) + { + offset_width = 0; + offset_height=0; + + if(Min(rect_start_x,rect_end_x)Limit_visible_right_zoom) // On dépasse du zoom à droite + offset_width += Max(rect_start_x,rect_end_x) - Limit_visible_right_zoom; + + if(Min(rect_start_y,rect_end_y)Limit_visible_bottom_zoom) // On dépasse du zoom en bas + offset_height += Max(rect_start_y,rect_end_y) - Limit_visible_bottom_zoom; + + if(width > offset_width) + { + if(offset_top==0) // La ligne du haut est visible + Horizontal_XOR_line_zoom(offset_left>0?offset_left:Min(rect_start_x,rect_end_x),Min(rect_start_y,rect_end_y),width-offset_width); + + if(Max(rect_start_y,rect_end_y)0?offset_left:Min(rect_start_x,rect_end_x),Max(rect_start_y,rect_end_y),width-offset_width); + } + + if(height>offset_height) + { + if(offset_left==0) // La ligne de gauche est visible + Vertical_XOR_line_zoom(Min(rect_start_x,rect_end_x),offset_top>0?offset_top:Min(rect_start_y,rect_end_y),height-offset_height); + + if(Max(rect_start_x,rect_end_x)0?offset_top:Min(rect_start_y,rect_end_y),height-offset_height); + } + } + } + else + Draw_grad_rectangle(rect_start_x,rect_start_y,rect_end_x,rect_end_y,vector_start_x,vector_start_y,vector_end_x,vector_end_y); + + Display_cursor(); + Wait_end_of_click(); + + if ((Config.Coords_rel) && (Menu_is_visible)) + { + Print_in_menu("X: Y: ",0); + Print_coordinates(); + } +} +/////////////////////////////////////////////////// OPERATION_CENTERED_LINES + + +void Centered_lines_12_0(void) + // Opération : OPERATION_CENTERED_LINES + // Click Souris: 1 ou 2 + // Taille_Pile : 0 + // + // Souris effacée: Oui +{ + Init_start_operation(); + Backup(); + Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right; + + if ((Config.Coords_rel) && (Menu_is_visible)) + Print_in_menu("X:± 0 Y:± 0",0); + + Operation_push(Mouse_K); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +void Centered_lines_12_3(void) + // Opération : OPERATION_CENTERED_LINES + // Click Souris: 1 ou 2 + // Taille_Pile : 3 + // + // Souris effacée: Non +{ + short start_x; + short start_y; + + Operation_pop(&start_y); + Operation_pop(&start_x); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + +void Centered_lines_0_3(void) + // Opération : OPERATION_CENTERED_LINES + // Click Souris: 0 + // Taille_Pile : 3 + // + // Souris effacée: Oui +{ + short start_x; + short start_y; + short Button; + short color; + + Operation_pop(&start_y); + Operation_pop(&start_x); + Operation_pop(&Button); + + color=(Button==LEFT_SIDE)?Fore_color:Back_color; + + Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color); + Paintbrush_shape_before_operation=Paintbrush_shape; + Paintbrush_shape=PAINTBRUSH_SHAPE_POINT; + + Operation_push(Button); + Operation_push(Paintbrush_X); // Nouveau début X + Operation_push(Paintbrush_Y); // Nouveau début Y + Operation_push(Paintbrush_X); // Nouvelle dernière fin X + Operation_push(Paintbrush_Y); // Nouvelle dernière fin Y + Operation_push(Paintbrush_X); // Nouvelle dernière position X + Operation_push(Paintbrush_Y); // Nouvelle dernière position Y +} + + +void Centered_lines_12_7(void) + // Opération : OPERATION_CENTERED_LINES + // Click Souris: 1 ou 2 + // Taille_Pile : 7 + // + // Souris effacée: Non +{ + short Button; + short start_x; + short start_y; + short end_x; + short end_y; + short last_x; + short last_y; + short color; + + Operation_pop(&last_y); + Operation_pop(&last_x); + Operation_pop(&end_y); + Operation_pop(&end_x); + Operation_pop(&start_y); + Operation_pop(&start_x); + Operation_pop(&Button); + + if (Mouse_K==Button) + { + if ( (end_x!=Paintbrush_X) || (end_y!=Paintbrush_Y) || + (last_x!=Paintbrush_X) || (last_y!=Paintbrush_Y) ) + { + Hide_cursor(); + + color=(Button==LEFT_SIDE)?Fore_color:Back_color; + + Paintbrush_shape=Paintbrush_shape_before_operation; + + Pixel_figure_preview_auto (start_x,start_y); + Hide_line_preview (start_x,start_y,last_x,last_y); + + Smear_start=1; + Display_paintbrush (start_x,start_y,color,0); + Draw_line_permanet(start_x,start_y,Paintbrush_X,Paintbrush_Y,color); + + Paintbrush_shape=PAINTBRUSH_SHAPE_POINT; + Pixel_figure_preview(Paintbrush_X,Paintbrush_Y,color); + Draw_line_preview(start_x,start_y,Paintbrush_X,Paintbrush_Y,color); + + Display_cursor(); + } + + Operation_push(Button); + Operation_push(start_x); + Operation_push(start_y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); + } + else + { + Hide_cursor(); + + Paintbrush_shape=Paintbrush_shape_before_operation; + + Pixel_figure_preview_auto (start_x,start_y); + Hide_line_preview (start_x,start_y,last_x,last_y); + + if ( (Config.Coords_rel) && (Menu_is_visible) ) + { + Print_in_menu("X: Y: ",0); + Print_coordinates(); + } + + Display_cursor(); + Wait_end_of_click(); + } +} + + +void Centered_lines_0_7(void) + // Opération : OPERATION_CENTERED_LINES + // Click Souris: 0 + // Taille_Pile : 7 + // + // Souris effacée: Non +{ + short Button; + short start_x; + short start_y; + short end_x; + short end_y; + short last_x; + short last_y; + short color; + + Operation_pop(&last_y); + Operation_pop(&last_x); + Operation_pop(&end_y); + Operation_pop(&end_x); + + if ((Paintbrush_X!=last_x) || (Paintbrush_Y!=last_y)) + { + Hide_cursor(); + Operation_pop(&start_y); + Operation_pop(&start_x); + Operation_pop(&Button); + + color=(Button==LEFT_SIDE)?Fore_color:Back_color; + + Display_coords_rel_or_abs(start_x,start_y); + + Hide_line_preview(start_x,start_y,last_x,last_y); + + Pixel_figure_preview(start_x,start_y,color); + Draw_line_preview(start_x,start_y,Paintbrush_X,Paintbrush_Y,color); + + Operation_push(Button); + Operation_push(start_x); + Operation_push(start_y); + Display_cursor(); + } + + Operation_push(end_x); + Operation_push(end_y); + Operation_push(Paintbrush_X); + Operation_push(Paintbrush_Y); +} + + diff --git a/operatio.h b/operatio.h index 89428cca..41f6f133 100644 --- a/operatio.h +++ b/operatio.h @@ -1,219 +1,219 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file operatio.h -/// Code for the operations, ie all drawing tools. -////////////////////////////////////////////////////////////////////////////// - -/// Do some housekeeping before starting work on a operation. -void Start_operation_stack(word new_operation); -/// Put a value on ::Operation_stack -void Operation_push(short value); -/// Take a value off ::Operation_stack -void Operation_pop(short * value); - -//////////////////////////////////////////////////// OPERATION_CONTINUOUS_DRAW -void Freehand_mode1_1_0(void); -void Freehand_mode1_1_2(void); -void Freehand_mode12_0_2(void); -void Freehand_mode1_2_0(void); -void Freehand_mode1_2_2(void); - -///////////////////////////////////////////////// OPERATION_DISCONTINUOUS_DRAW -void Freehand_mode2_1_0(void); -void Freehand_mode2_1_2(void); -void Freehand_mode2_2_0(void); -void Freehand_mode2_2_2(void); - -////////////////////////////////////////////////////// OPERATION_POINT_DRAW -void Freehand_mode3_1_0(void); -void Freehand_Mode3_2_0(void); -void Freehand_mode3_0_1(void); - -///////////////////////////////////////////////////////////// OPERATION_LINE - -void Line_12_0(void); -void Line_12_5(void); -void Line_0_5(void); - -///////////////////////////////////////////////////////////// OPERATION_MAGNIFY - -void Magnifier_12_0(void); - -/////////////////////////////////////////////////// OPERATION_RECTANGLE_????? - -void Rectangle_12_0(void); -void Rectangle_12_5(void); -void Empty_rectangle_0_5(void); -void Filled_rectangle_0_5(void); - -////////////////////////////////////////////////////// OPERATION_CERCLE_????? - -void Circle_12_0(void); -void Circle_12_5(void); -void Empty_circle_0_5(void); -void Filled_circle_0_5(void); - -///////////////////////////////////////////////////// OPERATION_ELLIPSE_????? - -void Ellipse_12_0(void); -void Ellipse_12_5(void); -void Empty_ellipse_0_5(void); -void Filled_ellipse_0_5(void); - -////////////////////////////////////////////////////// OPERATION_GRAB_BRUSH - -void Brush_12_0(void); -void Brush_12_5(void); -void Brush_0_5(void); - -///////////////////////////////////////////////////// OPERATION_STRETCH_BRUSH - -void Stretch_brush_12_0(void); -void Stretch_brush_1_7(void); -void Stretch_brush_0_7(void); -void Stretch_brush_2_7(void); - -//////////////////////////////////////////////////// OPERATION_ROTATE_BRUSH - -void Rotate_brush_12_0(void); -void Rotate_brush_1_5(void); -void Rotate_brush_0_5(void); -void Rotate_brush_2_5(void); - -///////////////////////////////////////////////////// OPERATION_DISTORT_BRUSH - -void Distort_brush_0_0(void); -void Distort_brush_1_0(void); -void Distort_brush_2_0(void); -void Distort_brush_1_8(void); -void Distort_brush_2_8(void); -void Distort_brush_1_9(void); -void Distort_brush_0_9(void); - -//////////////////////////////////////////////////////// OPERATION_POLYBRUSH - -void Polybrush_12_8(void); - -////////////////////////////////////////////////////////////// OPERATION_FILL - -void Fill_1_0(void); -void Fill_2_0(void); - -///////////////////////////////////////////////////////// OPERATION_REPLACE - -void Replace_1_0(void); -void Replace_2_0(void); - -/////////////////////////////////////////////////////////// OPERATION_COLORPICK - -void Pipette_0_0(void); -void Colorpicker_12_0(void); -void Colorpicker_1_1(void); -void Colorpicker_2_1(void); -void Colorpicker_0_1(void); - -/////////////////////////////////////////////////////////// OPERATION_K_LIGNE - -void K_line_12_0(void); -void K_line_12_6(void); -void K_line_0_6(void); -void K_line_12_7(void); - -/////////////////////////////////////////////////// OPERATION_COURBE_?_POINTS - -void Curve_34_points_1_0(void); -void Curve_34_points_2_0(void); -void Curve_34_points_1_5(void); -void Curve_34_points_2_5(void); - -void Curve_4_points_0_5(void); -void Curve_4_points_1_9(void); -void Curve_4_points_2_9(void); - -void Curve_3_points_0_5(void); -void Curve_3_points_0_11(void); -void Curve_3_points_12_11(void); - -///////////////////////////////////////////////////////////// OPERATION_AIRBRUSH - -void Airbrush_1_0(void); -void Airbrush_2_0(void); -void Airbrush_12_2(void); -void Airbrush_0_2(void); - -//////////////////////////////////////////////////////////// OPERATION_*POLY* - -void Polygon_12_0(void); -void Polygon_12_9(void); - -void Polyfill_12_0(void); -void Polyfill_0_8(void); -void Polyfill_12_8(void); -void Polyfill_12_9(void); - -void Polyform_12_0(void); -void Polyform_12_8(void); -void Polyform_0_8(void); - -void Filled_polyform_12_0(void); -void Filled_polyform_12_8(void); -void Filled_polyform_0_8(void); -void Filled_contour_0_8(void); - -//////////////////////////////////////////////////////////// OPERATION_SCROLL - -void Scroll_12_0(void); -void Scroll_12_4(void); -void Scroll_0_4(void); - -//////////////////////////////////////////////////// OPERATION_GRAD_CIRCLE - -void Grad_circle_12_0(void); -void Grad_circle_12_6(void); -void Grad_circle_0_6(void); -void Grad_circle_12_8(void); -void Grad_circle_or_ellipse_0_8(void); - -////////////////////////////////////////////////// OPERATION_GRAD_ELLIPSE - -void Grad_ellipse_12_0(void); -void Grad_ellipse_12_6(void); -void Grad_ellipse_0_6(void); -void Grad_ellipse_12_8(void); - -///////////////////////////////////////////////// OPERATION_GRAD_RECTANGLE - -void Grad_rectangle_12_0(void); -void Grad_rectangle_12_5(void); -void Grad_rectangle_0_5(void); -void Grad_rectangle_0_7(void); -void Grad_rectangle_12_7(void); -void Grad_rectangle_12_9(void); -void Grad_rectangle_0_9(void); - -/////////////////////////////////////////////////// OPERATION_CENTERED_LINES - -void Centered_lines_12_0(void); -void Centered_lines_12_3(void); -void Centered_lines_0_3(void); -void Centered_lines_12_7(void); -void Centered_lines_0_7(void); - +/* Grafx2 - The Ultimate 256-color bitmap paint program + + 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file operatio.h +/// Code for the operations, ie all drawing tools. +////////////////////////////////////////////////////////////////////////////// + +/// Do some housekeeping before starting work on a operation. +void Start_operation_stack(word new_operation); +/// Put a value on ::Operation_stack +void Operation_push(short value); +/// Take a value off ::Operation_stack +void Operation_pop(short * value); + +//////////////////////////////////////////////////// OPERATION_CONTINUOUS_DRAW +void Freehand_mode1_1_0(void); +void Freehand_mode1_1_2(void); +void Freehand_mode12_0_2(void); +void Freehand_mode1_2_0(void); +void Freehand_mode1_2_2(void); + +///////////////////////////////////////////////// OPERATION_DISCONTINUOUS_DRAW +void Freehand_mode2_1_0(void); +void Freehand_mode2_1_2(void); +void Freehand_mode2_2_0(void); +void Freehand_mode2_2_2(void); + +////////////////////////////////////////////////////// OPERATION_POINT_DRAW +void Freehand_mode3_1_0(void); +void Freehand_Mode3_2_0(void); +void Freehand_mode3_0_1(void); + +///////////////////////////////////////////////////////////// OPERATION_LINE + +void Line_12_0(void); +void Line_12_5(void); +void Line_0_5(void); + +///////////////////////////////////////////////////////////// OPERATION_MAGNIFY + +void Magnifier_12_0(void); + +/////////////////////////////////////////////////// OPERATION_RECTANGLE_????? + +void Rectangle_12_0(void); +void Rectangle_12_5(void); +void Empty_rectangle_0_5(void); +void Filled_rectangle_0_5(void); + +////////////////////////////////////////////////////// OPERATION_CERCLE_????? + +void Circle_12_0(void); +void Circle_12_5(void); +void Empty_circle_0_5(void); +void Filled_circle_0_5(void); + +///////////////////////////////////////////////////// OPERATION_ELLIPSE_????? + +void Ellipse_12_0(void); +void Ellipse_12_5(void); +void Empty_ellipse_0_5(void); +void Filled_ellipse_0_5(void); + +////////////////////////////////////////////////////// OPERATION_GRAB_BRUSH + +void Brush_12_0(void); +void Brush_12_5(void); +void Brush_0_5(void); + +///////////////////////////////////////////////////// OPERATION_STRETCH_BRUSH + +void Stretch_brush_12_0(void); +void Stretch_brush_1_7(void); +void Stretch_brush_0_7(void); +void Stretch_brush_2_7(void); + +//////////////////////////////////////////////////// OPERATION_ROTATE_BRUSH + +void Rotate_brush_12_0(void); +void Rotate_brush_1_5(void); +void Rotate_brush_0_5(void); +void Rotate_brush_2_5(void); + +///////////////////////////////////////////////////// OPERATION_DISTORT_BRUSH + +void Distort_brush_0_0(void); +void Distort_brush_1_0(void); +void Distort_brush_2_0(void); +void Distort_brush_1_8(void); +void Distort_brush_2_8(void); +void Distort_brush_1_9(void); +void Distort_brush_0_9(void); + +//////////////////////////////////////////////////////// OPERATION_POLYBRUSH + +void Polybrush_12_8(void); + +////////////////////////////////////////////////////////////// OPERATION_FILL + +void Fill_1_0(void); +void Fill_2_0(void); + +///////////////////////////////////////////////////////// OPERATION_REPLACE + +void Replace_1_0(void); +void Replace_2_0(void); + +/////////////////////////////////////////////////////////// OPERATION_COLORPICK + +void Pipette_0_0(void); +void Colorpicker_12_0(void); +void Colorpicker_1_1(void); +void Colorpicker_2_1(void); +void Colorpicker_0_1(void); + +/////////////////////////////////////////////////////////// OPERATION_K_LIGNE + +void K_line_12_0(void); +void K_line_12_6(void); +void K_line_0_6(void); +void K_line_12_7(void); + +/////////////////////////////////////////////////// OPERATION_COURBE_?_POINTS + +void Curve_34_points_1_0(void); +void Curve_34_points_2_0(void); +void Curve_34_points_1_5(void); +void Curve_34_points_2_5(void); + +void Curve_4_points_0_5(void); +void Curve_4_points_1_9(void); +void Curve_4_points_2_9(void); + +void Curve_3_points_0_5(void); +void Curve_3_points_0_11(void); +void Curve_3_points_12_11(void); + +///////////////////////////////////////////////////////////// OPERATION_AIRBRUSH + +void Airbrush_1_0(void); +void Airbrush_2_0(void); +void Airbrush_12_2(void); +void Airbrush_0_2(void); + +//////////////////////////////////////////////////////////// OPERATION_*POLY* + +void Polygon_12_0(void); +void Polygon_12_9(void); + +void Polyfill_12_0(void); +void Polyfill_0_8(void); +void Polyfill_12_8(void); +void Polyfill_12_9(void); + +void Polyform_12_0(void); +void Polyform_12_8(void); +void Polyform_0_8(void); + +void Filled_polyform_12_0(void); +void Filled_polyform_12_8(void); +void Filled_polyform_0_8(void); +void Filled_contour_0_8(void); + +//////////////////////////////////////////////////////////// OPERATION_SCROLL + +void Scroll_12_0(void); +void Scroll_12_4(void); +void Scroll_0_4(void); + +//////////////////////////////////////////////////// OPERATION_GRAD_CIRCLE + +void Grad_circle_12_0(void); +void Grad_circle_12_6(void); +void Grad_circle_0_6(void); +void Grad_circle_12_8(void); +void Grad_circle_or_ellipse_0_8(void); + +////////////////////////////////////////////////// OPERATION_GRAD_ELLIPSE + +void Grad_ellipse_12_0(void); +void Grad_ellipse_12_6(void); +void Grad_ellipse_0_6(void); +void Grad_ellipse_12_8(void); + +///////////////////////////////////////////////// OPERATION_GRAD_RECTANGLE + +void Grad_rectangle_12_0(void); +void Grad_rectangle_12_5(void); +void Grad_rectangle_0_5(void); +void Grad_rectangle_0_7(void); +void Grad_rectangle_12_7(void); +void Grad_rectangle_12_9(void); +void Grad_rectangle_0_9(void); + +/////////////////////////////////////////////////// OPERATION_CENTERED_LINES + +void Centered_lines_12_0(void); +void Centered_lines_12_3(void); +void Centered_lines_0_3(void); +void Centered_lines_12_7(void); +void Centered_lines_0_7(void); + diff --git a/pages.h b/pages.h index efc816e5..a85a03f7 100644 --- a/pages.h +++ b/pages.h @@ -1,93 +1,93 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file pages.h -/// Handler for the Undo/Redo system. -////////////////////////////////////////////////////////////////////////////// - -#ifndef _PAGES_H_ -#define _PAGES_H_ - - -////////////////////////////////////////////////////////////////////////// -/////////////////////////// GESTION DU BACKUP //////////////////////////// -////////////////////////////////////////////////////////////////////////// - - - /// - /// GESTION DES PAGES - /// - -void Init_page(T_Page * page); -void Download_infos_page_main(T_Page * page); -void Upload_infos_page_main(T_Page * page); -void Download_infos_page_spare(T_Page * page); -void Upload_infos_page_spare(T_Page * page); -void Download_infos_backup(T_List_of_pages * list); -void Free_a_page(T_Page * page); -void Copy_S_page(T_Page * dest,T_Page * source); -int Size_of_a_page(T_Page * page); - - - - /// - /// GESTION DES LISTES DE PAGES - /// - -void Init_list_of_pages(T_List_of_pages * list); -int Allocate_list_of_pages(T_List_of_pages * list,int size); -void Free_a_list_of_pages(T_List_of_pages * list); -int Size_of_a_list_of_pages(T_List_of_pages * list); -void Backward_in_list_of_pages(T_List_of_pages * list); -void Advance_in_list_of_pages(T_List_of_pages * list); -int New_page_is_possible(T_Page * new_page,T_List_of_pages * current_list,T_List_of_pages * secondary_list); -void Free_last_page_of_list(T_List_of_pages * list); -void Create_new_page(T_Page * new_page,T_List_of_pages * current_list,T_List_of_pages * secondary_list); -void Change_page_number_of_list(T_List_of_pages * list,int number); -void Free_page_of_a_list(T_List_of_pages * list); - - - - /// - /// GESTION DES BACKUPS - /// - -int Init_all_backup_lists(int size,int width,int height); -void Set_number_of_backups(int nb_backups); -int Backup_with_new_dimensions(int upload,int width,int height); -int Backup_and_resize_the_spare(int width,int height); -void Backup(void); -void Undo(void); -void Redo(void); -void Free_current_page(void); -void Exchange_main_and_spare(void); - - - - /// - /// GESTION DES EMPRUNTS DE MEMOIRE DE PAGE - /// - -int Can_borrow_memory_from_page(int size); -void * Borrow_memory_from_page(int size); - - - -#endif +/* Grafx2 - The Ultimate 256-color bitmap paint program + + 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file pages.h +/// Handler for the Undo/Redo system. +////////////////////////////////////////////////////////////////////////////// + +#ifndef _PAGES_H_ +#define _PAGES_H_ + + +////////////////////////////////////////////////////////////////////////// +/////////////////////////// GESTION DU BACKUP //////////////////////////// +////////////////////////////////////////////////////////////////////////// + + + /// + /// GESTION DES PAGES + /// + +void Init_page(T_Page * page); +void Download_infos_page_main(T_Page * page); +void Upload_infos_page_main(T_Page * page); +void Download_infos_page_spare(T_Page * page); +void Upload_infos_page_spare(T_Page * page); +void Download_infos_backup(T_List_of_pages * list); +void Free_a_page(T_Page * page); +void Copy_S_page(T_Page * dest,T_Page * source); +int Size_of_a_page(T_Page * page); + + + + /// + /// GESTION DES LISTES DE PAGES + /// + +void Init_list_of_pages(T_List_of_pages * list); +int Allocate_list_of_pages(T_List_of_pages * list,int size); +void Free_a_list_of_pages(T_List_of_pages * list); +int Size_of_a_list_of_pages(T_List_of_pages * list); +void Backward_in_list_of_pages(T_List_of_pages * list); +void Advance_in_list_of_pages(T_List_of_pages * list); +int New_page_is_possible(T_Page * new_page,T_List_of_pages * current_list,T_List_of_pages * secondary_list); +void Free_last_page_of_list(T_List_of_pages * list); +void Create_new_page(T_Page * new_page,T_List_of_pages * current_list,T_List_of_pages * secondary_list); +void Change_page_number_of_list(T_List_of_pages * list,int number); +void Free_page_of_a_list(T_List_of_pages * list); + + + + /// + /// GESTION DES BACKUPS + /// + +int Init_all_backup_lists(int size,int width,int height); +void Set_number_of_backups(int nb_backups); +int Backup_with_new_dimensions(int upload,int width,int height); +int Backup_and_resize_the_spare(int width,int height); +void Backup(void); +void Undo(void); +void Redo(void); +void Free_current_page(void); +void Exchange_main_and_spare(void); + + + + /// + /// GESTION DES EMPRUNTS DE MEMOIRE DE PAGE + /// + +int Can_borrow_memory_from_page(int size); +void * Borrow_memory_from_page(int size); + + + +#endif diff --git a/palette.c b/palette.c index 4b083c66..ce00dd00 100644 --- a/palette.c +++ b/palette.c @@ -1,2302 +1,2302 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - 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 -*/ -#include -#include -#include -#include "const.h" -#include "struct.h" -#include "global.h" -#include "misc.h" -#include "engine.h" -#include "readline.h" -#include "buttons.h" -#include "pages.h" -#include "help.h" -#include "sdlscreen.h" -#include "errors.h" -#include "op_c.h" -#include "windows.h" -#include "input.h" -#include "palette.h" -#include "shade.h" - -byte Palette_view_is_RGB = 1; // Indique si on est en HSL ou en RGB - -// --------------------------- Menu des palettes ----------------------------- -char * Palette_reduce_label[7]= -{ - "128"," 64"," 32"," 16"," 8"," 4"," 2" -}; - -// Nombre de graduations pour une composante RGB -int RGB_scale = 256; // 24bit -//int RGB_scale = 64; // VGA -//int RGB_scale = 16; // Amiga -//int RGB_scale = 4; // MSX2 -//int RGB_scale = 3; // Amstrad CPC - -// Nombre de graduations pour une composante dans le mode actuel -int Color_count=256; -// Les composantes vont de 0 à (Color_count-1) -int Color_max=255; -// Le demi-pas est une quantité que l'on ajoute à une composante -// avant de faire un arrondi par division. -int Color_halfstep=0; - - -void Set_palette_RGB_scale(int scale) -{ - if (scale>= 2 && scale <= 256) - RGB_scale = scale; -} - -byte Round_palette_component(byte comp) -{ - return ((comp+128/RGB_scale)*(RGB_scale-1)/255*255+(RGB_scale&1?1:0))/(RGB_scale-1); -} - -// Définir les unités pour les graduations R G B ou H S V -void Componant_unit(int count) -{ - Color_count = count; - Color_max = count-1; - Color_halfstep = 256/count/2; -} - -void Set_HSL(T_Palette start_palette, T_Palette end_palette, byte color, short diff_h, short diff_s, short diff_l) -{ - byte h, s, l; - RGB_to_HSL(start_palette[color].R,start_palette[color].G,start_palette[color].B,&h,&s,&l); - // La teinte (Hue) est cyclique - h=(diff_h+256+h); - // Pour les autres (Saturation, Lightness), au lieu d'additionner, - // on va faire un ratio, cela utilise mieux la plage de valeurs 0-255 - if (diff_s<0) - s=(255+diff_s)*s/255; - else if (diff_s>0) - s=255-(255-diff_s)*(255-s)/255; - if (diff_l<0) - l=(255+diff_l)*l/255; - else if (diff_l>0) - l=255-(255-diff_l)*(255-l)/255; - HSL_to_RGB(h,s,l,&end_palette[color].R,&end_palette[color].G,&end_palette[color].B); -} - -void Set_red(byte color, short new_color, T_Palette palette) -{ - if (new_color< 0) - new_color= 0; - if (new_color>255) - new_color=255; - // Arrondi - new_color=Round_palette_component(new_color); - - palette[color].R=new_color; - Set_color(color,palette[color].R,palette[color].G,palette[color].B); -} - - -void Set_green(byte color, short new_color, T_Palette palette) -{ - if (new_color< 0) - new_color= 0; - if (new_color>255) - new_color=255; - // Arrondi - new_color=Round_palette_component(new_color); - - palette[color].G=new_color; - Set_color(color,palette[color].R,palette[color].G,palette[color].B); -} - - -void Set_blue(byte color, short new_color, T_Palette palette) -{ - if (new_color< 0) - new_color= 0; - if (new_color>255) - new_color=255; - // Arrondi - new_color=Round_palette_component(new_color); - - palette[color].B=new_color; - Set_color(color,palette[color].R,palette[color].G,palette[color].B); -} - -void Format_componant(byte value, char *str) -// Formate une chaine de 4 caractères+\0 : "nnn " -{ - Num2str(value,str,3); - str[3]=' '; - str[4]='\0'; -} - -void Spread_colors(short start,short end,T_Palette palette) -// Modifie la palette pour obtenir un dégradé de couleur entre les deux bornes -// passées en paramètre -{ - short start_red; - short start_green; - short start_blue; - short end_red; - short end_green; - short end_blue; - short index; - - // On vérifie qu'il y ait assez de couleurs entre le début et la fin pour - // pouvoir faire un dégradé: - if ( (start!=end) && (start+1!=end) ) - { - start_red=palette[start].R; - start_green =palette[start].G; - start_blue =palette[start].B; - - end_red =palette[end ].R; - end_green =palette[end ].G; - end_blue =palette[end ].B; - - for (index=start+1;index=Window_pos_Y) && (y_pos=Window_pos_X) && (x_pos=Menu_Y_before_window) - end_y=Menu_Y_before_window; - else - end_y=Main_image_height; - - if (!Main_magnifier_mode) - { - if (Main_image_width>=Screen_width) - end_x=Screen_width; - else - end_x=Main_image_width; - - } - else - { - if (Main_image_width>=Main_separator_position) - end_x=Main_separator_position; - else - end_x=Main_image_width; - - if ((Main_X_zoom+(Main_image_width*Main_magnifier_factor))>=Screen_width) - end_x_mag=Screen_width; - else - end_x_mag=(Main_X_zoom+(Main_image_width*Main_magnifier_factor)); - - if (Main_image_height*Main_magnifier_factor>=Menu_Y_before_window) - end_y_mag=Menu_Y_before_window; - else - end_y_mag=Main_image_height*Main_magnifier_factor; - } - - // On doit maintenant faire la traduction à l'écran - Remap_zone_highlevel(0,0,end_x,end_y,conversion_table); - - if (Main_magnifier_mode) - { - Remap_zone_highlevel(Main_separator_position,0,end_x_mag,end_y_mag,conversion_table); - // Il peut encore rester le bas de la barre de split à remapper si la - // partie zoomée ne descend pas jusqu'en bas... - Remap_zone_highlevel(Main_separator_position,end_y_mag, - (Main_separator_position+(SEPARATOR_WIDTH*Menu_factor_X)), - Menu_Y_before_window,conversion_table); - } - // Remappe tous les fonds de fenetre (qui doivent contenir un bout d'écran) - Remap_window_backgrounds(conversion_table, 0, Menu_Y_before_window); -} - - -void Swap(int with_remap,short block_1_start,short block_2_start,short block_size,T_Palette palette, dword * color_usage) -{ - short pos_1; - short pos_2; - short end_1; - short end_2; - dword temp; - byte conversion_table[256]; - - T_Components temp_palette[256]; - dword Utilisation_temporaire[256]; - - // On fait une copie de la palette - memcpy(temp_palette, palette, sizeof(T_Palette)); - - // On fait une copie de la table d'utilisation des couleurs - memcpy(Utilisation_temporaire, color_usage, sizeof(dword) * 256); - - // On commence à initialiser la table de conversion à un état où elle ne - // fera aucune conversion. - for (pos_1=0;pos_1<=255;pos_1++) - conversion_table[pos_1]=pos_1; - - // On calcul les dernières couleurs de chaque bloc. - end_1=block_1_start+block_size-1; - end_2=block_2_start+block_size-1; - - if ((block_2_start>=block_1_start) && (block_2_start<=end_1)) - { - // Le bloc destination commence dans le bloc source. - - for (pos_1=block_1_start,pos_2=end_1+1;pos_1<=end_2;pos_1++) - { - // Il faut transformer la couleur pos_1 en pos_2: - - conversion_table[pos_2]=pos_1; - color_usage[pos_1]=Utilisation_temporaire[pos_2]; - palette[pos_1].R=temp_palette[pos_2].R; - palette[pos_1].G=temp_palette[pos_2].G; - palette[pos_1].B=temp_palette[pos_2].B; - - // On gère la mise à jour de pos_2 - if (pos_2==end_2) - pos_2=block_1_start; - else - pos_2++; - } - } - else - if ((block_2_start=block_1_start)) - { - // Le bloc destination déborde dans le bloc source. - - for (pos_1=block_2_start,pos_2=block_1_start;pos_1<=end_1;pos_1++) - { - // Il faut transformer la couleur pos_1 en pos_2: - - conversion_table[pos_2]=pos_1; - color_usage[pos_1]=Utilisation_temporaire[pos_2]; - palette[pos_1].R=temp_palette[pos_2].R; - palette[pos_1].G=temp_palette[pos_2].G; - palette[pos_1].B=temp_palette[pos_2].B; - - // On gère la mise à jour de pos_2 - if (pos_2==end_1) - pos_2=block_2_start; - else - pos_2++; - } - } - else - { - // Le bloc source et le bloc destination sont distincts. - - for (pos_1=block_1_start,pos_2=block_2_start;pos_1<=end_1;pos_1++,pos_2++) - { - // Il va falloir permutter la couleur pos_1 avec la couleur pos_2 - conversion_table[pos_1]=pos_2; - conversion_table[pos_2]=pos_1; - - // On intervertit le nombre d'utilisation des couleurs pour garder une - // cohérence lors d'un éventuel "Zap unused". - temp =color_usage[pos_1]; - color_usage[pos_1]=color_usage[pos_2]; - color_usage[pos_2]=temp; - - // On fait un changement de teinte: - temp =palette[pos_1].R; - palette[pos_1].R=palette[pos_2].R; - palette[pos_2].R=temp; - - temp =palette[pos_1].G; - palette[pos_1].G=palette[pos_2].G; - palette[pos_2].G=temp; - - temp =palette[pos_1].B; - palette[pos_1].B=palette[pos_2].B; - palette[pos_2].B=temp; - } - } - - if (with_remap) - { - Remap_image_highlevel(conversion_table); - } -} - - - -void Set_nice_menu_colors(dword * color_usage,int not_picture) -{ - short index,index2; - byte color; - byte replace_table[256]; - T_Components rgb[4]; - short new_colors[4]={255,254,253,252}; - - // On initialise la table de remplacement - for (index=0; index<256; index++) - replace_table[index]=index; - - // On recherche les 4 couleurs les moins utilisées dans l'image pour pouvoir - // les remplacer par les nouvelles couleurs. - for (index2=0; index2<4; index2++) - for (index=255; index>=0; index--) - { - if ((index!=new_colors[0]) && (index!=new_colors[1]) - && (index!=new_colors[2]) && (index!=new_colors[3]) - && (color_usage[index]new_colors[index+1]) - { - index2 =new_colors[index]; - new_colors[index] =new_colors[index+1]; - new_colors[index+1]=index2; - color=1; - } - } - } while (color); - - // On sauvegarde dans rgb les teintes qu'on va remplacer et on met les - // couleurs du menu par défaut - for (index=0; index<4; index++) - { - color=new_colors[index]; - rgb[index].R=Main_palette[color].R; - rgb[index].G=Main_palette[color].G; - rgb[index].B=Main_palette[color].B; - Main_palette[color].R=Fav_menu_colors[index].R; - Main_palette[color].G=Fav_menu_colors[index].G; - Main_palette[color].B=Fav_menu_colors[index].B; - } - - // Maintenant qu'on a placé notre nouvelle palette, on va chercher quelles - // sont les couleurs qui peuvent remplacer les anciennes - Hide_cursor(); - for (index=0; index<4; index++) - replace_table[new_colors[index]]=Best_color_nonexcluded - (rgb[index].R,rgb[index].G,rgb[index].B); - - if (not_picture) - { - // Remap caused by preview. Only remap screen - Remap_zone_highlevel(0,0,Screen_width,Screen_height,replace_table); - } - else - { - // On fait un changement des couleurs visibles à l'écran et dans l'image - Remap_image_highlevel(replace_table); - } - Display_cursor(); -} - - - -void Reduce_palette(short * used_colors,int nb_colors_asked,T_Palette palette,dword * color_usage) -{ - char str[5]; // buffer d'affichage du compteur - byte conversion_table[256]; // Table de conversion - int color_1; // |_ Variables de balayages - int color_2; // | de la palette - int best_color_1=0; - int best_color_2=0; - int difference; - int best_difference; - dword Utilisation; - dword Meilleure_utilisation; - - // On commence par initialiser la table de conversion dans un état où - // aucune conversion ne sera effectuée. - for (color_1=0; color_1<=255; color_1++) - conversion_table[color_1]=color_1; - - // Si on ne connait pas encore le nombre de couleurs utilisées, on le - // calcule! (!!! La fonction appelée Efface puis Affiche le curseur !!!) - if ((*used_colors)<0) - Update_color_count(used_colors,color_usage); - - Hide_cursor(); - - // On tasse la palette vers le début parce qu'elle doit ressembler à - // du Gruyère (et comme Papouille il aime pas le fromage...) - - // Pour cela, on va scruter la couleur color_1 et se servir de l'indice - // color_2 comme position de destination. - for (color_1=color_2=0;color_1<=255;color_1++) - { - if (color_usage[color_1]) - { - // On commence par s'occuper des teintes de la palette - palette[color_2].R=palette[color_1].R; - palette[color_2].G=palette[color_1].G; - palette[color_2].B=palette[color_1].B; - - // Ensuite, on met à jour le tableau d'occupation des couleurs. - color_usage[color_2]=color_usage[color_1]; - - // On va maintenant s'occuper de la table de conversion: - conversion_table[color_1]=color_2; - - // Maintenant, la place désignée par color_2 est occupée, alors on - // doit passer à un indice de destination suivant. - color_2++; - } - } - - // On met toutes les couleurs inutilisées en noir - for (;color_2<256;color_2++) - { - palette[color_2].R=0; - palette[color_2].G=0; - palette[color_2].B=0; - color_usage[color_2]=0; - } - - // Maintenant qu'on a une palette clean, on va boucler en réduisant - // le nombre de couleurs jusqu'à ce qu'on atteigne le nombre désiré. - while ((*used_colors)>nb_colors_asked) - { - // Il s'agit de trouver les 2 couleurs qui se ressemblent le plus - // parmis celles qui sont utilisées (bien sûr) et de les remplacer par - // une seule couleur qui est la moyenne pondérée de ces 2 couleurs - // en fonction de leur utilisation dans l'image. - - best_difference =0x7FFF; - Meilleure_utilisation=0x7FFFFFFF; - - for (color_1=0;color_1<(*used_colors);color_1++) - for (color_2=color_1+1;color_2<(*used_colors);color_2++) - if (color_1!=color_2) - { - difference =abs((short)palette[color_1].R-palette[color_2].R)+ - abs((short)palette[color_1].G-palette[color_2].G)+ - abs((short)palette[color_1].B-palette[color_2].B); - - if (difference<=best_difference) - { - Utilisation=color_usage[color_1]+color_usage[color_2]; - if ((differencebest_color_2) - { - // La color_1 va scroller en arrière. - - // Donc on transfère son utilisation dans l'utilisation de la - // couleur qui la précède. - color_usage[color_1-1]=color_usage[color_1]; - - // Et on transfère ses teintes dans les teintes de la couleur qui - // la précède. - palette[color_1-1].R=palette[color_1].R; - palette[color_1-1].G=palette[color_1].G; - palette[color_1-1].B=palette[color_1].B; - } - - // Une fois la palette et la table d'utilisation gérées, on peut - // s'occuper de notre table de conversion. - if (conversion_table[color_1]>best_color_2) - // La color_1 avait l'intention de se faire remplacer par une - // couleur que l'on va (ou que l'on a déjà) bouger en arrière. - conversion_table[color_1]--; - } - - // On vient d'éjecter une couleur, donc on peut mettre à jour le nombre - // de couleurs utilisées. - (*used_colors)--; - - // A la fin, on doit passer (dans la palette) les teintes du dernier - // élément de notre ensemble en noir. - palette[*used_colors].R=0; - palette[*used_colors].G=0; - palette[*used_colors].B=0; - - // Au passage, on va s'assurer que l'on a pas oublié de la mettre à une - // utilisation nulle. - color_usage[*used_colors]=0; - - // Après avoir éjecté une couleur, on le fait savoir à l'utilisateur par - // l'intermédiaire du compteur de nombre utilisées. - Num2str(*used_colors,str,3); - Print_in_window(186,23,str,MC_Black,MC_Light); - } - - // Maintenant, tous ces calculs doivent êtres pris en compte dans la - // palette, l'image et à l'écran. - Remap_image_highlevel(conversion_table); // Et voila pour l'image et l'écran - Display_cursor(); -} - - - -void Set_palette_slider(T_Scroller_button * slider, - word nb_elements, word position, - char * value, short x_pos) -{ - slider->Nb_elements=nb_elements; - slider->Position=position; - Compute_slider_cursor_height(slider); - Window_draw_slider(slider); - Print_counter(x_pos,172,value,MC_Black,MC_Light); -} - - - -void Display_sliders(T_Scroller_button * red_slider, - T_Scroller_button * green_slider, - T_Scroller_button * blue_slider, - byte block_is_selected, T_Components * palette) -{ - char str[5]; - - if (block_is_selected) - { - Set_palette_slider(red_slider,Color_max*2+1,Color_max,"± 0",176); - Set_palette_slider(green_slider,Color_max*2+1,Color_max,"± 0",203); - Set_palette_slider(blue_slider,Color_max*2+1,Color_max,"± 0",230); - } - else - { - byte j1, j2, j3; - j1= palette[Fore_color].R; - j2= palette[Fore_color].G; - j3= palette[Fore_color].B; - if (!Palette_view_is_RGB) - { - RGB_to_HSL(j1,j2,j3,&j1,&j2,&j3); - } - - Format_componant(j1*Color_max/255,str); - Set_palette_slider(red_slider,Color_count,Color_max-j1*Color_max/255,str,176); - Format_componant(j2*Color_max/255,str); - Set_palette_slider(green_slider,Color_count,Color_max-j2*Color_max/255,str,203); - Format_componant(j3*Color_max/255,str); - Set_palette_slider(blue_slider,Color_count,Color_max-j3*Color_max/255,str,230); - } -} - - - -void Draw_all_palette_sliders(T_Scroller_button * red_slider, - T_Scroller_button * green_slider, - T_Scroller_button * blue_slider, - T_Palette palette,byte start,byte end) -{ - char str[5]; - - Hide_cursor(); - // Réaffichage des jauges: - if (start!=end) - { - // Dans le cas d'un bloc, tout à 0. - red_slider->Position =Color_max; - Window_draw_slider(red_slider); - Print_counter(176,172,"± 0",MC_Black,MC_Light); - - green_slider->Position =Color_max; - Window_draw_slider(green_slider); - Print_counter(203,172,"± 0",MC_Black,MC_Light); - - blue_slider->Position =Color_max; - Window_draw_slider(blue_slider); - Print_counter(230,172,"± 0",MC_Black,MC_Light); - } - else - { - // Dans le cas d'une seule couleur, composantes. - byte j1, j2, j3; - j1= palette[start].R; - j2= palette[start].G; - j3= palette[start].B; - if (!Palette_view_is_RGB) - { - RGB_to_HSL(j1,j2,j3,&j1,&j2,&j3); - } - Format_componant(j1*Color_max/255,str); - red_slider->Position=Color_max-j1*Color_max/255; - Window_draw_slider(red_slider); - Print_counter(176,172,str,MC_Black,MC_Light); - - Format_componant(j2*Color_max/255,str); - green_slider->Position=Color_max-j2*Color_max/255; - Window_draw_slider(green_slider); - Print_counter(203,172,str,MC_Black,MC_Light); - - Format_componant(j3*Color_max/255,str); - blue_slider->Position=Color_max-j3*Color_max/255; - Window_draw_slider(blue_slider); - Print_counter(230,172,str,MC_Black,MC_Light); - } - Display_cursor(); -} - - -void Button_Palette(void) -{ - static short reducer_index=0; - static short reduce_colors_number=256; - short temp_color; // Variable pouvant reservir pour différents calculs intermédiaires - dword temp; - byte color,click; // Variables pouvant reservir pour différents calculs intermédiaires - short clicked_button; - word old_mouse_x; - word old_mouse_y; - byte old_mouse_k; - byte block_start; - byte block_end; - byte first_color; - byte last_color; - char str[10]; - word i; - //short x_pos,y_pos; - T_Normal_button * button_used; - T_Scroller_button * red_slider; - T_Scroller_button * green_slider; - T_Scroller_button * blue_slider; - T_Scroller_button * reduce_slider; - byte image_is_backed_up=0; - byte need_to_remap=0; - - dword color_usage[256]; - short used_colors=-1; // -1 <=> Inconnu - byte conversion_table[256]; - - T_Components * backup_palette; - T_Components * temp_palette; - T_Components * working_palette; - - backup_palette =(T_Components *)malloc(sizeof(T_Palette)); - temp_palette=(T_Components *)malloc(sizeof(T_Palette)); - working_palette=(T_Components *)malloc(sizeof(T_Palette)); - - Componant_unit(RGB_scale); - - Open_window(299,188,"Palette"); - - memcpy(working_palette,Main_palette,sizeof(T_Palette)); - memcpy(backup_palette ,Main_palette,sizeof(T_Palette)); - memcpy(temp_palette,Main_palette,sizeof(T_Palette)); - - Window_set_palette_button(5,79); // 1 - - Window_display_frame (173, 67,121,116); - Window_display_frame (128, 16, 91, 39); - Window_display_frame (221, 16, 73, 39); - // Frame creux destiné à l'affichage de la(les) couleur(s) sélectionnée(s) - Window_display_frame_in(259, 88, 26, 74); - - // Graduation des jauges de couleur - Block(Window_pos_X+(Menu_factor_X*179),Window_pos_Y+(Menu_factor_Y*109),Menu_factor_X*17,Menu_factor_Y,MC_Dark); - Block(Window_pos_X+(Menu_factor_X*206),Window_pos_Y+(Menu_factor_Y*109),Menu_factor_X*17,Menu_factor_Y,MC_Dark); - Block(Window_pos_X+(Menu_factor_X*233),Window_pos_Y+(Menu_factor_Y*109),Menu_factor_X*17,Menu_factor_Y,MC_Dark); - Block(Window_pos_X+(Menu_factor_X*179),Window_pos_Y+(Menu_factor_Y*125),Menu_factor_X*17,Menu_factor_Y,MC_Dark); - Block(Window_pos_X+(Menu_factor_X*206),Window_pos_Y+(Menu_factor_Y*125),Menu_factor_X*17,Menu_factor_Y,MC_Dark); - Block(Window_pos_X+(Menu_factor_X*233),Window_pos_Y+(Menu_factor_Y*125),Menu_factor_X*17,Menu_factor_Y,MC_Dark); - Block(Window_pos_X+(Menu_factor_X*179),Window_pos_Y+(Menu_factor_Y*141),Menu_factor_X*17,Menu_factor_Y,MC_Dark); - Block(Window_pos_X+(Menu_factor_X*206),Window_pos_Y+(Menu_factor_Y*141),Menu_factor_X*17,Menu_factor_Y,MC_Dark); - Block(Window_pos_X+(Menu_factor_X*233),Window_pos_Y+(Menu_factor_Y*141),Menu_factor_X*17,Menu_factor_Y,MC_Dark); - // Jauges de couleur - Palette_view_is_RGB=1; - red_slider = Window_set_scroller_button(182, 81, 88,Color_count,1,Color_max-working_palette[Fore_color].R*Color_max/255);// 2 - green_slider = Window_set_scroller_button(209, 81, 88,Color_count,1,Color_max-working_palette[Fore_color].G*Color_max/255);// 3 - blue_slider = Window_set_scroller_button(236, 81, 88,Color_count,1,Color_max-working_palette[Fore_color].B*Color_max/255);// 4 - Print_in_window(184,71,"R",MC_Dark,MC_Light); - Print_in_window(211,71,"G",MC_Dark,MC_Light); - Print_in_window(238,71,"B",MC_Dark,MC_Light); - - first_color=last_color=block_start=block_end=Fore_color; - Tag_color_range(block_start,block_end); - - // Affichage dans le block de visu de la couleur en cours - Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y*89),Menu_factor_X*24,Menu_factor_Y*72,Back_color); - Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); - - // Affichage des valeurs de la couleur courante (pour 1 couleur) - Format_componant(Main_palette[Fore_color].R*Color_max/255,str); - Print_counter(176,172,str,MC_Black,MC_Light); - Format_componant(Main_palette[Fore_color].G*Color_max/255,str); - Print_counter(203,172,str,MC_Black,MC_Light); - Format_componant(Main_palette[Fore_color].B*Color_max/255,str); - Print_counter(230,172,str,MC_Black,MC_Light); - - Print_in_window(129,58,"Color number:",MC_Dark,MC_Light); - Num2str(Fore_color,str,3); - Print_in_window(237,58,str,MC_Black,MC_Light); - - - Window_set_normal_button( 6,17,59,14,"Default",3,1,SDLK_f); // 5 - Window_set_normal_button(66,17,29,14,"Gry" ,1,1,SDLK_g); // 6 - Window_set_normal_button(66,47,29,14,"Swp" ,0,1,KEY_NONE); // 7 - Window_set_normal_button( 6,47,59,14,"X-Swap" ,1,1,SDLK_x); // 8 - Window_set_normal_button(66,32,29,14,"Cpy" ,1,1,SDLK_c); // 9 - Window_set_normal_button( 6,32,59,14,"Spread" ,4,1,SDLK_e); // 10 - - Window_set_normal_button(239,20,51,14,"Reduce" ,1,1,SDLK_r); // 11 - Print_in_window(241,41,"to",MC_Dark,MC_Light); - - Window_set_normal_button( 6,168,35,14,"Undo" ,1,1,SDLK_u); // 12 - Window_set_normal_button( 62,168,51,14,"Cancel",0,1,KEY_ESC); // 13 - Window_set_normal_button(117,168,51,14,"OK" ,0,1,SDLK_RETURN); // 14 - - button_used = Window_set_normal_button(132,20,83,14,"Used: ???",4,1,SDLK_d);// 15 - Window_set_normal_button(132,37,83,14,"Zap unused",0,1,SDLK_DELETE);//16 - - // Jauge de réduction de palette - reduce_slider = Window_set_scroller_button(225,20,31,7,1,reducer_index);// 17 - - Window_set_repeatable_button(266, 74,12,11,"+",0,1,SDLK_KP_PLUS); // 18 - Window_set_repeatable_button(266,165,12,11,"-",0,1,SDLK_KP_MINUS); // 19 - - Window_set_normal_button(96,17,29,14,"Neg" ,1,1,SDLK_n); // 20 - Window_set_normal_button(66,62,29,14,"Inv" ,1,1,SDLK_i); // 21 - Window_set_normal_button( 6,62,59,14,"X-Inv." ,5,1,SDLK_v); // 22 - - Window_set_input_button(263,39,3); // 23 - - Window_set_normal_button(96,32,29,14,"HSL" ,1,1,SDLK_h); // 24 - Window_set_normal_button(96,47,29,14,"Srt" ,1,1,SDLK_s); // 25 - // Affichage du facteur de réduction de la palette - Num2str(reduce_colors_number,str,3); - Print_in_window(265,41,str,MC_Black,MC_Light); - - // Dessin des petits effets spéciaux pour les boutons [+] et [-] - Draw_thingumajig(263, 74,MC_White,-1); - Draw_thingumajig(280, 74,MC_White,+1); - Draw_thingumajig(263,165,MC_Dark,-1); - Draw_thingumajig(280,165,MC_Dark,+1); - - Update_window_area(0,0,299,188); - - Display_cursor(); - - if (Config.Auto_nb_used) - Update_color_count(&used_colors,color_usage); - - do - { - old_mouse_x=Mouse_X; - old_mouse_y=Mouse_Y; - old_mouse_k=Mouse_K; - clicked_button=Window_clicked_button(); - - switch (clicked_button) - { - case 0 : // Nulle part - break; - case -1 : // Hors de la fenêtre - case 1 : // palette - if ( (Mouse_X!=old_mouse_x) || (Mouse_Y!=old_mouse_y) || (Mouse_K!=old_mouse_k) ) - { - Hide_cursor(); - temp_color=(clicked_button==1) ? Window_attribute2 : Read_pixel(Mouse_X,Mouse_Y); - if (Mouse_K==RIGHT_SIDE) - { - if (Back_color!=temp_color) - { - Back_color=temp_color; - // 4 blocks de back_color entourant la fore_color - Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*24,Menu_factor_Y<<2,Back_color); - Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y*157),Menu_factor_X*24,Menu_factor_Y<<2,Back_color); - Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color); - Block(Window_pos_X+(Menu_factor_X*280),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color); - Update_rect(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*32,Menu_factor_Y*72); - } - } - else - { - if (!old_mouse_k) - { - // On vient de clicker sur une couleur (et une seule) - if ( (Fore_color!=temp_color) || (block_start!=block_end) ) - { - // La couleur en question est nouvelle ou elle annule un - // ancien bloc. Il faut donc sélectionner cette couleur comme - // unique couleur choisie. - - Fore_color=first_color=last_color=block_start=block_end=temp_color; - Tag_color_range(block_start,block_end); - - // Affichage du n° de la couleur sélectionnée - Block(Window_pos_X+(Menu_factor_X*237),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*56,Menu_factor_Y*7,MC_Light); - Num2str(Fore_color,str,3); - Print_in_window(237,58,str,MC_Black,MC_Light); - Update_rect(Window_pos_X+(Menu_factor_X*237),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*56,Menu_factor_Y*7); - - // Affichage des jauges - Block(Window_pos_X+(Menu_factor_X*176),Window_pos_Y+(Menu_factor_Y*172),Menu_factor_X*84,Menu_factor_Y*7,MC_Light); - Display_sliders(red_slider,green_slider,blue_slider,0,working_palette); - - // Affichage dans le block de visu de la couleur en cours - Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); - Update_rect(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64); - - memcpy(backup_palette ,working_palette,sizeof(T_Palette)); - memcpy(temp_palette,working_palette,sizeof(T_Palette)); - } - } - else - { - // On maintient le click, on va donc tester si le curseur bouge - if (temp_color!=last_color) - { - // On commence par ordonner la 1ère et dernière couleur du bloc - if (first_colortemp_color) - { - block_start=temp_color; - block_end=first_color; - - // Affichage du n° de la couleur sélectionnée - Num2str(block_start,str ,3); - Num2str(block_end ,str+4,3); - str[3]=26; // Flèche vers la droite - Print_in_window(237,58,str,MC_Black,MC_Light); - - // Affichage des jauges - Display_sliders(red_slider,green_slider,blue_slider,1,NULL); - - // Affichage dans le block de visu du bloc (dégradé) en cours - Display_grad_block_in_window(264,93,block_start,block_end); - } - else - { - block_start=block_end=first_color; - Block(Window_pos_X+(Menu_factor_X*176),Window_pos_Y+(Menu_factor_Y*172),Menu_factor_X*84,Menu_factor_Y*7,MC_Light); - - // Affichage du n° de la couleur sélectionnée - Block(Window_pos_X+(Menu_factor_X*261),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*32,Menu_factor_Y*7,MC_Light); - Num2str(Fore_color,str,3); - Print_in_window(237,58,str,MC_Black,MC_Light); - - // Affichage des jauges - Display_sliders(red_slider,green_slider,blue_slider,0,working_palette); - - // Affichage dans le block de visu de la couleur en cours - Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); - Update_rect(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64); - } - - // On tagge le bloc (ou la couleur) - Tag_color_range(block_start,block_end); - } - - last_color=temp_color; - } - } - Display_cursor(); - } - break; - case 2 : // Jauge rouge - Hide_cursor(); - if (block_start==block_end) - { - if(Palette_view_is_RGB) - { - Set_red(Fore_color,(Color_max-red_slider->Position)*255/Color_max,working_palette); - Format_componant(working_palette[Fore_color].R*Color_max/255,str); - } - else - { - HSL_to_RGB( - 255-red_slider->Position, - 255-green_slider->Position, - 255-blue_slider->Position, - &working_palette[Fore_color].R, - &working_palette[Fore_color].G, - &working_palette[Fore_color].B); - Format_componant((int)255-red_slider->Position,str); - } - Print_counter(176,172,str,MC_Black,MC_Light); - } - else - { - if(Palette_view_is_RGB) - { - for (i=block_start; i<=block_end; i++) - Set_red(i,temp_palette[i].R+(Color_max-red_slider->Position)*255/Color_max,working_palette); - } - else - { - for (i=block_start; i<=block_end; i++) - Set_HSL( - temp_palette, - working_palette, - i, - Color_max-red_slider->Position, - Color_max-green_slider->Position, - Color_max-blue_slider->Position - ); - } - - if (red_slider->Position>Color_max) - { - // Jauge dans les négatifs: - Num2str(-(Color_max-red_slider->Position),str,4); - str[0]='-'; - } - else if (red_slider->PositionPosition ,str,4); - str[0]='+'; - } - else - { - // Jauge nulle: - strcpy(str,"± 0"); - } - Print_counter(176,172,str,MC_Black,MC_Light); - - } - - need_to_remap=1; - - Display_cursor(); - Set_palette(working_palette); - break; - case 3 : // Jauge verte - Hide_cursor(); - if (block_start==block_end) - { - if(Palette_view_is_RGB) - { - Set_green (Fore_color,(Color_max-green_slider->Position)*255/Color_max,working_palette); - Format_componant(working_palette[Fore_color].G*Color_max/255,str); - } - else - { - HSL_to_RGB( - 255-red_slider->Position, - 255-green_slider->Position, - 255-blue_slider->Position, - &working_palette[Fore_color].R, - &working_palette[Fore_color].G, - &working_palette[Fore_color].B); - Format_componant((int)255-green_slider->Position,str); - } - Print_counter(203,172,str,MC_Black,MC_Light); - } - else - { - if(Palette_view_is_RGB) - { - for (i=block_start; i<=block_end; i++) - Set_green (i,temp_palette[i].G+(Color_max-green_slider->Position)*255/Color_max,working_palette); - } - else - { - for (i=block_start; i<=block_end; i++) - Set_HSL( - temp_palette, - working_palette, - i, - Color_max-red_slider->Position, - Color_max-green_slider->Position, - Color_max-blue_slider->Position - ); - } - - if (green_slider->Position>Color_max) - { - // Jauge dans les négatifs: - Num2str(-(Color_max-green_slider->Position),str,4); - str[0]='-'; - } - else if (green_slider->PositionPosition ,str,4); - str[0]='+'; - } - else - { - // Jauge nulle: - strcpy(str,"± 0"); - } - Print_counter(203,172,str,MC_Black,MC_Light); - } - - need_to_remap=1; - - Display_cursor(); - Set_palette(working_palette); - break; - - case 4 : // Jauge bleue - Hide_cursor(); - if (block_start==block_end) - { - if(Palette_view_is_RGB) - { - Set_blue (Fore_color,(Color_max-blue_slider->Position)*255/Color_max,working_palette); - Format_componant(working_palette[Fore_color].B*Color_max/255,str); - } - else - { - HSL_to_RGB( - 255-red_slider->Position, - 255-green_slider->Position, - 255-blue_slider->Position, - &working_palette[Fore_color].R, - &working_palette[Fore_color].G, - &working_palette[Fore_color].B); - Format_componant((int)255-blue_slider->Position,str); - } - Print_counter(230,172,str,MC_Black,MC_Light); - } - else - { - if(Palette_view_is_RGB) - { - for (i=block_start; i<=block_end; i++) - Set_blue(i,temp_palette[i].B+(Color_max-blue_slider->Position)*255/Color_max,working_palette); - } - else - { - for (i=block_start; i<=block_end; i++) - Set_HSL( - temp_palette, - working_palette, - i, - Color_max-red_slider->Position, - Color_max-green_slider->Position, - Color_max-blue_slider->Position - ); - } - - if (blue_slider->Position>Color_max) - { - // Jauge dans les négatifs: - Num2str(-(Color_max-blue_slider->Position),str,4); - str[0]='-'; - } - else if (blue_slider->PositionPosition ,str,4); - str[0]='+'; - } - else - { - // Jauge nulle: - strcpy(str,"± 0"); - } - Print_counter(230,172,str,MC_Black,MC_Light); - } - - need_to_remap=1; - - Display_cursor(); - Set_palette(working_palette); - break; - - case 5 : // Default - memcpy(backup_palette,working_palette,sizeof(T_Palette)); - memcpy(working_palette,Gfx->Default_palette,sizeof(T_Palette)); - memcpy(temp_palette,Gfx->Default_palette,sizeof(T_Palette)); - Set_palette(Gfx->Default_palette); - Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); - // On prépare la "modifiabilité" des nouvelles couleurs - memcpy(temp_palette,working_palette,sizeof(T_Palette)); - - need_to_remap=1; - break; - - case 6 : // Grey scale - // Backup - memcpy(backup_palette,working_palette,sizeof(T_Palette)); - // Grey Scale - for (i=block_start;i<=block_end;i++) - { - temp_color=(dword)( ((dword)working_palette[i].R*30) + ((dword)working_palette[i].G*59) + ((dword)working_palette[i].B*11) )/100; - Set_red(i,temp_color,working_palette); - Set_green (i,temp_color,working_palette); - Set_blue (i,temp_color,working_palette); - } - Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); - // On prépare la "modifiabilité" des nouvelles couleurs - Set_palette(working_palette); - memcpy(temp_palette,working_palette,sizeof(T_Palette)); - - need_to_remap=1; - break; - - case 7 : // Swap - case 8 : // X-Swap - temp_color=Wait_click_in_palette(Window_palette_button_list); - if ((temp_color>=0) - && (temp_color!=block_start)) - { - Hide_cursor(); - memcpy(backup_palette,working_palette,sizeof(T_Palette)); - - // On calcule le nombre de couleurs a swapper sans risquer de sortir - // de la palette (La var. first_color est utilisée pour économiser 1 var; c'est tout) - first_color=(temp_color+block_end-block_start<=255)?block_end+1-block_start:256-temp_color; - - if (clicked_button==8) // On ne fait de backup de l'image que si on - // est en mode X-SWAP. - if (!image_is_backed_up) - { - Backup(); - image_is_backed_up=1; - } - - Swap(clicked_button==8,block_start,temp_color,first_color,working_palette,color_usage); - - memcpy(temp_palette,working_palette,sizeof(T_Palette)); - - // On déplace le bloc vers les modifs: - last_color=block_end=temp_color+first_color-1; - Fore_color=first_color=block_start=temp_color; - // On raffiche le n° des bornes du bloc: - if (block_start!=block_end) - { - // Cas d'un bloc multi-couleur - Num2str(block_start,str ,3); - Num2str(block_end ,str+4,3); - str[3]=26; // Flèche vers la droite - // Affichage dans le block de visu du bloc (dégradé) en cours - Display_grad_block_in_window(264,93,block_start,block_end); - } - else - { - // Cas d'une seule couleur - Num2str(Fore_color,str,3); - Block(Window_pos_X+(Menu_factor_X*237),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*56,Menu_factor_Y* 7,MC_Light); - // Affichage dans le block de visu de la couleur en cours - Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); - } - Print_in_window(237,58,str,MC_Black,MC_Light); - // On tag le bloc (ou la couleur) - Tag_color_range(block_start,block_end); - - need_to_remap=1; - - Set_palette(working_palette); - - Display_cursor(); - Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); - - // En cas de X-Swap, tout l'ecran a pu changer de couleur. - if (clicked_button==8) - Update_rect(0, 0, Screen_width, Menu_Y_before_window); - Wait_end_of_click(); - } - break; - - case 9 : // Copy - temp_color=Wait_click_in_palette(Window_palette_button_list); - if ((temp_color>=0) && (temp_color!=block_start)) - { - Hide_cursor(); - memcpy(backup_palette,working_palette,sizeof(T_Palette)); - memcpy(working_palette+temp_color,backup_palette+block_start, - ((temp_color+block_end-block_start<=255)?block_end+1-block_start:256-temp_color)*3); - memcpy(temp_palette,working_palette,sizeof(T_Palette)); - Set_palette(working_palette); - // On déplace le bloc vers les modifs: - last_color=block_end=((temp_color+block_end-block_start<=255)?(temp_color+block_end-block_start):255); - Fore_color=first_color=block_start=temp_color; - // On raffiche le n° des bornes du bloc: - if (block_start!=block_end) - { - // Cas d'un bloc multi-couleur - Num2str(block_start,str ,3); - Num2str(block_end ,str+4,3); - str[3]=26; // Flèche vers la droite - // Affichage dans le block de visu du bloc (dégradé) en cours - Display_grad_block_in_window(264,93,block_start,block_end); - } - else - { - // Cas d'une seule couleur - Num2str(Fore_color,str,3); - Block(Window_pos_X+(Menu_factor_X*237),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*56,Menu_factor_Y* 7,MC_Light); - // Affichage dans le block de visu de la couleur en cours - Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); - } - Print_in_window(237,58,str,MC_Black,MC_Light); - // On tag le bloc (ou la couleur) - Tag_color_range(block_start,block_end); - - need_to_remap=1; - - Display_cursor(); - Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); - Wait_end_of_click(); - } - break; - - case 10 : // Spread - if (block_start!=block_end) - { - memcpy(backup_palette,working_palette,sizeof(T_Palette)); - Spread_colors(block_start,block_end,working_palette); - } - else - { - temp_color=Wait_click_in_palette(Window_palette_button_list); - if (temp_color>=0) - { - memcpy(backup_palette,working_palette,sizeof(T_Palette)); - if (temp_colorPosition) - { - reducer_index=reduce_slider->Position; - // Affichage du facteur de réduction de la palette - Hide_cursor(); - Print_in_window(265,41,Palette_reduce_label[reducer_index],MC_Black,MC_Light); - Display_cursor(); - reduce_colors_number=atoi(Palette_reduce_label[reducer_index]); - } - break; - - case 18 : // [+] - if (!Palette_view_is_RGB) - break; - Hide_cursor(); - if (block_start==block_end) - { - if (red_slider->Position) - { - (red_slider->Position)--; - Window_draw_slider(red_slider); - Set_red(Fore_color,(Color_max-red_slider->Position)*255/Color_max,working_palette); - Format_componant(working_palette[Fore_color].R*Color_max/255,str); - Print_counter(176,172,str,MC_Black,MC_Light); - } - if (green_slider->Position) - { - (green_slider->Position)--; - Window_draw_slider(green_slider); - Set_green (Fore_color,(Color_max-green_slider->Position)*255/Color_max,working_palette); - Format_componant(working_palette[Fore_color].G*Color_max/255,str); - Print_counter(203,172,str,MC_Black,MC_Light); - } - if (blue_slider->Position) - { - (blue_slider->Position)--; - Window_draw_slider(blue_slider); - Set_blue (Fore_color,(Color_max-blue_slider->Position)*255/Color_max,working_palette); - Format_componant(working_palette[Fore_color].B*Color_max/255,str); - Print_counter(230,172,str,MC_Black,MC_Light); - } - } - else - { - if (red_slider->Position) - { - (red_slider->Position)--; - Window_draw_slider(red_slider); - } - if (green_slider->Position) - { - (green_slider->Position)--; - Window_draw_slider(green_slider); - } - if (blue_slider->Position) - { - (blue_slider->Position)--; - Window_draw_slider(blue_slider); - } - - for (i=block_start; i<=block_end; i++) - { - Set_red(i,temp_palette[i].R+(Color_max-red_slider->Position)*255/Color_max,working_palette); - Set_green (i,temp_palette[i].G+(Color_max-green_slider->Position)*255/Color_max,working_palette); - Set_blue (i,temp_palette[i].B+(Color_max-blue_slider->Position)*255/Color_max,working_palette); - } - - // -- red -- - if (red_slider->Position>Color_max) - { - // Jauge dans les négatifs: - Num2str(-(Color_max-red_slider->Position),str,4); - str[0]='-'; - } - else if (red_slider->PositionPosition ,str,4); - str[0]='+'; - } - else - { - // Jauge nulle: - strcpy(str,"± 0"); - } - Print_counter(176,172,str,MC_Black,MC_Light); - - - // -- green -- - if (green_slider->Position>Color_max) - { - // Jauge dans les négatifs: - Num2str(-(Color_max-green_slider->Position),str,4); - str[0]='-'; - } - else if (green_slider->PositionPosition ,str,4); - str[0]='+'; - } - else - { - // Jauge nulle: - strcpy(str,"± 0"); - } - Print_counter(203,172,str,MC_Black,MC_Light); - - - // -- blue -- - if (blue_slider->Position>Color_max) - { - // Jauge dans les négatifs: - Num2str(-(Color_max-blue_slider->Position),str,4); - str[0]='-'; - } - else if (blue_slider->PositionPosition ,str,4); - str[0]='+'; - } - else - { - // Jauge nulle: - strcpy(str,"± 0"); - } - Print_counter(230,172,str,MC_Black,MC_Light); - } - - need_to_remap=1; - - Display_cursor(); - Set_palette(working_palette); - break; - - case 19 : // [-] - if (!Palette_view_is_RGB) - break; - Hide_cursor(); - if (block_start==block_end) - { - if (red_slider->PositionPosition)++; - Window_draw_slider(red_slider); - Set_red(Fore_color,(Color_max-red_slider->Position)*255/Color_max,working_palette); - Format_componant(working_palette[Fore_color].R*Color_max/255,str); - Print_counter(176,172,str,MC_Black,MC_Light); - } - if (green_slider->PositionPosition)++; - Window_draw_slider(green_slider); - Set_green (Fore_color,(Color_max-green_slider->Position)*255/Color_max,working_palette); - Format_componant(working_palette[Fore_color].G*Color_max/255,str); - Print_counter(203,172,str,MC_Black,MC_Light); - } - if (blue_slider->PositionPosition)++; - Window_draw_slider(blue_slider); - Set_blue (Fore_color,(Color_max-blue_slider->Position)*255/Color_max,working_palette); - Format_componant(working_palette[Fore_color].B*Color_max/255,str); - Print_counter(230,172,str,MC_Black,MC_Light); - } - } - else - { - if (red_slider->Position<(Color_max*2)) - { - (red_slider->Position)++; - Window_draw_slider(red_slider); - } - if (green_slider->Position<(Color_max*2)) - { - (green_slider->Position)++; - Window_draw_slider(green_slider); - } - if (blue_slider->Position<(Color_max*2)) - { - (blue_slider->Position)++; - Window_draw_slider(blue_slider); - } - - for (i=block_start; i<=block_end; i++) - { - Set_red(i,temp_palette[i].R+(Color_max-red_slider->Position)*255/Color_max,working_palette); - Set_green (i,temp_palette[i].G+(Color_max-green_slider->Position)*255/Color_max,working_palette); - Set_blue (i,temp_palette[i].B+(Color_max-blue_slider->Position)*255/Color_max,working_palette); - } - - // -- red -- - if (red_slider->Position>Color_max) - { - // Jauge dans les négatifs: - Num2str(-(Color_max-red_slider->Position),str,4); - str[0]='-'; - } - else if (red_slider->PositionPosition ,str,4); - str[0]='+'; - } - else - { - // Jauge nulle: - strcpy(str,"± 0"); - } - Print_counter(176,172,str,MC_Black,MC_Light); - - - // -- green -- - if (green_slider->Position>Color_max) - { - // Jauge dans les négatifs: - Num2str(-(Color_max-green_slider->Position),str,4); - str[0]='-'; - } - else if (green_slider->PositionPosition ,str,4); - str[0]='+'; - } - else - { - // Jauge nulle: - strcpy(str,"± 0"); - } - Print_counter(203,172,str,MC_Black,MC_Light); - - - // -- blue -- - if (blue_slider->Position>Color_max) - { - // Jauge dans les négatifs: - Num2str(-(Color_max-blue_slider->Position),str,4); - str[0]='-'; - } - else if (blue_slider->PositionPosition ,str,4); - str[0]='+'; - } - else - { - // Jauge nulle: - strcpy(str,"± 0"); - } - Print_counter(230,172,str,MC_Black,MC_Light); - } - - need_to_remap=1; - - Display_cursor(); - Set_palette(working_palette); - break; - - case 20 : // Negative - // Backup - memcpy(backup_palette,working_palette,sizeof(T_Palette)); - // Negative - for (i=block_start;i<=block_end;i++) - { - Set_red(i,255-working_palette[i].R,working_palette); - Set_green (i,255-working_palette[i].G,working_palette); - Set_blue (i,255-working_palette[i].B,working_palette); - } - Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); - Set_palette(working_palette); - // On prépare la "modifiabilité" des nouvelles couleurs - memcpy(temp_palette,working_palette,sizeof(T_Palette)); - - need_to_remap=1; - break; - - case 21 : // Inversion - case 22 : // X-Inversion - // Backup - memcpy(backup_palette,working_palette,sizeof(T_Palette)); - // On initialise la table de conversion - for (i=0; i<=255; i++) - conversion_table[i]=i; - // Inversion - for (i=block_start;i<=block_end;i++) - { - temp_color=block_end-(i-block_start); - Set_red(i,backup_palette[temp_color].R,working_palette); - Set_green (i,backup_palette[temp_color].G,working_palette); - Set_blue (i,backup_palette[temp_color].B,working_palette); - if (clicked_button==22) - { - conversion_table[i]=temp_color; - conversion_table[temp_color]=i; - - temp=color_usage[i]; - color_usage[i]=color_usage[temp_color]; - color_usage[temp_color]=temp; - } - } - Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); - // Si on est en X-Invert, on remap l'image (=> on fait aussi 1 backup) - if (clicked_button==22) - { - if (!image_is_backed_up) - { - Backup(); - image_is_backed_up=1; - } - Hide_cursor(); - Remap_image_highlevel(conversion_table); - Display_cursor(); - } - // On prépare la "modifiabilité" des nouvelles couleurs - Set_palette(working_palette); - memcpy(temp_palette,working_palette,sizeof(T_Palette)); - - need_to_remap=1; - break; - - case 23 : // Saisie du nombre de couleurs pour la réduction de palette - Num2str(reduce_colors_number,str,3); - - if (Readline(265,41,str,3,1)) - { - temp_color=atoi(str); - // Correction de la valeur lue - if ( (temp_color>256) || (temp_color<2) ) - { - if (temp_color>256) - temp_color=256; - else - temp_color=2; - - Num2str(temp_color,str,3); - Window_input_content(Window_special_button_list,str); - } - - reduce_colors_number=temp_color; - } - Display_cursor(); - break; - - case 24 : // HSL <> RGB - - // Acte les changements en cours sur une ou plusieurs couleurs - memcpy(temp_palette,working_palette,sizeof(T_Palette)); - memcpy(backup_palette ,working_palette,sizeof(T_Palette)); - - Palette_view_is_RGB = !Palette_view_is_RGB; - - if(! Palette_view_is_RGB) - { - // On passe en HSL - Print_in_window(184,71,"H",MC_Dark,MC_Light); - Print_in_window(211,71,"S",MC_Dark,MC_Light); - Print_in_window(238,71,"L",MC_Dark,MC_Light); - Componant_unit(256); - - // Display the + and - button as disabled - Window_draw_normal_bouton(266, 74,12,11,"+",0,0); - Window_draw_normal_bouton(266,165,12,11,"-",0,0); - } - else - { - // On passe en RGB - Print_in_window(184,71,"R",MC_Dark,MC_Light); - Print_in_window(211,71,"G",MC_Dark,MC_Light); - Print_in_window(238,71,"B",MC_Dark,MC_Light); - Componant_unit(RGB_scale); - - // Display the + and - button as enabled - Window_draw_normal_bouton(266, 74,12,11,"+",0,1); - Window_draw_normal_bouton(266,165,12,11,"-",0,1); - } - Display_sliders(red_slider,green_slider,blue_slider,(block_start!=block_end),working_palette); - Update_window_area(265,73,14,103); - break; - - case 25 : // Sort palette - { - byte h = 0, l = 0, s=0; - byte oh=0,ol=0,os=0; // Valeur pour la couleur précédente - int swap=1; - byte remap_table[256]; - byte inverted_table[256]; - byte begin, end; - - if(block_start==block_end) - { - begin = 0; - end = 255; - } - else - { - begin = block_start; - end = block_end; - } - - // Init remap table - for (i=0;i<256;i++) - remap_table[i]=i; - // Make a backup because remapping is an undoable modification - if (!image_is_backed_up) - { - Backup(); - image_is_backed_up=1; - } - - if(Window_attribute1==LEFT_SIDE) - // Laft click on button: Sort by Hue (H) and Lightness (L) - while(swap==1) - { - swap=0; - h=0;l=255;s=0; - for(temp_color=begin;temp_color<=end;temp_color++) - { - oh=h; ol=l; os=s; - RGB_to_HSL(working_palette[temp_color].R, - working_palette[temp_color].G, - working_palette[temp_color].B,&h,&s,&l); - - if( - ((s==0) && (os>0)) // A grey is before a saturated color - || ((s>0 && os > 0) && (hol))) // 2 saturated colors: sort by H, then by L - || ((os==0 && s==0) && l>ol)) // Two greys: sort by L only - { - // Swap color with the previous one - byte swap_color; - Swap(0,temp_color,temp_color-1,1,working_palette,color_usage); - - swap_color=remap_table[temp_color]; - remap_table[temp_color]=remap_table[temp_color-1]; - remap_table[temp_color-1]=swap_color; - - swap=1; - } - } - } - - else // Right click > Sort only on L - while(swap==1) - { - swap=0; - l=255; - for(temp_color=begin;temp_color<=end;temp_color++) - { - ol=l; - RGB_to_HSL(working_palette[temp_color].R, - working_palette[temp_color].G, - working_palette[temp_color].B,&h,&s,&l); - - if(l>ol) - { - // Swap color with the previous one - byte swap_color; - Swap(0,temp_color,temp_color-1,1,working_palette,color_usage); - - swap_color=remap_table[temp_color]; - remap_table[temp_color]=remap_table[temp_color-1]; - remap_table[temp_color-1]=swap_color; - - swap=1; - } - } - } - - for (i=0;i<256;i++) - inverted_table[remap_table[i]]=i; - Remap_image_highlevel(inverted_table); - // Maintenant, tous ces calculs doivent êtres pris en compte dans la - // palette, l'image et à l'écran. - Set_palette(working_palette); - need_to_remap=1; - } - break; - } - - - if (!Mouse_K) - { - switch (Key) - { - case SDLK_LEFTBRACKET : // Décaler Forecolor vers la gauche - if (block_start==block_end) - { - Fore_color--; - first_color--; - last_color--; - block_start--; - block_end--; - Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); - Hide_cursor(); - Tag_color_range(block_start,block_end); - // Affichage du n° de la couleur sélectionnée - Num2str(Fore_color,str,3); - Print_in_window(237,58,str,MC_Black,MC_Light); - // Affichage dans le block de visu de la couleur en cours - Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); - Update_rect(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64); - Display_cursor(); - } - Key=0; - break; - - case SDLK_RIGHTBRACKET : // Décaler Forecolor vers la droite - if (block_start==block_end) - { - Fore_color++; - first_color++; - last_color++; - block_start++; - block_end++; - Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); - Hide_cursor(); - Tag_color_range(block_start,block_end); - // Affichage du n° de la couleur sélectionnée - Num2str(Fore_color,str,3); - Print_in_window(237,58,str,MC_Black,MC_Light); - // Affichage dans le block de visu de la couleur en cours - Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); - Update_rect(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64); - Display_cursor(); - } - Key=0; - break; - - case (SDLK_LEFTBRACKET|MOD_SHIFT) : // Decaler Backcolor vers la gauche - Back_color--; - case (SDLK_RIGHTBRACKET|MOD_SHIFT) : // Decaler Backcolor vers la droite - // attention: pas de break ci-dessus - if (Key==(SDLK_RIGHTBRACKET|MOD_SHIFT)) - Back_color++; - Hide_cursor(); - Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*24,Menu_factor_Y<<2,Back_color); - Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y*157),Menu_factor_X*24,Menu_factor_Y<<2,Back_color); - Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color); - Block(Window_pos_X+(Menu_factor_X*280),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color); - Update_rect(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*32,Menu_factor_Y*72); - Display_cursor(); - Key=0; - break; - - case SDLK_BACKSPACE : // Remise des couleurs du menu à l'état normal en essayant - // de ne pas trop modifier l'image. - if (!image_is_backed_up) - { - Backup(); - image_is_backed_up=1; - } - if (used_colors==-1) - Update_color_count(&used_colors,color_usage); - - memcpy(backup_palette,working_palette,sizeof(T_Palette)); - memcpy(temp_palette,Main_palette,sizeof(T_Palette)); - memcpy(Main_palette,working_palette,sizeof(T_Palette)); - Set_nice_menu_colors(color_usage,0); - memcpy(working_palette,Main_palette,sizeof(T_Palette)); - memcpy(Main_palette,temp_palette,sizeof(T_Palette)); - Set_palette(working_palette); - memcpy(temp_palette,working_palette,sizeof(T_Palette)); - Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); - Update_color_count(&used_colors,color_usage); - need_to_remap=1; - Key=0; - break; - - case SDLK_BACKQUOTE : // Récupération d'une couleur derrière le menu - case SDLK_COMMA : - Get_color_behind_window(&color,&click); - if (click) - { - Hide_cursor(); - if (click==RIGHT_SIDE) - { - if (Back_color!=color) - { - Back_color=color; - // 4 blocks de back_color entourant la fore_color - Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*24,Menu_factor_Y<<2,Back_color); - Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y*157),Menu_factor_X*24,Menu_factor_Y<<2,Back_color); - Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color); - Block(Window_pos_X+(Menu_factor_X*280),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color); - Update_rect(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*32,Menu_factor_Y*72); - } - } - else - { - Fore_color=first_color=last_color=block_start=block_end=color; - Tag_color_range(block_start,block_end); - - // Affichage du n° de la couleur sélectionnée - Block(Window_pos_X+(Menu_factor_X*261),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*32,Menu_factor_Y*7,MC_Light); - Num2str(Fore_color,str,3); - Print_in_window(237,58,str,MC_Black,MC_Light); - - // Affichage des jauges - Display_sliders(red_slider,green_slider,blue_slider,0,working_palette); - - // Affichage dans le block de visu de la couleur en cours - Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); - Update_rect(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64); - - memcpy(backup_palette ,working_palette,sizeof(T_Palette)); - memcpy(temp_palette,working_palette,sizeof(T_Palette)); - } - Display_cursor(); - Wait_end_of_click(); - } - Key=0; - break; - default: - if (Is_shortcut(Key,0x100+BUTTON_HELP)) - { - Key=0; - Window_help(BUTTON_PALETTE, NULL); - break; - } - } - - if (need_to_remap) - { - Hide_cursor(); - Compute_optimal_menu_colors(working_palette); - - // On remappe brutalement - Remap_screen_after_menu_colors_change(); - // Puis on remet les trucs qui ne devaient pas changer - Window_draw_palette_bouton(5,79); - Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y*89),Menu_factor_X*24,Menu_factor_Y*72,Back_color); - Display_grad_block_in_window(264,93,block_start,block_end); - - Update_rect(Window_pos_X+8*Menu_factor_X,Window_pos_Y+82*Menu_factor_Y,Menu_factor_X*16*10,Menu_factor_Y*5*16); - - Display_cursor(); - need_to_remap=0; - } - } - } - while ((clicked_button!=13) && (clicked_button!=14)); - - if (clicked_button==14) // Sortie par OK - { - if ( (!image_is_backed_up) - && memcmp(Main_palette,working_palette,sizeof(T_Palette)) ) - Backup(); - memcpy(Main_palette,working_palette,sizeof(T_Palette)); - } - - Compute_optimal_menu_colors(Main_palette); - - // La variable employée ici n'a pas vraiment de rapport avec son nom... - need_to_remap=(Window_pos_Y+(Window_height*Menu_factor_Y)Position = rgb_scale_slider->Position>128?rgb_scale_slider->Position*2-256:0; - Num2str(256-rgb_scale_slider->Position,str,3); - Print_in_window(157,78,str,MC_Black,MC_Light); - Window_draw_slider(rgb_scale_slider); - break; - - case 10: - // /2 RGB scale - rgb_scale_slider->Position = rgb_scale_slider->Position>253?254:(rgb_scale_slider->Position)/2+128; - Num2str(256-rgb_scale_slider->Position,str,3); - Print_in_window(157,78,str,MC_Black,MC_Light); - Window_draw_slider(rgb_scale_slider); - } - } - while (clicked_button!=1 && clicked_button!=2 && clicked_button!=3 && clicked_button!=4); - - // We need to get the sliders positions before closing the window, because they will be freed. - palette_cols=256-columns_slider->Position; - palette_lines=16-lines_slider->Position; - rgb_scale=256-rgb_scale_slider->Position; - - Close_window(); - Unselect_button(BUTTON_PALETTE); - Display_cursor(); - - if (clicked_button==4) // Cancel - return; - - if (palette_vertical != Config.Palette_vertical) - { - Config.Palette_vertical=palette_vertical; - palette_needs_redraw=1; - } - if (palette_cols!=Config.Palette_cells_X || - palette_lines!=Config.Palette_cells_Y) - { - Config.Palette_cells_X = palette_cols; - Config.Palette_cells_Y = palette_lines; - palette_needs_redraw=1; - } - if (rgb_scale!=RGB_scale) - { - Set_palette_RGB_scale(rgb_scale); - Set_palette(Main_palette); - } - - if (clicked_button==1) - { - Menu_tag_colors("Tag colors to exclude",Exclude_color,&dummy,1, NULL); - } - else if (clicked_button==2) - { - // Open the menu with Shade settings. Same as the shortcut, except - // that this will not activate shade mode on exit. - Shade_settings_menu(); - } - - if (palette_needs_redraw) - { - Change_palette_cells(); - Display_menu(); - Display_sprite_in_menu(BUTTON_PAL_LEFT,18+(Config.Palette_vertical!=0)); - } -} +/* Grafx2 - The Ultimate 256-color bitmap paint program + + 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 +*/ +#include +#include +#include +#include "const.h" +#include "struct.h" +#include "global.h" +#include "misc.h" +#include "engine.h" +#include "readline.h" +#include "buttons.h" +#include "pages.h" +#include "help.h" +#include "sdlscreen.h" +#include "errors.h" +#include "op_c.h" +#include "windows.h" +#include "input.h" +#include "palette.h" +#include "shade.h" + +byte Palette_view_is_RGB = 1; // Indique si on est en HSL ou en RGB + +// --------------------------- Menu des palettes ----------------------------- +char * Palette_reduce_label[7]= +{ + "128"," 64"," 32"," 16"," 8"," 4"," 2" +}; + +// Nombre de graduations pour une composante RGB +int RGB_scale = 256; // 24bit +//int RGB_scale = 64; // VGA +//int RGB_scale = 16; // Amiga +//int RGB_scale = 4; // MSX2 +//int RGB_scale = 3; // Amstrad CPC + +// Nombre de graduations pour une composante dans le mode actuel +int Color_count=256; +// Les composantes vont de 0 à (Color_count-1) +int Color_max=255; +// Le demi-pas est une quantité que l'on ajoute à une composante +// avant de faire un arrondi par division. +int Color_halfstep=0; + + +void Set_palette_RGB_scale(int scale) +{ + if (scale>= 2 && scale <= 256) + RGB_scale = scale; +} + +byte Round_palette_component(byte comp) +{ + return ((comp+128/RGB_scale)*(RGB_scale-1)/255*255+(RGB_scale&1?1:0))/(RGB_scale-1); +} + +// Définir les unités pour les graduations R G B ou H S V +void Componant_unit(int count) +{ + Color_count = count; + Color_max = count-1; + Color_halfstep = 256/count/2; +} + +void Set_HSL(T_Palette start_palette, T_Palette end_palette, byte color, short diff_h, short diff_s, short diff_l) +{ + byte h, s, l; + RGB_to_HSL(start_palette[color].R,start_palette[color].G,start_palette[color].B,&h,&s,&l); + // La teinte (Hue) est cyclique + h=(diff_h+256+h); + // Pour les autres (Saturation, Lightness), au lieu d'additionner, + // on va faire un ratio, cela utilise mieux la plage de valeurs 0-255 + if (diff_s<0) + s=(255+diff_s)*s/255; + else if (diff_s>0) + s=255-(255-diff_s)*(255-s)/255; + if (diff_l<0) + l=(255+diff_l)*l/255; + else if (diff_l>0) + l=255-(255-diff_l)*(255-l)/255; + HSL_to_RGB(h,s,l,&end_palette[color].R,&end_palette[color].G,&end_palette[color].B); +} + +void Set_red(byte color, short new_color, T_Palette palette) +{ + if (new_color< 0) + new_color= 0; + if (new_color>255) + new_color=255; + // Arrondi + new_color=Round_palette_component(new_color); + + palette[color].R=new_color; + Set_color(color,palette[color].R,palette[color].G,palette[color].B); +} + + +void Set_green(byte color, short new_color, T_Palette palette) +{ + if (new_color< 0) + new_color= 0; + if (new_color>255) + new_color=255; + // Arrondi + new_color=Round_palette_component(new_color); + + palette[color].G=new_color; + Set_color(color,palette[color].R,palette[color].G,palette[color].B); +} + + +void Set_blue(byte color, short new_color, T_Palette palette) +{ + if (new_color< 0) + new_color= 0; + if (new_color>255) + new_color=255; + // Arrondi + new_color=Round_palette_component(new_color); + + palette[color].B=new_color; + Set_color(color,palette[color].R,palette[color].G,palette[color].B); +} + +void Format_componant(byte value, char *str) +// Formate une chaine de 4 caractères+\0 : "nnn " +{ + Num2str(value,str,3); + str[3]=' '; + str[4]='\0'; +} + +void Spread_colors(short start,short end,T_Palette palette) +// Modifie la palette pour obtenir un dégradé de couleur entre les deux bornes +// passées en paramètre +{ + short start_red; + short start_green; + short start_blue; + short end_red; + short end_green; + short end_blue; + short index; + + // On vérifie qu'il y ait assez de couleurs entre le début et la fin pour + // pouvoir faire un dégradé: + if ( (start!=end) && (start+1!=end) ) + { + start_red=palette[start].R; + start_green =palette[start].G; + start_blue =palette[start].B; + + end_red =palette[end ].R; + end_green =palette[end ].G; + end_blue =palette[end ].B; + + for (index=start+1;index=Window_pos_Y) && (y_pos=Window_pos_X) && (x_pos=Menu_Y_before_window) + end_y=Menu_Y_before_window; + else + end_y=Main_image_height; + + if (!Main_magnifier_mode) + { + if (Main_image_width>=Screen_width) + end_x=Screen_width; + else + end_x=Main_image_width; + + } + else + { + if (Main_image_width>=Main_separator_position) + end_x=Main_separator_position; + else + end_x=Main_image_width; + + if ((Main_X_zoom+(Main_image_width*Main_magnifier_factor))>=Screen_width) + end_x_mag=Screen_width; + else + end_x_mag=(Main_X_zoom+(Main_image_width*Main_magnifier_factor)); + + if (Main_image_height*Main_magnifier_factor>=Menu_Y_before_window) + end_y_mag=Menu_Y_before_window; + else + end_y_mag=Main_image_height*Main_magnifier_factor; + } + + // On doit maintenant faire la traduction à l'écran + Remap_zone_highlevel(0,0,end_x,end_y,conversion_table); + + if (Main_magnifier_mode) + { + Remap_zone_highlevel(Main_separator_position,0,end_x_mag,end_y_mag,conversion_table); + // Il peut encore rester le bas de la barre de split à remapper si la + // partie zoomée ne descend pas jusqu'en bas... + Remap_zone_highlevel(Main_separator_position,end_y_mag, + (Main_separator_position+(SEPARATOR_WIDTH*Menu_factor_X)), + Menu_Y_before_window,conversion_table); + } + // Remappe tous les fonds de fenetre (qui doivent contenir un bout d'écran) + Remap_window_backgrounds(conversion_table, 0, Menu_Y_before_window); +} + + +void Swap(int with_remap,short block_1_start,short block_2_start,short block_size,T_Palette palette, dword * color_usage) +{ + short pos_1; + short pos_2; + short end_1; + short end_2; + dword temp; + byte conversion_table[256]; + + T_Components temp_palette[256]; + dword Utilisation_temporaire[256]; + + // On fait une copie de la palette + memcpy(temp_palette, palette, sizeof(T_Palette)); + + // On fait une copie de la table d'utilisation des couleurs + memcpy(Utilisation_temporaire, color_usage, sizeof(dword) * 256); + + // On commence à initialiser la table de conversion à un état où elle ne + // fera aucune conversion. + for (pos_1=0;pos_1<=255;pos_1++) + conversion_table[pos_1]=pos_1; + + // On calcul les dernières couleurs de chaque bloc. + end_1=block_1_start+block_size-1; + end_2=block_2_start+block_size-1; + + if ((block_2_start>=block_1_start) && (block_2_start<=end_1)) + { + // Le bloc destination commence dans le bloc source. + + for (pos_1=block_1_start,pos_2=end_1+1;pos_1<=end_2;pos_1++) + { + // Il faut transformer la couleur pos_1 en pos_2: + + conversion_table[pos_2]=pos_1; + color_usage[pos_1]=Utilisation_temporaire[pos_2]; + palette[pos_1].R=temp_palette[pos_2].R; + palette[pos_1].G=temp_palette[pos_2].G; + palette[pos_1].B=temp_palette[pos_2].B; + + // On gère la mise à jour de pos_2 + if (pos_2==end_2) + pos_2=block_1_start; + else + pos_2++; + } + } + else + if ((block_2_start=block_1_start)) + { + // Le bloc destination déborde dans le bloc source. + + for (pos_1=block_2_start,pos_2=block_1_start;pos_1<=end_1;pos_1++) + { + // Il faut transformer la couleur pos_1 en pos_2: + + conversion_table[pos_2]=pos_1; + color_usage[pos_1]=Utilisation_temporaire[pos_2]; + palette[pos_1].R=temp_palette[pos_2].R; + palette[pos_1].G=temp_palette[pos_2].G; + palette[pos_1].B=temp_palette[pos_2].B; + + // On gère la mise à jour de pos_2 + if (pos_2==end_1) + pos_2=block_2_start; + else + pos_2++; + } + } + else + { + // Le bloc source et le bloc destination sont distincts. + + for (pos_1=block_1_start,pos_2=block_2_start;pos_1<=end_1;pos_1++,pos_2++) + { + // Il va falloir permutter la couleur pos_1 avec la couleur pos_2 + conversion_table[pos_1]=pos_2; + conversion_table[pos_2]=pos_1; + + // On intervertit le nombre d'utilisation des couleurs pour garder une + // cohérence lors d'un éventuel "Zap unused". + temp =color_usage[pos_1]; + color_usage[pos_1]=color_usage[pos_2]; + color_usage[pos_2]=temp; + + // On fait un changement de teinte: + temp =palette[pos_1].R; + palette[pos_1].R=palette[pos_2].R; + palette[pos_2].R=temp; + + temp =palette[pos_1].G; + palette[pos_1].G=palette[pos_2].G; + palette[pos_2].G=temp; + + temp =palette[pos_1].B; + palette[pos_1].B=palette[pos_2].B; + palette[pos_2].B=temp; + } + } + + if (with_remap) + { + Remap_image_highlevel(conversion_table); + } +} + + + +void Set_nice_menu_colors(dword * color_usage,int not_picture) +{ + short index,index2; + byte color; + byte replace_table[256]; + T_Components rgb[4]; + short new_colors[4]={255,254,253,252}; + + // On initialise la table de remplacement + for (index=0; index<256; index++) + replace_table[index]=index; + + // On recherche les 4 couleurs les moins utilisées dans l'image pour pouvoir + // les remplacer par les nouvelles couleurs. + for (index2=0; index2<4; index2++) + for (index=255; index>=0; index--) + { + if ((index!=new_colors[0]) && (index!=new_colors[1]) + && (index!=new_colors[2]) && (index!=new_colors[3]) + && (color_usage[index]new_colors[index+1]) + { + index2 =new_colors[index]; + new_colors[index] =new_colors[index+1]; + new_colors[index+1]=index2; + color=1; + } + } + } while (color); + + // On sauvegarde dans rgb les teintes qu'on va remplacer et on met les + // couleurs du menu par défaut + for (index=0; index<4; index++) + { + color=new_colors[index]; + rgb[index].R=Main_palette[color].R; + rgb[index].G=Main_palette[color].G; + rgb[index].B=Main_palette[color].B; + Main_palette[color].R=Fav_menu_colors[index].R; + Main_palette[color].G=Fav_menu_colors[index].G; + Main_palette[color].B=Fav_menu_colors[index].B; + } + + // Maintenant qu'on a placé notre nouvelle palette, on va chercher quelles + // sont les couleurs qui peuvent remplacer les anciennes + Hide_cursor(); + for (index=0; index<4; index++) + replace_table[new_colors[index]]=Best_color_nonexcluded + (rgb[index].R,rgb[index].G,rgb[index].B); + + if (not_picture) + { + // Remap caused by preview. Only remap screen + Remap_zone_highlevel(0,0,Screen_width,Screen_height,replace_table); + } + else + { + // On fait un changement des couleurs visibles à l'écran et dans l'image + Remap_image_highlevel(replace_table); + } + Display_cursor(); +} + + + +void Reduce_palette(short * used_colors,int nb_colors_asked,T_Palette palette,dword * color_usage) +{ + char str[5]; // buffer d'affichage du compteur + byte conversion_table[256]; // Table de conversion + int color_1; // |_ Variables de balayages + int color_2; // | de la palette + int best_color_1=0; + int best_color_2=0; + int difference; + int best_difference; + dword Utilisation; + dword Meilleure_utilisation; + + // On commence par initialiser la table de conversion dans un état où + // aucune conversion ne sera effectuée. + for (color_1=0; color_1<=255; color_1++) + conversion_table[color_1]=color_1; + + // Si on ne connait pas encore le nombre de couleurs utilisées, on le + // calcule! (!!! La fonction appelée Efface puis Affiche le curseur !!!) + if ((*used_colors)<0) + Update_color_count(used_colors,color_usage); + + Hide_cursor(); + + // On tasse la palette vers le début parce qu'elle doit ressembler à + // du Gruyère (et comme Papouille il aime pas le fromage...) + + // Pour cela, on va scruter la couleur color_1 et se servir de l'indice + // color_2 comme position de destination. + for (color_1=color_2=0;color_1<=255;color_1++) + { + if (color_usage[color_1]) + { + // On commence par s'occuper des teintes de la palette + palette[color_2].R=palette[color_1].R; + palette[color_2].G=palette[color_1].G; + palette[color_2].B=palette[color_1].B; + + // Ensuite, on met à jour le tableau d'occupation des couleurs. + color_usage[color_2]=color_usage[color_1]; + + // On va maintenant s'occuper de la table de conversion: + conversion_table[color_1]=color_2; + + // Maintenant, la place désignée par color_2 est occupée, alors on + // doit passer à un indice de destination suivant. + color_2++; + } + } + + // On met toutes les couleurs inutilisées en noir + for (;color_2<256;color_2++) + { + palette[color_2].R=0; + palette[color_2].G=0; + palette[color_2].B=0; + color_usage[color_2]=0; + } + + // Maintenant qu'on a une palette clean, on va boucler en réduisant + // le nombre de couleurs jusqu'à ce qu'on atteigne le nombre désiré. + while ((*used_colors)>nb_colors_asked) + { + // Il s'agit de trouver les 2 couleurs qui se ressemblent le plus + // parmis celles qui sont utilisées (bien sûr) et de les remplacer par + // une seule couleur qui est la moyenne pondérée de ces 2 couleurs + // en fonction de leur utilisation dans l'image. + + best_difference =0x7FFF; + Meilleure_utilisation=0x7FFFFFFF; + + for (color_1=0;color_1<(*used_colors);color_1++) + for (color_2=color_1+1;color_2<(*used_colors);color_2++) + if (color_1!=color_2) + { + difference =abs((short)palette[color_1].R-palette[color_2].R)+ + abs((short)palette[color_1].G-palette[color_2].G)+ + abs((short)palette[color_1].B-palette[color_2].B); + + if (difference<=best_difference) + { + Utilisation=color_usage[color_1]+color_usage[color_2]; + if ((differencebest_color_2) + { + // La color_1 va scroller en arrière. + + // Donc on transfère son utilisation dans l'utilisation de la + // couleur qui la précède. + color_usage[color_1-1]=color_usage[color_1]; + + // Et on transfère ses teintes dans les teintes de la couleur qui + // la précède. + palette[color_1-1].R=palette[color_1].R; + palette[color_1-1].G=palette[color_1].G; + palette[color_1-1].B=palette[color_1].B; + } + + // Une fois la palette et la table d'utilisation gérées, on peut + // s'occuper de notre table de conversion. + if (conversion_table[color_1]>best_color_2) + // La color_1 avait l'intention de se faire remplacer par une + // couleur que l'on va (ou que l'on a déjà) bouger en arrière. + conversion_table[color_1]--; + } + + // On vient d'éjecter une couleur, donc on peut mettre à jour le nombre + // de couleurs utilisées. + (*used_colors)--; + + // A la fin, on doit passer (dans la palette) les teintes du dernier + // élément de notre ensemble en noir. + palette[*used_colors].R=0; + palette[*used_colors].G=0; + palette[*used_colors].B=0; + + // Au passage, on va s'assurer que l'on a pas oublié de la mettre à une + // utilisation nulle. + color_usage[*used_colors]=0; + + // Après avoir éjecté une couleur, on le fait savoir à l'utilisateur par + // l'intermédiaire du compteur de nombre utilisées. + Num2str(*used_colors,str,3); + Print_in_window(186,23,str,MC_Black,MC_Light); + } + + // Maintenant, tous ces calculs doivent êtres pris en compte dans la + // palette, l'image et à l'écran. + Remap_image_highlevel(conversion_table); // Et voila pour l'image et l'écran + Display_cursor(); +} + + + +void Set_palette_slider(T_Scroller_button * slider, + word nb_elements, word position, + char * value, short x_pos) +{ + slider->Nb_elements=nb_elements; + slider->Position=position; + Compute_slider_cursor_height(slider); + Window_draw_slider(slider); + Print_counter(x_pos,172,value,MC_Black,MC_Light); +} + + + +void Display_sliders(T_Scroller_button * red_slider, + T_Scroller_button * green_slider, + T_Scroller_button * blue_slider, + byte block_is_selected, T_Components * palette) +{ + char str[5]; + + if (block_is_selected) + { + Set_palette_slider(red_slider,Color_max*2+1,Color_max,"± 0",176); + Set_palette_slider(green_slider,Color_max*2+1,Color_max,"± 0",203); + Set_palette_slider(blue_slider,Color_max*2+1,Color_max,"± 0",230); + } + else + { + byte j1, j2, j3; + j1= palette[Fore_color].R; + j2= palette[Fore_color].G; + j3= palette[Fore_color].B; + if (!Palette_view_is_RGB) + { + RGB_to_HSL(j1,j2,j3,&j1,&j2,&j3); + } + + Format_componant(j1*Color_max/255,str); + Set_palette_slider(red_slider,Color_count,Color_max-j1*Color_max/255,str,176); + Format_componant(j2*Color_max/255,str); + Set_palette_slider(green_slider,Color_count,Color_max-j2*Color_max/255,str,203); + Format_componant(j3*Color_max/255,str); + Set_palette_slider(blue_slider,Color_count,Color_max-j3*Color_max/255,str,230); + } +} + + + +void Draw_all_palette_sliders(T_Scroller_button * red_slider, + T_Scroller_button * green_slider, + T_Scroller_button * blue_slider, + T_Palette palette,byte start,byte end) +{ + char str[5]; + + Hide_cursor(); + // Réaffichage des jauges: + if (start!=end) + { + // Dans le cas d'un bloc, tout à 0. + red_slider->Position =Color_max; + Window_draw_slider(red_slider); + Print_counter(176,172,"± 0",MC_Black,MC_Light); + + green_slider->Position =Color_max; + Window_draw_slider(green_slider); + Print_counter(203,172,"± 0",MC_Black,MC_Light); + + blue_slider->Position =Color_max; + Window_draw_slider(blue_slider); + Print_counter(230,172,"± 0",MC_Black,MC_Light); + } + else + { + // Dans le cas d'une seule couleur, composantes. + byte j1, j2, j3; + j1= palette[start].R; + j2= palette[start].G; + j3= palette[start].B; + if (!Palette_view_is_RGB) + { + RGB_to_HSL(j1,j2,j3,&j1,&j2,&j3); + } + Format_componant(j1*Color_max/255,str); + red_slider->Position=Color_max-j1*Color_max/255; + Window_draw_slider(red_slider); + Print_counter(176,172,str,MC_Black,MC_Light); + + Format_componant(j2*Color_max/255,str); + green_slider->Position=Color_max-j2*Color_max/255; + Window_draw_slider(green_slider); + Print_counter(203,172,str,MC_Black,MC_Light); + + Format_componant(j3*Color_max/255,str); + blue_slider->Position=Color_max-j3*Color_max/255; + Window_draw_slider(blue_slider); + Print_counter(230,172,str,MC_Black,MC_Light); + } + Display_cursor(); +} + + +void Button_Palette(void) +{ + static short reducer_index=0; + static short reduce_colors_number=256; + short temp_color; // Variable pouvant reservir pour différents calculs intermédiaires + dword temp; + byte color,click; // Variables pouvant reservir pour différents calculs intermédiaires + short clicked_button; + word old_mouse_x; + word old_mouse_y; + byte old_mouse_k; + byte block_start; + byte block_end; + byte first_color; + byte last_color; + char str[10]; + word i; + //short x_pos,y_pos; + T_Normal_button * button_used; + T_Scroller_button * red_slider; + T_Scroller_button * green_slider; + T_Scroller_button * blue_slider; + T_Scroller_button * reduce_slider; + byte image_is_backed_up=0; + byte need_to_remap=0; + + dword color_usage[256]; + short used_colors=-1; // -1 <=> Inconnu + byte conversion_table[256]; + + T_Components * backup_palette; + T_Components * temp_palette; + T_Components * working_palette; + + backup_palette =(T_Components *)malloc(sizeof(T_Palette)); + temp_palette=(T_Components *)malloc(sizeof(T_Palette)); + working_palette=(T_Components *)malloc(sizeof(T_Palette)); + + Componant_unit(RGB_scale); + + Open_window(299,188,"Palette"); + + memcpy(working_palette,Main_palette,sizeof(T_Palette)); + memcpy(backup_palette ,Main_palette,sizeof(T_Palette)); + memcpy(temp_palette,Main_palette,sizeof(T_Palette)); + + Window_set_palette_button(5,79); // 1 + + Window_display_frame (173, 67,121,116); + Window_display_frame (128, 16, 91, 39); + Window_display_frame (221, 16, 73, 39); + // Frame creux destiné à l'affichage de la(les) couleur(s) sélectionnée(s) + Window_display_frame_in(259, 88, 26, 74); + + // Graduation des jauges de couleur + Block(Window_pos_X+(Menu_factor_X*179),Window_pos_Y+(Menu_factor_Y*109),Menu_factor_X*17,Menu_factor_Y,MC_Dark); + Block(Window_pos_X+(Menu_factor_X*206),Window_pos_Y+(Menu_factor_Y*109),Menu_factor_X*17,Menu_factor_Y,MC_Dark); + Block(Window_pos_X+(Menu_factor_X*233),Window_pos_Y+(Menu_factor_Y*109),Menu_factor_X*17,Menu_factor_Y,MC_Dark); + Block(Window_pos_X+(Menu_factor_X*179),Window_pos_Y+(Menu_factor_Y*125),Menu_factor_X*17,Menu_factor_Y,MC_Dark); + Block(Window_pos_X+(Menu_factor_X*206),Window_pos_Y+(Menu_factor_Y*125),Menu_factor_X*17,Menu_factor_Y,MC_Dark); + Block(Window_pos_X+(Menu_factor_X*233),Window_pos_Y+(Menu_factor_Y*125),Menu_factor_X*17,Menu_factor_Y,MC_Dark); + Block(Window_pos_X+(Menu_factor_X*179),Window_pos_Y+(Menu_factor_Y*141),Menu_factor_X*17,Menu_factor_Y,MC_Dark); + Block(Window_pos_X+(Menu_factor_X*206),Window_pos_Y+(Menu_factor_Y*141),Menu_factor_X*17,Menu_factor_Y,MC_Dark); + Block(Window_pos_X+(Menu_factor_X*233),Window_pos_Y+(Menu_factor_Y*141),Menu_factor_X*17,Menu_factor_Y,MC_Dark); + // Jauges de couleur + Palette_view_is_RGB=1; + red_slider = Window_set_scroller_button(182, 81, 88,Color_count,1,Color_max-working_palette[Fore_color].R*Color_max/255);// 2 + green_slider = Window_set_scroller_button(209, 81, 88,Color_count,1,Color_max-working_palette[Fore_color].G*Color_max/255);// 3 + blue_slider = Window_set_scroller_button(236, 81, 88,Color_count,1,Color_max-working_palette[Fore_color].B*Color_max/255);// 4 + Print_in_window(184,71,"R",MC_Dark,MC_Light); + Print_in_window(211,71,"G",MC_Dark,MC_Light); + Print_in_window(238,71,"B",MC_Dark,MC_Light); + + first_color=last_color=block_start=block_end=Fore_color; + Tag_color_range(block_start,block_end); + + // Affichage dans le block de visu de la couleur en cours + Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y*89),Menu_factor_X*24,Menu_factor_Y*72,Back_color); + Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); + + // Affichage des valeurs de la couleur courante (pour 1 couleur) + Format_componant(Main_palette[Fore_color].R*Color_max/255,str); + Print_counter(176,172,str,MC_Black,MC_Light); + Format_componant(Main_palette[Fore_color].G*Color_max/255,str); + Print_counter(203,172,str,MC_Black,MC_Light); + Format_componant(Main_palette[Fore_color].B*Color_max/255,str); + Print_counter(230,172,str,MC_Black,MC_Light); + + Print_in_window(129,58,"Color number:",MC_Dark,MC_Light); + Num2str(Fore_color,str,3); + Print_in_window(237,58,str,MC_Black,MC_Light); + + + Window_set_normal_button( 6,17,59,14,"Default",3,1,SDLK_f); // 5 + Window_set_normal_button(66,17,29,14,"Gry" ,1,1,SDLK_g); // 6 + Window_set_normal_button(66,47,29,14,"Swp" ,0,1,KEY_NONE); // 7 + Window_set_normal_button( 6,47,59,14,"X-Swap" ,1,1,SDLK_x); // 8 + Window_set_normal_button(66,32,29,14,"Cpy" ,1,1,SDLK_c); // 9 + Window_set_normal_button( 6,32,59,14,"Spread" ,4,1,SDLK_e); // 10 + + Window_set_normal_button(239,20,51,14,"Reduce" ,1,1,SDLK_r); // 11 + Print_in_window(241,41,"to",MC_Dark,MC_Light); + + Window_set_normal_button( 6,168,35,14,"Undo" ,1,1,SDLK_u); // 12 + Window_set_normal_button( 62,168,51,14,"Cancel",0,1,KEY_ESC); // 13 + Window_set_normal_button(117,168,51,14,"OK" ,0,1,SDLK_RETURN); // 14 + + button_used = Window_set_normal_button(132,20,83,14,"Used: ???",4,1,SDLK_d);// 15 + Window_set_normal_button(132,37,83,14,"Zap unused",0,1,SDLK_DELETE);//16 + + // Jauge de réduction de palette + reduce_slider = Window_set_scroller_button(225,20,31,7,1,reducer_index);// 17 + + Window_set_repeatable_button(266, 74,12,11,"+",0,1,SDLK_KP_PLUS); // 18 + Window_set_repeatable_button(266,165,12,11,"-",0,1,SDLK_KP_MINUS); // 19 + + Window_set_normal_button(96,17,29,14,"Neg" ,1,1,SDLK_n); // 20 + Window_set_normal_button(66,62,29,14,"Inv" ,1,1,SDLK_i); // 21 + Window_set_normal_button( 6,62,59,14,"X-Inv." ,5,1,SDLK_v); // 22 + + Window_set_input_button(263,39,3); // 23 + + Window_set_normal_button(96,32,29,14,"HSL" ,1,1,SDLK_h); // 24 + Window_set_normal_button(96,47,29,14,"Srt" ,1,1,SDLK_s); // 25 + // Affichage du facteur de réduction de la palette + Num2str(reduce_colors_number,str,3); + Print_in_window(265,41,str,MC_Black,MC_Light); + + // Dessin des petits effets spéciaux pour les boutons [+] et [-] + Draw_thingumajig(263, 74,MC_White,-1); + Draw_thingumajig(280, 74,MC_White,+1); + Draw_thingumajig(263,165,MC_Dark,-1); + Draw_thingumajig(280,165,MC_Dark,+1); + + Update_window_area(0,0,299,188); + + Display_cursor(); + + if (Config.Auto_nb_used) + Update_color_count(&used_colors,color_usage); + + do + { + old_mouse_x=Mouse_X; + old_mouse_y=Mouse_Y; + old_mouse_k=Mouse_K; + clicked_button=Window_clicked_button(); + + switch (clicked_button) + { + case 0 : // Nulle part + break; + case -1 : // Hors de la fenêtre + case 1 : // palette + if ( (Mouse_X!=old_mouse_x) || (Mouse_Y!=old_mouse_y) || (Mouse_K!=old_mouse_k) ) + { + Hide_cursor(); + temp_color=(clicked_button==1) ? Window_attribute2 : Read_pixel(Mouse_X,Mouse_Y); + if (Mouse_K==RIGHT_SIDE) + { + if (Back_color!=temp_color) + { + Back_color=temp_color; + // 4 blocks de back_color entourant la fore_color + Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*24,Menu_factor_Y<<2,Back_color); + Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y*157),Menu_factor_X*24,Menu_factor_Y<<2,Back_color); + Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color); + Block(Window_pos_X+(Menu_factor_X*280),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color); + Update_rect(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*32,Menu_factor_Y*72); + } + } + else + { + if (!old_mouse_k) + { + // On vient de clicker sur une couleur (et une seule) + if ( (Fore_color!=temp_color) || (block_start!=block_end) ) + { + // La couleur en question est nouvelle ou elle annule un + // ancien bloc. Il faut donc sélectionner cette couleur comme + // unique couleur choisie. + + Fore_color=first_color=last_color=block_start=block_end=temp_color; + Tag_color_range(block_start,block_end); + + // Affichage du n° de la couleur sélectionnée + Block(Window_pos_X+(Menu_factor_X*237),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*56,Menu_factor_Y*7,MC_Light); + Num2str(Fore_color,str,3); + Print_in_window(237,58,str,MC_Black,MC_Light); + Update_rect(Window_pos_X+(Menu_factor_X*237),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*56,Menu_factor_Y*7); + + // Affichage des jauges + Block(Window_pos_X+(Menu_factor_X*176),Window_pos_Y+(Menu_factor_Y*172),Menu_factor_X*84,Menu_factor_Y*7,MC_Light); + Display_sliders(red_slider,green_slider,blue_slider,0,working_palette); + + // Affichage dans le block de visu de la couleur en cours + Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); + Update_rect(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64); + + memcpy(backup_palette ,working_palette,sizeof(T_Palette)); + memcpy(temp_palette,working_palette,sizeof(T_Palette)); + } + } + else + { + // On maintient le click, on va donc tester si le curseur bouge + if (temp_color!=last_color) + { + // On commence par ordonner la 1ère et dernière couleur du bloc + if (first_colortemp_color) + { + block_start=temp_color; + block_end=first_color; + + // Affichage du n° de la couleur sélectionnée + Num2str(block_start,str ,3); + Num2str(block_end ,str+4,3); + str[3]=26; // Flèche vers la droite + Print_in_window(237,58,str,MC_Black,MC_Light); + + // Affichage des jauges + Display_sliders(red_slider,green_slider,blue_slider,1,NULL); + + // Affichage dans le block de visu du bloc (dégradé) en cours + Display_grad_block_in_window(264,93,block_start,block_end); + } + else + { + block_start=block_end=first_color; + Block(Window_pos_X+(Menu_factor_X*176),Window_pos_Y+(Menu_factor_Y*172),Menu_factor_X*84,Menu_factor_Y*7,MC_Light); + + // Affichage du n° de la couleur sélectionnée + Block(Window_pos_X+(Menu_factor_X*261),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*32,Menu_factor_Y*7,MC_Light); + Num2str(Fore_color,str,3); + Print_in_window(237,58,str,MC_Black,MC_Light); + + // Affichage des jauges + Display_sliders(red_slider,green_slider,blue_slider,0,working_palette); + + // Affichage dans le block de visu de la couleur en cours + Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); + Update_rect(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64); + } + + // On tagge le bloc (ou la couleur) + Tag_color_range(block_start,block_end); + } + + last_color=temp_color; + } + } + Display_cursor(); + } + break; + case 2 : // Jauge rouge + Hide_cursor(); + if (block_start==block_end) + { + if(Palette_view_is_RGB) + { + Set_red(Fore_color,(Color_max-red_slider->Position)*255/Color_max,working_palette); + Format_componant(working_palette[Fore_color].R*Color_max/255,str); + } + else + { + HSL_to_RGB( + 255-red_slider->Position, + 255-green_slider->Position, + 255-blue_slider->Position, + &working_palette[Fore_color].R, + &working_palette[Fore_color].G, + &working_palette[Fore_color].B); + Format_componant((int)255-red_slider->Position,str); + } + Print_counter(176,172,str,MC_Black,MC_Light); + } + else + { + if(Palette_view_is_RGB) + { + for (i=block_start; i<=block_end; i++) + Set_red(i,temp_palette[i].R+(Color_max-red_slider->Position)*255/Color_max,working_palette); + } + else + { + for (i=block_start; i<=block_end; i++) + Set_HSL( + temp_palette, + working_palette, + i, + Color_max-red_slider->Position, + Color_max-green_slider->Position, + Color_max-blue_slider->Position + ); + } + + if (red_slider->Position>Color_max) + { + // Jauge dans les négatifs: + Num2str(-(Color_max-red_slider->Position),str,4); + str[0]='-'; + } + else if (red_slider->PositionPosition ,str,4); + str[0]='+'; + } + else + { + // Jauge nulle: + strcpy(str,"± 0"); + } + Print_counter(176,172,str,MC_Black,MC_Light); + + } + + need_to_remap=1; + + Display_cursor(); + Set_palette(working_palette); + break; + case 3 : // Jauge verte + Hide_cursor(); + if (block_start==block_end) + { + if(Palette_view_is_RGB) + { + Set_green (Fore_color,(Color_max-green_slider->Position)*255/Color_max,working_palette); + Format_componant(working_palette[Fore_color].G*Color_max/255,str); + } + else + { + HSL_to_RGB( + 255-red_slider->Position, + 255-green_slider->Position, + 255-blue_slider->Position, + &working_palette[Fore_color].R, + &working_palette[Fore_color].G, + &working_palette[Fore_color].B); + Format_componant((int)255-green_slider->Position,str); + } + Print_counter(203,172,str,MC_Black,MC_Light); + } + else + { + if(Palette_view_is_RGB) + { + for (i=block_start; i<=block_end; i++) + Set_green (i,temp_palette[i].G+(Color_max-green_slider->Position)*255/Color_max,working_palette); + } + else + { + for (i=block_start; i<=block_end; i++) + Set_HSL( + temp_palette, + working_palette, + i, + Color_max-red_slider->Position, + Color_max-green_slider->Position, + Color_max-blue_slider->Position + ); + } + + if (green_slider->Position>Color_max) + { + // Jauge dans les négatifs: + Num2str(-(Color_max-green_slider->Position),str,4); + str[0]='-'; + } + else if (green_slider->PositionPosition ,str,4); + str[0]='+'; + } + else + { + // Jauge nulle: + strcpy(str,"± 0"); + } + Print_counter(203,172,str,MC_Black,MC_Light); + } + + need_to_remap=1; + + Display_cursor(); + Set_palette(working_palette); + break; + + case 4 : // Jauge bleue + Hide_cursor(); + if (block_start==block_end) + { + if(Palette_view_is_RGB) + { + Set_blue (Fore_color,(Color_max-blue_slider->Position)*255/Color_max,working_palette); + Format_componant(working_palette[Fore_color].B*Color_max/255,str); + } + else + { + HSL_to_RGB( + 255-red_slider->Position, + 255-green_slider->Position, + 255-blue_slider->Position, + &working_palette[Fore_color].R, + &working_palette[Fore_color].G, + &working_palette[Fore_color].B); + Format_componant((int)255-blue_slider->Position,str); + } + Print_counter(230,172,str,MC_Black,MC_Light); + } + else + { + if(Palette_view_is_RGB) + { + for (i=block_start; i<=block_end; i++) + Set_blue(i,temp_palette[i].B+(Color_max-blue_slider->Position)*255/Color_max,working_palette); + } + else + { + for (i=block_start; i<=block_end; i++) + Set_HSL( + temp_palette, + working_palette, + i, + Color_max-red_slider->Position, + Color_max-green_slider->Position, + Color_max-blue_slider->Position + ); + } + + if (blue_slider->Position>Color_max) + { + // Jauge dans les négatifs: + Num2str(-(Color_max-blue_slider->Position),str,4); + str[0]='-'; + } + else if (blue_slider->PositionPosition ,str,4); + str[0]='+'; + } + else + { + // Jauge nulle: + strcpy(str,"± 0"); + } + Print_counter(230,172,str,MC_Black,MC_Light); + } + + need_to_remap=1; + + Display_cursor(); + Set_palette(working_palette); + break; + + case 5 : // Default + memcpy(backup_palette,working_palette,sizeof(T_Palette)); + memcpy(working_palette,Gfx->Default_palette,sizeof(T_Palette)); + memcpy(temp_palette,Gfx->Default_palette,sizeof(T_Palette)); + Set_palette(Gfx->Default_palette); + Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); + // On prépare la "modifiabilité" des nouvelles couleurs + memcpy(temp_palette,working_palette,sizeof(T_Palette)); + + need_to_remap=1; + break; + + case 6 : // Grey scale + // Backup + memcpy(backup_palette,working_palette,sizeof(T_Palette)); + // Grey Scale + for (i=block_start;i<=block_end;i++) + { + temp_color=(dword)( ((dword)working_palette[i].R*30) + ((dword)working_palette[i].G*59) + ((dword)working_palette[i].B*11) )/100; + Set_red(i,temp_color,working_palette); + Set_green (i,temp_color,working_palette); + Set_blue (i,temp_color,working_palette); + } + Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); + // On prépare la "modifiabilité" des nouvelles couleurs + Set_palette(working_palette); + memcpy(temp_palette,working_palette,sizeof(T_Palette)); + + need_to_remap=1; + break; + + case 7 : // Swap + case 8 : // X-Swap + temp_color=Wait_click_in_palette(Window_palette_button_list); + if ((temp_color>=0) + && (temp_color!=block_start)) + { + Hide_cursor(); + memcpy(backup_palette,working_palette,sizeof(T_Palette)); + + // On calcule le nombre de couleurs a swapper sans risquer de sortir + // de la palette (La var. first_color est utilisée pour économiser 1 var; c'est tout) + first_color=(temp_color+block_end-block_start<=255)?block_end+1-block_start:256-temp_color; + + if (clicked_button==8) // On ne fait de backup de l'image que si on + // est en mode X-SWAP. + if (!image_is_backed_up) + { + Backup(); + image_is_backed_up=1; + } + + Swap(clicked_button==8,block_start,temp_color,first_color,working_palette,color_usage); + + memcpy(temp_palette,working_palette,sizeof(T_Palette)); + + // On déplace le bloc vers les modifs: + last_color=block_end=temp_color+first_color-1; + Fore_color=first_color=block_start=temp_color; + // On raffiche le n° des bornes du bloc: + if (block_start!=block_end) + { + // Cas d'un bloc multi-couleur + Num2str(block_start,str ,3); + Num2str(block_end ,str+4,3); + str[3]=26; // Flèche vers la droite + // Affichage dans le block de visu du bloc (dégradé) en cours + Display_grad_block_in_window(264,93,block_start,block_end); + } + else + { + // Cas d'une seule couleur + Num2str(Fore_color,str,3); + Block(Window_pos_X+(Menu_factor_X*237),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*56,Menu_factor_Y* 7,MC_Light); + // Affichage dans le block de visu de la couleur en cours + Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); + } + Print_in_window(237,58,str,MC_Black,MC_Light); + // On tag le bloc (ou la couleur) + Tag_color_range(block_start,block_end); + + need_to_remap=1; + + Set_palette(working_palette); + + Display_cursor(); + Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); + + // En cas de X-Swap, tout l'ecran a pu changer de couleur. + if (clicked_button==8) + Update_rect(0, 0, Screen_width, Menu_Y_before_window); + Wait_end_of_click(); + } + break; + + case 9 : // Copy + temp_color=Wait_click_in_palette(Window_palette_button_list); + if ((temp_color>=0) && (temp_color!=block_start)) + { + Hide_cursor(); + memcpy(backup_palette,working_palette,sizeof(T_Palette)); + memcpy(working_palette+temp_color,backup_palette+block_start, + ((temp_color+block_end-block_start<=255)?block_end+1-block_start:256-temp_color)*3); + memcpy(temp_palette,working_palette,sizeof(T_Palette)); + Set_palette(working_palette); + // On déplace le bloc vers les modifs: + last_color=block_end=((temp_color+block_end-block_start<=255)?(temp_color+block_end-block_start):255); + Fore_color=first_color=block_start=temp_color; + // On raffiche le n° des bornes du bloc: + if (block_start!=block_end) + { + // Cas d'un bloc multi-couleur + Num2str(block_start,str ,3); + Num2str(block_end ,str+4,3); + str[3]=26; // Flèche vers la droite + // Affichage dans le block de visu du bloc (dégradé) en cours + Display_grad_block_in_window(264,93,block_start,block_end); + } + else + { + // Cas d'une seule couleur + Num2str(Fore_color,str,3); + Block(Window_pos_X+(Menu_factor_X*237),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*56,Menu_factor_Y* 7,MC_Light); + // Affichage dans le block de visu de la couleur en cours + Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); + } + Print_in_window(237,58,str,MC_Black,MC_Light); + // On tag le bloc (ou la couleur) + Tag_color_range(block_start,block_end); + + need_to_remap=1; + + Display_cursor(); + Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); + Wait_end_of_click(); + } + break; + + case 10 : // Spread + if (block_start!=block_end) + { + memcpy(backup_palette,working_palette,sizeof(T_Palette)); + Spread_colors(block_start,block_end,working_palette); + } + else + { + temp_color=Wait_click_in_palette(Window_palette_button_list); + if (temp_color>=0) + { + memcpy(backup_palette,working_palette,sizeof(T_Palette)); + if (temp_colorPosition) + { + reducer_index=reduce_slider->Position; + // Affichage du facteur de réduction de la palette + Hide_cursor(); + Print_in_window(265,41,Palette_reduce_label[reducer_index],MC_Black,MC_Light); + Display_cursor(); + reduce_colors_number=atoi(Palette_reduce_label[reducer_index]); + } + break; + + case 18 : // [+] + if (!Palette_view_is_RGB) + break; + Hide_cursor(); + if (block_start==block_end) + { + if (red_slider->Position) + { + (red_slider->Position)--; + Window_draw_slider(red_slider); + Set_red(Fore_color,(Color_max-red_slider->Position)*255/Color_max,working_palette); + Format_componant(working_palette[Fore_color].R*Color_max/255,str); + Print_counter(176,172,str,MC_Black,MC_Light); + } + if (green_slider->Position) + { + (green_slider->Position)--; + Window_draw_slider(green_slider); + Set_green (Fore_color,(Color_max-green_slider->Position)*255/Color_max,working_palette); + Format_componant(working_palette[Fore_color].G*Color_max/255,str); + Print_counter(203,172,str,MC_Black,MC_Light); + } + if (blue_slider->Position) + { + (blue_slider->Position)--; + Window_draw_slider(blue_slider); + Set_blue (Fore_color,(Color_max-blue_slider->Position)*255/Color_max,working_palette); + Format_componant(working_palette[Fore_color].B*Color_max/255,str); + Print_counter(230,172,str,MC_Black,MC_Light); + } + } + else + { + if (red_slider->Position) + { + (red_slider->Position)--; + Window_draw_slider(red_slider); + } + if (green_slider->Position) + { + (green_slider->Position)--; + Window_draw_slider(green_slider); + } + if (blue_slider->Position) + { + (blue_slider->Position)--; + Window_draw_slider(blue_slider); + } + + for (i=block_start; i<=block_end; i++) + { + Set_red(i,temp_palette[i].R+(Color_max-red_slider->Position)*255/Color_max,working_palette); + Set_green (i,temp_palette[i].G+(Color_max-green_slider->Position)*255/Color_max,working_palette); + Set_blue (i,temp_palette[i].B+(Color_max-blue_slider->Position)*255/Color_max,working_palette); + } + + // -- red -- + if (red_slider->Position>Color_max) + { + // Jauge dans les négatifs: + Num2str(-(Color_max-red_slider->Position),str,4); + str[0]='-'; + } + else if (red_slider->PositionPosition ,str,4); + str[0]='+'; + } + else + { + // Jauge nulle: + strcpy(str,"± 0"); + } + Print_counter(176,172,str,MC_Black,MC_Light); + + + // -- green -- + if (green_slider->Position>Color_max) + { + // Jauge dans les négatifs: + Num2str(-(Color_max-green_slider->Position),str,4); + str[0]='-'; + } + else if (green_slider->PositionPosition ,str,4); + str[0]='+'; + } + else + { + // Jauge nulle: + strcpy(str,"± 0"); + } + Print_counter(203,172,str,MC_Black,MC_Light); + + + // -- blue -- + if (blue_slider->Position>Color_max) + { + // Jauge dans les négatifs: + Num2str(-(Color_max-blue_slider->Position),str,4); + str[0]='-'; + } + else if (blue_slider->PositionPosition ,str,4); + str[0]='+'; + } + else + { + // Jauge nulle: + strcpy(str,"± 0"); + } + Print_counter(230,172,str,MC_Black,MC_Light); + } + + need_to_remap=1; + + Display_cursor(); + Set_palette(working_palette); + break; + + case 19 : // [-] + if (!Palette_view_is_RGB) + break; + Hide_cursor(); + if (block_start==block_end) + { + if (red_slider->PositionPosition)++; + Window_draw_slider(red_slider); + Set_red(Fore_color,(Color_max-red_slider->Position)*255/Color_max,working_palette); + Format_componant(working_palette[Fore_color].R*Color_max/255,str); + Print_counter(176,172,str,MC_Black,MC_Light); + } + if (green_slider->PositionPosition)++; + Window_draw_slider(green_slider); + Set_green (Fore_color,(Color_max-green_slider->Position)*255/Color_max,working_palette); + Format_componant(working_palette[Fore_color].G*Color_max/255,str); + Print_counter(203,172,str,MC_Black,MC_Light); + } + if (blue_slider->PositionPosition)++; + Window_draw_slider(blue_slider); + Set_blue (Fore_color,(Color_max-blue_slider->Position)*255/Color_max,working_palette); + Format_componant(working_palette[Fore_color].B*Color_max/255,str); + Print_counter(230,172,str,MC_Black,MC_Light); + } + } + else + { + if (red_slider->Position<(Color_max*2)) + { + (red_slider->Position)++; + Window_draw_slider(red_slider); + } + if (green_slider->Position<(Color_max*2)) + { + (green_slider->Position)++; + Window_draw_slider(green_slider); + } + if (blue_slider->Position<(Color_max*2)) + { + (blue_slider->Position)++; + Window_draw_slider(blue_slider); + } + + for (i=block_start; i<=block_end; i++) + { + Set_red(i,temp_palette[i].R+(Color_max-red_slider->Position)*255/Color_max,working_palette); + Set_green (i,temp_palette[i].G+(Color_max-green_slider->Position)*255/Color_max,working_palette); + Set_blue (i,temp_palette[i].B+(Color_max-blue_slider->Position)*255/Color_max,working_palette); + } + + // -- red -- + if (red_slider->Position>Color_max) + { + // Jauge dans les négatifs: + Num2str(-(Color_max-red_slider->Position),str,4); + str[0]='-'; + } + else if (red_slider->PositionPosition ,str,4); + str[0]='+'; + } + else + { + // Jauge nulle: + strcpy(str,"± 0"); + } + Print_counter(176,172,str,MC_Black,MC_Light); + + + // -- green -- + if (green_slider->Position>Color_max) + { + // Jauge dans les négatifs: + Num2str(-(Color_max-green_slider->Position),str,4); + str[0]='-'; + } + else if (green_slider->PositionPosition ,str,4); + str[0]='+'; + } + else + { + // Jauge nulle: + strcpy(str,"± 0"); + } + Print_counter(203,172,str,MC_Black,MC_Light); + + + // -- blue -- + if (blue_slider->Position>Color_max) + { + // Jauge dans les négatifs: + Num2str(-(Color_max-blue_slider->Position),str,4); + str[0]='-'; + } + else if (blue_slider->PositionPosition ,str,4); + str[0]='+'; + } + else + { + // Jauge nulle: + strcpy(str,"± 0"); + } + Print_counter(230,172,str,MC_Black,MC_Light); + } + + need_to_remap=1; + + Display_cursor(); + Set_palette(working_palette); + break; + + case 20 : // Negative + // Backup + memcpy(backup_palette,working_palette,sizeof(T_Palette)); + // Negative + for (i=block_start;i<=block_end;i++) + { + Set_red(i,255-working_palette[i].R,working_palette); + Set_green (i,255-working_palette[i].G,working_palette); + Set_blue (i,255-working_palette[i].B,working_palette); + } + Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); + Set_palette(working_palette); + // On prépare la "modifiabilité" des nouvelles couleurs + memcpy(temp_palette,working_palette,sizeof(T_Palette)); + + need_to_remap=1; + break; + + case 21 : // Inversion + case 22 : // X-Inversion + // Backup + memcpy(backup_palette,working_palette,sizeof(T_Palette)); + // On initialise la table de conversion + for (i=0; i<=255; i++) + conversion_table[i]=i; + // Inversion + for (i=block_start;i<=block_end;i++) + { + temp_color=block_end-(i-block_start); + Set_red(i,backup_palette[temp_color].R,working_palette); + Set_green (i,backup_palette[temp_color].G,working_palette); + Set_blue (i,backup_palette[temp_color].B,working_palette); + if (clicked_button==22) + { + conversion_table[i]=temp_color; + conversion_table[temp_color]=i; + + temp=color_usage[i]; + color_usage[i]=color_usage[temp_color]; + color_usage[temp_color]=temp; + } + } + Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); + // Si on est en X-Invert, on remap l'image (=> on fait aussi 1 backup) + if (clicked_button==22) + { + if (!image_is_backed_up) + { + Backup(); + image_is_backed_up=1; + } + Hide_cursor(); + Remap_image_highlevel(conversion_table); + Display_cursor(); + } + // On prépare la "modifiabilité" des nouvelles couleurs + Set_palette(working_palette); + memcpy(temp_palette,working_palette,sizeof(T_Palette)); + + need_to_remap=1; + break; + + case 23 : // Saisie du nombre de couleurs pour la réduction de palette + Num2str(reduce_colors_number,str,3); + + if (Readline(265,41,str,3,1)) + { + temp_color=atoi(str); + // Correction de la valeur lue + if ( (temp_color>256) || (temp_color<2) ) + { + if (temp_color>256) + temp_color=256; + else + temp_color=2; + + Num2str(temp_color,str,3); + Window_input_content(Window_special_button_list,str); + } + + reduce_colors_number=temp_color; + } + Display_cursor(); + break; + + case 24 : // HSL <> RGB + + // Acte les changements en cours sur une ou plusieurs couleurs + memcpy(temp_palette,working_palette,sizeof(T_Palette)); + memcpy(backup_palette ,working_palette,sizeof(T_Palette)); + + Palette_view_is_RGB = !Palette_view_is_RGB; + + if(! Palette_view_is_RGB) + { + // On passe en HSL + Print_in_window(184,71,"H",MC_Dark,MC_Light); + Print_in_window(211,71,"S",MC_Dark,MC_Light); + Print_in_window(238,71,"L",MC_Dark,MC_Light); + Componant_unit(256); + + // Display the + and - button as disabled + Window_draw_normal_bouton(266, 74,12,11,"+",0,0); + Window_draw_normal_bouton(266,165,12,11,"-",0,0); + } + else + { + // On passe en RGB + Print_in_window(184,71,"R",MC_Dark,MC_Light); + Print_in_window(211,71,"G",MC_Dark,MC_Light); + Print_in_window(238,71,"B",MC_Dark,MC_Light); + Componant_unit(RGB_scale); + + // Display the + and - button as enabled + Window_draw_normal_bouton(266, 74,12,11,"+",0,1); + Window_draw_normal_bouton(266,165,12,11,"-",0,1); + } + Display_sliders(red_slider,green_slider,blue_slider,(block_start!=block_end),working_palette); + Update_window_area(265,73,14,103); + break; + + case 25 : // Sort palette + { + byte h = 0, l = 0, s=0; + byte oh=0,ol=0,os=0; // Valeur pour la couleur précédente + int swap=1; + byte remap_table[256]; + byte inverted_table[256]; + byte begin, end; + + if(block_start==block_end) + { + begin = 0; + end = 255; + } + else + { + begin = block_start; + end = block_end; + } + + // Init remap table + for (i=0;i<256;i++) + remap_table[i]=i; + // Make a backup because remapping is an undoable modification + if (!image_is_backed_up) + { + Backup(); + image_is_backed_up=1; + } + + if(Window_attribute1==LEFT_SIDE) + // Laft click on button: Sort by Hue (H) and Lightness (L) + while(swap==1) + { + swap=0; + h=0;l=255;s=0; + for(temp_color=begin;temp_color<=end;temp_color++) + { + oh=h; ol=l; os=s; + RGB_to_HSL(working_palette[temp_color].R, + working_palette[temp_color].G, + working_palette[temp_color].B,&h,&s,&l); + + if( + ((s==0) && (os>0)) // A grey is before a saturated color + || ((s>0 && os > 0) && (hol))) // 2 saturated colors: sort by H, then by L + || ((os==0 && s==0) && l>ol)) // Two greys: sort by L only + { + // Swap color with the previous one + byte swap_color; + Swap(0,temp_color,temp_color-1,1,working_palette,color_usage); + + swap_color=remap_table[temp_color]; + remap_table[temp_color]=remap_table[temp_color-1]; + remap_table[temp_color-1]=swap_color; + + swap=1; + } + } + } + + else // Right click > Sort only on L + while(swap==1) + { + swap=0; + l=255; + for(temp_color=begin;temp_color<=end;temp_color++) + { + ol=l; + RGB_to_HSL(working_palette[temp_color].R, + working_palette[temp_color].G, + working_palette[temp_color].B,&h,&s,&l); + + if(l>ol) + { + // Swap color with the previous one + byte swap_color; + Swap(0,temp_color,temp_color-1,1,working_palette,color_usage); + + swap_color=remap_table[temp_color]; + remap_table[temp_color]=remap_table[temp_color-1]; + remap_table[temp_color-1]=swap_color; + + swap=1; + } + } + } + + for (i=0;i<256;i++) + inverted_table[remap_table[i]]=i; + Remap_image_highlevel(inverted_table); + // Maintenant, tous ces calculs doivent êtres pris en compte dans la + // palette, l'image et à l'écran. + Set_palette(working_palette); + need_to_remap=1; + } + break; + } + + + if (!Mouse_K) + { + switch (Key) + { + case SDLK_LEFTBRACKET : // Décaler Forecolor vers la gauche + if (block_start==block_end) + { + Fore_color--; + first_color--; + last_color--; + block_start--; + block_end--; + Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); + Hide_cursor(); + Tag_color_range(block_start,block_end); + // Affichage du n° de la couleur sélectionnée + Num2str(Fore_color,str,3); + Print_in_window(237,58,str,MC_Black,MC_Light); + // Affichage dans le block de visu de la couleur en cours + Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); + Update_rect(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64); + Display_cursor(); + } + Key=0; + break; + + case SDLK_RIGHTBRACKET : // Décaler Forecolor vers la droite + if (block_start==block_end) + { + Fore_color++; + first_color++; + last_color++; + block_start++; + block_end++; + Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); + Hide_cursor(); + Tag_color_range(block_start,block_end); + // Affichage du n° de la couleur sélectionnée + Num2str(Fore_color,str,3); + Print_in_window(237,58,str,MC_Black,MC_Light); + // Affichage dans le block de visu de la couleur en cours + Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); + Update_rect(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64); + Display_cursor(); + } + Key=0; + break; + + case (SDLK_LEFTBRACKET|MOD_SHIFT) : // Decaler Backcolor vers la gauche + Back_color--; + case (SDLK_RIGHTBRACKET|MOD_SHIFT) : // Decaler Backcolor vers la droite + // attention: pas de break ci-dessus + if (Key==(SDLK_RIGHTBRACKET|MOD_SHIFT)) + Back_color++; + Hide_cursor(); + Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*24,Menu_factor_Y<<2,Back_color); + Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y*157),Menu_factor_X*24,Menu_factor_Y<<2,Back_color); + Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color); + Block(Window_pos_X+(Menu_factor_X*280),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color); + Update_rect(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*32,Menu_factor_Y*72); + Display_cursor(); + Key=0; + break; + + case SDLK_BACKSPACE : // Remise des couleurs du menu à l'état normal en essayant + // de ne pas trop modifier l'image. + if (!image_is_backed_up) + { + Backup(); + image_is_backed_up=1; + } + if (used_colors==-1) + Update_color_count(&used_colors,color_usage); + + memcpy(backup_palette,working_palette,sizeof(T_Palette)); + memcpy(temp_palette,Main_palette,sizeof(T_Palette)); + memcpy(Main_palette,working_palette,sizeof(T_Palette)); + Set_nice_menu_colors(color_usage,0); + memcpy(working_palette,Main_palette,sizeof(T_Palette)); + memcpy(Main_palette,temp_palette,sizeof(T_Palette)); + Set_palette(working_palette); + memcpy(temp_palette,working_palette,sizeof(T_Palette)); + Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end); + Update_color_count(&used_colors,color_usage); + need_to_remap=1; + Key=0; + break; + + case SDLK_BACKQUOTE : // Récupération d'une couleur derrière le menu + case SDLK_COMMA : + Get_color_behind_window(&color,&click); + if (click) + { + Hide_cursor(); + if (click==RIGHT_SIDE) + { + if (Back_color!=color) + { + Back_color=color; + // 4 blocks de back_color entourant la fore_color + Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*24,Menu_factor_Y<<2,Back_color); + Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y*157),Menu_factor_X*24,Menu_factor_Y<<2,Back_color); + Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color); + Block(Window_pos_X+(Menu_factor_X*280),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color); + Update_rect(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*32,Menu_factor_Y*72); + } + } + else + { + Fore_color=first_color=last_color=block_start=block_end=color; + Tag_color_range(block_start,block_end); + + // Affichage du n° de la couleur sélectionnée + Block(Window_pos_X+(Menu_factor_X*261),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*32,Menu_factor_Y*7,MC_Light); + Num2str(Fore_color,str,3); + Print_in_window(237,58,str,MC_Black,MC_Light); + + // Affichage des jauges + Display_sliders(red_slider,green_slider,blue_slider,0,working_palette); + + // Affichage dans le block de visu de la couleur en cours + Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color); + Update_rect(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64); + + memcpy(backup_palette ,working_palette,sizeof(T_Palette)); + memcpy(temp_palette,working_palette,sizeof(T_Palette)); + } + Display_cursor(); + Wait_end_of_click(); + } + Key=0; + break; + default: + if (Is_shortcut(Key,0x100+BUTTON_HELP)) + { + Key=0; + Window_help(BUTTON_PALETTE, NULL); + break; + } + } + + if (need_to_remap) + { + Hide_cursor(); + Compute_optimal_menu_colors(working_palette); + + // On remappe brutalement + Remap_screen_after_menu_colors_change(); + // Puis on remet les trucs qui ne devaient pas changer + Window_draw_palette_bouton(5,79); + Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y*89),Menu_factor_X*24,Menu_factor_Y*72,Back_color); + Display_grad_block_in_window(264,93,block_start,block_end); + + Update_rect(Window_pos_X+8*Menu_factor_X,Window_pos_Y+82*Menu_factor_Y,Menu_factor_X*16*10,Menu_factor_Y*5*16); + + Display_cursor(); + need_to_remap=0; + } + } + } + while ((clicked_button!=13) && (clicked_button!=14)); + + if (clicked_button==14) // Sortie par OK + { + if ( (!image_is_backed_up) + && memcmp(Main_palette,working_palette,sizeof(T_Palette)) ) + Backup(); + memcpy(Main_palette,working_palette,sizeof(T_Palette)); + } + + Compute_optimal_menu_colors(Main_palette); + + // La variable employée ici n'a pas vraiment de rapport avec son nom... + need_to_remap=(Window_pos_Y+(Window_height*Menu_factor_Y)Position = rgb_scale_slider->Position>128?rgb_scale_slider->Position*2-256:0; + Num2str(256-rgb_scale_slider->Position,str,3); + Print_in_window(157,78,str,MC_Black,MC_Light); + Window_draw_slider(rgb_scale_slider); + break; + + case 10: + // /2 RGB scale + rgb_scale_slider->Position = rgb_scale_slider->Position>253?254:(rgb_scale_slider->Position)/2+128; + Num2str(256-rgb_scale_slider->Position,str,3); + Print_in_window(157,78,str,MC_Black,MC_Light); + Window_draw_slider(rgb_scale_slider); + } + } + while (clicked_button!=1 && clicked_button!=2 && clicked_button!=3 && clicked_button!=4); + + // We need to get the sliders positions before closing the window, because they will be freed. + palette_cols=256-columns_slider->Position; + palette_lines=16-lines_slider->Position; + rgb_scale=256-rgb_scale_slider->Position; + + Close_window(); + Unselect_button(BUTTON_PALETTE); + Display_cursor(); + + if (clicked_button==4) // Cancel + return; + + if (palette_vertical != Config.Palette_vertical) + { + Config.Palette_vertical=palette_vertical; + palette_needs_redraw=1; + } + if (palette_cols!=Config.Palette_cells_X || + palette_lines!=Config.Palette_cells_Y) + { + Config.Palette_cells_X = palette_cols; + Config.Palette_cells_Y = palette_lines; + palette_needs_redraw=1; + } + if (rgb_scale!=RGB_scale) + { + Set_palette_RGB_scale(rgb_scale); + Set_palette(Main_palette); + } + + if (clicked_button==1) + { + Menu_tag_colors("Tag colors to exclude",Exclude_color,&dummy,1, NULL); + } + else if (clicked_button==2) + { + // Open the menu with Shade settings. Same as the shortcut, except + // that this will not activate shade mode on exit. + Shade_settings_menu(); + } + + if (palette_needs_redraw) + { + Change_palette_cells(); + Display_menu(); + Display_sprite_in_menu(BUTTON_PAL_LEFT,18+(Config.Palette_vertical!=0)); + } +} diff --git a/palette.h b/palette.h index 273f792b..e28f280c 100644 --- a/palette.h +++ b/palette.h @@ -1,42 +1,42 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - 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 -*/ -////////////////////////////////////////////////////////////////////////////// -///@file palette.h -/// Palette screen, and some palette-related high-level functions. -////////////////////////////////////////////////////////////////////////////// - -/// Open the palette menu and handles everything inside it. -void Button_Palette(void); -/// Open the secondary palette menu and handles it. -void Button_Secondary_palette(void); - -/// Choose the number of graduations for RGB components, from 2 to 256. -void Set_palette_RGB_scale(int); - -/// -/// Scale a component (R, G or B) according to the current RGB graduations. -/// Returns the resulting value, in the [0-255] range. -byte Round_palette_component(byte comp); - -/*! - Adds 4 menu colors in the current palette. - @param color_usage An up-to-date color usage table (byte[256]) (read only) - @param not_picture 0 if the caller is the palette screen, 1 if it's a preview in the file selector. -*/ -void Set_nice_menu_colors(dword * color_usage,int not_picture); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + 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 +*/ +////////////////////////////////////////////////////////////////////////////// +///@file palette.h +/// Palette screen, and some palette-related high-level functions. +////////////////////////////////////////////////////////////////////////////// + +/// Open the palette menu and handles everything inside it. +void Button_Palette(void); +/// Open the secondary palette menu and handles it. +void Button_Secondary_palette(void); + +/// Choose the number of graduations for RGB components, from 2 to 256. +void Set_palette_RGB_scale(int); + +/// +/// Scale a component (R, G or B) according to the current RGB graduations. +/// Returns the resulting value, in the [0-255] range. +byte Round_palette_component(byte comp); + +/*! + Adds 4 menu colors in the current palette. + @param color_usage An up-to-date color usage table (byte[256]) (read only) + @param not_picture 0 if the caller is the palette screen, 1 if it's a preview in the file selector. +*/ +void Set_nice_menu_colors(dword * color_usage,int not_picture); diff --git a/pxdouble.c b/pxdouble.c index a52ec1a2..78b4f8e0 100644 --- a/pxdouble.c +++ b/pxdouble.c @@ -1,497 +1,497 @@ -/* 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 -*/ - -#include -#include -#include -#include "global.h" -#include "sdlscreen.h" -#include "misc.h" -#include "pxdouble.h" -#include "pxwide.h" // for Display_transparent_line_on_screen_wide() - -#define ZOOMX 2 -#define ZOOMY 2 - -void Pixel_double (word x,word y,byte color) -/* Affiche un pixel de la color aux coords x;y à l'écran */ -{ - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 1)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1)* VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1)* VIDEO_LINE_WIDTH + 1)=color; -} - -byte Read_pixel_double (word x,word y) -/* On retourne la couleur du pixel aux coords données */ -{ - return *( Screen_pixels + y * ZOOMY * VIDEO_LINE_WIDTH + x * ZOOMX); -} - -void Block_double (word start_x,word start_y,word width,word height,byte color) -/* On affiche un rectangle de la couleur donnée */ -{ - SDL_Rect rectangle; - rectangle.x=start_x*ZOOMX; - rectangle.y=start_y*ZOOMY; - rectangle.w=width*ZOOMX; - rectangle.h=height*ZOOMY; - SDL_FillRect(Screen_SDL,&rectangle,color); -} - -void Display_part_of_screen_double (word width,word height,word image_width) -/* Afficher une partie de l'image telle quelle sur l'écran */ -{ - byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) - byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) - int y; - int dy; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - // On fait une copie de la ligne - for (dy=width;dy>0;dy--) - { - *(dest+1)=*dest=*src; - src++; - dest+=ZOOMX; - } - // On double la ligne qu'on vient de copier - memcpy(dest-width*ZOOMX+VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); - - // On passe à la ligne suivante - src+=image_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - } - //Update_rect(0,0,width,height); -} - -void Pixel_preview_normal_double (word x,word y,byte color) -/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image - * dans l'écran, en mode normal (pas en mode loupe) - * Note: si on modifie cette procédure, il faudra penser à faire également - * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ -{ -// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) - Pixel_double(x-Main_offset_X,y-Main_offset_Y,color); -} - -void Pixel_preview_magnifier_double (word x,word y,byte color) -{ - // Affiche le pixel dans la partie non zoomée - Pixel_double(x-Main_offset_X,y-Main_offset_Y,color); - - // Regarde si on doit aussi l'afficher dans la partie zoomée - if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom - && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) - { - // On est dedans - int height; - int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); - - if (Menu_Y - y_zoom < Main_magnifier_factor) - // On ne doit dessiner qu'un morceau du pixel - // sinon on dépasse sur le menu - height = Menu_Y - y_zoom; - else - height = Main_magnifier_factor; - - Block_double( - Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, - y_zoom, Main_magnifier_factor, height, color - ); - } -} - -void Horizontal_XOR_line_double(word x_pos,word y_pos,word width) -{ - //On calcule la valeur initiale de dest: - byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; - - int x; - - for (x=0;x0;i--) - { - *dest=*(dest+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+1)=~*dest; - dest+=VIDEO_LINE_WIDTH*ZOOMY; - } -} - -void Display_brush_color_double(word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) -{ - // dest = Position à l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - // src = Position dans la brosse - byte* src = Brush + y_offset * brush_width + x_offset; - - word x,y; - - // Pour chaque ligne - for(y = height;y > 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *(dest+VIDEO_LINE_WIDTH+1) = *(dest+VIDEO_LINE_WIDTH) = *(dest+1) = *dest = *src; - } - - // Pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - src = src + brush_width - width; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Display_brush_mono_double(word x_pos, word y_pos, - word x_offset, word y_offset, word width, word height, - byte transp_color, byte color, word brush_width) -/* On affiche la brosse en monochrome */ -{ - byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; // dest = adr destination à - // l'écran - byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds - // la brosse - int x,y; - - for(y=height;y!=0;y--) - //Pour chaque ligne - { - for(x=width;x!=0;x--) - //Pour chaque pixel - { - if (*src!=transp_color) - *(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*dest=color; - - // On passe au pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - src+=brush_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Clear_brush_double(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) -{ - byte* dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) - byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) - int y; - int x; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - for(x=width;x!=0;x--) - //Pour chaque pixel - { - *(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*dest=*src; - - // On passe au pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - src+=image_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; - } - Update_rect(x_pos,y_pos,width,height); -} - -// Affiche une brosse (arbitraire) à l'écran -void Display_brush_double(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) -{ - // dest = Position à l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - // src = Position dans la brosse - byte* src = brush + y_offset * brush_width + x_offset; - - word x,y; - - // Pour chaque ligne - for(y = height;y > 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*dest=*src; - } - - // Pixel suivant - src++; dest+=ZOOMX; - } - - // On passe à la ligne suivante - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - src = src + brush_width - width; - } -} - -void Remap_screen_double(word x_pos,word y_pos,word width,word height,byte * conversion_table) -{ - // dest = coords a l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - int x,y; - - // Pour chaque ligne - for(y=height;y>0;y--) - { - // Pour chaque pixel - for(x=width;x>0;x--) - { - *(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*dest= - conversion_table[*dest]; - dest +=ZOOMX; - } - - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - } - - Update_rect(x_pos,y_pos,width,height); -} - -void Display_line_on_screen_fast_double(word x_pos,word y_pos,word width,byte * line) -/* On affiche toute une ligne de pixels telle quelle. */ -/* Utilisée si le buffer contient déja des pixel doublés. */ -{ - memcpy(Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH,line,width*ZOOMX); - memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+1)*VIDEO_LINE_WIDTH,line,width*ZOOMX); -} - -void Display_line_on_screen_double(word x_pos,word y_pos,word width,byte * line) -/* On affiche une ligne de pixels en les doublant. */ -{ - int x; - byte *dest; - dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; - for(x=width;x>0;x--) - { - *(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*dest=*line; - dest+=ZOOMX; - line++; - } -} -void Display_transparent_mono_line_on_screen_double( - word x_pos, word y_pos, word width, byte* line, - byte transp_color, byte color) -// Affiche une ligne à l'écran avec une couleur + transparence. -// Utilisé par les brosses en mode zoom -{ - byte* dest = Screen_pixels+ y_pos*VIDEO_LINE_WIDTH + x_pos*ZOOMX; - int x; - // Pour chaque pixel - for(x=0;x 0); - src += image_width; - } -// ATTENTION on n'arrive jamais ici ! -} - -// Affiche une partie de la brosse couleur zoomée -void Display_brush_color_zoom_double(word x_pos,word y_pos, - word x_offset,word y_offset, - word width, // width non zoomée - word end_y_pos,byte transp_color, - word brush_width, // width réelle de la brosse - byte * buffer) -{ - byte* src = Brush+y_offset*brush_width + x_offset; - word y = y_pos; - byte bx; - - // Pour chaque ligne - while(1) - { - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - // On affiche facteur fois la ligne zoomée - for(bx=Main_magnifier_factor;bx>0;bx--) - { - Display_transparent_line_on_screen_wide(x_pos,y*ZOOMY,width*Main_magnifier_factor,buffer,transp_color); - memcpy(Screen_pixels + (y*ZOOMY+1)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); - y++; - if(y==end_y_pos) - { - return; - } - } - src += brush_width; - } - // ATTENTION zone jamais atteinte -} - -void Display_brush_mono_zoom_double(word x_pos, word y_pos, - word x_offset, word y_offset, - word width, // width non zoomée - word end_y_pos, - byte transp_color, byte color, - word brush_width, // width réelle de la brosse - byte * buffer -) - -{ - byte* src = Brush + y_offset * brush_width + x_offset; - int y=y_pos*ZOOMY; - - //Pour chaque ligne à zoomer : - while(1) - { - int bx; - // src = Ligne originale - // On éclate la ligne - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - - // On affiche la ligne Facteur fois à l'écran (sur des - // lignes consécutives) - bx = Main_magnifier_factor*ZOOMY; - - // Pour chaque ligne écran - do - { - // On affiche la ligne zoomée - Display_transparent_mono_line_on_screen_double( - x_pos, y, width * Main_magnifier_factor, - buffer, transp_color, color - ); - // On passe à la ligne suivante - y++; - // On vérifie qu'on est pas à la ligne finale - if(y == end_y_pos*ZOOMY) - { - Update_rect( x_pos, y_pos, - width * Main_magnifier_factor, end_y_pos - y_pos ); - return; - } - bx --; - } - while (bx > 0); - - // Passage à la ligne suivante dans la brosse aussi - src+=brush_width; - } -} - -void Clear_brush_scaled_double(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) -{ - - // En fait on va recopier l'image non zoomée dans la partie zoomée ! - byte* src = Main_screen + y_offset * image_width + x_offset; - int y = y_pos; - int bx; - - // Pour chaque ligne à zoomer - while(1){ - Zoom_a_line(src,buffer,Main_magnifier_factor*ZOOMX,width); - - bx=Main_magnifier_factor; - - // Pour chaque ligne - do{ - Display_line_on_screen_fast_double(x_pos,y, - width * Main_magnifier_factor,buffer); - - // Ligne suivante - y++; - if(y==end_y_pos) - { - Update_rect(x_pos,y_pos, - width*Main_magnifier_factor,end_y_pos-y_pos); - return; - } - bx--; - }while(bx!=0); - - src+= image_width; - } -} - - +/* 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 +*/ + +#include +#include +#include +#include "global.h" +#include "sdlscreen.h" +#include "misc.h" +#include "pxdouble.h" +#include "pxwide.h" // for Display_transparent_line_on_screen_wide() + +#define ZOOMX 2 +#define ZOOMY 2 + +void Pixel_double (word x,word y,byte color) +/* Affiche un pixel de la color aux coords x;y à l'écran */ +{ + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 1)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1)* VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1)* VIDEO_LINE_WIDTH + 1)=color; +} + +byte Read_pixel_double (word x,word y) +/* On retourne la couleur du pixel aux coords données */ +{ + return *( Screen_pixels + y * ZOOMY * VIDEO_LINE_WIDTH + x * ZOOMX); +} + +void Block_double (word start_x,word start_y,word width,word height,byte color) +/* On affiche un rectangle de la couleur donnée */ +{ + SDL_Rect rectangle; + rectangle.x=start_x*ZOOMX; + rectangle.y=start_y*ZOOMY; + rectangle.w=width*ZOOMX; + rectangle.h=height*ZOOMY; + SDL_FillRect(Screen_SDL,&rectangle,color); +} + +void Display_part_of_screen_double (word width,word height,word image_width) +/* Afficher une partie de l'image telle quelle sur l'écran */ +{ + byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) + byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) + int y; + int dy; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + // On fait une copie de la ligne + for (dy=width;dy>0;dy--) + { + *(dest+1)=*dest=*src; + src++; + dest+=ZOOMX; + } + // On double la ligne qu'on vient de copier + memcpy(dest-width*ZOOMX+VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); + + // On passe à la ligne suivante + src+=image_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + } + //Update_rect(0,0,width,height); +} + +void Pixel_preview_normal_double (word x,word y,byte color) +/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image + * dans l'écran, en mode normal (pas en mode loupe) + * Note: si on modifie cette procédure, il faudra penser à faire également + * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ +{ +// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) + Pixel_double(x-Main_offset_X,y-Main_offset_Y,color); +} + +void Pixel_preview_magnifier_double (word x,word y,byte color) +{ + // Affiche le pixel dans la partie non zoomée + Pixel_double(x-Main_offset_X,y-Main_offset_Y,color); + + // Regarde si on doit aussi l'afficher dans la partie zoomée + if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom + && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) + { + // On est dedans + int height; + int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); + + if (Menu_Y - y_zoom < Main_magnifier_factor) + // On ne doit dessiner qu'un morceau du pixel + // sinon on dépasse sur le menu + height = Menu_Y - y_zoom; + else + height = Main_magnifier_factor; + + Block_double( + Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, + y_zoom, Main_magnifier_factor, height, color + ); + } +} + +void Horizontal_XOR_line_double(word x_pos,word y_pos,word width) +{ + //On calcule la valeur initiale de dest: + byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; + + int x; + + for (x=0;x0;i--) + { + *dest=*(dest+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+1)=~*dest; + dest+=VIDEO_LINE_WIDTH*ZOOMY; + } +} + +void Display_brush_color_double(word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) +{ + // dest = Position à l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + // src = Position dans la brosse + byte* src = Brush + y_offset * brush_width + x_offset; + + word x,y; + + // Pour chaque ligne + for(y = height;y > 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *(dest+VIDEO_LINE_WIDTH+1) = *(dest+VIDEO_LINE_WIDTH) = *(dest+1) = *dest = *src; + } + + // Pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + src = src + brush_width - width; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Display_brush_mono_double(word x_pos, word y_pos, + word x_offset, word y_offset, word width, word height, + byte transp_color, byte color, word brush_width) +/* On affiche la brosse en monochrome */ +{ + byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; // dest = adr destination à + // l'écran + byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds + // la brosse + int x,y; + + for(y=height;y!=0;y--) + //Pour chaque ligne + { + for(x=width;x!=0;x--) + //Pour chaque pixel + { + if (*src!=transp_color) + *(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*dest=color; + + // On passe au pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + src+=brush_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Clear_brush_double(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) +{ + byte* dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) + byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) + int y; + int x; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + for(x=width;x!=0;x--) + //Pour chaque pixel + { + *(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*dest=*src; + + // On passe au pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + src+=image_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; + } + Update_rect(x_pos,y_pos,width,height); +} + +// Affiche une brosse (arbitraire) à l'écran +void Display_brush_double(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) +{ + // dest = Position à l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + // src = Position dans la brosse + byte* src = brush + y_offset * brush_width + x_offset; + + word x,y; + + // Pour chaque ligne + for(y = height;y > 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*dest=*src; + } + + // Pixel suivant + src++; dest+=ZOOMX; + } + + // On passe à la ligne suivante + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + src = src + brush_width - width; + } +} + +void Remap_screen_double(word x_pos,word y_pos,word width,word height,byte * conversion_table) +{ + // dest = coords a l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + int x,y; + + // Pour chaque ligne + for(y=height;y>0;y--) + { + // Pour chaque pixel + for(x=width;x>0;x--) + { + *(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*dest= + conversion_table[*dest]; + dest +=ZOOMX; + } + + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + } + + Update_rect(x_pos,y_pos,width,height); +} + +void Display_line_on_screen_fast_double(word x_pos,word y_pos,word width,byte * line) +/* On affiche toute une ligne de pixels telle quelle. */ +/* Utilisée si le buffer contient déja des pixel doublés. */ +{ + memcpy(Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH,line,width*ZOOMX); + memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+1)*VIDEO_LINE_WIDTH,line,width*ZOOMX); +} + +void Display_line_on_screen_double(word x_pos,word y_pos,word width,byte * line) +/* On affiche une ligne de pixels en les doublant. */ +{ + int x; + byte *dest; + dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; + for(x=width;x>0;x--) + { + *(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*dest=*line; + dest+=ZOOMX; + line++; + } +} +void Display_transparent_mono_line_on_screen_double( + word x_pos, word y_pos, word width, byte* line, + byte transp_color, byte color) +// Affiche une ligne à l'écran avec une couleur + transparence. +// Utilisé par les brosses en mode zoom +{ + byte* dest = Screen_pixels+ y_pos*VIDEO_LINE_WIDTH + x_pos*ZOOMX; + int x; + // Pour chaque pixel + for(x=0;x 0); + src += image_width; + } +// ATTENTION on n'arrive jamais ici ! +} + +// Affiche une partie de la brosse couleur zoomée +void Display_brush_color_zoom_double(word x_pos,word y_pos, + word x_offset,word y_offset, + word width, // width non zoomée + word end_y_pos,byte transp_color, + word brush_width, // width réelle de la brosse + byte * buffer) +{ + byte* src = Brush+y_offset*brush_width + x_offset; + word y = y_pos; + byte bx; + + // Pour chaque ligne + while(1) + { + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + // On affiche facteur fois la ligne zoomée + for(bx=Main_magnifier_factor;bx>0;bx--) + { + Display_transparent_line_on_screen_wide(x_pos,y*ZOOMY,width*Main_magnifier_factor,buffer,transp_color); + memcpy(Screen_pixels + (y*ZOOMY+1)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); + y++; + if(y==end_y_pos) + { + return; + } + } + src += brush_width; + } + // ATTENTION zone jamais atteinte +} + +void Display_brush_mono_zoom_double(word x_pos, word y_pos, + word x_offset, word y_offset, + word width, // width non zoomée + word end_y_pos, + byte transp_color, byte color, + word brush_width, // width réelle de la brosse + byte * buffer +) + +{ + byte* src = Brush + y_offset * brush_width + x_offset; + int y=y_pos*ZOOMY; + + //Pour chaque ligne à zoomer : + while(1) + { + int bx; + // src = Ligne originale + // On éclate la ligne + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + + // On affiche la ligne Facteur fois à l'écran (sur des + // lignes consécutives) + bx = Main_magnifier_factor*ZOOMY; + + // Pour chaque ligne écran + do + { + // On affiche la ligne zoomée + Display_transparent_mono_line_on_screen_double( + x_pos, y, width * Main_magnifier_factor, + buffer, transp_color, color + ); + // On passe à la ligne suivante + y++; + // On vérifie qu'on est pas à la ligne finale + if(y == end_y_pos*ZOOMY) + { + Update_rect( x_pos, y_pos, + width * Main_magnifier_factor, end_y_pos - y_pos ); + return; + } + bx --; + } + while (bx > 0); + + // Passage à la ligne suivante dans la brosse aussi + src+=brush_width; + } +} + +void Clear_brush_scaled_double(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) +{ + + // En fait on va recopier l'image non zoomée dans la partie zoomée ! + byte* src = Main_screen + y_offset * image_width + x_offset; + int y = y_pos; + int bx; + + // Pour chaque ligne à zoomer + while(1){ + Zoom_a_line(src,buffer,Main_magnifier_factor*ZOOMX,width); + + bx=Main_magnifier_factor; + + // Pour chaque ligne + do{ + Display_line_on_screen_fast_double(x_pos,y, + width * Main_magnifier_factor,buffer); + + // Ligne suivante + y++; + if(y==end_y_pos) + { + Update_rect(x_pos,y_pos, + width*Main_magnifier_factor,end_y_pos-y_pos); + return; + } + bx--; + }while(bx!=0); + + src+= image_width; + } +} + + diff --git a/pxdouble.h b/pxdouble.h index e7655ce9..3d8296f8 100644 --- a/pxdouble.h +++ b/pxdouble.h @@ -1,48 +1,48 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file pxdouble.h -/// Renderer for double pixels (2x2). -////////////////////////////////////////////////////////////////////////////// - -#include "struct.h" - - void Pixel_double (word x,word y,byte color); - byte Read_pixel_double (word x,word y); - void Block_double (word start_x,word start_y,word width,word height,byte color); - void Pixel_preview_normal_double (word x,word y,byte color); - void Pixel_preview_magnifier_double (word x,word y,byte color); - void Horizontal_XOR_line_double (word x_pos,word y_pos,word width); - void Vertical_XOR_line_double (word x_pos,word y_pos,word height); - void Display_brush_color_double (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); - void Display_brush_mono_double (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); - void Clear_brush_double (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); - void Remap_screen_double (word x_pos,word y_pos,word width,word height,byte * conversion_table); - void Display_part_of_screen_double (word width,word height,word image_width); - void Display_line_on_screen_double (word x_pos,word y_pos,word width,byte * line); - void Read_line_screen_double (word x_pos,word y_pos,word width,byte * line); - void Display_part_of_screen_scaled_double(word width,word height,word image_width,byte * buffer); - void Display_brush_color_zoom_double (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); - void Display_brush_mono_zoom_double (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); - void Clear_brush_scaled_double (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); - void Display_brush_double (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); - - void Display_line_on_screen_fast_double (word x_pos,word y_pos,word width,byte * line); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file pxdouble.h +/// Renderer for double pixels (2x2). +////////////////////////////////////////////////////////////////////////////// + +#include "struct.h" + + void Pixel_double (word x,word y,byte color); + byte Read_pixel_double (word x,word y); + void Block_double (word start_x,word start_y,word width,word height,byte color); + void Pixel_preview_normal_double (word x,word y,byte color); + void Pixel_preview_magnifier_double (word x,word y,byte color); + void Horizontal_XOR_line_double (word x_pos,word y_pos,word width); + void Vertical_XOR_line_double (word x_pos,word y_pos,word height); + void Display_brush_color_double (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); + void Display_brush_mono_double (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); + void Clear_brush_double (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); + void Remap_screen_double (word x_pos,word y_pos,word width,word height,byte * conversion_table); + void Display_part_of_screen_double (word width,word height,word image_width); + void Display_line_on_screen_double (word x_pos,word y_pos,word width,byte * line); + void Read_line_screen_double (word x_pos,word y_pos,word width,byte * line); + void Display_part_of_screen_scaled_double(word width,word height,word image_width,byte * buffer); + void Display_brush_color_zoom_double (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); + void Display_brush_mono_zoom_double (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); + void Clear_brush_scaled_double (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); + void Display_brush_double (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); + + void Display_line_on_screen_fast_double (word x_pos,word y_pos,word width,byte * line); diff --git a/pxquad.c b/pxquad.c index b257e316..fc401181 100644 --- a/pxquad.c +++ b/pxquad.c @@ -1,532 +1,532 @@ -/* 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 -*/ - -#include -#include -#include -#include "global.h" -#include "sdlscreen.h" -#include "misc.h" -#include "pxquad.h" - -#define ZOOMX 4 -#define ZOOMY 4 - -void Pixel_quad (word x,word y,byte color) -/* Affiche un pixel de la color aux coords x;y à l'écran */ -{ - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 1)=color; - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 2)=color; - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 3)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 1)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 2)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 3)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH + 1)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH + 2)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH + 3)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+3) * VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+3) * VIDEO_LINE_WIDTH + 1)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+3) * VIDEO_LINE_WIDTH + 2)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+3) * VIDEO_LINE_WIDTH + 3)=color; -} - -byte Read_pixel_quad (word x,word y) -/* On retourne la couleur du pixel aux coords données */ -{ - return *( Screen_pixels + y * ZOOMY * VIDEO_LINE_WIDTH + x * ZOOMX); -} - -void Block_quad (word start_x,word start_y,word width,word height,byte color) -/* On affiche un rectangle de la couleur donnée */ -{ - SDL_Rect rectangle; - rectangle.x=start_x*ZOOMX; - rectangle.y=start_y*ZOOMY; - rectangle.w=width*ZOOMX; - rectangle.h=height*ZOOMY; - SDL_FillRect(Screen_SDL,&rectangle,color); -} - -void Display_part_of_screen_quad (word width,word height,word image_width) -/* Afficher une partie de l'image telle quelle sur l'écran */ -{ - byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) - byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) - int y; - int dy; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - // On fait une copie de la ligne - for (dy=width;dy>0;dy--) - { - *(dest+3)=*(dest+2)=*(dest+1)=*dest=*src; - src++; - dest+=ZOOMX; - } - // On double la ligne qu'on vient de copier - memcpy(dest-width*ZOOMX+VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); - // On la triple - memcpy(dest-width*ZOOMX+2*VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); - // On la quadruple - memcpy(dest-width*ZOOMX+3*VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); - - // On passe à la ligne suivante - src+=image_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - } - //Update_rect(0,0,width,height); -} - -void Pixel_preview_normal_quad (word x,word y,byte color) -/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image - * dans l'écran, en mode normal (pas en mode loupe) - * Note: si on modifie cette procédure, il faudra penser à faire également - * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ -{ -// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) - Pixel_quad(x-Main_offset_X,y-Main_offset_Y,color); -} - -void Pixel_preview_magnifier_quad (word x,word y,byte color) -{ - // Affiche le pixel dans la partie non zoomée - Pixel_quad(x-Main_offset_X,y-Main_offset_Y,color); - - // Regarde si on doit aussi l'afficher dans la partie zoomée - if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom - && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) - { - // On est dedans - int height; - int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); - - if (Menu_Y - y_zoom < Main_magnifier_factor) - // On ne doit dessiner qu'un morceau du pixel - // sinon on dépasse sur le menu - height = Menu_Y - y_zoom; - else - height = Main_magnifier_factor; - - Block_quad( - Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, - y_zoom, Main_magnifier_factor, height, color - ); - } -} - -void Horizontal_XOR_line_quad(word x_pos,word y_pos,word width) -{ - //On calcule la valeur initiale de dest: - byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; - - int x; - - for (x=0;x0;i--) - { - *(dest+3*VIDEO_LINE_WIDTH+3)=*(dest+3*VIDEO_LINE_WIDTH+2)=*(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+3)=*(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*(dest)=~*(dest); - dest+=VIDEO_LINE_WIDTH*ZOOMY; - } -} - -void Display_brush_color_quad(word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) -{ - // dest = Position à l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - // src = Position dans la brosse - byte* src = Brush + y_offset * brush_width + x_offset; - - word x,y; - - // Pour chaque ligne - for(y = height;y > 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *(dest+3*VIDEO_LINE_WIDTH+3) = *(dest+3*VIDEO_LINE_WIDTH+2) = *(dest+3*VIDEO_LINE_WIDTH+1) = *(dest+3*VIDEO_LINE_WIDTH) = *(dest+2*VIDEO_LINE_WIDTH+3) = *(dest+2*VIDEO_LINE_WIDTH+2) = *(dest+2*VIDEO_LINE_WIDTH+1) = *(dest+2*VIDEO_LINE_WIDTH) = *(dest+VIDEO_LINE_WIDTH+3) = *(dest+VIDEO_LINE_WIDTH+2) = *(dest+VIDEO_LINE_WIDTH+1) = *(dest+VIDEO_LINE_WIDTH) = *(dest+3) = *(dest+2) = *(dest+1) = *dest = *src; - } - - // Pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - src = src + brush_width - width; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Display_brush_mono_quad(word x_pos, word y_pos, - word x_offset, word y_offset, word width, word height, - byte transp_color, byte color, word brush_width) -/* On affiche la brosse en monochrome */ -{ - byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; // dest = adr destination à - // l'écran - byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds - // la brosse - int x,y; - - for(y=height;y!=0;y--) - //Pour chaque ligne - { - for(x=width;x!=0;x--) - //Pour chaque pixel - { - if (*src!=transp_color) - *(dest+3*VIDEO_LINE_WIDTH+3)=*(dest+3*VIDEO_LINE_WIDTH+2)=*(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+3)=*(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=color; - - // On passe au pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - src+=brush_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Clear_brush_quad(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) -{ - byte* dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) - byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) - int y; - int x; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - for(x=width;x!=0;x--) - //Pour chaque pixel - { - *(dest+3*VIDEO_LINE_WIDTH+3)=*(dest+3*VIDEO_LINE_WIDTH+2)=*(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+3)=*(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=*src; - - // On passe au pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - src+=image_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; - } - Update_rect(x_pos,y_pos,width,height); -} - -// Affiche une brosse (arbitraire) à l'écran -void Display_brush_quad(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) -{ - // dest = Position à l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - // src = Position dans la brosse - byte* src = brush + y_offset * brush_width + x_offset; - - word x,y; - - // Pour chaque ligne - for(y = height;y > 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *(dest+3*VIDEO_LINE_WIDTH+3)=*(dest+3*VIDEO_LINE_WIDTH+2)=*(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+3)=*(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=*src; - } - - // Pixel suivant - src++; dest+=ZOOMX; - } - - // On passe à la ligne suivante - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - src = src + brush_width - width; - } -} - -void Remap_screen_quad(word x_pos,word y_pos,word width,word height,byte * conversion_table) -{ - // dest = coords a l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - int x,y; - - // Pour chaque ligne - for(y=height;y>0;y--) - { - // Pour chaque pixel - for(x=width;x>0;x--) - { - *(dest+3*VIDEO_LINE_WIDTH+3)=*(dest+3*VIDEO_LINE_WIDTH+2)=*(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+3)=*(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest= - conversion_table[*dest]; - dest +=ZOOMX; - } - - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - } - - Update_rect(x_pos,y_pos,width,height); -} - -void Display_line_on_screen_fast_quad(word x_pos,word y_pos,word width,byte * line) -/* On affiche toute une ligne de pixels telle quelle. */ -/* Utilisée si le buffer contient déja des pixel doublés. */ -{ - memcpy(Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH,line,width*ZOOMX); - memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+1)*VIDEO_LINE_WIDTH,line,width*ZOOMX); - memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+2)*VIDEO_LINE_WIDTH,line,width*ZOOMX); - memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+3)*VIDEO_LINE_WIDTH,line,width*ZOOMX); -} - -void Display_line_on_screen_quad(word x_pos,word y_pos,word width,byte * line) -/* On affiche une ligne de pixels en les doublant. */ -{ - int x; - byte *dest; - dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; - for(x=width;x>0;x--) - { - *(dest+3*VIDEO_LINE_WIDTH+3)=*(dest+3*VIDEO_LINE_WIDTH+2)=*(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+3)=*(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=*line; - dest+=ZOOMX; - line++; - } -} -void Display_transparent_mono_line_on_screen_quad( - word x_pos, word y_pos, word width, byte* line, - byte transp_color, byte color) -// Affiche une ligne à l'écran avec une couleur + transparence. -// Utilisé par les brosses en mode zoom -{ - byte* dest = Screen_pixels+ y_pos*VIDEO_LINE_WIDTH + x_pos*ZOOMX; - int x; - // Pour chaque pixel - for(x=0;x 0); - src += image_width; - } -// ATTENTION on n'arrive jamais ici ! -} - -// Affiche une partie de la brosse couleur zoomée -void Display_brush_color_zoom_quad(word x_pos,word y_pos, - word x_offset,word y_offset, - word width, // width non zoomée - word end_y_pos,byte transp_color, - word brush_width, // width réelle de la brosse - byte * buffer) -{ - byte* src = Brush+y_offset*brush_width + x_offset; - word y = y_pos; - byte bx; - - // Pour chaque ligne - while(1) - { - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - // On affiche facteur fois la ligne zoomée - for(bx=Main_magnifier_factor;bx>0;bx--) - { - byte* line_src = buffer; - byte* dest = Screen_pixels + y*ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - word x; - // Pour chaque pixel de la ligne - for(x = width*Main_magnifier_factor;x > 0;x--) - { - if(*line_src!=transp_color) - { - *(dest+3)=*(dest+2)=*(dest+1)=*dest = *line_src; - } - line_src++; - dest+=ZOOMX; - } - // Double the line - memcpy(Screen_pixels + (y*ZOOMY+1)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); - // Triple the line - memcpy(Screen_pixels + (y*ZOOMY+2)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); - // Quadruple it - memcpy(Screen_pixels + (y*ZOOMY+3)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); - y++; - if(y==end_y_pos) - { - return; - } - } - src += brush_width; - } - // ATTENTION zone jamais atteinte -} - -void Display_brush_mono_zoom_quad(word x_pos, word y_pos, - word x_offset, word y_offset, - word width, // width non zoomée - word end_y_pos, - byte transp_color, byte color, - word brush_width, // width réelle de la brosse - byte * buffer -) - -{ - byte* src = Brush + y_offset * brush_width + x_offset; - int y=y_pos*ZOOMY; - - //Pour chaque ligne à zoomer : - while(1) - { - int bx; - // src = Ligne originale - // On éclate la ligne - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - - // On affiche la ligne Facteur fois à l'écran (sur des - // lignes consécutives) - bx = Main_magnifier_factor*ZOOMY; - - // Pour chaque ligne écran - do - { - // On affiche la ligne zoomée - Display_transparent_mono_line_on_screen_quad( - x_pos, y, width * Main_magnifier_factor, - buffer, transp_color, color - ); - // On passe à la ligne suivante - y++; - // On vérifie qu'on est pas à la ligne finale - if(y == end_y_pos*ZOOMY) - { - Update_rect( x_pos, y_pos, - width * Main_magnifier_factor, end_y_pos - y_pos ); - return; - } - bx --; - } - while (bx > 0); - - // Passage à la ligne suivante dans la brosse aussi - src+=brush_width; - } -} - -void Clear_brush_scaled_quad(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) -{ - - // En fait on va recopier l'image non zoomée dans la partie zoomée ! - byte* src = Main_screen + y_offset * image_width + x_offset; - int y = y_pos; - int bx; - - // Pour chaque ligne à zoomer - while(1){ - Zoom_a_line(src,buffer,Main_magnifier_factor*ZOOMX,width); - - bx=Main_magnifier_factor; - - // Pour chaque ligne - do{ - // TODO a verifier - Display_line_on_screen_fast_quad(x_pos,y, - width * Main_magnifier_factor,buffer); - - // Ligne suivante - y++; - if(y==end_y_pos) - { - Update_rect(x_pos,y_pos, - width*Main_magnifier_factor,end_y_pos-y_pos); - return; - } - bx--; - }while(bx!=0); - - src+= image_width; - } -} - - +/* 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 +*/ + +#include +#include +#include +#include "global.h" +#include "sdlscreen.h" +#include "misc.h" +#include "pxquad.h" + +#define ZOOMX 4 +#define ZOOMY 4 + +void Pixel_quad (word x,word y,byte color) +/* Affiche un pixel de la color aux coords x;y à l'écran */ +{ + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 1)=color; + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 2)=color; + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 3)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 1)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 2)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 3)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH + 1)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH + 2)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH + 3)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+3) * VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+3) * VIDEO_LINE_WIDTH + 1)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+3) * VIDEO_LINE_WIDTH + 2)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+3) * VIDEO_LINE_WIDTH + 3)=color; +} + +byte Read_pixel_quad (word x,word y) +/* On retourne la couleur du pixel aux coords données */ +{ + return *( Screen_pixels + y * ZOOMY * VIDEO_LINE_WIDTH + x * ZOOMX); +} + +void Block_quad (word start_x,word start_y,word width,word height,byte color) +/* On affiche un rectangle de la couleur donnée */ +{ + SDL_Rect rectangle; + rectangle.x=start_x*ZOOMX; + rectangle.y=start_y*ZOOMY; + rectangle.w=width*ZOOMX; + rectangle.h=height*ZOOMY; + SDL_FillRect(Screen_SDL,&rectangle,color); +} + +void Display_part_of_screen_quad (word width,word height,word image_width) +/* Afficher une partie de l'image telle quelle sur l'écran */ +{ + byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) + byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) + int y; + int dy; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + // On fait une copie de la ligne + for (dy=width;dy>0;dy--) + { + *(dest+3)=*(dest+2)=*(dest+1)=*dest=*src; + src++; + dest+=ZOOMX; + } + // On double la ligne qu'on vient de copier + memcpy(dest-width*ZOOMX+VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); + // On la triple + memcpy(dest-width*ZOOMX+2*VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); + // On la quadruple + memcpy(dest-width*ZOOMX+3*VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); + + // On passe à la ligne suivante + src+=image_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + } + //Update_rect(0,0,width,height); +} + +void Pixel_preview_normal_quad (word x,word y,byte color) +/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image + * dans l'écran, en mode normal (pas en mode loupe) + * Note: si on modifie cette procédure, il faudra penser à faire également + * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ +{ +// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) + Pixel_quad(x-Main_offset_X,y-Main_offset_Y,color); +} + +void Pixel_preview_magnifier_quad (word x,word y,byte color) +{ + // Affiche le pixel dans la partie non zoomée + Pixel_quad(x-Main_offset_X,y-Main_offset_Y,color); + + // Regarde si on doit aussi l'afficher dans la partie zoomée + if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom + && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) + { + // On est dedans + int height; + int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); + + if (Menu_Y - y_zoom < Main_magnifier_factor) + // On ne doit dessiner qu'un morceau du pixel + // sinon on dépasse sur le menu + height = Menu_Y - y_zoom; + else + height = Main_magnifier_factor; + + Block_quad( + Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, + y_zoom, Main_magnifier_factor, height, color + ); + } +} + +void Horizontal_XOR_line_quad(word x_pos,word y_pos,word width) +{ + //On calcule la valeur initiale de dest: + byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; + + int x; + + for (x=0;x0;i--) + { + *(dest+3*VIDEO_LINE_WIDTH+3)=*(dest+3*VIDEO_LINE_WIDTH+2)=*(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+3)=*(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*(dest)=~*(dest); + dest+=VIDEO_LINE_WIDTH*ZOOMY; + } +} + +void Display_brush_color_quad(word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) +{ + // dest = Position à l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + // src = Position dans la brosse + byte* src = Brush + y_offset * brush_width + x_offset; + + word x,y; + + // Pour chaque ligne + for(y = height;y > 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *(dest+3*VIDEO_LINE_WIDTH+3) = *(dest+3*VIDEO_LINE_WIDTH+2) = *(dest+3*VIDEO_LINE_WIDTH+1) = *(dest+3*VIDEO_LINE_WIDTH) = *(dest+2*VIDEO_LINE_WIDTH+3) = *(dest+2*VIDEO_LINE_WIDTH+2) = *(dest+2*VIDEO_LINE_WIDTH+1) = *(dest+2*VIDEO_LINE_WIDTH) = *(dest+VIDEO_LINE_WIDTH+3) = *(dest+VIDEO_LINE_WIDTH+2) = *(dest+VIDEO_LINE_WIDTH+1) = *(dest+VIDEO_LINE_WIDTH) = *(dest+3) = *(dest+2) = *(dest+1) = *dest = *src; + } + + // Pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + src = src + brush_width - width; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Display_brush_mono_quad(word x_pos, word y_pos, + word x_offset, word y_offset, word width, word height, + byte transp_color, byte color, word brush_width) +/* On affiche la brosse en monochrome */ +{ + byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; // dest = adr destination à + // l'écran + byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds + // la brosse + int x,y; + + for(y=height;y!=0;y--) + //Pour chaque ligne + { + for(x=width;x!=0;x--) + //Pour chaque pixel + { + if (*src!=transp_color) + *(dest+3*VIDEO_LINE_WIDTH+3)=*(dest+3*VIDEO_LINE_WIDTH+2)=*(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+3)=*(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=color; + + // On passe au pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + src+=brush_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Clear_brush_quad(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) +{ + byte* dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) + byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) + int y; + int x; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + for(x=width;x!=0;x--) + //Pour chaque pixel + { + *(dest+3*VIDEO_LINE_WIDTH+3)=*(dest+3*VIDEO_LINE_WIDTH+2)=*(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+3)=*(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=*src; + + // On passe au pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + src+=image_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; + } + Update_rect(x_pos,y_pos,width,height); +} + +// Affiche une brosse (arbitraire) à l'écran +void Display_brush_quad(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) +{ + // dest = Position à l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + // src = Position dans la brosse + byte* src = brush + y_offset * brush_width + x_offset; + + word x,y; + + // Pour chaque ligne + for(y = height;y > 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *(dest+3*VIDEO_LINE_WIDTH+3)=*(dest+3*VIDEO_LINE_WIDTH+2)=*(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+3)=*(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=*src; + } + + // Pixel suivant + src++; dest+=ZOOMX; + } + + // On passe à la ligne suivante + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + src = src + brush_width - width; + } +} + +void Remap_screen_quad(word x_pos,word y_pos,word width,word height,byte * conversion_table) +{ + // dest = coords a l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + int x,y; + + // Pour chaque ligne + for(y=height;y>0;y--) + { + // Pour chaque pixel + for(x=width;x>0;x--) + { + *(dest+3*VIDEO_LINE_WIDTH+3)=*(dest+3*VIDEO_LINE_WIDTH+2)=*(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+3)=*(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest= + conversion_table[*dest]; + dest +=ZOOMX; + } + + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + } + + Update_rect(x_pos,y_pos,width,height); +} + +void Display_line_on_screen_fast_quad(word x_pos,word y_pos,word width,byte * line) +/* On affiche toute une ligne de pixels telle quelle. */ +/* Utilisée si le buffer contient déja des pixel doublés. */ +{ + memcpy(Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH,line,width*ZOOMX); + memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+1)*VIDEO_LINE_WIDTH,line,width*ZOOMX); + memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+2)*VIDEO_LINE_WIDTH,line,width*ZOOMX); + memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+3)*VIDEO_LINE_WIDTH,line,width*ZOOMX); +} + +void Display_line_on_screen_quad(word x_pos,word y_pos,word width,byte * line) +/* On affiche une ligne de pixels en les doublant. */ +{ + int x; + byte *dest; + dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; + for(x=width;x>0;x--) + { + *(dest+3*VIDEO_LINE_WIDTH+3)=*(dest+3*VIDEO_LINE_WIDTH+2)=*(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+3)=*(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=*line; + dest+=ZOOMX; + line++; + } +} +void Display_transparent_mono_line_on_screen_quad( + word x_pos, word y_pos, word width, byte* line, + byte transp_color, byte color) +// Affiche une ligne à l'écran avec une couleur + transparence. +// Utilisé par les brosses en mode zoom +{ + byte* dest = Screen_pixels+ y_pos*VIDEO_LINE_WIDTH + x_pos*ZOOMX; + int x; + // Pour chaque pixel + for(x=0;x 0); + src += image_width; + } +// ATTENTION on n'arrive jamais ici ! +} + +// Affiche une partie de la brosse couleur zoomée +void Display_brush_color_zoom_quad(word x_pos,word y_pos, + word x_offset,word y_offset, + word width, // width non zoomée + word end_y_pos,byte transp_color, + word brush_width, // width réelle de la brosse + byte * buffer) +{ + byte* src = Brush+y_offset*brush_width + x_offset; + word y = y_pos; + byte bx; + + // Pour chaque ligne + while(1) + { + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + // On affiche facteur fois la ligne zoomée + for(bx=Main_magnifier_factor;bx>0;bx--) + { + byte* line_src = buffer; + byte* dest = Screen_pixels + y*ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + word x; + // Pour chaque pixel de la ligne + for(x = width*Main_magnifier_factor;x > 0;x--) + { + if(*line_src!=transp_color) + { + *(dest+3)=*(dest+2)=*(dest+1)=*dest = *line_src; + } + line_src++; + dest+=ZOOMX; + } + // Double the line + memcpy(Screen_pixels + (y*ZOOMY+1)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); + // Triple the line + memcpy(Screen_pixels + (y*ZOOMY+2)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); + // Quadruple it + memcpy(Screen_pixels + (y*ZOOMY+3)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); + y++; + if(y==end_y_pos) + { + return; + } + } + src += brush_width; + } + // ATTENTION zone jamais atteinte +} + +void Display_brush_mono_zoom_quad(word x_pos, word y_pos, + word x_offset, word y_offset, + word width, // width non zoomée + word end_y_pos, + byte transp_color, byte color, + word brush_width, // width réelle de la brosse + byte * buffer +) + +{ + byte* src = Brush + y_offset * brush_width + x_offset; + int y=y_pos*ZOOMY; + + //Pour chaque ligne à zoomer : + while(1) + { + int bx; + // src = Ligne originale + // On éclate la ligne + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + + // On affiche la ligne Facteur fois à l'écran (sur des + // lignes consécutives) + bx = Main_magnifier_factor*ZOOMY; + + // Pour chaque ligne écran + do + { + // On affiche la ligne zoomée + Display_transparent_mono_line_on_screen_quad( + x_pos, y, width * Main_magnifier_factor, + buffer, transp_color, color + ); + // On passe à la ligne suivante + y++; + // On vérifie qu'on est pas à la ligne finale + if(y == end_y_pos*ZOOMY) + { + Update_rect( x_pos, y_pos, + width * Main_magnifier_factor, end_y_pos - y_pos ); + return; + } + bx --; + } + while (bx > 0); + + // Passage à la ligne suivante dans la brosse aussi + src+=brush_width; + } +} + +void Clear_brush_scaled_quad(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) +{ + + // En fait on va recopier l'image non zoomée dans la partie zoomée ! + byte* src = Main_screen + y_offset * image_width + x_offset; + int y = y_pos; + int bx; + + // Pour chaque ligne à zoomer + while(1){ + Zoom_a_line(src,buffer,Main_magnifier_factor*ZOOMX,width); + + bx=Main_magnifier_factor; + + // Pour chaque ligne + do{ + // TODO a verifier + Display_line_on_screen_fast_quad(x_pos,y, + width * Main_magnifier_factor,buffer); + + // Ligne suivante + y++; + if(y==end_y_pos) + { + Update_rect(x_pos,y_pos, + width*Main_magnifier_factor,end_y_pos-y_pos); + return; + } + bx--; + }while(bx!=0); + + src+= image_width; + } +} + + diff --git a/pxquad.h b/pxquad.h index e5618472..66ed0713 100644 --- a/pxquad.h +++ b/pxquad.h @@ -1,48 +1,48 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file pxquad.h -/// Renderer for quadruple pixels (4x4). -////////////////////////////////////////////////////////////////////////////// - -#include "struct.h" - - void Pixel_quad (word x,word y,byte color); - byte Read_pixel_quad (word x,word y); - void Block_quad (word start_x,word start_y,word width,word height,byte color); - void Pixel_preview_normal_quad (word x,word y,byte color); - void Pixel_preview_magnifier_quad (word x,word y,byte color); - void Horizontal_XOR_line_quad (word x_pos,word y_pos,word width); - void Vertical_XOR_line_quad (word x_pos,word y_pos,word height); - void Display_brush_color_quad (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); - void Display_brush_mono_quad (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); - void Clear_brush_quad (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); - void Remap_screen_quad (word x_pos,word y_pos,word width,word height,byte * conversion_table); - void Display_part_of_screen_quad (word width,word height,word image_width); - void Display_line_on_screen_quad (word x_pos,word y_pos,word width,byte * line); - void Read_line_screen_quad (word x_pos,word y_pos,word width,byte * line); - void Display_part_of_screen_scaled_quad(word width,word height,word image_width,byte * buffer); - void Display_brush_color_zoom_quad (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); - void Display_brush_mono_zoom_quad (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); - void Clear_brush_scaled_quad (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); - void Display_brush_quad (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); - - void Display_line_on_screen_fast_quad (word x_pos,word y_pos,word width,byte * line); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file pxquad.h +/// Renderer for quadruple pixels (4x4). +////////////////////////////////////////////////////////////////////////////// + +#include "struct.h" + + void Pixel_quad (word x,word y,byte color); + byte Read_pixel_quad (word x,word y); + void Block_quad (word start_x,word start_y,word width,word height,byte color); + void Pixel_preview_normal_quad (word x,word y,byte color); + void Pixel_preview_magnifier_quad (word x,word y,byte color); + void Horizontal_XOR_line_quad (word x_pos,word y_pos,word width); + void Vertical_XOR_line_quad (word x_pos,word y_pos,word height); + void Display_brush_color_quad (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); + void Display_brush_mono_quad (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); + void Clear_brush_quad (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); + void Remap_screen_quad (word x_pos,word y_pos,word width,word height,byte * conversion_table); + void Display_part_of_screen_quad (word width,word height,word image_width); + void Display_line_on_screen_quad (word x_pos,word y_pos,word width,byte * line); + void Read_line_screen_quad (word x_pos,word y_pos,word width,byte * line); + void Display_part_of_screen_scaled_quad(word width,word height,word image_width,byte * buffer); + void Display_brush_color_zoom_quad (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); + void Display_brush_mono_zoom_quad (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); + void Clear_brush_scaled_quad (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); + void Display_brush_quad (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); + + void Display_line_on_screen_fast_quad (word x_pos,word y_pos,word width,byte * line); diff --git a/pxsimple.c b/pxsimple.c index c18020f0..35650b6f 100644 --- a/pxsimple.c +++ b/pxsimple.c @@ -1,470 +1,470 @@ -/* 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 -*/ - -#include -#include -#include -#include "global.h" -#include "sdlscreen.h" -#include "misc.h" -#include "pxsimple.h" - -void Pixel_simple (word x,word y,byte color) -/* Affiche un pixel de la color aux coords x;y à l'écran */ -{ - *(Screen_pixels + x + y * VIDEO_LINE_WIDTH)=color; -} - -byte Read_pixel_simple (word x,word y) -/* On retourne la couleur du pixel aux coords données */ -{ - return *( Screen_pixels + y * VIDEO_LINE_WIDTH + x ); -} - -void Block_simple (word start_x,word start_y,word width,word height,byte color) -/* On affiche un rectangle de la couleur donnée */ -{ - SDL_Rect rectangle; - rectangle.x=start_x; - rectangle.y=start_y; - rectangle.w=width; - rectangle.h=height; - SDL_FillRect(Screen_SDL,&rectangle,color); -} - -void Display_part_of_screen_simple (word width,word height,word image_width) -/* Afficher une partie de l'image telle quelle sur l'écran */ -{ - byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) - byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) - int y; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - // On fait une copie de la ligne - memcpy(dest,src,width); - - // On passe à la ligne suivante - src+=image_width; - dest+=VIDEO_LINE_WIDTH; - } - //Update_rect(0,0,width,height); -} - -void Pixel_preview_normal_simple (word x,word y,byte color) -/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image - * dans l'écran, en mode normal (pas en mode loupe) - * Note: si on modifie cette procédure, il faudra penser à faire également - * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ -{ -// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) - Pixel_simple(x-Main_offset_X,y-Main_offset_Y,color); -} - -void Pixel_preview_magnifier_simple (word x,word y,byte color) -{ - // Affiche le pixel dans la partie non zoomée - Pixel_simple(x-Main_offset_X,y-Main_offset_Y,color); - - // Regarde si on doit aussi l'afficher dans la partie zoomée - if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom - && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) - { - // On est dedans - int height; - int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); - - if (Menu_Y - y_zoom < Main_magnifier_factor) - // On ne doit dessiner qu'un morceau du pixel - // sinon on dépasse sur le menu - height = Menu_Y - y_zoom; - else - height = Main_magnifier_factor; - - Block_simple( - Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, - y_zoom, Main_magnifier_factor, height, color - ); - } -} - -void Horizontal_XOR_line_simple(word x_pos,word y_pos,word width) -{ - //On calcule la valeur initiale de dest: - byte* dest=y_pos*VIDEO_LINE_WIDTH+x_pos+Screen_pixels; - - int x; - - for (x=0;x 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *dest = *src; - } - - // Pixel suivant - src++; dest++; - } - - // On passe à la ligne suivante - dest = dest + VIDEO_LINE_WIDTH - width; - src = src + brush_width - width; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Display_brush_mono_simple(word x_pos, word y_pos, - word x_offset, word y_offset, word width, word height, - byte transp_color, byte color, word brush_width) -/* On affiche la brosse en monochrome */ -{ - byte* dest=y_pos*VIDEO_LINE_WIDTH+x_pos+Screen_pixels; // dest = adr Destination à - // l'écran - byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds - // la brosse - int x,y; - - for(y=height;y!=0;y--) - //Pour chaque ligne - { - for(x=width;x!=0;x--) - //Pour chaque pixel - { - if (*src!=transp_color) - *dest=color; - - // On passe au pixel suivant - src++; - dest++; - } - - // On passe à la ligne suivante - src+=brush_width-width; - dest+=VIDEO_LINE_WIDTH-width; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Clear_brush_simple(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) -{ - byte* dest=Screen_pixels+x_pos+y_pos*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) - byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) - int y; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - // On fait une copie de la ligne - memcpy(dest,src,width); - - // On passe à la ligne suivante - src+=image_width; - dest+=VIDEO_LINE_WIDTH; - } - Update_rect(x_pos,y_pos,width,height); -} - -// Affiche une brosse (arbitraire) à l'écran -void Display_brush_simple(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) -{ - // dest = Position à l'écran - byte* dest = Screen_pixels + y_pos * VIDEO_LINE_WIDTH + x_pos; - // src = Position dans la brosse - byte* src = brush + y_offset * brush_width + x_offset; - - word x,y; - - // Pour chaque ligne - for(y = height;y > 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *dest = *src; - } - - // Pixel suivant - src++; dest++; - } - - // On passe à la ligne suivante - dest = dest + VIDEO_LINE_WIDTH - width; - src = src + brush_width - width; - } -} - -void Remap_screen_simple(word x_pos,word y_pos,word width,word height,byte * conversion_table) -{ - // dest = coords a l'écran - byte* dest = Screen_pixels + y_pos * VIDEO_LINE_WIDTH + x_pos; - int x,y; - - // Pour chaque ligne - for(y=height;y>0;y--) - { - // Pour chaque pixel - for(x=width;x>0;x--) - { - *dest = conversion_table[*dest]; - dest ++; - } - - dest = dest + VIDEO_LINE_WIDTH - width; - } - - Update_rect(x_pos,y_pos,width,height); -} - -void Display_line_on_screen_simple(word x_pos,word y_pos,word width,byte * line) -/* On affiche toute une ligne de pixels. Utilisé pour les textes. */ -{ - memcpy(Screen_pixels+x_pos+y_pos*VIDEO_LINE_WIDTH,line,width); -} - -void Display_transparent_mono_line_on_screen_simple( - word x_pos, word y_pos, word width, byte* line, - byte transp_color, byte color) -// Affiche une ligne à l'écran avec une couleur + transparence. -// Utilisé par les brosses en mode zoom -{ - byte* dest = Screen_pixels+ y_pos * VIDEO_LINE_WIDTH + x_pos; - int x; - // Pour chaque pixel - for(x=0;x 0); - src += image_width; - } -// ATTENTION on n'arrive jamais ici ! -} - -void Display_transparent_line_on_screen_simple(word x_pos,word y_pos,word width,byte* line,byte transp_color) -{ - byte* src = line; - byte* dest = Screen_pixels + y_pos * VIDEO_LINE_WIDTH + x_pos; - - word x; - - // Pour chaque pixel de la ligne - for(x = width;x > 0;x--) - { - if(*src!=transp_color) - *dest = *src; - src++; - dest++; - } -} - -// Affiche une partie de la brosse couleur zoomée -void Display_brush_color_zoom_simple(word x_pos,word y_pos, - word x_offset,word y_offset, - word width, // width non zoomée - word end_y_pos,byte transp_color, - word brush_width, // width réelle de la brosse - byte * buffer) -{ - byte* src = Brush+y_offset*brush_width + x_offset; - word y = y_pos; - byte bx; - - // Pour chaque ligne - while(1) - { - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - // On affiche facteur fois la ligne zoomée - for(bx=Main_magnifier_factor;bx>0;bx--) - { - Display_transparent_line_on_screen_simple(x_pos,y,width*Main_magnifier_factor,buffer,transp_color); - y++; - if(y==end_y_pos) - { - return; - } - } - src += brush_width; - } - // ATTENTION zone jamais atteinte -} - -void Display_brush_mono_zoom_simple(word x_pos, word y_pos, - word x_offset, word y_offset, - word width, // width non zoomée - word end_y_pos, - byte transp_color, byte color, - word brush_width, // width réelle de la brosse - byte * buffer -) - -{ - byte* src = Brush + y_offset * brush_width + x_offset; - int y=y_pos; - - //Pour chaque ligne à zoomer : - while(1) - { - int bx; - // src = Ligne originale - // On éclate la ligne - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - - // On affiche la ligne Facteur fois à l'écran (sur des - // lignes consécutives) - bx = Main_magnifier_factor; - - // Pour chaque ligne écran - do - { - // On affiche la ligne zoomée - Display_transparent_mono_line_on_screen_simple( - x_pos, y, width * Main_magnifier_factor, - buffer, transp_color, color - ); - // On passe à la ligne suivante - y++; - // On vérifie qu'on est pas à la ligne finale - if(y == end_y_pos) - { - Update_rect( x_pos, y_pos, - width * Main_magnifier_factor, end_y_pos - y_pos ); - return; - } - bx --; - } - while (bx > 0); - - // Passage à la ligne suivante dans la brosse aussi - src+=brush_width; - } -} - -void Clear_brush_scaled_simple(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) -{ - // En fait on va recopier l'image non zoomée dans la partie zoomée ! - byte* src = Main_screen + y_offset * image_width + x_offset; - int y = y_pos; - int bx; - - // Pour chaque ligne à zoomer - while(1){ - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - - bx=Main_magnifier_factor; - - // Pour chaque ligne - do{ - Display_line_on_screen_simple(x_pos,y, - width * Main_magnifier_factor,buffer); - - // Ligne suivante - y++; - if(y==end_y_pos) - { - Update_rect(x_pos,y_pos, - width*Main_magnifier_factor,end_y_pos-y_pos); - return; - } - bx--; - }while(bx!=0); - - src+= image_width; - } -} - - +/* 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 +*/ + +#include +#include +#include +#include "global.h" +#include "sdlscreen.h" +#include "misc.h" +#include "pxsimple.h" + +void Pixel_simple (word x,word y,byte color) +/* Affiche un pixel de la color aux coords x;y à l'écran */ +{ + *(Screen_pixels + x + y * VIDEO_LINE_WIDTH)=color; +} + +byte Read_pixel_simple (word x,word y) +/* On retourne la couleur du pixel aux coords données */ +{ + return *( Screen_pixels + y * VIDEO_LINE_WIDTH + x ); +} + +void Block_simple (word start_x,word start_y,word width,word height,byte color) +/* On affiche un rectangle de la couleur donnée */ +{ + SDL_Rect rectangle; + rectangle.x=start_x; + rectangle.y=start_y; + rectangle.w=width; + rectangle.h=height; + SDL_FillRect(Screen_SDL,&rectangle,color); +} + +void Display_part_of_screen_simple (word width,word height,word image_width) +/* Afficher une partie de l'image telle quelle sur l'écran */ +{ + byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) + byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) + int y; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + // On fait une copie de la ligne + memcpy(dest,src,width); + + // On passe à la ligne suivante + src+=image_width; + dest+=VIDEO_LINE_WIDTH; + } + //Update_rect(0,0,width,height); +} + +void Pixel_preview_normal_simple (word x,word y,byte color) +/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image + * dans l'écran, en mode normal (pas en mode loupe) + * Note: si on modifie cette procédure, il faudra penser à faire également + * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ +{ +// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) + Pixel_simple(x-Main_offset_X,y-Main_offset_Y,color); +} + +void Pixel_preview_magnifier_simple (word x,word y,byte color) +{ + // Affiche le pixel dans la partie non zoomée + Pixel_simple(x-Main_offset_X,y-Main_offset_Y,color); + + // Regarde si on doit aussi l'afficher dans la partie zoomée + if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom + && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) + { + // On est dedans + int height; + int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); + + if (Menu_Y - y_zoom < Main_magnifier_factor) + // On ne doit dessiner qu'un morceau du pixel + // sinon on dépasse sur le menu + height = Menu_Y - y_zoom; + else + height = Main_magnifier_factor; + + Block_simple( + Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, + y_zoom, Main_magnifier_factor, height, color + ); + } +} + +void Horizontal_XOR_line_simple(word x_pos,word y_pos,word width) +{ + //On calcule la valeur initiale de dest: + byte* dest=y_pos*VIDEO_LINE_WIDTH+x_pos+Screen_pixels; + + int x; + + for (x=0;x 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *dest = *src; + } + + // Pixel suivant + src++; dest++; + } + + // On passe à la ligne suivante + dest = dest + VIDEO_LINE_WIDTH - width; + src = src + brush_width - width; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Display_brush_mono_simple(word x_pos, word y_pos, + word x_offset, word y_offset, word width, word height, + byte transp_color, byte color, word brush_width) +/* On affiche la brosse en monochrome */ +{ + byte* dest=y_pos*VIDEO_LINE_WIDTH+x_pos+Screen_pixels; // dest = adr Destination à + // l'écran + byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds + // la brosse + int x,y; + + for(y=height;y!=0;y--) + //Pour chaque ligne + { + for(x=width;x!=0;x--) + //Pour chaque pixel + { + if (*src!=transp_color) + *dest=color; + + // On passe au pixel suivant + src++; + dest++; + } + + // On passe à la ligne suivante + src+=brush_width-width; + dest+=VIDEO_LINE_WIDTH-width; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Clear_brush_simple(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) +{ + byte* dest=Screen_pixels+x_pos+y_pos*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) + byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) + int y; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + // On fait une copie de la ligne + memcpy(dest,src,width); + + // On passe à la ligne suivante + src+=image_width; + dest+=VIDEO_LINE_WIDTH; + } + Update_rect(x_pos,y_pos,width,height); +} + +// Affiche une brosse (arbitraire) à l'écran +void Display_brush_simple(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) +{ + // dest = Position à l'écran + byte* dest = Screen_pixels + y_pos * VIDEO_LINE_WIDTH + x_pos; + // src = Position dans la brosse + byte* src = brush + y_offset * brush_width + x_offset; + + word x,y; + + // Pour chaque ligne + for(y = height;y > 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *dest = *src; + } + + // Pixel suivant + src++; dest++; + } + + // On passe à la ligne suivante + dest = dest + VIDEO_LINE_WIDTH - width; + src = src + brush_width - width; + } +} + +void Remap_screen_simple(word x_pos,word y_pos,word width,word height,byte * conversion_table) +{ + // dest = coords a l'écran + byte* dest = Screen_pixels + y_pos * VIDEO_LINE_WIDTH + x_pos; + int x,y; + + // Pour chaque ligne + for(y=height;y>0;y--) + { + // Pour chaque pixel + for(x=width;x>0;x--) + { + *dest = conversion_table[*dest]; + dest ++; + } + + dest = dest + VIDEO_LINE_WIDTH - width; + } + + Update_rect(x_pos,y_pos,width,height); +} + +void Display_line_on_screen_simple(word x_pos,word y_pos,word width,byte * line) +/* On affiche toute une ligne de pixels. Utilisé pour les textes. */ +{ + memcpy(Screen_pixels+x_pos+y_pos*VIDEO_LINE_WIDTH,line,width); +} + +void Display_transparent_mono_line_on_screen_simple( + word x_pos, word y_pos, word width, byte* line, + byte transp_color, byte color) +// Affiche une ligne à l'écran avec une couleur + transparence. +// Utilisé par les brosses en mode zoom +{ + byte* dest = Screen_pixels+ y_pos * VIDEO_LINE_WIDTH + x_pos; + int x; + // Pour chaque pixel + for(x=0;x 0); + src += image_width; + } +// ATTENTION on n'arrive jamais ici ! +} + +void Display_transparent_line_on_screen_simple(word x_pos,word y_pos,word width,byte* line,byte transp_color) +{ + byte* src = line; + byte* dest = Screen_pixels + y_pos * VIDEO_LINE_WIDTH + x_pos; + + word x; + + // Pour chaque pixel de la ligne + for(x = width;x > 0;x--) + { + if(*src!=transp_color) + *dest = *src; + src++; + dest++; + } +} + +// Affiche une partie de la brosse couleur zoomée +void Display_brush_color_zoom_simple(word x_pos,word y_pos, + word x_offset,word y_offset, + word width, // width non zoomée + word end_y_pos,byte transp_color, + word brush_width, // width réelle de la brosse + byte * buffer) +{ + byte* src = Brush+y_offset*brush_width + x_offset; + word y = y_pos; + byte bx; + + // Pour chaque ligne + while(1) + { + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + // On affiche facteur fois la ligne zoomée + for(bx=Main_magnifier_factor;bx>0;bx--) + { + Display_transparent_line_on_screen_simple(x_pos,y,width*Main_magnifier_factor,buffer,transp_color); + y++; + if(y==end_y_pos) + { + return; + } + } + src += brush_width; + } + // ATTENTION zone jamais atteinte +} + +void Display_brush_mono_zoom_simple(word x_pos, word y_pos, + word x_offset, word y_offset, + word width, // width non zoomée + word end_y_pos, + byte transp_color, byte color, + word brush_width, // width réelle de la brosse + byte * buffer +) + +{ + byte* src = Brush + y_offset * brush_width + x_offset; + int y=y_pos; + + //Pour chaque ligne à zoomer : + while(1) + { + int bx; + // src = Ligne originale + // On éclate la ligne + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + + // On affiche la ligne Facteur fois à l'écran (sur des + // lignes consécutives) + bx = Main_magnifier_factor; + + // Pour chaque ligne écran + do + { + // On affiche la ligne zoomée + Display_transparent_mono_line_on_screen_simple( + x_pos, y, width * Main_magnifier_factor, + buffer, transp_color, color + ); + // On passe à la ligne suivante + y++; + // On vérifie qu'on est pas à la ligne finale + if(y == end_y_pos) + { + Update_rect( x_pos, y_pos, + width * Main_magnifier_factor, end_y_pos - y_pos ); + return; + } + bx --; + } + while (bx > 0); + + // Passage à la ligne suivante dans la brosse aussi + src+=brush_width; + } +} + +void Clear_brush_scaled_simple(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) +{ + // En fait on va recopier l'image non zoomée dans la partie zoomée ! + byte* src = Main_screen + y_offset * image_width + x_offset; + int y = y_pos; + int bx; + + // Pour chaque ligne à zoomer + while(1){ + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + + bx=Main_magnifier_factor; + + // Pour chaque ligne + do{ + Display_line_on_screen_simple(x_pos,y, + width * Main_magnifier_factor,buffer); + + // Ligne suivante + y++; + if(y==end_y_pos) + { + Update_rect(x_pos,y_pos, + width*Main_magnifier_factor,end_y_pos-y_pos); + return; + } + bx--; + }while(bx!=0); + + src+= image_width; + } +} + + diff --git a/pxsimple.h b/pxsimple.h index 2bca1cb9..785a96a5 100644 --- a/pxsimple.h +++ b/pxsimple.h @@ -1,51 +1,51 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file pxsimple.h -/// Renderer for simple pixels (1x1). This is the normal one. -////////////////////////////////////////////////////////////////////////////// - -#include "struct.h" - - void Pixel_simple (word x,word y,byte color); - byte Read_pixel_simple (word x,word y); - void Block_simple (word start_x,word start_y,word width,word height,byte color); - void Pixel_preview_normal_simple (word x,word y,byte color); - void Pixel_preview_magnifier_simple (word x,word y,byte color); - void Horizontal_XOR_line_simple (word x_pos,word y_pos,word width); - void Vertical_XOR_line_simple (word x_pos,word y_pos,word height); - void Display_brush_color_simple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); - void Display_brush_mono_simple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); - void Clear_brush_simple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); - void Remap_screen_simple (word x_pos,word y_pos,word width,word height,byte * conversion_table); - void Display_part_of_screen_simple (word width,word height,word image_width); - void Display_line_on_screen_simple (word x_pos,word y_pos,word width,byte * line); - void Read_line_screen_simple (word x_pos,word y_pos,word width,byte * line); - void Display_part_of_screen_scaled_simple(word width,word height,word image_width,byte * buffer); - void Display_brush_color_zoom_simple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); - void Display_brush_mono_zoom_simple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); - void Clear_brush_scaled_simple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); - void Display_brush_simple (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); - -void Display_transparent_mono_line_on_screen_simple( - word x_pos, word y_pos, word width, byte* line, - byte transp_color, byte color); -void Display_transparent_line_on_screen_simple(word x_pos,word y_pos,word width,byte* line,byte transp_color); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file pxsimple.h +/// Renderer for simple pixels (1x1). This is the normal one. +////////////////////////////////////////////////////////////////////////////// + +#include "struct.h" + + void Pixel_simple (word x,word y,byte color); + byte Read_pixel_simple (word x,word y); + void Block_simple (word start_x,word start_y,word width,word height,byte color); + void Pixel_preview_normal_simple (word x,word y,byte color); + void Pixel_preview_magnifier_simple (word x,word y,byte color); + void Horizontal_XOR_line_simple (word x_pos,word y_pos,word width); + void Vertical_XOR_line_simple (word x_pos,word y_pos,word height); + void Display_brush_color_simple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); + void Display_brush_mono_simple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); + void Clear_brush_simple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); + void Remap_screen_simple (word x_pos,word y_pos,word width,word height,byte * conversion_table); + void Display_part_of_screen_simple (word width,word height,word image_width); + void Display_line_on_screen_simple (word x_pos,word y_pos,word width,byte * line); + void Read_line_screen_simple (word x_pos,word y_pos,word width,byte * line); + void Display_part_of_screen_scaled_simple(word width,word height,word image_width,byte * buffer); + void Display_brush_color_zoom_simple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); + void Display_brush_mono_zoom_simple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); + void Clear_brush_scaled_simple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); + void Display_brush_simple (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); + +void Display_transparent_mono_line_on_screen_simple( + word x_pos, word y_pos, word width, byte* line, + byte transp_color, byte color); +void Display_transparent_line_on_screen_simple(word x_pos,word y_pos,word width,byte* line,byte transp_color); diff --git a/pxtall.c b/pxtall.c index 8e4c326e..d7e30162 100644 --- a/pxtall.c +++ b/pxtall.c @@ -1,453 +1,453 @@ -/* 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 -*/ - -#include -#include -#include -#include "global.h" -#include "sdlscreen.h" -#include "misc.h" -#include "pxtall.h" -#include "pxsimple.h" - -#define ZOOMX 1 -#define ZOOMY 2 - -void Pixel_tall (word x,word y,byte color) -/* Affiche un pixel de la color aux coords x;y à l'écran */ -{ - *(Screen_pixels + x + y*ZOOMY*VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x + (y*ZOOMY+1)*VIDEO_LINE_WIDTH)=color; -} - -byte Read_pixel_tall (word x,word y) -/* On retourne la couleur du pixel aux coords données */ -{ - return *( Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x ); -} - -void Block_tall (word start_x,word start_y,word width,word height,byte color) -/* On affiche un rectangle de la couleur donnée */ -{ - SDL_Rect rectangle; - rectangle.x=start_x; - rectangle.y=start_y*ZOOMY; - rectangle.w=width; - rectangle.h=height*ZOOMY; - SDL_FillRect(Screen_SDL,&rectangle,color); -} - -void Display_part_of_screen_tall (word width,word height,word image_width) -/* Afficher une partie de l'image telle quelle sur l'écran */ -{ - byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) - byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) - int y; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - // On fait une copie de la ligne - memcpy(dest,src,width); - dest+=VIDEO_LINE_WIDTH; - memcpy(dest,src,width); - - // On passe à la ligne suivante - src+=image_width; - dest+=VIDEO_LINE_WIDTH; - } - //Update_rect(0,0,width,height); -} - -void Pixel_preview_normal_tall (word x,word y,byte color) -/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image - * dans l'écran, en mode normal (pas en mode loupe) - * Note: si on modifie cette procédure, il faudra penser à faire également - * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ -{ -// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) - Pixel_tall(x-Main_offset_X,y-Main_offset_Y,color); -} - -void Pixel_preview_magnifier_tall (word x,word y,byte color) -{ - // Affiche le pixel dans la partie non zoomée - Pixel_tall(x-Main_offset_X,y-Main_offset_Y,color); - - // Regarde si on doit aussi l'afficher dans la partie zoomée - if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom - && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) - { - // On est dedans - int height; - int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); - - if (Menu_Y - y_zoom < Main_magnifier_factor) - // On ne doit dessiner qu'un morceau du pixel - // sinon on dépasse sur le menu - height = Menu_Y - y_zoom; - else - height = Main_magnifier_factor; - - Block_tall( - Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, - y_zoom, Main_magnifier_factor, height, color - ); - } -} - -void Horizontal_XOR_line_tall(word x_pos,word y_pos,word width) -{ - //On calcule la valeur initiale de dest: - byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos+Screen_pixels; - - int x; - - for (x=0;x 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *dest = *src; - *(dest+VIDEO_LINE_WIDTH) = *src; - } - - // Pixel suivant - src++; dest++; - } - - // On passe à la ligne suivante - dest = dest + ZOOMY*VIDEO_LINE_WIDTH - width; - src = src + brush_width - width; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Display_brush_mono_tall(word x_pos, word y_pos, - word x_offset, word y_offset, word width, word height, - byte transp_color, byte color, word brush_width) -/* On affiche la brosse en monochrome */ -{ - byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos+Screen_pixels; // dest = adr Destination à - // l'écran - byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds - // la brosse - int x,y; - - for(y=height;y!=0;y--) - //Pour chaque ligne - { - for(x=width;x!=0;x--) - //Pour chaque pixel - { - if (*src!=transp_color) - { - *dest=color; - *(dest+VIDEO_LINE_WIDTH)=color; - } - - // On passe au pixel suivant - src++; - dest++; - } - - // On passe à la ligne suivante - src+=brush_width-width; - dest+=ZOOMY*VIDEO_LINE_WIDTH-width; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Clear_brush_tall(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) -{ - byte* dest=Screen_pixels+x_pos+y_pos*ZOOMY*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) - byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) - int y; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - // On fait une copie de la ligne - memcpy(dest,src,width); - dest+=VIDEO_LINE_WIDTH; - memcpy(dest,src,width); - - // On passe à la ligne suivante - src+=image_width; - dest+=VIDEO_LINE_WIDTH; - } - Update_rect(x_pos,y_pos,width,height); -} - -// Affiche une brosse (arbitraire) à l'écran -void Display_brush_tall(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) -{ - // dest = Position à l'écran - byte* dest = Screen_pixels + y_pos*ZOOMY*VIDEO_LINE_WIDTH + x_pos; - // src = Position dans la brosse - byte* src = brush + y_offset * brush_width + x_offset; - - word x,y; - - // Pour chaque ligne - for(y = height;y > 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *dest = *src; - *(dest+VIDEO_LINE_WIDTH) = *src; - } - - // Pixel suivant - src++; dest++; - } - - // On passe à la ligne suivante - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width; - src = src + brush_width - width; - } -} - -void Remap_screen_tall(word x_pos,word y_pos,word width,word height,byte * conversion_table) -{ - // dest = coords a l'écran - byte* dest = Screen_pixels + y_pos*ZOOMY*VIDEO_LINE_WIDTH + x_pos; - int x,y; - - // Pour chaque ligne - for(y=height*ZOOMY;y>0;y--) - { - // Pour chaque pixel - for(x=width;x>0;x--) - { - *dest = conversion_table[*dest]; - dest ++; - } - - dest = dest + VIDEO_LINE_WIDTH - width; - } - - Update_rect(x_pos,y_pos,width,height); -} - -void Display_line_on_screen_tall(word x_pos,word y_pos,word width,byte * line) -/* On affiche toute une ligne de pixels. Utilisé pour les textes. */ -{ - memcpy(Screen_pixels+x_pos+y_pos*ZOOMY*VIDEO_LINE_WIDTH,line,width); - memcpy(Screen_pixels+x_pos+(y_pos*ZOOMY+1)*VIDEO_LINE_WIDTH,line,width); -} - -void Read_line_screen_tall(word x_pos,word y_pos,word width,byte * line) -{ - memcpy(line,VIDEO_LINE_WIDTH*ZOOMY*y_pos + x_pos + Screen_pixels,width); -} - -void Display_part_of_screen_scaled_tall( - word width, // width non zoomée - word height, // height zoomée - word image_width,byte * buffer) -{ - byte* src = Main_screen + Main_magnifier_offset_Y * image_width - + Main_magnifier_offset_X; - int y = 0; // Ligne en cours de traitement - - // Pour chaque ligne à zoomer - while(1) - { - int x; - - // On éclate la ligne - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - // On l'affiche Facteur fois, sur des lignes consécutives - x = Main_magnifier_factor*ZOOMY; - // Pour chaque ligne - do{ - // On affiche la ligne zoomée - Display_line_on_screen_simple( - Main_X_zoom, y, width*Main_magnifier_factor, - buffer - ); - // On passe à la suivante - y++; - if(y==height*ZOOMY) - { - Update_rect(Main_X_zoom,0, - width*Main_magnifier_factor,height); - return; - } - x--; - }while (x > 0); - src += image_width; - } -// ATTENTION on n'arrive jamais ici ! -} - -// Affiche une partie de la brosse couleur zoomée -void Display_brush_color_zoom_tall(word x_pos,word y_pos, - word x_offset,word y_offset, - word width, // width non zoomée - word end_y_pos,byte transp_color, - word brush_width, // width réelle de la brosse - byte * buffer) -{ - byte* src = Brush+y_offset*brush_width + x_offset; - word y = y_pos; - byte bx; - - // Pour chaque ligne - while(1) - { - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - // On affiche facteur fois la ligne zoomée - for(bx=Main_magnifier_factor;bx>0;bx--) - { - Display_transparent_line_on_screen_simple(x_pos,y*ZOOMY,width*Main_magnifier_factor,buffer,transp_color); - memcpy(Screen_pixels + (y*ZOOMY +1) * VIDEO_LINE_WIDTH + x_pos, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos, width*Main_magnifier_factor); - y++; - if(y==end_y_pos) - { - return; - } - } - src += brush_width; - } - // ATTENTION zone jamais atteinte -} - -void Display_brush_mono_zoom_tall(word x_pos, word y_pos, - word x_offset, word y_offset, - word width, // width non zoomée - word end_y_pos, - byte transp_color, byte color, - word brush_width, // width réelle de la brosse - byte * buffer -) - -{ - byte* src = Brush + y_offset * brush_width + x_offset; - int y=y_pos*ZOOMY; - - //Pour chaque ligne à zoomer : - while(1) - { - int bx; - // src = Ligne originale - // On éclate la ligne - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - - // On affiche la ligne Facteur fois à l'écran (sur des - // lignes consécutives) - bx = Main_magnifier_factor*ZOOMY; - - // Pour chaque ligne écran - do - { - // On affiche la ligne zoomée - Display_transparent_mono_line_on_screen_simple( - x_pos, y, width * Main_magnifier_factor, - buffer, transp_color, color - ); - // On passe à la ligne suivante - y++; - // On vérifie qu'on est pas à la ligne finale - if(y == end_y_pos*ZOOMY) - { - Update_rect( x_pos, y_pos, - width * Main_magnifier_factor, end_y_pos - y_pos ); - return; - } - bx --; - } - while (bx > 0); - - // Passage à la ligne suivante dans la brosse aussi - src+=brush_width; - } -} - -void Clear_brush_scaled_tall(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) -{ - // En fait on va recopier l'image non zoomée dans la partie zoomée ! - byte* src = Main_screen + y_offset * image_width + x_offset; - int y = y_pos; - int bx; - - // Pour chaque ligne à zoomer - while(1){ - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - - bx=Main_magnifier_factor; - - // Pour chaque ligne - do{ - Display_line_on_screen_tall(x_pos,y, - width * Main_magnifier_factor,buffer); - - // Ligne suivante - y++; - if(y==end_y_pos) - { - Update_rect(x_pos,y_pos, - width*Main_magnifier_factor,end_y_pos-y_pos); - return; - } - bx--; - }while(bx!=0); - - src+= image_width; - } -} +/* 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 +*/ + +#include +#include +#include +#include "global.h" +#include "sdlscreen.h" +#include "misc.h" +#include "pxtall.h" +#include "pxsimple.h" + +#define ZOOMX 1 +#define ZOOMY 2 + +void Pixel_tall (word x,word y,byte color) +/* Affiche un pixel de la color aux coords x;y à l'écran */ +{ + *(Screen_pixels + x + y*ZOOMY*VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x + (y*ZOOMY+1)*VIDEO_LINE_WIDTH)=color; +} + +byte Read_pixel_tall (word x,word y) +/* On retourne la couleur du pixel aux coords données */ +{ + return *( Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x ); +} + +void Block_tall (word start_x,word start_y,word width,word height,byte color) +/* On affiche un rectangle de la couleur donnée */ +{ + SDL_Rect rectangle; + rectangle.x=start_x; + rectangle.y=start_y*ZOOMY; + rectangle.w=width; + rectangle.h=height*ZOOMY; + SDL_FillRect(Screen_SDL,&rectangle,color); +} + +void Display_part_of_screen_tall (word width,word height,word image_width) +/* Afficher une partie de l'image telle quelle sur l'écran */ +{ + byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) + byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) + int y; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + // On fait une copie de la ligne + memcpy(dest,src,width); + dest+=VIDEO_LINE_WIDTH; + memcpy(dest,src,width); + + // On passe à la ligne suivante + src+=image_width; + dest+=VIDEO_LINE_WIDTH; + } + //Update_rect(0,0,width,height); +} + +void Pixel_preview_normal_tall (word x,word y,byte color) +/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image + * dans l'écran, en mode normal (pas en mode loupe) + * Note: si on modifie cette procédure, il faudra penser à faire également + * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ +{ +// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) + Pixel_tall(x-Main_offset_X,y-Main_offset_Y,color); +} + +void Pixel_preview_magnifier_tall (word x,word y,byte color) +{ + // Affiche le pixel dans la partie non zoomée + Pixel_tall(x-Main_offset_X,y-Main_offset_Y,color); + + // Regarde si on doit aussi l'afficher dans la partie zoomée + if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom + && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) + { + // On est dedans + int height; + int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); + + if (Menu_Y - y_zoom < Main_magnifier_factor) + // On ne doit dessiner qu'un morceau du pixel + // sinon on dépasse sur le menu + height = Menu_Y - y_zoom; + else + height = Main_magnifier_factor; + + Block_tall( + Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, + y_zoom, Main_magnifier_factor, height, color + ); + } +} + +void Horizontal_XOR_line_tall(word x_pos,word y_pos,word width) +{ + //On calcule la valeur initiale de dest: + byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos+Screen_pixels; + + int x; + + for (x=0;x 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *dest = *src; + *(dest+VIDEO_LINE_WIDTH) = *src; + } + + // Pixel suivant + src++; dest++; + } + + // On passe à la ligne suivante + dest = dest + ZOOMY*VIDEO_LINE_WIDTH - width; + src = src + brush_width - width; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Display_brush_mono_tall(word x_pos, word y_pos, + word x_offset, word y_offset, word width, word height, + byte transp_color, byte color, word brush_width) +/* On affiche la brosse en monochrome */ +{ + byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos+Screen_pixels; // dest = adr Destination à + // l'écran + byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds + // la brosse + int x,y; + + for(y=height;y!=0;y--) + //Pour chaque ligne + { + for(x=width;x!=0;x--) + //Pour chaque pixel + { + if (*src!=transp_color) + { + *dest=color; + *(dest+VIDEO_LINE_WIDTH)=color; + } + + // On passe au pixel suivant + src++; + dest++; + } + + // On passe à la ligne suivante + src+=brush_width-width; + dest+=ZOOMY*VIDEO_LINE_WIDTH-width; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Clear_brush_tall(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) +{ + byte* dest=Screen_pixels+x_pos+y_pos*ZOOMY*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) + byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) + int y; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + // On fait une copie de la ligne + memcpy(dest,src,width); + dest+=VIDEO_LINE_WIDTH; + memcpy(dest,src,width); + + // On passe à la ligne suivante + src+=image_width; + dest+=VIDEO_LINE_WIDTH; + } + Update_rect(x_pos,y_pos,width,height); +} + +// Affiche une brosse (arbitraire) à l'écran +void Display_brush_tall(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) +{ + // dest = Position à l'écran + byte* dest = Screen_pixels + y_pos*ZOOMY*VIDEO_LINE_WIDTH + x_pos; + // src = Position dans la brosse + byte* src = brush + y_offset * brush_width + x_offset; + + word x,y; + + // Pour chaque ligne + for(y = height;y > 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *dest = *src; + *(dest+VIDEO_LINE_WIDTH) = *src; + } + + // Pixel suivant + src++; dest++; + } + + // On passe à la ligne suivante + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width; + src = src + brush_width - width; + } +} + +void Remap_screen_tall(word x_pos,word y_pos,word width,word height,byte * conversion_table) +{ + // dest = coords a l'écran + byte* dest = Screen_pixels + y_pos*ZOOMY*VIDEO_LINE_WIDTH + x_pos; + int x,y; + + // Pour chaque ligne + for(y=height*ZOOMY;y>0;y--) + { + // Pour chaque pixel + for(x=width;x>0;x--) + { + *dest = conversion_table[*dest]; + dest ++; + } + + dest = dest + VIDEO_LINE_WIDTH - width; + } + + Update_rect(x_pos,y_pos,width,height); +} + +void Display_line_on_screen_tall(word x_pos,word y_pos,word width,byte * line) +/* On affiche toute une ligne de pixels. Utilisé pour les textes. */ +{ + memcpy(Screen_pixels+x_pos+y_pos*ZOOMY*VIDEO_LINE_WIDTH,line,width); + memcpy(Screen_pixels+x_pos+(y_pos*ZOOMY+1)*VIDEO_LINE_WIDTH,line,width); +} + +void Read_line_screen_tall(word x_pos,word y_pos,word width,byte * line) +{ + memcpy(line,VIDEO_LINE_WIDTH*ZOOMY*y_pos + x_pos + Screen_pixels,width); +} + +void Display_part_of_screen_scaled_tall( + word width, // width non zoomée + word height, // height zoomée + word image_width,byte * buffer) +{ + byte* src = Main_screen + Main_magnifier_offset_Y * image_width + + Main_magnifier_offset_X; + int y = 0; // Ligne en cours de traitement + + // Pour chaque ligne à zoomer + while(1) + { + int x; + + // On éclate la ligne + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + // On l'affiche Facteur fois, sur des lignes consécutives + x = Main_magnifier_factor*ZOOMY; + // Pour chaque ligne + do{ + // On affiche la ligne zoomée + Display_line_on_screen_simple( + Main_X_zoom, y, width*Main_magnifier_factor, + buffer + ); + // On passe à la suivante + y++; + if(y==height*ZOOMY) + { + Update_rect(Main_X_zoom,0, + width*Main_magnifier_factor,height); + return; + } + x--; + }while (x > 0); + src += image_width; + } +// ATTENTION on n'arrive jamais ici ! +} + +// Affiche une partie de la brosse couleur zoomée +void Display_brush_color_zoom_tall(word x_pos,word y_pos, + word x_offset,word y_offset, + word width, // width non zoomée + word end_y_pos,byte transp_color, + word brush_width, // width réelle de la brosse + byte * buffer) +{ + byte* src = Brush+y_offset*brush_width + x_offset; + word y = y_pos; + byte bx; + + // Pour chaque ligne + while(1) + { + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + // On affiche facteur fois la ligne zoomée + for(bx=Main_magnifier_factor;bx>0;bx--) + { + Display_transparent_line_on_screen_simple(x_pos,y*ZOOMY,width*Main_magnifier_factor,buffer,transp_color); + memcpy(Screen_pixels + (y*ZOOMY +1) * VIDEO_LINE_WIDTH + x_pos, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos, width*Main_magnifier_factor); + y++; + if(y==end_y_pos) + { + return; + } + } + src += brush_width; + } + // ATTENTION zone jamais atteinte +} + +void Display_brush_mono_zoom_tall(word x_pos, word y_pos, + word x_offset, word y_offset, + word width, // width non zoomée + word end_y_pos, + byte transp_color, byte color, + word brush_width, // width réelle de la brosse + byte * buffer +) + +{ + byte* src = Brush + y_offset * brush_width + x_offset; + int y=y_pos*ZOOMY; + + //Pour chaque ligne à zoomer : + while(1) + { + int bx; + // src = Ligne originale + // On éclate la ligne + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + + // On affiche la ligne Facteur fois à l'écran (sur des + // lignes consécutives) + bx = Main_magnifier_factor*ZOOMY; + + // Pour chaque ligne écran + do + { + // On affiche la ligne zoomée + Display_transparent_mono_line_on_screen_simple( + x_pos, y, width * Main_magnifier_factor, + buffer, transp_color, color + ); + // On passe à la ligne suivante + y++; + // On vérifie qu'on est pas à la ligne finale + if(y == end_y_pos*ZOOMY) + { + Update_rect( x_pos, y_pos, + width * Main_magnifier_factor, end_y_pos - y_pos ); + return; + } + bx --; + } + while (bx > 0); + + // Passage à la ligne suivante dans la brosse aussi + src+=brush_width; + } +} + +void Clear_brush_scaled_tall(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) +{ + // En fait on va recopier l'image non zoomée dans la partie zoomée ! + byte* src = Main_screen + y_offset * image_width + x_offset; + int y = y_pos; + int bx; + + // Pour chaque ligne à zoomer + while(1){ + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + + bx=Main_magnifier_factor; + + // Pour chaque ligne + do{ + Display_line_on_screen_tall(x_pos,y, + width * Main_magnifier_factor,buffer); + + // Ligne suivante + y++; + if(y==end_y_pos) + { + Update_rect(x_pos,y_pos, + width*Main_magnifier_factor,end_y_pos-y_pos); + return; + } + bx--; + }while(bx!=0); + + src+= image_width; + } +} diff --git a/pxtall.h b/pxtall.h index 2533b809..0499cf33 100644 --- a/pxtall.h +++ b/pxtall.h @@ -1,46 +1,46 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file pxtall.h -/// Renderer for tall pixels (1x2). -////////////////////////////////////////////////////////////////////////////// - -#include "struct.h" - - void Pixel_tall (word x,word y,byte color); - byte Read_pixel_tall (word x,word y); - void Block_tall (word start_x,word start_y,word width,word height,byte color); - void Pixel_preview_normal_tall (word x,word y,byte color); - void Pixel_preview_magnifier_tall (word x,word y,byte color); - void Horizontal_XOR_line_tall (word x_pos,word y_pos,word width); - void Vertical_XOR_line_tall (word x_pos,word y_pos,word height); - void Display_brush_color_tall (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); - void Display_brush_mono_tall (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); - void Clear_brush_tall (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); - void Remap_screen_tall (word x_pos,word y_pos,word width,word height,byte * conversion_table); - void Display_part_of_screen_tall (word width,word height,word image_width); - void Display_line_on_screen_tall (word x_pos,word y_pos,word width,byte * line); - void Read_line_screen_tall (word x_pos,word y_pos,word width,byte * line); - void Display_part_of_screen_scaled_tall(word width,word height,word image_width,byte * buffer); - void Display_brush_color_zoom_tall (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); - void Display_brush_mono_zoom_tall (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); - void Clear_brush_scaled_tall (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); - void Display_brush_tall (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file pxtall.h +/// Renderer for tall pixels (1x2). +////////////////////////////////////////////////////////////////////////////// + +#include "struct.h" + + void Pixel_tall (word x,word y,byte color); + byte Read_pixel_tall (word x,word y); + void Block_tall (word start_x,word start_y,word width,word height,byte color); + void Pixel_preview_normal_tall (word x,word y,byte color); + void Pixel_preview_magnifier_tall (word x,word y,byte color); + void Horizontal_XOR_line_tall (word x_pos,word y_pos,word width); + void Vertical_XOR_line_tall (word x_pos,word y_pos,word height); + void Display_brush_color_tall (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); + void Display_brush_mono_tall (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); + void Clear_brush_tall (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); + void Remap_screen_tall (word x_pos,word y_pos,word width,word height,byte * conversion_table); + void Display_part_of_screen_tall (word width,word height,word image_width); + void Display_line_on_screen_tall (word x_pos,word y_pos,word width,byte * line); + void Read_line_screen_tall (word x_pos,word y_pos,word width,byte * line); + void Display_part_of_screen_scaled_tall(word width,word height,word image_width,byte * buffer); + void Display_brush_color_zoom_tall (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); + void Display_brush_mono_zoom_tall (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); + void Clear_brush_scaled_tall (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); + void Display_brush_tall (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); diff --git a/pxtall2.c b/pxtall2.c index d4e4cf0e..9e046dae 100644 --- a/pxtall2.c +++ b/pxtall2.c @@ -1,524 +1,524 @@ -/* 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 -*/ - -#include -#include -#include -#include "global.h" -#include "sdlscreen.h" -#include "misc.h" -#include "pxtall2.h" - -#define ZOOMX 2 -#define ZOOMY 4 - -void Pixel_tall2 (word x,word y,byte color) -/* Affiche un pixel de la color aux coords x;y à l'écran */ -{ - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 1)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 1)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH + 1)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+3) * VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+3) * VIDEO_LINE_WIDTH + 1)=color; -} - -byte Read_pixel_tall2 (word x,word y) -/* On retourne la couleur du pixel aux coords données */ -{ - return *( Screen_pixels + y * ZOOMY * VIDEO_LINE_WIDTH + x * ZOOMX); -} - -void Block_tall2 (word start_x,word start_y,word width,word height,byte color) -/* On affiche un rectangle de la couleur donnée */ -{ - SDL_Rect rectangle; - rectangle.x=start_x*ZOOMX; - rectangle.y=start_y*ZOOMY; - rectangle.w=width*ZOOMX; - rectangle.h=height*ZOOMY; - SDL_FillRect(Screen_SDL,&rectangle,color); -} - -void Display_part_of_screen_tall2 (word width,word height,word image_width) -/* Afficher une partie de l'image telle quelle sur l'écran */ -{ - byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) - byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) - int y; - int dy; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - // On fait une copie de la ligne - for (dy=width;dy>0;dy--) - { - *(dest+1)=*dest=*src; - src++; - dest+=ZOOMX; - } - // On double la ligne qu'on vient de copier - memcpy(dest-width*ZOOMX+VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); - // On la triple - memcpy(dest-width*ZOOMX+2*VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); - // On la quadruple - memcpy(dest-width*ZOOMX+3*VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); - - // On passe à la ligne suivante - src+=image_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - } - //Update_rect(0,0,width,height); -} - -void Pixel_preview_normal_tall2 (word x,word y,byte color) -/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image - * dans l'écran, en mode normal (pas en mode loupe) - * Note: si on modifie cette procédure, il faudra penser à faire également - * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ -{ -// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) - Pixel_tall2(x-Main_offset_X,y-Main_offset_Y,color); -} - -void Pixel_preview_magnifier_tall2 (word x,word y,byte color) -{ - // Affiche le pixel dans la partie non zoomée - Pixel_tall2(x-Main_offset_X,y-Main_offset_Y,color); - - // Regarde si on doit aussi l'afficher dans la partie zoomée - if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom - && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) - { - // On est dedans - int height; - int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); - - if (Menu_Y - y_zoom < Main_magnifier_factor) - // On ne doit dessiner qu'un morceau du pixel - // sinon on dépasse sur le menu - height = Menu_Y - y_zoom; - else - height = Main_magnifier_factor; - - Block_tall2( - Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, - y_zoom, Main_magnifier_factor, height, color - ); - } -} - -void Horizontal_XOR_line_tall2(word x_pos,word y_pos,word width) -{ - //On calcule la valeur initiale de dest: - byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; - - int x; - - for (x=0;x0;i--) - { - *(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*(dest)=~*(dest); - dest+=VIDEO_LINE_WIDTH*ZOOMY; - } -} - -void Display_brush_color_tall2(word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) -{ - // dest = Position à l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - // src = Position dans la brosse - byte* src = Brush + y_offset * brush_width + x_offset; - - word x,y; - - // Pour chaque ligne - for(y = height;y > 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *(dest+3*VIDEO_LINE_WIDTH+1) = *(dest+3*VIDEO_LINE_WIDTH) = *(dest+2*VIDEO_LINE_WIDTH+1) = *(dest+2*VIDEO_LINE_WIDTH) = *(dest+VIDEO_LINE_WIDTH+1) = *(dest+VIDEO_LINE_WIDTH) = *(dest+1) = *dest = *src; - } - - // Pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - src = src + brush_width - width; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Display_brush_mono_tall2(word x_pos, word y_pos, - word x_offset, word y_offset, word width, word height, - byte transp_color, byte color, word brush_width) -/* On affiche la brosse en monochrome */ -{ - byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; // dest = adr destination à - // l'écran - byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds - // la brosse - int x,y; - - for(y=height;y!=0;y--) - //Pour chaque ligne - { - for(x=width;x!=0;x--) - //Pour chaque pixel - { - if (*src!=transp_color) - *(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*(dest)=color; - - // On passe au pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - src+=brush_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Clear_brush_tall2(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) -{ - byte* dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) - byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) - int y; - int x; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - for(x=width;x!=0;x--) - //Pour chaque pixel - { - *(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*(dest)=*src; - - // On passe au pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - src+=image_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; - } - Update_rect(x_pos,y_pos,width,height); -} - -// Affiche une brosse (arbitraire) à l'écran -void Display_brush_tall2(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) -{ - // dest = Position à l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - // src = Position dans la brosse - byte* src = brush + y_offset * brush_width + x_offset; - - word x,y; - - // Pour chaque ligne - for(y = height;y > 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*(dest)=*src; - } - - // Pixel suivant - src++; dest+=ZOOMX; - } - - // On passe à la ligne suivante - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - src = src + brush_width - width; - } -} - -void Remap_screen_tall2(word x_pos,word y_pos,word width,word height,byte * conversion_table) -{ - // dest = coords a l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - int x,y; - - // Pour chaque ligne - for(y=height;y>0;y--) - { - // Pour chaque pixel - for(x=width;x>0;x--) - { - *(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*(dest)= - conversion_table[*dest]; - dest +=ZOOMX; - } - - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - } - - Update_rect(x_pos,y_pos,width,height); -} - -void Display_line_on_screen_fast_tall2(word x_pos,word y_pos,word width,byte * line) -/* On affiche toute une ligne de pixels telle quelle. */ -/* Utilisée si le buffer contient déja des pixel doublés. */ -{ - memcpy(Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH,line,width*ZOOMX); - memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+1)*VIDEO_LINE_WIDTH,line,width*ZOOMX); - memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+2)*VIDEO_LINE_WIDTH,line,width*ZOOMX); - memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+3)*VIDEO_LINE_WIDTH,line,width*ZOOMX); -} - -void Display_line_on_screen_tall2(word x_pos,word y_pos,word width,byte * line) -/* On affiche une ligne de pixels en les doublant. */ -{ - int x; - byte *dest; - dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; - for(x=width;x>0;x--) - { - *(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*(dest)=*line; - dest+=ZOOMX; - line++; - } -} -void Display_transparent_mono_line_on_screen_tall2( - word x_pos, word y_pos, word width, byte* line, - byte transp_color, byte color) -// Affiche une ligne à l'écran avec une couleur + transparence. -// Utilisé par les brosses en mode zoom -{ - byte* dest = Screen_pixels+ y_pos*VIDEO_LINE_WIDTH + x_pos*ZOOMX; - int x; - // Pour chaque pixel - for(x=0;x 0); - src += image_width; - } -// ATTENTION on n'arrive jamais ici ! -} - -// Affiche une partie de la brosse couleur zoomée -void Display_brush_color_zoom_tall2(word x_pos,word y_pos, - word x_offset,word y_offset, - word width, // width non zoomée - word end_y_pos,byte transp_color, - word brush_width, // width réelle de la brosse - byte * buffer) -{ - byte* src = Brush+y_offset*brush_width + x_offset; - word y = y_pos; - byte bx; - - // Pour chaque ligne - while(1) - { - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - // On affiche facteur fois la ligne zoomée - for(bx=Main_magnifier_factor;bx>0;bx--) - { - byte* line_src = buffer; - byte* dest = Screen_pixels + y*ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - word x; - // Pour chaque pixel de la ligne - for(x = width*Main_magnifier_factor;x > 0;x--) - { - if(*line_src!=transp_color) - { - *(dest+1)=*dest = *line_src; - } - line_src++; - dest+=ZOOMX; - } - // Double the line - memcpy(Screen_pixels + (y*ZOOMY+1)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); - // Triple the line - memcpy(Screen_pixels + (y*ZOOMY+2)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); - // Quadruple it - memcpy(Screen_pixels + (y*ZOOMY+3)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); - y++; - if(y==end_y_pos) - { - return; - } - } - src += brush_width; - } - // ATTENTION zone jamais atteinte -} - -void Display_brush_mono_zoom_tall2(word x_pos, word y_pos, - word x_offset, word y_offset, - word width, // width non zoomée - word end_y_pos, - byte transp_color, byte color, - word brush_width, // width réelle de la brosse - byte * buffer -) - -{ - byte* src = Brush + y_offset * brush_width + x_offset; - int y=y_pos*ZOOMY; - - //Pour chaque ligne à zoomer : - while(1) - { - int bx; - // src = Ligne originale - // On éclate la ligne - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - - // On affiche la ligne Facteur fois à l'écran (sur des - // lignes consécutives) - bx = Main_magnifier_factor*ZOOMY; - - // Pour chaque ligne écran - do - { - // On affiche la ligne zoomée - Display_transparent_mono_line_on_screen_tall2( - x_pos, y, width * Main_magnifier_factor, - buffer, transp_color, color - ); - // On passe à la ligne suivante - y++; - // On vérifie qu'on est pas à la ligne finale - if(y == end_y_pos*ZOOMY) - { - Update_rect( x_pos, y_pos, - width * Main_magnifier_factor, end_y_pos - y_pos ); - return; - } - bx --; - } - while (bx > 0); - - // Passage à la ligne suivante dans la brosse aussi - src+=brush_width; - } -} - -void Clear_brush_scaled_tall2(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) -{ - - // En fait on va recopier l'image non zoomée dans la partie zoomée ! - byte* src = Main_screen + y_offset * image_width + x_offset; - int y = y_pos; - int bx; - - // Pour chaque ligne à zoomer - while(1){ - Zoom_a_line(src,buffer,Main_magnifier_factor*ZOOMX,width); - - bx=Main_magnifier_factor; - - // Pour chaque ligne - do{ - // TODO a verifier - Display_line_on_screen_fast_tall2(x_pos,y, - width * Main_magnifier_factor,buffer); - - // Ligne suivante - y++; - if(y==end_y_pos) - { - Update_rect(x_pos,y_pos, - width*Main_magnifier_factor,end_y_pos-y_pos); - return; - } - bx--; - }while(bx!=0); - - src+= image_width; - } -} - - +/* 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 +*/ + +#include +#include +#include +#include "global.h" +#include "sdlscreen.h" +#include "misc.h" +#include "pxtall2.h" + +#define ZOOMX 2 +#define ZOOMY 4 + +void Pixel_tall2 (word x,word y,byte color) +/* Affiche un pixel de la color aux coords x;y à l'écran */ +{ + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 1)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 1)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH + 1)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+3) * VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+3) * VIDEO_LINE_WIDTH + 1)=color; +} + +byte Read_pixel_tall2 (word x,word y) +/* On retourne la couleur du pixel aux coords données */ +{ + return *( Screen_pixels + y * ZOOMY * VIDEO_LINE_WIDTH + x * ZOOMX); +} + +void Block_tall2 (word start_x,word start_y,word width,word height,byte color) +/* On affiche un rectangle de la couleur donnée */ +{ + SDL_Rect rectangle; + rectangle.x=start_x*ZOOMX; + rectangle.y=start_y*ZOOMY; + rectangle.w=width*ZOOMX; + rectangle.h=height*ZOOMY; + SDL_FillRect(Screen_SDL,&rectangle,color); +} + +void Display_part_of_screen_tall2 (word width,word height,word image_width) +/* Afficher une partie de l'image telle quelle sur l'écran */ +{ + byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) + byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) + int y; + int dy; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + // On fait une copie de la ligne + for (dy=width;dy>0;dy--) + { + *(dest+1)=*dest=*src; + src++; + dest+=ZOOMX; + } + // On double la ligne qu'on vient de copier + memcpy(dest-width*ZOOMX+VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); + // On la triple + memcpy(dest-width*ZOOMX+2*VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); + // On la quadruple + memcpy(dest-width*ZOOMX+3*VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); + + // On passe à la ligne suivante + src+=image_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + } + //Update_rect(0,0,width,height); +} + +void Pixel_preview_normal_tall2 (word x,word y,byte color) +/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image + * dans l'écran, en mode normal (pas en mode loupe) + * Note: si on modifie cette procédure, il faudra penser à faire également + * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ +{ +// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) + Pixel_tall2(x-Main_offset_X,y-Main_offset_Y,color); +} + +void Pixel_preview_magnifier_tall2 (word x,word y,byte color) +{ + // Affiche le pixel dans la partie non zoomée + Pixel_tall2(x-Main_offset_X,y-Main_offset_Y,color); + + // Regarde si on doit aussi l'afficher dans la partie zoomée + if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom + && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) + { + // On est dedans + int height; + int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); + + if (Menu_Y - y_zoom < Main_magnifier_factor) + // On ne doit dessiner qu'un morceau du pixel + // sinon on dépasse sur le menu + height = Menu_Y - y_zoom; + else + height = Main_magnifier_factor; + + Block_tall2( + Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, + y_zoom, Main_magnifier_factor, height, color + ); + } +} + +void Horizontal_XOR_line_tall2(word x_pos,word y_pos,word width) +{ + //On calcule la valeur initiale de dest: + byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; + + int x; + + for (x=0;x0;i--) + { + *(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*(dest)=~*(dest); + dest+=VIDEO_LINE_WIDTH*ZOOMY; + } +} + +void Display_brush_color_tall2(word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) +{ + // dest = Position à l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + // src = Position dans la brosse + byte* src = Brush + y_offset * brush_width + x_offset; + + word x,y; + + // Pour chaque ligne + for(y = height;y > 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *(dest+3*VIDEO_LINE_WIDTH+1) = *(dest+3*VIDEO_LINE_WIDTH) = *(dest+2*VIDEO_LINE_WIDTH+1) = *(dest+2*VIDEO_LINE_WIDTH) = *(dest+VIDEO_LINE_WIDTH+1) = *(dest+VIDEO_LINE_WIDTH) = *(dest+1) = *dest = *src; + } + + // Pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + src = src + brush_width - width; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Display_brush_mono_tall2(word x_pos, word y_pos, + word x_offset, word y_offset, word width, word height, + byte transp_color, byte color, word brush_width) +/* On affiche la brosse en monochrome */ +{ + byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; // dest = adr destination à + // l'écran + byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds + // la brosse + int x,y; + + for(y=height;y!=0;y--) + //Pour chaque ligne + { + for(x=width;x!=0;x--) + //Pour chaque pixel + { + if (*src!=transp_color) + *(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*(dest)=color; + + // On passe au pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + src+=brush_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Clear_brush_tall2(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) +{ + byte* dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) + byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) + int y; + int x; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + for(x=width;x!=0;x--) + //Pour chaque pixel + { + *(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*(dest)=*src; + + // On passe au pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + src+=image_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; + } + Update_rect(x_pos,y_pos,width,height); +} + +// Affiche une brosse (arbitraire) à l'écran +void Display_brush_tall2(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) +{ + // dest = Position à l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + // src = Position dans la brosse + byte* src = brush + y_offset * brush_width + x_offset; + + word x,y; + + // Pour chaque ligne + for(y = height;y > 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*(dest)=*src; + } + + // Pixel suivant + src++; dest+=ZOOMX; + } + + // On passe à la ligne suivante + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + src = src + brush_width - width; + } +} + +void Remap_screen_tall2(word x_pos,word y_pos,word width,word height,byte * conversion_table) +{ + // dest = coords a l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + int x,y; + + // Pour chaque ligne + for(y=height;y>0;y--) + { + // Pour chaque pixel + for(x=width;x>0;x--) + { + *(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*(dest)= + conversion_table[*dest]; + dest +=ZOOMX; + } + + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + } + + Update_rect(x_pos,y_pos,width,height); +} + +void Display_line_on_screen_fast_tall2(word x_pos,word y_pos,word width,byte * line) +/* On affiche toute une ligne de pixels telle quelle. */ +/* Utilisée si le buffer contient déja des pixel doublés. */ +{ + memcpy(Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH,line,width*ZOOMX); + memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+1)*VIDEO_LINE_WIDTH,line,width*ZOOMX); + memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+2)*VIDEO_LINE_WIDTH,line,width*ZOOMX); + memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+3)*VIDEO_LINE_WIDTH,line,width*ZOOMX); +} + +void Display_line_on_screen_tall2(word x_pos,word y_pos,word width,byte * line) +/* On affiche une ligne de pixels en les doublant. */ +{ + int x; + byte *dest; + dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; + for(x=width;x>0;x--) + { + *(dest+3*VIDEO_LINE_WIDTH+1)=*(dest+3*VIDEO_LINE_WIDTH)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+1)=*(dest)=*line; + dest+=ZOOMX; + line++; + } +} +void Display_transparent_mono_line_on_screen_tall2( + word x_pos, word y_pos, word width, byte* line, + byte transp_color, byte color) +// Affiche une ligne à l'écran avec une couleur + transparence. +// Utilisé par les brosses en mode zoom +{ + byte* dest = Screen_pixels+ y_pos*VIDEO_LINE_WIDTH + x_pos*ZOOMX; + int x; + // Pour chaque pixel + for(x=0;x 0); + src += image_width; + } +// ATTENTION on n'arrive jamais ici ! +} + +// Affiche une partie de la brosse couleur zoomée +void Display_brush_color_zoom_tall2(word x_pos,word y_pos, + word x_offset,word y_offset, + word width, // width non zoomée + word end_y_pos,byte transp_color, + word brush_width, // width réelle de la brosse + byte * buffer) +{ + byte* src = Brush+y_offset*brush_width + x_offset; + word y = y_pos; + byte bx; + + // Pour chaque ligne + while(1) + { + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + // On affiche facteur fois la ligne zoomée + for(bx=Main_magnifier_factor;bx>0;bx--) + { + byte* line_src = buffer; + byte* dest = Screen_pixels + y*ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + word x; + // Pour chaque pixel de la ligne + for(x = width*Main_magnifier_factor;x > 0;x--) + { + if(*line_src!=transp_color) + { + *(dest+1)=*dest = *line_src; + } + line_src++; + dest+=ZOOMX; + } + // Double the line + memcpy(Screen_pixels + (y*ZOOMY+1)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); + // Triple the line + memcpy(Screen_pixels + (y*ZOOMY+2)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); + // Quadruple it + memcpy(Screen_pixels + (y*ZOOMY+3)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); + y++; + if(y==end_y_pos) + { + return; + } + } + src += brush_width; + } + // ATTENTION zone jamais atteinte +} + +void Display_brush_mono_zoom_tall2(word x_pos, word y_pos, + word x_offset, word y_offset, + word width, // width non zoomée + word end_y_pos, + byte transp_color, byte color, + word brush_width, // width réelle de la brosse + byte * buffer +) + +{ + byte* src = Brush + y_offset * brush_width + x_offset; + int y=y_pos*ZOOMY; + + //Pour chaque ligne à zoomer : + while(1) + { + int bx; + // src = Ligne originale + // On éclate la ligne + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + + // On affiche la ligne Facteur fois à l'écran (sur des + // lignes consécutives) + bx = Main_magnifier_factor*ZOOMY; + + // Pour chaque ligne écran + do + { + // On affiche la ligne zoomée + Display_transparent_mono_line_on_screen_tall2( + x_pos, y, width * Main_magnifier_factor, + buffer, transp_color, color + ); + // On passe à la ligne suivante + y++; + // On vérifie qu'on est pas à la ligne finale + if(y == end_y_pos*ZOOMY) + { + Update_rect( x_pos, y_pos, + width * Main_magnifier_factor, end_y_pos - y_pos ); + return; + } + bx --; + } + while (bx > 0); + + // Passage à la ligne suivante dans la brosse aussi + src+=brush_width; + } +} + +void Clear_brush_scaled_tall2(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) +{ + + // En fait on va recopier l'image non zoomée dans la partie zoomée ! + byte* src = Main_screen + y_offset * image_width + x_offset; + int y = y_pos; + int bx; + + // Pour chaque ligne à zoomer + while(1){ + Zoom_a_line(src,buffer,Main_magnifier_factor*ZOOMX,width); + + bx=Main_magnifier_factor; + + // Pour chaque ligne + do{ + // TODO a verifier + Display_line_on_screen_fast_tall2(x_pos,y, + width * Main_magnifier_factor,buffer); + + // Ligne suivante + y++; + if(y==end_y_pos) + { + Update_rect(x_pos,y_pos, + width*Main_magnifier_factor,end_y_pos-y_pos); + return; + } + bx--; + }while(bx!=0); + + src+= image_width; + } +} + + diff --git a/pxtall2.h b/pxtall2.h index 262c6e45..eaf40fe5 100644 --- a/pxtall2.h +++ b/pxtall2.h @@ -1,48 +1,48 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file pxtall2.h -/// Renderer for double-tall pixels (2x4). -////////////////////////////////////////////////////////////////////////////// - -#include "struct.h" - - void Pixel_tall2 (word x,word y,byte color); - byte Read_pixel_tall2 (word x,word y); - void Block_tall2 (word start_x,word start_y,word width,word height,byte color); - void Pixel_preview_normal_tall2 (word x,word y,byte color); - void Pixel_preview_magnifier_tall2 (word x,word y,byte color); - void Horizontal_XOR_line_tall2 (word x_pos,word y_pos,word width); - void Vertical_XOR_line_tall2 (word x_pos,word y_pos,word height); - void Display_brush_color_tall2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); - void Display_brush_mono_tall2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); - void Clear_brush_tall2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); - void Remap_screen_tall2 (word x_pos,word y_pos,word width,word height,byte * conversion_table); - void Display_part_of_screen_tall2 (word width,word height,word image_width); - void Display_line_on_screen_tall2 (word x_pos,word y_pos,word width,byte * line); - void Read_line_screen_tall2 (word x_pos,word y_pos,word width,byte * line); - void Display_part_of_screen_scaled_tall2(word width,word height,word image_width,byte * buffer); - void Display_brush_color_zoom_tall2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); - void Display_brush_mono_zoom_tall2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); - void Clear_brush_scaled_tall2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); - void Display_brush_tall2 (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); - - void Display_line_on_screen_fast_tall2 (word x_pos,word y_pos,word width,byte * line); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file pxtall2.h +/// Renderer for double-tall pixels (2x4). +////////////////////////////////////////////////////////////////////////////// + +#include "struct.h" + + void Pixel_tall2 (word x,word y,byte color); + byte Read_pixel_tall2 (word x,word y); + void Block_tall2 (word start_x,word start_y,word width,word height,byte color); + void Pixel_preview_normal_tall2 (word x,word y,byte color); + void Pixel_preview_magnifier_tall2 (word x,word y,byte color); + void Horizontal_XOR_line_tall2 (word x_pos,word y_pos,word width); + void Vertical_XOR_line_tall2 (word x_pos,word y_pos,word height); + void Display_brush_color_tall2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); + void Display_brush_mono_tall2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); + void Clear_brush_tall2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); + void Remap_screen_tall2 (word x_pos,word y_pos,word width,word height,byte * conversion_table); + void Display_part_of_screen_tall2 (word width,word height,word image_width); + void Display_line_on_screen_tall2 (word x_pos,word y_pos,word width,byte * line); + void Read_line_screen_tall2 (word x_pos,word y_pos,word width,byte * line); + void Display_part_of_screen_scaled_tall2(word width,word height,word image_width,byte * buffer); + void Display_brush_color_zoom_tall2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); + void Display_brush_mono_zoom_tall2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); + void Clear_brush_scaled_tall2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); + void Display_brush_tall2 (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); + + void Display_line_on_screen_fast_tall2 (word x_pos,word y_pos,word width,byte * line); diff --git a/pxtriple.c b/pxtriple.c index eb14ff20..4ce54c3d 100644 --- a/pxtriple.c +++ b/pxtriple.c @@ -1,520 +1,520 @@ -/* 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 -*/ - -#include -#include -#include -#include "global.h" -#include "sdlscreen.h" -#include "misc.h" -#include "pxtriple.h" - -#define ZOOMX 3 -#define ZOOMY 3 - -void Pixel_triple (word x,word y,byte color) -/* Affiche un pixel de la color aux coords x;y à l'écran */ -{ - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 1)=color; - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 2)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 1)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 2)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH + 1)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH + 2)=color; -} - -byte Read_pixel_triple (word x,word y) -/* On retourne la couleur du pixel aux coords données */ -{ - return *( Screen_pixels + y * ZOOMY * VIDEO_LINE_WIDTH + x * ZOOMX); -} - -void Block_triple (word start_x,word start_y,word width,word height,byte color) -/* On affiche un rectangle de la couleur donnée */ -{ - SDL_Rect rectangle; - rectangle.x=start_x*ZOOMX; - rectangle.y=start_y*ZOOMY; - rectangle.w=width*ZOOMX; - rectangle.h=height*ZOOMY; - SDL_FillRect(Screen_SDL,&rectangle,color); -} - -void Display_part_of_screen_triple (word width,word height,word image_width) -/* Afficher une partie de l'image telle quelle sur l'écran */ -{ - byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) - byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) - int y; - int dy; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - // On fait une copie de la ligne - for (dy=width;dy>0;dy--) - { - *(dest+2)=*(dest+1)=*dest=*src; - src++; - dest+=ZOOMX; - } - // On double la ligne qu'on vient de copier - memcpy(dest-width*ZOOMX+VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); - // On la triple - memcpy(dest-width*ZOOMX+2*VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); - - // On passe à la ligne suivante - src+=image_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - } - //Update_rect(0,0,width,height); -} - -void Pixel_preview_normal_triple (word x,word y,byte color) -/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image - * dans l'écran, en mode normal (pas en mode loupe) - * Note: si on modifie cette procédure, il faudra penser à faire également - * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ -{ -// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) - Pixel_triple(x-Main_offset_X,y-Main_offset_Y,color); -} - -void Pixel_preview_magnifier_triple (word x,word y,byte color) -{ - // Affiche le pixel dans la partie non zoomée - Pixel_triple(x-Main_offset_X,y-Main_offset_Y,color); - - // Regarde si on doit aussi l'afficher dans la partie zoomée - if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom - && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) - { - // On est dedans - int height; - int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); - - if (Menu_Y - y_zoom < Main_magnifier_factor) - // On ne doit dessiner qu'un morceau du pixel - // sinon on dépasse sur le menu - height = Menu_Y - y_zoom; - else - height = Main_magnifier_factor; - - Block_triple( - Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, - y_zoom, Main_magnifier_factor, height, color - ); - } -} - -void Horizontal_XOR_line_triple(word x_pos,word y_pos,word width) -{ - //On calcule la valeur initiale de dest: - byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; - - int x; - - for (x=0;x0;i--) - { - *(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+2)=*(dest+1)=*dest=~*dest; - dest+=VIDEO_LINE_WIDTH*ZOOMY; - } -} - -void Display_brush_color_triple(word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) -{ - // dest = Position à l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - // src = Position dans la brosse - byte* src = Brush + y_offset * brush_width + x_offset; - - word x,y; - - // Pour chaque ligne - for(y = height;y > 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *(dest+2*VIDEO_LINE_WIDTH+2) = *(dest+2*VIDEO_LINE_WIDTH+1) = *(dest+2*VIDEO_LINE_WIDTH) = *(dest+VIDEO_LINE_WIDTH+2) = *(dest+VIDEO_LINE_WIDTH+1) = *(dest+VIDEO_LINE_WIDTH) = *(dest+2) = *(dest+1) = *dest = *src; - } - - // Pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - src = src + brush_width - width; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Display_brush_mono_triple(word x_pos, word y_pos, - word x_offset, word y_offset, word width, word height, - byte transp_color, byte color, word brush_width) -/* On affiche la brosse en monochrome */ -{ - byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; // dest = adr destination à - // l'écran - byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds - // la brosse - int x,y; - - for(y=height;y!=0;y--) - //Pour chaque ligne - { - for(x=width;x!=0;x--) - //Pour chaque pixel - { - if (*src!=transp_color) - *(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+2)=*(dest+1)=*dest=color; - - // On passe au pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - src+=brush_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Clear_brush_triple(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) -{ - byte* dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) - byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) - int y; - int x; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - for(x=width;x!=0;x--) - //Pour chaque pixel - { - *(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+2)=*(dest+1)=*dest=*src; - - // On passe au pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - src+=image_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; - } - Update_rect(x_pos,y_pos,width,height); -} - -// Affiche une brosse (arbitraire) à l'écran -void Display_brush_triple(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) -{ - // dest = Position à l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - // src = Position dans la brosse - byte* src = brush + y_offset * brush_width + x_offset; - - word x,y; - - // Pour chaque ligne - for(y = height;y > 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+2)=*(dest+1)=*dest=*src; - } - - // Pixel suivant - src++; dest+=ZOOMX; - } - - // On passe à la ligne suivante - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - src = src + brush_width - width; - } -} - -void Remap_screen_triple(word x_pos,word y_pos,word width,word height,byte * conversion_table) -{ - // dest = coords a l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - int x,y; - - // Pour chaque ligne - for(y=height;y>0;y--) - { - // Pour chaque pixel - for(x=width;x>0;x--) - { - *(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+2)=*(dest+1)=*dest= - conversion_table[*dest]; - dest +=ZOOMX; - } - - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - } - - Update_rect(x_pos,y_pos,width,height); -} - -void Display_line_on_screen_fast_triple(word x_pos,word y_pos,word width,byte * line) -/* On affiche toute une ligne de pixels telle quelle. */ -/* Utilisée si le buffer contient déja des pixel doublés. */ -{ - memcpy(Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH,line,width*ZOOMX); - memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+1)*VIDEO_LINE_WIDTH,line,width*ZOOMX); - memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+2)*VIDEO_LINE_WIDTH,line,width*ZOOMX); -} - -void Display_line_on_screen_triple(word x_pos,word y_pos,word width,byte * line) -/* On affiche une ligne de pixels en les doublant. */ -{ - int x; - byte *dest; - dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; - for(x=width;x>0;x--) - { - *(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+2)=*(dest+1)=*dest=*line; - dest+=ZOOMX; - line++; - } -} -void Display_transparent_mono_line_on_screen_triple( - word x_pos, word y_pos, word width, byte* line, - byte transp_color, byte color) -// Affiche une ligne à l'écran avec une couleur + transparence. -// Utilisé par les brosses en mode zoom -{ - byte* dest = Screen_pixels+ y_pos*VIDEO_LINE_WIDTH + x_pos*ZOOMX; - int x; - // Pour chaque pixel - for(x=0;x 0); - src += image_width; - } -// ATTENTION on n'arrive jamais ici ! -} - -// Affiche une partie de la brosse couleur zoomée -void Display_brush_color_zoom_triple(word x_pos,word y_pos, - word x_offset,word y_offset, - word width, // width non zoomée - word end_y_pos,byte transp_color, - word brush_width, // width réelle de la brosse - byte * buffer) -{ - byte* src = Brush+y_offset*brush_width + x_offset; - word y = y_pos; - byte bx; - - // Pour chaque ligne - while(1) - { - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - // On affiche facteur fois la ligne zoomée - for(bx=Main_magnifier_factor;bx>0;bx--) - { - byte* line_src = buffer; - byte* dest = Screen_pixels + y*ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - word x; - // Pour chaque pixel de la ligne - for(x = width*Main_magnifier_factor;x > 0;x--) - { - if(*line_src!=transp_color) - { - *(dest+2)=*(dest+1)=*dest = *line_src; - } - line_src++; - dest+=ZOOMX; - } - // Double the line - memcpy(Screen_pixels + (y*ZOOMY+1)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); - // Triple the line - memcpy(Screen_pixels + (y*ZOOMY+2)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); - y++; - if(y==end_y_pos) - { - return; - } - } - src += brush_width; - } - // ATTENTION zone jamais atteinte -} - -void Display_brush_mono_zoom_triple(word x_pos, word y_pos, - word x_offset, word y_offset, - word width, // width non zoomée - word end_y_pos, - byte transp_color, byte color, - word brush_width, // width réelle de la brosse - byte * buffer -) - -{ - byte* src = Brush + y_offset * brush_width + x_offset; - int y=y_pos*ZOOMY; - - //Pour chaque ligne à zoomer : - while(1) - { - int bx; - // src = Ligne originale - // On éclate la ligne - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - - // On affiche la ligne Facteur fois à l'écran (sur des - // lignes consécutives) - bx = Main_magnifier_factor*ZOOMY; - - // Pour chaque ligne écran - do - { - // On affiche la ligne zoomée - Display_transparent_mono_line_on_screen_triple( - x_pos, y, width * Main_magnifier_factor, - buffer, transp_color, color - ); - // On passe à la ligne suivante - y++; - // On vérifie qu'on est pas à la ligne finale - if(y == end_y_pos*ZOOMY) - { - Update_rect( x_pos, y_pos, - width * Main_magnifier_factor, end_y_pos - y_pos ); - return; - } - bx --; - } - while (bx > 0); - - // Passage à la ligne suivante dans la brosse aussi - src+=brush_width; - } -} - -void Clear_brush_scaled_triple(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) -{ - - // En fait on va recopier l'image non zoomée dans la partie zoomée ! - byte* src = Main_screen + y_offset * image_width + x_offset; - int y = y_pos; - int bx; - - // Pour chaque ligne à zoomer - while(1){ - Zoom_a_line(src,buffer,Main_magnifier_factor*ZOOMX,width); - - bx=Main_magnifier_factor; - - // Pour chaque ligne - do{ - // TODO a verifier - Display_line_on_screen_fast_triple(x_pos,y, - width * Main_magnifier_factor,buffer); - - // Ligne suivante - y++; - if(y==end_y_pos) - { - Update_rect(x_pos,y_pos, - width*Main_magnifier_factor,end_y_pos-y_pos); - return; - } - bx--; - }while(bx!=0); - - src+= image_width; - } -} - - +/* 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 +*/ + +#include +#include +#include +#include "global.h" +#include "sdlscreen.h" +#include "misc.h" +#include "pxtriple.h" + +#define ZOOMX 3 +#define ZOOMY 3 + +void Pixel_triple (word x,word y,byte color) +/* Affiche un pixel de la color aux coords x;y à l'écran */ +{ + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 1)=color; + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 2)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 1)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 2)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH + 1)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+2) * VIDEO_LINE_WIDTH + 2)=color; +} + +byte Read_pixel_triple (word x,word y) +/* On retourne la couleur du pixel aux coords données */ +{ + return *( Screen_pixels + y * ZOOMY * VIDEO_LINE_WIDTH + x * ZOOMX); +} + +void Block_triple (word start_x,word start_y,word width,word height,byte color) +/* On affiche un rectangle de la couleur donnée */ +{ + SDL_Rect rectangle; + rectangle.x=start_x*ZOOMX; + rectangle.y=start_y*ZOOMY; + rectangle.w=width*ZOOMX; + rectangle.h=height*ZOOMY; + SDL_FillRect(Screen_SDL,&rectangle,color); +} + +void Display_part_of_screen_triple (word width,word height,word image_width) +/* Afficher une partie de l'image telle quelle sur l'écran */ +{ + byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) + byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) + int y; + int dy; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + // On fait une copie de la ligne + for (dy=width;dy>0;dy--) + { + *(dest+2)=*(dest+1)=*dest=*src; + src++; + dest+=ZOOMX; + } + // On double la ligne qu'on vient de copier + memcpy(dest-width*ZOOMX+VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); + // On la triple + memcpy(dest-width*ZOOMX+2*VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); + + // On passe à la ligne suivante + src+=image_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + } + //Update_rect(0,0,width,height); +} + +void Pixel_preview_normal_triple (word x,word y,byte color) +/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image + * dans l'écran, en mode normal (pas en mode loupe) + * Note: si on modifie cette procédure, il faudra penser à faire également + * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ +{ +// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) + Pixel_triple(x-Main_offset_X,y-Main_offset_Y,color); +} + +void Pixel_preview_magnifier_triple (word x,word y,byte color) +{ + // Affiche le pixel dans la partie non zoomée + Pixel_triple(x-Main_offset_X,y-Main_offset_Y,color); + + // Regarde si on doit aussi l'afficher dans la partie zoomée + if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom + && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) + { + // On est dedans + int height; + int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); + + if (Menu_Y - y_zoom < Main_magnifier_factor) + // On ne doit dessiner qu'un morceau du pixel + // sinon on dépasse sur le menu + height = Menu_Y - y_zoom; + else + height = Main_magnifier_factor; + + Block_triple( + Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, + y_zoom, Main_magnifier_factor, height, color + ); + } +} + +void Horizontal_XOR_line_triple(word x_pos,word y_pos,word width) +{ + //On calcule la valeur initiale de dest: + byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; + + int x; + + for (x=0;x0;i--) + { + *(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+2)=*(dest+1)=*dest=~*dest; + dest+=VIDEO_LINE_WIDTH*ZOOMY; + } +} + +void Display_brush_color_triple(word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) +{ + // dest = Position à l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + // src = Position dans la brosse + byte* src = Brush + y_offset * brush_width + x_offset; + + word x,y; + + // Pour chaque ligne + for(y = height;y > 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *(dest+2*VIDEO_LINE_WIDTH+2) = *(dest+2*VIDEO_LINE_WIDTH+1) = *(dest+2*VIDEO_LINE_WIDTH) = *(dest+VIDEO_LINE_WIDTH+2) = *(dest+VIDEO_LINE_WIDTH+1) = *(dest+VIDEO_LINE_WIDTH) = *(dest+2) = *(dest+1) = *dest = *src; + } + + // Pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + src = src + brush_width - width; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Display_brush_mono_triple(word x_pos, word y_pos, + word x_offset, word y_offset, word width, word height, + byte transp_color, byte color, word brush_width) +/* On affiche la brosse en monochrome */ +{ + byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; // dest = adr destination à + // l'écran + byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds + // la brosse + int x,y; + + for(y=height;y!=0;y--) + //Pour chaque ligne + { + for(x=width;x!=0;x--) + //Pour chaque pixel + { + if (*src!=transp_color) + *(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+2)=*(dest+1)=*dest=color; + + // On passe au pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + src+=brush_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Clear_brush_triple(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) +{ + byte* dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) + byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) + int y; + int x; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + for(x=width;x!=0;x--) + //Pour chaque pixel + { + *(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+2)=*(dest+1)=*dest=*src; + + // On passe au pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + src+=image_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; + } + Update_rect(x_pos,y_pos,width,height); +} + +// Affiche une brosse (arbitraire) à l'écran +void Display_brush_triple(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) +{ + // dest = Position à l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + // src = Position dans la brosse + byte* src = brush + y_offset * brush_width + x_offset; + + word x,y; + + // Pour chaque ligne + for(y = height;y > 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+2)=*(dest+1)=*dest=*src; + } + + // Pixel suivant + src++; dest+=ZOOMX; + } + + // On passe à la ligne suivante + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + src = src + brush_width - width; + } +} + +void Remap_screen_triple(word x_pos,word y_pos,word width,word height,byte * conversion_table) +{ + // dest = coords a l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + int x,y; + + // Pour chaque ligne + for(y=height;y>0;y--) + { + // Pour chaque pixel + for(x=width;x>0;x--) + { + *(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+2)=*(dest+1)=*dest= + conversion_table[*dest]; + dest +=ZOOMX; + } + + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + } + + Update_rect(x_pos,y_pos,width,height); +} + +void Display_line_on_screen_fast_triple(word x_pos,word y_pos,word width,byte * line) +/* On affiche toute une ligne de pixels telle quelle. */ +/* Utilisée si le buffer contient déja des pixel doublés. */ +{ + memcpy(Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH,line,width*ZOOMX); + memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+1)*VIDEO_LINE_WIDTH,line,width*ZOOMX); + memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+2)*VIDEO_LINE_WIDTH,line,width*ZOOMX); +} + +void Display_line_on_screen_triple(word x_pos,word y_pos,word width,byte * line) +/* On affiche une ligne de pixels en les doublant. */ +{ + int x; + byte *dest; + dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; + for(x=width;x>0;x--) + { + *(dest+2*VIDEO_LINE_WIDTH+2)=*(dest+2*VIDEO_LINE_WIDTH+1)=*(dest+2*VIDEO_LINE_WIDTH)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+2)=*(dest+1)=*dest=*line; + dest+=ZOOMX; + line++; + } +} +void Display_transparent_mono_line_on_screen_triple( + word x_pos, word y_pos, word width, byte* line, + byte transp_color, byte color) +// Affiche une ligne à l'écran avec une couleur + transparence. +// Utilisé par les brosses en mode zoom +{ + byte* dest = Screen_pixels+ y_pos*VIDEO_LINE_WIDTH + x_pos*ZOOMX; + int x; + // Pour chaque pixel + for(x=0;x 0); + src += image_width; + } +// ATTENTION on n'arrive jamais ici ! +} + +// Affiche une partie de la brosse couleur zoomée +void Display_brush_color_zoom_triple(word x_pos,word y_pos, + word x_offset,word y_offset, + word width, // width non zoomée + word end_y_pos,byte transp_color, + word brush_width, // width réelle de la brosse + byte * buffer) +{ + byte* src = Brush+y_offset*brush_width + x_offset; + word y = y_pos; + byte bx; + + // Pour chaque ligne + while(1) + { + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + // On affiche facteur fois la ligne zoomée + for(bx=Main_magnifier_factor;bx>0;bx--) + { + byte* line_src = buffer; + byte* dest = Screen_pixels + y*ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + word x; + // Pour chaque pixel de la ligne + for(x = width*Main_magnifier_factor;x > 0;x--) + { + if(*line_src!=transp_color) + { + *(dest+2)=*(dest+1)=*dest = *line_src; + } + line_src++; + dest+=ZOOMX; + } + // Double the line + memcpy(Screen_pixels + (y*ZOOMY+1)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); + // Triple the line + memcpy(Screen_pixels + (y*ZOOMY+2)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); + y++; + if(y==end_y_pos) + { + return; + } + } + src += brush_width; + } + // ATTENTION zone jamais atteinte +} + +void Display_brush_mono_zoom_triple(word x_pos, word y_pos, + word x_offset, word y_offset, + word width, // width non zoomée + word end_y_pos, + byte transp_color, byte color, + word brush_width, // width réelle de la brosse + byte * buffer +) + +{ + byte* src = Brush + y_offset * brush_width + x_offset; + int y=y_pos*ZOOMY; + + //Pour chaque ligne à zoomer : + while(1) + { + int bx; + // src = Ligne originale + // On éclate la ligne + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + + // On affiche la ligne Facteur fois à l'écran (sur des + // lignes consécutives) + bx = Main_magnifier_factor*ZOOMY; + + // Pour chaque ligne écran + do + { + // On affiche la ligne zoomée + Display_transparent_mono_line_on_screen_triple( + x_pos, y, width * Main_magnifier_factor, + buffer, transp_color, color + ); + // On passe à la ligne suivante + y++; + // On vérifie qu'on est pas à la ligne finale + if(y == end_y_pos*ZOOMY) + { + Update_rect( x_pos, y_pos, + width * Main_magnifier_factor, end_y_pos - y_pos ); + return; + } + bx --; + } + while (bx > 0); + + // Passage à la ligne suivante dans la brosse aussi + src+=brush_width; + } +} + +void Clear_brush_scaled_triple(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) +{ + + // En fait on va recopier l'image non zoomée dans la partie zoomée ! + byte* src = Main_screen + y_offset * image_width + x_offset; + int y = y_pos; + int bx; + + // Pour chaque ligne à zoomer + while(1){ + Zoom_a_line(src,buffer,Main_magnifier_factor*ZOOMX,width); + + bx=Main_magnifier_factor; + + // Pour chaque ligne + do{ + // TODO a verifier + Display_line_on_screen_fast_triple(x_pos,y, + width * Main_magnifier_factor,buffer); + + // Ligne suivante + y++; + if(y==end_y_pos) + { + Update_rect(x_pos,y_pos, + width*Main_magnifier_factor,end_y_pos-y_pos); + return; + } + bx--; + }while(bx!=0); + + src+= image_width; + } +} + + diff --git a/pxtriple.h b/pxtriple.h index 15c03e6d..6e470548 100644 --- a/pxtriple.h +++ b/pxtriple.h @@ -1,48 +1,48 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file pxtriple.h -/// Renderer for triple pixels (3x3). -////////////////////////////////////////////////////////////////////////////// - -#include "struct.h" - - void Pixel_triple (word x,word y,byte color); - byte Read_pixel_triple (word x,word y); - void Block_triple (word start_x,word start_y,word width,word height,byte color); - void Pixel_preview_normal_triple (word x,word y,byte color); - void Pixel_preview_magnifier_triple (word x,word y,byte color); - void Horizontal_XOR_line_triple (word x_pos,word y_pos,word width); - void Vertical_XOR_line_triple (word x_pos,word y_pos,word height); - void Display_brush_color_triple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); - void Display_brush_mono_triple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); - void Clear_brush_triple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); - void Remap_screen_triple (word x_pos,word y_pos,word width,word height,byte * conversion_table); - void Display_part_of_screen_triple (word width,word height,word image_width); - void Display_line_on_screen_triple (word x_pos,word y_pos,word width,byte * line); - void Read_line_screen_triple (word x_pos,word y_pos,word width,byte * line); - void Display_part_of_screen_scaled_triple(word width,word height,word image_width,byte * buffer); - void Display_brush_color_zoom_triple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); - void Display_brush_mono_zoom_triple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); - void Clear_brush_scaled_triple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); - void Display_brush_triple (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); - - void Display_line_on_screen_fast_triple (word x_pos,word y_pos,word width,byte * line); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file pxtriple.h +/// Renderer for triple pixels (3x3). +////////////////////////////////////////////////////////////////////////////// + +#include "struct.h" + + void Pixel_triple (word x,word y,byte color); + byte Read_pixel_triple (word x,word y); + void Block_triple (word start_x,word start_y,word width,word height,byte color); + void Pixel_preview_normal_triple (word x,word y,byte color); + void Pixel_preview_magnifier_triple (word x,word y,byte color); + void Horizontal_XOR_line_triple (word x_pos,word y_pos,word width); + void Vertical_XOR_line_triple (word x_pos,word y_pos,word height); + void Display_brush_color_triple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); + void Display_brush_mono_triple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); + void Clear_brush_triple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); + void Remap_screen_triple (word x_pos,word y_pos,word width,word height,byte * conversion_table); + void Display_part_of_screen_triple (word width,word height,word image_width); + void Display_line_on_screen_triple (word x_pos,word y_pos,word width,byte * line); + void Read_line_screen_triple (word x_pos,word y_pos,word width,byte * line); + void Display_part_of_screen_scaled_triple(word width,word height,word image_width,byte * buffer); + void Display_brush_color_zoom_triple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); + void Display_brush_mono_zoom_triple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); + void Clear_brush_scaled_triple (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); + void Display_brush_triple (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); + + void Display_line_on_screen_fast_triple (word x_pos,word y_pos,word width,byte * line); diff --git a/pxwide.c b/pxwide.c index ffabba61..204258c8 100644 --- a/pxwide.c +++ b/pxwide.c @@ -1,506 +1,506 @@ -/* 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 -*/ - -#include -#include -#include -#include "global.h" -#include "sdlscreen.h" -#include "misc.h" -#include "pxwide.h" - -#define ZOOMX 2 -#define ZOOMY 1 - -void Pixel_wide (word x,word y,byte color) -/* Affiche un pixel de la color aux coords x;y à l'écran */ -{ - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 1)=color; -} - -byte Read_pixel_wide (word x,word y) -/* On retourne la couleur du pixel aux coords données */ -{ - return *( Screen_pixels + y * ZOOMY * VIDEO_LINE_WIDTH + x * ZOOMX); -} - -void Block_wide (word start_x,word start_y,word width,word height,byte color) -/* On affiche un rectangle de la couleur donnée */ -{ - SDL_Rect rectangle; - rectangle.x=start_x*ZOOMX; - rectangle.y=start_y*ZOOMY; - rectangle.w=width*ZOOMX; - rectangle.h=height*ZOOMY; - SDL_FillRect(Screen_SDL,&rectangle,color); -} - -void Display_part_of_screen_wide (word width,word height,word image_width) -/* Afficher une partie de l'image telle quelle sur l'écran */ -{ - byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) - byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) - int y; - int dy; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - // On fait une copie de la ligne - for (dy=width;dy>0;dy--) - { - *(dest+1)=*dest=*src; - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - src+=image_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - } - //Update_rect(0,0,width,height); -} - -void Pixel_preview_normal_wide (word x,word y,byte color) -/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image - * dans l'écran, en mode normal (pas en mode loupe) - * Note: si on modifie cette procédure, il faudra penser à faire également - * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ -{ -// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) - Pixel_wide(x-Main_offset_X,y-Main_offset_Y,color); -} - -void Pixel_preview_magnifier_wide (word x,word y,byte color) -{ - // Affiche le pixel dans la partie non zoomée - Pixel_wide(x-Main_offset_X,y-Main_offset_Y,color); - - // Regarde si on doit aussi l'afficher dans la partie zoomée - if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom - && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) - { - // On est dedans - int height; - int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); - - if (Menu_Y - y_zoom < Main_magnifier_factor) - // On ne doit dessiner qu'un morceau du pixel - // sinon on dépasse sur le menu - height = Menu_Y - y_zoom; - else - height = Main_magnifier_factor; - - Block_wide( - Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, - y_zoom, Main_magnifier_factor, height, color - ); - } -} - -void Horizontal_XOR_line_wide(word x_pos,word y_pos,word width) -{ - //On calcule la valeur initiale de dest: - byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; - - int x; - - for (x=0;x0;i--) - { - *dest=*(dest+1)=~*dest; - dest+=VIDEO_LINE_WIDTH*ZOOMY; - } -} - -void Display_brush_color_wide(word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) -{ - // dest = Position à l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - // src = Position dans la brosse - byte* src = Brush + y_offset * brush_width + x_offset; - - word x,y; - - // Pour chaque ligne - for(y = height;y > 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *(dest+1) = *dest = *src; - } - - // Pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - src = src + brush_width - width; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Display_brush_mono_wide(word x_pos, word y_pos, - word x_offset, word y_offset, word width, word height, - byte transp_color, byte color, word brush_width) -/* On affiche la brosse en monochrome */ -{ - byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; // dest = adr destination à - // l'écran - byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds - // la brosse - int x,y; - - for(y=height;y!=0;y--) - //Pour chaque ligne - { - for(x=width;x!=0;x--) - //Pour chaque pixel - { - if (*src!=transp_color) - *(dest+1)=*dest=color; - - // On passe au pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - src+=brush_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Clear_brush_wide(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) -{ - byte* dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) - byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) - int y; - int x; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - for(x=width;x!=0;x--) - //Pour chaque pixel - { - *(dest+1)=*dest=*src; - - // On passe au pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - src+=image_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; - } - Update_rect(x_pos,y_pos,width,height); -} - -// Affiche une brosse (arbitraire) à l'écran -void Display_brush_wide(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) -{ - // dest = Position à l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - // src = Position dans la brosse - byte* src = brush + y_offset * brush_width + x_offset; - - word x,y; - - // Pour chaque ligne - for(y = height;y > 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *(dest+1) = *dest = *src; - } - - // Pixel suivant - src++; dest+=ZOOMX; - } - - // On passe à la ligne suivante - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - src = src + brush_width - width; - } -} - -void Remap_screen_wide(word x_pos,word y_pos,word width,word height,byte * conversion_table) -{ - // dest = coords a l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - int x,y; - - // Pour chaque ligne - for(y=height;y>0;y--) - { - // Pour chaque pixel - for(x=width;x>0;x--) - { - *(dest+1) = *dest = conversion_table[*dest]; - dest +=ZOOMX; - } - - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - } - - Update_rect(x_pos,y_pos,width,height); -} - -void Display_line_on_screen_fast_wide(word x_pos,word y_pos,word width,byte * line) -/* On affiche toute une ligne de pixels telle quelle. */ -/* Utilisée si le buffer contient déja des pixel doublés. */ -{ - memcpy(Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH,line,width*ZOOMX); -} - -void Display_line_on_screen_wide(word x_pos,word y_pos,word width,byte * line) -/* On affiche une ligne de pixels en les doublant. */ -{ - int x; - byte *dest; - dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; - for(x=width;x>0;x--) - { - *(dest+1)=*dest=*line; - dest+=ZOOMX; - line++; - } -} -void Display_transparent_mono_line_on_screen_wide( - word x_pos, word y_pos, word width, byte* line, - byte transp_color, byte color) -// Affiche une ligne à l'écran avec une couleur + transparence. -// Utilisé par les brosses en mode zoom -{ - byte* dest = Screen_pixels+ y_pos*VIDEO_LINE_WIDTH + x_pos*ZOOMX; - int x; - // Pour chaque pixel - for(x=0;x 0); - src += image_width; - } -// ATTENTION on n'arrive jamais ici ! -} - -void Display_transparent_line_on_screen_wide(word x_pos,word y_pos,word width,byte* line,byte transp_color) -{ - byte* src = line; - byte* dest = Screen_pixels+ y_pos*VIDEO_LINE_WIDTH + x_pos*ZOOMX; - word x; - - // Pour chaque pixel de la ligne - for(x = width;x > 0;x--) - { - if(*src!=transp_color) - { - *(dest+1) = *dest = *src; - } - src++; - dest+=ZOOMX; - } -} - -// Affiche une partie de la brosse couleur zoomée -void Display_brush_color_zoom_wide(word x_pos,word y_pos, - word x_offset,word y_offset, - word width, // width non zoomée - word end_y_pos,byte transp_color, - word brush_width, // width réelle de la brosse - byte * buffer) -{ - byte* src = Brush+y_offset*brush_width + x_offset; - word y = y_pos; - byte bx; - - // Pour chaque ligne - while(1) - { - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - // On affiche facteur fois la ligne zoomée - for(bx=Main_magnifier_factor;bx>0;bx--) - { - Display_transparent_line_on_screen_wide(x_pos,y*ZOOMY,width*Main_magnifier_factor,buffer,transp_color); - y++; - if(y==end_y_pos) - { - return; - } - } - src += brush_width; - } - // ATTENTION zone jamais atteinte -} - -void Display_brush_mono_zoom_wide(word x_pos, word y_pos, - word x_offset, word y_offset, - word width, // width non zoomée - word end_y_pos, - byte transp_color, byte color, - word brush_width, // width réelle de la brosse - byte * buffer -) - -{ - byte* src = Brush + y_offset * brush_width + x_offset; - int y=y_pos*ZOOMY; - - //Pour chaque ligne à zoomer : - while(1) - { - int bx; - // src = Ligne originale - // On éclate la ligne - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - - // On affiche la ligne Facteur fois à l'écran (sur des - // lignes consécutives) - bx = Main_magnifier_factor*ZOOMY; - - // Pour chaque ligne écran - do - { - // On affiche la ligne zoomée - Display_transparent_mono_line_on_screen_wide( - x_pos, y, width * Main_magnifier_factor, - buffer, transp_color, color - ); - // On passe à la ligne suivante - y++; - // On vérifie qu'on est pas à la ligne finale - if(y == end_y_pos*ZOOMY) - { - Update_rect( x_pos, y_pos, - width * Main_magnifier_factor, end_y_pos - y_pos ); - return; - } - bx --; - } - while (bx > 0); - - // Passage à la ligne suivante dans la brosse aussi - src+=brush_width; - } -} - -void Clear_brush_scaled_wide(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) -{ - // En fait on va recopier l'image non zoomée dans la partie zoomée ! - byte* src = Main_screen + y_offset * image_width + x_offset; - int y = y_pos; - int bx; - - // Pour chaque ligne à zoomer - while(1){ - Zoom_a_line(src,buffer,Main_magnifier_factor*ZOOMX,width); - - bx=Main_magnifier_factor; - - // Pour chaque ligne - do{ - Display_line_on_screen_fast_wide(x_pos,y, - width * Main_magnifier_factor,buffer); - - // Ligne suivante - y++; - if(y==end_y_pos) - { - Update_rect(x_pos,y_pos, - width*Main_magnifier_factor,end_y_pos-y_pos); - return; - } - bx--; - }while(bx!=0); - - src+= image_width; - } -} - - +/* 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 +*/ + +#include +#include +#include +#include "global.h" +#include "sdlscreen.h" +#include "misc.h" +#include "pxwide.h" + +#define ZOOMX 2 +#define ZOOMY 1 + +void Pixel_wide (word x,word y,byte color) +/* Affiche un pixel de la color aux coords x;y à l'écran */ +{ + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 1)=color; +} + +byte Read_pixel_wide (word x,word y) +/* On retourne la couleur du pixel aux coords données */ +{ + return *( Screen_pixels + y * ZOOMY * VIDEO_LINE_WIDTH + x * ZOOMX); +} + +void Block_wide (word start_x,word start_y,word width,word height,byte color) +/* On affiche un rectangle de la couleur donnée */ +{ + SDL_Rect rectangle; + rectangle.x=start_x*ZOOMX; + rectangle.y=start_y*ZOOMY; + rectangle.w=width*ZOOMX; + rectangle.h=height*ZOOMY; + SDL_FillRect(Screen_SDL,&rectangle,color); +} + +void Display_part_of_screen_wide (word width,word height,word image_width) +/* Afficher une partie de l'image telle quelle sur l'écran */ +{ + byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) + byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) + int y; + int dy; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + // On fait une copie de la ligne + for (dy=width;dy>0;dy--) + { + *(dest+1)=*dest=*src; + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + src+=image_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + } + //Update_rect(0,0,width,height); +} + +void Pixel_preview_normal_wide (word x,word y,byte color) +/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image + * dans l'écran, en mode normal (pas en mode loupe) + * Note: si on modifie cette procédure, il faudra penser à faire également + * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ +{ +// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) + Pixel_wide(x-Main_offset_X,y-Main_offset_Y,color); +} + +void Pixel_preview_magnifier_wide (word x,word y,byte color) +{ + // Affiche le pixel dans la partie non zoomée + Pixel_wide(x-Main_offset_X,y-Main_offset_Y,color); + + // Regarde si on doit aussi l'afficher dans la partie zoomée + if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom + && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) + { + // On est dedans + int height; + int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); + + if (Menu_Y - y_zoom < Main_magnifier_factor) + // On ne doit dessiner qu'un morceau du pixel + // sinon on dépasse sur le menu + height = Menu_Y - y_zoom; + else + height = Main_magnifier_factor; + + Block_wide( + Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, + y_zoom, Main_magnifier_factor, height, color + ); + } +} + +void Horizontal_XOR_line_wide(word x_pos,word y_pos,word width) +{ + //On calcule la valeur initiale de dest: + byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; + + int x; + + for (x=0;x0;i--) + { + *dest=*(dest+1)=~*dest; + dest+=VIDEO_LINE_WIDTH*ZOOMY; + } +} + +void Display_brush_color_wide(word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) +{ + // dest = Position à l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + // src = Position dans la brosse + byte* src = Brush + y_offset * brush_width + x_offset; + + word x,y; + + // Pour chaque ligne + for(y = height;y > 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *(dest+1) = *dest = *src; + } + + // Pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + src = src + brush_width - width; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Display_brush_mono_wide(word x_pos, word y_pos, + word x_offset, word y_offset, word width, word height, + byte transp_color, byte color, word brush_width) +/* On affiche la brosse en monochrome */ +{ + byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; // dest = adr destination à + // l'écran + byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds + // la brosse + int x,y; + + for(y=height;y!=0;y--) + //Pour chaque ligne + { + for(x=width;x!=0;x--) + //Pour chaque pixel + { + if (*src!=transp_color) + *(dest+1)=*dest=color; + + // On passe au pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + src+=brush_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Clear_brush_wide(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) +{ + byte* dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) + byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) + int y; + int x; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + for(x=width;x!=0;x--) + //Pour chaque pixel + { + *(dest+1)=*dest=*src; + + // On passe au pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + src+=image_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; + } + Update_rect(x_pos,y_pos,width,height); +} + +// Affiche une brosse (arbitraire) à l'écran +void Display_brush_wide(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) +{ + // dest = Position à l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + // src = Position dans la brosse + byte* src = brush + y_offset * brush_width + x_offset; + + word x,y; + + // Pour chaque ligne + for(y = height;y > 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *(dest+1) = *dest = *src; + } + + // Pixel suivant + src++; dest+=ZOOMX; + } + + // On passe à la ligne suivante + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + src = src + brush_width - width; + } +} + +void Remap_screen_wide(word x_pos,word y_pos,word width,word height,byte * conversion_table) +{ + // dest = coords a l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + int x,y; + + // Pour chaque ligne + for(y=height;y>0;y--) + { + // Pour chaque pixel + for(x=width;x>0;x--) + { + *(dest+1) = *dest = conversion_table[*dest]; + dest +=ZOOMX; + } + + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + } + + Update_rect(x_pos,y_pos,width,height); +} + +void Display_line_on_screen_fast_wide(word x_pos,word y_pos,word width,byte * line) +/* On affiche toute une ligne de pixels telle quelle. */ +/* Utilisée si le buffer contient déja des pixel doublés. */ +{ + memcpy(Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH,line,width*ZOOMX); +} + +void Display_line_on_screen_wide(word x_pos,word y_pos,word width,byte * line) +/* On affiche une ligne de pixels en les doublant. */ +{ + int x; + byte *dest; + dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; + for(x=width;x>0;x--) + { + *(dest+1)=*dest=*line; + dest+=ZOOMX; + line++; + } +} +void Display_transparent_mono_line_on_screen_wide( + word x_pos, word y_pos, word width, byte* line, + byte transp_color, byte color) +// Affiche une ligne à l'écran avec une couleur + transparence. +// Utilisé par les brosses en mode zoom +{ + byte* dest = Screen_pixels+ y_pos*VIDEO_LINE_WIDTH + x_pos*ZOOMX; + int x; + // Pour chaque pixel + for(x=0;x 0); + src += image_width; + } +// ATTENTION on n'arrive jamais ici ! +} + +void Display_transparent_line_on_screen_wide(word x_pos,word y_pos,word width,byte* line,byte transp_color) +{ + byte* src = line; + byte* dest = Screen_pixels+ y_pos*VIDEO_LINE_WIDTH + x_pos*ZOOMX; + word x; + + // Pour chaque pixel de la ligne + for(x = width;x > 0;x--) + { + if(*src!=transp_color) + { + *(dest+1) = *dest = *src; + } + src++; + dest+=ZOOMX; + } +} + +// Affiche une partie de la brosse couleur zoomée +void Display_brush_color_zoom_wide(word x_pos,word y_pos, + word x_offset,word y_offset, + word width, // width non zoomée + word end_y_pos,byte transp_color, + word brush_width, // width réelle de la brosse + byte * buffer) +{ + byte* src = Brush+y_offset*brush_width + x_offset; + word y = y_pos; + byte bx; + + // Pour chaque ligne + while(1) + { + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + // On affiche facteur fois la ligne zoomée + for(bx=Main_magnifier_factor;bx>0;bx--) + { + Display_transparent_line_on_screen_wide(x_pos,y*ZOOMY,width*Main_magnifier_factor,buffer,transp_color); + y++; + if(y==end_y_pos) + { + return; + } + } + src += brush_width; + } + // ATTENTION zone jamais atteinte +} + +void Display_brush_mono_zoom_wide(word x_pos, word y_pos, + word x_offset, word y_offset, + word width, // width non zoomée + word end_y_pos, + byte transp_color, byte color, + word brush_width, // width réelle de la brosse + byte * buffer +) + +{ + byte* src = Brush + y_offset * brush_width + x_offset; + int y=y_pos*ZOOMY; + + //Pour chaque ligne à zoomer : + while(1) + { + int bx; + // src = Ligne originale + // On éclate la ligne + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + + // On affiche la ligne Facteur fois à l'écran (sur des + // lignes consécutives) + bx = Main_magnifier_factor*ZOOMY; + + // Pour chaque ligne écran + do + { + // On affiche la ligne zoomée + Display_transparent_mono_line_on_screen_wide( + x_pos, y, width * Main_magnifier_factor, + buffer, transp_color, color + ); + // On passe à la ligne suivante + y++; + // On vérifie qu'on est pas à la ligne finale + if(y == end_y_pos*ZOOMY) + { + Update_rect( x_pos, y_pos, + width * Main_magnifier_factor, end_y_pos - y_pos ); + return; + } + bx --; + } + while (bx > 0); + + // Passage à la ligne suivante dans la brosse aussi + src+=brush_width; + } +} + +void Clear_brush_scaled_wide(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) +{ + // En fait on va recopier l'image non zoomée dans la partie zoomée ! + byte* src = Main_screen + y_offset * image_width + x_offset; + int y = y_pos; + int bx; + + // Pour chaque ligne à zoomer + while(1){ + Zoom_a_line(src,buffer,Main_magnifier_factor*ZOOMX,width); + + bx=Main_magnifier_factor; + + // Pour chaque ligne + do{ + Display_line_on_screen_fast_wide(x_pos,y, + width * Main_magnifier_factor,buffer); + + // Ligne suivante + y++; + if(y==end_y_pos) + { + Update_rect(x_pos,y_pos, + width*Main_magnifier_factor,end_y_pos-y_pos); + return; + } + bx--; + }while(bx!=0); + + src+= image_width; + } +} + + diff --git a/pxwide.h b/pxwide.h index f7003c54..b1db7ec4 100644 --- a/pxwide.h +++ b/pxwide.h @@ -1,49 +1,49 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file pxwide.h -/// Renderer for wide pixels (2x1). -////////////////////////////////////////////////////////////////////////////// - -#include "struct.h" - - void Pixel_wide (word x,word y,byte color); - byte Read_pixel_wide (word x,word y); - void Block_wide (word start_x,word start_y,word width,word height,byte color); - void Pixel_preview_normal_wide (word x,word y,byte color); - void Pixel_preview_magnifier_wide (word x,word y,byte color); - void Horizontal_XOR_line_wide (word x_pos,word y_pos,word width); - void Vertical_XOR_line_wide (word x_pos,word y_pos,word height); - void Display_brush_color_wide (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); - void Display_brush_mono_wide (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); - void Clear_brush_wide (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); - void Remap_screen_wide (word x_pos,word y_pos,word width,word height,byte * conversion_table); - void Display_part_of_screen_wide (word width,word height,word image_width); - void Display_line_on_screen_wide (word x_pos,word y_pos,word width,byte * line); - void Read_line_screen_wide (word x_pos,word y_pos,word width,byte * line); - void Display_part_of_screen_scaled_wide(word width,word height,word image_width,byte * buffer); - void Display_brush_color_zoom_wide (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); - void Display_brush_mono_zoom_wide (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); - void Clear_brush_scaled_wide (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); - void Display_brush_wide (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); - - void Display_line_on_screen_fast_wide (word x_pos,word y_pos,word width,byte * line); - void Display_transparent_line_on_screen_wide(word x_pos,word y_pos,word width,byte* line,byte transp_color); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file pxwide.h +/// Renderer for wide pixels (2x1). +////////////////////////////////////////////////////////////////////////////// + +#include "struct.h" + + void Pixel_wide (word x,word y,byte color); + byte Read_pixel_wide (word x,word y); + void Block_wide (word start_x,word start_y,word width,word height,byte color); + void Pixel_preview_normal_wide (word x,word y,byte color); + void Pixel_preview_magnifier_wide (word x,word y,byte color); + void Horizontal_XOR_line_wide (word x_pos,word y_pos,word width); + void Vertical_XOR_line_wide (word x_pos,word y_pos,word height); + void Display_brush_color_wide (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); + void Display_brush_mono_wide (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); + void Clear_brush_wide (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); + void Remap_screen_wide (word x_pos,word y_pos,word width,word height,byte * conversion_table); + void Display_part_of_screen_wide (word width,word height,word image_width); + void Display_line_on_screen_wide (word x_pos,word y_pos,word width,byte * line); + void Read_line_screen_wide (word x_pos,word y_pos,word width,byte * line); + void Display_part_of_screen_scaled_wide(word width,word height,word image_width,byte * buffer); + void Display_brush_color_zoom_wide (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); + void Display_brush_mono_zoom_wide (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); + void Clear_brush_scaled_wide (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); + void Display_brush_wide (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); + + void Display_line_on_screen_fast_wide (word x_pos,word y_pos,word width,byte * line); + void Display_transparent_line_on_screen_wide(word x_pos,word y_pos,word width,byte* line,byte transp_color); diff --git a/pxwide2.c b/pxwide2.c index 15358dbb..82d429fe 100644 --- a/pxwide2.c +++ b/pxwide2.c @@ -1,514 +1,514 @@ -/* 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 -*/ - -#include -#include -#include -#include "global.h" -#include "sdlscreen.h" -#include "misc.h" -#include "pxwide2.h" - -#define ZOOMX 4 -#define ZOOMY 2 - -void Pixel_wide2 (word x,word y,byte color) -/* Affiche un pixel de la color aux coords x;y à l'écran */ -{ - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 1)=color; - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 2)=color; - *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 3)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 1)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 2)=color; - *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 3)=color; -} - -byte Read_pixel_wide2 (word x,word y) -/* On retourne la couleur du pixel aux coords données */ -{ - return *( Screen_pixels + y * ZOOMY * VIDEO_LINE_WIDTH + x * ZOOMX); -} - -void Block_wide2 (word start_x,word start_y,word width,word height,byte color) -/* On affiche un rectangle de la couleur donnée */ -{ - SDL_Rect rectangle; - rectangle.x=start_x*ZOOMX; - rectangle.y=start_y*ZOOMY; - rectangle.w=width*ZOOMX; - rectangle.h=height*ZOOMY; - SDL_FillRect(Screen_SDL,&rectangle,color); -} - -void Display_part_of_screen_wide2 (word width,word height,word image_width) -/* Afficher une partie de l'image telle quelle sur l'écran */ -{ - byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) - byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) - int y; - int dy; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - // On fait une copie de la ligne - for (dy=width;dy>0;dy--) - { - *(dest+3)=*(dest+2)=*(dest+1)=*dest=*src; - src++; - dest+=ZOOMX; - } - // On double la ligne qu'on vient de copier - memcpy(dest-width*ZOOMX+VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); - - // On passe à la ligne suivante - src+=image_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - } - //Update_rect(0,0,width,height); -} - -void Pixel_preview_normal_wide2 (word x,word y,byte color) -/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image - * dans l'écran, en mode normal (pas en mode loupe) - * Note: si on modifie cette procédure, il faudra penser à faire également - * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ -{ -// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) - Pixel_wide2(x-Main_offset_X,y-Main_offset_Y,color); -} - -void Pixel_preview_magnifier_wide2 (word x,word y,byte color) -{ - // Affiche le pixel dans la partie non zoomée - Pixel_wide2(x-Main_offset_X,y-Main_offset_Y,color); - - // Regarde si on doit aussi l'afficher dans la partie zoomée - if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom - && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) - { - // On est dedans - int height; - int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); - - if (Menu_Y - y_zoom < Main_magnifier_factor) - // On ne doit dessiner qu'un morceau du pixel - // sinon on dépasse sur le menu - height = Menu_Y - y_zoom; - else - height = Main_magnifier_factor; - - Block_wide2( - Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, - y_zoom, Main_magnifier_factor, height, color - ); - } -} - -void Horizontal_XOR_line_wide2(word x_pos,word y_pos,word width) -{ - //On calcule la valeur initiale de dest: - byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; - - int x; - - for (x=0;x0;i--) - { - *(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*(dest)=~*(dest); - dest+=VIDEO_LINE_WIDTH*ZOOMY; - } -} - -void Display_brush_color_wide2(word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) -{ - // dest = Position à l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - // src = Position dans la brosse - byte* src = Brush + y_offset * brush_width + x_offset; - - word x,y; - - // Pour chaque ligne - for(y = height;y > 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *(dest+VIDEO_LINE_WIDTH+3) = *(dest+VIDEO_LINE_WIDTH+2) = *(dest+VIDEO_LINE_WIDTH+1) = *(dest+VIDEO_LINE_WIDTH) = *(dest+3) = *(dest+2) = *(dest+1) = *dest = *src; - } - - // Pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - src = src + brush_width - width; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Display_brush_mono_wide2(word x_pos, word y_pos, - word x_offset, word y_offset, word width, word height, - byte transp_color, byte color, word brush_width) -/* On affiche la brosse en monochrome */ -{ - byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; // dest = adr destination à - // l'écran - byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds - // la brosse - int x,y; - - for(y=height;y!=0;y--) - //Pour chaque ligne - { - for(x=width;x!=0;x--) - //Pour chaque pixel - { - if (*src!=transp_color) - *(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=color; - - // On passe au pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - src+=brush_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; - } - Update_rect(x_pos,y_pos,width,height); -} - -void Clear_brush_wide2(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) -{ - byte* dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) - byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) - int y; - int x; - - for(y=height;y!=0;y--) - // Pour chaque ligne - { - for(x=width;x!=0;x--) - //Pour chaque pixel - { - *(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=*src; - - // On passe au pixel suivant - src++; - dest+=ZOOMX; - } - - // On passe à la ligne suivante - src+=image_width-width; - dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; - } - Update_rect(x_pos,y_pos,width,height); -} - -// Affiche une brosse (arbitraire) à l'écran -void Display_brush_wide2(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) -{ - // dest = Position à l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - // src = Position dans la brosse - byte* src = brush + y_offset * brush_width + x_offset; - - word x,y; - - // Pour chaque ligne - for(y = height;y > 0; y--) - { - // Pour chaque pixel - for(x = width;x > 0; x--) - { - // On vérifie que ce n'est pas la transparence - if(*src != transp_color) - { - *(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=*src; - } - - // Pixel suivant - src++; dest+=ZOOMX; - } - - // On passe à la ligne suivante - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - src = src + brush_width - width; - } -} - -void Remap_screen_wide2(word x_pos,word y_pos,word width,word height,byte * conversion_table) -{ - // dest = coords a l'écran - byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - int x,y; - - // Pour chaque ligne - for(y=height;y>0;y--) - { - // Pour chaque pixel - for(x=width;x>0;x--) - { - *(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest= - conversion_table[*dest]; - dest +=ZOOMX; - } - - dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; - } - - Update_rect(x_pos,y_pos,width,height); -} - -void Display_line_on_screen_fast_wide2(word x_pos,word y_pos,word width,byte * line) -/* On affiche toute une ligne de pixels telle quelle. */ -/* Utilisée si le buffer contient déja des pixel doublés. */ -{ - memcpy(Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH,line,width*ZOOMX); - memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+1)*VIDEO_LINE_WIDTH,line,width*ZOOMX); -} - -void Display_line_on_screen_wide2(word x_pos,word y_pos,word width,byte * line) -/* On affiche une ligne de pixels en les doublant. */ -{ - int x; - byte *dest; - dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; - for(x=width;x>0;x--) - { - *(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=*line; - dest+=ZOOMX; - line++; - } -} -void Display_transparent_mono_line_on_screen_wide2( - word x_pos, word y_pos, word width, byte* line, - byte transp_color, byte color) -// Affiche une ligne à l'écran avec une couleur + transparence. -// Utilisé par les brosses en mode zoom -{ - byte* dest = Screen_pixels+ y_pos*VIDEO_LINE_WIDTH + x_pos*ZOOMX; - int x; - // Pour chaque pixel - for(x=0;x 0); - src += image_width; - } -// ATTENTION on n'arrive jamais ici ! -} - -// Affiche une partie de la brosse couleur zoomée -void Display_brush_color_zoom_wide2(word x_pos,word y_pos, - word x_offset,word y_offset, - word width, // width non zoomée - word end_y_pos,byte transp_color, - word brush_width, // width réelle de la brosse - byte * buffer) -{ - byte* src = Brush+y_offset*brush_width + x_offset; - word y = y_pos; - byte bx; - - // Pour chaque ligne - while(1) - { - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - // On affiche facteur fois la ligne zoomée - for(bx=Main_magnifier_factor;bx>0;bx--) - { - byte* line_src = buffer; - byte* dest = Screen_pixels + y*ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; - word x; - // Pour chaque pixel de la ligne - for(x = width*Main_magnifier_factor;x > 0;x--) - { - if(*line_src!=transp_color) - { - *(dest+3)=*(dest+2)=*(dest+1)=*dest = *line_src; - } - line_src++; - dest+=ZOOMX; - } - // Double the line - memcpy(Screen_pixels + (y*ZOOMY+1)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); - y++; - if(y==end_y_pos) - { - return; - } - } - src += brush_width; - } - // ATTENTION zone jamais atteinte -} - -void Display_brush_mono_zoom_wide2(word x_pos, word y_pos, - word x_offset, word y_offset, - word width, // width non zoomée - word end_y_pos, - byte transp_color, byte color, - word brush_width, // width réelle de la brosse - byte * buffer -) - -{ - byte* src = Brush + y_offset * brush_width + x_offset; - int y=y_pos*ZOOMY; - - //Pour chaque ligne à zoomer : - while(1) - { - int bx; - // src = Ligne originale - // On éclate la ligne - Zoom_a_line(src,buffer,Main_magnifier_factor,width); - - // On affiche la ligne Facteur fois à l'écran (sur des - // lignes consécutives) - bx = Main_magnifier_factor*ZOOMY; - - // Pour chaque ligne écran - do - { - // On affiche la ligne zoomée - Display_transparent_mono_line_on_screen_wide2( - x_pos, y, width * Main_magnifier_factor, - buffer, transp_color, color - ); - // On passe à la ligne suivante - y++; - // On vérifie qu'on est pas à la ligne finale - if(y == end_y_pos*ZOOMY) - { - Update_rect( x_pos, y_pos, - width * Main_magnifier_factor, end_y_pos - y_pos ); - return; - } - bx --; - } - while (bx > 0); - - // Passage à la ligne suivante dans la brosse aussi - src+=brush_width; - } -} - -void Clear_brush_scaled_wide2(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) -{ - - // En fait on va recopier l'image non zoomée dans la partie zoomée ! - byte* src = Main_screen + y_offset * image_width + x_offset; - int y = y_pos; - int bx; - - // Pour chaque ligne à zoomer - while(1){ - Zoom_a_line(src,buffer,Main_magnifier_factor*ZOOMX,width); - - bx=Main_magnifier_factor; - - // Pour chaque ligne - do{ - // TODO a verifier - Display_line_on_screen_fast_wide2(x_pos,y, - width * Main_magnifier_factor,buffer); - - // Ligne suivante - y++; - if(y==end_y_pos) - { - Update_rect(x_pos,y_pos, - width*Main_magnifier_factor,end_y_pos-y_pos); - return; - } - bx--; - }while(bx!=0); - - src+= image_width; - } -} - - +/* 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 +*/ + +#include +#include +#include +#include "global.h" +#include "sdlscreen.h" +#include "misc.h" +#include "pxwide2.h" + +#define ZOOMX 4 +#define ZOOMY 2 + +void Pixel_wide2 (word x,word y,byte color) +/* Affiche un pixel de la color aux coords x;y à l'écran */ +{ + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 1)=color; + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 2)=color; + *(Screen_pixels + x * ZOOMX + y*ZOOMY * VIDEO_LINE_WIDTH + 3)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 1)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 2)=color; + *(Screen_pixels + x * ZOOMX + (y*ZOOMY+1) * VIDEO_LINE_WIDTH + 3)=color; +} + +byte Read_pixel_wide2 (word x,word y) +/* On retourne la couleur du pixel aux coords données */ +{ + return *( Screen_pixels + y * ZOOMY * VIDEO_LINE_WIDTH + x * ZOOMX); +} + +void Block_wide2 (word start_x,word start_y,word width,word height,byte color) +/* On affiche un rectangle de la couleur donnée */ +{ + SDL_Rect rectangle; + rectangle.x=start_x*ZOOMX; + rectangle.y=start_y*ZOOMY; + rectangle.w=width*ZOOMX; + rectangle.h=height*ZOOMY; + SDL_FillRect(Screen_SDL,&rectangle,color); +} + +void Display_part_of_screen_wide2 (word width,word height,word image_width) +/* Afficher une partie de l'image telle quelle sur l'écran */ +{ + byte* dest=Screen_pixels; //On va se mettre en 0,0 dans l'écran (dest) + byte* src=Main_offset_Y*image_width+Main_offset_X+Main_screen; //Coords de départ ds la source (src) + int y; + int dy; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + // On fait une copie de la ligne + for (dy=width;dy>0;dy--) + { + *(dest+3)=*(dest+2)=*(dest+1)=*dest=*src; + src++; + dest+=ZOOMX; + } + // On double la ligne qu'on vient de copier + memcpy(dest-width*ZOOMX+VIDEO_LINE_WIDTH,dest-width*ZOOMX,width*ZOOMX); + + // On passe à la ligne suivante + src+=image_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + } + //Update_rect(0,0,width,height); +} + +void Pixel_preview_normal_wide2 (word x,word y,byte color) +/* Affichage d'un pixel dans l'écran, par rapport au décalage de l'image + * dans l'écran, en mode normal (pas en mode loupe) + * Note: si on modifie cette procédure, il faudra penser à faire également + * la modif dans la procédure Pixel_Preview_Loupe_SDL. */ +{ +// if(x-Main_offset_X >= 0 && y - Main_offset_Y >= 0) + Pixel_wide2(x-Main_offset_X,y-Main_offset_Y,color); +} + +void Pixel_preview_magnifier_wide2 (word x,word y,byte color) +{ + // Affiche le pixel dans la partie non zoomée + Pixel_wide2(x-Main_offset_X,y-Main_offset_Y,color); + + // Regarde si on doit aussi l'afficher dans la partie zoomée + if (y >= Limit_top_zoom && y <= Limit_visible_bottom_zoom + && x >= Limit_left_zoom && x <= Limit_visible_right_zoom) + { + // On est dedans + int height; + int y_zoom = Main_magnifier_factor * (y-Main_magnifier_offset_Y); + + if (Menu_Y - y_zoom < Main_magnifier_factor) + // On ne doit dessiner qu'un morceau du pixel + // sinon on dépasse sur le menu + height = Menu_Y - y_zoom; + else + height = Main_magnifier_factor; + + Block_wide2( + Main_magnifier_factor * (x-Main_magnifier_offset_X) + Main_X_zoom, + y_zoom, Main_magnifier_factor, height, color + ); + } +} + +void Horizontal_XOR_line_wide2(word x_pos,word y_pos,word width) +{ + //On calcule la valeur initiale de dest: + byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; + + int x; + + for (x=0;x0;i--) + { + *(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*(dest)=~*(dest); + dest+=VIDEO_LINE_WIDTH*ZOOMY; + } +} + +void Display_brush_color_wide2(word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) +{ + // dest = Position à l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + // src = Position dans la brosse + byte* src = Brush + y_offset * brush_width + x_offset; + + word x,y; + + // Pour chaque ligne + for(y = height;y > 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *(dest+VIDEO_LINE_WIDTH+3) = *(dest+VIDEO_LINE_WIDTH+2) = *(dest+VIDEO_LINE_WIDTH+1) = *(dest+VIDEO_LINE_WIDTH) = *(dest+3) = *(dest+2) = *(dest+1) = *dest = *src; + } + + // Pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + src = src + brush_width - width; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Display_brush_mono_wide2(word x_pos, word y_pos, + word x_offset, word y_offset, word width, word height, + byte transp_color, byte color, word brush_width) +/* On affiche la brosse en monochrome */ +{ + byte* dest=y_pos*ZOOMY*VIDEO_LINE_WIDTH+x_pos*ZOOMX+Screen_pixels; // dest = adr destination à + // l'écran + byte* src=brush_width*y_offset+x_offset+Brush; // src = adr ds + // la brosse + int x,y; + + for(y=height;y!=0;y--) + //Pour chaque ligne + { + for(x=width;x!=0;x--) + //Pour chaque pixel + { + if (*src!=transp_color) + *(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=color; + + // On passe au pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + src+=brush_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; + } + Update_rect(x_pos,y_pos,width,height); +} + +void Clear_brush_wide2(word x_pos,word y_pos,__attribute__((unused)) word x_offset,__attribute__((unused)) word y_offset,word width,word height,__attribute__((unused))byte transp_color,word image_width) +{ + byte* dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; //On va se mettre en 0,0 dans l'écran (dest) + byte* src = ( y_pos + Main_offset_Y ) * image_width + x_pos + Main_offset_X + Main_screen; //Coords de départ ds la source (src) + int y; + int x; + + for(y=height;y!=0;y--) + // Pour chaque ligne + { + for(x=width;x!=0;x--) + //Pour chaque pixel + { + *(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=*src; + + // On passe au pixel suivant + src++; + dest+=ZOOMX; + } + + // On passe à la ligne suivante + src+=image_width-width; + dest+=VIDEO_LINE_WIDTH*ZOOMY-width*ZOOMX; + } + Update_rect(x_pos,y_pos,width,height); +} + +// Affiche une brosse (arbitraire) à l'écran +void Display_brush_wide2(byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width) +{ + // dest = Position à l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + // src = Position dans la brosse + byte* src = brush + y_offset * brush_width + x_offset; + + word x,y; + + // Pour chaque ligne + for(y = height;y > 0; y--) + { + // Pour chaque pixel + for(x = width;x > 0; x--) + { + // On vérifie que ce n'est pas la transparence + if(*src != transp_color) + { + *(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=*src; + } + + // Pixel suivant + src++; dest+=ZOOMX; + } + + // On passe à la ligne suivante + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + src = src + brush_width - width; + } +} + +void Remap_screen_wide2(word x_pos,word y_pos,word width,word height,byte * conversion_table) +{ + // dest = coords a l'écran + byte* dest = Screen_pixels + y_pos * ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + int x,y; + + // Pour chaque ligne + for(y=height;y>0;y--) + { + // Pour chaque pixel + for(x=width;x>0;x--) + { + *(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest= + conversion_table[*dest]; + dest +=ZOOMX; + } + + dest = dest + VIDEO_LINE_WIDTH*ZOOMY - width*ZOOMX; + } + + Update_rect(x_pos,y_pos,width,height); +} + +void Display_line_on_screen_fast_wide2(word x_pos,word y_pos,word width,byte * line) +/* On affiche toute une ligne de pixels telle quelle. */ +/* Utilisée si le buffer contient déja des pixel doublés. */ +{ + memcpy(Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH,line,width*ZOOMX); + memcpy(Screen_pixels+x_pos*ZOOMX+(y_pos*ZOOMY+1)*VIDEO_LINE_WIDTH,line,width*ZOOMX); +} + +void Display_line_on_screen_wide2(word x_pos,word y_pos,word width,byte * line) +/* On affiche une ligne de pixels en les doublant. */ +{ + int x; + byte *dest; + dest=Screen_pixels+x_pos*ZOOMX+y_pos*ZOOMY*VIDEO_LINE_WIDTH; + for(x=width;x>0;x--) + { + *(dest+VIDEO_LINE_WIDTH+3)=*(dest+VIDEO_LINE_WIDTH+2)=*(dest+VIDEO_LINE_WIDTH+1)=*(dest+VIDEO_LINE_WIDTH)=*(dest+3)=*(dest+2)=*(dest+1)=*dest=*line; + dest+=ZOOMX; + line++; + } +} +void Display_transparent_mono_line_on_screen_wide2( + word x_pos, word y_pos, word width, byte* line, + byte transp_color, byte color) +// Affiche une ligne à l'écran avec une couleur + transparence. +// Utilisé par les brosses en mode zoom +{ + byte* dest = Screen_pixels+ y_pos*VIDEO_LINE_WIDTH + x_pos*ZOOMX; + int x; + // Pour chaque pixel + for(x=0;x 0); + src += image_width; + } +// ATTENTION on n'arrive jamais ici ! +} + +// Affiche une partie de la brosse couleur zoomée +void Display_brush_color_zoom_wide2(word x_pos,word y_pos, + word x_offset,word y_offset, + word width, // width non zoomée + word end_y_pos,byte transp_color, + word brush_width, // width réelle de la brosse + byte * buffer) +{ + byte* src = Brush+y_offset*brush_width + x_offset; + word y = y_pos; + byte bx; + + // Pour chaque ligne + while(1) + { + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + // On affiche facteur fois la ligne zoomée + for(bx=Main_magnifier_factor;bx>0;bx--) + { + byte* line_src = buffer; + byte* dest = Screen_pixels + y*ZOOMY * VIDEO_LINE_WIDTH + x_pos * ZOOMX; + word x; + // Pour chaque pixel de la ligne + for(x = width*Main_magnifier_factor;x > 0;x--) + { + if(*line_src!=transp_color) + { + *(dest+3)=*(dest+2)=*(dest+1)=*dest = *line_src; + } + line_src++; + dest+=ZOOMX; + } + // Double the line + memcpy(Screen_pixels + (y*ZOOMY+1)*VIDEO_LINE_WIDTH + x_pos*ZOOMX, Screen_pixels + y*ZOOMY*VIDEO_LINE_WIDTH + x_pos*ZOOMX, width*ZOOMX*Main_magnifier_factor); + y++; + if(y==end_y_pos) + { + return; + } + } + src += brush_width; + } + // ATTENTION zone jamais atteinte +} + +void Display_brush_mono_zoom_wide2(word x_pos, word y_pos, + word x_offset, word y_offset, + word width, // width non zoomée + word end_y_pos, + byte transp_color, byte color, + word brush_width, // width réelle de la brosse + byte * buffer +) + +{ + byte* src = Brush + y_offset * brush_width + x_offset; + int y=y_pos*ZOOMY; + + //Pour chaque ligne à zoomer : + while(1) + { + int bx; + // src = Ligne originale + // On éclate la ligne + Zoom_a_line(src,buffer,Main_magnifier_factor,width); + + // On affiche la ligne Facteur fois à l'écran (sur des + // lignes consécutives) + bx = Main_magnifier_factor*ZOOMY; + + // Pour chaque ligne écran + do + { + // On affiche la ligne zoomée + Display_transparent_mono_line_on_screen_wide2( + x_pos, y, width * Main_magnifier_factor, + buffer, transp_color, color + ); + // On passe à la ligne suivante + y++; + // On vérifie qu'on est pas à la ligne finale + if(y == end_y_pos*ZOOMY) + { + Update_rect( x_pos, y_pos, + width * Main_magnifier_factor, end_y_pos - y_pos ); + return; + } + bx --; + } + while (bx > 0); + + // Passage à la ligne suivante dans la brosse aussi + src+=brush_width; + } +} + +void Clear_brush_scaled_wide2(word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,__attribute__((unused)) byte transp_color,word image_width,byte * buffer) +{ + + // En fait on va recopier l'image non zoomée dans la partie zoomée ! + byte* src = Main_screen + y_offset * image_width + x_offset; + int y = y_pos; + int bx; + + // Pour chaque ligne à zoomer + while(1){ + Zoom_a_line(src,buffer,Main_magnifier_factor*ZOOMX,width); + + bx=Main_magnifier_factor; + + // Pour chaque ligne + do{ + // TODO a verifier + Display_line_on_screen_fast_wide2(x_pos,y, + width * Main_magnifier_factor,buffer); + + // Ligne suivante + y++; + if(y==end_y_pos) + { + Update_rect(x_pos,y_pos, + width*Main_magnifier_factor,end_y_pos-y_pos); + return; + } + bx--; + }while(bx!=0); + + src+= image_width; + } +} + + diff --git a/pxwide2.h b/pxwide2.h index bcc5eed0..15dff2d9 100644 --- a/pxwide2.h +++ b/pxwide2.h @@ -1,48 +1,48 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file pxwide2.h -/// Renderer for double-wide pixels (4x2). -////////////////////////////////////////////////////////////////////////////// - -#include "struct.h" - - void Pixel_wide2 (word x,word y,byte color); - byte Read_pixel_wide2 (word x,word y); - void Block_wide2 (word start_x,word start_y,word width,word height,byte color); - void Pixel_preview_normal_wide2 (word x,word y,byte color); - void Pixel_preview_magnifier_wide2 (word x,word y,byte color); - void Horizontal_XOR_line_wide2 (word x_pos,word y_pos,word width); - void Vertical_XOR_line_wide2 (word x_pos,word y_pos,word height); - void Display_brush_color_wide2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); - void Display_brush_mono_wide2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); - void Clear_brush_wide2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); - void Remap_screen_wide2 (word x_pos,word y_pos,word width,word height,byte * conversion_table); - void Display_part_of_screen_wide2 (word width,word height,word image_width); - void Display_line_on_screen_wide2 (word x_pos,word y_pos,word width,byte * line); - void Read_line_screen_wide2 (word x_pos,word y_pos,word width,byte * line); - void Display_part_of_screen_scaled_wide2(word width,word height,word image_width,byte * buffer); - void Display_brush_color_zoom_wide2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); - void Display_brush_mono_zoom_wide2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); - void Clear_brush_scaled_wide2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); - void Display_brush_wide2 (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); - - void Display_line_on_screen_fast_wide2 (word x_pos,word y_pos,word width,byte * line); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file pxwide2.h +/// Renderer for double-wide pixels (4x2). +////////////////////////////////////////////////////////////////////////////// + +#include "struct.h" + + void Pixel_wide2 (word x,word y,byte color); + byte Read_pixel_wide2 (word x,word y); + void Block_wide2 (word start_x,word start_y,word width,word height,byte color); + void Pixel_preview_normal_wide2 (word x,word y,byte color); + void Pixel_preview_magnifier_wide2 (word x,word y,byte color); + void Horizontal_XOR_line_wide2 (word x_pos,word y_pos,word width); + void Vertical_XOR_line_wide2 (word x_pos,word y_pos,word height); + void Display_brush_color_wide2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); + void Display_brush_mono_wide2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,byte color,word brush_width); + void Clear_brush_wide2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word image_width); + void Remap_screen_wide2 (word x_pos,word y_pos,word width,word height,byte * conversion_table); + void Display_part_of_screen_wide2 (word width,word height,word image_width); + void Display_line_on_screen_wide2 (word x_pos,word y_pos,word width,byte * line); + void Read_line_screen_wide2 (word x_pos,word y_pos,word width,byte * line); + void Display_part_of_screen_scaled_wide2(word width,word height,word image_width,byte * buffer); + void Display_brush_color_zoom_wide2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word brush_width,byte * buffer); + void Display_brush_mono_zoom_wide2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,byte color,word brush_width,byte * buffer); + void Clear_brush_scaled_wide2 (word x_pos,word y_pos,word x_offset,word y_offset,word width,word end_y_pos,byte transp_color,word image_width,byte * buffer); + void Display_brush_wide2 (byte * brush, word x_pos,word y_pos,word x_offset,word y_offset,word width,word height,byte transp_color,word brush_width); + + void Display_line_on_screen_fast_wide2 (word x_pos,word y_pos,word width,byte * line); diff --git a/readini.h b/readini.h index 7715ac8b..02188f3d 100644 --- a/readini.h +++ b/readini.h @@ -1,27 +1,27 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file readini.h -/// Reading settings in gfx2.ini -////////////////////////////////////////////////////////////////////////////// - -int Load_INI(T_Config * conf); -int Load_INI_seek_pattern(char * buffer,char * pattern); -void Load_INI_clear_string(char * str, byte keep_comments); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file readini.h +/// Reading settings in gfx2.ini +////////////////////////////////////////////////////////////////////////////// + +int Load_INI(T_Config * conf); +int Load_INI_seek_pattern(char * buffer,char * pattern); +void Load_INI_clear_string(char * str, byte keep_comments); diff --git a/readline.c b/readline.c index 293de1b5..15c2e291 100644 --- a/readline.c +++ b/readline.c @@ -1,350 +1,350 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 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 -*/ -/************************************************************************ -* * -* READLINE (procédure permettant de saisir une chaîne de caractères) * -* * -************************************************************************/ - -#include -#include - -#include "const.h" -#include "struct.h" -#include "global.h" -#include "misc.h" -#include "errors.h" -#include "const.h" -#include "sdlscreen.h" -#include "readline.h" -#include "windows.h" -#include "input.h" - -#define TEXT_COLOR MC_Black -#define BACKGROUND_COLOR MC_Light -#define CURSOR_COLOR MC_Black -#define CURSOR_BACKGROUND_COLOR MC_Dark - -// Suppresion d'un caractère à une certaine POSITION dans une CHAINE. -void Remove_character(char * str, byte position) -{ - for (;str[position]!='\0';position++) - str[position]=str[position+1]; -} - - -void Insert_character(char * str, char letter, byte position) -// Insertion d'une LETTRE à une certaine POSITION -// dans une CHAINE d'une certaine TAILLE. -{ - char temp_char; - - for (;letter!='\0';position++) - { - // On mémorise le caractère qui se trouve en "position" - temp_char=str[position]; - // On splotch la lettre à insérer - str[position]=letter; - // On place le caractère mémorisé dans "letter" comme nouvelle lettre à insérer - letter=temp_char; - } - // On termine la chaine - str[position]='\0'; -} - -int Valid_character(int c) -{ - // Sous Linux: Seul le / est strictement interdit, mais beaucoup - // d'autres poseront des problèmes au shell, alors on évite. - // Sous Windows : c'est moins grave car le fopen() échouerait de toutes façons. - // AmigaOS4: Pas de ':' car utilisé pour les volumes. - #if defined(__WIN32__) - char forbidden_char[] = {'/', '|', '?', '*', '<', '>', ':', '\\'}; - #elif defined (__amigaos4__) - char forbidden_char[] = {'/', '|', '?', '*', '<', '>', ':'}; - #else - char forbidden_char[] = {'/', '|', '?', '*', '<', '>'}; - #endif - int position; - - if (c < ' ' || c > 255) - return 0; - - for (position=0; position<(long)sizeof(forbidden_char); position++) - if (c == forbidden_char[position]) - return 0; - return 1; -} - -void Display_whole_string(word x_pos,word y_pos,char * str,byte position) -{ - Print_in_window(x_pos,y_pos,str,TEXT_COLOR,BACKGROUND_COLOR); - Print_char_in_window(x_pos+(position<<3),y_pos,str[position],CURSOR_COLOR,CURSOR_BACKGROUND_COLOR); -} - -/**************************************************************************** -* Enhanced super scanf deluxe pro plus giga mieux :-) * -****************************************************************************/ -byte Readline(word x_pos,word y_pos,char * str,byte visible_size,byte input_type) -// Paramètres: -// x_pos, y_pos : Coordonnées de la saisie dans la fenêtre -// str : Chaîne recevant la saisie (et contenant éventuellement une valeur initiale) -// max_size : Nombre de caractères logeant dans la zone de saisie -// input_type : 0=Chaîne, 1=Nombre, 2=Nom de fichier -// Sortie: -// 0: Sortie par annulation (Esc.) / 1: sortie par acceptation (Return) -{ - byte max_size; - // Grosse astuce pour les noms de fichiers: La taille affichée est différente - // de la taille maximum gérée. - if (input_type == 2) - max_size = 255; - else - max_size = visible_size; - return Readline_ex(x_pos,y_pos,str,visible_size,max_size,input_type); -} - -/**************************************************************************** -* Enhanced super scanf deluxe pro plus giga mieux :-) * -****************************************************************************/ -byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_size, byte input_type) -// Paramètres: -// x_pos, y_pos : Coordonnées de la saisie dans la fenêtre -// str : Chaîne recevant la saisie (et contenant éventuellement une valeur initiale) -// max_size : Nombre de caractères logeant dans la zone de saisie -// input_type : 0=Chaîne, 1=Nombre, 2=Nom de fichier -// Sortie: -// 0: Sortie par annulation (Esc.) / 1: sortie par acceptation (Return) -{ - char initial_string[256]; - char display_string[256]; - byte position; - byte size; - word input_key=0; - byte is_authorized; - - byte offset=0; // index du premier caractère affiché - - Hide_cursor(); - // Effacement de la chaîne - Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), - visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR); - Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), - visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3)); - - // Mise à jour des variables se rapportant à la chaîne en fonction de la chaîne initiale - strcpy(initial_string,str); - - // Si on a commencé à editer par un clic-droit, on vide la chaine. - if (Mouse_K==RIGHT_SIDE) - str[0]='\0'; - else if (input_type==1) - snprintf(str,10,"%d",atoi(str)); // On tasse la chaine à gauche - - - size=strlen(str); - position=(sizevisible_size) - offset=position-visible_size+1; - // Formatage d'une partie de la chaine (si trop longue pour tenir) - strncpy(display_string, str + offset, visible_size); - display_string[visible_size]='\0'; - if (offset>0) - display_string[0]=LEFT_TRIANGLE_CHARACTER; - if (visible_size + offset + 1 < size ) - display_string[visible_size-1]=RIGHT_TRIANGLE_CHARACTER; - - Display_whole_string(x_pos,y_pos,display_string,position - offset); - Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), - visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3)); - Flush_update(); - - while ((input_key!=SDLK_RETURN) && (input_key!=KEY_ESC)) - { - Display_cursor(); - do - { - if(!Get_input()) SDL_Delay(20); - input_key=Key_ANSI; - } while(input_key==0); - Hide_cursor(); - switch (input_key) - { - case SDLK_DELETE : // Suppr. - if (position0) - { - // Effacement de la chaîne - if (position==size) - Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), - visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR); - position--; - if (offset > 0 && (position == 0 || position < (offset + 1))) - offset--; - goto affichage; - } - break; - case SDLK_RIGHT : // Droite - if ((position visible_size + offset - 2) - //if (offset + visible_size < max_size && (position == size || (position > visible_size + offset - 2))) - if (display_string[position-offset]==RIGHT_TRIANGLE_CHARACTER || position-offset>=visible_size) - offset++; - goto affichage; - } - break; - case SDLK_HOME : // Home - if (position) - { - // Effacement de la chaîne - if (position==size) - Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), - visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR); - position = 0; - offset = 0; - goto affichage; - } - break; - case SDLK_END : // End - if ((positionvisible_size) - offset=position-visible_size+1; - goto affichage; - } - break; - case SDLK_BACKSPACE : // Backspace : combinaison de gauche + suppr - - if (position) - { - position--; - if (offset > 0 && (position == 0 || position < (offset + 1))) - offset--; - Remove_character(str,position); - size--; - // Effacement de la chaîne - Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), - visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR); - goto affichage; - } - break; - case SDLK_RETURN : - break; - - case KEY_ESC : - // On restaure la chaine initiale - strcpy(str,initial_string); - size=strlen(str); - break; - default : - if (size=' ' && input_key<= 255) - is_authorized=1; - break; - case 1 : // Nombre - if ( (input_key>='0') && (input_key<='9') ) - is_authorized=1; - break; - default : // Nom de fichier - // On regarde si la touche est autorisée - if ( Valid_character(input_key)) - is_authorized=1; - } // End du "switch(input_type)" - - // Si la touche était autorisée... - if (is_authorized) - { - // ... alors on l'insère ... - Insert_character(str,input_key,position/*,size*/); - // ce qui augmente la taille de la chaine - size++; - // et qui risque de déplacer le curseur vers la droite - if (size=visible_size) - offset++; - } - // Enfin, on raffiche la chaine - goto affichage; - } // End du test d'autorisation de touche - } // End du test de place libre - break; - -affichage: - size=strlen(str); - // Formatage d'une partie de la chaine (si trop longue pour tenir) - strncpy(display_string, str + offset, visible_size); - display_string[visible_size]='\0'; - if (offset>0) - display_string[0]=LEFT_TRIANGLE_CHARACTER; - if (visible_size + offset + 0 < size ) - display_string[visible_size-1]=RIGHT_TRIANGLE_CHARACTER; - - Display_whole_string(x_pos,y_pos,display_string,position - offset); - Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), - visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3)); - } // End du "switch(input_key)" - Flush_update(); - - } // End du "while" - - // Effacement de la chaîne - Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), - visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR); - // On raffiche la chaine correctement - if (input_type==1) - { - if (str[0]=='\0') - { - strcpy(str,"0"); - size=1; - } - Print_in_window(x_pos+((max_size-size)<<3),y_pos,str,TEXT_COLOR,BACKGROUND_COLOR); - } - else - { - Print_in_window_limited(x_pos,y_pos,str,visible_size,TEXT_COLOR,BACKGROUND_COLOR); - } - Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), - visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3)); - - return (input_key==SDLK_RETURN); -} +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 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 +*/ +/************************************************************************ +* * +* READLINE (procédure permettant de saisir une chaîne de caractères) * +* * +************************************************************************/ + +#include +#include + +#include "const.h" +#include "struct.h" +#include "global.h" +#include "misc.h" +#include "errors.h" +#include "const.h" +#include "sdlscreen.h" +#include "readline.h" +#include "windows.h" +#include "input.h" + +#define TEXT_COLOR MC_Black +#define BACKGROUND_COLOR MC_Light +#define CURSOR_COLOR MC_Black +#define CURSOR_BACKGROUND_COLOR MC_Dark + +// Suppresion d'un caractère à une certaine POSITION dans une CHAINE. +void Remove_character(char * str, byte position) +{ + for (;str[position]!='\0';position++) + str[position]=str[position+1]; +} + + +void Insert_character(char * str, char letter, byte position) +// Insertion d'une LETTRE à une certaine POSITION +// dans une CHAINE d'une certaine TAILLE. +{ + char temp_char; + + for (;letter!='\0';position++) + { + // On mémorise le caractère qui se trouve en "position" + temp_char=str[position]; + // On splotch la lettre à insérer + str[position]=letter; + // On place le caractère mémorisé dans "letter" comme nouvelle lettre à insérer + letter=temp_char; + } + // On termine la chaine + str[position]='\0'; +} + +int Valid_character(int c) +{ + // Sous Linux: Seul le / est strictement interdit, mais beaucoup + // d'autres poseront des problèmes au shell, alors on évite. + // Sous Windows : c'est moins grave car le fopen() échouerait de toutes façons. + // AmigaOS4: Pas de ':' car utilisé pour les volumes. + #if defined(__WIN32__) + char forbidden_char[] = {'/', '|', '?', '*', '<', '>', ':', '\\'}; + #elif defined (__amigaos4__) + char forbidden_char[] = {'/', '|', '?', '*', '<', '>', ':'}; + #else + char forbidden_char[] = {'/', '|', '?', '*', '<', '>'}; + #endif + int position; + + if (c < ' ' || c > 255) + return 0; + + for (position=0; position<(long)sizeof(forbidden_char); position++) + if (c == forbidden_char[position]) + return 0; + return 1; +} + +void Display_whole_string(word x_pos,word y_pos,char * str,byte position) +{ + Print_in_window(x_pos,y_pos,str,TEXT_COLOR,BACKGROUND_COLOR); + Print_char_in_window(x_pos+(position<<3),y_pos,str[position],CURSOR_COLOR,CURSOR_BACKGROUND_COLOR); +} + +/**************************************************************************** +* Enhanced super scanf deluxe pro plus giga mieux :-) * +****************************************************************************/ +byte Readline(word x_pos,word y_pos,char * str,byte visible_size,byte input_type) +// Paramètres: +// x_pos, y_pos : Coordonnées de la saisie dans la fenêtre +// str : Chaîne recevant la saisie (et contenant éventuellement une valeur initiale) +// max_size : Nombre de caractères logeant dans la zone de saisie +// input_type : 0=Chaîne, 1=Nombre, 2=Nom de fichier +// Sortie: +// 0: Sortie par annulation (Esc.) / 1: sortie par acceptation (Return) +{ + byte max_size; + // Grosse astuce pour les noms de fichiers: La taille affichée est différente + // de la taille maximum gérée. + if (input_type == 2) + max_size = 255; + else + max_size = visible_size; + return Readline_ex(x_pos,y_pos,str,visible_size,max_size,input_type); +} + +/**************************************************************************** +* Enhanced super scanf deluxe pro plus giga mieux :-) * +****************************************************************************/ +byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_size, byte input_type) +// Paramètres: +// x_pos, y_pos : Coordonnées de la saisie dans la fenêtre +// str : Chaîne recevant la saisie (et contenant éventuellement une valeur initiale) +// max_size : Nombre de caractères logeant dans la zone de saisie +// input_type : 0=Chaîne, 1=Nombre, 2=Nom de fichier +// Sortie: +// 0: Sortie par annulation (Esc.) / 1: sortie par acceptation (Return) +{ + char initial_string[256]; + char display_string[256]; + byte position; + byte size; + word input_key=0; + byte is_authorized; + + byte offset=0; // index du premier caractère affiché + + Hide_cursor(); + // Effacement de la chaîne + Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), + visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR); + Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), + visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3)); + + // Mise à jour des variables se rapportant à la chaîne en fonction de la chaîne initiale + strcpy(initial_string,str); + + // Si on a commencé à editer par un clic-droit, on vide la chaine. + if (Mouse_K==RIGHT_SIDE) + str[0]='\0'; + else if (input_type==1) + snprintf(str,10,"%d",atoi(str)); // On tasse la chaine à gauche + + + size=strlen(str); + position=(sizevisible_size) + offset=position-visible_size+1; + // Formatage d'une partie de la chaine (si trop longue pour tenir) + strncpy(display_string, str + offset, visible_size); + display_string[visible_size]='\0'; + if (offset>0) + display_string[0]=LEFT_TRIANGLE_CHARACTER; + if (visible_size + offset + 1 < size ) + display_string[visible_size-1]=RIGHT_TRIANGLE_CHARACTER; + + Display_whole_string(x_pos,y_pos,display_string,position - offset); + Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), + visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3)); + Flush_update(); + + while ((input_key!=SDLK_RETURN) && (input_key!=KEY_ESC)) + { + Display_cursor(); + do + { + if(!Get_input()) SDL_Delay(20); + input_key=Key_ANSI; + } while(input_key==0); + Hide_cursor(); + switch (input_key) + { + case SDLK_DELETE : // Suppr. + if (position0) + { + // Effacement de la chaîne + if (position==size) + Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), + visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR); + position--; + if (offset > 0 && (position == 0 || position < (offset + 1))) + offset--; + goto affichage; + } + break; + case SDLK_RIGHT : // Droite + if ((position visible_size + offset - 2) + //if (offset + visible_size < max_size && (position == size || (position > visible_size + offset - 2))) + if (display_string[position-offset]==RIGHT_TRIANGLE_CHARACTER || position-offset>=visible_size) + offset++; + goto affichage; + } + break; + case SDLK_HOME : // Home + if (position) + { + // Effacement de la chaîne + if (position==size) + Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), + visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR); + position = 0; + offset = 0; + goto affichage; + } + break; + case SDLK_END : // End + if ((positionvisible_size) + offset=position-visible_size+1; + goto affichage; + } + break; + case SDLK_BACKSPACE : // Backspace : combinaison de gauche + suppr + + if (position) + { + position--; + if (offset > 0 && (position == 0 || position < (offset + 1))) + offset--; + Remove_character(str,position); + size--; + // Effacement de la chaîne + Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), + visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR); + goto affichage; + } + break; + case SDLK_RETURN : + break; + + case KEY_ESC : + // On restaure la chaine initiale + strcpy(str,initial_string); + size=strlen(str); + break; + default : + if (size=' ' && input_key<= 255) + is_authorized=1; + break; + case 1 : // Nombre + if ( (input_key>='0') && (input_key<='9') ) + is_authorized=1; + break; + default : // Nom de fichier + // On regarde si la touche est autorisée + if ( Valid_character(input_key)) + is_authorized=1; + } // End du "switch(input_type)" + + // Si la touche était autorisée... + if (is_authorized) + { + // ... alors on l'insère ... + Insert_character(str,input_key,position/*,size*/); + // ce qui augmente la taille de la chaine + size++; + // et qui risque de déplacer le curseur vers la droite + if (size=visible_size) + offset++; + } + // Enfin, on raffiche la chaine + goto affichage; + } // End du test d'autorisation de touche + } // End du test de place libre + break; + +affichage: + size=strlen(str); + // Formatage d'une partie de la chaine (si trop longue pour tenir) + strncpy(display_string, str + offset, visible_size); + display_string[visible_size]='\0'; + if (offset>0) + display_string[0]=LEFT_TRIANGLE_CHARACTER; + if (visible_size + offset + 0 < size ) + display_string[visible_size-1]=RIGHT_TRIANGLE_CHARACTER; + + Display_whole_string(x_pos,y_pos,display_string,position - offset); + Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), + visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3)); + } // End du "switch(input_key)" + Flush_update(); + + } // End du "while" + + // Effacement de la chaîne + Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), + visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR); + // On raffiche la chaine correctement + if (input_type==1) + { + if (str[0]=='\0') + { + strcpy(str,"0"); + size=1; + } + Print_in_window(x_pos+((max_size-size)<<3),y_pos,str,TEXT_COLOR,BACKGROUND_COLOR); + } + else + { + Print_in_window_limited(x_pos,y_pos,str,visible_size,TEXT_COLOR,BACKGROUND_COLOR); + } + Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y), + visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3)); + + return (input_key==SDLK_RETURN); +} diff --git a/readline.h b/readline.h index b2a3675f..f76242a3 100644 --- a/readline.h +++ b/readline.h @@ -1,44 +1,44 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file readline.h -/// Text input functions. -////////////////////////////////////////////////////////////////////////////// - -/// -/// Lets the user input a line of text, exit by Esc or Return. -/// @param x_pos Coordinates of input, in window coordinates before scaling. -/// @param y_pos Coordinates of input, in window coordinates before scaling. -/// @param str The original string value (will be modified, unless user cancels. -/// @param visible_size Number of characters visible and editable. -/// @param input_type 0=string, 1=number, 2=filename (255 editable characters) -/// @return 0 if user cancelled (esc), 1 if accepted (return) -byte Readline(word x_pos,word y_pos,char * str,byte visible_size,byte input_type); - -/// -/// Lets the user input a line of text, exit by Esc or Return. -/// @param x_pos Coordinates of input, in window coordinates before scaling. -/// @param y_pos Coordinates of input, in window coordinates before scaling. -/// @param str The original string value (will be modified, unless user cancels. -/// @param visible_size Number of characters visible. -/// @param max_size Number of characters editable. -/// @param input_type 0=string, 1=number, 2=filename (255 editable characters) -/// @return 0 if user cancelled (esc), 1 if accepted (return) -byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_size, byte input_type); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file readline.h +/// Text input functions. +////////////////////////////////////////////////////////////////////////////// + +/// +/// Lets the user input a line of text, exit by Esc or Return. +/// @param x_pos Coordinates of input, in window coordinates before scaling. +/// @param y_pos Coordinates of input, in window coordinates before scaling. +/// @param str The original string value (will be modified, unless user cancels. +/// @param visible_size Number of characters visible and editable. +/// @param input_type 0=string, 1=number, 2=filename (255 editable characters) +/// @return 0 if user cancelled (esc), 1 if accepted (return) +byte Readline(word x_pos,word y_pos,char * str,byte visible_size,byte input_type); + +/// +/// Lets the user input a line of text, exit by Esc or Return. +/// @param x_pos Coordinates of input, in window coordinates before scaling. +/// @param y_pos Coordinates of input, in window coordinates before scaling. +/// @param str The original string value (will be modified, unless user cancels. +/// @param visible_size Number of characters visible. +/// @param max_size Number of characters editable. +/// @param input_type 0=string, 1=number, 2=filename (255 editable characters) +/// @return 0 if user cancelled (esc), 1 if accepted (return) +byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_size, byte input_type); diff --git a/saveini.h b/saveini.h index 6d1f58df..93f9647b 100644 --- a/saveini.h +++ b/saveini.h @@ -1,25 +1,25 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file saveini.h -/// Saving settings in gfx2.ini -////////////////////////////////////////////////////////////////////////////// - -int Save_INI(T_Config * conf); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file saveini.h +/// Saving settings in gfx2.ini +////////////////////////////////////////////////////////////////////////////// + +int Save_INI(T_Config * conf); diff --git a/setup.c b/setup.c index 5b54ce09..4e259390 100644 --- a/setup.c +++ b/setup.c @@ -1,182 +1,182 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 Peter Gordon - 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 -*/ - -#include -#include -#include -#include -#include -#if defined(__WIN32__) - #include - #include // Mingw's _mkdir() -#elif defined(__macosx__) - #import - #import -#elif defined(__FreeBSD__) - #import -#endif - -#include "struct.h" -#include "io.h" -#include "setup.h" - -int Create_ConfigDirectory(char * config_dir) -{ - #ifdef __WIN32__ - // Mingw's mkdir has a weird name and only one argument - return _mkdir(config_dir); - #else - return mkdir(config_dir,S_IRUSR|S_IWUSR|S_IXUSR); - #endif -} - -#if defined(__macosx__) || defined(__amigaos4__) || defined(__AROS__) || defined(__MORPHOS__) || defined(__amigaos__) - #define ARG_UNUSED __attribute__((unused)) -#else - #define ARG_UNUSED -#endif -// Determine which directory contains the executable. -// IN: Main's argv[0], some platforms need it, some don't. -// OUT: Write into program_dir. Trailing / or \ is kept. -// Note : in fact this is only used to check for the datafiles and fonts in -// this same directory. -void Set_program_directory(ARG_UNUSED const char * argv0,char * program_dir) -{ - #undef ARG_UNUSED - - // MacOSX - #if defined(__macosx__) - CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFURLGetFileSystemRepresentation(url,true,(UInt8*)program_dir,MAXPATHLEN); - CFRelease(url); - // Append trailing slash - strcat(program_dir ,"/"); - - // AmigaOS and alike: hard-coded volume name. - #elif defined(__amigaos4__) || defined(__AROS__) || defined(__MORPHOS__) || defined(__amigaos__) - strcpy(program_dir,"PROGDIR:"); - - // Others: The part of argv[0] before the executable name. - // Keep the last \ or /. - // Note that on Unix, once installed, the executable is called from a shell - // script sitting in /usr/local/bin/, this allows argv[0] to contain the full - // path. On Windows, Mingw32 already provides the full path in all cases. - #else - Extract_path(program_dir, argv0); - #endif -} - -// Determine which directory contains the read-only data. -// IN: The directory containing the executable -// OUT: Write into data_dir. Trailing / or \ is kept. -void Set_data_directory(const char * program_dir, char * data_dir) -{ - // On all platforms, data is in the executable's directory - strcpy(data_dir,program_dir); - // Except MacOSX, here it is stored in a special folder: - #if defined(__macosx__) - strcat(data_dir,"Contents/Resources/"); - #endif -} - -// Determine which directory should store the user's configuration. -// -// For most Unix and Windows platforms: -// If a config file already exists in program_dir, it will return it in priority -// (Useful for development, and possibly for upgrading from DOS version) -// If the standard directory doesn't exist yet, this function will attempt -// to create it ($(HOME)/.grafx2, or %APPDATA%\GrafX2) -// If it cannot be created, this function will return the executable's -// own directory. -// IN: The directory containing the executable -// OUT: Write into config_dir. Trailing / or \ is kept. -void Set_config_directory(const char * program_dir, char * config_dir) -{ - // AmigaOS4 - #if defined(__amigaos4__) || defined(__AROS__) - strcpy(config_dir,"PROGDIR:"); - // GP2X - #elif defined(__GP2X__) - // On the GP2X, the program is installed to the sdcard, and we don't want to mess with the system tree which is - // on an internal flash chip. So, keep these settings locals. - strcpy(config_dir,program_dir); - #else - char filename[MAX_PATH_CHARACTERS]; - - // In priority: check own directory - strcpy(config_dir, program_dir); - strcpy(filename, config_dir); - strcat(filename, "gfx2.cfg"); - - if (!File_exists(filename)) - { - char *config_parent_dir; - #if defined(__WIN32__) - // "%APPDATA%\GrafX2" - const char* Config_SubDir = "GrafX2"; - config_parent_dir = getenv("APPDATA"); - #elif defined(__BEOS__) || defined(__HAIKU__) - // "~/.grafx2", the BeOS way - const char* Config_SubDir = ".grafx2"; - config_parent_dir = getenv("$HOME"); - #elif defined(__macosx__) - // "~/Library/Preferences/com.googlecode.grafx2" - const char* Config_SubDir = "Library/Preferences/com.googlecode.grafx2"; - config_parent_dir = getenv("HOME"); - #else - // "~/.grafx2" - const char* Config_SubDir = ".grafx2"; - config_parent_dir = getenv("HOME"); - #endif - - if (config_parent_dir && config_parent_dir[0]!='\0') - { - int size = strlen(config_parent_dir); - strcpy(config_dir, config_parent_dir); - if (config_parent_dir[size-1] != '\\' && config_parent_dir[size-1] != '/') - { - strcat(config_dir,PATH_SEPARATOR); - } - strcat(config_dir,Config_SubDir); - if (Directory_exists(config_dir)) - { - // Répertoire trouvé, ok - strcat(config_dir,PATH_SEPARATOR); - } - else - { - // Tentative de création - if (!Create_ConfigDirectory(config_dir)) - { - // Réussi - strcat(config_dir,PATH_SEPARATOR); - } - else - { - // Echec: on se rabat sur le repertoire de l'executable. - strcpy(config_dir,program_dir); - } - } - } - } - #endif -} +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 Peter Gordon + 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 +*/ + +#include +#include +#include +#include +#include +#if defined(__WIN32__) + #include + #include // Mingw's _mkdir() +#elif defined(__macosx__) + #import + #import +#elif defined(__FreeBSD__) + #import +#endif + +#include "struct.h" +#include "io.h" +#include "setup.h" + +int Create_ConfigDirectory(char * config_dir) +{ + #ifdef __WIN32__ + // Mingw's mkdir has a weird name and only one argument + return _mkdir(config_dir); + #else + return mkdir(config_dir,S_IRUSR|S_IWUSR|S_IXUSR); + #endif +} + +#if defined(__macosx__) || defined(__amigaos4__) || defined(__AROS__) || defined(__MORPHOS__) || defined(__amigaos__) + #define ARG_UNUSED __attribute__((unused)) +#else + #define ARG_UNUSED +#endif +// Determine which directory contains the executable. +// IN: Main's argv[0], some platforms need it, some don't. +// OUT: Write into program_dir. Trailing / or \ is kept. +// Note : in fact this is only used to check for the datafiles and fonts in +// this same directory. +void Set_program_directory(ARG_UNUSED const char * argv0,char * program_dir) +{ + #undef ARG_UNUSED + + // MacOSX + #if defined(__macosx__) + CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); + CFURLGetFileSystemRepresentation(url,true,(UInt8*)program_dir,MAXPATHLEN); + CFRelease(url); + // Append trailing slash + strcat(program_dir ,"/"); + + // AmigaOS and alike: hard-coded volume name. + #elif defined(__amigaos4__) || defined(__AROS__) || defined(__MORPHOS__) || defined(__amigaos__) + strcpy(program_dir,"PROGDIR:"); + + // Others: The part of argv[0] before the executable name. + // Keep the last \ or /. + // Note that on Unix, once installed, the executable is called from a shell + // script sitting in /usr/local/bin/, this allows argv[0] to contain the full + // path. On Windows, Mingw32 already provides the full path in all cases. + #else + Extract_path(program_dir, argv0); + #endif +} + +// Determine which directory contains the read-only data. +// IN: The directory containing the executable +// OUT: Write into data_dir. Trailing / or \ is kept. +void Set_data_directory(const char * program_dir, char * data_dir) +{ + // On all platforms, data is in the executable's directory + strcpy(data_dir,program_dir); + // Except MacOSX, here it is stored in a special folder: + #if defined(__macosx__) + strcat(data_dir,"Contents/Resources/"); + #endif +} + +// Determine which directory should store the user's configuration. +// +// For most Unix and Windows platforms: +// If a config file already exists in program_dir, it will return it in priority +// (Useful for development, and possibly for upgrading from DOS version) +// If the standard directory doesn't exist yet, this function will attempt +// to create it ($(HOME)/.grafx2, or %APPDATA%\GrafX2) +// If it cannot be created, this function will return the executable's +// own directory. +// IN: The directory containing the executable +// OUT: Write into config_dir. Trailing / or \ is kept. +void Set_config_directory(const char * program_dir, char * config_dir) +{ + // AmigaOS4 + #if defined(__amigaos4__) || defined(__AROS__) + strcpy(config_dir,"PROGDIR:"); + // GP2X + #elif defined(__GP2X__) + // On the GP2X, the program is installed to the sdcard, and we don't want to mess with the system tree which is + // on an internal flash chip. So, keep these settings locals. + strcpy(config_dir,program_dir); + #else + char filename[MAX_PATH_CHARACTERS]; + + // In priority: check own directory + strcpy(config_dir, program_dir); + strcpy(filename, config_dir); + strcat(filename, "gfx2.cfg"); + + if (!File_exists(filename)) + { + char *config_parent_dir; + #if defined(__WIN32__) + // "%APPDATA%\GrafX2" + const char* Config_SubDir = "GrafX2"; + config_parent_dir = getenv("APPDATA"); + #elif defined(__BEOS__) || defined(__HAIKU__) + // "~/.grafx2", the BeOS way + const char* Config_SubDir = ".grafx2"; + config_parent_dir = getenv("$HOME"); + #elif defined(__macosx__) + // "~/Library/Preferences/com.googlecode.grafx2" + const char* Config_SubDir = "Library/Preferences/com.googlecode.grafx2"; + config_parent_dir = getenv("HOME"); + #else + // "~/.grafx2" + const char* Config_SubDir = ".grafx2"; + config_parent_dir = getenv("HOME"); + #endif + + if (config_parent_dir && config_parent_dir[0]!='\0') + { + int size = strlen(config_parent_dir); + strcpy(config_dir, config_parent_dir); + if (config_parent_dir[size-1] != '\\' && config_parent_dir[size-1] != '/') + { + strcat(config_dir,PATH_SEPARATOR); + } + strcat(config_dir,Config_SubDir); + if (Directory_exists(config_dir)) + { + // Répertoire trouvé, ok + strcat(config_dir,PATH_SEPARATOR); + } + else + { + // Tentative de création + if (!Create_ConfigDirectory(config_dir)) + { + // Réussi + strcat(config_dir,PATH_SEPARATOR); + } + else + { + // Echec: on se rabat sur le repertoire de l'executable. + strcpy(config_dir,program_dir); + } + } + } + } + #endif +} diff --git a/setup.h b/setup.h index c4df3f40..0fc2e25e 100644 --- a/setup.h +++ b/setup.h @@ -1,54 +1,54 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 Peter Gordon - 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file setup.h -/// Functions that determine where grafx2 is running, finds its data, and -/// reads and writes configuration files. -////////////////////////////////////////////////////////////////////////////// - -/// -/// Determine which directory contains the executable. -/// - IN: Main's argv[0], some platforms need it, some don't. -/// - OUT: Write into program_dir. Trailing / or \ is kept. -/// Note : in fact this is only used to check for the datafiles and fonts in this same directory. -void Set_program_directory(const char * argv0,char * program_dir); - -/// -/// Determine which directory contains the read-only data. -/// IN: The directory containing the executable -/// OUT: Write into data_dir. Trailing / or \ is kept. -void Set_data_directory(const char * program_dir, char * data_dir); - -/// -/// Determine which directory should store the user's configuration. -/// For most Unix and Windows platforms: -/// If a config file already exists in program_dir, it will return it in priority -/// (Useful for development, and possibly for upgrading from DOS version) -/// If the standard directory doesn't exist yet, this function will attempt -/// to create it ($(HOME)/.grafx2, or %APPDATA%\\GrafX2) -/// If it cannot be created, this function will return the executable's -/// own directory. -/// IN: The directory containing the executable -/// OUT: Write into config_dir. Trailing / or \ is kept. -void Set_config_directory(const char * program_dir, char * config_dir); - +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 Peter Gordon + 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file setup.h +/// Functions that determine where grafx2 is running, finds its data, and +/// reads and writes configuration files. +////////////////////////////////////////////////////////////////////////////// + +/// +/// Determine which directory contains the executable. +/// - IN: Main's argv[0], some platforms need it, some don't. +/// - OUT: Write into program_dir. Trailing / or \ is kept. +/// Note : in fact this is only used to check for the datafiles and fonts in this same directory. +void Set_program_directory(const char * argv0,char * program_dir); + +/// +/// Determine which directory contains the read-only data. +/// IN: The directory containing the executable +/// OUT: Write into data_dir. Trailing / or \ is kept. +void Set_data_directory(const char * program_dir, char * data_dir); + +/// +/// Determine which directory should store the user's configuration. +/// For most Unix and Windows platforms: +/// If a config file already exists in program_dir, it will return it in priority +/// (Useful for development, and possibly for upgrading from DOS version) +/// If the standard directory doesn't exist yet, this function will attempt +/// to create it ($(HOME)/.grafx2, or %APPDATA%\\GrafX2) +/// If it cannot be created, this function will return the executable's +/// own directory. +/// IN: The directory containing the executable +/// OUT: Write into config_dir. Trailing / or \ is kept. +void Set_config_directory(const char * program_dir, char * config_dir); + diff --git a/shade.h b/shade.h index 2a0d0b69..7f9e23c8 100644 --- a/shade.h +++ b/shade.h @@ -1,32 +1,32 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - 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 -*/ -////////////////////////////////////////////////////////////////////////////// -///@file shade.h -/// Screens for Shade and Quick-shade settings. -////////////////////////////////////////////////////////////////////////////// - - -#ifndef SHADE_H_INCLUDED -#define SHADE_H_INCLUDED - -void Button_Quick_shade_menu(void); - -int Shade_settings_menu(void); - -#endif // SHADE_H_INCLUDED +/* Grafx2 - The Ultimate 256-color bitmap paint program + + 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 +*/ +////////////////////////////////////////////////////////////////////////////// +///@file shade.h +/// Screens for Shade and Quick-shade settings. +////////////////////////////////////////////////////////////////////////////// + + +#ifndef SHADE_H_INCLUDED +#define SHADE_H_INCLUDED + +void Button_Quick_shade_menu(void); + +int Shade_settings_menu(void); + +#endif // SHADE_H_INCLUDED diff --git a/special.c b/special.c index 61a09152..9fa8483e 100644 --- a/special.c +++ b/special.c @@ -1,364 +1,364 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - 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 -*/ -#include -#include -#include "const.h" -#include "struct.h" -#include "global.h" -#include "graph.h" -#include "engine.h" -#include "windows.h" -#include "special.h" - - - -//---------------------- Modifier le pinceau spécial ------------------------- - -void Set_paintbrush_size(int width, int height) -{ - int x_pos,y_pos; - int x,y; - float radius2; - - if (width<1) width=1; - if (height<1) height=1; - if (width>MAX_PAINTBRUSH_SIZE) width=MAX_PAINTBRUSH_SIZE; - if (height>MAX_PAINTBRUSH_SIZE) height=MAX_PAINTBRUSH_SIZE; - Paintbrush_width=width; - Paintbrush_height=height; - Paintbrush_offset_X=Paintbrush_width>>1; - Paintbrush_offset_Y=Paintbrush_height>>1; - switch (Paintbrush_shape) - { - case PAINTBRUSH_SHAPE_ROUND : - radius2=Paintbrush_offset_X+0.414213562; // [0.410..0.415[ - radius2*=radius2; - for (y_pos=0; y_pos>1; - for (y_pos=0; y_pos>1; - for (y_pos=0; y_pos>1; - for (y_pos=0; y_pos>1; - for (y_pos=0; y_pos>1; - for (y_pos=0; y_pos1) - || (Paintbrush_height>1) ) ) - { - Hide_cursor(); - switch (Paintbrush_shape) - { - case PAINTBRUSH_SHAPE_ROUND: - case PAINTBRUSH_SHAPE_SIEVE_ROUND: - case PAINTBRUSH_SHAPE_CROSS: - case PAINTBRUSH_SHAPE_PLUS: - case PAINTBRUSH_SHAPE_DIAMOND: - case PAINTBRUSH_SHAPE_RANDOM: - if (Paintbrush_width&1) - Set_paintbrush_size(Paintbrush_width-2,Paintbrush_height-2); - else - Set_paintbrush_size(Paintbrush_width-1,Paintbrush_height-1); - break; - case PAINTBRUSH_SHAPE_SQUARE: - case PAINTBRUSH_SHAPE_SLASH: - case PAINTBRUSH_SHAPE_ANTISLASH: - case PAINTBRUSH_SHAPE_SIEVE_SQUARE: - Set_paintbrush_size(Paintbrush_width-1,Paintbrush_height-1); - break; - case PAINTBRUSH_SHAPE_HORIZONTAL_BAR: - Set_paintbrush_size(Paintbrush_width-1,1); - break; - case PAINTBRUSH_SHAPE_VERTICAL_BAR: - Set_paintbrush_size(1,Paintbrush_height-1); - } - Display_paintbrush_in_menu(); - Display_cursor(); - } -} - -void Bigger_paintbrush(void) -{ - if ( (Paintbrush_shapeMain_image_width) - temp_x_offset=Main_image_width-Screen_width; - if (temp_y_offset+Menu_Y>Main_image_height) - temp_y_offset=Main_image_height-Menu_Y; - if (temp_x_offset<0) - temp_x_offset=0; - if (temp_y_offset<0) - temp_y_offset=0; - - if ( (Main_offset_X!=temp_x_offset) || - (Main_offset_Y!=temp_y_offset) ) - { - Hide_cursor(); - Main_offset_X=temp_x_offset; - Main_offset_Y=temp_y_offset; - - Compute_limits(); - Compute_paintbrush_coordinates(); - - Display_all_screen(); // <=> Display_screen + Display_image_limits - Display_cursor(); - } -} - - -// ---------------------- Scroller la fenêtre de la loupe -------------------- -void Scroll_magnifier(short delta_x,short delta_y) -{ - short temp_x_offset; - short temp_y_offset; - - temp_x_offset=Main_magnifier_offset_X+delta_x; - temp_y_offset=Main_magnifier_offset_Y+delta_y; - - if (temp_x_offset+Main_magnifier_width>Main_image_width) - temp_x_offset=Main_image_width-Main_magnifier_width; - if (temp_y_offset+Main_magnifier_height>Main_image_height) - temp_y_offset=Main_image_height-Main_magnifier_height; - if (temp_x_offset<0) - temp_x_offset=0; - if (temp_y_offset<0) - temp_y_offset=0; - - if ( (Main_magnifier_offset_X!=temp_x_offset) || - (Main_magnifier_offset_Y!=temp_y_offset) ) - { - Hide_cursor(); - Main_magnifier_offset_X=temp_x_offset; - Main_magnifier_offset_Y=temp_y_offset; - - Position_screen_according_to_zoom(); - - Compute_limits(); - Compute_paintbrush_coordinates(); - - Display_all_screen(); - Display_cursor(); - } -} - - -// -------------- Changer le Zoom (grâce aux touches [+] et [-]) ------------- -void Zoom(short delta) -{ - short index; - for (index=0; ZOOM_FACTOR[index]!=Main_magnifier_factor; index++); - index+=delta; - - if ( (index>=0) && (index +*/ +#include +#include +#include "const.h" +#include "struct.h" +#include "global.h" +#include "graph.h" +#include "engine.h" +#include "windows.h" +#include "special.h" + + + +//---------------------- Modifier le pinceau spécial ------------------------- + +void Set_paintbrush_size(int width, int height) +{ + int x_pos,y_pos; + int x,y; + float radius2; + + if (width<1) width=1; + if (height<1) height=1; + if (width>MAX_PAINTBRUSH_SIZE) width=MAX_PAINTBRUSH_SIZE; + if (height>MAX_PAINTBRUSH_SIZE) height=MAX_PAINTBRUSH_SIZE; + Paintbrush_width=width; + Paintbrush_height=height; + Paintbrush_offset_X=Paintbrush_width>>1; + Paintbrush_offset_Y=Paintbrush_height>>1; + switch (Paintbrush_shape) + { + case PAINTBRUSH_SHAPE_ROUND : + radius2=Paintbrush_offset_X+0.414213562; // [0.410..0.415[ + radius2*=radius2; + for (y_pos=0; y_pos>1; + for (y_pos=0; y_pos>1; + for (y_pos=0; y_pos>1; + for (y_pos=0; y_pos>1; + for (y_pos=0; y_pos>1; + for (y_pos=0; y_pos1) + || (Paintbrush_height>1) ) ) + { + Hide_cursor(); + switch (Paintbrush_shape) + { + case PAINTBRUSH_SHAPE_ROUND: + case PAINTBRUSH_SHAPE_SIEVE_ROUND: + case PAINTBRUSH_SHAPE_CROSS: + case PAINTBRUSH_SHAPE_PLUS: + case PAINTBRUSH_SHAPE_DIAMOND: + case PAINTBRUSH_SHAPE_RANDOM: + if (Paintbrush_width&1) + Set_paintbrush_size(Paintbrush_width-2,Paintbrush_height-2); + else + Set_paintbrush_size(Paintbrush_width-1,Paintbrush_height-1); + break; + case PAINTBRUSH_SHAPE_SQUARE: + case PAINTBRUSH_SHAPE_SLASH: + case PAINTBRUSH_SHAPE_ANTISLASH: + case PAINTBRUSH_SHAPE_SIEVE_SQUARE: + Set_paintbrush_size(Paintbrush_width-1,Paintbrush_height-1); + break; + case PAINTBRUSH_SHAPE_HORIZONTAL_BAR: + Set_paintbrush_size(Paintbrush_width-1,1); + break; + case PAINTBRUSH_SHAPE_VERTICAL_BAR: + Set_paintbrush_size(1,Paintbrush_height-1); + } + Display_paintbrush_in_menu(); + Display_cursor(); + } +} + +void Bigger_paintbrush(void) +{ + if ( (Paintbrush_shapeMain_image_width) + temp_x_offset=Main_image_width-Screen_width; + if (temp_y_offset+Menu_Y>Main_image_height) + temp_y_offset=Main_image_height-Menu_Y; + if (temp_x_offset<0) + temp_x_offset=0; + if (temp_y_offset<0) + temp_y_offset=0; + + if ( (Main_offset_X!=temp_x_offset) || + (Main_offset_Y!=temp_y_offset) ) + { + Hide_cursor(); + Main_offset_X=temp_x_offset; + Main_offset_Y=temp_y_offset; + + Compute_limits(); + Compute_paintbrush_coordinates(); + + Display_all_screen(); // <=> Display_screen + Display_image_limits + Display_cursor(); + } +} + + +// ---------------------- Scroller la fenêtre de la loupe -------------------- +void Scroll_magnifier(short delta_x,short delta_y) +{ + short temp_x_offset; + short temp_y_offset; + + temp_x_offset=Main_magnifier_offset_X+delta_x; + temp_y_offset=Main_magnifier_offset_Y+delta_y; + + if (temp_x_offset+Main_magnifier_width>Main_image_width) + temp_x_offset=Main_image_width-Main_magnifier_width; + if (temp_y_offset+Main_magnifier_height>Main_image_height) + temp_y_offset=Main_image_height-Main_magnifier_height; + if (temp_x_offset<0) + temp_x_offset=0; + if (temp_y_offset<0) + temp_y_offset=0; + + if ( (Main_magnifier_offset_X!=temp_x_offset) || + (Main_magnifier_offset_Y!=temp_y_offset) ) + { + Hide_cursor(); + Main_magnifier_offset_X=temp_x_offset; + Main_magnifier_offset_Y=temp_y_offset; + + Position_screen_according_to_zoom(); + + Compute_limits(); + Compute_paintbrush_coordinates(); + + Display_all_screen(); + Display_cursor(); + } +} + + +// -------------- Changer le Zoom (grâce aux touches [+] et [-]) ------------- +void Zoom(short delta) +{ + short index; + for (index=0; ZOOM_FACTOR[index]!=Main_magnifier_factor; index++); + index+=delta; + + if ( (index>=0) && (index -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file special.h -/// Editor functions that can be hooked to a keyboard shortcut, but don't have -/// a menu button associated to them. -////////////////////////////////////////////////////////////////////////////// - -void Set_paintbrush_size(int width, int height); -void Smaller_paintbrush(void); -void Bigger_paintbrush(void); - -void Special_next_forecolor(void); -void Special_previous_forecolor(void); -void Special_next_backcolor(void); -void Special_previous_backcolor(void); - -void Special_next_user_forecolor(void); -void Special_previous_user_forecolor(void); -void Special_next_user_backcolor(void); -void Special_previous_user_backcolor(void); - -void Scroll_screen(short delta_x,short delta_y); -void Scroll_magnifier(short delta_x,short delta_y); - -void Zoom(short delta); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file special.h +/// Editor functions that can be hooked to a keyboard shortcut, but don't have +/// a menu button associated to them. +////////////////////////////////////////////////////////////////////////////// + +void Set_paintbrush_size(int width, int height); +void Smaller_paintbrush(void); +void Bigger_paintbrush(void); + +void Special_next_forecolor(void); +void Special_previous_forecolor(void); +void Special_next_backcolor(void); +void Special_previous_backcolor(void); + +void Special_next_user_forecolor(void); +void Special_previous_user_forecolor(void); +void Special_next_user_backcolor(void); +void Special_previous_user_backcolor(void); + +void Scroll_screen(short delta_x,short delta_y); +void Scroll_magnifier(short delta_x,short delta_y); + +void Zoom(short delta); diff --git a/struct.h b/struct.h index ed890449..93c1872b 100644 --- a/struct.h +++ b/struct.h @@ -1,410 +1,410 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file struct.h -/// Structures that can be used in the whole program. -////////////////////////////////////////////////////////////////////////////// -#ifndef _STRUCT_H_ -#define _STRUCT_H_ - -#if defined(__BEOS__) - #include -#else - #include -#endif - -#include "const.h" - - -// POSIX calls it strcasecmp, Windows uses stricmp... no ANSI standard. -#ifdef WIN32 - #define strcasecmp stricmp -#endif - -// Definition of the base data types -/// 8bit unsigned integer -#define byte uint8_t -/// 16bit unsigned integer -#define word uint16_t -/// 32bit unsigned integer -#define dword uint32_t -/// 64bit unsigned integer -#define qword uint64_t - -// Named function prototypes -typedef void (* Func_action) (void); -typedef void (* Func_pixel) (word,word,byte); -typedef byte (* Func_read) (word,word); -typedef void (* Func_clear) (byte); -typedef void (* Func_display) (word,word,word); -typedef byte (* Func_effect) (word,word,byte); -typedef void (* Func_block) (word,word,word,word,byte); -typedef void (* Func_line_XOR) (word,word,word); -typedef void (* Func_display_brush_color) (word,word,word,word,word,word,byte,word); -typedef void (* Func_display_brush_mono) (word,word,word,word,word,word,byte,byte,word); -typedef void (* Func_gradient) (long,short,short); -typedef void (* Func_remap) (word,word,word,word,byte *); -typedef void (* Func_procsline) (word,word,word,byte *); -typedef void (* Func_display_zoom) (word,word,word,byte *); -typedef void (* Func_display_brush_color_zoom) (word,word,word,word,word,word,byte,word,byte *); -typedef void (* Func_display_brush_mono_zoom) (word,word,word,word,word,word,byte,byte,word,byte *); -typedef void (* Func_draw_brush) (byte *,word,word,word,word,word,word,byte,word); -typedef void (* Func_draw_list_item) (word,word,word,byte); - -/// A set of RGB values. -typedef struct -{ - byte R; ///< Red - byte G; ///< Green - byte B; ///< Blue -}__attribute__ ((__packed__)) T_Components, T_Palette[256]; ///< A complete 256-entry RGB palette (768 bytes). - -/// A normal rectangular button in windows and menus. -typedef struct T_Normal_button -{ - short Number; ///< Unique identifier for all controls - word Pos_X; ///< Coordinate for top of button, relative to the window, before scaling. - word Pos_Y; ///< Coordinate for left of button, relative to the window, before scaling. - word Width; ///< Width before scaling - word Height; ///< Height before scaling - byte Clickable; ///< Boolean, unused. - byte Repeatable; ///< Boolean, true if the button activates repeatedly until you release the mouse button. Used for "+" buttons, for example. - word Shortcut; ///< Keyboard shortcut that will emulate a click on this button. - struct T_Normal_button * Next;///< Pointer to the next normal button of current window. -} T_Normal_button; - -/// A window control that shows a complete 256-color palette -typedef struct T_Palette_button -{ - short Number; ///< Unique identifier for all controls - word Pos_X; ///< Coordinate for top of button, relative to the window, before scaling. - word Pos_Y; ///< Coordinate for left of button, relative to the window, before scaling. - struct T_Palette_button * Next;///< Pointer to the next palette of current window. -} T_Palette_button; - -/// A window control that represents a vertical scrollbar, with a slider, and two arrow buttons. -typedef struct T_Scroller_button -{ - short Number; ///< Unique identifier for all controls - word Pos_X; ///< Coordinate for top of button, relative to the window, before scaling. - word Pos_Y; ///< Coordinate for left of button, relative to the window, before scaling. - word Height; ///< Height before scaling. - word Nb_elements; ///< Number of distinct values it can take. - word Nb_visibles; ///< If this slider is meant to show several elements of a collection, this is their number (otherwise, it's 1). - word Position; ///< Current position of the slider: which item it's pointing. - word Cursor_height; ///< Vertical dimension of the slider, in pixels before scaling. - struct T_Scroller_button * Next;///< Pointer to the next scroller of current window. -} T_Scroller_button; - -/// -/// A window control that only has a rectangular "active" area which catches mouse clicks, -// but no visible shape. It's used for custom controls where the drawing is done on -// a case by case basis. -typedef struct T_Special_button -{ - short Number; ///< Unique identifier for all controls - word Pos_X; ///< Coordinate for top of button, relative to the window, before scaling. - word Pos_Y; ///< Coordinate for left of button, relative to the window, before scaling. - word Width; ///< Width before scaling - word Height; ///< Height before scaling - struct T_Special_button * Next;///< Pointer to the next special button of current window. -} T_Special_button; - -/// Data for a dropdown item, ie. one proposed choice. -typedef struct T_Dropdown_choice -{ - short Number; ///< Value that identifies the choice (for this dropdown only) - const char * Label; ///< String to display in the dropdown panel - struct T_Dropdown_choice * Next;///< Pointer to the next choice for this dropdown. -} T_Dropdown_choice; - -/// A window control that behaves like a dropdown button. -typedef struct T_Dropdown_button -{ - short Number; ///< Unique identifier for all controls - word Pos_X; ///< Coordinate for top of button, relative to the window, before scaling. - word Pos_Y; ///< Coordinate for left of button, relative to the window, before scaling. - word Width; ///< Width before scaling - word Height; ///< Height before scaling - byte Display_choice; ///< Boolean, true if the engine should print the selected item's label in the dropdown area when the user chooses it. - byte Display_centered; ///< Boolean, true to center the labels (otherwise, align left) - byte Display_arrow; ///< Boolean, true to display a "down" arrow box in top right - byte Active_button; ///< Determines which mouse button(s) cause the dropdown panel to open: LEFT_SIDE || RIGHT_SIDE || (LEFT_SIDE|RIGHT_SIDE) - word Dropdown_width; ///< Width of the dropdown panel when it's open. Use 0 for "same as the dropdown button" - T_Dropdown_choice * First_item; ///< Linked list with the choices available for this dropdown. - struct T_Dropdown_button * Next;///< Pointer to the next dropdown button of current window. -} T_Dropdown_button; - -/// Data for one item (file, directory) in a fileselector. -typedef struct T_Fileselector_item -{ - char Short_name[19]; ///< Name to display. - char Full_name[256]; ///< Filesystem value. - byte Type; ///< Type of item: 0 = File, 1 = Directory, 2 = Drive - - struct T_Fileselector_item * Next; ///< Pointer to next item of the current fileselector. - struct T_Fileselector_item * Previous;///< Pointer to previous item of the current fileselector. -} T_Fileselector_item; - -/// Data for a fileselector -typedef struct T_Fileselector -{ - /// Number of elements in the current fileselector's ::Filelist - short Nb_elements; - /// Number of files in the current fileselector's ::Filelist - short Nb_files; - /// Number of directories in the current fileselector's ::Filelist - short Nb_directories; - /// Head of the linked list for the fileselector. - T_Fileselector_item * First; - /// Index for direct access to element number N - T_Fileselector_item ** Index; -} T_Fileselector; - -typedef struct T_List_button -{ - short Number; ///< Unique identifier for all controls - short List_start; ///< Index of the font to appear as first line - short Cursor_position; ///< Index of the selected line (0=top) - - T_Special_button * Entry_button; ///< Pointer to the associated selection control. - T_Scroller_button * Scroller; ///< Pointer to the associated scroller - - Func_draw_list_item Draw_list_item; ///< - - struct T_List_button * Next; ///< Pointer to the next list button of current window. -} T_List_button; - -/// Data for one line of the "Help" screens. -typedef struct { - char Line_type; ///< Kind of line: 'N' for normal line, 'S' for a bold line, 'K' for a line with keyboard shortcut, 'T' and '-' for upper and lower titles. - char * Text; ///< Displayed string. - int Line_parameter; ///< Generic parameter depending on line type. For 'K' lines: a shortcut identifier. For others: unused. -} T_Help_table; - -/// Data for one section of the "Help" screens, ie a page. -typedef struct -{ - const T_Help_table* Help_table; ///< Pointer to the array of ::T_Help_table that contains the lines - word Length; ///< Size of the array of lines -} T_Help_section; - -/// Data for one setting of gradients. Warning, this one is saved/loaded as binary. -typedef struct -{ - byte Start; ///< First color - byte End; ///< Last color - dword Inverse; ///< Boolean, true if the gradient goes in descending order - dword Mix; ///< Amount of randomness to add to the mix (0-255) - dword Technique;///< Gradient technique: 0 (no pattern) 1 (dithering), or 2 (big dithering) -} T_Gradient_array; - -/// Data for one setting of shade. Warning, this one is saved/loaded as binary. -typedef struct -{ - word List[512]; ///< List of entries, each one is either a color (0-255) or -1 for empty. - byte Step; ///< Step to increment/decrement on left-clicks. - byte Mode; ///< Shade mode: Normal, Loop, or No-saturation see ::SHADE_MODES -} T_Shade; - -/// Data for one fullscreen video mode in configuration file. Warning, this one is saved/loaded as binary. -typedef struct -{ - byte State; ///< How good is the mode supported. 0:Good (white) 1:OK (light) 2:So-so (dark) 4:User-disabled (black); +128 => System doesn't support it at all. - word Width; ///< Videomode width in pixels. - word Height;///< Videomode height in pixels. -} __attribute__((__packed__)) T_Config_video_mode; - -/// Header for gfx2.cfg. Warning, this one is saved/loaded as binary. -typedef struct -{ - char Signature[3]; ///< Signature for the file format. "CFG". - byte Version1; ///< Major version number (ex: 2) - byte Version2; ///< Minor version number (ex: 0) - byte Beta1; ///< Major beta version number (ex: 96) - byte Beta2; ///< Major beta version number (ex: 5) -} __attribute__((__packed__)) T_Config_header; - -/// Header for a config chunk in for gfx2.cfg. Warning, this one is saved/loaded as binary. -typedef struct -{ - byte Number; ///< Section identfier. Possible values are in enum ::CHUNKS_CFG - word Size; ///< Size of the configuration block that follows, in bytes. -} T_Config_chunk; - -/// Configuration for one keyboard shortcut in gfx2.cfg. Warning, this one is saved/loaded as binary. -typedef struct -{ - word Number; ///< Indicates the shortcut action. This is a number starting from 0, which matches ::T_Key_config.Number - word Key; ///< Keyboard shortcut: SDLK_something, or -1 for none - word Key2; ///< Alternate keyboard shortcut: SDLK_something, or -1 for none -} __attribute__((__packed__)) T_Config_shortcut_info; - -/// This structure holds all the settings which are saved and loaded as gfx2.ini. -typedef struct -{ - char *Font_file; ///< Name of the font used in the menus. Matches file skins/font_*.png (Case-sensitive on some filesystems) - char *Skin_file; ///< String, name of the file where all the graphic data is stored - int Show_hidden_files; ///< Boolean, true to show hidden files in fileselectors. - int Show_hidden_directories; ///< Boolean, true to show hidden directories in fileselectors. -// int Show_system_directories; ///< (removed when converted from DOS) - byte Display_image_limits; ///< Boolean, true to display a dotted line at the borders of the image if it's smaller than screen. - byte Cursor; ///< Mouse cursor aspect: 1 Solid, 2 Transparent, 3 Thin - byte Maximize_preview; ///< Boolean, true to make previews in fileselector fit the whole rectangle. - byte Auto_set_res; ///< Boolean, true to make grafx2 switch to a new resolution whenever you load an image. - byte Coords_rel; ///< Boolean, true to display coordinates as relative (instead of absolute) - byte Backup; ///< Boolean, true to backup the original file whenever you save an image. - byte Adjust_brush_pick; ///< Boolean, true to omit the right and bottom edges when grabbing a brush in Grid mode. - byte Auto_save; ///< Boolean, true to save configuration when exiting program. - byte Max_undo_pages; ///< Number of steps to memorize for Undo/Redo. - byte Mouse_sensitivity_index_x; ///< Mouse sensitivity in X axis - byte Mouse_sensitivity_index_y; ///< Mouse sensitivity in Y axis - byte Mouse_fix_factor_X; ///< Mouse correction factor in X axis. - byte Mouse_fix_factor_Y; ///< Mouse correction factor in Y axis. - byte Mouse_merge_movement; ///< Number of SDL mouse events that are merged into a single change of mouse coordinates. - byte Delay_left_click_on_slider; ///< Delay (in 1/100s) between two activations of a repeatable button when you hold left-click. - byte Delay_right_click_on_slider; ///< Delay (in 1/100s) between two activations of a repeatable button when you hold left-click. - long Timer_delay; ///< Delay (in 1/55s) before showing a preview in a fileselector. - T_Components Fav_menu_colors[4]; ///< Favorite colors to use for the menu. - int Nb_max_vertices_per_polygon; ///< Limit for the number of vertices in polygon tools. - byte Clear_palette; ///< Boolean, true to reset the palette (to black) before loading an image. - byte Set_resolution_according_to; ///< When Auto_set_res is on, this determines if the mode should be chosen according to the "original screen" information in the file (1) or the picture dimensons (2) - byte Ratio; ///< Determines the scaling of menu and windows: 0 no scaling, 1 scaling, 2 slight scaling. - byte Fast_zoom; ///< Boolean, true if the magnifier shortcut should automatically view the mouse area. - byte Find_file_fast; ///< In fileselectors, this determines which entries should be sought when typing letters: 0 all, 1 files only, 2 directories only. - byte Separate_colors; ///< Boolean, true if the menu palette should separate color cells with a black outline. - word Palette_cells_X; ///< Number of colors to show in a row of the menu palette. - word Palette_cells_Y; ///< Number of colors to show in a column of the menu palette. - byte Palette_vertical; ///< Boolean, true if the menu palette should go top to bottom instead of left to right - byte FX_Feedback; ///< Boolean, true if drawing effects should read the image being modified (instead of the image before clicking) - byte Safety_colors; ///< Boolean, true to make the palette automatically re-create menu colors if needed after a "Zap" or color reduction. - byte Opening_message; ///< Boolean, true to display the splash screen on strtup. - byte Clear_with_stencil; ///< Boolean, true to take the stencil into effect (if active) when using the Clear function. - byte Auto_discontinuous; ///< Boolean, true to automatically switch to the discontinuous freehand draw after grabbing a brush. - byte Screen_size_in_GIF; ///< Boolean, true to store current resolution in GIF files. - byte Auto_nb_used; ///< Boolean, true to count colors in Palette screen. - byte Default_resolution; ///< Default video mode to use on startup. Index in ::Video_mode. - char *Bookmark_directory[NB_BOOKMARKS];///< Bookmarked directories in fileselectors: This is the full dierctory name. - char Bookmark_label[NB_BOOKMARKS][8+1];///< Bookmarked directories in fileselectors: This is the displayed name. - int Window_pos_x; ///< Last window x position (9999 if unsupportd/irrelevant for the platform) - int Window_pos_y; ///< Last window y position (9999 if unsupportd/irrelevant for the platform) - word Double_click_speed; ///< Maximum delay for double-click, in ms. - word Double_key_speed; ///< Maximum delay for double-keypress, in ms. -} T_Config; - -// Structures utilisées pour les descriptions de pages et de liste de pages. -// Lorsqu'on gèrera les animations, il faudra aussi des listes de listes de -// pages. - -// Ces structures sont manipulées à travers des fonctions de gestion du -// backup dans "graph.c". - -/// This is the data for one step of Undo/Redo, for one image. -typedef struct -{ - byte * Image; ///< Pixel data for the image. - int Width; ///< Image width in pixels. - int Height; ///< Image height in pixels. - T_Palette Palette; ///< Image palette. - - char Comment[COMMENT_SIZE+1]; ///< Comment to store in the image file. - - char File_directory[MAX_PATH_CHARACTERS];///< Directory that contains the file. - char Filename[MAX_PATH_CHARACTERS]; ///< Filename without directory. - byte File_format; ///< File format, in enum ::FILE_FORMATS - -} T_Page; - -/// Collection of undo/redo steps. -typedef struct -{ - int List_size; /// Number of ::T_Page in the vector "Pages". - int Nb_pages_allocated;/// Number of ::T_Page used so far in the vector "Pages". - T_Page * Pages; /// Vector of Pages, each one being a undo/redo step. -} T_List_of_pages; - - -/// GUI skin data -typedef struct -{ - // Mouse - - /// X coordinate of the mouse cursor's "hot spot". It is < ::CURSOR_SPRITE_WIDTH - word Cursor_offset_X[NB_CURSOR_SPRITES]; - /// Y coordinate of the mouse cursor's "hot spot". It is < ::CURSOR_SPRITE_HEIGHT - word Cursor_offset_Y[NB_CURSOR_SPRITES]; - /// Graphic resources for the mouse cursor. - byte Cursor_sprite[NB_CURSOR_SPRITES][CURSOR_SPRITE_HEIGHT][CURSOR_SPRITE_WIDTH]; - - // Preset paintbrushes - - /// Graphic resources for the preset paintbrushes. - byte Paintbrush_sprite [NB_PAINTBRUSH_SPRITES][PAINTBRUSH_HEIGHT][PAINTBRUSH_WIDTH]; - /// Width of the preset paintbrushes. - word Preset_paintbrush_width[NB_PAINTBRUSH_SPRITES]; - /// Height of the preset paintbrushes. - word Preset_paintbrush_height[NB_PAINTBRUSH_SPRITES]; - /// Type of the preset paintbrush: index in enum PAINTBRUSH_SHAPES - byte Paintbrush_type[NB_PAINTBRUSH_SPRITES]; - /// Brush handle for the preset brushes. Generally ::Preset_paintbrush_width[]/2 - word Preset_paintbrush_offset_X[NB_PAINTBRUSH_SPRITES]; - /// Brush handle for the preset brushes. Generally ::Preset_paintbrush_height[]/2 - word Preset_paintbrush_offset_Y[NB_PAINTBRUSH_SPRITES]; - - // Sieve patterns - - /// Preset sieve patterns, stored as binary (one word per line) - word Sieve_pattern[12][16]; - - // Menu and other graphics - - /// Bitmap data for the menu, a single rectangle. - byte Menu_block[MENU_HEIGHT][MENU_WIDTH]; - /// Bitmap data for the icons that are displayed over the menu. - byte Menu_sprite[NB_MENU_SPRITES][MENU_SPRITE_HEIGHT][MENU_SPRITE_WIDTH]; - /// Bitmap data for the different "effects" icons. - byte Effect_sprite[NB_EFFECTS_SPRITES][MENU_SPRITE_HEIGHT][MENU_SPRITE_WIDTH]; - /// Bitmap data for the Grafx2 logo that appears on splash screen. All 256 colors allowed. - byte Logo_grafx2[231*56]; - /// Bitmap data for the 6x8 font used in help screens. - byte Help_font_norm [256][6][8]; - /// Bitmap data for the 6x8 font used in help screens ("bold" verstion). - byte Bold_font [256][6][8]; - // 12 - // 34 - /// Bitmap data for the title font used in help screens. Top-left quarter. - byte Help_font_t1 [64][6][8]; - /// Bitmap data for the title font used in help screens. Top-right quarter. - byte Help_font_t2 [64][6][8]; - /// Bitmap data for the title font used in help screens. Bottom-left quarter. - byte Help_font_t3 [64][6][8]; - /// Bitmap data for the title font used in help screens. Bottom-right quarter. - byte Help_font_t4 [64][6][8]; - /// Bitmap data for the small 8x8 icons. - byte Icon_sprite[NB_ICON_SPRITES][ICON_SPRITE_HEIGHT][ICON_SPRITE_WIDTH]; - - /// A default 256-color palette. - T_Palette Default_palette; - - -} T_Gui_skin; - -#endif +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file struct.h +/// Structures that can be used in the whole program. +////////////////////////////////////////////////////////////////////////////// +#ifndef _STRUCT_H_ +#define _STRUCT_H_ + +#if defined(__BEOS__) + #include +#else + #include +#endif + +#include "const.h" + + +// POSIX calls it strcasecmp, Windows uses stricmp... no ANSI standard. +#ifdef WIN32 + #define strcasecmp stricmp +#endif + +// Definition of the base data types +/// 8bit unsigned integer +#define byte uint8_t +/// 16bit unsigned integer +#define word uint16_t +/// 32bit unsigned integer +#define dword uint32_t +/// 64bit unsigned integer +#define qword uint64_t + +// Named function prototypes +typedef void (* Func_action) (void); +typedef void (* Func_pixel) (word,word,byte); +typedef byte (* Func_read) (word,word); +typedef void (* Func_clear) (byte); +typedef void (* Func_display) (word,word,word); +typedef byte (* Func_effect) (word,word,byte); +typedef void (* Func_block) (word,word,word,word,byte); +typedef void (* Func_line_XOR) (word,word,word); +typedef void (* Func_display_brush_color) (word,word,word,word,word,word,byte,word); +typedef void (* Func_display_brush_mono) (word,word,word,word,word,word,byte,byte,word); +typedef void (* Func_gradient) (long,short,short); +typedef void (* Func_remap) (word,word,word,word,byte *); +typedef void (* Func_procsline) (word,word,word,byte *); +typedef void (* Func_display_zoom) (word,word,word,byte *); +typedef void (* Func_display_brush_color_zoom) (word,word,word,word,word,word,byte,word,byte *); +typedef void (* Func_display_brush_mono_zoom) (word,word,word,word,word,word,byte,byte,word,byte *); +typedef void (* Func_draw_brush) (byte *,word,word,word,word,word,word,byte,word); +typedef void (* Func_draw_list_item) (word,word,word,byte); + +/// A set of RGB values. +typedef struct +{ + byte R; ///< Red + byte G; ///< Green + byte B; ///< Blue +}__attribute__ ((__packed__)) T_Components, T_Palette[256]; ///< A complete 256-entry RGB palette (768 bytes). + +/// A normal rectangular button in windows and menus. +typedef struct T_Normal_button +{ + short Number; ///< Unique identifier for all controls + word Pos_X; ///< Coordinate for top of button, relative to the window, before scaling. + word Pos_Y; ///< Coordinate for left of button, relative to the window, before scaling. + word Width; ///< Width before scaling + word Height; ///< Height before scaling + byte Clickable; ///< Boolean, unused. + byte Repeatable; ///< Boolean, true if the button activates repeatedly until you release the mouse button. Used for "+" buttons, for example. + word Shortcut; ///< Keyboard shortcut that will emulate a click on this button. + struct T_Normal_button * Next;///< Pointer to the next normal button of current window. +} T_Normal_button; + +/// A window control that shows a complete 256-color palette +typedef struct T_Palette_button +{ + short Number; ///< Unique identifier for all controls + word Pos_X; ///< Coordinate for top of button, relative to the window, before scaling. + word Pos_Y; ///< Coordinate for left of button, relative to the window, before scaling. + struct T_Palette_button * Next;///< Pointer to the next palette of current window. +} T_Palette_button; + +/// A window control that represents a vertical scrollbar, with a slider, and two arrow buttons. +typedef struct T_Scroller_button +{ + short Number; ///< Unique identifier for all controls + word Pos_X; ///< Coordinate for top of button, relative to the window, before scaling. + word Pos_Y; ///< Coordinate for left of button, relative to the window, before scaling. + word Height; ///< Height before scaling. + word Nb_elements; ///< Number of distinct values it can take. + word Nb_visibles; ///< If this slider is meant to show several elements of a collection, this is their number (otherwise, it's 1). + word Position; ///< Current position of the slider: which item it's pointing. + word Cursor_height; ///< Vertical dimension of the slider, in pixels before scaling. + struct T_Scroller_button * Next;///< Pointer to the next scroller of current window. +} T_Scroller_button; + +/// +/// A window control that only has a rectangular "active" area which catches mouse clicks, +// but no visible shape. It's used for custom controls where the drawing is done on +// a case by case basis. +typedef struct T_Special_button +{ + short Number; ///< Unique identifier for all controls + word Pos_X; ///< Coordinate for top of button, relative to the window, before scaling. + word Pos_Y; ///< Coordinate for left of button, relative to the window, before scaling. + word Width; ///< Width before scaling + word Height; ///< Height before scaling + struct T_Special_button * Next;///< Pointer to the next special button of current window. +} T_Special_button; + +/// Data for a dropdown item, ie. one proposed choice. +typedef struct T_Dropdown_choice +{ + short Number; ///< Value that identifies the choice (for this dropdown only) + const char * Label; ///< String to display in the dropdown panel + struct T_Dropdown_choice * Next;///< Pointer to the next choice for this dropdown. +} T_Dropdown_choice; + +/// A window control that behaves like a dropdown button. +typedef struct T_Dropdown_button +{ + short Number; ///< Unique identifier for all controls + word Pos_X; ///< Coordinate for top of button, relative to the window, before scaling. + word Pos_Y; ///< Coordinate for left of button, relative to the window, before scaling. + word Width; ///< Width before scaling + word Height; ///< Height before scaling + byte Display_choice; ///< Boolean, true if the engine should print the selected item's label in the dropdown area when the user chooses it. + byte Display_centered; ///< Boolean, true to center the labels (otherwise, align left) + byte Display_arrow; ///< Boolean, true to display a "down" arrow box in top right + byte Active_button; ///< Determines which mouse button(s) cause the dropdown panel to open: LEFT_SIDE || RIGHT_SIDE || (LEFT_SIDE|RIGHT_SIDE) + word Dropdown_width; ///< Width of the dropdown panel when it's open. Use 0 for "same as the dropdown button" + T_Dropdown_choice * First_item; ///< Linked list with the choices available for this dropdown. + struct T_Dropdown_button * Next;///< Pointer to the next dropdown button of current window. +} T_Dropdown_button; + +/// Data for one item (file, directory) in a fileselector. +typedef struct T_Fileselector_item +{ + char Short_name[19]; ///< Name to display. + char Full_name[256]; ///< Filesystem value. + byte Type; ///< Type of item: 0 = File, 1 = Directory, 2 = Drive + + struct T_Fileselector_item * Next; ///< Pointer to next item of the current fileselector. + struct T_Fileselector_item * Previous;///< Pointer to previous item of the current fileselector. +} T_Fileselector_item; + +/// Data for a fileselector +typedef struct T_Fileselector +{ + /// Number of elements in the current fileselector's ::Filelist + short Nb_elements; + /// Number of files in the current fileselector's ::Filelist + short Nb_files; + /// Number of directories in the current fileselector's ::Filelist + short Nb_directories; + /// Head of the linked list for the fileselector. + T_Fileselector_item * First; + /// Index for direct access to element number N + T_Fileselector_item ** Index; +} T_Fileselector; + +typedef struct T_List_button +{ + short Number; ///< Unique identifier for all controls + short List_start; ///< Index of the font to appear as first line + short Cursor_position; ///< Index of the selected line (0=top) + + T_Special_button * Entry_button; ///< Pointer to the associated selection control. + T_Scroller_button * Scroller; ///< Pointer to the associated scroller + + Func_draw_list_item Draw_list_item; ///< + + struct T_List_button * Next; ///< Pointer to the next list button of current window. +} T_List_button; + +/// Data for one line of the "Help" screens. +typedef struct { + char Line_type; ///< Kind of line: 'N' for normal line, 'S' for a bold line, 'K' for a line with keyboard shortcut, 'T' and '-' for upper and lower titles. + char * Text; ///< Displayed string. + int Line_parameter; ///< Generic parameter depending on line type. For 'K' lines: a shortcut identifier. For others: unused. +} T_Help_table; + +/// Data for one section of the "Help" screens, ie a page. +typedef struct +{ + const T_Help_table* Help_table; ///< Pointer to the array of ::T_Help_table that contains the lines + word Length; ///< Size of the array of lines +} T_Help_section; + +/// Data for one setting of gradients. Warning, this one is saved/loaded as binary. +typedef struct +{ + byte Start; ///< First color + byte End; ///< Last color + dword Inverse; ///< Boolean, true if the gradient goes in descending order + dword Mix; ///< Amount of randomness to add to the mix (0-255) + dword Technique;///< Gradient technique: 0 (no pattern) 1 (dithering), or 2 (big dithering) +} T_Gradient_array; + +/// Data for one setting of shade. Warning, this one is saved/loaded as binary. +typedef struct +{ + word List[512]; ///< List of entries, each one is either a color (0-255) or -1 for empty. + byte Step; ///< Step to increment/decrement on left-clicks. + byte Mode; ///< Shade mode: Normal, Loop, or No-saturation see ::SHADE_MODES +} T_Shade; + +/// Data for one fullscreen video mode in configuration file. Warning, this one is saved/loaded as binary. +typedef struct +{ + byte State; ///< How good is the mode supported. 0:Good (white) 1:OK (light) 2:So-so (dark) 4:User-disabled (black); +128 => System doesn't support it at all. + word Width; ///< Videomode width in pixels. + word Height;///< Videomode height in pixels. +} __attribute__((__packed__)) T_Config_video_mode; + +/// Header for gfx2.cfg. Warning, this one is saved/loaded as binary. +typedef struct +{ + char Signature[3]; ///< Signature for the file format. "CFG". + byte Version1; ///< Major version number (ex: 2) + byte Version2; ///< Minor version number (ex: 0) + byte Beta1; ///< Major beta version number (ex: 96) + byte Beta2; ///< Major beta version number (ex: 5) +} __attribute__((__packed__)) T_Config_header; + +/// Header for a config chunk in for gfx2.cfg. Warning, this one is saved/loaded as binary. +typedef struct +{ + byte Number; ///< Section identfier. Possible values are in enum ::CHUNKS_CFG + word Size; ///< Size of the configuration block that follows, in bytes. +} T_Config_chunk; + +/// Configuration for one keyboard shortcut in gfx2.cfg. Warning, this one is saved/loaded as binary. +typedef struct +{ + word Number; ///< Indicates the shortcut action. This is a number starting from 0, which matches ::T_Key_config.Number + word Key; ///< Keyboard shortcut: SDLK_something, or -1 for none + word Key2; ///< Alternate keyboard shortcut: SDLK_something, or -1 for none +} __attribute__((__packed__)) T_Config_shortcut_info; + +/// This structure holds all the settings which are saved and loaded as gfx2.ini. +typedef struct +{ + char *Font_file; ///< Name of the font used in the menus. Matches file skins/font_*.png (Case-sensitive on some filesystems) + char *Skin_file; ///< String, name of the file where all the graphic data is stored + int Show_hidden_files; ///< Boolean, true to show hidden files in fileselectors. + int Show_hidden_directories; ///< Boolean, true to show hidden directories in fileselectors. +// int Show_system_directories; ///< (removed when converted from DOS) + byte Display_image_limits; ///< Boolean, true to display a dotted line at the borders of the image if it's smaller than screen. + byte Cursor; ///< Mouse cursor aspect: 1 Solid, 2 Transparent, 3 Thin + byte Maximize_preview; ///< Boolean, true to make previews in fileselector fit the whole rectangle. + byte Auto_set_res; ///< Boolean, true to make grafx2 switch to a new resolution whenever you load an image. + byte Coords_rel; ///< Boolean, true to display coordinates as relative (instead of absolute) + byte Backup; ///< Boolean, true to backup the original file whenever you save an image. + byte Adjust_brush_pick; ///< Boolean, true to omit the right and bottom edges when grabbing a brush in Grid mode. + byte Auto_save; ///< Boolean, true to save configuration when exiting program. + byte Max_undo_pages; ///< Number of steps to memorize for Undo/Redo. + byte Mouse_sensitivity_index_x; ///< Mouse sensitivity in X axis + byte Mouse_sensitivity_index_y; ///< Mouse sensitivity in Y axis + byte Mouse_fix_factor_X; ///< Mouse correction factor in X axis. + byte Mouse_fix_factor_Y; ///< Mouse correction factor in Y axis. + byte Mouse_merge_movement; ///< Number of SDL mouse events that are merged into a single change of mouse coordinates. + byte Delay_left_click_on_slider; ///< Delay (in 1/100s) between two activations of a repeatable button when you hold left-click. + byte Delay_right_click_on_slider; ///< Delay (in 1/100s) between two activations of a repeatable button when you hold left-click. + long Timer_delay; ///< Delay (in 1/55s) before showing a preview in a fileselector. + T_Components Fav_menu_colors[4]; ///< Favorite colors to use for the menu. + int Nb_max_vertices_per_polygon; ///< Limit for the number of vertices in polygon tools. + byte Clear_palette; ///< Boolean, true to reset the palette (to black) before loading an image. + byte Set_resolution_according_to; ///< When Auto_set_res is on, this determines if the mode should be chosen according to the "original screen" information in the file (1) or the picture dimensons (2) + byte Ratio; ///< Determines the scaling of menu and windows: 0 no scaling, 1 scaling, 2 slight scaling. + byte Fast_zoom; ///< Boolean, true if the magnifier shortcut should automatically view the mouse area. + byte Find_file_fast; ///< In fileselectors, this determines which entries should be sought when typing letters: 0 all, 1 files only, 2 directories only. + byte Separate_colors; ///< Boolean, true if the menu palette should separate color cells with a black outline. + word Palette_cells_X; ///< Number of colors to show in a row of the menu palette. + word Palette_cells_Y; ///< Number of colors to show in a column of the menu palette. + byte Palette_vertical; ///< Boolean, true if the menu palette should go top to bottom instead of left to right + byte FX_Feedback; ///< Boolean, true if drawing effects should read the image being modified (instead of the image before clicking) + byte Safety_colors; ///< Boolean, true to make the palette automatically re-create menu colors if needed after a "Zap" or color reduction. + byte Opening_message; ///< Boolean, true to display the splash screen on strtup. + byte Clear_with_stencil; ///< Boolean, true to take the stencil into effect (if active) when using the Clear function. + byte Auto_discontinuous; ///< Boolean, true to automatically switch to the discontinuous freehand draw after grabbing a brush. + byte Screen_size_in_GIF; ///< Boolean, true to store current resolution in GIF files. + byte Auto_nb_used; ///< Boolean, true to count colors in Palette screen. + byte Default_resolution; ///< Default video mode to use on startup. Index in ::Video_mode. + char *Bookmark_directory[NB_BOOKMARKS];///< Bookmarked directories in fileselectors: This is the full dierctory name. + char Bookmark_label[NB_BOOKMARKS][8+1];///< Bookmarked directories in fileselectors: This is the displayed name. + int Window_pos_x; ///< Last window x position (9999 if unsupportd/irrelevant for the platform) + int Window_pos_y; ///< Last window y position (9999 if unsupportd/irrelevant for the platform) + word Double_click_speed; ///< Maximum delay for double-click, in ms. + word Double_key_speed; ///< Maximum delay for double-keypress, in ms. +} T_Config; + +// Structures utilisées pour les descriptions de pages et de liste de pages. +// Lorsqu'on gèrera les animations, il faudra aussi des listes de listes de +// pages. + +// Ces structures sont manipulées à travers des fonctions de gestion du +// backup dans "graph.c". + +/// This is the data for one step of Undo/Redo, for one image. +typedef struct +{ + byte * Image; ///< Pixel data for the image. + int Width; ///< Image width in pixels. + int Height; ///< Image height in pixels. + T_Palette Palette; ///< Image palette. + + char Comment[COMMENT_SIZE+1]; ///< Comment to store in the image file. + + char File_directory[MAX_PATH_CHARACTERS];///< Directory that contains the file. + char Filename[MAX_PATH_CHARACTERS]; ///< Filename without directory. + byte File_format; ///< File format, in enum ::FILE_FORMATS + +} T_Page; + +/// Collection of undo/redo steps. +typedef struct +{ + int List_size; /// Number of ::T_Page in the vector "Pages". + int Nb_pages_allocated;/// Number of ::T_Page used so far in the vector "Pages". + T_Page * Pages; /// Vector of Pages, each one being a undo/redo step. +} T_List_of_pages; + + +/// GUI skin data +typedef struct +{ + // Mouse + + /// X coordinate of the mouse cursor's "hot spot". It is < ::CURSOR_SPRITE_WIDTH + word Cursor_offset_X[NB_CURSOR_SPRITES]; + /// Y coordinate of the mouse cursor's "hot spot". It is < ::CURSOR_SPRITE_HEIGHT + word Cursor_offset_Y[NB_CURSOR_SPRITES]; + /// Graphic resources for the mouse cursor. + byte Cursor_sprite[NB_CURSOR_SPRITES][CURSOR_SPRITE_HEIGHT][CURSOR_SPRITE_WIDTH]; + + // Preset paintbrushes + + /// Graphic resources for the preset paintbrushes. + byte Paintbrush_sprite [NB_PAINTBRUSH_SPRITES][PAINTBRUSH_HEIGHT][PAINTBRUSH_WIDTH]; + /// Width of the preset paintbrushes. + word Preset_paintbrush_width[NB_PAINTBRUSH_SPRITES]; + /// Height of the preset paintbrushes. + word Preset_paintbrush_height[NB_PAINTBRUSH_SPRITES]; + /// Type of the preset paintbrush: index in enum PAINTBRUSH_SHAPES + byte Paintbrush_type[NB_PAINTBRUSH_SPRITES]; + /// Brush handle for the preset brushes. Generally ::Preset_paintbrush_width[]/2 + word Preset_paintbrush_offset_X[NB_PAINTBRUSH_SPRITES]; + /// Brush handle for the preset brushes. Generally ::Preset_paintbrush_height[]/2 + word Preset_paintbrush_offset_Y[NB_PAINTBRUSH_SPRITES]; + + // Sieve patterns + + /// Preset sieve patterns, stored as binary (one word per line) + word Sieve_pattern[12][16]; + + // Menu and other graphics + + /// Bitmap data for the menu, a single rectangle. + byte Menu_block[MENU_HEIGHT][MENU_WIDTH]; + /// Bitmap data for the icons that are displayed over the menu. + byte Menu_sprite[NB_MENU_SPRITES][MENU_SPRITE_HEIGHT][MENU_SPRITE_WIDTH]; + /// Bitmap data for the different "effects" icons. + byte Effect_sprite[NB_EFFECTS_SPRITES][MENU_SPRITE_HEIGHT][MENU_SPRITE_WIDTH]; + /// Bitmap data for the Grafx2 logo that appears on splash screen. All 256 colors allowed. + byte Logo_grafx2[231*56]; + /// Bitmap data for the 6x8 font used in help screens. + byte Help_font_norm [256][6][8]; + /// Bitmap data for the 6x8 font used in help screens ("bold" verstion). + byte Bold_font [256][6][8]; + // 12 + // 34 + /// Bitmap data for the title font used in help screens. Top-left quarter. + byte Help_font_t1 [64][6][8]; + /// Bitmap data for the title font used in help screens. Top-right quarter. + byte Help_font_t2 [64][6][8]; + /// Bitmap data for the title font used in help screens. Bottom-left quarter. + byte Help_font_t3 [64][6][8]; + /// Bitmap data for the title font used in help screens. Bottom-right quarter. + byte Help_font_t4 [64][6][8]; + /// Bitmap data for the small 8x8 icons. + byte Icon_sprite[NB_ICON_SPRITES][ICON_SPRITE_HEIGHT][ICON_SPRITE_WIDTH]; + + /// A default 256-color palette. + T_Palette Default_palette; + + +} T_Gui_skin; + +#endif diff --git a/text.h b/text.h index 11b0f7e8..cb96813a 100644 --- a/text.h +++ b/text.h @@ -1,54 +1,54 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2008 Yves Rizoud - Copyright 2008 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file text.h -/// Functions related to rendering text as a brush, using TrueType or SFont. -////////////////////////////////////////////////////////////////////////////// - -/// Initialization of text settings, needs to be called once on program startup. -void Init_text(void); -/// Returns true if text.c was compiled with TrueType support. -int TrueType_is_supported(void); -/// Add a new font to the list to propose to the user. -void Add_font(const char *name); -/// -/// Creates a brush, from the parameters given: -/// @param str The text to render -/// @param font_number The index of the font to use. Pass 0 for the first font you declared with ::Add_font(), 1 for the second etc. -/// @param size The size in points (unused for bitmap fonts) -/// @param antialias Boolean, true to use antialiasing in TrueType -/// @param bold Boolean, true to use bold rendering in TrueType -/// @param italic Boolean, true to use italic rendering in TrueType -/// @param width Returns the width of the created brush, in pixels. -/// @param height Returns the height of the created brush, in pixels. -/// Returns true on success. -byte *Render_text(const char *str, int font_number, int size, int antialias, int bold, int italic, int *width, int *height); - -/// Finds a label to display for a font declared with ::Add_font(). -char * Font_label(int index); -/// Finds the filename of a font declared with ::Add_font(). -char * Font_name(int index); -/// Returns true if the font of this number is TrueType, false if it's a SFont bitmap. -char * TrueType_font(int index); -/// -/// Number of fonts declared with a series of ::Add_font(). This is public for -/// convenience, but functionaly it is read-only. -extern int Nb_fonts; +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 Yves Rizoud + Copyright 2008 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file text.h +/// Functions related to rendering text as a brush, using TrueType or SFont. +////////////////////////////////////////////////////////////////////////////// + +/// Initialization of text settings, needs to be called once on program startup. +void Init_text(void); +/// Returns true if text.c was compiled with TrueType support. +int TrueType_is_supported(void); +/// Add a new font to the list to propose to the user. +void Add_font(const char *name); +/// +/// Creates a brush, from the parameters given: +/// @param str The text to render +/// @param font_number The index of the font to use. Pass 0 for the first font you declared with ::Add_font(), 1 for the second etc. +/// @param size The size in points (unused for bitmap fonts) +/// @param antialias Boolean, true to use antialiasing in TrueType +/// @param bold Boolean, true to use bold rendering in TrueType +/// @param italic Boolean, true to use italic rendering in TrueType +/// @param width Returns the width of the created brush, in pixels. +/// @param height Returns the height of the created brush, in pixels. +/// Returns true on success. +byte *Render_text(const char *str, int font_number, int size, int antialias, int bold, int italic, int *width, int *height); + +/// Finds a label to display for a font declared with ::Add_font(). +char * Font_label(int index); +/// Finds the filename of a font declared with ::Add_font(). +char * Font_name(int index); +/// Returns true if the font of this number is TrueType, false if it's a SFont bitmap. +char * TrueType_font(int index); +/// +/// Number of fonts declared with a series of ::Add_font(). This is public for +/// convenience, but functionaly it is read-only. +extern int Nb_fonts; diff --git a/transform.c b/transform.c index 3f30c081..3305d89c 100644 --- a/transform.c +++ b/transform.c @@ -1,409 +1,409 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2009 Yves Rizoud - Copyright 2009 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 -*/ -#include -#include - -#include "global.h" -#include "struct.h" -#include "transform.h" -#include "engine.h" -#include "sdlscreen.h" -#include "windows.h" -#include "input.h" -#include "help.h" -#include "misc.h" // Num2str -#include "readline.h" -#include "buttons.h" // Message_out_of_memory() -#include "pages.h" // Backup_with_new_dimensions() - -/// Reduces a fraction A/B to its smallest representation. ie (40,60) becomes (2/3) -void Factorize(short *a, short *b) -{ - // Method: brute-force. - short factor; - - factor=2; - while (factor<=*a && factor<=*b) - { - if (((*a % factor) == 0) && ((*b % factor) == 0)) - { - // common factor is found - *a/=factor; - *b/=factor; - // restart - factor=2; - } - else - factor++; - } -} - -/// Multiplies original_size by new_ratio/old_ratio, but keeps result in 1-9999 range. -short Compute_dimension(short original_size, short new_ratio, short old_ratio) -{ - long amount; - amount = (long)original_size*new_ratio/old_ratio; - if (amount>9999) - return 9999; - else if (amount<1) - return 1; - else - return amount; -} - -void Button_Transform_menu(void) -{ - enum RESIZE_UNIT { - UNIT_PIXELS = 1, - UNIT_PERCENT = 2, - UNIT_RATIO = 3 - }; - - char buffer[5]; - short clicked_button; - const char * unit_label[] = { - "", - "Pixels ", - "Percent", - "Ratio "}; - short last_unit_index = -1; - short old_ratio_width; - short old_ratio_height; - short new_ratio_width; - short new_ratio_height; - short new_width=Main_image_width; - short new_height=Main_image_height; - byte need_display_size = 0; - - // Persistent data - static short unit_index = 1; // 1= Pixels, 2= Percent, 3=Ratio - static short ratio_is_locked = 1; // True if X and Y resize should go together - - T_Dropdown_button * unit_button; - T_Special_button * input_button[4]; - short *input_value[4]; - - // Set initial ratio - if (unit_index == UNIT_PERCENT) - new_ratio_width=old_ratio_width=new_ratio_height=old_ratio_height=100; - else - new_ratio_width=old_ratio_width=new_ratio_height=old_ratio_height=1; - - Open_window(215,165,"Picture transform"); - - Window_display_frame( 5, 15,205,91); - Window_display_frame( 5,110, 55,49); - Window_display_frame(64,110, 85,49); - - Window_set_normal_button(154,140, 54,14,"Cancel",0,1,KEY_ESC); // 1 - - Print_in_window( 9,114,"Mirror",MC_Dark,MC_Light); - Window_set_normal_button( 17,125, 27,14,"X\035" ,1,1,SDLK_x); // 2 - Window_set_normal_button( 17,140, 27,14,"Y\022" ,1,1,SDLK_y); // 3 - - Print_in_window( 84,114,"Rotate",MC_Dark,MC_Light); - Window_set_normal_button( 69,125, 37,14,"-90°" ,0,1,SDLK_LAST); // 4 - Window_set_normal_button(107,125, 37,14,"+90°" ,0,1,SDLK_LAST); // 5 - Window_set_normal_button( 69,140, 75,14,"180°" ,0,1,SDLK_LAST); // 6 - - Print_in_window( 87, 19,"Resize",MC_Dark,MC_Light); - Window_set_normal_button( 80, 86, 60,14,"RESIZE",1,1,SDLK_r); // 7 - Print_in_window( 51, 34,"New",MC_Dark,MC_Light); - Print_in_window( 96, 34,"Old",MC_Dark,MC_Light); - Print_in_window( 30, 44,"X:",MC_Dark,MC_Light); - Print_in_window( 30, 59,"Y:",MC_Dark,MC_Light); - Print_in_window( 80, 44,":",MC_Dark,MC_Light); - Print_in_window( 80, 59,":",MC_Dark,MC_Light); - Print_in_window( 44, 75,"Lock proportions",MC_Dark,MC_Light); - - Window_set_normal_button( 28, 72, 13,13,ratio_is_locked?"X":" ",0,1,SDLK_l);// 8 - unit_button = Window_set_dropdown_button(128,50,69,11,69,unit_label[unit_index],1,0,1,LEFT_SIDE|RIGHT_SIDE);// 9 - Window_dropdown_add_item(unit_button,UNIT_PIXELS,unit_label[UNIT_PIXELS]); - Window_dropdown_add_item(unit_button,UNIT_PERCENT,unit_label[UNIT_PERCENT]); - Window_dropdown_add_item(unit_button,UNIT_RATIO,unit_label[UNIT_RATIO]); - - input_button[0] = Window_set_input_button(45,43,4); // 10 - input_button[1] = Window_set_input_button(89,43,4); // 11 - input_button[2] = Window_set_input_button(45,58,4); // 12 - input_button[3] = Window_set_input_button(89,58,4); // 13 - - Update_window_area(0,0,Window_width, Window_height); - - Display_cursor(); - - do - { - // Display the coordinates with the right unit - if (last_unit_index != unit_index) - { - switch(unit_index) - { - case UNIT_PIXELS: - default: - input_value[0]=&new_width; - input_value[1]=&Main_image_width; // Don't worry, it's read-only - input_value[2]=&new_height; - input_value[3]=&Main_image_height; // Don't worry, it's read-only - break; - case UNIT_PERCENT: - case UNIT_RATIO: - input_value[0]=&new_ratio_width; - input_value[1]=&old_ratio_width; - input_value[2]=&new_ratio_height; - input_value[3]=&old_ratio_height; - break; - } - need_display_size=1; - last_unit_index=unit_index; - } - if (need_display_size) - { - short i; - Hide_cursor(); - for (i=0;i<4;i++) - { - // "Old" values are not editable, unless the unit is "ratio" - byte color = ((unit_index!=UNIT_RATIO) && (i==1 || i==3)) ? MC_Dark : MC_Black; - Num2str(*(input_value[i]),buffer,4); - Print_in_window_limited(input_button[i]->Pos_X+2,input_button[i]->Pos_Y+2,buffer,input_button[i]->Width/8,color,MC_Light); - } - Display_cursor(); - need_display_size=0; - } - - clicked_button=Window_clicked_button(); - - // Contextual help - if (Is_shortcut(Key,0x100+BUTTON_HELP)) - { - Key=0; - Window_help(BUTTON_ADJUST, "PICTURE TRANSFORM"); - } - else switch(clicked_button) - { - case 9: // Unit - switch(Window_attribute2) - { - case UNIT_PIXELS: - // Do nothing, pixel size was already computed. - break; - case UNIT_PERCENT: - if (unit_index == UNIT_RATIO) - { - // Approximate from current ratio - new_ratio_width = Compute_dimension(new_ratio_width,100,old_ratio_width); - new_ratio_height = Compute_dimension(new_ratio_height,100,old_ratio_height); - old_ratio_width = 100; - old_ratio_height = 100; - // Update pixel dimensions, to match percentage exactly - new_width=Compute_dimension(Main_image_width, new_ratio_width, old_ratio_width); - new_height=Compute_dimension(Main_image_height, new_ratio_height, old_ratio_height); - } - else // unit_index == UNIT_PIXELS - { - // Approximate from current pixel size - new_ratio_width = new_width*100/Main_image_width; - new_ratio_height = new_height*100/Main_image_height; - old_ratio_width = 100; - old_ratio_height = 100; - } - break; - case UNIT_RATIO: - if (unit_index == UNIT_PERCENT) - { - // Compute simplest ratio from current % - Factorize(&new_ratio_width, &old_ratio_width); - Factorize(&new_ratio_height, &old_ratio_height); - } - else // unit_index == UNIT_PIXELS - { - // Compute simplest ratio from current pixel size - new_ratio_width = new_width; - new_ratio_height = new_height; - old_ratio_width = Main_image_width; - old_ratio_height = Main_image_height; - Factorize(&new_ratio_width, &old_ratio_width); - Factorize(&new_ratio_height, &old_ratio_height); - } - break; - } - - unit_index = Window_attribute2; - break; - - case 8: // Lock proportions - ratio_is_locked = ! ratio_is_locked; - Hide_cursor(); - Print_in_window(31,75,(ratio_is_locked)?"X":" ",MC_Black,MC_Light); - Display_cursor(); - break; - - case 11: // input old width - case 13: // input old height - // "Old" values are not editable, unless the unit is "ratio" - if (unit_index!=UNIT_RATIO) - break; - case 10: // input new width - case 12: // input new height - Num2str(*( input_value[clicked_button-10]),buffer,4); - Hide_cursor(); - if (Readline(input_button[clicked_button-10]->Pos_X+2, - input_button[clicked_button-10]->Pos_Y+2, - buffer, - 4, - 1)) - { - // Accept entered value - *(input_value[clicked_button-10])=atoi(buffer); - // 0 is not acceptable size - if (*(input_value[clicked_button-10])==0) - { - *(input_value[clicked_button-10])=1; - } - // Adapt the other coordinate if X and Y are locked - if (ratio_is_locked) - { - if (clicked_button == 10 || clicked_button == 11 ) - { - // Get Y value because X changed - if (unit_index == UNIT_PIXELS) - { - new_height=Compute_dimension(Main_image_height, new_width, Main_image_width); - } - else - { - // Copy the whole ratio - new_ratio_height=new_ratio_width; - old_ratio_height=old_ratio_width; - } - } - else // (clicked_button == 12 || clicked_button == 13) - { - // Get X value because Y changed - if (unit_index == UNIT_PIXELS) - { - new_width=Compute_dimension(Main_image_width, new_height, Main_image_height); - } - else - { - // Copy the whole ratio - new_ratio_width=new_ratio_height; - old_ratio_width=old_ratio_height; - } - } - } - - // Re-compute ratio from size in pixels - if (unit_index == UNIT_PIXELS) - { - //new_width=(long)Main_image_width*new_ratio_width/old_ratio_width; - //new_height=(long)Main_image_height*new_ratio_height/old_ratio_height; - } - else // Re-compute size in pixels from ratio - { - new_width=Compute_dimension(Main_image_width,new_ratio_width,old_ratio_width); - new_height=Compute_dimension(Main_image_height,new_ratio_height,old_ratio_height); - } - need_display_size=1; - } - Display_cursor(); - break; - } - } - while (clicked_button<=0 || clicked_button>=8); - - Close_window(); - - // The Scroll operation uses the same button as transformation menu. - if (Current_operation != OPERATION_SCROLL) - Unselect_button(BUTTON_ADJUST); - - if (clicked_button != 1) // 1 is Cancel - { - short old_width; - short old_height; - - // Determine new image dimensions - switch (clicked_button) - { - case 7 : // Resize - // Keep new_width and new_height as entered. - break; - case 2 : // Flip X - case 3 : // Flip Y - case 6 : // 180° Rotation - new_width=Main_image_width; - new_height=Main_image_height; - break; - - case 4 : // -90° Rotation - case 5 : // +90° Rotation - - new_width=Main_image_height; - new_height=Main_image_width; - break; - } - // Memorize the current dimensions - old_width=Main_image_width; - old_height=Main_image_height; - - // Allocate a new page - if (Backup_with_new_dimensions(1,new_width,new_height)) - { - // The new image is allocated, the new dimensions are already updated. - - Main_image_is_modified=1; - - // Process the transformation: - switch(clicked_button) - { - case 2 : // Flip X - memcpy(Main_screen,Screen_backup,Main_image_width*Main_image_height); - Flip_X_lowlevel(Main_screen, Main_image_width, Main_image_height); - break; - case 3 : // Flip Y - memcpy(Main_screen,Screen_backup,Main_image_width*Main_image_height); - Flip_Y_lowlevel(Main_screen, Main_image_width, Main_image_height); - break; - case 4 : // -90° Rotation - Rotate_270_deg_lowlevel(Screen_backup, Main_screen, old_width, old_height); - break; - case 5 : // +90° Rotation - Rotate_90_deg_lowlevel(Screen_backup, Main_screen, old_width, old_height); - break; - case 6 : // 180° Rotation - memcpy(Main_screen,Screen_backup,Main_image_width*Main_image_height); - Rotate_180_deg_lowlevel(Main_screen, Main_image_width, Main_image_height); - break; - case 7 : // Resize - Rescale(Screen_backup, old_width, old_height, Main_screen, Main_image_width, Main_image_height, 0, 0); - break; - } - Display_all_screen(); - } - else - { - Display_cursor(); - Message_out_of_memory(); - Hide_cursor(); - } - } - Display_cursor(); -} +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2009 Yves Rizoud + Copyright 2009 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 +*/ +#include +#include + +#include "global.h" +#include "struct.h" +#include "transform.h" +#include "engine.h" +#include "sdlscreen.h" +#include "windows.h" +#include "input.h" +#include "help.h" +#include "misc.h" // Num2str +#include "readline.h" +#include "buttons.h" // Message_out_of_memory() +#include "pages.h" // Backup_with_new_dimensions() + +/// Reduces a fraction A/B to its smallest representation. ie (40,60) becomes (2/3) +void Factorize(short *a, short *b) +{ + // Method: brute-force. + short factor; + + factor=2; + while (factor<=*a && factor<=*b) + { + if (((*a % factor) == 0) && ((*b % factor) == 0)) + { + // common factor is found + *a/=factor; + *b/=factor; + // restart + factor=2; + } + else + factor++; + } +} + +/// Multiplies original_size by new_ratio/old_ratio, but keeps result in 1-9999 range. +short Compute_dimension(short original_size, short new_ratio, short old_ratio) +{ + long amount; + amount = (long)original_size*new_ratio/old_ratio; + if (amount>9999) + return 9999; + else if (amount<1) + return 1; + else + return amount; +} + +void Button_Transform_menu(void) +{ + enum RESIZE_UNIT { + UNIT_PIXELS = 1, + UNIT_PERCENT = 2, + UNIT_RATIO = 3 + }; + + char buffer[5]; + short clicked_button; + const char * unit_label[] = { + "", + "Pixels ", + "Percent", + "Ratio "}; + short last_unit_index = -1; + short old_ratio_width; + short old_ratio_height; + short new_ratio_width; + short new_ratio_height; + short new_width=Main_image_width; + short new_height=Main_image_height; + byte need_display_size = 0; + + // Persistent data + static short unit_index = 1; // 1= Pixels, 2= Percent, 3=Ratio + static short ratio_is_locked = 1; // True if X and Y resize should go together + + T_Dropdown_button * unit_button; + T_Special_button * input_button[4]; + short *input_value[4]; + + // Set initial ratio + if (unit_index == UNIT_PERCENT) + new_ratio_width=old_ratio_width=new_ratio_height=old_ratio_height=100; + else + new_ratio_width=old_ratio_width=new_ratio_height=old_ratio_height=1; + + Open_window(215,165,"Picture transform"); + + Window_display_frame( 5, 15,205,91); + Window_display_frame( 5,110, 55,49); + Window_display_frame(64,110, 85,49); + + Window_set_normal_button(154,140, 54,14,"Cancel",0,1,KEY_ESC); // 1 + + Print_in_window( 9,114,"Mirror",MC_Dark,MC_Light); + Window_set_normal_button( 17,125, 27,14,"X\035" ,1,1,SDLK_x); // 2 + Window_set_normal_button( 17,140, 27,14,"Y\022" ,1,1,SDLK_y); // 3 + + Print_in_window( 84,114,"Rotate",MC_Dark,MC_Light); + Window_set_normal_button( 69,125, 37,14,"-90°" ,0,1,SDLK_LAST); // 4 + Window_set_normal_button(107,125, 37,14,"+90°" ,0,1,SDLK_LAST); // 5 + Window_set_normal_button( 69,140, 75,14,"180°" ,0,1,SDLK_LAST); // 6 + + Print_in_window( 87, 19,"Resize",MC_Dark,MC_Light); + Window_set_normal_button( 80, 86, 60,14,"RESIZE",1,1,SDLK_r); // 7 + Print_in_window( 51, 34,"New",MC_Dark,MC_Light); + Print_in_window( 96, 34,"Old",MC_Dark,MC_Light); + Print_in_window( 30, 44,"X:",MC_Dark,MC_Light); + Print_in_window( 30, 59,"Y:",MC_Dark,MC_Light); + Print_in_window( 80, 44,":",MC_Dark,MC_Light); + Print_in_window( 80, 59,":",MC_Dark,MC_Light); + Print_in_window( 44, 75,"Lock proportions",MC_Dark,MC_Light); + + Window_set_normal_button( 28, 72, 13,13,ratio_is_locked?"X":" ",0,1,SDLK_l);// 8 + unit_button = Window_set_dropdown_button(128,50,69,11,69,unit_label[unit_index],1,0,1,LEFT_SIDE|RIGHT_SIDE);// 9 + Window_dropdown_add_item(unit_button,UNIT_PIXELS,unit_label[UNIT_PIXELS]); + Window_dropdown_add_item(unit_button,UNIT_PERCENT,unit_label[UNIT_PERCENT]); + Window_dropdown_add_item(unit_button,UNIT_RATIO,unit_label[UNIT_RATIO]); + + input_button[0] = Window_set_input_button(45,43,4); // 10 + input_button[1] = Window_set_input_button(89,43,4); // 11 + input_button[2] = Window_set_input_button(45,58,4); // 12 + input_button[3] = Window_set_input_button(89,58,4); // 13 + + Update_window_area(0,0,Window_width, Window_height); + + Display_cursor(); + + do + { + // Display the coordinates with the right unit + if (last_unit_index != unit_index) + { + switch(unit_index) + { + case UNIT_PIXELS: + default: + input_value[0]=&new_width; + input_value[1]=&Main_image_width; // Don't worry, it's read-only + input_value[2]=&new_height; + input_value[3]=&Main_image_height; // Don't worry, it's read-only + break; + case UNIT_PERCENT: + case UNIT_RATIO: + input_value[0]=&new_ratio_width; + input_value[1]=&old_ratio_width; + input_value[2]=&new_ratio_height; + input_value[3]=&old_ratio_height; + break; + } + need_display_size=1; + last_unit_index=unit_index; + } + if (need_display_size) + { + short i; + Hide_cursor(); + for (i=0;i<4;i++) + { + // "Old" values are not editable, unless the unit is "ratio" + byte color = ((unit_index!=UNIT_RATIO) && (i==1 || i==3)) ? MC_Dark : MC_Black; + Num2str(*(input_value[i]),buffer,4); + Print_in_window_limited(input_button[i]->Pos_X+2,input_button[i]->Pos_Y+2,buffer,input_button[i]->Width/8,color,MC_Light); + } + Display_cursor(); + need_display_size=0; + } + + clicked_button=Window_clicked_button(); + + // Contextual help + if (Is_shortcut(Key,0x100+BUTTON_HELP)) + { + Key=0; + Window_help(BUTTON_ADJUST, "PICTURE TRANSFORM"); + } + else switch(clicked_button) + { + case 9: // Unit + switch(Window_attribute2) + { + case UNIT_PIXELS: + // Do nothing, pixel size was already computed. + break; + case UNIT_PERCENT: + if (unit_index == UNIT_RATIO) + { + // Approximate from current ratio + new_ratio_width = Compute_dimension(new_ratio_width,100,old_ratio_width); + new_ratio_height = Compute_dimension(new_ratio_height,100,old_ratio_height); + old_ratio_width = 100; + old_ratio_height = 100; + // Update pixel dimensions, to match percentage exactly + new_width=Compute_dimension(Main_image_width, new_ratio_width, old_ratio_width); + new_height=Compute_dimension(Main_image_height, new_ratio_height, old_ratio_height); + } + else // unit_index == UNIT_PIXELS + { + // Approximate from current pixel size + new_ratio_width = new_width*100/Main_image_width; + new_ratio_height = new_height*100/Main_image_height; + old_ratio_width = 100; + old_ratio_height = 100; + } + break; + case UNIT_RATIO: + if (unit_index == UNIT_PERCENT) + { + // Compute simplest ratio from current % + Factorize(&new_ratio_width, &old_ratio_width); + Factorize(&new_ratio_height, &old_ratio_height); + } + else // unit_index == UNIT_PIXELS + { + // Compute simplest ratio from current pixel size + new_ratio_width = new_width; + new_ratio_height = new_height; + old_ratio_width = Main_image_width; + old_ratio_height = Main_image_height; + Factorize(&new_ratio_width, &old_ratio_width); + Factorize(&new_ratio_height, &old_ratio_height); + } + break; + } + + unit_index = Window_attribute2; + break; + + case 8: // Lock proportions + ratio_is_locked = ! ratio_is_locked; + Hide_cursor(); + Print_in_window(31,75,(ratio_is_locked)?"X":" ",MC_Black,MC_Light); + Display_cursor(); + break; + + case 11: // input old width + case 13: // input old height + // "Old" values are not editable, unless the unit is "ratio" + if (unit_index!=UNIT_RATIO) + break; + case 10: // input new width + case 12: // input new height + Num2str(*( input_value[clicked_button-10]),buffer,4); + Hide_cursor(); + if (Readline(input_button[clicked_button-10]->Pos_X+2, + input_button[clicked_button-10]->Pos_Y+2, + buffer, + 4, + 1)) + { + // Accept entered value + *(input_value[clicked_button-10])=atoi(buffer); + // 0 is not acceptable size + if (*(input_value[clicked_button-10])==0) + { + *(input_value[clicked_button-10])=1; + } + // Adapt the other coordinate if X and Y are locked + if (ratio_is_locked) + { + if (clicked_button == 10 || clicked_button == 11 ) + { + // Get Y value because X changed + if (unit_index == UNIT_PIXELS) + { + new_height=Compute_dimension(Main_image_height, new_width, Main_image_width); + } + else + { + // Copy the whole ratio + new_ratio_height=new_ratio_width; + old_ratio_height=old_ratio_width; + } + } + else // (clicked_button == 12 || clicked_button == 13) + { + // Get X value because Y changed + if (unit_index == UNIT_PIXELS) + { + new_width=Compute_dimension(Main_image_width, new_height, Main_image_height); + } + else + { + // Copy the whole ratio + new_ratio_width=new_ratio_height; + old_ratio_width=old_ratio_height; + } + } + } + + // Re-compute ratio from size in pixels + if (unit_index == UNIT_PIXELS) + { + //new_width=(long)Main_image_width*new_ratio_width/old_ratio_width; + //new_height=(long)Main_image_height*new_ratio_height/old_ratio_height; + } + else // Re-compute size in pixels from ratio + { + new_width=Compute_dimension(Main_image_width,new_ratio_width,old_ratio_width); + new_height=Compute_dimension(Main_image_height,new_ratio_height,old_ratio_height); + } + need_display_size=1; + } + Display_cursor(); + break; + } + } + while (clicked_button<=0 || clicked_button>=8); + + Close_window(); + + // The Scroll operation uses the same button as transformation menu. + if (Current_operation != OPERATION_SCROLL) + Unselect_button(BUTTON_ADJUST); + + if (clicked_button != 1) // 1 is Cancel + { + short old_width; + short old_height; + + // Determine new image dimensions + switch (clicked_button) + { + case 7 : // Resize + // Keep new_width and new_height as entered. + break; + case 2 : // Flip X + case 3 : // Flip Y + case 6 : // 180° Rotation + new_width=Main_image_width; + new_height=Main_image_height; + break; + + case 4 : // -90° Rotation + case 5 : // +90° Rotation + + new_width=Main_image_height; + new_height=Main_image_width; + break; + } + // Memorize the current dimensions + old_width=Main_image_width; + old_height=Main_image_height; + + // Allocate a new page + if (Backup_with_new_dimensions(1,new_width,new_height)) + { + // The new image is allocated, the new dimensions are already updated. + + Main_image_is_modified=1; + + // Process the transformation: + switch(clicked_button) + { + case 2 : // Flip X + memcpy(Main_screen,Screen_backup,Main_image_width*Main_image_height); + Flip_X_lowlevel(Main_screen, Main_image_width, Main_image_height); + break; + case 3 : // Flip Y + memcpy(Main_screen,Screen_backup,Main_image_width*Main_image_height); + Flip_Y_lowlevel(Main_screen, Main_image_width, Main_image_height); + break; + case 4 : // -90° Rotation + Rotate_270_deg_lowlevel(Screen_backup, Main_screen, old_width, old_height); + break; + case 5 : // +90° Rotation + Rotate_90_deg_lowlevel(Screen_backup, Main_screen, old_width, old_height); + break; + case 6 : // 180° Rotation + memcpy(Main_screen,Screen_backup,Main_image_width*Main_image_height); + Rotate_180_deg_lowlevel(Main_screen, Main_image_width, Main_image_height); + break; + case 7 : // Resize + Rescale(Screen_backup, old_width, old_height, Main_screen, Main_image_width, Main_image_height, 0, 0); + break; + } + Display_all_screen(); + } + else + { + Display_cursor(); + Message_out_of_memory(); + Hide_cursor(); + } + } + Display_cursor(); +} diff --git a/transform.h b/transform.h index 38b91db6..899c4443 100644 --- a/transform.h +++ b/transform.h @@ -1,27 +1,27 @@ -/* Grafx2 - The Ultimate 256-color bitmap paint program - - Copyright 2009 Yves Rizoud - Copyright 2009 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 -*/ - -////////////////////////////////////////////////////////////////////////////// -///@file transform.h -/// Screen and functions for picture transform. -////////////////////////////////////////////////////////////////////////////// - -/// Opens and handles the Picture transform screen. -void Button_Transform_menu(void); +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2009 Yves Rizoud + Copyright 2009 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 +*/ + +////////////////////////////////////////////////////////////////////////////// +///@file transform.h +/// Screen and functions for picture transform. +////////////////////////////////////////////////////////////////////////////// + +/// Opens and handles the Picture transform screen. +void Button_Transform_menu(void);